There is a way to prevent the initial "fall" of sprites in Phaser 3? - phaser-framework

Day 3 in Phaser and I'm trying to avoid the initial "fall from the sky" of the assets.
I initialized it like this:
this.kid = this.physics.add.sprite(50, 380, 'idle');
but when reload the game, the sprites fall from sky until touch the ground. Any suggestion?

I think you have a gravity Y set to some positive value.
You can set it to 0 in the config to avoid things falling.
new Phaser.Game({
physics: {
default: 'arcade',
arcade: {
gravity: { y: 0 }
}
}
})
I suggest you to follow the tutorial "Making your first Phaser 3 game".
In part6 there is the part about gravity.

Related

Animation for a canvas object

I'm trying to use an animation for a sudoku app. I want for everytime i insert a wrong number, that number would change color and it's scale.
My code is:
override fun onDraw(canvas: Canvas?) {
canvas ?: return
drawBoard(canvas)
drawNumberProblem(canvas)
}
private fun drawNumberProblem(canvas: Canvas){
paint.color=darkcolor
paint.textSize = cellSide*3/4
SudokuGame.numbersproblem.forEach { e->
canvas.drawText("${e.number}", originX + e.col * cellSide+cellSide/5, originX + (e.row+1) * cellSide-cellSide/10, paint)
}
}
And i tried:
private fun initAnimation() {
var animation = RotateAnimation(0f, 360f, 150f, 150f)
animation.setRepeatCount(Animation.INFINITE)
animation.setRepeatMode(Animation.RESTART)
animation.setDuration(7500L)
animation.interpolator = LinearInterpolator()
startAnimation(animation)
}
override fun onDraw(canvas: Canvas?) {
canvas ?: return
if(animation==null)
initAnimation()
drawBoard(canvas)
drawNumberProblem(canvas)
}
private fun drawNumberProblem(canvas: Canvas){
paint.color=darkcolor
paint.textSize = cellSide*3/4
SudokuGame.numbersproblem.forEach { e->
canvas.drawText("${e.number}", originX + e.col * cellSide+cellSide/5, originX + (e.row+1) * cellSide-cellSide/10, paint)
}
}
The animation, the board and the numbers are all good. The animation is only an example, i tried to rotate it to see if it's working. But the only problem is that the animation is working for the whole board, i want to have animation only over numbers.
Is there any way to create a initAnimation with a parameter like initAnimation(drawNumberProblem())?
I am new to kotlin animation, so i don't really care about the best way to do it, i want to find a simple way to understand it.
Thanks
If each cell is its own View (say a TextView) you can animate it the way you're trying to, and the animation framework will take care of the timing, the rotation and scaling, etc. Because each view is separate, they can all be animated independently, using Android's view animation libraries, and a lot of the work is taken care of for you - it's pretty easy to use!
If it's all one view, and you're drawing a bunch of elements which can all be animated, you have to keep track of those elements, any animations that should be happening to each one, and how each animation's state affects the element when it comes time to draw it. Instead of each view having its own state and being drawn separately, you have to draw the whole thing at once, because it's a single view. So you need to keep track of those individual element states yourself, so you can refer to them when drawing the current overall state.
So for example, say you've got an animation where an element needs to scale to 2x the size and then back to normal, and it runs for 1 second total (1000ms). When you come to draw that element, you need to know how far along that animation you are at that moment, so you can scale it appropriately, and draw it at the correct size.
There are lots of ways to do this, probably some smarter ones, but this is the most basic hands-on example I think. I'm not testing this, but hopefully it gives you the idea:
// for brevity, so we can just say "now" instead of writing out the whole function call
val now: Long get() = System.currentTimeMillis()
// store a start time for each grid cell (or null if there's no anim running)
val animStartTimes = Array(CELL_COUNT)<Long?>
val animLength = 1000 // millis
// Basic function to start an animation - you could adapt this to prevent restarts
// while an anim is already running, etc
fun startAnim(cellIndex: Int) {
animStartTimes[cellIndex] = now
// tell the view it needs to redraw (since we're animating something now)
invalidate()
}
// Get the current progress of an animation in a cell, from 0% to 100% (0.0 to 1.0)
// I'm treating a finished item as "reset" to its original state
fun getAnimProgress(cellIndex: Int): Float {
val start = animStartTimes[cellIndex]
if (start == null) return 0f
val progress = (now - start) / animLength
if (progress > 1f) {
// animation has ended (past 100% of its runtime) so let's clear it
animStartTimes[cellIndex] = null
return 0f // like I said, I'm treating finished animations as "reset" to 0%
} else return progress
}
override fun onDraw(canvas: Canvas) {
// this flag can be set to true if we find an element that's still animating,
// so we can decide whether to call invalidate() again (forcing a redraw next frame)
var animating = false
items.forEachIndexed { i, item ->
val animProgress = getAnimProgress(i)
if (animProgress > 0f) animating = true // set that flag
// now you need to use that 0.0-1.0 value to calculate your animation state,
// e.g. adjusting the text size by some factor - 0.0 should produce your "default" state
}
// finally, force a redraw next frame if necessary - only do this when your view
// contents might need to change, otherwise you're wasting resources
if (animating) invalidate()
}
I hope that makes sense - obviously I haven't shown how to actually draw the states of your animation, that depends on exactly what you're doing - but that's the basics of it. It's a lot more work than using view animation, but it's not too bad when you get the idea.
The drawing part is a little more complex, and you'll probably want to get familiar with manipulating the Canvas - e.g. to draw a rotated character, you turn the canvas, draw the character as normal, then undo the canvas rotation so it's the right way up again, and the character is tilted. I don't have time to look for any tutorials about it, but this article covers the matrix operations that scale/rotate/etc the canvas
So yeah, it's a bit involved - and depending on what you want to do, a grid of TextViews might be a better shout

