Timer Efficiency - performance

I'm working on an AS3 project and for one of the effects I use timers to switch the colors then stop. The function is below.
//global variable
private var valueAnimationTimer:Timer = new Timer(50);
//constructor
valueAnimationTimer.addEventListener(TimerEvent.TIMER, scrollUp );
//function
private function scrollUp(e:TimerEvent):void
{
var i:int = e.currentTarget.currentCount as int;
if (i < 10)
{
if (colored){
if (i % 2 == 0){
ChangeColor(ico, flickerColor);
}
else{
ico.transform.colorTransform = new ColorTransform();
}
}
tfValue.y -= 7.5;
}
else
{
RemoveFilters(ico);
tfValue.y = ico.height / 2;
e.currentTarget.reset();
RemoveSprite(tfValue);
colored = false;
}
}
Each character (object) has it's own version of this function and it happens at different times (like when it is injured or poisoned). The listener is added once in the constructor, it is only removed when the character dies and is removed from the stage. The issue here is after the timer is used on at least 3 characters, the frame rate begins to drop. Every time the function is called, the frame rate drops lower and lower.
What I don't understand is, if the timer is stopped, and the listeners are only added once so it doesn't overload the stack, then why does the frame rate begin to decline after the listener is actually used? It doesn't run forever only for a small amount of time, but it happens again and again. When the frame rate drops the entire program begins to lag badly and eventually freezes. I have no idea what is causing this

Also be aware that inside of the Timer function, the first number is your count in MILLISECONDS and the second is repeat count
var fl_TimerInstance:Timer = new Timer(240000, 1);
So this example above is a 4 minute timer that repeats 1 time
I bring this up because yours is set for 50 milliseconds which is very quick lol

Related

Text typing effect in C# based on current FPS and characters per second?

