在Phaser 3中,只要一个对象与另一个对象发生碰撞,如何播放动画



我正在用Phaser3创建一个游戏,特别是用物质物理引擎。我希望只在一个对象与另一个对象碰撞时播放动画。

对象的代码(变量benchcreate()函数之前声明(

//Place a bench
bench = this.matter.add.sprite(2000, 200, 'sheet', 'bench', {shapes: shapes.bench});
bench.setScale(2, 1);
bench.setPosition(2250 + bench.centerOfMass.x, 200 + bench.centerOfMass.y);
//Needed this again so that bench can detect collisions
bench.isSensor(true);

当前代码

//Detect collision when we are on the bench, so we can play the grind animation
this.matter.world.on('collisionstart', function (grindNow, skater, bench) {
grind = true;
});

问题是,当玩家与地面碰撞时,上面的代码仍然将true记录到控制台,我只想在这里检测与bench对象的碰撞。我试过只在函数中播放动画,但也不起作用。我也试过

if (this) {
grind = true;
}
else {
grind = false;
}

然后尝试使用该变量来决定何时播放研磨动画,但这也没有帮助。最后,我尝试在create函数中播放动画,即使动画已经创建,它也总是返回undefined

我试过在函数中设置一个变量,只玩

我找到了一个解决方案,尽管我不知道你是否想使用它。我找到了这个插件,它使管理与Phaser的冲突变得更容易。

遵循以下步骤:

  • 首先,在game_index.html文件中添加此行<script src="//cdn.jsdelivr.net/npm/phaser-matter-collision-plugin"></script>如下:
<script src="//cdn.jsdelivr.net/npm/phaser-matter-collision-plugin"></script>
<script src= "skateboarding.js" ></script>
<script src = "archery.js"></script>
<script src = "soccer.js"></script>

如果要以其他方式安装,请阅读完整安装指南

  • 第二个,在config对象中添加以下代码片段:
plugins: {
scene: [
{
plugin: PhaserMatterCollisionPlugin, // The plugin class
key: "matterCollision", // Where to store in Scene.Systems, e.g. scene.sys.matterCollision
mapping: "matterCollision" // Where to store in the Scene, e.g. scene.matterCollision
}
]
},

现在,config对象应该如下所示:

//Game configurations
var config = {
type: Phaser.AUTO,
width: 1500, //<-- this is the width of what we will see at one time
height: gameHeight,
physics: physicsConfig,
plugins: {
scene: [
{
plugin: PhaserMatterCollisionPlugin, // The plugin class
key: "matterCollision", // Where to store in Scene.Systems, e.g. scene.sys.matterCollision
mapping: "matterCollision" // Where to store in the Scene, e.g. scene.matterCollision
}
]
},
scene: {
preload: preload,
create: create,
update: update
}   
}

第三,删除以下代码片段:

//Detect the player's collision with the ground
this.matter.world.on('collisionstart', function (onGround, skater, ground) {
//If the player is touching the ground, set this value to true
skaterTouchingGround = true;
});
//Detect collision when we are on the bench, so we can play the grind animation
this.matter.world.on('collisionstart', function (grindNow, skater, bench) {
grind = true;
});

第四个,在删除先前代码片段的同一位置添加以下代码块:

//Detect the player's collision with the ground
this.matterCollision.addOnCollideStart({
objectA: skater,
objectB: ground,
callback: () => skaterTouchingGround = true
});
//Detect collision when we are on the bench, so we can play the grind animation
this.matterCollision.addOnCollideStart({
objectA: skater,
objectB: bench,
callback: () =>  grind = true
});

现在,当触摸player触摸bench时,您应该能够获得打印在console中的grind的值。

供您参考,以下是完整的代码:

//Define our start button for out index page
var startButton = document.querySelector("#startSkate").addEventListener("click", () => {
//Delay in ms to remove our button
let removeDelay = 1;
//Call function to start the game
this.startSkateGame();
//Call the setTimeout method and define a function
setTimeout(function () {
//Get elements and remove them to clear the page
document.getElementById('startArch').remove();
document.getElementById('startSkate').remove();
document.getElementById('startSoccer').remove();
document.getElementById('logo').remove();
//Pass the delay
}, removeDelay);
});
//Define the function that we call when our start button is clicked
startSkateGame = () => {
//Configurations for the physics engine
var physicsConfig = {
default: 'matter',
matter : {
gravity: {
x: 0,
y: 2.5, // <--This is the only way I could get the skater to roll up the ramp.s
},
debug: true //CHANGE THIS TO TRUE TO SEE LINES
}   
}
//Variables for height and width
var gameHeight = 750;
var gameWidth = 5000;
//Game configurations
var config = {
type: Phaser.AUTO,
width: 1500, //<-- this is the width of what we will see at one time
height: gameHeight,
physics: physicsConfig,
plugins: {
scene: [
{
plugin: PhaserMatterCollisionPlugin, // The plugin class
key: "matterCollision", // Where to store in Scene.Systems, e.g. scene.sys.matterCollision
mapping: "matterCollision" // Where to store in the Scene, e.g. scene.matterCollision
}
]
},
scene: {
preload: preload,
create: create,
update: update
}   
}
/* This variable will be used to make sure the skater 
cannot ollie while he is already in the air */
var skaterTouchingGround;
var grind;
//Start the game
var game = new Phaser.Game(config);
//Declare variables so we can access them in all functions
var skater;
var ground;
var sky;
var bench;
//Score variables
let score = 0;
let scoreBoard;
function preload() {
//Images
this.load.image('sky', 'archery_assets/images/sky.png');
//Load sprites from TexturePacker
this.load.atlas('sheet', 'skate_assets/sprites.png', 'skate_assets/sprites.json');
//Load body shapes from PhysicsEditor
this.load.json('shapes', 'skate_assets/spritesPE.json');
}
function create() {
//Background
sky = this.add.image(2500, 325,'sky')
//Scale the image
sky.setDisplaySize(gameWidth, gameHeight);
//Get the hitboxes
var shapes = this.cache.json.get('shapes');
//Set world bounds    
this.matter.world.setBounds(0, 0, gameWidth, gameHeight);
//Place ground object
ground = this.matter.add.sprite(0, 0, 'sheet', 'ground', {shape: shapes.ground});
//Ground is 600x600, so double the x pixels and we get screen width
ground.setScale(8.5, 1);
ground.setPosition(2500, 650);
//Let the ground detect collisions 
ground.isSensor(true);
//Place the ramp
var ramp = this.matter.add.sprite(0, 0, 'sheet', 'ramp', {shape: shapes.ramp});
ramp.setPosition(550 + ramp.centerOfMass.x, 250 + ramp.centerOfMass.y);
//Place a bench
bench = this.matter.add.sprite(2000, 200, 'sheet', 'bench', {shapes: shapes.bench});
bench.setScale(2, 1);
bench.setPosition(2250 + bench.centerOfMass.x, 200 + bench.centerOfMass.y);
//Needed this again so that bench can detect collisions
bench.isSensor(true);
//Create the skater
skater = this.matter.add.sprite(0, 0, 'sheet', 'roll/0001', {shape: shapes.s0001});
skater.setPosition(100 + skater.centerOfMass.x, 200 + skater.centerOfMass.y);
//Collision filtering
var staticCategory = this.matter.world.nextCategory();
ramp.setCollisionCategory(staticCategory);
ground.setCollisionCategory(staticCategory);
bench.setCollisionCategory(staticCategory);
//Skater needs to be in a different category
var skaterCategory = this.matter.world.nextCategory();
skater.setCollisionCategory(skaterCategory);
//Roll animation
//Generate the frame names
var rollFrameNames = this.anims.generateFrameNames(
'sheet', {start: 1, end: 4, zeroPad: 4,
prefix: 'roll/'}
);
//Create the animation
this.anims.create({
key: 'roll', frames: rollFrameNames, frameRate: 16, repeat: -1
});
//Push animation
var pushFrameNames = this.anims.generateFrameNames(
'sheet', {start: 5, end: 8, zeroPad: 4,
prefix: 'push/'}
);
this.anims.create({
key: 'push', frames: pushFrameNames, frameRate: 16, repeat: 0 
});
//Shuvit animation
var shuvFrameNames = this.anims.generateFrameNames(
'sheet', {start: 9, end: 12, zeroPad: 4,
prefix: 'shuv/'}
);
this.anims.create({
key: 'shuv', frames: shuvFrameNames, frameRate: 32, repeat: 0 
});
//Ollie animation
var ollieFrameNames = this.anims.generateFrameNames(
'sheet', {start: 13, end: 20, zeroPad: 4,
prefix: 'ollie/'}
);
this.anims.create({
key: 'ollie', frames: ollieFrameNames, frameRate: 24, repeat: 0
});
//Kickflip animation
var kfFrameNames = this.anims.generateFrameNames(
'sheet', {start: 21, end: 33, zeroPad: 4,
prefix: 'kickflip/'}
);
this.anims.create({
key: 'kickflip', frames: kfFrameNames, frameRate: 24, repeat: 0
});
//Nosegrind  animation
var ngFrameNames = this.anims.generateFrameNames(
'sheet', {start: 34, end: 37, zeroPad: 4,
prefix: 'nosegrind/'}
);
this.anims.create({
key: 'nosegrind', frames: ngFrameNames, frameRate: 24, repeat: 0
});
//This keeps the rolling animation going once the push animation is done
skater.on('animationcomplete', () => {
skater.anims.play('roll');
});
//Input for arrowkeys
this.arrowKeys = this.input.keyboard.addKeys({
up: 'up',
down: 'down',
left: 'left',
right: 'right'
}); 
//Input for WASD keys
this.WASDkeys = this.input.keyboard.addKeys({
W: 'W',
A: 'A',
S: 'S',
D: 'D'
});
//Spacebar
this.spacebar = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.SPACE);
//Camera to follow the skater
this.cameras.main.setBounds(0, 0, gameWidth, gameHeight);
this.cameras.main.startFollow(skater);
//Detect the player's collision with the ground
this.matterCollision.addOnCollideStart({
objectA: skater,
objectB: ground,
callback: () => skaterTouchingGround = true
});
//Detect collision when we are on the bench, so we can play the grind animation
this.matterCollision.addOnCollideStart({
objectA: skater,
objectB: bench,
callback: () =>  grind = true
});
//Create the scoreboard as a container
scoreBoard = this.add.container(10, 50);
//Add text to this container, displaying our score
scoreText = this.add.text(10, 50, "SCORE: 0", {fontSize: '56px', color: '#fff'});
//Add the text to the container which will be our scoreboard
scoreBoard.add(scoreText);
//Make the scoreboard follow the player
this.tweens.add({
targets: scoreBoard,
ease: 'Linear',
duration: 1,
delay: 1,
yoyo: false,
repeat: -1
});
}
function update() {
console.log(skaterTouchingGround);
//Set variable for player movement
var pushSpeed = 0;
var ollie = 0;
//Make sure the player isn't doing anything if he's upside down, or crashed
let skaterCrashed;
//Variable to check the angle of the skater
let angleOkay = skater.angle > -89 && skater.angle < 89;
//Determine if the player is crashed or not
if (angleOkay) {
skaterCrashed = false;
}
else {
skaterCrashed = true;
window.alert("You crashed!");
}
//Starting parameter, as we don't want to do anything if we are crashed
if (!skaterCrashed) {
//Pushing
if (Phaser.Input.Keyboard.JustDown(this.spacebar) && skaterTouchingGround) {
//Increase speed
pushSpeed = 15;
//Move player
skater.setVelocityX(pushSpeed);
//Play push animation
skater.anims.play('push');
}
//Ollie
if (Phaser.Input.Keyboard.JustDown(this.arrowKeys.up) && skaterTouchingGround) {
//Set this to false, because we are about to jump
skaterTouchingGround = false;
//Set ollie power
ollie = -15;
//Set skate velocity
skater.setVelocityY(ollie);
//Play the ollie animation
skater.anims.play('ollie');
//Scoring for ollie
score += 1;
}
//Shuvit
if (Phaser.Input.Keyboard.JustDown(this.arrowKeys.down)) {
//Play the shuvit animation
skater.anims.play('shuv');
//Scoring for shuv
score += 3;
}
//Kickflip
if (Phaser.Input.Keyboard.JustDown(this.WASDkeys.W)  && skaterTouchingGround) {
//Reset variable since we are jumping
skaterTouchingGround = false
//Set jump height
ollie = -14
//Move the player
skater.setVelocityY(ollie);
//Play animation
skater.anims.play('kickflip');
//Scoring for kickflip
score += 10;
}
//Tilting backwards in the air
if (this.arrowKeys.left.isDown && !skaterTouchingGround) {
//Be able to turn backwards so you don't flip
skater.angle -= 3 ;
}
//Tilting forwards in the air
if (this.arrowKeys.right.isDown && !skaterTouchingGround) {
//Be able to turn forwards so you don't flip
skater.angle += 3 ;
}
}
//Move the scoreboard
scoreText.x = skater.body.position.x - 200;
scoreText.setText("SCORE : " + score);
}
}

最新更新