Creating a highscore board

I

iBack

Guest
Hi, I'm new to game maker and GML and want to know how to make a highscore board.

So far, i have been following the tutorial made by Shaun on creating "your first game in game maker studio 2" and learning this way. I have completed to tutorial and am adding features to this such as, going back to title screen once pressing esc and pausing the game. I now want to create a highscore board that appears at the title screen once the player has cleared the stage.

So it will work like this...once player has cleared the stage of enemies, the game will go back to title screen with the player total score. However, I'm not sure how to do this. I'm stuck at clearing one enemy then goes back to title screen instead of clearing all enemies then going to title screen.


Code:
if (hp <= 0)
{

with (obj_score) thescore = thescore + 5;//kill counter
instance_destroy();
room_goto(rm_title);


}
this code within the obj_enemy step event, adds to score once you clear enemy and takes the player back to title screen after clearing one enemy. can someone please help me with this, im not sure what to do next.
 
D

dannyjenn

Guest
You need to put the code in an if statement.
Code:
if (hp <= 0)
{
    with (obj_score) thescore = thescore + 5;//kill counter // update the score
    if(instance_count(obj_enemy)==1) // if this is the last remaining instance of obj_enemy, then destroy the instance and goto rm_title
    {
        instance_destroy();
        room_goto(rm_title);
    }
    else{ // but if it's not the last instance
        instance_destroy(); // destroy it but don;t go to the rm_title
    }
}
As for your question about the high score... is obj_score a persistent object? If not, you will need to change thescore into a global variable (though if it's a global variable, there's no real reason to have it inside of obj_score. Also, if you wanted a global variable to keep track of the score, you could just use the built-in score variable. It's already global.)
 
Last edited by a moderator:

Neptune

Member
If you're wanting to just see the score number from any room, you can store the value in a 'global' variable.
Global variables are not reset between rooms (unless you manually reset them).
Try initializing 'thescore' globally in a create event (make sure this event only runs at the start of the game, and not every time you transition rooms).
Code:
global.thescore = 0;
 
I

iBack

Guest
You need to put the code in an if statement.
Code:
if (hp <= 0)
{
    with (obj_score) thescore = thescore + 5;//kill counter // update the score
    if(instance_count(obj_enemy)==1) // if this is the last remaining instance of obj_enemy, then destroy the instance and goto rm_title
    {
        instance_destroy();
        room_goto(rm_title);
    }
    else{ // but if it's not the last instance
        instance_destroy(); // destroy it but don;t go to the rm_title
    }
}
As for your question about the high score... is obj_score a persistent object? If not, you will need to change thescore into a global variable (though if it's a global variable, there's no real reason to have it inside of obj_score. Also, if you wanted a global variable to keep track of the score, you could just use the built-in score variable. It's already global.)
I put in the code but it says the following, "Object obj_enemy Event Step at line 21: Unknown function or script instance_count.

Instance_count is a built in variable it should work, I'm not sure why its not. any help? also have you guys got the full complete file for that tutorial so you can test it out.
 
I

iBack

Guest
Code:
if (hp<=0)
{

    with (obj_score) thescore = thescore + 5;
    if(instance_count==1)
    
    {
    
    instance_destroy();
    room_goto_previous();
    
    }
    else
    
    {
    instance_destroy();
    
    }



}

ok I wrote the following instead due to that error i got and it seems to take out each enemy however, it still does not go back to title screen once all enemies are cleared for some reason. any know why this is and what the next step would be?
 
D

dannyjenn

Guest
Oh, sorry, I meant instance_number(obj_enemy), not instance_count.

instance_number(obj_enemy) gets the number of obj_enemy instances in the room. This is what you want, since you need to check whether this particular instance is the last remaining enemy.

instance_count gets the total number of instances in the room. This is not what you want, since it also includes the player and the obj_score and any other instances you happen to have. So it's never going to equal 1.
 
I

iBack

Guest
Oh, sorry, I meant instance_number(obj_enemy), not instance_count.

instance_number(obj_enemy) gets the number of obj_enemy instances in the room. This is what you want, since you need to check whether this particular instance is the last remaining enemy.

instance_count gets the total number of instances in the room. This is not what you want, since it also includes the player and the obj_score and any other instances you happen to have. So it's never going to equal 1.
Thank you very much it worked. Next step is i'm trying to get score to appear on the title screen. I don't want a GUI for this to work, just the text.

Code:
if(!rm_game)

{

    object_get_visible(obj_highscoreboard) visible=false;

}
else
{
    object_get_visible(obj_highscoreboard) visible=true;

}
so what i've done is i've created another obj called obj_highscoreboard and made it persistent, also, created a global variable global.highscoreboard. In the enemy obj, it keeps track of the score just like "thescore" variable.

so far what this code does is, it shows in both title and game which i do not want. what i wanted to do here inside the obj_highscorebaord is, make it so when in title_game (where the game plays) obj_highscoreboard is not visible and its working in the background, but, becomes visible once you go back to title screen.
 
D

dannyjenn

Guest
I think your logic is right, but your code is all wrong. Here's how it should look:
Code:
if(room != rm_game) // where rm_game is the name of the title screen room

{

    visible=false;

}
else
{
    visible=true;

}
(And just making sure, but that code should go in your obj_highscoreboard's room start event.)


so what i've done is i've created another obj called obj_highscoreboard and made it persistent, also, created a global variable global.highscoreboard. In the enemy obj, it keeps track of the score just like "thescore" variable.
Just to clarify, you mean you got rid of thescore and replaced it with global.highscoreboard, correct? Because you don;t need two separate variables. Also, if obj_highscoreboard is persistent, the variable does not need to be global. (Global doesn't hurt, but it's not necessary here.)
 
I

iBack

Guest
I think your logic is right, but your code is all wrong. Here's how it should look:
Code:
if(room != rm_game) // where rm_game is the name of the title screen room

{

    visible=false;

}
else
{
    visible=true;

}
(And just making sure, but that code should go in your obj_highscoreboard's room start event.)


Just to clarify, you mean you got rid of thescore and replaced it with global.highscoreboard, correct? Because you don;t need two separate variables. Also, if obj_highscoreboard is persistent, the variable does not need to be global. (Global doesn't hurt, but it's not necessary here.)
it doesn't work. for some reason this time, the draw text is not showing up on title screen. btw i'm drawing highboard score on the screen like this..

Code:
var cx = camera_get_view_x (view_camera[0]);
var cy = camera_get_view_y (view_camera[0]);
var cw = camera_get_view_width (view_camera[0]);

draw_set_color(c_white);
draw_set_halign(fa_center);
draw_set_font(fnt_score);
draw_text(room_width/2, room_height/2, "your score : ");
draw_text(cx + cw/2, cy + 350, string (global.highscoreboard));


if(room != rm_game)

{

    visible=false;

}
else
{
    visible=true;

}
I didn't get rid of "thescore", i basically wrote, with (obj_highscoreboard) global.highscoreboard = global.highscoreboard + 5; so i now have both "thescore" and "global.highscorebaord".
 
I

iBack

Guest
I think your logic is right, but your code is all wrong. Here's how it should look:
Code:
if(room != rm_game) // where rm_game is the name of the title screen room

{

    visible=false;

}
else
{
    visible=true;

}
(And just making sure, but that code should go in your obj_highscoreboard's room start event.)


Just to clarify, you mean you got rid of thescore and replaced it with global.highscoreboard, correct? Because you don;t need two separate variables. Also, if obj_highscoreboard is persistent, the variable does not need to be global. (Global doesn't hurt, but it's not necessary here.)
for some reason it worked when i wrote the following...

Code:
var cx = camera_get_view_x (view_camera[0]);
var cy = camera_get_view_y (view_camera[0]);
var cw = camera_get_view_width (view_camera[0]);





if(room != rm_game)

{
draw_text(cx + cw/2, cy + 350, string (global.highscoreboard));
draw_set_color(c_white);
draw_set_halign(fa_center);
draw_set_font(fnt_score);
draw_text(room_width/2, room_height/2, "your score : ");
    

}
else
{
    
    

}
 
D

dannyjenn

Guest
Ok, so the reason the first code didn't work is because GameMaker completely ignores the draw event whenever the instance is invisible. So once it goes invisible, you can't make it visible again from inside the draw event. (That's why I suggested putting the code in the room start event. The step event would work too, though it would be less efficient.)

But if the second code works, great :)

For future reference, another way you could have done it would be this:
Code:
if(room==rm_game)
{
    exit;
}

var cx = camera_get_view_x (view_camera[0]);
var cy = camera_get_view_y (view_camera[0]);
var cw = camera_get_view_width (view_camera[0]);

draw_set_color(c_white);
draw_set_halign(fa_center);
draw_set_font(fnt_score);
draw_text(room_width/2, room_height/2, "your score : ");
draw_text(cx + cw/2, cy + 350, string (global.highscoreboard));
The exit command basically ends the event (i.e. it ignores the rest of the code in that event). So if you put it at the top like that, it will ignore the draw event whenever you're in rm_game.
 
Top