How to detect click on the images in phaser3 - javascript

I am new to phaser and I am trying to detect a click on several images in phaser3 .This has somehow become a two part problem for me.
First is to detect click on the objects, but even if I click anywhere else on the screen also the click handler fires.
Second part is that I have identical and multiple images on the scene, and I want to detect clicks on each of them inside a single function only and detect which image was clicked .
Here is my code:
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/phaser#3.24.1/dist/phaser-arcade-physics.min.js"></script>
<style media="screen">
canvas { display : block; margin : auto;}
</style>
</head>
<body>
<script>
var config = {
type: Phaser.CANVAS,
scale: {
mode: Phaser.Scale.ScaleModes.FIT,
parent: 'phaser-example',
autoCenter: Phaser.Scale.CENTER_BOTH,
width: 400,
height: 640
},
// width: 400,
// height: 640,
physics: {
default: 'arcade',
arcade: {
gravity: { y: 10 }
}
},
scene: {
preload: preload,
create: create,
update: update
}
};
var game = new Phaser.Game(config);
var Bimages;
function preload ()
{
this.load.setBaseURL('http://localhost:3000');
this.load.image('sky', 'assets/skies/deepblue.png');
this.load.image('tube1', 'assets/myassets/ballSort/tube.png');
this.load.image('tube2', 'assets/myassets/ballSort/tube.png');
}
var numOfTestTubes = 5;
var storeTubes = [];
function create ()
{
ctx = this;
this.add.image(400, 300, 'sky').scaleY = 1.2;
var t1 = ctx.add.image(150, 300, 'tube1');
t1.scaleY = 0.5;
t1.scaleX = 0.5;
var t2 = ctx.add.image(220, 300, 'tube2');
t2.scaleY = 0.5;
t2.scaleX = 0.5;
t1.setInteractive();
t2.setInteractive();
t1.on('pointerdown', handleclick);
}
function update(){
}
function handleclick(pointer, targets){
console.log("clicked0",pointer);
}
</script>
</body>
</html>
Can anyone help me out here please?

The pointerdown event listener on game objects is different than the pointerdown event listener on the global input manager. If you instead do this.input.on('pointerdown', ...) you'll get a callback with the pointer, but also an array of game objects that were clicked, with an empty array if no game objects were clicked. If you need to register clicks on input objects that overlap each other, you can change this behavior with #setTopOnly. You can check object equality or against some property expected such as the object's name or texture key. I linked a stackblitz with rectangles, but understand they are behaving the same as an image's hitbox would.
https://stackblitz.com/edit/phaser-so-global-input-manager?file=index.ts

Related

Problems with phaser framework, running a server on xampp, getting errors, javascript/html

So I have this code that will run a game being this the base of that game. it uses phaser.
I was trying to run it on xampp on htdocs/itw/test.html
with the 2 pngs and json file being located on htdocs/itw/assets/
the pngs are tilesets and the json tilemap
but I get this errors on console executing the indext.html
Any Help would be awsome
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/phaser#3.15.1/dist/phaser-arcade-physics.min.js"></script>
</head>
<body>
<script>
const config = {
type: Phaser.AUTO, // Which renderer to use
width: 800, // Canvas width in pixels
height: 600, // Canvas height in pixels
parent: "game-container", // ID of the DOM element to add the canvas to
scene: {
preload: preload,
create: create,
update: update
}
};
const game = new Phaser.Game(config);
function preload() {
// Runs once, loads up assets like images and audio
this.load.image("quadrados1", "../assets/outside.png");
this.load.image("quadrados2", "../assets/outside2.png");
this.load.tilemapTiledJSON("mapa", "../assets/fcul_map.json");
}
function create() {
// Runs once, after all assets in preload are loaded
const map = this.make.tilemap({ key: "mapa" });
const tileset = map.addTilesetImage("outside", "quadrados1");
const belowLayer = map.createStaticLayer("Below Player", tileset, 0, 0);
const worldLayer = map.createStaticLayer("World", tileset, 0, 0);
const aboveLayer = map.createStaticLayer("Above Player", tileset, 0, 0);
}
function update(time, delta) {
// Runs once per frame for the duration of the scene
}
</script>
</body>
</html>
.. represents parent directory. Try removing them in your load statements
Ex.
../assets/outside.png to assets/outside.png

Issue with animations from an atlas in Phaser 3

