I am new to Phaser. The code snippet is as follows and collisionCnt here is globally initialised as 0:
update: function() {
this.collisionChecker = this.physics.arcade.collide(this.ground, this.rainGroup, this.over, this.overCheck, this); //checks for collision between rain drops and ground
this.physics.arcade.collide(this.rainGroup, this.rainGroup); //checks for collision between rain drops
},
overCheck: function() {
collisionCnt++;
if(collisionCnt == 4) {
console.log(collisionCnt);
return true;
}
else {
console.log(collisionCnt);
return false;
}
},
over: function() {
this.state.start('gameOver');
}
The problem is update method continuously monitors an instance of collision and returns true continuously resulting in the collisionCnt becoming equals to 4 for a single collision event. I need at least 4 objects of rainGroup group to touch the ground before it is game over. All help is welcome and thanks in advance :)
One way to resolve this would be to give your rain drops a property that would denote whether they had collided or touched the ground. Then in your check see if that property was set and if it was not increment your counter and set the property.
I've created a full JSFiddle as a working example but the relevant code changes in your code might be something like this:
this.collisionChecker = this.physics.arcade.collide(this.ground, this.rainGroup, this.over); //checks for collision between rain drops and ground
over: function(ground, rainDrop) {
if (!rainDrop.hasTouchedGround) {
collisionCnt++;
rainDrop.hasTouchedGround = true;
if (collisionCnt >= 4) {
this.state.start('gameOver');
}
}
}
The second option is to kill rain drops when they touch the ground. That makes things much easier, but will remove the sprite from the display.
over: function(ground, rainDrop) {
collisionCnt++;
rainDrop.kill();
if (collisionCnt >= 4) {
this.state.start('gameOver');
}
}
JSFiddle example showing this option.
Related
In phaser 3 framework, what syntax do I use to check the current frame index?
I want to make a hit area appear only when the player's sprite sheet reaches a certain index(the index displaying the motion of 'attack'). I want to accomplish this through detecting its current frame index.
How can I do this?
You could use the sprite events like: Phaser.Animations.Events.ANIMATION_UPDATE, details in official phaser documenation
player.on(Phaser.Animations.Events.ANIMATION_UPDATE, function (anim, frame, gameObject, frameKey) {
// Here you can check for the specific-frame
if(frameKey == "show_hit_area_frame"){
// ... show hitarea
}
// alternatively: with the index of the frame
if(frame.index == 7){
// ... show hitarea
}
});
In this selected Event, you can also check the current frame, for other properties of the frame object (details in official documenation), if you don't know/have the specific framekey/index.
The solution is found.
//hitbox solution: https://newdocs.phaser.io/docs/3.52.0/Phaser.Animations.Events.ANIMATION_COMPLETE_KEY
//hitboxB listener
gameState.playerB.on('animationstart-kill', function () {
console.log("finish kill <3")
gameState.hitBoxB.x = gameState.playerB.flipX ? gameState.playerB.x + 120 : gameState.playerB.x - 120;
gameState.hitBoxB.y = gameState.playerB.y;
// gameState.hitBoxB.visible = true;
})
gameState.playerB.on('animationcomplete-kill', function () {
console.log("kill <3")
gameState.hitBoxB.x =0 ;
gameState.hitBoxB.y = 0;
// gameState.hitBoxB.visible = false;
})
I'm using Phaser.io
I just learned how to set a collider function:
this.physics.add.collider(enemies, platforms, function (enemy) {
enemy.destroy();
gameState.score += 10;
});
But I would like to do the same thing without the platform. Instead of the platform, I would like to use the world bounds.
I know you can set world bounds like this:
player.setCollideWorldBounds(true);
I've tried:
this.physics.add.collider(enemies, this.worldBounds, function (enemy) {
enemy.destroy();
gameState.score += 10;
});
But this doesn't work.
Any ideas?
I have found a solution for you:
First, set your enemy's sprite to collide with the setCollideWorldBounds(true) like so:
enemy.setCollideWorldBounds(true);
Second, turn the option for your enemy's sprite to listen for WorldBound events like so:
enemy.body.onWorldBounds = true;
Third & lastly, set the "wordbounds" event listener & make the enemy disappear like so:
enemy.body.world.on('worldbounds', function(body) {
// Checks if it's the sprite that you'listening for
if (body.gameObject === this) {
// Make the enemy sprite unactived & make it disappear
this.setActive(false);
this.setVisible(false);
}
}, enemy);
I have an object which is placed on the ground.
when i press "space" key it hast to jump and fall down on the ground.
to fall it down i am using gravity with rigid body.
i attached it to boxcollider of the ground so that it can detect
when is on ground and air through OnTriggerEnter() and OnTriggerExit() respecitvely.
the code is follows:-
#pragma strict
var jumping:boolean=false;//when the body is in air that is still jumping
var grounded:boolean=true;//laid on ground
var body: Rigidbody;
function Start ()
{
body = GetComponent.<Rigidbody>();
}
function Update () {
if(Input.GetKey("up")){transform.Translate(-3*Time.deltaTime,0,0);}
if(Input.GetKey("left")){transform.Translate(0,0,-3*Time.deltaTime);}
if(Input.GetKey("right")){transform.Translate(0,0,3*Time.deltaTime);}
if(Input.GetKey("down")){transform.Translate(3*Time.deltaTime,0,0);}
if(Input.GetKey("space"))
{
jumping=true;
if(grounded && jumping)
{
body.AddForce(transform.up*5);
}
}
}
//On the ground
function OnTriggerEnter()
{
grounded=true;jumping=false;
body.useGravity=false;
}
//On the ground
function OnTriggerStay()
{
body.useGravity=false;
grounded=true;jumping=false;
}
//jumping
function OnTriggerExit()
{
body.useGravity=true;
grounded=false;jumping=false;
}
but it is not jumping,instead it goes up for while and fall down contineously. eventhough useGravity becomes false it continues to fall down.
what is wrong in my code?
Thanks in advance.
The problem is with ForceMode. You don't define it, so it defaults to Force but you need Impulse for a jump like effect.
Here's a link to the documentation for a better understand.
I'm learning javascript by using the easeljs library to make a simple game, for school lessons.
I want to make a crosshair give some feedback to the player by showing a small animation while you are pointing at your target, using a hittest I made.
However, when the crosshair touches the target, the animation (should be two little triangles pointing to the middle of the crosshair) seems to be stuck on it's first frame.
Here is a bit of my code, I put both of these functions inside a ticker function. The functions do what they're supposed to do (I checked by sending a message to the console.log), but I think the animation is reset as soon as the variable "hitTestControle" is set to true, at every tick.
If you want to check out all of the code, here is a link to the "game":
http://athena.fhict.nl/users/i279907/achtergrond/achtergrond.html
function hitTest() {
if(distance(crossHair, block) < 60) {
hitTestControle = true;
} else {
hitTestControle = false;
console.log(hitTestControle);
}
}
function hitTestControl() {
if(hitTestControle == true) {
crossHair.gotoAndPlay("move");
console.log("hit");
} else {
crossHair.gotoAndPlay("stop");
}
}
PS: There also seems to be something wrong with this hittest I used.
function distance() {
var difx = blok.x - crossHair.x;
var dify = blok.y - crossHair.y;
return Math.sqrt( (difx * difx) + (dify * dify) );
}
It looks like you're starting the animation... setting it to the first frame and starting it... every time hitTestControle is true. Since hitTestControle will be true as long as you're hovering over the target, the animation will never reach the second frame.
What you need to do is start the animation when you transition from hitTestControle = false to hitTestControle = true, but once that happens you just let it play automatically.
Try changing your hitTestControl() function to something like this:
function hitTestControl() {
if(hitTestControle == true && alreadyOverHit == false) {
crossHair.gotoAndPlay("move");
alreadyOverHit = true;
console.log("hit");
} else {
crossHair.gotoAndPlay("stop");
alreadyOverHit = false;
}
}
In other words, only start the animation once, during the first frame you're detecting a hit, and then don't touch it unless you move off the target and back on.
it is the first time for me to explore jQuery and gameQuery for building games using JavaScript, so am asking about sth that might look very naive, but really i cant get it.
i am developing a game like Space Invader, the detection for collision between player missile and enemies not working.
This is my code:
the definition for my Enemy class
function Enemy(node){
this.node = $(node);
this.pts_value = 0;
return true;
}
this is the code i use to add ten enemy sprite next to each other. the enemies move together to the left and the right
$.each(new Array(10), function(index, value) {
$("#enemy_group").addSprite("enemy2_"+index,{animation: enemies[2],
posx: index * 55, posy: 0, width: 48, height: 48})
$("#enemy2_"+index).addClass("enemy");
$("#enemy2_"+index)[0].enemy = new Enemy($("#enemy2_"+index));
$("#enemy2_"+index)[0].pts_value = 150;
});
so when i need to move the enemies, i move the enemies together, i move the group that includes all the sprites "#enemy_group"
if(ENEMY_TO_RIGHT){
var enemiesNewPos = (parseInt($("#enemy_group").css("left"))) + ENEMY_SPEED;
if(enemiesNewPos < PLAYGROUND_WIDTH - 550){
$("#enemy_group").css("left", ""+enemiesNewPos+"px");
} else {
ENEMY_TO_RIGHT = false;
}
} else {
var enemiesNewPos = (parseInt($("#enemy_group").css("left"))) - ENEMY_SPEED;
if(enemiesNewPos > 0){
$("#enemy_group").css("left", ""+enemiesNewPos+"px");
} else {
ENEMY_TO_RIGHT = true;
}
}
finally for collision detection, i want to remove the enemy sprite that the players missile has hit, each missile sprite has an added class names ".playerMissiles"
$(".playerMissiles").each(function(){
var posy = parseInt($(this).css("top"));
if(posy < 0){
$(this).remove();
return;
}
$(this).css("top", ""+(posy - MISSILE_SPEED)+"px");
//Test for collisions
var collided = $(this).collision(".enemy, .group");
if(collided.length > 0){
//An enemy has been hit!
collided.each(function(){
$(this).setAnimation(enemies[0], function(node){$(node).remove();});
})
}
});
i was following the documentation tutorial on the gameQuery website.
any help appreciated, thanks,
I can't see any problem with your code. I can only give you a few pointers:
Did you create "enemy_group" with the addGroup function?
Is "enemy_group" nested in something special like a custom div ? for the collision detection to work you need a chain of parent composed only of sprites and groups (and tiles map)
Is "enemy_group" nested in a sprite, if so it's a bad idea because you will need to add the selector for this sprite in your methode call and this sprite will be included in the colliding element list.
The same goes for the ".playerMissiles"
Just to be sure what version of gameQuery and jQuery do you use? The last version from gitHub is unstable and I wouldn't recomend using it, user 0.5.1 instead.
You could use jquery collision plugin, so you avoid doid the logic by yourself.
Hope this helps. Cheers