如何在Phaser.io的按键上完整制作动画

时间:2018-10-14 02:18:29

标签: javascript phaser-framework

因此,我浏览了一些视频,一些提出相同问题的网站,甚至是phaser.io自己的示例代码,但我仍然坚持无法通过按键使动画完全完成。我想我有移相器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 :(得分:0)

我不完全确定这会回答您的问题,但是仅仅发表评论就太久了:

  1. 您可以在许多地方直接致电update()。例如,game.time.events.add(Phaser.Time.SECOND, update, this);game.time.events.add(Phaser.Time.SECOND * 5, update, this);。假设设置正确,update将自动被Phaser调用,而无需自己调用。这可能会引起问题。

  2. 在定义动画时,您还可以定义动画完成或循环时将发生的情况。请参阅onCompleteonLoop的官方文档。有关用法示例,另请参见Animation Events example。例如,这会比以下更好:

    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的{​​{1}}。