Anchored sprite lags when the underlying sprite moves in Phaser

On this link there is an example of a game developed using Phaser
http://examples.phaser.io.
Your tank is a sprite with a turret sprite anchored on it:
// The base of our tank
tank = game.add.sprite(0, 0, 'tank', 'tank1');
tank.anchor.setTo(0.5, 0.5);
...
// Finally the turret that we place on-top of the tank body
turret = game.add.sprite(0, 0, 'tank', 'turret');
turret.anchor.setTo(0.3, 0.5);
..
Also notice the following in the update function that executes every frame:
turret.x = tank.x;
turret.y = tank.y;
Notice that when you accelerate, the turret lags a bit and catches up with the underlying tank sprite only when you reach zero velocity. How to fix this?
a little bit late.. you should consider that your sprite uses physics that renders in various sections. Try to see API DOCs preUpdate, postUpdate, Phaser.World.
So, in your case, if you use for instance ARCADE Physics, you should reload data of your x,y via body which belongs to arcade.physics, not other.
tank = game.add.sprite(0, 0, 'tank', 'tank1');
tank.anchor.setTo(0.5, 0.5);
game.physics.enable(tank, Phaser.Physics.ARCADE);
......
turret.x = tank.body.x;
turret.y = tank.body.y;

Spritebuilder sprite position changes

I have my game in spritebuilder, and I am trying to move a ball up every 0.005 seconds. I have an NSTimer doing that, but sometimes ball.position.y + 2 is different.
For instance, one time I play the game, the ball moves to the top of the screen at the speed I want it to. Then, without even closing the game, just opening the scene again, the ball moves at half of the speed, as if + 2 isn't as much at that time, or the NSTimer decides to run at half speed.
NOTE: This only happens on an actual device. I can't get it to happen in a simulator.
Does anyone know why this is happening?
Thanks.
EDIT: My code (abridged):
timer2 = NSTimer.scheduledTimerWithTimeInterval(0.005, target: self, selector: "updateTick", userInfo: nil, repeats: true)
My update function:
func updateTick() {
...
incrementBalls()
...
}
My incrementBalls() function:
for index in 0...balls.count - 1 {
balls[index].position = ccpAdd(_physicsBody.position, CGPoint(x: balls[index].position.x, y: balls[index].position.y + 2))
}
I fixed this by instead using the update method and doing some math to move the balls instead of the unreliable NSTimer.

Phaser P2 body.collideWorldBounds stops body collisions

I'm using Phaser 2.4.2 with P2 physics. I have a sort of jar shaped body containing some circular bodies (balls). I want to move the jar offscreen but the balls are colliding with the world bounds.
I tried setting collideWorldBounds on the balls like so:
ball.body.setCircle(64);
ball.body.collideWorldBounds = false;
but this stops them colliding with the jar which I want -- the result is gravity makes them drop offscreen.
You can see a demo here: https://output.jsbin.com/vuyexo
Click the red button to make the jar move.
Uncomment collideWorldBounds=false in the 'balls' section.
Why is this happening and how can I make the balls collide with the jar body but not the world bounds when the jar is moved offscreen?
You can set the P2 world bounds using setBoundsToWorld so like this
//..
game.physics.p2.gravity.y = 300;
game.physics.p2.setBoundsToWorld(false, false, true, true); // left=false, right=false, top=true, bottom=true
Alternatively you could just make the P2 world larger, so for example make the width 2000 instead of 768.
game.world.setBounds(0, 0, 2000, 1024);
By default p2 collides everything with everything else, but if you want it to do something different then you have to explicitly list which objects collide with each other by adding each body to a collision group and then calling body.collides like this:
var jarCG = this.physics.p2.createCollisionGroup();
var ballsCG = this.physics.p2.createCollisionGroup();
jar.body.setCollisionGroup(jarCG);
jar.body.collides(ballsCG);
for (var i = 0; i < 9; i++)
{
var ball = balls.create(250+(i%3)*128,300+Math.floor(i/3)*128);
ball.body.setCircle(64);
ball.body.debug = true;
ball.body.collideWorldBounds = false;
ball.body.setCollisionGroup(ballsCG);
ball.body.collides([jarCG, ballsCG]);
}
This is working for me, but using a tween to move the jar still makes the physics act weird. You can fix it by either using jar.body.velocity.x instead of tweening or by also tweening all the balls. You can also try tweening stack.x if you just want to move the sprites, but for some reason this isn't moving their bodies.

background tileSprite is over sized

I'm creating a simple platform game with the phaser framework. I've added to background images as tileSprites to provide a parallax background. They are both showing in game, however they are over sized, roughly double the height I expect.
Sprite asset size - 2048 x 1024
Game world size - 2400 x 1024
Adding the tileSprite
preload: function () {
this.load.image('far-background', 'assets/far-background.png');
this.load.image('near-background', 'assets/near-background.png');
},
create: function () {
this.farBackground = this.add.tileSprite(0,0, 2400, 1024, 'far-background');
this.nearBackground = this.add.tileSprite(0,0, 2400, 1024, 'near-background');
}
How do I make the tilesprites fill the canvas vertically?
Full code can be found here if needed.
Any help much appreciated.
If you have (tile)sprites in the game that are too big, you can try using the scale property to manipulate their size: http://phaser.io/docs/2.2.2/Phaser.TileSprite.html#scale
Here is an example of using the scale property to manipulate a sprite's size: http://phaser.io/examples/v2/sprites/scale-a-sprite
Hope this helps :)

Resources