I'm using TweenLite from greensock in a flex game. I have the requirement to perform some long animations where one object needs to go from x1 to x2 within hours. this is what im doing:
TweenLite.fromTo(obj, duration, {x:x1}, {x:x2});
When the animation starts immediately the cpu usage goes over 20% and remain this way untill the animation is over. since the animation could take a lot of time to complete i need something that doesnt affect the cpu usage so drastically.
any idea?
Related
I have been developing a game using Flex, and used the Timer class to keep the main loop going.
However, when I tried using the enterFrame event to do the main loop, there were a few problems.
First of all, physics simulation seemed way too fast. Is the enterFrame event called more than once per frame? I set the application's global frame rate to 24, so shouldn't the application set off the event every 1/24 of a second?
And the second problem is that when the game runs like this, some MXML components that are added are not shown. I have absolutely no idea why this happens.
Help me please?!?
Thanks.
Don't count on the framerate to be even, or that the enterframe is called at a fixed interval. Even the timer-class isn't 100% accurate.
When doing timings, always use the delta between frame-updates and use that delta for your calculations. Also be sure to put in a safe-guard that the delta never exceeds some value to avoid strange behavior when the flash application freezes up for some unexpected reason.
This article explains it all perfectly:
http://gafferongames.com/game-physics/fix-your-timestep/
The framerate is a desired value. If a user runs it on a slow machine, you might experience their output to be too slow. How about reverting to the good old
setInterval?
In MXML-based apps, you set the target framerate for the app and I believe this is a core part of Flash as well.
Two questions...
In many games you want the game to run as fast as it can for graphical smoothness, with some upper cap like 50-100Hz. How can you have variable framerates in Flash, or is it really not how things work?
What happens when an app cannot run at the target framerate? Do updates 'stack up' leading to other problems, or does Flash discard them?
I've a simple case where I'm moving a sprite from left to right at 100px/s, at 20fps it looks un-smooth. It's not jerky or anything, but you can clearly see the stepped motion, the artwork is black/white which accentuates it I think. I reckon a higher FPS is needed ideally, but on slower systems it might be too much and I don't want to run into nasty issues where I try to drive it too fast.
If the ActionScript takes too much time and the player can't maintain the frame rate that was specified, the frame rate just drops. There's nothing to stack up, you just get frames generated less often. For this reason when frame rate is important it's critical to make sure the AS code is not taking more time than you have available given the desired frame rate. Also make sure all calculates for movement are based on time and not frames.
As far as animation as 20fps, yeah, it will not look smooth. Bump up the frame rate. :-)
http://www.morearty.com/blog/2006/07/17/flex-tip-a-higher-frame-rate-even-makes-text-entry-look-better/
If Flash is unable to execute at the desired framerate, it will begin dropping frames. You can read the details of this here.
If you are dealing with framerates in Flash a lot, it can be helpful to understand the 'elastic racetrack' model that Flash uses. You can see details about it here, but the basic idea is that the amount of time spend executing code or rendering a frame can vary on a frame by frame basis.
I am trying to build animation based on mathematical formulae(speed varying with time as per equations)- hence am charting x,y coordinates with formulae on user provider values, rather than inbuilt functions
In doing that, am struggling to get the timer right. for e.g if I set
timer=new timer(1),
object.x=object.x+1
the object doesn't zoom past screen within a second (or 600 milliseconds)- takes closer to 6-7 second to cover the 600 odd pixels. presume screen update doesnt work as fast as timer ticks
Is there a way for me to set up, such that I can predict speed on screen so animation takes abt 30 seconds?
Its better to use ENTER_FRAME listener and do animation there, based on current time (getTimer()).
Update: see getTimer() docs:
http://www.adobe.com/livedocs/flash/9.0/ActionScriptLangRefV3/flash/utils/package.html#getTimer%28%29
Note the time when animation started. On each frame, subtract start time from current time. You get number of milliseconds passed. Compute coordinates/colors/rotations based on that number.
I have been involved in building a custum QGIS application in which live data is to be shown on the viewer of the application.
The IPC being used is unix message queues.
The data is to be refreshed at a specified interval say, 3 seconds.
Now the problem that i am facing is that the processing of the data which is to be shown is taking more than 3 seconds,so what i have done is that before the app starts to process data for the next update,the refresh QTimer is stopped and after the data is processed i again restart the QTimer.The app should work in such a way that after an update/refresh(during this refresh the app goes unresponsive) the user should get ample time to continue to work on the app apart from seeing the data being updated.I am able to get acceptable pauses for the user to work-- in one scenario.
But on different OS(RHEL 5.0 to RHEL 5.2) the situation is something different.The timer goes wild and continues to fire without giving any pauses b/w the successive updates thus going into an infinite loop.Handling this update data definitely takes longer than 3 sec,but for that very reason i have stopped-restarted the timer while processing..and the same logic works in one scenario while in other it doesnt.. The other fact that i have observed is that when this quick firing of the timer happens the time taken by the refreshing function to exit is very small abt 300ms so the start-stop of the timer that i have placed at the start-and-end of this function happens in that small time..so before the actual processing of the data finishes,there are 3-4 starts of the timer in queue waiting to be executed and thus the infinite looping problem gets worse from that point for every successive update.
The important thing to note here is that for the same code in one OS the refresh time is shown to be as around 4000ms(the actual processing time taken for the same amount of data) while for the other OS its 300ms.
Maybe this has something to do with newer libs on the updated OS..but I dont know how to debug it because i am not able to get any clues why its happening as such... maybe something related to pthreads has changed b/w the OSs??
So, my query is that is there any way that will assure that some processing in my app is timerised(and which is independent of the OS) without using QTimer as i think that QTimer is not a good option to achieve what i want??
What option can be there?? pthreads or Boost threads? which one would be better if i am to use threads as an alternate??But how can i make sure atleast a 3 second gap b/w successive updates no matter how long the update processing takes?
Kindly help.
Thanks.
If I was trying to get an acceptable, longer-term solution, I would investigate updating your display in a separate thread. In that thread, you could paint the display to an image, updating as often as you desire... although you might want to throttle the thread so it doesn't take all of the processing time available. Then in the UI thread, you could read that image and draw it to screen. That could improve your responsiveness to panning, since you could be displaying different parts of the image. You could update the image every 3 seconds based on a timer (just redraw from the source), or you could have the other thread emit a signal whenever the new data is completely refreshed.
In our game project we did have a timer loop set to fire about 20 times a second (the same as the application framerate). We use this to move some sprites around.
I'm wondering if this could cause problems and we should instead do our updates using an EnterFrame event handler?
I get the impression that having a timer loop run faster than the application framerate is likely to cause problems... is this the case?
As an update, trying to do it on EnterFrame caused very weird problems. Instead of a frame every 75ms, suddenly it jumped to 25ms. Note, it wasn't just our calculation claimed the framerate was different, suddenly the animations sped up to a crazy rate.
I'd go for the Enter frame, in some special cases it can be useful to have two "loops" one for logic and one for the visuals, but for most games I make I stick to the Enter frame-event listener. Having a separate timer for moving your stuff around is a bit unnecessary since having it set to anything except the framerate would make the motion either jerky or just not visible (since the frame is not redrawn).
One thing to consider however is to decouple your logic from the framerate, this is most easily accomplished by using getTimer (available in both as2 and as3) to calculate the time that has expired since the last frame and adjusting the motions or whatever accordingly.
A timer is no more reliable than the enter frame event, flash will try to keep up with whatever rate you've set, but if you're doing heavy processing or complex graphics it will slow down, both timers and framerate.
Here's a rundown of how Flash handles framerates and why you saw your content play faster.
At the deepest level, whatever host application that Flash is running in (the browser usually) polls flash at some interval. That interval might be every 10ms in one browser, or 50ms in another. Every time time that poll occurs, Flash does something like this:
Have (1000/framerate) miliseconds passed since the last frame update?
If no: do nothing and return
If yes: Execute a frame update:
Advance all (playing) timelines one frame
Dispatch all events (including an ENTER_FRAME event
Execute all frame scripts and event handlers with pending events
Draw screen updates
return
However, certain kinds of external events (such as keypresses, mouse events, and timer events) are handled asynchronously to the above process. So if you have an event handler that fires when a key is pressed, the code in that handler might be executed several times between frame updates. The screen will still only be redrawn once per frame update, unless you use the updateAfterEvent() method (global in AS2, attached to events in AS3).
Note that the asynchronous behavior of these events does not affect the timing of frame updates. Even if you use timer events to, for example, redraw the screen 50 times per second, frame animations will still occur at the published framerate, and scripted animations will not execute any faster if they're driven by the enterFrame event (rather than the timer).
The nice thing about using enter frame events, is your processing will degrade at the same pace as the rendering and you'll get a screen update right after the code block finishes.
Either method isn't guaranteed to occur at a specific time interval. So your event handler should be determining how long it's been since it last executed, and making decisions off of that instead of purely how many times it's run.
I think timerEvent and Enter Frame are both good options, I have used both of them in my games. ( Did you mean timerEvent by timer loop? )
PS: notice that in slow machines the timer may not refresh quick enough, so you may need to adjust your code to make game work "faster" in slow machines.
I would suggest using a class such as TweenLite ( http://blog.greensock.com/tweenliteas3/ ) which is lightweight at about 3kb or if you need more power you can use TweenMax, which i believe is 11kb. There are many advantages here. First off, this "engine" has been thoroughly tested and benchmarked and is well known as one of the most resource friendly ways to animate few or even many things. I have seen a benchmark, where in AS3, 1,500 sprites are being animated with TweenLite and it holds a strong 20 fps, as where competitors like Tweener would bog down to 9 fps http://blog.greensock.com/tweening-speed-test/. The next advantage is the ease of use as I will demonstrate below.
//Make sure you have a class path pointed at a folder that contains the following.
import gs.TweenLite;
import gs.easing.*;
var ball_mc:MovieClip = new MovieClip();
var g:Graphics = ball_mc.graphics;
g.beginFill(0xFF0000,1);
g.drawCircle(0,0,10);
g.endFill();
//Now we animate ball_mc
//Example: TweenLite.to(displayObjectName, totalTweeningTime, {someProperty:someValue,anotherProperty:anotherValue,onComplete:aFunctionCalledWhenComplete});
TweenLite.to(ball_mc, 1,{x:400,alpha:0.5});
So this takes ball_mc and moves it to 400 from its current position on the x axis and during that same Tween it reduces or increases the alpha from its current value to 0.5.
After importing the needed class, it is really only 1 line of code to animate each object, which is really nice. We can a also affect the ease, which I believe by default is Expo.easeOut(Strong easeOut). If you wanted it to bounce or be elastic such effects are available just by adding a property to the object as follows.
TweenLite.to(ball_mc, 1,{x:400,alpha:0.5,ease:Bounce.easeOut});
TweenLite.to(ball_mc, 1,{x:400,alpha:0.5,ease:Elastic.easeOut});
The easing all comes from the gs.easing.* import which I believe is Penner's Easing Equations utilized through TweenLite.
In the end we have no polling (Open loops) to manage such as Timer and we have very readable code that can be amended or removed with ease.
It is also important to note that TweenLite and TweenMax offer far more than I have displayed here and it is safe to say that I use one of the two classes in every single project. The animations are custom, they have functionality attached to them (onComplete: functionCall), and again, they are optimal and resource friendly.