Animation flickering problem - flicker

This is the game loop in my code and the drawing code:
float frames_per_second = 60;
display_timer = al_create_timer(1/frames_per_second);
queue = al_create_event_queue();
al_register_event_source(queue, al_get_timer_event_source(display_timer));
al_start_timer(display_timer);
while(!end_game)
{
ALLEGRO_EVENT event;
al_wait_for_event(queue, &event);
if(event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) break;
if(event.any.source == al_get_timer_event_source(display_timer))
{update_display();}
update_input();
}
void update_display()
{
al_clear_to_color(al_map_rgb(255, 255,255));
draw_objects(); //this is just an al_draw_bitmap() call
al_flip_display();
}
The animation created by moving objects on screen flickers, I'm surprised by this since I write to the back buffer of the screen thus I expect double buffering. What can I do to correct the flickering? Thanks.

Unrelated to the problem, you can check a timer by looking for the ALLEGRO_EVENT_TIMER event. You can use event.timer.source to check which timer it is, if you have more than one.
I think the main problem here is that you are drawing the graphics at 60fps but you are updating the input at an unlimited rate. This is actually backwards. You want to update the input at a fixed rate. You can draw the graphics as often as you like... although it makes no sense to update the graphics if nothing has changed.
So it should look something more like:
if(event.type == ALLEGRO_EVENT_TIMER)
{
update_input();
update_display();
}
However, this does not implement frame skipping if things get too slow. What you should do is set up the timer in a dedicated queue (that contains no other event sources). Then as long as there are events sitting in that dedicated timer queue, update the input.
Then update the display, assuming you've processed at least one tick. So you may, if things get too slow, do multiple input updates per drawn frame.

Related

TouchDown only seems to fire once in the entire application [libGDX]

So in my game I spawn a grapple hook when I touch the screen, connecting player and ceiling. The problem is that the touchDown() of my inputAdapter only seems to activate the first time I touch, nothing happens after when I touch again (meaning: no other "grapple hooks" get created, just the one). touchUp() or every other input method still work.
Here are all the classes: Rope - GamePlay - InputManager and also just in case MainMenu
EDIT
So I was being a moron and in the overlapsOnX() method forgot to add and substract the width of the "cloud" so unless I got very lucky (or spawned in the right place) the rope wouldnt get created.
Here's how the method should look like
private boolean overlapsOnX(Body player, Body cloud){ //check if the player is currently in the same X position than a cloud
return player.getPosition().x >= cloud.getPosition().x - (20 / PPM) && player.getPosition().x <= cloud.getPosition().x + (20 / PPM);
}
TouchDown returns a boolean to indicate if the input has been processed or not. You are returning false, but you probably mean to return true. This would indicate the input has finished being handled.

Trigger a function when specific frame number is reached - AS3

I wanted friends, do the following when my MC get a determanido internal quandro, it triggers a function to another MC. for example when the ball hit the wall, a person goes to search - la, I have tried using :
("root") {root.MC.play ()}
Translation from comments:
Friends, I have an MC_1 with 10 frames, when it reaches frame 5, I want another movieClip MC_2 to respond (eg: to move or fade etc)
creating a ENTER_FRAME listener for your MC_1 is the easiest way to achieve this
MC_1.addEventListener(Event.ENTER_FRAME,respond);
function respond(e:Event):void{
if(MC_1.currentFrame>=5)
MC_2.gotoAndPlay(2);
//or any other respose you want from MC_2
}
addFrameScript can be used in AS3 to specify a function to execute on reaching a MovieClip frame.
MovieClip.addFrameScript(index:int, func:Function);
A sample implementation of this:
// addFrameScript's index is zero Based, hence 4 means frame 5
MC_1.addFrameScript(4, funcToExecute);
function funcToExecute():void{
// this will get called when MC_1 reaches frame 5
// do stuff here, like manipulating MC_2, etc...
}

