• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

help needed for a tutorial system

S

Stratos.la

Guest
so yeah im losing it! any help would be greatly appreciated! so the basic idea is to have an interactive tutorial. Main steps are on start show instructions, then spawn enemy, instruction again to attack, then spawn second type of enemy, second instructions , third type of enemy , third instructions! But i ve been at it for two days and i dont know what else to do! Sorry for the long post and codes!

all the code is in the oTutorial object. Here is the step event. you will see i have many commented out codes since im still trying to figure it out

GML:
if (!instance_exists(oPotionTutorial) && !instance_exists(oMpotionTutorial))
{
    draw = false;
}

//if there are no potions left instansiate enemies and set the first wave to true
if starter == true && (!instance_exists(oPotionTutorial) && !instance_exists(oMpotionTutorial)) && alarm[1] == -1
{
    alarm[1] = room_speed * 2
    firstWave = true 
    starter = false

}
// if first wave and enemies exist , draw intstruction
if firstWave == true && instance_exists(obj_enemy2Tutorial)
{
    drawspell = true
    firstWave = false
  

if firstWave == false && !instance_exists(obj_enemy2Tutorial)
{
    drawspell = false;
}
}

  
      
if secondWave == true && alarm[1] == -1 // && !instance_exists(obj_enemy2Tutorial) && alarm[1] == -1
{
    alarm[1] = room_speed * 2
    //firstWave = false;
    //if firstWave == false {drawspell2 = true;}
    //secondWave = true;

        //if drawspell2 == true && alarm[4] = -1
        //{
        //    alarm[4] = room_speed * 2
        //}
}
//if !instance_exists(oFireRainTut) && alarm[4] = -1
//    {
    //    alarm[4] = room_speed * 5
//    }
then we have the create event

GML:
if alarm[0] == -1{
alarm[0] = room_speed*1;}

gold = 0;
draw = false;
drawspell = false;
drawspell2 = false;
starter = true;
firstWave = false;
secondWave = false;
finalwave = false;
and my draw gui event
GML:
display_set_gui_size(room_width,room_height)

if (draw == true)
{
    //draw = false
    draw_set_font(magico)
    draw_set_color(c_white)
    draw_set_halign(fa_center)
    draw_text(room_width/2,room_height/2,"Tap on bottles to collect and again to use")
    draw_set_halign(-1)
    draw_set_font(-1)
    draw_set_color(-1)
  
}
if (drawspell == true)
{
    draw_set_font(magico)
    draw_set_color(c_white)
    draw_set_halign(fa_center)
    draw_text(room_width/2,room_height/2,"Draw a fireball spell to attack the enemies")
    draw_set_halign(-1)
    draw_set_font(-1)
    draw_set_color(-1)
}
if (drawspell2 == true)
{
    draw_set_font(magico)
    draw_set_color(c_white)
    draw_set_halign(fa_center)
    draw_text(room_width/2,room_height/2,"Draw a fireRain and tap the enemies to attack")
    draw_set_halign(-1)
    draw_set_font(-1)
    draw_set_color(-1)
}
and all the alarms have inside is to turn the text to false and make it dissapear except the alarm[1] that spawns two enemies with instance_create_layer ! so with a bit more detail i want to spawn 3 types of enemy waves and show different instructions on each wave. Ideally i would like (as im trying to do now) to show the instruction for a second or two then hide it and if the user doesnt do anything draw them again. and thats on all waves. the only kinda working code i had was this but still it didnt work out the proper way i needed! on the second wave it spawns 4 enemies instead of two and re shows the first waves instructions!

GML:
// remove instruction if potions are not there
if (!instance_exists(oPotionTutorial) && !instance_exists(oMpotionTutorial))
    {
        draw = false;
    }

//if there are no potions left instansiate enemies and set the first wave to true
if starter == true && (!instance_exists(oPotionTutorial) && !instance_exists(oMpotionTutorial)) && alarm[1] == -1
    {
        alarm[1] = room_speed * 2
        firstWave = true
        drawspell = true;
        starter = false;
        // hide the text after some time
        if drawspell == true && alarm[3] == -1
            {alarm[3] = room_speed * 3}
    } 

// if the first wave is still tru and there are no enemies left set it to false hide the instructions and start the second wave
if firstWave == true && !instance_exists(obj_enemy2Tutorial)
    {
        firstWave = false;
        drawspell = false;
        secondWave = true;

    }
  
// if the second wave is true and there are no enemies on the screen instantiate them and show the second instrucions
if secondWave == true && !instance_exists(obj_enemy2Tutorial) && alarm[1] == -1
    {
        alarm[1] = room_speed * 3
        drawspell2 = true;
        //hide them after 3 seconds
        if drawspell2 == true && alarm[4] = -1
        {alarm[4] = room_speed * 3}
    }
 

Rob

Member
I think you might benefit more from a state system than lots of different checks (if it's all the different checks that are actually causing you the problems).

If you have states, you can decide what happens via player input, what they see, and what code runs, within that state block.

If you're having difficulty planning what should happen when then making some notes and organising "what should happen when" will help a lot. EG - does the player have to move to a certain position before the next state will trigger? Do they have to cast a certain spell, etc, and this will let you know how to plan out your states.

So you might have an enum like this:


GML:
//Create event

enum tutorial{
    init, //Initialise any variables you need to
    learn_movement, //player learns how to move
    learn_fireball, //player learns how to cast fireball
    finish_tutoral, //player finishes tutorial and either go to title screen or start game
}

state = tutorial.init;
GML:
//Step

if (state == tutorial.init){
    //initialise stuff
    state = tutorial.learn_movement;
}

if (state == tutorial.learn_movement){
    if obj_player.x >= 100 state = tutorial.learn_fireball;
}

if (state == tutorial.learn_fireball){
    if space is pressed state = tutorial.finish_tutorial;
}
 

Yal

šŸ§ *penguin noises*
GMC Elder
Having a queue of some sort would be the most natural way to handle this: the queue contains an inline array or a struct or something, which contains tutorial message(s), which are shown first, and then a list of objects to create; when the messages all are closed, you create those objects, and then switch to a state where you monitor the number of them; when they've all destroyed, you take the next item out of the queue and repeat the process. The objects can be either enemies to kill, items to collect, or even invisible markers to collect (for things like movement tutorials). To add new things to the tutorial, just add more things to the queue, and you can reorder things easily.
 

Nidoking

Member
I'm working on a tutorial system and plan to use a timeline for it. Timelines let you set up a sequence of steps that can be separated by number of steps or by user action (by manipulating the timeline speed). A sequence might end up working better, but I'd have to learn how to use them.
 
Top