I used TexturePacker to create a spritesheet with a JSON file, this is my bit of code:
var game = new Phaser.Game(800, 600, Phaser.AUTO, '', {
preload: preload,
create: create,
update: update
});
function preload() {
game.load.atlas('seyan_f_torch', '../sprite_hashes/seyan_f_torch.png', '../sprite_hashes/seyan_f_torch.json');
};
function create() {
var seyan_f_torch = game.add.sprite(20, 20, 'seyan_f_torch', '00219001.png');
console.log(Phaser.Animation.generateFrameNames('00', 219016, 219023, ''));
seyan_f_torch.animations.add('walk-s', Phaser.Animation.generateFrameNames('00', 219016, 219023, '.png'), 10, true);
// seyan_f_torch.animations.play('walk-s');
};
function update() {
};
Everything works fine and this is the bit of json code:
"00219001.png":
{
"frame": {"x":782,"y":139,"w":37,"h":58},
"rotated": true,
"trimmed": true,
"spriteSourceSize": {"x":39,"y":67,"w":37,"h":58},
"sourceSize": {"w":120,"h":240},
"pivot": {"x":0.5,"y":0.5}
},
But when the image loads it loads like this:
Any information on how to get it to turn the right way would be great thanks.
Edit:
It appears Phaser does not have support for rotated atlas so if you use Texture pack in my case, uncheck rotate images.
https://github.com/photonstorm/phaser/issues/2359#issuecomment-189161540
From the Phaser forum:
// Set anchor to the center of your sprite
sprite.anchor.setTo(.5, .5);
// Invert scale.x to flip left/right
sprite.scale.x *= -1;
// Invert scale.y to flip up/down
sprite.scale.y *= -1;
Related
The game I'm creating doesn't require any physics, however you are able to interact when hovering over/clicking on the sprite by using sprite.setInteractive({cursor: "pointer"});, sprite.on('pointermove', function(activePointer) {...}); and similar. However I noticed two issues with that:
The sprite has some area which are transparent. The interactive functions will still trigger when clicking on those transparent areas, which is unideal.
When playing a sprite animation, the interactive area doesn't seem to entirely (at all?) change, thus if the sprite ends on a frame bigger than the previous, there end up being small areas I can't interact with.
One option I thought of was to create a polygon over my sprite, which covers the area I want to be interactive. However before I do that, I simply wanted to ask if there are simpler ways to fix these issues.
Was trying to find an answer for this myself just now..
Think Make Pixel Perfect is what you're looking for.
this.add.sprite(x, y, key).setInteractive(this.input.makePixelPerfect());
https://newdocs.phaser.io/docs/3.54.0/focus/Phaser.Input.InputPlugin-makePixelPerfect
This might not be the best solution, but I would solve this problem like this. (If I don't want to use physics, and if it doesn't impact the performance too much)
I would check in the event-handler, if at the mouse-position the pixel is transparent or so, this is more exact and less work, than using bounding-boxes.
You would have to do some minor calculations, but it should work well.
btw.: if the origin is not 0, you would would have to compensate in the calculations for this. (in this example, the origin offset is implemented)
Here is a demo, for the click event:
let Scene = {
preload ()
{
this.load.spritesheet('brawler', 'https://labs.phaser.io/assets/animations/brawler48x48.png', { frameWidth: 48, frameHeight: 48 });
},
create ()
{
// Animation set
this.anims.create({
key: 'walk',
frames: this.anims.generateFrameNumbers('brawler', { frames: [ 0, 1, 2, 3 ] }),
frameRate: 8,
repeat: -1
});
// create sprite
const cody = this.add.sprite(200, 100).setOrigin(0);
cody.play('walk');
cody.setInteractive();
// just info text
this.mytext = this.add.text(10, 10, 'Click the Sprite, or close to it ...', { fontFamily: 'Arial' });
// event to watch
cody.on('pointerdown', function (pointer) {
// calculate x,y position of the sprite to check
let x = (pointer.x - cody.x) / (cody.displayWidth / cody.width)
let y = (pointer.y - cody.y) / (cody.displayHeight / cody.height);
// just checking if the properties are set
if(cody.anims && cody.anims.currentFrame){
let currentFrame = cody.anims.currentFrame;
let pixelColor = this.textures.getPixel(x, y, currentFrame.textureKey, currentFrame.textureFrame);
// alpha > 0 a visible pixel of the sprite, is clicked
if(pixelColor.a > 0) {
this.mytext.text = 'Hit';
} else {
this.mytext.text = 'No Hit';
}
// just reset the textmessage
setTimeout(_ => this.mytext.text = 'Click the Sprite, or close to it ...' , 1000);
}
}, this);
}
};
const config = {
type: Phaser.AUTO,
width: 400,
height: 200,
scene: Scene
};
const game = new Phaser.Game(config);
<script src="https://cdn.jsdelivr.net/npm/phaser#3.55.2/dist/phaser.js"></script>
I am creating an instructional slideshow with HTML5 canvas. Each slide has animated 2D elements moving an scaling and a navigation pointing to each slide. Ultimately, I'd like to create this without using Animate CC, just incase the program goes away and I'd have to start from scratch if edits need to be made (like Edge files). I'd like to manually code this with HTML5, CSS, and JavaScript preferably utilizing CreateJS.
I've located tutorials on simple slideshows and animated transitions, but I'm moreso looking for animation taking place in each slide or scene.
Is this possible? Is there a tutorial out there? Thank you in advance.
You absolutely don't have to use Adobe Animate to create animated content with CreateJS.
Here is a revised version of #hadders's code using CreateJS. Note that you need to use 1.0 to get the "yoyo" effect, which TweenJS calls "bounce"
var stage, bmp;
function init() {
stage = new createjs.Stage("canvas");
createjs.Ticker.on("tick", stage);
bmp = new createjs.Bitmap("https://s3-us-west-2.amazonaws.com/s.cdpn.io/56901/dog_1_small.jpg");
bmp.set({ x: 50, y: 50, alpha: 1});
stage.addChild(bmp);
createjs.Tween.get(bmp, {loop:-1, bounce:true}).to({
alpha: 0,
x:500,
y:400
}, 1000);
}
init();
Here is a fiddle with it in action: https://jsfiddle.net/8xmy6xuw/
Cheers,
Use a library such as GSAP. Create an object which contains the coords which you'll use to position the canvas elements e.g. {x:100, y:100} then use GSAP to tween the x/y values of the object. The canvas element can then be positioned/animated using this tweened coord object.
This seems like a decent enough example :
https://codepen.io/jonathan/pen/ychlf
HTML
<div id="canvas-wrapper">
<canvas id="canvas" width="800" height="600">canvas not supported</canvas>
</div>
JS
var ctx, img;
function init() {
ctx = document.getElementById("canvas").getContext("2d");
img = new Image();
img.src = "https://s3-us-west-2.amazonaws.com/s.cdpn.io/56901/dog_1_small.jpg";
img.xpos = 50;
img.ypos = 50;
img.globalAlpha = 1.0;
img.onload = function() {
TweenLite.ticker.addEventListener("tick",loop);
}
TweenMax.to(img, 1 ,{
globalAlpha:0,
xpos:500,
ypos:400,
repeat:-1,
yoyo:true
});
}
function loop(){
ctx.clearRect(0,0,800,600);
ctx.globalAlpha = img.globalAlpha;
ctx.drawImage(img, img.xpos, img.ypos);
}
init();
hope that helps
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;
My goal is to make a sprite bigger than the screen and have the user scroll to see the different parts of it, so I wanted to ask if Phaser had any sprite eventListener-functions such as:
var canvas = window.document.getElementsByTagName('canvas')[0],
prevX = 0, prevY = 0, mouseDown = false;
where canvas can be used as
canvas.addEventListener('mousedown',function(e){
});
canvas.addEventListener('mousemove',function(e){
});
Here is how I did it.
In your update function:
if (this.game.input.activePointer.isDown) {
if (this.game.origDragPoint) {
// move the camera by the amount the mouse has moved since last update
this.game.camera.x += this.game.origDragPoint.x - this.game.input.activePointer.position.x;
this.game.camera.y += this.game.origDragPoint.y - this.game.input.activePointer.position.y;
}
// set new drag origin to current position
this.game.origDragPoint = this.game.input.activePointer.position.clone();
}
else {
this.game.origDragPoint = null;
}
If using the camera is OK for you, you can try this Phaser 2 plugin: https://jdnichollsc.github.io/Phaser-Kinetic-Scrolling-Plugin/
With this plugin you can enable vertical and horizontal scroll to simulate scrolling into the canvas element used by Phaser, also you can customize the movement before to initialize the plugin, example:
var game = new Phaser.Game(400, 400, Phaser.AUTO, '', {
init: function () {
//Load the plugin
this.game.kineticScrolling = this.game.plugins.add(Phaser.Plugin.KineticScrolling);
},
create: function () {
//Configure the plugin
this.game.kineticScrolling.configure({
kineticMovement: true,
timeConstantScroll: 325, //really mimic iOS
horizontalScroll: true,
verticalScroll: false,
horizontalWheel: true,
verticalWheel: false,
deltaWheel: 40
});
//Starts the plugin
this.game.kineticScrolling.start();
//Changing the world size
this.game.world.setBounds(0, 0, 800, 800);
},
stopScrolling: function () {
//Stop the plugin
this.game.kineticScrolling.stop();
}
});
Also there's a fork for Phaser 3, check the repo from GitHub.
Regards, Nicholls
So I am working on a simple android app using Phaser. But I was looking if it is possible to create a loading screen that uses a spritesheet animation or programmatically do an animation other than just a simple crop how phaser does it?
this.preloadBar = this.add.sprite(50, 170, 'preloaderBar');
this.load.setPreloadSprite(this.preloadBar);
Thanks in advance :)
In order to achieve that, i have a boot state where i initialise various game related utilities and the sprite i want to have during the loading screen. Then i just load the preloader state where everything else is being loaded and i just put the previous sprite on the screen. When everything finishes, main game, or menu state starts.
Here is an example:
Test.Boot.prototype = {
init: function () {
//general game config like scaleManager
},
preload: function () {
this.game.stage.backgroundColor = '#000000';
// the sprite you want to show during loading
this.game.load.atlasJSONHash('logo', 'asset/images/hand.png', 'asset/images/hand.json');
},
create: function () {
this.state.start('Preloader');
}
};
// Preloader.js
Test.Preloader.prototype = {
preload: function() {
//add the animation
this.logo = this.add.sprite(this.world.width/2, this.world.height/2, 'logo');
this.logo.anchor.set(0.5, 0.5);
this.logo.animations.add('shake',[8,9,10,11,12,13,14,15,16,17,17,8,9,8]);
this.logo.animations.play('shake', 60, true);
//load all the other assets
this.game.load.image("hero", "asset/images/hero.png");
this.game.load.image("clouds", "asset/images/sky3.jpg");
//this.game.load.image("rope", "asset/images/rope.png");
this.game.load.atlasJSONHash('items', 'asset/images/items.png', 'asset/images/items.json');
this.game.load.physics('physicsData', 'asset/images/polygon.json');
},
create: function() {
this.game.stage.backgroundColor = '#1589FF';
//A simple fade out effect
this.game.time.events.add(Phaser.Timer.SECOND * 2.0, function() {
var tween = this.add.tween(this.logo)
.to({alpha: 0}, 750, Phaser.Easing.Linear.none);
tween.onComplete.add(function() {
this.logo.destroy();
this.startGame();
}, this);
tween.start();
}, this);
},
startGame: function() {
this.state.start('MainMenu');
},
};
There is a video tutorial with similar technique here if you want to know more.