forleafe Posted June 2, 2017 Share Posted June 2, 2017 Obviously this isn't optimal. Was wondering if maybe I'm doing something wrong? I have a standard game loop that's managed by requestAnimationFrame(gameLoop); and within my gameloop I have a function that moves each enemy like so: enemy.position.y += 6 I don't really know what to do to keep my movement speed from varying so dramatically across different devices. Another issue that might be related, over time my sprite movement becomes gradually faster and choppier. This is the part that really really bothers me. Any help or insight would be deeply appreciated. Quote Link to comment Share on other sites More sharing options...
Taz Posted June 2, 2017 Share Posted June 2, 2017 The easier way is to create an Application and use its ticker, like in this Pixi Example. It rotates the sprite but the same concept applies to moving it: enemy.position.y += delta * 6; Or you can do it like this for example using requestAnimationFrame (enemy.velocity.y is in pixels per millisecond in this example): var lastTime = 0; requestAnimationFrame(update); function update(time) { var deltaTime = 0; if (lastTime) { deltaTime = time - lastTime; } lastTime = time; enemy.position.y += deltaTime * enemy.velocity.y; renderer.render(stage); requestAnimationFrame(update); } Quote Link to comment Share on other sites More sharing options...
forleafe Posted June 2, 2017 Author Share Posted June 2, 2017 I thought I'd post this here as well. You can see at a certain point (top graph) towards the last 4th the framerate just shoots through the roof. And around then is when my sprites begin moving so fast that they actually begin to flicker. Quote Link to comment Share on other sites More sharing options...
forleafe Posted June 2, 2017 Author Share Posted June 2, 2017 13 minutes ago, Jinz said: The easier way is to create an Application and use its ticker, like in this Pixi Example. It rotates the sprite but the same concept applies to moving it: enemy.position.y += delta * 6; Or you can do it like this for example using requestAnimationFrame (enemy.velocity.y is in pixels per millisecond in this example): var lastTime = 0; requestAnimationFrame(update); function update(time) { var deltaTime = 0; if (lastTime) { deltaTime = time - lastTime; } lastTime = time; enemy.position.y += deltaTime * enemy.velocity.y; renderer.render(stage); requestAnimationFrame(update); } Okay, I'm kind of getting this. But what exactly is "time" I don't see it defined anywhere? It's just first just passed into your update function. Another thing I'm not quite understanding is your conditional. if(lastTime) ... If lastTime what? It's declared as number, 0. How can a number ever evaluate to "true"? I guess the general concept of this I'm missing a little bit of too. Thanks so much for your help btw. Quote Link to comment Share on other sites More sharing options...
themoonrat Posted June 2, 2017 Share Posted June 2, 2017 So, I'd _really_ recommend using the built in pixi stuff for this as Jinz suggested, as it'll give you all the information you need to use , and again I'll link to the example page; please read the code, it has comments explaining exactly what you want to know: https://pixijs.github.io/examples/#/basics/basic.js Note how it's added a function to the ticker ... this could be your function to do all your game update stuff. Also note how it multiplies the rotation speed by the delta. The delta here is your critical friend in helping you deal with different framerates on different devices. If your game is running at 60fps, and your target frame rate is 60fps, then the delta will be 1. So, in this case, multiplying your position change by 1 does nothing. But imagine the game is only running at half speed, 30fps. Well, the delta sent through now is 2. This is just what you need! You're function is being hit half the amount of times, so it needs to move your sprite double the amount each time. Quote Link to comment Share on other sites More sharing options...
forleafe Posted June 2, 2017 Author Share Posted June 2, 2017 23 minutes ago, themoonrat said: So, I'd _really_ recommend using the built in pixi stuff for this as Jinz suggested, as it'll give you all the information you need to use , and again I'll link to the example page; please read the code, it has comments explaining exactly what you want to know: https://pixijs.github.io/examples/#/basics/basic.js Note how it's added a function to the ticker ... this could be your function to do all your game update stuff. Also note how it multiplies the rotation speed by the delta. The delta here is your critical friend in helping you deal with different framerates on different devices. If your game is running at 60fps, and your target frame rate is 60fps, then the delta will be 1. So, in this case, multiplying your position change by 1 does nothing. But imagine the game is only running at half speed, 30fps. Well, the delta sent through now is 2. This is just what you need! You're function is being hit half the amount of times, so it needs to move your sprite double the amount each time. Thanks for that. my only question is the "delta" bit that they passed in. Does pixi automatically know what that variable is and how to keep track of it? I don't see it declared anywhere. I'm also reading this example code under the assumption that everything added to the "ticker" function will be run regularly with every cycle? Quote Link to comment Share on other sites More sharing options...
themoonrat Posted June 2, 2017 Share Posted June 2, 2017 The ticker uses requestAnimationFrame in the background. Internally, it makes a record of the last time requestAnimationFrame fired, and compares it with the latest time the requestAnimationFrame fired. It compares those 2 times, looks at your target frame rate (60fps by default) and therefore knows what the delta is. When you add your function to the ticker, when requestAnimationFrame comes through, the ticker does it's calculations, then calls your function, also passing through the delta as it's first parameter. Quote Link to comment Share on other sites More sharing options...
forleafe Posted June 5, 2017 Author Share Posted June 5, 2017 On 6/2/2017 at 4:06 PM, themoonrat said: The ticker uses requestAnimationFrame in the background. Internally, it makes a record of the last time requestAnimationFrame fired, and compares it with the latest time the requestAnimationFrame fired. It compares those 2 times, looks at your target frame rate (60fps by default) and therefore knows what the delta is. When you add your function to the ticker, when requestAnimationFrame comes through, the ticker does it's calculations, then calls your function, also passing through the delta as it's first parameter. Maybe you could possibly help me change up my code to utilize the ticker. Having a bit of trouble getting my head around it. so my current code works with a gameloop that loops itself using requestAnimationFrame() like so... function gameLoop(){ requestAnimationFrame(gameLoop); gameState(); renderer.render(stage); }; Other parts of my code will call the gameLoop. A few examples include a song loader that changes the gamestate to a loading screen and then calls the gameloop to display said loading screen. Another is my setup function that calls the gameloop when it's finished initializing variables. I've looked at the pixi documentation... but I guess I don't really understand how to replicate this usage with the ticker. So far what I've done is tried formatting my code like this: renderer.ticker.add(function(delta){ state(); renderer.render(stage); }); But again, I can't really seem to call anything when I need it. The ticker just appears to run once, render my renderer, and then that's it. It doesn't do anything more. I've tried using PIXI.ticker.Ticker.start() but that doesn't seem to do anything either. Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted June 5, 2017 Share Posted June 5, 2017 Are you going to use Application class, like in github examples or not? I can provide you with code if you answer that one Quote Link to comment Share on other sites More sharing options...
forleafe Posted June 5, 2017 Author Share Posted June 5, 2017 I have, yes. I was previously using autoDetectRenderer(); but I went ahead and changed that. Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted June 5, 2017 Share Posted June 5, 2017 then you dont have to add "render" method, just app.ticker.add(function(delta) { do_your_physics_here }); Quote Link to comment Share on other sites More sharing options...
forleafe Posted June 5, 2017 Author Share Posted June 5, 2017 25 minutes ago, ivan.popelyshev said: then you dont have to add "render" method, just app.ticker.add(function(delta) { do_your_physics_here }); I went ahead and did that. The main issue turned out to be how PIXI.Application deals with the "stage". It apparently creates one and you don't have to. So I had to add everything using renderer.stage.addChild(); where renderer is my variable for PIXI.Application My only other issue that you might be able to help with... since switching from autoDetectRenderer to Application. renderer.width is coming up undefined. Is there not an easy way I can just grab a number value for the width of the renderer? I have no clue why it's coming up undefined suddenly from just switching to Application like that. Quote Link to comment Share on other sites More sharing options...
Taz Posted June 5, 2017 Share Posted June 5, 2017 1 hour ago, forleafe said: I went ahead and did that. The main issue turned out to be how PIXI.Application deals with the "stage". It apparently creates one and you don't have to. So I had to add everything using renderer.stage.addChild(); where renderer is my variable for PIXI.Application My only other issue that you might be able to help with... since switching from autoDetectRenderer to Application. renderer.width is coming up undefined. Is there not an easy way I can just grab a number value for the width of the renderer? I have no clue why it's coming up undefined suddenly from just switching to Application like that. The renderer is property of Application. The way you have yours named, you would have to do renderer.renderer.width to get the renderer's width. But if you name it application like the examples, then you can use application.renderer.width to get the renderer's width and application.stage.addChild to add to the stage. Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted June 5, 2017 Share Posted June 5, 2017 There's "application.screen.width" for that cause Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.