This is more of a logic question than a Phaser 3 question. I am trying to make the game 'snake'. I can move 1 body up, down, left, and right easily, however, I do have issues when there is more than 1 body of 'snake'. In snake, when the front of a snake switches directions, the others follow suit in such a way so that they stay behind the snake. I cannot seem to figure out how to do this- changing the direction respectively for all of the 'other' bodies behind the 'snake'. In short, this is basically one sprite following another sprite. I would appreciate some help on this. Here is my code so far:
create() {
this.snake = this.physics.add.group()
this.front = this.snake.create(25,25,"tile").setScale(0.12)
}
This is where I create my snake, as well as the 'front' of the snake.
update() {
this.cursors = this.input.keyboard.createCursorKeys()
if (this.cursors.right.isDown) {
this.x_vel = this.vel
this.y_vel = 0
this.DIRECTION = "right"
} if (this.cursors.left.isDown) {
this.x_vel = -this.vel
this.y_vel = 0
this.DIRECTION = "left"
} if (this.cursors.up.isDown) {
this.x_vel = 0
this.y_vel = -this.vel
this.DIRECTION = "up"
} if (this.cursors.down.isDown) {
this.x_vel = 0
this.y_vel = this.vel
this.DIRECTION = "down"
}
this.front.x += this.x_vel
this.front.y += this.y_vel
}
This is how I will move my snake. I am only moving the 'front' of the snake because I want all of the other snake 'bodies' to follow the 'front' of the snake.
I have tried looking at other snake projects, especially those on phaser discussions and on medium, but they don't go over the details that much and I have trouble following their code.
In short, I would appreciate any hints or pointers you'd give me. Thanks in advance.
There are many different way's to do this, one easy solution is the way show on an official phaser game example (It uses the old Phaser "class" creation, but the idea is still the same)
Basically just use the built-in function Phaser.Actions.ShiftPosition
here is the link to the documentation. This function shifts the position of all items in array, to the last position of the previous item. So basically this function hast all the logic, and move the snake.
You just need to create a Group
(or you can use an array) with the body parts and pass it to the function, and the function will take care of moving each child.
Phaser.Actions.ShiftPosition(myObjects, 400, 300);
Phaser.Actions.ShiftPosition(...)
is the function to call
myObjects
is the list of snake parts you want to move
400,300
should be the new position for the first item in the Array
Tipp: In your posted code, I would move this line
this.cursors = this.input.keyboard.createCursorKeys()
into thecreate
function, since you just have to setthis.cursor
once.
Here is a Short Demo:
(ShowCasing the shifting array)
const COLORS = [ 0x9bbc0f, 0x8bac0f, 0x306230, 0x0f380f ];
class DemoScene extends Phaser.Scene {
preload(){
//create texture for the demo
let graphics = this.make.graphics();
graphics.fillStyle( 0xff0000 );
graphics.fillRect(0, 0, 8, 8);
graphics.generateTexture(`texture`, 8, 8);
}
create () {
this.add.text(10,10,'Demo');
this.snake = this.add.group();
// create head
this.snake.create(100, 100, 'texture');
// body part1
this.snake.create(90, 100, 'texture');
// body part2
this.snake.create(80, 100, 'texture');
// move timer
this.lastStep = 0
}
update (delta) {
//movement should be improved, this is just for the demo
if(this.lastStep + 10 < delta ){
let bodyParts = this.snake.getChildren();
let {x, y} = bodyParts[bodyParts.length - 1];
// here the magic happens
Phaser.Actions.ShiftPosition( bodyParts, bodyParts[0].x + 1, bodyParts[0].y)
this.lastStep = delta
}
}
}
var config = {
width: 540,
height: 180,
scene: DemoScene,
};
new Phaser.Game(config);
console.clear();
document.body.style = 'margin:0;';
<script src="//cdn.jsdelivr.net/npm/phaser/dist/phaser.min.js"></script>