I've been attempting to learn Phaser 3 so I can support my students in learning the framework. I've been able to get a spritesheet working, however, I'd prefer to use a json file, so I'm using the load atlas instead. The problem I'm having no matter what I try is that the update method is giving an error when I attempt to play the animation I created in the create method.
It says, Uncaught TypeError: Cannot read property 'frame' of undefined
I'm exporting my json and spritesheet using LeshyLabs https://www.leshylabs.com/apps/sstool/
Here's my code. Any help would be very much appreciated.
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>First Phaser Game</title>
<script src="//cdn.jsdelivr.net/npm/phaser#3.11.0/dist/phaser.js"></script>
<style type="text/css">
body {
margin: 0;
}
</style>
</head>
<body>
<script type="text/javascript">
var config = {
type: Phaser.AUTO,
width: 1200,
height: 800,
physics: {
default: 'arcade',
arcade: {
gravity: { y: 300 },
debug: false
}
},
scene: {
preload: preload,
create: create,
update: update
}
};
var game = new Phaser.Game(config);
var platforms;
var cursors;
var megaman;
function addPlatform(x,y,width){
for (i=0;i<width;i++){
platforms.create(x+(i*64), y, 'ground');
}
}
function preload()
{
this.load.image('bg', 'assets/ripbgzsnes03.png');
this.load.image('ground', 'assets/platform.png');
this.load.image('star', 'assets/star.png');
this.load.image('bomb', 'assets/bomb.png');
this.load.atlas('megaman', 'assets/spritesheet.png', 'assets/megamansprites2.json');
}
function create()
{
this.bg = this.add.image(2400,config.height/2,'bg');
this.bg.displayWidth = 4800;
this.bg.displayHeight = config.height;
this.physics.world.bounds.width = 4800;
platforms = this.physics.add.staticGroup();
addPlatform(0, 580, 40);
this.physics.add.collider(megaman, platforms);
this.anims.create({
key:'standing',
frames: this.anims.generateFrameNames('stand', {
prefix:'stand',
end:7,
zeroPad: 2
}),
repeat: -1
});
megaman = this.physics.add.sprite(100, 450, 'megaman');
megaman.setCollideWorldBounds(true);
cursors = this.input.keyboard.createCursorKeys();
// set bounds so the camera won't go outside the game world
this.cameras.main.setBounds(0, 0, 4800, config.heightInPixels);
// make the camera follow the player
this.cameras.main.startFollow(megaman);
}
function update()
{
megaman.play('standing')
// if (cursors.left.isDown)
// {
// megaman.setVelocityX(-250);
// // megaman.anims.play('running', true);
// }
// else if (cursors.right.isDown)
// {
// megaman.setVelocityX(250);
// // megaman.anims.play('running', true);
// }
// else
// {
// megaman.setVelocityX(0);
// // megaman.play('standing');
// }
// if (cursors.up.isDown && megaman.body.touching.down)
// {
// megaman.setVelocityY(-330);
// }
}
</script>
</body>
</html>
In your load statement, you're naming the atlas 'megaman' (name will be the first parameter passed into the load method). Then, in the anims.create() method, you're referencing an atlas called 'stand' to generate the frame names. That's why you're getting undefined.
You can see an example of setting up animations with an atlas here: Phaser Labs - Animation from Atlas.
In the meantime, if you change your create method to this, it should work:
this.anims.create({
key:'standing',
frames: this.anims.generateFrameNames('megaman', {
prefix:'stand',
end:7,
zeroPad: 2
}),
repeat: -1
});

Container doesn't render children when declared by 'new' keyword (Phaser 3)

