Как сделать анимацию полностью завершенной нажатием клавиши для phaser.io - PullRequest
0 голосов
/ 14 октября 2018

Итак, я просмотрел несколько видеороликов, некоторые веб-сайты, которые задавали тот же вопрос, и даже собственные примеры кода phaser.io, и я все еще застрял на том, что не могу полностью завершить анимацию при нажатии клавиши,Я думаю, что у меня есть Phaser 2.4.4, наш профессор требовал этого.Анимация не единственная, что происходит, пока нажата клавиша.Я вызываю другую функцию, чтобы что-то сделать (телепортировать персонажа).Я играл с time.events весь день, но не повезло.Все, что мне нужно, чтобы это получилось - это воспроизвести анимацию при нажатии клавиши, сделать персонажа невидимым, а затем снова показать персонажа в новом месте с той же анимацией телепортации.У меня уже есть функция, по большей части связанная с фактическим телепортированием, это просто анимация, которая не воспроизводится полностью.Он играет только тогда, когда я удерживаю соответствующие кнопки, а затем останавливается, когда я отпускаю.Просматривая другие сайты, один из них сказал, что делает .isPressed () для аналогичной проблемы, но игровой экран просто становится черным, если я пытаюсь использовать это.Вот мой грязный и напряженный код, так что вы все можете мне помочь с надеждой.Я просто включу большую часть обновлений, потому что там может быть что-то, что мешает с чем-то другим.Плюс 3 других связанных метода.

    //Inside create
    blinkAni = knight.animations.add('teleport', [7, 8, 9, 10, 11, 12], 14);
    blinkAni.onComplete.add(blinkTele, this);
    
    canBlink = true;
}
    
function update(){
    var hitPlatform = game.physics.arcade.collide(knight, platforms);

    //------------------MOVEMENT--------------------------//

    //Teleport
    if (blink.isDown &&//These for blinking in current direction
        (moveBinds.leftA.isDown || moveBinds.rightD.isDown || moveBinds.upW.isDown || moveBinds.downS.isDown)) {
        knight.animations.play('teleport');
        
//        if(canBlink){
//            blinkTele();
//            canBlink = false;
//        }
    } else if (game.input.activePointer.leftButton.isDown) {
        knight.animations.play('teleport');
        if(canTele){
            cursorTele();
            //canTele = false;
        }
    }
    //Attack
    else if (attack.isDown) {
        knight.animations.play('attack');
    }
    //Move Left and Right
    else if (moveBinds.leftA.isDown) {
        knight.body.velocity.x = -400;
        knight.scale.setTo(-1, 1); //Knight faces left
        knight.animations.play('walk');
    } else if (moveBinds.rightD.isDown) {
        knight.body.velocity.x = 400;
        knight.scale.setTo(1, 1); //Knight faces right
        knight.animations.play('walk');
    } else {
        knight.animations.play('stand');
    }

    //Jump ------------NEEDS FIXING: touching.down->->->->Only works with actual ground and platforms, not world bounds. So make ground and //platform objects
    if (moveBinds.upW.isDown && knight.body.touching.down) {
        knight.body.velocity.y = -300;
    }

    //Stop moving left/right ------------NEEDS FIXING: touching.down->->->->->Ditto^^^
    if (moveBinds.downS.isDown && knight.body.touching.down) {
        knight.body.velocity.x = 0;
    }

    // Horizontal momentum kept and slowed down with drag
    speed = knight.body.velocity.x;
    if (speed > 0) {
        knight.body.velocity.x = Math.abs(speed - drag);
    } else if (speed < 0) {
        knight.body.velocity.x = speed + drag;
    } else {
        knight.body.velocity.x = 0;
    }
    //------------------END MOVEMENT--------------------------//
}

//Long teleportation
function cursorTele() {
    //In order to make it to where the knight's center/midpoint is wherever the mouse clicks, calculations are needed
    //if() facing right
    var newX = game.input.activePointer.x - knight.body.width/4;
    //^^With current spritesheet this is what has to be done in order to center width-wise^^
    var newY = game.input.activePointer.y - knight.body.height/2;
    //to prevent getting stuck in ground
    if (newY >= game.world.height - antiGroundStuck) {
        newY = game.world.height - antiGroundStuck;
    }
    teleport(newX, newY);
}


//Blink
function blinkTele(sprite, animation) {
    var newX = knight.body.x;
    var newY = knight.body.y;
    //if moving right add 10 to current pos
    if (moveBinds.rightD.isDown) {
        newX += blinkDist;
    }
    //else subtract 10
    else if (moveBinds.leftA.isDown) {
        newX -= blinkDist;
    }

    //if moving up subtract 10 to current pos
    else if (moveBinds.upW.isDown) {
        newY -= blinkDist;
    }
    //else add 10
    else if (moveBinds.downS.isDown) {
        newY += blinkDist;
        //check to not go below ground. Account for height of world and height of ground
        if (newY >= game.world.height - antiGroundStuck)
            newY = game.world.height - antiGroundStuck; //above or exactly at ground height
    }

    //        blinkTick--;

    //reset timer and tick if out of ticks
    //if(){
    //knight.body.y = 300;
    //            this.blinkTimer.destroy();
    //            blinkTimer = game.time.create(false);
    //            blinkTimer.start();
    //            blinkTick = 5;
    //      }
    teleport(newX, newY);
}

