Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

109 Commits

Repository files navigation

💾 floppy 💾

floppy is a micro game engine for beginners written in javascript.

  • it has basic primitives for drawing (rectangles, circles, lines, text)
  • it includes interaction (click, tap)
  • it includes sound (generated)
  • it comes with a (simple) web editor online and ...
  • ... with a tutorial to write your first game (simple, but complete)

Index

Tutorial

Commands

Editor

Thanks and Inspiration

Tutorial

In this tutorial we will create a squash like game.

Step 0

When opening the web editor default code include two functions (update and render) with empty body.

Code

functionupdate(){}functionrender(){}

What it is inside those functions it is executed continuosly (about 60 times each second). First the update function, then the render function.

Result

Step 1 - Coloring Background

In order to color the whole game window with a light blue, we add a Rect command to the render function.

Code

functionupdate(){}functionrender(){Rect(0,0,WIDTH,HEIGHT,"lightblue");// NEW}

WIDTH is a constant = 320 = the whole width of game window

HEIGHT is a constant = 480 = the whole height of game window

Result

Step 2 - Drawing Pad

To draw the pad, first we define four new variables (padX, padY, padW, padH) and then add a Rect command (using those variables).

Code

padX=100;// NEWpadY=430;// NEW padW=120;// NEWpadH=15;// NEWfunctionupdate(){}functionrender(){Rect(0,0,WIDTH,HEIGHT,"lightblue");Rect(padX,padY,padW,padH,"green");// NEW}

Result

Step 3 - Drawing Ball

To draw the ball, first we define its variables (ballX, ballY, ballR) and then add a Circle command (using those variables).

Code

padX=100;padY=430;padW=120;padH=15;ballX=160;// NEWballY=70;// NEWballR=16;// NEWfunctionupdate(){}functionrender(){Rect(0,0,WIDTH,HEIGHT,"lightblue");Rect(padX,padY,padW,padH,"green");Circle(ballX,ballY,ballR,"red");// NEW}

Result

Step 4 - Moving Ball

To move the ball we update its position (ballX, ballY).

Three new variables are defined in order to manage the update (dirX, dirY, speed).

Code

padX=100;padY=430;padW=120;padH=15;ballX=160;ballY=70;ballR=16;dirX=1;// NEWdirY=1;// NEWspeed=2;// NEWfunctionupdate(){ballX=ballX+dirX*speed;// NEWballY=ballY+dirY*speed;// NEW}functionrender(){Rect(0,0,WIDTH,HEIGHT,"lightblue");Rect(padX,padY,padW,padH,"green");Circle(ballX,ballY,ballR,"red");// NEW}

Result

Step 5 - Bounching Right

When the ball reaches the right border of game window we set dirX to -1 in order to have the ball bounching.

Code

padX=100;padY=430;padW=120;padH=15;ballX=160;ballY=70;ballR=16;dirX=1;dirY=1;speed=2;functionupdate(){if(ballX+ballR>WIDTH){// NEWdirX=-1;// NEW}// NEW ballX=ballX+dirX*speed;ballY=ballY+dirY*speed;}functionrender(){Rect(0,0,WIDTH,HEIGHT,"lightblue");Rect(padX,padY,padW,padH,"green");Circle(ballX,ballY,ballR,"red");}

Step 6 - Bounching Left

When the ball reaches the left border of game window we set dirX to 1 in order to have the ball bounching.

Code

padX=100;padY=430;padW=120;padH=15;ballX=160;ballY=70;ballR=16;dirX=1;dirY=1;speed=2;functionupdate(){if(ballX+ballR>WIDTH){dirX=-1;}if(ballX<ballR){// NEWdirX=1;// NEW }// NEWballX=ballX+dirX*speed;ballY=ballY+dirY*speed;}functionrender(){Rect(0,0,WIDTH,HEIGHT,"lightblue");Rect(padX,padY,padW,padH,"green");Circle(ballX,ballY,ballR,"red");}

Step 7 - Bounching Top

When the ball reaches the top border of game window we set dirY to 1 in order to have the ball bounching.

Code

padX=100;padY=430;padW=120;padH=15;ballX=160;ballY=70;ballR=16;dirX=1;dirY=1;speed=2;functionupdate(){if(ballX+ballR>WIDTH){dirX=-1;}if(ballX<ballR){dirX=1;}if(ballY<ballR){// NEWdirY=1;// NEW}// NEWballX=ballX+dirX*speed;ballY=ballY+dirY*speed;}functionrender(){Rect(0,0,WIDTH,HEIGHT,"lightblue");Rect(padX,padY,padW,padH,"green");Circle(ballX,ballY,ballR,"red");}

Step 8 - Moving Pad

To move the pad, when TAPPED is true, we set the position of the pad taking the x position of our tapping (TAPX).

Code

padX=100;padY=430;padW=120;padH=15;ballX=160;ballY=70;ballR=16;dirX=1;dirY=1;speed=2;functionupdate(){if(ballX+ballR>WIDTH){dirX=-1;}if(ballX<ballR){dirX=1;}if(ballY<ballR){dirY=1;}if(TAPPED){// NEWpadX=TAPX-padW/2;// NEW}// NEWballX=ballX+dirX*speed;ballY=ballY+dirY*speed;}functionrender(){Rect(0,0,WIDTH,HEIGHT,"lightblue");Rect(padX,padY,padW,padH,"green");Circle(ballX,ballY,ballR,"red");}

Result

Step 9 - Bounching Pad

When the ball reaches the pad we set dirY to -1 in order to have the ball bounching on the pad.

Code

padX=100;padY=430;padW=120;padH=15;ballX=160;ballY=70;ballR=16;dirX=1;dirY=1;speed=2;functionupdate(){if(ballX+ballR>WIDTH){dirX=-1;}if(ballX<ballR){dirX=1;}if(ballY<ballR){dirY=1;}if(TAPPED){padX=TAPX-padW/2;}if((ballX>padX)&&(ballX<padX+padW)&&(ballY+ballR>padY)){// NEWdirY=-1;// NEW}// NEWballX=ballX+dirX*speed;ballY=ballY+dirY*speed;}functionrender(){Rect(0,0,WIDTH,HEIGHT,"lightblue");Rect(padX,padY,padW,padH,"green");Circle(ballX,ballY,ballR,"red");}

Step 10 - Restarting Ball

If the ball crosses the pad games is restarted from initial position.

Code

padX=100;padY=430;padW=120;padH=15;ballX=160;ballY=70;ballR=16;dirX=1;dirY=1;speed=2;functionupdate(){if(ballX+ballR>WIDTH){dirX=-1;}if(ballX<ballR){dirX=1;}if(ballY<ballR){dirY=1;}if(TAPPED){padX=TAPX-padW/2;}if((ballX>padX)&&(ballX<padX+padW)&&(ballY+ballR>padY)){dirY=-1;}if(ballY+ballR>padY+padH){// NEWballX=160;// NEWballY=70;// NEW}ballX=ballX+dirX*speed;ballY=ballY+dirY*speed;}functionrender(){Rect(0,0,WIDTH,HEIGHT,"lightblue");Rect(padX,padY,padW,padH,"green");Circle(ballX,ballY,ballR,"red");}

Step 11 - Adding Score

In order to manage and show the score, we add a new variable (score) and we use the Text command in the render function.

Code

padX=100;padY=430;padW=120;padH=15;ballX=160;ballY=70;ballR=16;dirX=1;dirY=1;speed=2;score=0;// NEWfunctionupdate(){if(ballX+ballR>WIDTH){dirX=-1;}if(ballX<ballR){dirX=1;}if(ballY<ballR){dirY=1;}if(TAPPED){padX=TAPX-padW/2;}if((ballX>padX)&&(ballX<padX+padW)&&(ballY+ballR>padY)){dirY=-1;score=score+10;// NEW}if(ballY+ballR>padY+padH){ballX=160;ballY=70;}ballX=ballX+dirX*speed;ballY=ballY+dirY*speed;}functionrender(){Rect(0,0,WIDTH,HEIGHT,"lightblue");Rect(padX,padY,padW,padH,"green");Circle(ballX,ballY,ballR,"red");Text(score,50,50,30,"green");// NEW}

Step 12 - Adding Lifes

To manage multiple lifes, we add a new variable (lifes). We set it initially to 3 and we subtract 1 every time we lose a ball.

Code

padX=100;padY=430;padW=120;padH=15;ballX=160;ballY=70;ballR=16;dirX=1;dirY=1;speed=2;score=0;lifes=3;// NEWfunctionupdate(){if(ballX+ballR>WIDTH){dirX=-1;}if(ballX<ballR){dirX=1;}if(ballY<ballR){dirY=1;}if(TAPPED){padX=TAPX-padW/2;}if((ballX>padX)&&(ballX<padX+padW)&&(ballY+ballR>padY)){dirY=-1;score=score+10;}if(ballY+ballR>padY+padH){ballX=160;ballY=70;lifes=lifes-1;// NEW}if(lifes==0){// NEWspeed=0;// NEW}// NEWballX=ballX+dirX*speed;ballY=ballY+dirY*speed;}functionrender(){Rect(0,0,WIDTH,HEIGHT,"lightblue");Rect(padX,padY,padW,padH,"green");Circle(ballX,ballY,ballR,"red");Text(score,50,50,30,"green");Text(lifes,250,50,30,"red");// NEW}

Step 13 - Adding Challenge

To add a challenge in the game, we increase the ball speed by 0.2 at each bounch on the pad.

Code

padX=100;padY=430;padW=120;padH=15;ballX=160;ballY=70;ballR=16;dirX=1;dirY=1;speed=2;score=0;lifes=3;functionupdate(){if(ballX+ballR>WIDTH){dirX=-1;}if(ballX<ballR){dirX=1;}if(ballY<ballR){dirY=1;}if(TAPPED){padX=TAPX-padW/2;}if((ballX>padX)&&(ballX<padX+padW)&&(ballY+ballR>padY)){dirY=-1;score=score+10;speed=speed+0.2;// NEW}if(ballY+ballR>padY+padH){ballX=160;ballY=70;lifes=lifes-1;}if(lifes==0){speed=0;}ballX=ballX+dirX*speed;ballY=ballY+dirY*speed;}functionrender(){Rect(0,0,WIDTH,HEIGHT,"lightblue");Rect(padX,padY,padW,padH,"green");Circle(ballX,ballY,ballR,"red");Text(score,50,50,30,"green");Text(lifes,250,50,30,"red");}

Step 14 - Adding Sound

Last enrichment. We add a sound (generic) when bounching using the SoundEffect command.

Code

padX=100;padY=430;padW=120;padH=15;ballX=160;ballY=70;ballR=16;dirX=1;dirY=1;speed=2;score=0;lifes=3;functionupdate(){if(ballX+ballR>WIDTH){dirX=-1;SoundEffect();//}if(ballX<ballR){dirX=1;SoundEffect();//}if(ballY<ballR){dirY=1;SoundEffect();//}if(TAPPED){padX=TAPX-padW/2;}if((ballX>padX)&&(ballX<padX+padW)&&(ballY+ballR>padY)){dirY=-1;score=score+10;speed=speed+0.2;SoundEffect();//}if(ballY+ballR>padY+padH){ballX=160;ballY=70;lifes=lifes-1;}if(lifes==0){speed=0;}ballX=ballX+dirX*speed;ballY=ballY+dirY*speed;}functionrender(){Rect(0,0,WIDTH,HEIGHT,"lightblue");Rect(padX,padY,padW,padH,"green");Circle(ballX,ballY,ballR,"red");Text(score,50,50,30,"green");Text(lifes,250,50,30,"red");}

Step 15 - Publishing Online

We can finally publish the game using HTML Pasta.

Here the game published online. Game.

Commands

Game Loop

functionupdate(){};functionrender(){};

Draw

Rect

Rect(x,y,w,h,"color");

Circle

Circle(x,y,r,"color");

Text

Text("text",x,y,size,"color");

Line

Line(x_init,y_init,x_end,y_end,width,"color");

Constants

WIDTHHEIGHT

Interaction

TAPPEDTAPXTAPY

Sound

SoundEffect(frequencyValue,attack,decay,type,volumeValue,panValue,wait,pitchBendAmount,reverse,randomValue,dissonance,echo,reverb,timeout);

more information @: https://github.com/kittykatattack/sound.js#generating-sound-effects-and-music

Utils

Random(min,max);// Random integer from min to maxPitchToFrequency(octave,semitone);// Frequency from octave (integer), semitone (integer)

Editor

web editor

with:

  • live preview
  • syntax warnings
  • saving game
  • exporting game
  • using offline

Thanks and Inspirations

For game engine: How To Design A Mobile Game With HTML5

For approach: pico-8

For sound: sound.js

About

a micro game engine for beginners

Resources

Stars

37 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors