I have custom buttons on game screen(Y, X, B, A) and metronome time event(1 tact in 1 second). How can i do for example this combo: А| А| YY| A ? Buttons must be pressed in metronome tact.
My metronome and buttons code:
export default class DemoScene extends Phaser.Scene {
constructor() {
super(‘Demo’);
this.canClick = false;
}
create() {
this.metronome();
new ControllButtnos(this);
}
update() {
if (
Math.floor(this.metronomeTween.getElapsed()) >= 900 ||
(Math.floor(this.metronomeTween.getElapsed()) >= 0 &&
Math.floor(this.metronomeTween.getElapsed()) <= 150)
) {
this.canClick = true;
} else {
this.canClick = false;
}
}
metronome() {
const border = this.add.graphics();
border.lineStyle(3, 0xffffff, 1);
border.strokeRect(
5,
5,
this.sys.game.config.width - 10,
this.sys.game.config.height - 10
);
const borderTween = this.tweens.add({
targets: border,
alpha: 0,
duration: 500,
repeat: 0,
yoyo: false
});
borderTween.pause();
this.metronomeTween = this.time.addEvent({
delay: 1000,
callback: () => {
borderTween.play();
},
loop: true
});
}
}
Buttons Class:
export default class ControlButtons extends Phaser.GameObjects.Group {
constructor(scene) {
super(scene);
this.scene = scene;
this.createButtons();
}
createButtons() {
// Controll buttons events
buttonY.on('pointerdown', () => {
console.log('Y');
});
buttonX.on('pointerdown', () => {
console.log(this.scene.canClick);
if (this.scene.canClick) {
console.log(Math.floor(this.scene.metronomeTween.getElapsed()));
}
});
buttonB.on('pointerdown', () => {
console.log('B');
});
buttonA.on('pointerdown', () => {
console.log('A');
});
}
}
I see many flaws in your code I dont know how to help Is this code working for you?
One possible solution can be to implement a state machine working on states…
so from a=>b b=>c d=> etx and in then in update work with time state.go(b,(deltatime)=> if(deltatime etx)
return true.
I worked with rxjs too maybe it is more simple you just measure the scanned accumulated time between every click, but I dont know how to use it with phaser uum maybe try this
Thanks for the answer. I have laid out only the necessary part of the code from the class, since I do not want to put some details on a general review (this is a commercial project). Yes, this code works. If you can give a more detailed answer, I can send you the full code.
Okay, I dont know other way than i mentioned…
try to explain more detailed how it supposed to work, like in math., every second i get 0,2 sec time to click and next click accumulates till i miss click and break the combo?
I am clueless Mate
This is me just spit-balling here, but if I was to approach this I would at least consider simply recording every button press along with a “timestamp” (probably your own in-game millisecond counter) of when that button was pressed. Then I would analyze this stream of presses to see what was on the metronome and what wasn’t. This is oftentimes how other timing-based key combinations such as special moves in fighting games are handled, rather than trying to write logic to determine at the time of press if a special move was performed.
Hi @AntonPiniaz,
A possible solution would be to use a string in which both the metronome and the pressed keys will modify it.
This string would be verified from the metronome in each tac.
In this code I am using the cursors and looking for the combo “L | L | RR | L” (left left right …):
class GameScene extends Phaser.Scene{
constructor(){
super('gameScene');
}
create(){
this.combo = '';
this.metronome();
this.cursors = this.input.keyboard.createCursorKeys();
this.info = this.add.text(100,100,'');
}
update(){
if(Phaser.Input.Keyboard.JustDown(this.cursors.left)){
this.combo += 'L';
} else if(Phaser.Input.Keyboard.JustDown(this.cursors.right)){
this.combo += 'R';
}
}
metronome() {
const border = this.add.graphics();
border.lineStyle(3, 0xffffff, 1);
border.strokeRect(
5,
5,
this.sys.game.config.width - 10,
this.sys.game.config.height - 10
);
const borderTween = this.tweens.add({
targets: border,
alpha: 0,
duration: 500,
repeat: 0,
yoyo: false
});
borderTween.pause();
this.metronomeTween = this.time.addEvent({
delay: 1000,
callback: () => {
borderTween.play();
this.combo +='|';
this.checkCombo('L|L|RR|L');
},
loop: true
});
}
checkCombo(comboString){
if(this.combo.indexOf('||') != -1){
this.combo = '';
return;
}
if(this.combo.indexOf(comboString) != -1){
this.combo = '';
this.info.setText(`combo ${comboString} activated`);
setTimeout(()=>{this.info.setText('')},1500);
}
}
}
Code and demo: https://codepen.io/jjcapellan/pen/EzGRgv
Regards.
1 Like
Thank you, this is exactly what I need. I implement this solution for my buttons.
True, I have already solved this problem earlier, but your approach is more concise and clear.
cool I had another solution maybe you found the solution
cheers =)
I don’t know if to post it but I do it anyway this is how I solved it sort of in observables which I don’t know if they can be implemented
Hi Jack… I wanted to help but I am pretty new to Phaser 3 and have a headache but I made this in … observables maybe helps a little
//x=this.paddlepos;
switch (event.keyCode) {
case PADDLE_KEYS.left:
//x+=1;
return 0
case PADDLE_KEYS.right:
return 2
default:
//return null;
return 1
}
return null
})
this.$animator2 = zip(
interval(12,animationFrameScheduler).pipe(
sample(interval(4000))
),
of(43,52,52,25,42,32,22,24)
, $press.pipe(
map((f)=>({
delta:f,
combo:null
})),
scan((f,ff)=>({
delta:f.delta,
combo:f.delta+ff.delta
})
)),
(x,y,s) =>s,
)
I don't know as I said if it is to any help but it records every clicks and emits an object every four seconds and scans =accumulates the combo in 2 steps like for example two left is zero two right is 4.,... um yes,
and I'm still a bit noob to phaser3 but its suppose to be implemented somehow
so the latest click combined with 4 seconds plus the click with the 4 seconds before. in phase 3 you have the update function, but this way no break combo is implemented, but for example, if two left breaks the combo just put some logic the "of " is just for a demo like if the first combo is an "a" next combo is "a" +"previous"
cheers mate