Phaser JS 走上基于瓷砖的楼梯
Phaser JS walk up tile based stairs
我正在 Phaser js 中创建一个小型 2d-minecraft 克隆,作为我自己的学习经验。到目前为止,我已经让玩家移动和随机关卡种子正常工作。
我正在使用 Phasers P2JS 引擎并且具有基于框的精灵。我现在正在努力的是我希望玩家能够不受阻碍地走上小海拔(1 瓦高),但我不知道应该如何实现它。
我曾尝试更改播放器的边界框,使其在底部有一个斜坡,但这让我在爬墙时遇到了一堆麻烦。我想要一种尽可能无缝的方式来做到这一点。最好玩家的速度不会因爬台阶而改变太多。
我正在考虑编写某种碰撞检测函数来处理这个问题,但我不确定这是否是最好的方法。
感谢您的帮助。
下面是我的代码和一张图片,显示了我希望能够走上去的那种台阶。它是图像左侧的第一个海拔高度。
var pablo = require('../generators/pablo.js');
var destiny = {};
var socket;
var player;
var jumpButton;
var levelCollisionGroup;
var playerCollisionGroup;
destiny.create = function () {
console.info("game loaded");
// World
this.game.world.setBounds(0, 0, 4000, 1000);
this.game.physics.startSystem(Phaser.Physics.P2JS);
this.game.physics.p2.gravity.y = 600;
this.game.physics.p2.applySpringForces= false;
this.game.physics.p2.applyDamping= false;
this.game.physics.p2.restitution = 0;
this.game.physics.p2.friction = 0.01;
// Player
playerCollisionGroup = this.game.physics.p2.createCollisionGroup();
player = this.game.add.sprite(this.game.world.centerX, 800, 'player');
this.game.physics.p2.enable(player,true);
player.body.fixedRotation = true;
player.body.setCollisionGroup(playerCollisionGroup);
player.body.mass = 2;
// Camera
this.game.camera.follow(player);
this.game.camera.deadzone = new Phaser.Rectangle(200, 0, 400, 100);
// Controls
jumpButton = this.game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR);
leftButton = this.game.input.keyboard.addKey(Phaser.Keyboard.A);
rightButton = this.game.input.keyboard.addKey(Phaser.Keyboard.D);
// Level
levelCollisionGroup = this.game.physics.p2.createCollisionGroup();
this.game.physics.p2.updateBoundsCollisionGroup();
for (i = 0; i < 280; i = i + 1) {
var block;
var height = pablo.getHeight(i);
for(j = 0; j < height; j = j + 1){
if(j === height-1){
block = this.game.add.sprite(15*i, 993-15*j, 'grass');
} else {
block = this.game.add.sprite(15*i, 993-15*j, 'dirt');
}
block.width = 15;
block.height = 15;
this.game.physics.p2.enable(block);
block.body.static=true;
block.body.immovable = true;
block.body.collides([levelCollisionGroup, playerCollisionGroup]);
block.body.setCollisionGroup(levelCollisionGroup);
if(j == height){
}
}
}
player.body.collides(levelCollisionGroup);
this.game.stage.backgroundColor = "#5599CC";
};
destiny.update = function() {
player.body.velocity.x=0;
if (leftButton.isDown) {
player.body.velocity.x = -200;
} else if (rightButton.isDown) {
player.body.velocity.x = 200;
}
if (jumpButton.isDown && this.checkIfCanJump()) {
player.body.velocity.y = -400;
}
};
destiny.render = function() {
this.game.debug.cameraInfo(this.game.camera, 32, 32);
this.game.debug.spriteCoords(player, 32, 550);
};
destiny.checkIfCanJump = function() {
var result = false;
for (var i=0; i < this.game.physics.p2.world.narrowphase.contactEquations.length; i++) {
var c = this.game.physics.p2.world.narrowphase.contactEquations[i];
if (c.bodyA === player.body.data || c.bodyB === player.body.data) {
var d = p2.vec2.dot(c.normalA, p2.vec2.fromValues(0, 1));
if (c.bodyA === player.body.data) {
d *= -1;
}
if (d > 0.5) {
result = true;
}
}
}
return result;
};
module.exports = destiny;
=====================编辑=====================
我现在尝试在生成世界时创建边缘块的斜率。但我意识到,当我后来添加破解块的功能时,这让我不得不重新生成世界。因此这不是解决方案。我想我需要做一些碰撞检测并在我碰到边缘时将播放器向上移动。但我不太确定如何在移相器中执行此操作。仍然感谢任何帮助。
!!!这是不该做什么的图片!!!
Emanuele Feronato post on replicating the game Magick in Phaser.
在那里,他介绍了一个方块与 barrier/wall 碰撞的情况,以及方块向上爬一级的能力。
你可以查看教程,但他似乎在检查对角线瓷砖是否为空(换句话说,它只是一个 'step' 向上),如果是, 运行一个'jump'函数,看起来更像一个攀登。
根据您希望角色如何迈步,您可能会同时查看下一个图块(在 x 轴上)以及它之后的图块以检查高度。
因此,例如,如果向右移动,下一个瓷砖是平坦的,但第二个瓷砖有一个台阶,您可能会开始在 y 轴上向上移动您的角色。
我正在 Phaser js 中创建一个小型 2d-minecraft 克隆,作为我自己的学习经验。到目前为止,我已经让玩家移动和随机关卡种子正常工作。
我正在使用 Phasers P2JS 引擎并且具有基于框的精灵。我现在正在努力的是我希望玩家能够不受阻碍地走上小海拔(1 瓦高),但我不知道应该如何实现它。
我曾尝试更改播放器的边界框,使其在底部有一个斜坡,但这让我在爬墙时遇到了一堆麻烦。我想要一种尽可能无缝的方式来做到这一点。最好玩家的速度不会因爬台阶而改变太多。
我正在考虑编写某种碰撞检测函数来处理这个问题,但我不确定这是否是最好的方法。
感谢您的帮助。
下面是我的代码和一张图片,显示了我希望能够走上去的那种台阶。它是图像左侧的第一个海拔高度。
var pablo = require('../generators/pablo.js');
var destiny = {};
var socket;
var player;
var jumpButton;
var levelCollisionGroup;
var playerCollisionGroup;
destiny.create = function () {
console.info("game loaded");
// World
this.game.world.setBounds(0, 0, 4000, 1000);
this.game.physics.startSystem(Phaser.Physics.P2JS);
this.game.physics.p2.gravity.y = 600;
this.game.physics.p2.applySpringForces= false;
this.game.physics.p2.applyDamping= false;
this.game.physics.p2.restitution = 0;
this.game.physics.p2.friction = 0.01;
// Player
playerCollisionGroup = this.game.physics.p2.createCollisionGroup();
player = this.game.add.sprite(this.game.world.centerX, 800, 'player');
this.game.physics.p2.enable(player,true);
player.body.fixedRotation = true;
player.body.setCollisionGroup(playerCollisionGroup);
player.body.mass = 2;
// Camera
this.game.camera.follow(player);
this.game.camera.deadzone = new Phaser.Rectangle(200, 0, 400, 100);
// Controls
jumpButton = this.game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR);
leftButton = this.game.input.keyboard.addKey(Phaser.Keyboard.A);
rightButton = this.game.input.keyboard.addKey(Phaser.Keyboard.D);
// Level
levelCollisionGroup = this.game.physics.p2.createCollisionGroup();
this.game.physics.p2.updateBoundsCollisionGroup();
for (i = 0; i < 280; i = i + 1) {
var block;
var height = pablo.getHeight(i);
for(j = 0; j < height; j = j + 1){
if(j === height-1){
block = this.game.add.sprite(15*i, 993-15*j, 'grass');
} else {
block = this.game.add.sprite(15*i, 993-15*j, 'dirt');
}
block.width = 15;
block.height = 15;
this.game.physics.p2.enable(block);
block.body.static=true;
block.body.immovable = true;
block.body.collides([levelCollisionGroup, playerCollisionGroup]);
block.body.setCollisionGroup(levelCollisionGroup);
if(j == height){
}
}
}
player.body.collides(levelCollisionGroup);
this.game.stage.backgroundColor = "#5599CC";
};
destiny.update = function() {
player.body.velocity.x=0;
if (leftButton.isDown) {
player.body.velocity.x = -200;
} else if (rightButton.isDown) {
player.body.velocity.x = 200;
}
if (jumpButton.isDown && this.checkIfCanJump()) {
player.body.velocity.y = -400;
}
};
destiny.render = function() {
this.game.debug.cameraInfo(this.game.camera, 32, 32);
this.game.debug.spriteCoords(player, 32, 550);
};
destiny.checkIfCanJump = function() {
var result = false;
for (var i=0; i < this.game.physics.p2.world.narrowphase.contactEquations.length; i++) {
var c = this.game.physics.p2.world.narrowphase.contactEquations[i];
if (c.bodyA === player.body.data || c.bodyB === player.body.data) {
var d = p2.vec2.dot(c.normalA, p2.vec2.fromValues(0, 1));
if (c.bodyA === player.body.data) {
d *= -1;
}
if (d > 0.5) {
result = true;
}
}
}
return result;
};
module.exports = destiny;
=====================编辑=====================
我现在尝试在生成世界时创建边缘块的斜率。但我意识到,当我后来添加破解块的功能时,这让我不得不重新生成世界。因此这不是解决方案。我想我需要做一些碰撞检测并在我碰到边缘时将播放器向上移动。但我不太确定如何在移相器中执行此操作。仍然感谢任何帮助。
!!!这是不该做什么的图片!!!
Emanuele Feronato post on replicating the game Magick in Phaser.
在那里,他介绍了一个方块与 barrier/wall 碰撞的情况,以及方块向上爬一级的能力。
你可以查看教程,但他似乎在检查对角线瓷砖是否为空(换句话说,它只是一个 'step' 向上),如果是, 运行一个'jump'函数,看起来更像一个攀登。
根据您希望角色如何迈步,您可能会同时查看下一个图块(在 x 轴上)以及它之后的图块以检查高度。
因此,例如,如果向右移动,下一个瓷砖是平坦的,但第二个瓷砖有一个台阶,您可能会开始在 y 轴上向上移动您的角色。