Creation of an HTML5 3D Sokoban level with Babylon.js

Read all posts about "" game

Babylon.js is a 3D engine based on webgl and javascript which allows you to do a lot of interesting stuff thanks to its enormous list of features you can see in the official site.

To show you some basic concepts, I am going to build a 3D Sokoban level like I did some years ago with Unity and some Flash 3D engines, look at these posts:

* Flash 3D Sokoban prototype with Flare3D
* Flash 3D Sokoban prototype with Away3D
* 3D Sokoban prototype with Unity

During the creation of this little level, we are going to learn these concepts:

* Create a scene
* Create an environmental fog
* Create a Box primitive
* Create a Sphere primitive
* Apply a diffuse color to a primitive (that is, paint it the color you want)
* Create a light
* Modify the size of primitives
* Add and control a camera – touch controls are managed by hands.js

This what we are going to do:

You can move the can along fixed arcs with mouse or arrow keys.

And this is the source code, first the HTML part:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
     <head>
          <script src="babylon.1.12.js"></script>
          <script src="hand.js"></script>
          <style>
               html, body, canvas {
                    width: 100%;
                    height: 100%;
                    padding: 0;
                    margin: 0;
                    overflow: hidden;
               }
          </style>
     </head>
     <body>
		<canvas id="gameCanvas"></canvas>
		<script src="game.js"></script>
     </body>
</html>

Then, the fully commented javascript part, which is game.js file:

// array representation of a classic Sokoban level
var level=[[0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0],[0,1,1,1,1,0,0,0,0,0],[0,1,0,0,1,1,1,1,1,0],[0,1,0,2,0,0,3,0,1,0],[0,1,0,3,0,0,2,4,1,0],[0,1,1,1,0,0,1,1,1,0],[0,0,0,1,1,1,1,0,0,0],[0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0]];
// identifying the canvas id
var canvas = document.getElementById("gameCanvas");
// creation of the engine itself
var engine = new BABYLON.Engine(canvas,true);
// attaching a scene to the engine. This is where our game will take place
var scene = new BABYLON.Scene(engine);
// adding a little fog to the scene, to give some kind of "depth" to the scene
scene.fogMode = BABYLON.Scene.FOGMODE_EXP;
// the density is very high, so a low value is recommended
scene.fogDensity = 0.05;
// creation of a camera, the type is "AcrRotate".
// this mean the camera is bound along two arcs, one running from north to south, the other from east to west
// the first argument is the came of the camera instance
// the second argument is the angle along the north-south arc, in radians (3 * Math.PI / 2)
// the 3rd argumentis the angle along the east-west arc, in radians (3*Math.PI/4)
// the 4th argument is the radius of such arcs (20)
// the 5th argument is the camera target (BABYLON.Vector3.Zero()) in this case the origin
// finally, the scene where to attach the camera ("scene")
var camera = new BABYLON.ArcRotateCamera("camera",3 * Math.PI / 2, 3*Math.PI/4, 20, BABYLON.Vector3.Zero(), scene);
// adding touch controls to camera, that's where hand.js come into play
camera.attachControl(canvas, false);
// adding a point light to the scene at posiiton 0, -5, -10
var light = new BABYLON.PointLight("light",new BABYLON.Vector3(0,-5,-10),scene);   
// looping through the array to build the level
for(i=0;i<10;i++){
     for(j=0;j<10;j++){
     	// creation of a box with a side of 1 and adding it to the scene
		var box = BABYLON.Mesh.CreateBox("floorBox", 1, scene);
		// creation of a basic material
		var boxMaterial = new BABYLON.StandardMaterial("material", scene);
		// this is just a random number
		var randomColorOffset = Math.random()*0.1
		// if we are dealing with a target tile...
          if(level[j][i]==2||level[j][i]==5||level[j][i]==6){
          	// ... give the box a red diffuse color 
          	boxMaterial.diffuseColor = new BABYLON.Color3(0.45+randomColorOffset,0,0);     
          }
          else{
          	// otherwise give it a grey diffuse color
			boxMaterial.diffuseColor = new BABYLON.Color3(0.45+randomColorOffset,0.45+randomColorOffset,0.45+randomColorOffset);
          }
          // assigning the box the material
          box.material=boxMaterial;
          // placing the box in the right position 
		box.position = new BABYLON.Vector3(-4.5+j,-4.5+i,0);
	     // scaling the box along z axis, making it look like a tile
          box.scaling.z = 0.25;
          if(level[j][i]==1){   
          	// creation of a wall, not that different, but we don't scale it and we assign it a darker color
               box = BABYLON.Mesh.CreateBox("wallBox", 1, scene);
               boxMaterial.diffuseColor = new BABYLON.Color3(0.25+randomColorOffset,0.25+randomColorOffset,0.25+randomColorOffset);
               box.material=boxMaterial;
               box.position = new BABYLON.Vector3(-4.5+j,-4.5+i,-0.5);
          }
          if(level[j][i]==3){
          	// same thing for a crate, paint it by orange
               box = BABYLON.Mesh.CreateBox("crateBox", 1, scene);
               var crateMaterial = new BABYLON.StandardMaterial("material", scene);
			crateMaterial.diffuseColor = new BABYLON.Color3(0.45+randomColorOffset,0.25+randomColorOffset,0);
			box.material=crateMaterial;
               box.position = new BABYLON.Vector3(-4.5+j,-4.5+i,-0.5);
          }
          if(level[j][i]==4||level[j][i]==6){
          	// we want the player to be a ball, so here is how we create a ball:
          	// the second argument is the detail (10) - the lower the detail, the lighter the rendering
          	// the 3rd argument is the diameter
          	var sphere = BABYLON.Mesh.CreateSphere("sphere", 10, 1, scene);
          	// and we paint it green
               sphere.position = new BABYLON.Vector3(-4.5+j,-4.5+i,-0.5);
          	var sphereMaterial = new BABYLON.StandardMaterial("material", scene);
          	sphereMaterial.diffuseColor = new BABYLON.Color3(0,0.5,0);
          	sphere.material=sphereMaterial;
          }
	}
}
engine.runRenderLoop(function () {
     scene.render();
});

Next time, I am going to add interactivity and textures, meanwhile you can 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