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
bg7 = loadImage("assets/bg.png");
bg6 = loadImage("assets/bg6.png");
bg5 = loadImage("assets/bg5.png");
bg4 = loadImage("assets/bg2.png");
bg3 = loadImage("assets/bg4.png");
bg2 = loadImage("assets/bg1.png");
bg1 = loadImage("assets/bg3.png");
platform = loadImage("assets/platform.png");
platform.resize(960,610);
// 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);
}
// 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).
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;}
// 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;}
}
// 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
for (int i=0; i<sprites.length;i++){
sprites[i][0]=loadImage("assets/run/run"+i+".png");
sprites[i][0].resize(53,74);
for (int i=0; i<sprites.length;i++){
sprites[i][1]=loadImage("assets/jump/jump"+i+".png");
sprites[i][1].resize(53,74);
for (int i=0; i<sprites.length;i++){
sprites[i][2]=loadImage("assets/slide/slide"+i+".png");
sprites[i][2].resize(53,57);
// 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);
}
}
// 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);
image(sprites[frameCount/2%sprites.length][x],xcoord,ycoord);
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;
}
}
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
for (int i=0; i<sprites.length;i++){
sprites[i][0]=loadImage("assets/run/run"+i+".png");
sprites[i][0].resize(53,74);
for (int i=0; i<sprites.length;i++){
sprites[i][1]=loadImage("assets/jump/jump"+i+".png");
sprites[i][1].resize(53,74);
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
bg7 = loadImage("assets/bg.png");
bg6 = loadImage("assets/bg6.png");
bg5 = loadImage("assets/bg5.png");
bg4 = loadImage("assets/bg2.png");
bg3 = loadImage("assets/bg4.png");
bg2 = loadImage("assets/bg1.png");
bg1 = loadImage("assets/bg3.png");
platform = loadImage("assets/platform.png");
platform.resize(960,610);
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;}
int x=0, xcoord=100, ycoord=425;
image(sprites[frameCount/2%sprites.length][x],xcoord,ycoord);
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;
}
}
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!