Understanding the language, error messages, etc.
by ajsb113 » Mon Oct 06, 2014 2:21 pm
So for my Maruino game, I want to have the time limit like Mario, but it's not really working. When I test it the display just shows 0 in the top left, not the value for time. The same thing happens if I take away the decrement in updateTimer().
- Code: Select all
void startTimer(){
time = 230;
timer = gb.frameCount;
}
void updateTimer(){
if((gb.frameCount - timer)>=20){
timer = gb.frameCount;
time --;
}
gb.display.println(time);
}
I call startTimer() in my setup() and updateTimer() in the loop in gb.update(). If anyone sees the problem, help would be greatly appreciated
Last edited by
ajsb113 on Fri Oct 24, 2014 1:56 pm, edited 1 time in total.
-
ajsb113
-
- Posts: 45
- Joined: Tue Jun 24, 2014 4:47 am
- Location: Illinois, United States
by Myndale » Mon Oct 06, 2014 9:42 pm
Works fine for me, although when it hits 0 it keeps going into negatives. Here's the exact sketch I ran:
- Code: Select all
#include <SPI.h>
#include <Gamebuino.h>
Gamebuino gb;
byte time;
byte timer;
void startTimer(){
time = 230;
timer = gb.frameCount;
}
void updateTimer(){
if((gb.frameCount - timer)>=20){
timer = gb.frameCount;
time --;
}
gb.display.println(time);
}
void setup(){
gb.begin();
startTimer();
}
void loop(){
if(gb.update()){
updateTimer();
}
}
-
Myndale
-
- Posts: 507
- Joined: Sat Mar 01, 2014 1:25 am
by ajsb113 » Tue Oct 07, 2014 2:29 pm
I just ran that sketch and it worked, so I'll have to check what's wrong in my other program. The only weird thing I noticed was once it counted down to 218, it sped up greatly. Did you see that happen as well?
-
ajsb113
-
- Posts: 45
- Joined: Tue Jun 24, 2014 4:47 am
- Location: Illinois, United States
by rodot » Tue Oct 07, 2014 3:21 pm
You could also use something like
- Code: Select all
#include <SPI.h>
#include <Gamebuino.h>
Gamebuino gb;
long timer = 200;
void setup(){
gb.begin();
gb.titleScreen(F("Timer"));
}
void loop(){
if(gb.update()){
gb.display.println(gb.frameCount);
if(gb.buttons.pressed(BTN_A)){
//set the timer 100 frames later (5 seconds)
timer = gb.frameCount + 100;
}
int remaining = timer - gb.frameCount;
if(remaining > 0){
gb.display.println(remaining/20);
}
else{
gb.display.println(F("Time's up!\n\25 to reset"));
}
}
}
-
rodot
- Site Admin
-
- Posts: 1290
- Joined: Mon Nov 19, 2012 11:54 pm
- Location: France
-
by Myndale » Wed Oct 08, 2014 8:49 am
BTW it's probably not the best idea to use the frame counter for game timing, there's no way to guarantee that the frame rate will be consistent. If you want reliable timing then I would recommend using the millis() function which is driven by the timer 0 interrupt and independent of what the main program is doing:
http://arduino.cc/en/Reference/millisYour timer functions would then look like this:
- Code: Select all
long timer_start;
void startTimer(){
timer_start = millis();
}
void updateTimer(){
gb.display.println((timer_start + 230L*1000L - millis() + 999) / 1000);
}
(In case it's not immediately obvious the addition of 999 is to round the milliseconds
up to the nearest whole second.)
-
Myndale
-
- Posts: 507
- Joined: Sat Mar 01, 2014 1:25 am
by rodot » Wed Oct 08, 2014 7:25 pm
...but using the frame timing is more deterministic, because it measures the time spent in the game, so it's "reliable" even if there is frame rate drops due to high CPU usage (lots of bitmaps, background tasks or whatever).
For example if you have to finish a level under a given time, then taking a path where there is less bitmaps (which would create framerate drops) would be more efficient. Or using a given weapon that would display large explosions (why not load the animated sprite from the micro SD card or whatever) could also create a framerate drop, that would affect the time.
So you should use millis() if you want to be accurate in real-life time, but use the number of frames timing if you want your timing to be accurate in the in-game time (the game's engine time). At least that's my opinion ^^
-
rodot
- Site Admin
-
- Posts: 1290
- Joined: Mon Nov 19, 2012 11:54 pm
- Location: France
-
by ajsb113 » Thu Oct 09, 2014 2:47 pm
Thank you guys for helping out, but for some reason it still won't work in the game code. The methods are exactly the same as when I run it on a separate program, so I don't know what's getting in the way of it working.
-
ajsb113
-
- Posts: 45
- Joined: Tue Jun 24, 2014 4:47 am
- Location: Illinois, United States
by Myndale » Fri Oct 10, 2014 5:37 am
You might have run out of RAM, try calling gb.getFreeRam() to see how close you are. Alternatively try running your game in the Simbuino emulator and switch to the RAM tab, it'll run much slower but should give you an idea of where you're at (you should see large areas of 0 towards the end of RAM that never change).
-
Myndale
-
- Posts: 507
- Joined: Sat Mar 01, 2014 1:25 am
by ajsb113 » Thu Oct 16, 2014 2:40 pm
So i updated the updateTimer method as follows:
- Code: Select all
void updateTimer(){
if((gb.frameCount - timer)>=20){
timer = gb.frameCount;
time --;
}
gb.display.println(time);
gb.display.println(gb.getFreeRam());
}
and it prints out 1123 under the messed up timer. What exactly does this number mean and is it running low or is there more space?
-
ajsb113
-
- Posts: 45
- Joined: Tue Jun 24, 2014 4:47 am
- Location: Illinois, United States
by Myndale » Fri Oct 17, 2014 9:11 pm
That's the number of bytes available, given that there are only 2kb of available RAM you're only halfway there, so that's not the problem.
If you're still seeing strange behaviour you might be inadvertently trashing memory and causing a stack corruption or something, we'd probably need to look at your entire sketch to determine what's happening. If you can't/don't want to post it here then feel free to msg me offline, I'd be happy to take a look at it for you.
-
Myndale
-
- Posts: 507
- Joined: Sat Mar 01, 2014 1:25 am
Return to Programming Questions
Who is online
Users browsing this forum: No registered users and 4 guests