Create an HTML5 game like Space is Key with a lot of room for customization step 2: adding obstacles

Read all posts about "" game

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

Get the most popular Phaser 3 book

Through 202 pages, 32 source code examples and an Android Studio project you will learn how to build cross platform HTML5 games and create a complete game along the way.

Get the book

214 GAME PROTOTYPES EXPLAINED WITH SOURCE CODE
// 1+2=3
// 100 rounds
// 10000000
// 2 Cars
// 2048
// A Blocky Christmas
// A Jumping Block
// A Life of Logic
// Angry Birds
// Angry Birds Space
// Artillery
// Astro-PANIC!
// Avoider
// Back to Square One
// Ball Game
// Ball vs Ball
// Ball: Revamped
// Balloon Invasion
// BallPusher
// Ballz
// Bar Balance
// Bejeweled
// Biggification
// Block it
// Blockage
// Bloons
// Boids
// Bombuzal
// Boom Dots
// Bouncing Ball
// Bouncing Ball 2
// Bouncy Light
// BoxHead
// Breakout
// Bricks
// Bubble Chaos
// Bubbles 2
// Card Game
// Castle Ramble
// Chronotron
// Circle Chain
// Circle Path
// Circle Race
// Circular endless runner
// Cirplosion
// CLOCKS - The Game
// Color Hit
// Color Jump
// ColorFill
// Columns
// Concentration
// Crossy Road
// Crush the Castle
// Cube Jump
// CubesOut
// Dash N Blast
// Dashy Panda
// Deflection
// Diamond Digger Saga
// Don't touch the spikes
// Dots
// Down The Mountain
// Drag and Match
// Draw Game
// Drop Wizard
// DROP'd
// Dudeski
// Dungeon Raid
// Educational Game
// Elasticity
// Endless Runner
// Erase Box
// Eskiv
// Farm Heroes Saga
// Filler
// Flappy Bird
// Fling
// Flipping Legend
// Floaty Light
// Fuse Ballz
// GearTaker
// Gem Sweeper
// Globe
// Goat Rider
// Gold Miner
// Grindstone
// GuessNext
// Helicopter
// Hero Emblems
// Hero Slide
// Hexagonal Tiles
// HookPod
// Hop Hop Hop Underwater
// Horizontal Endless Runner
// Hundreds
// Hungry Hero
// Hurry it's Christmas
// InkTd
// Iromeku
// Jet Set Willy
// Jigsaw Game
// Knife Hit
// Knightfall
// Legends of Runeterra
// Lep's World
// Line Rider
// Lumines
// Magick
// MagOrMin
// Mass Attack
// Math Game
// Maze
// Meeblings
// Memdot
// Metro Siberia Underground
// Mike Dangers
// Mikey Hooks
// Nano War
// Nodes
// o:anquan
// One Button Game
// One Tap RPG
// Ononmin
// Pacco
// Perfect Square!
// Perfectionism
// Phyballs
// Pixel Purge
// PixelField
// Planet Revenge
// Plants Vs Zombies
// Platform
// Platform game
// Plus+Plus
// Pocket Snap
// Poker
// Pool
// Pop the Lock
// Pop to Save
// Poux
// Pudi
// Pumpkin Story
// Puppet Bird
// Pyramids of Ra
// qomp
// Quick Switch
// Racing
// Radical
// Rebuild Chile
// Renju
// Rise Above
// Risky Road
// Roguelike
// Roly Poly
// Run Around
// Rush Hour
// SameGame
// SamePhysics
// Save the Totem
// Security
// Serious Scramblers
// Shrink it
// Sling
// Slingy
// Snowflakes
// Sokoban
// Space Checkers
// Space is Key
// Spellfall
// Spinny Gun
// Splitter
// Spring Ninja
// Sproing
// Stabilize!
// Stack
// Stick Hero
// String Avoider
// Stringy
// Sudoku
// Super Mario Bros
// Surfingers
// Survival Horror
// Talesworth Adventure
// Tetris
// The Impossible Line
// The Moops - Combos of Joy
// The Next Arrow
// Threes
// Tic Tac Toe
// Timberman
// Tiny Wings
// Tipsy Tower
// Toony
// Totem Destroyer
// Tower Defense
// Trick Shot
// Tunnelball
// Turn
// Turnellio
// TwinSpin
// vvvvvv
// Warp Shift
// Way of an Idea
// Whack a Creep
// Wheel of Fortune
// Where's my Water
// Wish Upon a Star
// Word Game
// Wordle
// Worms
// Yanga
// Yeah Bunny
// Zhed
// zNumbers