I am working on a typing effect for TextMeshPro texts in Unity that should take into account both the current FPS and the user input 'characters per second' (to determine the speed).
The implementation runs in an IEnumerator and displays one or more characters of a given text at a time. After displaying the char(s), there is a 'yield return new WaitForSeconds()' before the next round of revealing begins. (It should be possible to display more than one char at a time, because WaitForSeconds() takes too much time in some cases, even if I enter very small numbers. So rather than waiting after every single char, it should be waited after a precomputed number of chars to maintain the specified typing speed.)
I'm not sure if my approach works as intended in the different possible scenarios and additionally, I'm not happy with the computations within the IEnumerator because I think it could slow down the revealing process.
I tested the typing effect with different FPS in PlayMode (by setting the FPS with "Application.targetFrameRate" manually) and noticed that with FPS lower than 30 the text is revealed very haltingly and thus the viewer gets frustrated because it looks laggy. Maybe someone has experience with this and can suggest an easier way of implementation?
// Precompute the time for displaying a single character by a given number of characters per second:
public void GetTimePerChar() {
if (_charsPerSecond > 0) {
TimePerChar = 1f / _charsPerSecond;
} else {
TimePerChar = 0f;
}
// Coroutine that reveals characters of a given text over time:
private IEnumerator DisplayText() {
/* some other code */
while (TmpText.maxVisibleCharacters < TotalCharCount) { // Reveal characters until the the total amount of chars is reached
if (CharsPerSecond > 0) {
TimePerFrame = Time.deltaTime; // How much time does 1 frame take
if (TimePerChar > 0) {
CharsPerFrame = TimePerFrame / TimePerChar; // How many chars can be displayed within a single frame
} else {
CharsPerFrame = 0f;
}
CharsPerRound = (int)Math.Ceiling(CharsPerFrame); // Rounded up number of chars (as fractions doesn't make sense to display)
TimePerRound = TimePerChar * CharsPerRound; // The individual waiting time before the next char(s) get revealed
TmpText.maxVisibleCharacters += CharsPerRound; // Reveal one or more characters at a time
if (CharsPerRound - CharsPerFrame > 0) { // If the number of chars got rounded up wait afterwards as long as it shall take to display them
yield return new WaitForSeconds(TimePerRound);
}
} else {
TmpText.maxVisibleCharacters = TotalCharCount; // With zero CharsPerSecond, display the whole text at once
}
}
/* some other code */
}

Game maker death codes which will run when you collide with a skeleton don't work like It should

p_hp is health variable and o_skeleton is our enemy. What I want to do is to kill the player when it collides with the skeleton 3 times, but it seems It doesn't work.
What did I do wrong?
p_hp=3;
if(place_meeting(x,y,o_skeleton))
{
p_hp=p_hp-1
}
if(place_meeting(x,y,o_skeleton)) && (p_hp==0)
{
instance_destroy(self);
}
Please help to solve my issue.
Is p_hp = 3 declared in the Step Event? then that means each time it reached that code, p_hp will reset back to 3. And the Step Event is called each frame.
I recommend declaring variables that'll change later on in the Create Event.
Also, It's better to use this to check if your character is still alive:
if (p_hp <= 0)
{
instance_destroy(self);
}
That way it doesn't need to collide to check if it's still alive, and if the chance happens that p_hp is lower than 0. It will still be destroyed.
Keep in mind, this possible results in the player dying instantly to the skeleton, because it's checking the Step Event each frame. In that case, you'll need to look into a short invincibility time after getting hit.
Adding invincibility after getting hit:
There are multiple ways to add invincibility, the method I use is to add invincibility would be making an invincibility variable and use that as a timer. give it a value the moment it's hit, and let it return to 0 over time. you should also add the check if the invincibility value is higher than 0;
So, in practise:
Create Event:
p_hp = 3;
invicibility = 0;
Step Event:
if (invincibility > 0) //timer in step event
{
invincibility -= 1/room_speed // (1/room_speed) = real time seconds
}
if (place_meeting(x,y,o_skeleton) && invincibility <= 0) //avoids getting hit while invincibility has value.
{
p_hp -= 1;
invincibility = 0.5; //grants half a second of invincibility after getting hit
}
if (p_hp <= 0)
{
instance_destroy(self);
}
(And as extra tip: p_hp -= 1 does the same as p_hp = p_hp - 1)

AS3: FPS drops down significantly because of innocent mouse moves

I have ~10000 objects in my game and exactly 60 (maximum) FPS when mouse isn't moved. But just when you start moving mouse in circles FPS tries to reach 30 averaging at 45. When you stop mouse it's INSTANTLY 60 (as so program lost it's heartbeat). SWF is run standalone - without any browsers.
I removed any MouseEvent.MOUSE_MOVE listeners and made mouseEnabled=false and mouseChildren=false for the main class.
I increased my FPS one-by-one from 12 to 60 - I gave name to each frame I born and it's really painful watching how 15 of them die just because of nothing...
Sample code:
public class Main extends Sprite
{
private var _periods : int = 0;
/** Idling FPS is 23. Move mouse to drop FPS to 21.*/
public function Main() : void
{
//true if need to drop FPS to 18 instead of 21 moving mouse:
const readyToKill2MoreFrames : Boolean = true;
if ( readyToKill2MoreFrames )
{
var ellipse : Sprite = new Sprite;
ellipse.graphics.beginFill( 0x00FF00 );
ellipse.graphics.drawEllipse( 300, 300, 400, 200 );
ellipse.graphics.endFill();
addChild( ellipse );
//uncomment to fall only to 21 instead of 18:
/*ellipse.mouseChildren = false;
ellipse.mouseEnabled = false;*/
}
var fps : TextField = new TextField;
//uncommenting doesn't change FPS:
//fps.mouseEnabled = false;
addChild( fps );
fps.text = "???";
fps.scaleX = fps.scaleY = 3;
var timer : Timer = new Timer( 1000 );
timer.addEventListener( TimerEvent.TIMER, function( ... args ) : void
{
fps.text = _periods.toString();
_periods = 0;
} );
timer.start();
addEventListener( Event.ENTER_FRAME, function( ... args ) : void
{
//seems like PC is too fast to demonstrate mouse movement
// drawbacks when he has nothing else to do, so let's make
// his attention flow:
for ( var i : int = 0; i < 500000; ++i )
{
var j : int = 2 + 2;
}
++_periods;
} );
}
}
You've probably moved on to more modern problems, but I've recently struggled with this issue myself, so here's an answer for future unfortunates stuck with the problems created by Adobe's decade-old sins.
It turns out legacy support for old-style buttons is the culprit. Quote from Adobe's tutorial on the excellent Scout profiling tool:
"Flash Player has some special code to handle old-style button objects (the kind that you create in Flash Professional).
Independently of looking for ActionScript event handlers for mouse
events, it searches the display list for any of these buttons whenever
the mouse moves. This can be expensive if you have a large number of
objects on the display list. Unfortunately, this operation happens
even if you don't use old-style button objects, but Adobe is working
on a fix for this."
Turns out Adobe never really got around to fixing this, so any large number of DisplayObjects will wreak havoc on your FPS while the mouse is moved. Only fix is to merge them somehow, e.g. by batch drawing them using Graphics. In my early tests, it seems setting mouseEnabled = false has no real effect, either.

JavaFX: pause transition, not equal times

I have written a small application that performs some long-running tasks. Instead of having the user to wait and seeing just a progress bar, I would like to display some (changing) information about the application.
For that purpose, I wrote the following code within the constructor of an extended Pane:
FadeTransition fadeOutTransition = new FadeTransition(Duration.millis(1000), this);
fadeOutTransition.setFromValue(0.8);
fadeOutTransition.setToValue(0.0);
Similarly the fadeInTransition. And further...
SequentialTransition seqTransition = new SequentialTransition (
new Transition() {
{ setInterpolator(Interpolator.DISCRETE);
setCycleDuration(Duration.seconds(1)); }
protected void interpolate(double frac) {
int nextElement = (int) ((explenations.size() - 1) * Math.random());
Explenation explenation = explenations.get(nextElement);
questionLabel.setText(explenation.getQuestion());
answerLabel.setText(explenation.getAnswer());
}
},
fadeInTransition,
new PauseTransition(Duration.seconds(15)),
fadeOutTransition
);
What I woud like is the text to fade in, stay there for ~15 seconds and then fade out again. Unfortunately, the animation flickers, moves faster and slower - and the PauseTransition never takes 15 seconds! What is wrong about the code? I'm using Java 7, and JavaFX 2.2 on Mac OS X.
The problem seems to be that I called the function
seqTransition.play();
multiple times. From there comes probably the flickering and the unequal waiting time.

Lap timer in XNA 4.0?

Right, I've got a slight problem here, in which I've attempted to implement a lap timer.
In my protect override void update I've got this;
if ((IntersectPixels(destinationRedRect, car2redTextureData, startingLineRectangle, startingLineTextureData)))
{
{
redHit = true;
_timer1 += gameTime.ElapsedGameTime.TotalMilliseconds;
}
}
What I'm saying here^ is, if car2red is colliding with the starting line, the timer begins, but if it's not, timer does not add seconds (it just stops_ . How can I make it so, if car2red hits the startingLine and moves forward a few pixels (without touching starting line) the timer still continues?
Thank you.
You should have a separate if statement like this:
if (redHit) {
_timer1 += gameTime.ElapsedGameTime.TotalMilliseconds;
}
if ((IntersectPixels(destinationRedRect, car2redTextureData, startingLineRectangle, startingLineTextureData)))
{
redHit = true;
//Only use this line if you want to reset the timer to 0 when the player crosses that line again.
_timer1 = 0;// I'm assuming that _timer1 is a double
}

Resources