I am trying to declare Container with new keyword for code modularization (referencing this article). However, when I declare one with new Container(), it doesn't render its child image/sprite. What am I doing wrong here? Please see my code below:
var config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#010101',
parent: 'phaser-example',
physics: {
default: 'arcade',
arcade: {
gravity: { y: 200 },
debug: true
}
},
scene: {
preload: preload,
create: create
}
};
var container1, container2;
var game = new Phaser.Game(config);
function preload () {
this.load.image('mushroom', 'assets/sprites/mushroom2.png');
this.load.image('lemming', 'assets/sprites/lemming.png');
}
function create () {
var image1 = this.add.image(-40, 0, 'mushroom');
var image2 = this.add.image(40, 0, 'lemming');
container1 = this.add.container(100, 200);
container1.add(image1);
container1.setSize(128, 64);
this.physics.world.enable(container1);
container1.body.setVelocity(0, 200).setBounce(1, 1).setCollideWorldBounds(true);
container2 = new Phaser.GameObjects.Container(this, 300, 200)
container2.add(image2);
container2.setSize(128, 64);
this.physics.world.enable(container2);
container2.body.setVelocity(0, 200).setBounce(1, 1).setCollideWorldBounds(true);
// container1 renders image1, but container2 doesn't render image2.
console.log(this.add.image, Phaser.GameObjects.Container);
console.log(container1, container2);
console.log(container1.list[0], container2.list[0]);
}
If you want to run this code, please go to Phaser3 SandBox, and copy & paste above code and click Run Code (sorry, I don't know how to save my code there). Any help would be highly appreciated!
Copying #rexrainbow's answer at Phaser forum:
A new game object won’t be added to display list, or updating list,
call this method to add this container to display list.
this.add.existing(container2);

How can I add a menu screen that loads first to my Phaser.js game?

Im trying to add a simple menu to my Phaser game that loads first, then once someone clicks on a button the game actually starts. I can figure out how to add the buttons later, I just cannot figure out how to add the menu screen. Ive researched quite a few ways online on how to get this done but none have worked for me. I've also tried breaking the code up into different states but that didnt work for me either. Maybe I was doing it incorrectly. Can someone show me correct way to add a menu to my game that loads before the actual game does?
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>test</title>
<script src="//cdn.jsdelivr.net/npm/phaser#3.1.1/dist/phaser.js"></script>
<script type="text/javascript" src="menu.js"></script>
<style type="text/css">
body {
margin-top: 45px;
margin-left: 250px;
background-color: black;
}
.page-title {
color: white;
}
</style>
</head>
<body>
<script type="text/javascript">
//CONFIGURE GAME
var config = {
type: Phaser.AUTO,
width: 800,
height: 600,
physics: {
default: 'arcade',
arcade: {
gravity: { y: 300 },
debug: false
}
},
scene: {
preload: preload,
create: create,
update: update,
}
};
var player;
var stars;
var bombs;
var platforms;
var cursors;
var score = 0;
var gameOver = false;
var scoreText;
var game = new Phaser.Game(config);
game.state.add('title', title);
game.state.start('title');
//PRELOAD FUNCTION
function preload ()
{
this.load.image('sky', 'phaser_assets/sky.png');
this.load.image('background', 'phaser_assets/background.png');
this.load.image('ground', 'phaser_assets/platform.png');
this.load.image('star', 'phaser_assets/star.png');
this.load.image('bomb', 'phaser_assets/head1.png', { frameWidth: 48, frameHeight: 100 });
this.load.spritesheet('trump', 'phaser_assets/trump.png', { frameWidth: 48, frameHeight: 100 });
}
//CREATE FUNCTION
function create ()
{
// A simple background for our game
this.add.image(400, 300, 'sky');
// The platforms group contains the ground and the 2 ledges we can jump on
platforms = this.physics.add.staticGroup();
// Here we create the ground.
// Scale it to fit the width of the game (the original sprite is 400x32 in size)
platforms.create(400, 568, 'ground').setScale(2).refreshBody();
// Now let's create some ledges
platforms.create(600, 400, 'ground');
platforms.create(50, 250, 'ground');
platforms.create(750, 220, 'ground');
// The player and its settings
player = this.physics.add.sprite(100, 450, 'trump');
// Player physics properties. Give the little guy a slight bounce.
player.setBounce(0.2);
player.setCollideWorldBounds(true);
}
//UPDATE FUNCTION
function update ()
{
if (gameOver)
{
return;
}
if (cursors.left.isDown)
{
player.setVelocityX(-200);
player.anims.play('left', true);
}
else if (cursors.right.isDown)
{
player.setVelocityX(200);
player.anims.play('right', true);
}
else
{
player.setVelocityX(0);
player.anims.play('turn');
}
if (cursors.up.isDown && player.body.touching.down)
{
player.setVelocityY(-330);
}
}
</script>
</body>
</html>

How to take screenshot of game div in phaser

I am using this code now, but it returns a blank transparent image:
$(document).ready(function(){
$("#t").click(function() {
html2canvas(document.querySelector("#bracelet_maker"),
{ onrendered: function(canvas){
src = canvas.toDataURL();
window.open(src); } });
});
});
If I use game.canvas.toDataUrl(); it returns a black image.
This is how the game is started in #bracelet_maker div
var game = new Phaser.Game(width,height,Phaser.AUTO,"bracelte_canvas",{
preload:preload,
create:create,
update:update });
Using Phaser.AUTO will allow either Phaser.WEBGL or Phaser.CANVAS be used, depending upon what your browser supports.
If you switch over to Phaser.CANVAS when creating your new Phaser.Game you should be able to use access the canvas.
For example, within Phaser by binding off the S key:
function create() {
// ...
var screenshotKey = game.input.keyboard.addKey(Phaser.Keyboard.S);
screenshotKey.onDown.add(function () { window.open(game.canvas.toDataURL());
}
There's also preserveDrawingBuffer which should allow you capture from WebGL as well, but it needs to be set early on in the process.
var game = new Phaser.Game(800, 600, Phaser.AUTO, '', {
preload: preload, create: create, update: update
});
game.preserveDrawingBuffer = true;

Categories

Resources