In the game I am making, I need to make a scoring system based on time.
If you get a match in the first second of gameplay. That match is worth more points, than if I get a match on the last second of gameplay.
So in other words, the faster you do the level, the more points you get. Does anyone know how to achieve this? I know the total time for each level.
The game is real time so it needs to be seen to show high scores early in the game with a decreasing score as time goes on.
Thanks.
Define a maximum time per level then do some math tricks:
score = Math.max(0, levelMaxTime - timeSpent) * levelScore;
Example:
timeSpent = 12; // The player completed the level in 12 seconds
levelMaxTime = 20; // The player has to completed the level within 30 seconds
levelScore = 50; // The player will be awarded of 50 points per remaining second
// Compute the final score
score = Math.max(0, levelMaxTime - timeSpent) * levelScore; // 400 points
You use the Timer Class for this. So you should end with something similar to :
private var delay:uint = 1000;
private var repeat:uint = 3;
private var timer:Timer = new Timer(delay, repeat);
Add listeners for the ticks...
timer.addEventListener(TimerEvent.TIMER, timerHandler);
timer.addEventListener(TimerEvent.TIMER_COMPLETE, completeHandler);
// Reduce bonus with time by a percentage
private function timerHandler(e:TimerEvent):void { scoreBonus *= 0.9; }
// Set bonus to 0
private function completeHandler(e:TimerEvent):void { scoreBonus = 0; }
Now set the score bonus & start the timer at the point where you wish to begin the bonus from.
scoreBonus = 10;
timer.start();
So at any point of time, you just need to add the bonus to the total score.
Related
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é
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.
}
im doing a basic game in action script and now i want to do a timer.
I want that the timer starts count when the game starts and in the end of the game when the player can do ten points i want to say in textfield that if the time was more than 5 minutes it was very bad if the timer was less than 2minutes very good and things like this!
Im trying do this but the timer dont count, anyone can help?
Thanks!
theTime.addEventListener(Event.ENTER_FRAME,showTime);
function showTime(event:Event):void {
var myTime:Date = new Date();
var theMinutes=myTime.getMinutes();
theTime.text =theMinutes;
}
new Date(); gives a Date object which contains the current date and time. To keep track of passed time you need to keep track of start and end time and find their difference. You can do this by using time property. Something like this:
// Do this when you start the game.
var startTime:Number = (new Date()).time;
// Do this when the game is over
var endTime:Number = (new Date()).time;
const MILLI_SECOND_IN_5_MIN:Number = 5 * 60 * 1000;
const MILLI_SECOND_IN_2_MIN:Number = 5 * 60 * 1000;
var timeDiff:Number = endTime - startTime;
if (timeDiff < MILLI_SECOND_IN_2_MIN) {
trace("Good");
} else if (timeDiff > MILLI_SECOND_IN_5_MIN) {
trace("Bad");
}
I've created a score system in my flash Quiz game where the faster you answer a question, the more points you get. At the moment however my tracer shows 'NAN' when I run my game. Can anybody see why this is?
var score:int = 0;
var count:int = 0;
var mTimer:Timer;
mTimer = new Timer(100, 70);
function processScore():void {
var count:int = mTimer.currentCount;
var score:int = score + (700 - (count * 10));
trace("score registered");
}
trace(aUserAnswers[numLoops] + " " + returnedNumber);
if(aUserAnswers[numLoops] == returnedNumber){
processScore();
}
returnedNumber is when a button is clicked, if the number matches that which is in the array, the question is correct.
Thank you
You're redeclaring count and score inside processScore(). That makes them local variables to the function, unrelated to the previous declared variables of the same name. This means that their values are lost when the function finishes and the previous variables are unchanged. I'm guessing that at some point you divide something by one of them and since you'll always be dividing by zero you get NAN.
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()