简体   繁体   中英

Phaser JS walk up tile based stairs

I'm creating a small 2d-minecraft clone, in Phaser js, on my own as a learning experience. So far I have gotten player movement and random level seeds to work ok.

I am using Phasers P2JS engine and have sprites that are box based. What I'm struggling with now Is I want the player to be able to walk unhindered up small elevations, (1-tile high) but I don't have any good idea of how I should Implement this.

I have tried changing the bounding box of the player so that it had a slope at the bottom but this gets me in to a bunch of trouble with wall climbing. I want a way to do this where it gets as seamless as possible. Preferably the player speed is not altered much by climbing the steps.

I am concidering writing some kind of collision detection function to handle this but I am uncertain if this is the best way to do it.

Thanks for your help.

Below is my code and an image that shows the kind of step I want to beable to walk up. Its the first elevation to the left in the image.

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;

在此处输入图片说明

===================== Edit =====================

I have now tried creating slopes of the edge pieces when generating the world. But I realized that this makes me have to regenerate the world when I later add the feature for hacking away blocks. Thus this is not the solution. I think I will need to do some collision detection and move the player up when I hit an edge. But I'm not quite sure how to do this in phaser. Any help is still appreciated.

!!! Here is an image of what not to do !!!

在此处输入图片说明

Emanuele Feronato has a post on replicating the game Magick in Phaser .

There he covers the case of a block colliding with a barrier/wall, with the ability of the block to climb one level up.

You can check the tutorial, but what he appears to be doing is checking to see if the diagonal tile is empty (in other words, is it just a 'step' up), and if it is, running a 'jump' function, which looks more like a climb.

Depending upon how you want your character to step, you could potentially look at both the next tile (on the x-axis) as well as the one after it to check for the height.

So for example, if moving right and the next tile is flat, but the second tile has a step, you might start moving your character up on the y-axis.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM