Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
My collision of moving objects is not working. I have created a demo so you can see it and see my problem all code and everything included.
As you may be able to see, I have 2 blocks coming from left to right and then I have a tank shooting bullets> I tried in all kind of directions and I always get the same results, basically my collision only works the velocity of the blocks value, in the example on the zip file only works up to 300px. Depending on the blocks speed, if I change the block speed to a greater number then the collision works on the same numbers pixels. it is really weird.
I was wondering if I'm just doing the whole thing wrong or what could my problem be? I would appreciate any pointers or ideas that can help me solve this issue. Thanks.
Demo source code.
BasicGame.Game = function (game) {
// When a State is added to Phaser it automatically has the following properties set on it, even if they already exist:
this.game; // a reference to the currently running game (Phaser.Game)
this.add; // used to add sprites, text, groups, etc (Phaser.GameObjectFactory)
this.camera; // a reference to the game camera (Phaser.Camera)
this.cache; // the game cache (Phaser.Cache)
this.input; // the global input manager. You can access this.input.keyboard, this.input.mouse, as well from it. (Phaser.Input)
this.load; // for preloading assets (Phaser.Loader)
this.math; // lots of useful common math operations (Phaser.Math)
this.sound; // the sound manager - add a sound, play one, set-up markers, etc (Phaser.SoundManager)
this.stage; // the game stage (Phaser.Stage)
this.time; // the clock (Phaser.Time)
this.tweens; // the tween manager (Phaser.TweenManager)
this.state; // the state manager (Phaser.StateManager)
this.world; // the game world (Phaser.World)
this.particles; // the particle manager (Phaser.Particles)
this.physics; // the physics manager (Phaser.Physics)
this.rnd; // the repeatable random number generator (Phaser.RandomDataGenerator)
// You can use any of these from any function within this State.
// But do consider them as being 'reserved words', i.e. don't create a property for your own game called "world" or you'll over-write the world reference.
this.bulletTimer = 0;
};
BasicGame.Game.prototype = {
create: function () {
//Enable physics
// Set the physics system
this.game.physics.startSystem(Phaser.Physics.ARCADE);
//End of physics
// Honestly, just about anything could go here. It's YOUR game after all. Eat your heart out!
this.createBullets();
this.createTanque();
this.timerBloques = this.time.events.loop(1500, this.createOnebloque, this);
},
update: function () {
if(this.game.input.activePointer.isDown){
this.fireBullet();
}
this.game.physics.arcade.overlap(this.bullets, this.bloque, this.collisionBulletBloque, null, this);
},
createBullets: function() {
this.bullets = this.game.add.group();
this.bullets.enableBody = true;
this.bullets.physicsBodyType = Phaser.Physics.ARCADE;
this.bullets.createMultiple(100, 'bulletSprite');
this.bullets.setAll('anchor.x', 0.5);
this.bullets.setAll('anchor.y', 1);
this.bullets.setAll('outOfBoundsKill', true);
this.bullets.setAll('checkWorldBounds', true);
},
fireBullet: function(){
if (this.bulletTimer < this.game.time.time) {
this.bulletTimer = this.game.time.time + 1400;
this.bullet = this.bullets.getFirstExists(false);
if (this.bullet) {
this.bullet.reset(this.tanque.x, this.tanque.y - 20);
this.game.physics.arcade.enable(this.bullet);
this.bullet.enableBody = true;
this.bullet.body.velocity.y = -800;
}
}
},
createOnebloque: function(){
this.bloquecs = ["bloqueSprite","bloquelSprite"];
this.bloquesr = this.bloquecs[Math.floor(Math.random()*2)];
this.bloque = this.add.sprite(0, 360, this.bloquesr);
this.game.physics.arcade.enable(this.bloque);
this.bloque.enableBody = true;
this.bloque.body.velocity.x = 300;
this.bloque.body.kinematic = true;
this.bloque.checkWorldBounds = true;
this.bloque.outOfBoundsKill = true;
this.bloque.body.immovable = true;
},
createTanque: function() {
this.tanqueBounds = new Phaser.Rectangle(0, 600, 1024, 150);
this.tanque = this.add.sprite(500, 700, 'tanqueSprite');
this.tanque.inputEnabled = true;
this.tanque.input.enableDrag(true);
this.tanque.anchor.setTo(0.5,0.5);
this.tanque.input.boundsRect = this.tanqueBounds;
},
collisionBulletBloque: function(bullet, bloque) {
this.bullet.kill();
},
quitGame: function (pointer) {
// Here you should destroy anything you no longer need.
// Stop music, delete sprites, purge caches, free resources, all that good stuff.
// Then let's go back to the main menu.
this.state.start('MainMenu');
}
};
The code definitely helps, but you can actually get an idea of what's happening just from playing the game.
As the blocks are going by you can actually get the bullets to disappear if you fire and hit the right edge of the center-most block.
What's happening is that you're checking for a collision between the bullets and a block, but the block is getting redefined every time you add a new one to the screen on the left.
What you probably want to do is create a pool of blocks (bloquePool for example), almost exactly like what you're doing in createBullets with your bullet pool (what you've called bullets).
Then check for a collision between the group of bullets and the group of blocks.
this.game.physics.arcade.overlap(
this.bullets, this.bloquePool, this.collisionBulletBloque, null, this
);
You should get the individual bullet and the individual block that collided passed into collisionBulletBloque so you can still kill the bullet as you are.
Related
I'm trying to create a 'Bomber-man' like game using Phaser3 library.
For this purpose I'd like to define a collision relationship between the player and the bricks,
and more importantly - detect the collision direction relative the the player.
I've noticed body properties like touching or blocked but they are always set to false. (please see below)
//scene.js
// bricks static group
this.scene.physics.add.staticGroup({ immovable: true });
// player defined in external file (as sprite)
this.player = new Player(this, 90, 90)
// player.js
// ...
this.physics.add.collider(
this,
scene.bricks,
function(player, brick) {
if(player.body.touching.left) { //ALWAYS FALSE!!!
this.isBlockedFromLeft = true;
}, else if(player.body.touching.right) {
this.isBlockedFromRight = true; // ALWAYS FALSE!!!
}
},
null,
this
);
I'd appreciate any help. This is driving me crazy. Maybe there is a better way to do it and i'm missing something...
Thanks in advance.
So I finally figured it out.
The major issue was the way I defined the player movement. It should be
if (this.keyboard.right.isDown) {
this.body.setVelocityX(this.speed);
}
rather than
if (this.keyboard.right.isDown) {
this.x += this.speed;
}
The second way prevent collision detection and the body.touching and body.blocked properties to be updated.
Furthermore, I've found out that when it comes to top-down tiled games, it's really easier to build up the game using the tile-map feature.
official examples can be found here:
https://phaser.io/examples/v3/search?search=map
and here is a tutorial of how to make a tiled-map using a light-weight software called 'Tiled'
https://www.youtube.com/watch?v=2_x1dOvgF1E
Thank you all!
I'm trying to make a sprite moving when the mouse is over it and I'd like it to stop when the mouse is not over it anymore.
Here is my code:
mySprite.events.onInputOver.add(() => touchMouse = true);
mySprite.events.onInputOut.add(() => touchMouse = false);
and
update() {
if (touchMouse) {
mySprite.x += 5;
}
}
My sprite is correctly moving but the onInputOut signal is not dispatched if I don't move the pointer out of theĀ initialĀ sprite position!! This result in my sprite moving out of my pointer and continuing its journey until I move my mouse...
Is it a phaser bug? Has anyone a solution to make this work?
Thank you very much and have a good day,
Simon
Edit:
I just tried to use the Phaser.InputHandler object instead but I got the same kind of bug. Here is the code:
update() {
if (mySprite.input.pointerOver()) {
mySprite.x += 5;
}
}
Someone answered my question in the html5gamedevs forum.
Phaser doesn't ordinarily update inputOver/inputOut events while the pointer isn't moving. You need to set pointer.dirty = true for that.
I am making a platformer, and I want to make something similar to Thwomp from Mario. So it's just an enemy that patrols between two points, and any collision with the player will kill the player.
I do this via Phaser's sprite.body.moveTo. I need to check if the enemy overlaps with the player, so I can trigger the player dying.
The problem is that, when the player and enemy collide, the moveTo is messed up, and the enemy's path is hindered. I took a short video to demonstrate what happens. Video.
Here is the code for when I create the enemy. I use an object group from Tiled for the properties, so thats what all the map.objects.mainObjecets[i] stuff is.
//demons is a phaser group with body enabled.
var demon = demons.create(map.objects.mainObjects[i].x,map.objects.mainObjects[i].y,'demon');
demon.direction = Number(map.objects.mainObjects[i].properties.direction);
demon.distance = Number(map.objects.mainObjects[i].properties.distance);
demon.duration = Number(map.objects.mainObjects[i].properties.duration);
//I tried using stopVelocityOnCollide and immovable to fix the problem, neither one worked
demon.body.stopVelocityOnCollide=false;
demon.body.immovable = true;
demon.body.onMoveComplete.add(moveDemon, this);
game.time.events.add(map.objects.mainObjects[i].properties.delay, function(a) {
a.body.moveTo(a.duration, a.distance, a.direction);
}, this, demon);
And here is the code that runs everytime a movement completes.
function moveDemon(demon) {
game.time.events.add(Phaser.Timer.SECOND * .3, function() { //.3 second delay before moving
demon.direction = 360-demon.direction;
demon.body.moveTo(demon.duration, demon.distance, demon.direction);
}, this);
}
And lastly, here is the code for checking for overlaps
this.physics.arcade.overlap(player,demons,function(){
//This code just moves the player back to the spawn point.
player.x = map.objects.spawn[0].x;
player.y = map.objects.spawn[0].y;
});
I'm new to phaser, and for the past few days I've been trying to make a really simple game, platformer-style, where the player must navigate to certain areas before being able to exit the level.
I have the basics running, but now I can't seem to figure out how to check if the player is in those areas.
The relevant part of the code so far is as follows:
var game = new Phaser.Game(800, 600, Phaser.AUTO, "mygame", {
preload: preload,
create: create,
update: update,
render: render
});
function preload() {
game.load.tilemap("questMap", "assets/quest.json", null, Phaser.Tilemap.TILED_JSON);
game.load.image("tilesheet", "assets/tilesheet.png");
game.load.image("npc", "assets/npc.png");
game.load.spritesheet("player", "assets/player.png", 64, 64);
}
var map;
var tileset;
var groundBg;
var props;
var houses;
var houseProps;
var npc;
var ground;
var areas;
var player;
function create() {
game.physics.startSystem(Phaser.Physics.ARCADE);
game.stage.backgroundColor = "#A8DBFF";
map = game.add.tilemap("questMap");
map.addTilesetImage("tilesheet");
map.addTilesetImage("npc");
ground = map.createLayer("ground");
groundBg = map.createLayer("groundbg");
props = map.createLayer("props");
houses = map.createLayer("houses");
houseProps = map.createLayer("houseprops");
npc = map.createLayer("npc");
map.setCollisionBetween(1, 5000);
ground.resizeWorld();
Not too pretty, I know.
I've created the map with tiled and there are a lot of small props and decorative tiles, hence the multiple "map.createLayer()" calls. The only one with collision is the ground layer.
Now, on my Tiled file, I've created an Object layer and drawn small rectangles on the areas I want to check if the player is in. I thought this was going to be an easy process but I can't seem to figure out how to load those areas into Phaser, and then check if the player is within bounds.
Googling has given me some results, but none seem to fit, as they usually cover how to add a sprite to an object, which in this case does not apply.
I simply need that small area to exist and check if the player is there. I've also given names to each of those rectangles in Tiled, via the custom properties tab.
I would try using a transparent image as the area you wish to check if your sprite is over and use
if(sprite1.overlap(transparentImage)){
//do something
}
I'm not sure where to post this question, so please excuse me if I am violating any policies.
To clarify my question, I want to achieve the same navigation bar as Teehan + Lax's.
Here is their website: http://www.teehanlax.com/tools/
If you notice, the navigation auto hides itself when you scroll down, however when you scroll up it would show it self again.
So my question is, how did they achieve this? Is it through only CSS or do I need JavaScript to do this? Whatever way it is, can someone also point towards the right direction on how I can find the information to implement this?
Thank you
It's not possible to change position from fixed to absolute in pure CSS like you want, so I used some javascript to do so. Demo
function followTo(elem, pos) {
var element = document.getElementById(elem);
window.onscroll = function(e){
var disFromTop = document.all? iebody.scrollTop : pageYOffset;
if (disFromTop > pos) {
element.style.position = 'absolute';
element.style.top = pos + 'px';
} else {
element.style.position = 'fixed';
element.style.top = 0;
}
};
};
followTo("nav", 100);
It even includes an IE fix pulled from this SO post to get the correct scroll position
Here is the jQuery version, taken from this SO post
EDIT
As pointed out by zanona, I did not include the feature where the navigation appears if you scroll up from a place further down in the page. As a result, I create a new technique that uses a setInterval
var last = 0, // The last read top value
delay = 150, // The delay for the setInterval
threshold = 30; // The max scroll distance before showing/hiding the nav
//I always set a variable to my setIntervals in case I want to stop them later on
var navMovement = setInterval(function() {
var nav = document.getElementById('nav'), // Gets nav object
pageVertOffset = document.all? iebody.scrollTop : pageYOffset;
// Happens if the difference in scroll is below the negative threshold
if(pageVertOffset - last < -threshold) {
nav.style.top = "0px"; // Put the nav at the top of the window
}
// Happens if the difference in scroll is above the threshold
else if(pageVertOffset - last > threshold){
nav.style.top = - nav.offsetHeight + "px"; // Hides the navigation
}
last = pageVertOffset; // Updates the previous scroll value
}, delay); // Runs every `delay` amount
Javascript version, or if you prefer, jQuery version
I thought I recreated the site pretty well (but it's better because mine has a kitten, haha)