//Teleport
function teleport(newX, newY) {
    knight.body.x = newX;
    knight.body.y = newY;
    //Make teleporting look like actual teleporting
    knight.visibile = false;
    game.time.events.add(Phaser.Time.SECOND, this);
}

Любая помощь будет принята с благодарностью!Я боролся буквально весь день с этим: (

1 Ответ

0 голосов
/ 15 октября 2018

Я не совсем уверен, что это ответит на ваш вопрос, но это будет слишком долго для простого комментария:

  1. Есть ряд мест, где выпозвонив update() напрямую.Например, game.time.events.add(Phaser.Time.SECOND, update, this); и game.time.events.add(Phaser.Time.SECOND * 5, update, this);.При условии правильной настройки, update будет автоматически вызван Phaser, и нет необходимости вызывать его самостоятельно.Это, вероятно, вызывает проблемы.

  2. При определении анимаций вы также можете определить, что произойдет, когда они завершатся, или цикл.См. Официальную документацию для onComplete и onLoop.См. Также Пример анимационных событий для примера использования.Это было бы лучше, чем, например, ниже:

    knight.animations.play('teleport', 7, true);
    knight.visibile = false;
    game.time.events.add(4000, blinkTele, this);
    //canBlink = false;
    

После этого вы сможете связать их вместе, чтобы сделать то, что вы хотите.

Обновление

Вот краткий рабочий пример использования Phaser 2.4.4:

var game = new Phaser.Game(800, 600, Phaser.AUTO, '', {
	preload: preload, create: create, update: update
});

function preload() {
	this.load.crossOrigin = 'anonymous';
	game.load.image('sky', 'https://jamesskemp.github.io/PhaserTutorials/Official-Making-A-Game/assets/sky.png');
	game.load.image('platform', 'https://jamesskemp.github.io/PhaserTutorials/Official-Making-A-Game/assets/platform.png');
	game.load.spritesheet('dude', 'https://jamesskemp.github.io/PhaserTutorials/Official-Making-A-Game/assets/dude.png', 32, 48);
}

var platforms;
var player;
var cursors;

var leftAnimation;
var rightAnimation;
var canMove = true;

function create() {
	// Enable arcade physics.
	game.physics.startSystem(Phaser.Physics.ARCADE);

	// Background image.
	game.add.sprite(0, 0, 'sky');

	// Includes ground and the ledges.
	platforms = game.add.group();

	// Enable physics for all objects in this group.
	platforms.enableBody = true;

	// Create the ground.
	var ground = platforms.create(0, game.world.height - 64, 'platform');

	// Scale the image to fit the width of the game.
	ground.scale.setTo(2, 2);

	// Ground is solid and doesn't move.
	ground.body.immovable = true;

	// Create the player.
	player = game.add.sprite(32, game.world.height - 150, 'dude');

	// Enable physics on the player.
	game.physics.arcade.enable(player);
	player.body.bounce.y = 0.2;
	player.body.gravity.y = 300;
	player.body.collideWorldBounds = true;

	// Player has walk animations, at 10 frames per second.
	leftAnimation = player.animations.add('left', [0, 1, 2, 3], 10);
	rightAnimation = player.animations.add('right', [5, 6, 7, 8], 10);

	rightAnimation.onComplete.add(animationComplete, this);
	leftAnimation.onComplete.add(animationComplete, this);

	// Enable keyboard cursor support.
	cursors = game.input.keyboard.createCursorKeys();
}

function animationComplete() {
	console.log('animation complete, moving to random location');
	player.x = game.rnd.integerInRange(10, game.world.width - 10);
	canMove = true;
}

function update() {
	// The player and platforms should collide.
	game.physics.arcade.collide(player, platforms);

	// Reset the player's velocity.
	player.body.velocity.x = 0;

	if (canMove) {
		if (cursors.left.isDown) {
			canMove = false;
			// Move to the left.
			player.body.velocity.x = -150;
			player.animations.play('left');
		} else if (cursors.right.isDown) {
			canMove = false;
			// Move to the right.
			player.body.velocity.x = 150;
			player.animations.play('right');
		}
	}

	// Player can jump if they're touching ground.
	if (cursors.up.isDown && player.body.touching.down) {
		player.body.velocity.y = -350;
	}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/phaser/2.4.4/phaser.min.js"></script>

К сожалению, неизвестных переменных достаточно, чтобы я не смог воспроизвести ваш пример для проверки своих теорий, но я попытался бы установить переменную, когда вы запустите анимацию телепортации ипроверьте это в update.Сначала я бы попытался обернуть всю логику движения.

onComplete сработает только после завершения анимации, чего не произойдет, если запустится другая анимация, такая как ваша последняя else, где запускается knight.animations.play('stand');.

...