Can you please show me how the dom can communicate mouse pointer movement events as an input to a phaser scene. I've seen how mouse movement can be tracked within the scene area; but once the mouse leaves and goes to other areas of the DOM, that data is not tracked. I figure if perhaps there was a way to have an input to communicate data from "the outside world" then this could be possible. I am very grateful for help and direction you could share.
All you need to do is add an event listener to the DOM object you also want to track movement in using plain JavaScript. Then, you tie the event listener to the game method you want to execute when the event is triggered.
const body = document.querySelector('body');
body.onmousemove = (pointer) => {
updatePoint(pointer);
};
And then setup your game as normal:
const config = {
type: Phaser.CANVAS,
height: 400,
width: 400,
parent: 'gameContainer',
scene: {
create: create
}
};
const game = new Phaser.Game(config);
let dataText;
function create() {
this.input.on('pointermove', (pointer) => {
updatePoint(pointer);
});
dataText = this.add.text (10, 10, 'x, y');
}
function updatePoint(pointer) {
dataText.text = 'x: ' + pointer.offsetX + ', y: ' + pointer.offsetY;
}
You may have to refactor your code a little bit to get this to work, because the event listener on your DOM element needs to be able to access the game methods. I created a quick codepen showing the setup that worked for me.
Related
I'm new to Phaser and am following this tutorial here: https://phaser.io/tutorials/making-your-first-phaser-3-game/part7
What do I need to change for use on a mobile cell phone browser to make the player automatically run to the right and jump when the screen is tapped? I've searched for ages but can't find the answer and am trying to learn
// Input Events
cursors = this.input.keyboard.createCursorKeys();
if (cursors.left.isDown)
{
player.setVelocityX(-160);
player.anims.play('left', true);
}
else if (cursors.right.isDown)
{
player.setVelocityX(160);
player.anims.play('right', true);
}
else
{
player.setVelocityX(0);
player.anims.play('turn');
}
if (cursors.up.isDown && player.body.touching.down)
{
player.setVelocityY(-330);
}
What I would do:
Add an input handler to your general game that calls a 'jump' function when a pointer is down.
this.input.on('pointerdown', this.jump, this);
Jump should now verify that the player can jump. Something like:
jump() {
if (this.player.body.touching.down) {
this.player.setVelocityY(-330);
}
}
To have your player automatically move at a speed, you can just set the player's body velocity when you're creating the player.
this.player.body.velocity.x = 160;
Note that if you want to keep the current ability to control the player, another option is to have actual buttons on the screen that the user can tap/click on to have the player move/act accordingly. There's an official plugin for Phaser 2 that does this, that you could look at.
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;
});
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.
I used latest version cocos2d-js to create my game. On the game screen, I added multiple sprites overlay in a row, like this
Overlay sprites
I added an event listener to move up a sprite on y-axis when it was clicked. However, when I clicked on the point that any two sprites contain, the two sprites moved up together.
This is my event listener code
var listener = cc.EventListener.create({
event: cc.EventListener.TOUCH_ONE_BY_ONE,
swallowTouches: true,
onTouchBegan: function (touch, event) {
var target = event.getCurrentTarget();
var location = target.convertToNodeSpace(touch.getLocation());
var targetSize = target.getContentSize();
var targetRectangle = cc.rect(0, 0, targetSize.width, targetSize.height);
if (cc.rectContainsPoint(targetRectangle, location)){
target.setPositionY(50);
}
}
});
How can I prevent to move them up together and move only one sprite?
Thanks.
onTouchBegan must returns boolean value as result, if returns true it's means touch was handled and event cycle will be stopped. Try to return true, if rect contains point.
Hope this helps. And sorry for my English.
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
}