Talking about Sokoban game, 3D, Game development, HTML5 and Javascript.
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.
Never miss an update! Subscribe, and I will bother you by email only when a new game or full source code comes out.