Create an HTML5 game like Space is Key with a lot of room for customization step 2: adding obstacles
Talking about Space is Key game, Game development, HTML5, Javascript and Phaser.
This has been one of the most difficult post to write. I am currently on holiday and I have a really bad connection, anyway finally I managed to publish something, all in all I am a blogger and bloggers have to post!
Here we go with the second step of the HTML5 game like Space is Key with a lot of room for customization, this time we’ll be adding some random obstacles and manage collisions, covering groups and physics overlapping.
At this time, generated levels aren’t guaranteed to be solvable, this will involve some artificial intelligence to create levels according to game parameters such as jump speed, but I am definitively willing to do it, meanwhile here is what you have at the moment:
Click the mouse to make blue box jump, avoid obstacles.
And here is the commented source code, with new lines highlighted, created with Phaser Framework:
<!doctype html>
<html>
<head>
<script src="phaser.min.js"></script>
<style>
body{margin:0}
</style>
<script type="text/javascript">
window.onload = function() {
// here we define a new 640x480 game, with three core functions:
// onPreload to be executed when the game preloads
// onCreate to be executed once the game is firstly created
// onUpdate to be called every time the game us updated
var game = new Phaser.Game(640,480,Phaser.CANVAS,"",{preload:onPreload, create:onCreate, update:onUpdate});
// the square!! the hero of the game
var theSquare;
// the spike!! hero's worst (and only) enemy
var theSpike;
// how many spikes are we going to add?
var spikesAmount=10;
// all spikes are going to be grouped here
var spikesGroup//=game.add.group();
// square's horizontal speed in pixels/frame
var xSpeed=4;
// square's jump height, in pixels
var jumpHeight=40;
// square's jump width, in pixels. xSpeed must divide jumpWidth
var jumpWidth=120;
// rotation performed at every jump, in degrees
var jumpRotation=180;
// time passed since the player started jumping, in frames
var jumpTime=0;
// is the player jumping?
var isJumping=false;
// simple degrees to radians conversion
var degToRad=0.0174532925;
// array containing all various floor y positions, in pixels
var floorY=Array(92,184,276,368,460);
// floor I am currently moving on
var currentFloor=0;
// floor height, in pixels
var floorHeight=20;
// x position where the level starts, in pixels
var levelStart=0;
// x position where the level ends, in pixels
var levelEnd=640;
// THE GAME IS PRELOADING
function onPreload() {
// loading player image
game.load.image("square", "square.png");
// loading spike image
game.load.image("spike", "spike.png");
}
// THE GAME HAS BEEN CREATED
function onCreate() {
// simply drawing all floors, as lines from levelStart to levelEnd, tickness floorHeight
var floor = game.add.graphics(0,0);
floor.lineStyle(floorHeight, 0x440044, 1);
for(i=0;i<floorY.length;i++){
floor.moveTo(levelStart,floorY[i]+floorHeight/2);
floor.lineTo(levelEnd,floorY[i]+floorHeight/2);
}
// adding the hero
theSquare=game.add.sprite(levelStart,floorY[currentFloor]-game.cache.getImage("square").height/2,"square");
theSquare.anchor.setTo(0.5,0.5);
// adding some spikes, first we declare the group
spikesGroup=game.add.group();
// the we create the spikes as sprites and randomly place them on the stage
for(i=0;i<spikesAmount;i++){
var randomFloor=Math.floor(Math.random()*floorY.length)
theSpike=game.add.sprite(Math.floor(Math.random()*400)+120,floorY[randomFloor]-game.cache.getImage("spike").height/2,"spike");
theSpike.anchor.setTo(0.5,0.5);
// finally we add the newly created spike to the group
spikesGroup.add(theSpike);
}
// event listener for mouse down
game.input.onDown.add(jump, this);
}
function jump(){
// if we aren't jumping... then JUMP!!
if (! isJumping) {
jumpTime=0;
isJumping=true;
}
}
// THE GAME IS GOING TO BE UPDATED
function onUpdate() {
// temp variable to let us know if we are on an odd or even floor
var mod=currentFloor%2;
// updating square x position
theSquare.x+=xSpeed*(1-2*mod);
// if the square reached the end of the floor...
if (theSquare.x>levelEnd&&mod==0||theSquare.x<levelStart&&mod==1) {
// move onto next floor
currentFloor++;
// if we just finished the lowest floor...
if (currentFloor>floorY.length-1) {
// start the game again
currentFloor=0;
}
// even or odd?
mod=currentFloor%2
// we start on the ground
isJumping=false;
theSquare.rotation=0;
theSquare.x=levelEnd*mod+levelStart*(1-mod);
theSquare.y=floorY[currentFloor]-game.cache.getImage("square").height/2;
}
// if we are jumping...
if (isJumping) {
// calculating the number of frames we will be jumping
var jumpFrames=jumpWidth/xSpeed;
// calculating how many degrees should the square rotate at each frame
var degreesPerFrame=jumpRotation/jumpFrames*(1-2*mod);
// calculating how may radians we have to apply to sine trigonometry function to simulate player jump
var radiansPerFrame=(180/jumpFrames)*degToRad
// anohter frame jumping...
jumpTime++;
// updating rotation
theSquare.angle+=degreesPerFrame;
// updating y position
theSquare.y=floorY[currentFloor]-game.cache.getImage("square").height/2-jumpHeight*Math.sin(radiansPerFrame*jumpTime);
// if we jumped enough...
if (jumpTime==jumpFrames) {
// ... just stop jumping
isJumping=false;
theSquare.y=floorY[currentFloor]-game.cache.getImage("square").height/2;
}
}
// checking for collision between the square and the group of spikes, and calling onCollision function if actors overlap
game.physics.overlap(theSquare,spikesGroup,onCollision);
}
// at the moment if there's a collision we simply make the player restart from the last visited floor
function onCollision(){
var mod=currentFloor%2;
isJumping=false;
theSquare.rotation=0;
theSquare.x=levelEnd*mod+levelStart*(1-mod);
theSquare.y=floorY[currentFloor]-game.cache.getImage("square").height/2;
}
function onRender(){
}
};
</script>
</head>
<body>
</body>
</html>
You can also download the source code with all required libraries
Never miss an update! Subscribe, and I will bother you by email only when a new game or full source code comes out.