Making health reduce by 1 every second - actionscript-3

I'm programming a tamagotci style game and I need to health by one, every second. I already have a score number in place that is changed when you feed the target. I would be incredibly grateful if someone could give me a hand in editing the current code I have at the moment, to reduce health by 1 every second. Here is my code if anyone needs to see it;
health=100
txtform.font = "Arial";
txtform.color = 0x000000;
txtform.size = 24;
txtform.bold = true;
healthdisplay.defaultTextFormat=txtform;
addChild(healthdisplay);
healthdisplay.text=("Health: " + health)
healthdisplay.x=75
healthdisplay.y=-20
healthdisplay.autoSize=TextFieldAutoSize.CENTER;
}
public function IncreaseHealth(points:int){
health+=points
healthdisplay.text=("Health: " + health)
healthdisplay.defaultTextFormat=txtform;
}

Make a function DecreaseHealth() that you call every second. Something like:
var timer:Timer = new Timer(1000); // 1 second = 1000 milliseconds.
timer.addEventListener(TimerEvent.TIMER, DecreaseHealth);
timer.start();
Where DecreaseHealth() has the following signature:
function DecreaseHealth(event:TimerEvent):void
{
health -= 1;
// Do printing or whatever else here.
}

Related

How do i set Time as high score?

im creating a simple game which the objective is to deliver items the fastest as you can.There are no other score points except time, i manage to make the time start as the game begin and stop when the objective is done, but how do i save the time when it stop and make it appear at the home page as the "Best Time"? for now im still using other score points with the time, but im going to delete it and use only Time instead, help me, thanks in advance :)
these are several codes where i manage to stop the time, just write it here in case if it is needed, will write other codes as well if needed.
if (score==15) {
time1.stop();
gotoAndPlay('resultframe')
stop();
time1.stop();
score2_txt.text = String(score);
timeField2.text = String(""+minute+":"+second+"");
response_txt.text = "Well Done! You won!";
var minute = 5;
var second = 59;
var time1:Timer = new Timer (1000);
time1.addEventListener(TimerEvent.TIMER, calcTime);
function calcTime(e:TimerEvent):void {
second -= 1;
if(second == 00){
minute -= 1;
second = 59;
}
timeField.text = String(""+minute+":"+second+"");
}
import flash.utils.getTimer;
var startTime:int;
function chronometerStart():void
{
startTime = getTimer();
}
function chronometerStop():int
{
var now:int = getTimer();
var time:int = now - startTime;
return time;
}
the getTimer()-method returns the number of milliseconds that have elapsed since the swf gegan to run.
Greetings André

Is this a good implementation of the gameloop

I have implemented a gameloop in Flash/Actionscript/Starling and I want to throw it at you to see if this is a valid implementation.
I wanted to have a variable time step approach.
private var _deltaTime:Number = 0;
private var _lastTime:Number = 0;
private var _speed = 1000 / 40;
private function onEnterFrame() {
var now = new Date().getTime();
var delta = now - _lastTime;
_deltaTime += delta - _speed;
_lastTime = now;
//skip if frame rate to fast
if (_deltaTime <= -_speed) {
_deltaTime += _speed;
return;
}
update();
}
private function update() {
updateGameState();
if (_deltaTime >= _speed) {
_deltaTime -= _speed;
update();
}
}
What I got sofar is that I have a constant speed (more or less).
My question is is there a better approach so that the movements will appear even
smoother.
What is really surprising to me is that even thou the FPS is pretty much constant (60FPS)
the movement is sometimes bumpy yet smoother than with the naive gameloop.
Youre on the right track - assuming that onEnterFrame is triggered in some way by Event.ENTER_FRAME - instead of skipping update, call it on every frame but pass in the time elapsed:
private function onEnterFrame() {
var now = new Date().getTime();
var delta = now - _lastTime;
_lastTime = now;
updateGameState(delta/1000);//divide by 1000 to give time in seconds
}
In updateGameState, you can utilise 'delta' to calculate movement etc, eg:
function updateGameState(timeElapsed:Number):void {
myAlien.x += myAlienSpeedPerSecond*timeElapsed;
}
This way you get smooth movement even when frame rate varies.
from the Starling introduction pages, it shows that time elapsed is built into the EnterFrameEvent class.
// the corresponding event listener
private function onEnterFrame(event:EnterFrameEvent):void
{
trace("Time passed since last frame: " + event.passedTime);
enemy.moveBy(event.passedTime * enemy.velocity);
}
http://wiki.starling-framework.org/manual/animation#enterframeevent

How to only execute something every 30 frames

My question is this, I want to add a rock every second (30 frames per second), I have different levels, this means I have different amounts of rocks in each level and I have different amount of speeds, so I want to add 10 rocks in a total of 30 seconds in level 1
in level 2 it's 20 rocks in a total of 20 seconds etc. I'm open to completly changing it, I just want the best solution. I want it to be dynamic so I can make a lot of levels. How should I got about doing this
I don't want to keep a counter and every time it's at 30 then add a rock and reset it.
Thank you in advance
switch(difficulty)
{
case 1:
timer = 30;
numberOfRocks = 10;
break;
case 2:
timer = 20;
numberOfRocks = 20;
break;
case 3:
timer = 10;
numberOfRocks = 30;
break;
case 4:
timer = 5;
numberOfRocks = 40;
break;
}
addEventListener(Event.ENTER_FRAME, loop)
}
private function loop(e:Event):void
{
for (var i:int = 0; i < (timer * 30); i++)
{
a_bitmap = new a_class();
a_bitmap.x = 750;
a_bitmap.y = Math.ceil(Math.random() * (600 - a_bitmap.height));
a_bitmap.height = 35;
a_bitmap.width = 35;
addChild(a_bitmap);
a_bitmap.name = "astroid" + i + "";
myArray.push(true);
}
}
A Timer may work better for you're needs than a frame handler. I'd recommend using math to calculate your level parameters instead of hard-coded switch statements, then you can add as many levels as you'd like (or have your game go indefinitely)
var rockLoadTimer:Timer;
function gameInit():void {
//your games initialization code here
//create a timer that fires every second when running
rockLoadTimer = new Timer(1000);
//the function to call every time the timer fires. You could also listen for TIMER_COMPLETE is wanted to run a function once all rocks are loaded
rockLoadTimer.addEventListener(TimerEvent.TIMER, addNextRock);
}
function startLevel(difficulty:int = 1):void {
//your code here to clear the level
//repeat count is used as the amount of rocks to load this level - level number times 10
rockLoadTimer.repeatCount = difficulty * 10;
//the delay time is how quickly you want the rocks to load. this is 5 seconds divided by the difficulty level
//so the first level would be every 5 seconds, second would be every 2 and a half seconds, third level would be every second and two thirds. etc.
rockLoadTimer.delay = Math.round(5000 / difficulty);
rockLoadTimer.reset();
rockLoadTimer.start();
}
function addNextRock(e:Event = null):void {
//your rock creation code here
}
You can use a Timer, and create an instance of a_class during each tick:
var timer:Timer = new Timer(1000, 30); // One per second for 30 seconds
timer.addEventListener(TimerEvent.TIMER, addAsteroid);
timer.start();
function addAsteroid():void {
a_bitmap = new a_class();
// etc.
}
The timer delay is "asteroids per millisecond", so if you want to create 10 over 30 seconds you would set it to 30000/10 = 3000.
However, this approach works best when there is a smooth framerate- it will execute once per second, but the number of frames of animation can vary if Flash is running at less than 30fps. If your game works how I think it does, this could result in asteroids being "bunched up". So, keeping a counter might be the better solution here, unless you plan on handling the rest of your game logic (i.e. asteroid movement speed) in a way that can account for variations in frame rate.
If you want to use a counter:
var creationCounter:Number = 0; // put this at class level
// Then in the ENTER_FRAME event:
creationCounter += asteroids_per_second / 30;
while (creationCounter-- >= 1) {
a_bitmap = new a_class();
// etc.
}
You can also use flash.utils.setInterval function .
setInterval(trace , 1000 , "trace message once per second");
If you use TweenLite, you can use the delayedCall function, it can use time or frames,
// delayedCall(delay:Number, onComplete:Function, onCompleteParams:Array = null, useFrames:Boolean = false):TweenMax
TweenLite.delayedCall(30, addAstroid, null, true);
More info, see the docs: http://www.greensock.com/as/docs/tween/com/greensock/TweenMax.html#delayedCall()

