Inspiration:
For my midterm project, I was inspired by the mechanics of the Chrome Dino Runner game and tried to create a newer version with more features.
Process:
First, the layers of the background are loaded, then resized to fit the screen.
// Load the background images void load(){ bg7 = loadImage("assets/bg.png"); // Resize the images bg7.resize(960,540); bg6 = loadImage("assets/bg6.png"); bg6.resize(960,540); bg5 = loadImage("assets/bg5.png"); bg5.resize(960,540); bg4 = loadImage("assets/bg2.png"); bg4.resize(960,540); bg3 = loadImage("assets/bg4.png"); bg3.resize(960,540); bg2 = loadImage("assets/bg1.png"); bg2.resize(960,540); bg1 = loadImage("assets/bg3.png"); bg1.resize(960,540); platform = loadImage("assets/platform.png"); platform.resize(960,610); }
Infinite side-scrolling:
Instead of making the character move inside the display window, I used an infinite side-scrolling in which the character is static whereas the background moves from the right to the left. To achieve that, I used two images placed next to each other that reappear on the right side once they get out of the display window.
Parallax effect
To give the game a realistic aspect, I added a Parallax effect in which the far-away clouds and mountains seem to move more slowly than the closer ones, by changing each layer’s (6 layers) position by a different amount (between 1 and 5).
// Parallax effect void update(){ x6--; x6_2--; x5-=2; x5_2-=2; x4-=3; x4_2-=3; x3-=3; x3_2-=3; x2-=4; x2_2-=4; x1-=5; x1_2-=5; // Infinite scrolling if (x6<=-width){x6=width;} if (x6_2<=-width){x6_2=width;} if (x5<=-width){x5=width;} if (x5_2<=-width){x5_2=width;} if (x4<=-width){x4=width;} if (x4_2<=-width){x4_2=width;} if (x3<=-width){x3=width;} if (x3_2<=-width){x3_2=width;} if (x2<=-width){x2=width;} if (x2_2<=-width){x2_2=width;} if (x1<=-width){x1=width;} if (x1_2<=-width){x1_2=width;} }
Spritesheet:
To animate the character, I am using 3 sprite sheets stored in a 2D array (running, jumping, sliding), each row has 10 images.
// Upload all the sprites void loadsprites(){ // Running for (int i=0; i<sprites.length;i++){ sprites[i][0]=loadImage("assets/run/run"+i+".png"); sprites[i][0].resize(53,74); } // Jumping for (int i=0; i<sprites.length;i++){ sprites[i][1]=loadImage("assets/jump/jump"+i+".png"); sprites[i][1].resize(53,74); } // Sliding for (int i=0; i<sprites.length;i++){ sprites[i][2]=loadImage("assets/slide/slide"+i+".png"); sprites[i][2].resize(53,57); } }
To loop over the sprites, I am using frameCount:
image(sprites[frameCount/2%sprites.length][x],xcoord,ycoord);
Then, I am using both keyPressed() and keyReleased() functions to detect when the user presses UP and DOWN keys and proceed with the movement.
void keyPressed(){ if (keyCode==UP){ x=1; ycoord=360; } if (keyCode==DOWN){ x=2; ycoord=442; } } void keyReleased(){ if (keyCode==UP){ x=0; ycoord=425; } if (keyCode==DOWN){ x=0; ycoord=425; } }
Gravity:
To make it a bit more realistic, I am trying to add the gravity effect to when the character jumps and falls back down.
Full Code:
PImage bg1, bg2, bg3, bg4, bg5, bg6, bg7, platform; // Background images int x1=0, x1_2=960, x2=0, x2_2=960, x3=0, x3_2=960; // X-coordinates of the images int x4=0, x4_2=960, x5=0, x5_2=960, x6=0, x6_2=960; // X-coordinates of the images PImage[][] sprites = new PImage[10][3]; // Store the sprites // Upload all the sprites void loadsprites(){ // Running for (int i=0; i<sprites.length;i++){ sprites[i][0]=loadImage("assets/run/run"+i+".png"); sprites[i][0].resize(53,74); } // Jumping for (int i=0; i<sprites.length;i++){ sprites[i][1]=loadImage("assets/jump/jump"+i+".png"); sprites[i][1].resize(53,74); } // Sliding for (int i=0; i<sprites.length;i++){ sprites[i][2]=loadImage("assets/slide/slide"+i+".png"); sprites[i][2].resize(53,57); } } // Load the background images void load(){ bg7 = loadImage("assets/bg.png"); // Resize the images bg7.resize(960,540); bg6 = loadImage("assets/bg6.png"); bg6.resize(960,540); bg5 = loadImage("assets/bg5.png"); bg5.resize(960,540); bg4 = loadImage("assets/bg2.png"); bg4.resize(960,540); bg3 = loadImage("assets/bg4.png"); bg3.resize(960,540); bg2 = loadImage("assets/bg1.png"); bg2.resize(960,540); bg1 = loadImage("assets/bg3.png"); bg1.resize(960,540); platform = loadImage("assets/platform.png"); platform.resize(960,610); } void display(){ image(bg7,0,0); image(bg6,x6,0); image(bg6,x6_2,0); image(bg5,x5,0); image(bg5,x5_2,0); image(bg4,x4,0); image(bg4,x4_2,0); image(bg3,x3,0); image(bg3,x3_2,0); image(bg2,x2,0); image(bg2,x2_2,0); image(bg1,x1,0); image(bg1,x1_2,0); tint(#7cdfd2); image(platform,x1,0); image(platform,x1_2,0); noTint(); } // Parallax effect void update(){ x6--; x6_2--; x5-=2; x5_2-=2; x4-=3; x4_2-=3; x3-=3; x3_2-=3; x2-=4; x2_2-=4; x1-=5; x1_2-=5; // Infinite scrolling if (x6<=-width){x6=width;} if (x6_2<=-width){x6_2=width;} if (x5<=-width){x5=width;} if (x5_2<=-width){x5_2=width;} if (x4<=-width){x4=width;} if (x4_2<=-width){x4_2=width;} if (x3<=-width){x3=width;} if (x3_2<=-width){x3_2=width;} if (x2<=-width){x2=width;} if (x2_2<=-width){x2_2=width;} if (x1<=-width){x1=width;} if (x1_2<=-width){x1_2=width;} } void setup(){ size(960,540); load(); loadsprites(); } int x=0, xcoord=100, ycoord=425; float g=2; void gravity(){ if (ycoord<425){ ycoord+=g; } } void draw(){ display(); update(); gravity(); image(sprites[frameCount/2%sprites.length][x],xcoord,ycoord); } void keyPressed(){ if (keyCode==UP){ x=1; ycoord=360; } if (keyCode==DOWN){ x=2; ycoord=442; } } void keyReleased(){ if (keyCode==UP){ x=0; ycoord=425; } if (keyCode==DOWN){ x=0; ycoord=425; } }
Ooo, looks very nice Badr, keep going!