I'm making a game in JavaScript, but in the class power ups, I want to create a power up each minute. The problem is that it's called in the update
method of the class, and this is called each frame in the main update, so once it runs, it doesn't stop again and keeps looping. How can I make it stop and start again?
I was trying with getting the seconds like this:
Method create power up:
let time = new Date.getSeconds();
if (time >=59) {create power up}
Method update of the power up class:
this.createpowerup();
Now in the main class I call all update methods from the classes that I have:
update() {
this.player_spaceship_object.update();
this.enemy_spaceship_object.update();
this.power_up_object.update();
this.movebackground();
}
So each frame it will be calling them, but the problem is when power up ends in zero, it creates a lot of power ups until it starts 1, theres like milliseconds to start 1, how can do this in a loop?
Power up class:
class Power_ups extends Phaser.GameObjects.Sprite {
constructor(scene) {
super(scene, scene.player_spaceship.x, scene.player_spaceship.y, "power_up");
//this.hi();
}
hi() {
setInterval(this.hola,5000);
}
hola() {
console.log("hola");
}
update() {
this.hi();
}
}
Main class, this is the class that runs once enter to the page:
class Scene2 extends Phaser.Scene {
constructor() {
super("Scene2");
}
create() {
this.scoreText;
this.timedEvent;
this.background = this.add.tileSprite(0,0,globalThis.config.width,globalThis.config.height,"space");
this.background.setOrigin(0,0);
this.player_spaceship = this.physics.add.sprite(globalThis.config.width/2-50,globalThis.config.height/2,"player_spaceship");
this.player_spaceship_object = new Player_spaceship(this);
this.enemy_spaceship_group = this.physics.add.group();
this.enemy_spaceship_object = new Enemy_spaceship(this);
this.physics.add.collider(this.player_spaceship,this.enemy_spaceship_group,this.collision_player_enemy,null,this);
this.power_up;
this.power_up_object = new Power_ups(this);
this.power_up_object.createpowerUp();
}
collision_player_enemy(player, enemy) { //parameters tells the function the objects that will collide
this.player_spaceship_object.damage();
this.enemy_spaceship_object.resetShip(enemy);
}
movebackground(bool = "") {
this.background.tilePositionY = (bool === true) ? this.background.tilePositionY += 1 : this.background.tilePositionY -= 1;
}
update() {
this.player_spaceship_object.update();
this.enemy_spaceship_object.update();
this.power_up_object.update();
this.movebackground();
}
}
I'm making a game in JavaScript, but in the class power ups, I want to create a power up each minute. The problem is that it's called in the update
method of the class, and this is called each frame in the main update, so once it runs, it doesn't stop again and keeps looping. How can I make it stop and start again?
I was trying with getting the seconds like this:
Method create power up:
let time = new Date.getSeconds();
if (time >=59) {create power up}
Method update of the power up class:
this.createpowerup();
Now in the main class I call all update methods from the classes that I have:
update() {
this.player_spaceship_object.update();
this.enemy_spaceship_object.update();
this.power_up_object.update();
this.movebackground();
}
So each frame it will be calling them, but the problem is when power up ends in zero, it creates a lot of power ups until it starts 1, theres like milliseconds to start 1, how can do this in a loop?
Power up class:
class Power_ups extends Phaser.GameObjects.Sprite {
constructor(scene) {
super(scene, scene.player_spaceship.x, scene.player_spaceship.y, "power_up");
//this.hi();
}
hi() {
setInterval(this.hola,5000);
}
hola() {
console.log("hola");
}
update() {
this.hi();
}
}
Main class, this is the class that runs once enter to the page:
class Scene2 extends Phaser.Scene {
constructor() {
super("Scene2");
}
create() {
this.scoreText;
this.timedEvent;
this.background = this.add.tileSprite(0,0,globalThis.config.width,globalThis.config.height,"space");
this.background.setOrigin(0,0);
this.player_spaceship = this.physics.add.sprite(globalThis.config.width/2-50,globalThis.config.height/2,"player_spaceship");
this.player_spaceship_object = new Player_spaceship(this);
this.enemy_spaceship_group = this.physics.add.group();
this.enemy_spaceship_object = new Enemy_spaceship(this);
this.physics.add.collider(this.player_spaceship,this.enemy_spaceship_group,this.collision_player_enemy,null,this);
this.power_up;
this.power_up_object = new Power_ups(this);
this.power_up_object.createpowerUp();
}
collision_player_enemy(player, enemy) { //parameters tells the function the objects that will collide
this.player_spaceship_object.damage();
this.enemy_spaceship_object.resetShip(enemy);
}
movebackground(bool = "") {
this.background.tilePositionY = (bool === true) ? this.background.tilePositionY += 1 : this.background.tilePositionY -= 1;
}
update() {
this.player_spaceship_object.update();
this.enemy_spaceship_object.update();
this.power_up_object.update();
this.movebackground();
}
}
Share
Improve this question
edited Sep 15, 2020 at 23:32
James Skemp
8,6019 gold badges70 silver badges112 bronze badges
asked Jul 4, 2020 at 4:48
plusplus
3653 silver badges14 bronze badges
5
- try setInterval, w3schools./jsref/met_win_setinterval.asp – R Pasha Commented Jul 4, 2020 at 4:50
- tried it doesnt work either – plus Commented Jul 4, 2020 at 4:50
- how did it fail? you got error? please post your code – R Pasha Commented Jul 4, 2020 at 4:53
- "doesn't work either" ... well it is the correct tool for the job so show us what you actually tried along with errors encountered If you read the documentation will also see there is a clearInterval() method. Also see how to create minimal reproducible example – charlietfl Commented Jul 4, 2020 at 4:54
- As you have a loop just take the delta of Date.now() and the last saved time in ms – Estradiaz Commented Jul 4, 2020 at 8:05
3 Answers
Reset to default 4You have a couple options with Phaser 3.
First, you could certainly add some logic to the built-in update()
functionality in the scene. However, if you do so you'll need to manually keep track of the last time you added a powerup, and when you need to add another one.
For example, you might add a property to the scene to track the next time a powerup should be added, and then if the current time is equal to or after that, create a powerup, and then update the property value (current time + 1 minute).
An easier method is likely to use Phaser 3's built-in timer functionality.
On your scene, add a property to keep track of the TimerEvent
, as this will allow you to later pause or stop it.
Next, in the scene's create()
create the timer event.
TypeScript example:
export default class MainGame extends Phaser.Scene {
// Store the timer so we can access it later.
private triggerTimer: Phaser.Time.TimerEvent;
public create(): void {
// ...
this.triggerTimer = this.time.addEvent({
callback: this.timerEvent,
callbackScope: this,
delay: 60000, // 1000 = 1 second
loop: true
});
// ...
}
public timerEvent(): void {
console.log('timerEvent');
// Create your new object here.
}
}
Either way, in your game sprite you should remove the functionality in update()
that triggers hi()
, as this effectively results in your sprites creating new timers every time the scene (and therefore each sprite) updates.
If you want an event to trigger x seconds after a sprite is created, you should define the timer (via setInterval
or a Phaser timer) in the constructor
instead.
You need to use setInterval
,
See example hope it will help you.
function update(){
console.log("your code");
}
setInterval(update, 2000);
I stringly remend using requestAnimationFrame in order to have a slightly better timing between your UI and logic.
function powerUpEveryMinute() {
// powerUp!!!!
setTimeout(() => {
requestAnimationFrame(powerUpEveryMinute);
}, 60000);
}
requestAnimationFrame(powerUpEveryMinute);
This will call the animationFrame API. First it runs your power up, waits 1 minute and then calls the animationFrame API again with the same function and power up will be called 1 minute after this first one.
Let me know if this works