AS3 seeing every score

I have recently taken up programming and encountered a problem when it comes to score display. The score has not problem incrementing and displaying it is just that as the score updates it does not remove the last score. After a dozen frames I have a jumble of scores displayed. I have spent a few days google searching to see if I could find any type of answer but not seen a problem similar to this.
My Code:
public function balldistance(event:Event){ // function called on ENTER_FRAME in order to update the distance of the ball object
var txt:TextField = new TextField();
txt.text = "Distance: " + String(balldist);
txt.x = 25;
txt.y = 25;
addChild(txt);
trace(balldist); // I added this line in my code for troubleshooting purposes just so I could see the balldist augment.
balldist += Ball5.dx; // I am having the score(balldist) augment based on the distance the ball has traveled from its starting point.
}
A friend of mine suggested a removeChild(txt) but when i tried this it did not show the score updating.
Thank you
It looks like you are creating a new txt:TextField EVERY time ENTER_FRAME is triggered.
Try declaring/initializing it once, outside of that listener function:
var txt:TextField = new TextField();
txt.x = 25;
txt.y = 25;
addChild(txt);
Then on enter frame reference the SAME txt TextFeild instance, instead of making a new one over and over again:
public function balldistance(event:Event){
txt.text = "Distance: " + String(balldist);
balldist += Ball5.dx;
}

Flex 4 timers keep Firing

I'm trying to create a simple flex4 project which involves some timers that trigger other functions.
I don't have much experience with Action Script and even less with timer events.
Here is a bit of my code it seems to be working for the most part but you lines were I'm adding up the total score (score = score +1;) seems to just keep adding and adding when I test the application. I think its because the timers keep firing the function but I'm not sure.
private var score:int = 0;
private function submit():void {
this.currentState = 'loading';
var timer:Timer = new Timer(2200);
timer.addEventListener(TimerEvent.TIMER, removeLoading);
timer.start();
}
private function removeLoading(event:TimerEvent):void{
removeloading.play();
var timer1:Timer = new Timer(1000);
timer1.addEventListener(TimerEvent.TIMER, viewResults);
timer1.start();
this.currentState = 'results';
}
private function viewResults(event:TimerEvent):void{
if (q1_t.selected == true){
answer1m.text = 'You Answer the Question Correctly.';
score = score +1;
} else {
answer1m.text ='The Correct answer was: '+ q1_t.label;
}
if (q2_f.selected == true){
answer2m.text = 'You Answer the Question Correctly.';
score = score +1;
} else {
answer2m.text ='The Correct answer was: '+ q2_f.label;
}
finalscore.text = score.toString();
}
So I did a bit more research and turns out I hadn't included the second timer parameter.
The second parameter is the number of times that the TimerEvent.TIMER event will be dispatched before stopping. If you set the second parameter to 0 (zero) or omitted it completely, the timer would run forever (or until you called the stop() method on the timer instance.
Since I only want to run the event once I need to add 1.
From this:
var timer:Timer = new Timer(2200);
To this:
var timer:Timer = new Timer(2200,1);