• 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!

[SOLVED] Randomized Spawning System (Jump n' Run)

D

Delta19ß5

Guest
I'm relative new in GMS and wanted to start with a jump n' run. I want to spawn objects on 5 different locations. Which location one of the object spawn is random. To avoid an overflow of instances I want max 6 instances of the object. Here's my problem I don't really know how to perform this. I have some piece of code but it don't work and I don't know why. I don't get any error. (In the create event of obj_rock rockamount is set to 0)
Here's the code:
///Spawnsystem
spawnpoint = random(4);

if rockamount < 6
{
if spawnpoint = 0
{
instance_create(575, 64, obj_rock);
rockamount += 1;
}
else
{
if spawnpoint = 1
{
instance_create(575, 96, obj_rock);
rockamount += 1;
}
else
{
if spawnpoint = 2
{
instance_create(575, 128, obj_rock);
rockamount += 1;
}
else
{
if spawnpoint = 3
{
instance_create(575, 160, obj_rock);
rockamount += 1;
}
else
{
if spawnpoint = 4
{
instance_create(575, 192, obj_rock)
rockamount += 1;
}
}
}
}
}
}

I got an alternative code that work but the instances only spawn at random y and set x. But i want only spawns at 5 different set locations :/
Here's it:
///Spawnsystem
if global.rockamount < 6
{
instance_create(575, random_range(64, 192), obj_rock);
global.rockamount += 1;
}

I hope you can help me with my program :)
 
A

Aura

Guest
First of all, your if-else structure is badly maintained. All the else-if statements should exist independently.

Code:
if (spawnpoint == 1) {
   //Do something
}
else if (spawnpoint == 2) {
   //Do something
}
else if (spawnpoint == 3) {
   //Do something
}
else if (spawnpoint == 4) {
   //Do something
}
You said that you are using the Create event of obj_rock for that and setting rockamount to 0. That means the variable would get reset with every instance created and you would get an influx of instances. Use a control object whose instances are not created again and again instead.
 
D

Delta19ß5

Guest
Thanks for the answer. Yeah I misstyped, got the variable in a create event of a controller object that doesn´t get created again and again. I´ll try optimize the if-else structure.
 

Mornedil

Member
For this you don't need to make an if-then-else structure at all. You can use the choose() function to pick from a few preset y positions:
Code:
if(rockamount < 6) {
    var yy = choose(64, 96, 128, 160, 192);
    instance_create(575, yy, obj_rock);
    rockamount++;
}
Also thought I'd throw this in there, you can use a switch statement to avoid a whole lot of if-statements in situations like the first long piece of code you posted:
Code:
if(rockamount < 6) {
    switch( irandom(1) ) {
        case 0:
            instance_create(575, 64, obj_rock);
            rockamount++;
            break;
   
        case 1:
            instance_create(575, 96, obj_rock);
            rockamount++;
            break;

        //etc etc
    }
}
 
Last edited:
D

Delta19ß5

Guest
Thanks that sounds pretty good:D
I´ll try this evening and give a report.
 
D

Delta19ß5

Guest
So at first I tried optimize my "if-attempt" but it didn't worked and I still wonder why.
But nevermind thanks to Mornedil both of your suggestion worked. Do you got any idea how I can get to to have a certain amount of time between the creation of a single instance?
Because I want the player to dodge the rocks with changing on 5 "lanes". But if all rocks spawn at once the chance is high every lanes is blocked and the rocks not dodgeable.
 
A

Aura

Guest
What did you change your if-else structure to? I don't see why it won't have worked.

Either way, for what you're currently trying to do, you can look into alarms. I guess you'd want an infinite dodging gameplay. In that case, you would use instance_number(obj_rock) instead of a variables; given that the rocks would eventually get destroyed. Alarms should do the job either way.

Create:
Code:
alarm[0] = room_speed; //Create the first instance after a second
Alarm 0:
Code:
//Create the instance
alarm[0] = room_speed * 2; //Create another instance after two seconds
That way the alarm event would get reset each time an instance is created and another instance would get created every 2 seconds. If you want to spawn only a limited number of instances during the whole gameplay, you'd set a condition for alarm reset.

Code:
if (rockamount < 5) {
   alarm[0] = room_speed;
}
That would make the alarm repeat itself only if rockamount is smaller than 5. And once it isn't, the alarm would never get reset and no instances shall be created afterwards.
 

Mornedil

Member
So at first I tried optimize my "if-attempt" but it didn't worked and I still wonder why..
The if-attempt probably didn't work because you used random() instead of irandom(), and then you checked if the value was equal to a whole number.
spawnpoint = random(4) could give you the value 2.56473, in which case your if(spawnpoint == 2) would basically never return true.
irandom(4) would always return a whole number, either 0, 1, 2, 3 or 4.

But nevermind thanks to Mornedil both of your suggestion worked. Do you got any idea how I can get to to have a certain amount of time between the creation of a single instance?
Because I want the player to dodge the rocks with changing on 5 "lanes". But if all rocks spawn at once the chance is high every lanes is blocked and the rocks not dodgeable.
You can use the alarm event and place the spawn code in there. Add alarm[0] = <VALUE> into the alarm event itself in order to continuously restart the alarm.
 
Last edited:
D

Delta19ß5

Guest
Your ideas sound pretty good. But I don´t understand how you can use alarm[0] = <VALUE> (i thought i´d set the time to wait) to set loops. I tried Aura's suggestion and it seems to work. Thanks a lot :D
But I have one last question even it's a bit off topic.
How can I get a scoreboard that counts how many rocks my player object has passed.
I tried it with collision_line over the whole room at the players x cord. But each rock it passes is counted multiple time (mostly 16 times).
How can I get it only to count one instance once?
 

Mornedil

Member
You should check the documentation when in doubt of how something works, but yeah, I didn't explain it fully because I was notified of Aura's reply while I was typing it, haha.
The value you set the alarm to is how many game frames it will take before the alarm is triggered. if your room speed is 60, then a value of 180 will be 3 seconds. But to make it easier you can just multiply the room_speed variable with a number to set the alarm in seconds, like in Aura's code.

To make it count score only once you will need to make a variable in the rock object to check if it has already counted score.

create event of rock object:
Code:
has_increased_score = false;
step event of rock object:
Code:
if ( !has_increased_score && x < obj_player.x ) {
    score ++;
    has_increased_score = true;
}
If you want you could replace the "x < obj_player.x" part of the if-statement to check in another way if score should be awared, but it should be enough if the rocks are just passing the players on the x coordinate.
 
D

Delta19ß5

Guest
Ok thanks a lot. Do I have to close the threads in this forum? I really don't know how :confused:
 

Mornedil

Member
No problem, always glad to help ^^.
We can't close threads, but if you feel like your questions have been answered you could mark it as solved:
Nocturne said:
If you get your topic solved, you can edit the topic Title to say [SOLVED] (but DO NOT REMOVE THE TITLE, just add this to it) or add a solved Tag, and it's always a nice gesture to post and thank the people that have helped you solve it too.
 
Top