2018-11-29 21:38:53

Hi.
So, i've been working on this little 1d sidescroller thing for a while now. The sidescroller part just about works, almost, there's just one pretty major gamebreaker that's fucking shit up, and it's stopping me from actually adding more to it.
Basically, whenever you try and jump, the hole program just freezes. It doesn't crash exactly, but it becomes pretty dam unresponsive and makes this vm's CPU go up pretty high.
Here is the code. Tips welcome.
#include"sound_pool.bgt"
#include"sound_positioning.bgt"
int x;
int maxx=100;
sound amb;
tts_voice v;
sound_pool p;
int movetime=150;
timer movetimer;
timer jumptimer;
int jumptime=1000;
bool jumping=false;
void main()
{
if(screen_reader_is_running(1))
install_keyhook();
show_game_window("2d engine");
v.speak_wait("Loading");
amb.load("sounds/ambience.ogg");
x=0;
mainloop();
}
void mainloop()
{
while(true)
{
amb.play_looped();
if(key_down(KEY_LEFT) and movetimer.elapsed>=movetime and jumping==false and x>0)
{
movetimer.restart();
x-=1;
p.play_stationary("sounds/step"+random(1,8)+".ogg",false);
}
if(key_down(KEY_RIGHT) and movetimer.elapsed>=movetime and jumping==false and x<maxx)
{
movetimer.restart();
x+=1;
p.play_stationary("sounds/step"+random(1,8)+".ogg",false);
}
if(key_pressed(KEY_UP) and jumping==false)
{
jumping=true;
jumptimer.restart();
p.play_stationary("sounds/jump.ogg",false);
while(jumping)
{
if(jumptimer.elapsed>=jumptime)
{
jumping=false;
p.play_stationary("sounds/land"+random(1,4)+".ogg",false);
}
}
}
if(key_pressed(KEY_ESCAPE))
{
v.speak_wait("Exiting...");
exit();
}
}
}
void checkstuff()
{
if(x>maxx)
x=maxx;
if(x<0)
x=0;
}

2018-11-29 21:43:18

Could it be the thing that says if jumping=false jumping=true thing

i am the bio control system, i can’t be stopped

Thumbs up

2018-11-29 22:01:07

What have you tried to fix this so far?

Generic signature

Thumbs up

2018-11-29 23:34:13

Lol @mat1211, i’ve been fucking around with various things for at least a week now, mostly just trial and error. This one’s got me pretty stumped, i’m probably just missing something obvious but i can’t for the life of me figure out what.

2018-11-30 01:41:05

Here you are, it should work unless I overlooked something important. Please, people like the one who posted post 2, if you don't know what you are suggesting and why, it might be better not to suggest it for the time being. You might only be confusing other beginners who are struggling with something.


#include"sound_pool.bgt"
// #include"sound_positioning.bgt"   Don't do this, it's already included in sound pool itself and this way the compiler has to go through the same code for sound positioning twice.
int x;
int maxx=100;
sound amb;
tts_voice v;
sound_pool p;
int movetime=150;
timer movetimer;
timer jumptimer;
int jumptime=1000;
bool jumping=false;
void main()
{
if(screen_reader_is_running(1))
install_keyhook();
show_game_window("2d engine");
v.speak_wait("Loading");
amb.load("sounds/ambience.ogg");
x=0;
amb.play_looped(); // It's better to move this from the main loop to here. If you use play_looped in the main loop, the end result you hear is the same as this but the function gets called again and again on every single iteration of the main loop with no real point or perceivable difference.
mainloop();
}
void mainloop()
{
while(true)
{
if(key_down(KEY_LEFT) and movetimer.elapsed>=movetime and jumping==false and x>0)
{
movetimer.restart();
x-=1;
p.play_stationary("sounds/step"+random(1,8)+".ogg",false);
}
if(key_down(KEY_RIGHT) and movetimer.elapsed>=movetime and jumping==false and x<maxx)
{
movetimer.restart();
x+=1;
p.play_stationary("sounds/step"+random(1,8)+".ogg",false);
}
if(key_pressed(KEY_UP) and jumping==false)
{
jumping=true;
jumptimer.restart();
p.play_stationary("sounds/jump.ogg",false);
}
if(jumptimer.elapsed>=jumptime and jumping)
{
jumping=false;
p.play_stationary("sounds/land"+random(1,4)+".ogg",false);
// If you did this from within the if check for the up arrow, you created a nested loop that was only started after you pressed the up arrow. This means that until the player landed from within the inner loop, nothing else from the outer loop was executed, i.e. walking etc. It's important to understand the script execution flow to avoid mistakes like this in the future. So, now that this is just another if in the main loop as it should be, the if should also check for jumping to be true. Otherwise, you would be landing every second no matter what.
}
if(key_pressed(KEY_ESCAPE))
{
v.speak_wait("Exiting...");
exit();
}
checkstuff(); // You might as well just call it here, in the main loop. It was not being used anywhere.
wait (5); // You didn't have this anywhere. Never, ever forget this in a main loop, or any loop that runs over a longer time and expects user input. No wonder your CPU ran at 100 %.
}
}
void checkstuff()
{
if(x>maxx)
x=maxx;
if(x<0)
x=0;
// In fact, the if that makes the player land could even be placed here instead of in the main loop, but then this function would need to be called from within the main loop like I proposed. The actual placement of the landing if is not that important, the structure is.
}

Hope this helps,
Lukas

Thumbs up +1

2018-11-30 02:29:00

Thanks lukas. I did actually consider putting the jump stuff outside of the if statement but figured that would probably break horribly. Will give it a test tomorrow once school is over and post here if i encounter any errors.

2018-11-30 15:33:19

Hi,
What you have to understand about while loops is that one while loop inside of another will block the first from running. Think of it as doing tasks. BGT cannot multitask nearly as much as a human can. Say you are working on a school project, and every 15 minutes you spend 5 minutes looking at this forum. When you are looking at this forum for 5 minutes, you are not working on your school project at all during that time, because you cannot multitask. You are basically performing one task, then performing another task and going back to the first one.
This is like what BGT does, when it encounters a loop inside of a loop. It runs over the first loop until the second one gets triggered, then it loops over the second one until it doesn't have to anymore, then loops over the first one again, starting from where it dropped out of the second one at first, until the second one gets triggered, etc.
Now I'll translate this concept to your game. You have one while loop that performs tasks like checking for keys pressed for walking, and starts jumping. This will include more checks as your sidescroller develops, perhaps the player will eventually be able to press h to check their health. So, you have this while loop with all of its checks, and inside of it, you have a check for the starting of a jump. Inside that if statement, you have another while loop, and BGT exclusively loops over that one until you stop the jump. It does not loop over the first loop anymore, which means that if you ever added that key to check health, you wouldn't be able to check health while jumping.
The reason your CPU spikes is because your jumping while loop has no waiting in it. It is being looped over really, really fast, which means your CPU doesn't have time to do anything else relating to other programs or your operating system.

Sincerely,
Lucas.

Thumbs up

2018-11-30 18:51:36

Yeah, makes sense. Thanks for all the help.