Timer flash to show something at the right time

I want to make a timer that will show text at my panelText (dynamic text box) at specific time, actually I have a video that I want to have subtitles, and I want to use timer, my video is 3 minutes and 37 second long, and I have script that I want to show at some time, example at 1 minute 0 seconds it will show the text "hello, this is my video to learn about solar system" in my panelText, and at 2 minute I want to show text "There are 8 planets in our solar system", something like that. For information, I'm using flvPlayback to play the video and load the external video.
An example from my code:
var myTimer:Timer = new Timer(217000);
var time = 0;
myTimer.start()
myTimer.addEventListener(TimerEvent.TIMER,timerHandle);
function timerHandle(event:TimerEvent){
if(myTimer == 120000)
{
panelText.text="There's 8 planets in our solar system";
}
and i got error 1176: Comparison between a value with static type flash.utils:Timer and a possibly unrelated type int. can someone help me?, i'm sorry for my bad english
You should use FLVPlayback's addASCuePoint() function to make precise actions when your FLVPlayback fideo is playing. You use this function to set up whatever points you want to display custom subtitles, there can be as many of these as you want, then you listen for MetadataEvent.CUE_POINT event on your FLVPlayback instance, and process the cue point in order to display the associated subtitle. Note though, you will have to separately parse subtitle expiration, or assign a cue point to remove the displayed subtitle several seconds past the displaying cue point. Although it will be better if you will be able to add subtitles directly on the video, so that seeking through your video will not require handling of misaligned subtitles. Still, it's doable with pure AS3 code, if you would also listen to VideoEvent.FAST_FORWARD and VideoEvent.REWIND events to handle user interaction with playback and display corresponding subtitle by calling findNearestCuePoint() to find the closest earlier subtitle-enabled cue point.
An example of adding a cue point:
flv.addASCuePoint(0.1,"1",{text:"Subtitle one"});
flv.addASCuePoint(6.8,"2",{text:"Subtitle two"});
flv.addASCuePoint(11.8,"2 hide",{text:""}); // remove old subtitle
flv.addASCuePoint(120.0,"3",{text:"There are 8 planets in our solar system"});
Note that each call returns an Object, which is also returned whenever a MetadataEvent.CUE_POINT event is dispatched. This has a parameters sub-object that you have passed into addASCuePoint as third parameter, which you then parse and take actions depending on what's in there. Here, I've placed a single field "text" into each of the parameter objects, which should be the text to display as subtitles. So, then you listen to the cue point event and take actions, like this:
flv.addEventListener(MetadataEvent.CUE_POINT,cueHandler);
// do this only once, a listener does not need to be added per cue point
function cueHandler(e:MetadataEvent):void {
var cuepoint:Object=e.info;
if (cuepoint.parameters) {
panelText.text=cuepoint.parameters.text;
} else {
// DEBUG here
}
}
In case of seeking, you listen for FF and rewind events with a function that will call findNearestCuePoint(), retrieve its parameters.text and place that text into your text field.
You misunderstood the usage of the Timer class.
var myTimer:Timer = new Timer(n) means that the Timer will always "tick" at the specified interval n, in your case every 217000 milliseconds (217 seconds).
This might not be the best solution, but it'll show you how you can use the timer class for a scenario such as yours.
var myTimer:Timer = new Timer(1000); //a timer that will tick every second
myTimer.addEventListener(TimerEvent.TIMER, timerHandler);
myTimer.start(); //you should set up your listener before you start the timer
function timerHandler(event:TimerEvent):void{
//myTimer.currentCount will tell you how many times your Timer has ticked
//every tick, in this scenario, represents exactly one second, because we initialized the Timer with 1000 milliseconds
//so, if you want to show some text 86 seconds after the video has started, you could do:
if(myTimer.currentCount == 86){
panelText.text = "We're 86 seconds into the video";
}else if(myTimer.currentCount == 217){
//after reading your code it seems like you intended to let the timer only run 217 seconds, because that's the length of your video
//my proposed solution could also handle this, in this else if clause
myTimer.stop();
myTimer.removeEventListener(TimerEvent.TIMER, timerHandler);
myTimer = null;
}
}
The error is right.you are comparing a timer with a number!!.
fixed part of code:
if(myTimer.currentCount==120000){
panelText.text="There's 8 planets in our solar system";
}
and your timer constructor is wrong!the first argument is delay and next is repeat count.
the fixed code:
var myTimer:Timer = new Timer(100,2170);
var time = 0;
myTimer.start()
myTimer.addEventListener(TimerEvent.TIMER,timerHandle);
function timerHandle(event:TimerEvent){
if(myTimer.currentCount == 1200)
{
panelText.text="There's 8 planets in our solar system";
}
in this code, our timer ticked at every 0.1 second(100 miliseconds) and is ticked 2170 times. so, to set your text, you must put a zero after your desired second.
hope this helps :)

AS3 How to delete an object for good?

I create a new Shape, make a listener that starts a function when an object hits the shape, the function clears graphics of the shape, removes listener and deletes the child. But it looks like it leaves some ghost that still triggers when my object comes to it's place. I'm not sure why it happens, I thought clear+remove should make it impossible to hitTest. But somehow children still pile over one another and the last created one triggers the function. So if you understand, please give me a hint, if not please tell me in general what is a way to delete a created Shape for good, so it didn't count existing?
A bit of details. Hitting the shape must start a function that deletes it and creates a new shape of the same name that has a different function that does the same etc. so the current function must be the one I called for, not the last one, whose listener I deleted. Making new shape each time may overload memory, besides I do clean up every time. Did I forget anything?
fun0(){
var bob:Shape = new Shape();
addChild(bob);
bob...drawRect...
addEventListener(...,fun1)
function fun1(){ if(hitTest...){
bob...clear();
removeChild(bob);
removeEventListener(...,fun1)
fun2();
}
}
fun2(){
var bob:Shape = new Shape();
addChild(bob);
bob...drawRect...
addEventListener(...,fun3)
function fun1(){ if(hitTest...){
bob...clear();
removeChild(bob);
removeEventListener(...,fun3)
fun0();
}
}
etc., it only sees fun3 after I once trigger it even though I deleted the listener. Again, I do move object away, it doesn't hitTest anymore, then clear+remove. If you don't understand or cannot help, please don't flame, just ignore this, I need help, not the info that I'm not as smart as you are. Thank you.
first of dont declare functions inside of functions. then use weak reference for event listners.
// params: eventName, listener, capturePhase, priority, useWeakReference
someObj.addEventListener("eventName",myFunct,false,0,true);
you musst get rid of any references to the object, then set it to null
removeChild(bob);
bob= null;
after that GC will collect it!
edit:
if you keep doing the hitTest, like on enterFrame for example. check if the object is on the stage, by checking its .stage property.
if(bob.stage)
{
if(hitTest ...){};
}

Walkcycles and timing in pygame

I have a pygame.Timer running in my game calling a draw function 32 times/second. The drawing method gets positions from all elements on my screen and blits them accordingly. However, I want the main character to walk around slower than other objects move.
Should I set up a timer specifically for it or should I just blit the same frames several times? Is there any better way to do it? A push in the right direction would be awesome :)
(If anyone's interested, here is the code that currently controls what frames to send to the drawing: http://github.com/kallepersson/subterranean-ng/blob/master/Player.py#L88)
Your walk cycle frame (like all motion) should be a function of absolute time, not of frame count. e.g.:
def walk_frame(millis, frames_per_second, framecount, start_millis=0):
millis_per_frame = 1000 / frames_per_second
elapsed_millis = millis - start_millis
total_frames = elapsed_millis / millis_per_frame
return total_frames % framecount