My take on handling slopes with Phaser and ARCADE physics
Talking about Jet Set Willy game, Game development, HTML5, Javascript and Phaser.
Do you like my tutorials?
Then consider supporting me on Ko-fi.
var game;
var heroSpeed = 50;
var heroGravity = 400;
window.onload = function() {
game = new Phaser.Game(480, 320, Phaser.AUTO, "");
game.state.add("PlayGame", playGame);
game.state.start("PlayGame");
}
var playGame = function(game){};
playGame.prototype = {
preload: function(){
game.load.spritesheet("hero", "hero.png", 20, 32);
game.load.image("floor", "floor.png");
game.load.image("slope", "slope.png");
game.load.image("big", "big.png");
},
create: function(){
// the floor, an ARCADE immovable body
this.floor = game.add.sprite(0, game.height - 32, "floor");
game.physics.enable(this.floor, Phaser.Physics.ARCADE);
this.floor.body.immovable = true;
// the big rock, an ARCADE immovable body
this.big = game.add.sprite(game.width -100, game.height - 132, "big");
game.physics.enable(this.big, Phaser.Physics.ARCADE);
this.big.body.immovable = true;
// the slope, an ARCADE immovable body
this.slope = game.add.sprite(game.width - 200, game.height - 132, "slope");
game.physics.enable(this.slope, Phaser.Physics.ARCADE);
this.slope.body.immovable = true;
// the hero
this.hero = game.add.sprite(32, game.height / 2, "hero");
this.hero.anchor.set(0.5);
this.hero.goingRight = false;
this.hero.goingLeft = false;
this.hero.idleFrame = 0;
game.physics.enable(this.hero, Phaser.Physics.ARCADE);
this.hero.body.gravity.y = heroGravity;
// animations and controls, check
// http://emanueleferonato.com/2016/05/02/understanding-html5-sprite-animation-with-phaser/
// for full information
var walkRightAnimation = this.hero.animations.add("walkRight", [0, 1, 2, 3]);
var walkLeftAnimation = this.hero.animations.add("walkLeft", [4, 5, 6, 7]);
this.rightKeyPressed = game.input.keyboard.addKey(Phaser.Keyboard.X);
this.leftKeyPressed = game.input.keyboard.addKey(Phaser.Keyboard.Z);
this.rightKeyPressed.onDown.add(function(){
this.hero.goingRight = true;
}, this);
this.rightKeyPressed.onUp.add(function(){
this.hero.goingRight = false;
}, this);
this.leftKeyPressed.onDown.add(function(){
this.hero.goingLeft = true;
}, this);
this.leftKeyPressed.onUp.add(function(){
this.hero.goingLeft = false;
}, this);
},
update: function(){
// normal ARCADE collision management between the hero and the floor + the hero and the big rock
game.physics.arcade.collide(this.hero, this.floor);
game.physics.arcade.collide(this.hero, this.big);
// with the slope we look for intersection instead
if(game.physics.arcade.intersects(this.hero, this.slope)){
// this is to compare horizontal offset between the hero and the slope
var dX = this.hero.x + this.hero.width / 2 - this.slope.x;
// we manually modify y property of the hero, no need to use trigonometry as it's a 45 degrees angle
this.hero.y = this.slope.y + this.slope.height - this.hero.height / 2 - dX
// and we set gravity to zero
this.hero.body.gravity.y = 0;
}
else{
// if we aren't on the slope, set the gravity to its default value
this.hero.body.gravity.y = heroGravity;
}
if(this.hero.goingRight && !this.hero.goingLeft){
this.hero.animations.play("walkRight", 10, true);
this.hero.body.velocity.x = heroSpeed
this.hero.idleFrame = 0;
}
else{
if(!this.hero.goingRight && this.hero.goingLeft){
this.hero.animations.play("walkLeft", 10, true);
this.hero.body.velocity.x = -heroSpeed;
this.hero.idleFrame = 4;
}
else{
this.hero.frame = this.hero.idleFrame;
this.hero.body.velocity.x = 0;
}
}
}
}
Never miss an update! Subscribe, and I will bother you by email only when a new game or full source code comes out.