I’m very new to Phaser and I’m working on a simple platformer to get comfortable with the basics. What I want is a group of 15 stars that the player can collect, and I want them to spawn at random xy coordinates. Each time the player collects all 15, the stars will reset to new xy coordinates. I’ve got it working pretty well, except some of the stars spawn in front of the platforms. I want them to only spawn where there’s no other tiles. Here’s a screenshot illustrating the problem:
I’ve tried various colliders, overlaps, I’ve tried adding a function for relocating any stars that overlap the platform layers, I’ve tried adding a function for removing stars that overlap, but none of those have worked. How can I make this work?
Here is my current code:
import stage1 from '/assets/scenes/stage1.js';
var config = {
type: Phaser.AUTO,
width: 800,
height: 480,
backgroundColor: '#007396',
scale: {
scale: 'SHOW_ALL',
orientation: 'LANDSCAPE'
},
resolution: window.devicePixelRatio,
physics: {
default: 'arcade',
arcade: {
gravity: { y: 500 },
debug: true
}
},
parent: 'gamewindow',
scene: [stage1]
};
var game = new Phaser.Game(config);
export default class stage1 extends Phaser.Scene {
constructor() {
super({
key: 'stage1'
});
}
preload() {
this.load.spritesheet('dude', '../assets/dude.png',
{
frameWidth: 32,
frameHeight: 48
});
this.load.image('star', '../assets/star.png');
this.load.image('tileset', '../assets/area01_level_tiles.png');
this.load.tilemapTiledJSON('map', '../area01.json');
}
create() {
//establish scoreboard
this.scoreText = this.add.text(16, 16, 'Score: ', {
fontFamily: 'Rationale',
fontSize: '50px',
fill: '#fff'
});
this.scoreText.setText('Score: ' + 0);
this.score = 0;
const map = this.make.tilemap({
key: 'map', //from load
tileWidth: 32,
tileHeight: 32
});
//establish level tileset
const tileset = map.addTilesetImage('area01_level_tiles', 'tileset');
//establish layers
const backgroundLayer = map.createStaticLayer('background (go in front of)', tileset, 0, 0);
const foregroundLayer = map.createStaticLayer('foreground (walk on)', tileset, 0, 0);
foregroundLayer.setCollisionByExclusion(-1, true);
//establish star group
this.stars = this.physics.add.group({
key: 'star',
allowGravity: false,
repeat: 14,
//setXY: {x: 100, y: 0, stepX: 70}
});
this.stars.children.iterate(function(child){
for (var i = 0; i < 13; i++){
var xPos = Phaser.Math.Between(100, map.widthInPixels);
var yPos = Phaser.Math.Between(0, 200);
child.x = xPos;
child.y = yPos;
child.setOrigin(0,0);
//this.child.setX(xPos);
//this.child.setY(yPos);
}
});
//add player
this.dude = this.physics.add.sprite(20, 0, 'dude', 4); //the 4 tells phaser to start from the 4th frame
this.dude.setBounce(0.2);
//put the front layer declaration after adding player sprite so sprite renders between this and platform layer
const frontLayer = map.createStaticLayer('front (go behind)', tileset, 0, 0);
//add player-platform collisions
this.dude.setCollideWorldBounds(true);
this.physics.add.collider(this.dude, foregroundLayer);
//set world bounds to follow camera bounds
this.physics.world.setBounds(0, 0, map.widthInPixels, map.heightInPixels);
//add player collision with stars
this.physics.add.overlap(this.dude, this.stars, this.getStar, null, this);
//establish camera
this.cameras.main.setBounds(0, 0, map.widthInPixels, map.heightInPixels);
//establish camera follow
this.cameras.main.startFollow(this.dude);
//establish anim
this.anims.create({
key: 'left',
frames: this.anims.generateFrameNumbers('dude', {start: 0, end: 3}),
frameRate: 10,
repeat: -1
});
this.anims.create({
key: 'turn',
frames: [{key: 'dude', frame: 4}],
frameRate: 20
});
this.anims.create({
key: 'right',
frames: this.anims.generateFrameNumbers('dude', {start: 5, end: 8}),
frameRate: 10,
repeat: -1
});
//adding cursor keys
this.cursors = this.input.keyboard.createCursorKeys();
}
update(time, delta) {
this.runBoyRun();
}
runBoyRun() {
if (this.cursors.left.isDown) {
this.dude.setVelocityX(-160);
this.dude.anims.play('left', true);
} else if (this.cursors.right.isDown) {
this.dude.setVelocityX(160);
this.dude.anims.play('right', true);
} else {
this.dude.setVelocityX(0);
this.dude.anims.play('turn');
}
if (this.cursors.up.isDown && Phaser.Input.Keyboard.JustDown(this.cursors.up)) {
this.dude.setVelocityY(-330);
}
}
getStar(dude, star) {
star.disableBody(true, true);
this.score += 1;
this.scoreText.setText('Score: ' + this.score);
if (this.stars.countActive(true) === 0)
{
this.stars.children.iterate(function (child) {
child.enableBody(true, child.x, child.y, true, true);
});
}
}
}