GML [SOLVED] triple parallax starfield

Heavybrush

Member
Hi guys,
I have a new project, and I would like to figure out how to make a triple parallax starfield

for now i made this:

start event
Code:
/// @description create starfield

//inputs
starField = 3;
starDepth[0] = 100;
starDepth[1] = 110;
starDepth[2] = 120;
stars = 0;
maxStars = 1000;
spd[0] = 0.3;
spd[1] = 0.2;
spd[2] = 0.1;
minSpd = 0;
maxSpd = 1;
dir = 90;
posX[0] = 0;
posX[1] = 0;
posX[2] = 0;
posY[0] = 0;
posY[1] = 0;
posY[2] = 0;
posW = room_width;
posH = room_height;
starColor[0] = global.ega_white;
starColor[1] = global.ega_light_grey;
starColor[2] = global.ega_dark_grey;

//stars init
for(var s = 0;s < starField;s++) {
    for(var i = maxStars;i > stars;i--) {
        //depth
        starDepth[i] = starDepth[s];
    
        //position
        posX[i] = irandom(posW);
        posY[i] = irandom(posH);
    
        //speed
        spd[i] = spd[s];
    
        //color
        starColor[i] = starColor[s];
    }
}
step event
Code:
/// @description move stars

//movement
for(var s = 0;s < starField;s++) {
    //direction
    var ax = dcos(dir);
    var ay = dsin(dir);
 
    for(var i = maxStars;i > stars;i--) {
        //position
        var xx = posX[i];
        var yy = posY[i];
    
        //speed
        xx += spd[i] * ax;
        yy += spd[i] * ay;
    
        //wrap
        if(xx < 0) xx += posW;
        else if(xx > posW) xx -= posW;
        if(yy < 0) yy += posH;
        else if(yy > posH) yy -= posH;
    
        //new position
        posX[i] = xx;
        posY[i] = yy;
    }
}
draw event
Code:
/// @description draw stars

//stars drawing
for(var s = 0;s < starField;s++) {
    for(var i = maxStars;i > stars;i--) {
        draw_point_colour(posX[i],posY[i],starColor[i]);
    }
}
it works but just one layer
i could put all the step event in the draw event but i made this way to have everything more clear

and i already tried using 2d arrays but i can't manage them yet
so i would like to understand how to do and talk about it with you guys

currently the direction of the stars is opposite to the direction, for one reason, it could be enhanced using the direction of my ship to have a little change

and i decided to make it with code instead animating a sprite, because you could take a powerup boost and have also a stars feedback having more speed also for them, and hopefully a little stroke about them when you are very fast
 
Last edited:

TheouAegis

Member
Because all you are doing in the create event is overwriting all the arrays 3 times.

maxStars is how manyvstars are in the room, right? Not how many are at each depth.

Remove the for(var s...) loop. It's not necessary.

The ONLY "star" arrays you need to define during the loop are posX and posY. Remove the others.

Code:
for(var i = maxStars;i > 0; i--) {
       //position
       posX[i] = irandom(posW);
       posY[i] = irandom(posH);
}
You also want more stars far away, fewer up close.

Calculate the value of s for each star when moving and drawing. Don't use 1000-index arrays.

Code:
var s,xx,yy;
var ax = dcos(dir), ay = dsin(dir);
for(var i=maxStars; i>0; i--) {
    s = floor(log(i/5));
    xx = posX[i] + spd[s] * ax;
    yy= posY[i] + spd[s] * ay;
    //wrap
       if(xx < 0) xx += posW;
       else if(xx > posW) xx -= posW;
       if(yy < 0) yy += posH;
       else if(yy > posH) yy -= posH;
    posX[i] = xx;
    posY[i] = yy;
}
I noticed you don't actually use starDepth.....
 

Heavybrush

Member
stars is 0 because i have set it as initial number of stars, max stars is the max amount of stars for each layer

actually I thought to be using them
I'm not using min speed and max speed, but only for now
 

Heavybrush

Member
solved

Code:
/// @description create starfield

//inputs
starField = 3;
starDepth[0] = 100;
starDepth[1] = 110;
starDepth[2] = 120;
stars = 0;
maxStars = 250;
spd[0] = 0.3;
spd[1] = 0.2;
spd[2] = 0.1;
minSpd = 0;
maxSpd = 1;
dir = 90;
posX[0,0] = 0;
posX[1,0] = 0;
posX[2,0] = 0;
posY[0,0] = 0;
posY[1,0] = 0;
posY[2,0] = 0;
posW = room_width;
posH = room_height;
starColor[0] = global.ega_white;
starColor[1] = global.ega_light_grey;
starColor[2] = global.ega_dark_grey;

//stars init
for(var s = 0;s < starField;s++) {
    for(var i = maxStars;i > stars;i--) {
        //position
        posX[s,i] = irandom(posW);
        posY[s,i] = irandom(posH);
    }
}
Code:
/// @description move stars

//movement
for(var s = 0;s < starField;s++) {
    //direction
    var ax = dcos(dir);
    var ay = dsin(dir);
   
    for(var i = maxStars;i > stars;i--) {
        //position
        var xx = posX[s,i];
        var yy = posY[s,i];
       
        //speed
        xx += spd[s] * ax;
        yy += spd[s] * ay;
       
        //wrap
        if(xx < 0) xx += posW;
        else if(xx > posW) xx -= posW;
        if(yy < 0) yy += posH;
        else if(yy > posH) yy -= posH;
       
        //new position
        posX[s,i] = xx;
        posY[s,i] = yy;
    }
}
Code:
/// @description draw stars

//stars drawing
for(var s = 0;s < starField;s++) {
    for(var i = maxStars;i > stars;i--) {
        draw_point_colour(posX[s,i],posY[s,i],starColor[s]);
    }
}
I was close to the solution
thank you so much :)
 
Top