search
HomeWeb Front-endH5 Tutorial[html5 game development] Classic Sokoban

Opening words:

lufylegend.js engine has been updated to 1.6 or above, although I have released some tutorials one after another , and also provides some simple game examples, but I have never produced several complete works. In fact, my time is too limited. In the next time, I will use the lufylegend.js engine to develop several games as much as possible. This is a complete work to increase the persuasiveness of this engine. I hope friends who like HTML5 and game development can give me more opinions.

This time, let’s take a look at a classic push box game. I believe everyone knows this game. The push box game originated in Japan and is an extremely logical exercise game. A thinking game, boxes can only be pushed but not pulled. Players must put all the boxes back into place in a limited space, as shown in the picture below.

[html5 game development] Classic Sokoban

figure 1



This is developed by me using the latest version of lufylegend.js engine. If you want to challenge it, you can click on the game link below to see how many levels you can pass.

http://lufylegend.com/demo/box

The game has a total of 6 levels. I added a ranking system to the game. After passing a level, you can upload your own results and compete with others, or you can reply to the article below with your experience of how to pass the level.

Production begins

Okay, enough nonsense, now let’s take a look at how to make this game.

First, first, you need to download the lufylegend.js engine

The following is the lufylegend-1.6.0 release I posted on my blog Post

http://blog.csdn.net/lufy_legend/article/details/8593968

Let’s get into the development step by step.

Second, draw the background and box

Let’s prepare a picture first,


Figure 2

#If we divide the above figure into 5 equal parts, then their serial numbers are 0,1,2,3,4.

We can use the above 5 small pictures to splice any room and the placement of boxes in the room.

For example, the example picture 1 at the beginning of my blog is a screenshot of the first level of the game. To draw this room, we must first know where these pictures should be placed. Prepare an array.


var stage01 = [
[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],
[-1,-1, 1, 1, 1, 1, 1, 1,-1,-1,-1],
[-1,-1, 1, 0, 0, 0, 0, 1, 1,-1,-1],
[-1,-1, 1, 0, 0, 4, 0, 0, 1,-1,-1],
[-1,-1, 1, 4, 4, 0, 4, 4, 1,-1,-1],
[-1,-1, 1, 0, 0, 4, 0, 0, 1,-1,-1],
[-1,-1, 1, 1, 0, 0, 0, 0, 1,-1,-1],
[-1,-1,-1, 1, 1, 1, 1, 1, 1,-1,-1],
[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1]
];

The -1 above means not to place it, and then 0, 1, 4, etc. respectively correspond to the serial numbers in Figure 2.

It is simple to draw the room according to this array. See the function below

function drawFloor(x,y){
	if(list[y][x] < 0)return;
	var bitmap = new LBitmap(bitmapDataList[list[y][x]]);
	bitmap.x = x*STEP;
	bitmap.y = y*STEP;
	boxLayer.addChild(bitmap);
}

This list array is the stage01 array above, and the parameters x and y are respectively is the serial number of the column and row of the array, and STEP is the length of each small picture. To draw a small tile, I actually created an LBitmap object.

About LSprite, LBitmap and other objects are very commonly used objects in the lufylegend.js engine. For their usage, please refer to the official API documentation, or read some of my previous articles to learn more. No need to go into details here.

Of course, at the beginning, there must be a box in the room, and the initial position of the box also needs to be set in advance. We also create an array.

var box01 = [
{x:3,y:3},
{x:4,y:3},
{x:5,y:3},
{x:5,y:5},
{x:6,y:5},
{x:7,y:5}
];

The function for drawing boxes is as follows

function drawBox(){
	var bitmap;
	for(var i=0;i<boxList[stageIndex].length;i++){
		bitmap = new LBitmap(bitmapDataList[2]);
		bitmap.x = boxList[stageIndex][i].x*STEP;
		bitmap.y = boxList[stageIndex][i].y*STEP;
		boxLayer.addChild(bitmap);
		nowBoxList.push(bitmap);
	}
}

Above, I also use the LBitmap object to display these boxes, and the nowBoxList array is used to store these boxes that have been loaded into the game interface. The box object is later used to determine whether the game is passed.

Because the 4 in the stage01 array indicates the position of the box that needs to be restored, when judging whether the game is passed, you only need to judge whether these positions coincide with the positions of all the boxes. Methods as below.

function checkBox(){
	var bitmap,x,y,win=true;
	list = [];
	for(var i=0;i<stageList[stageIndex].length;i++){
		list.push(stageList[stageIndex][i].join(",").split(","));
	}
	
	for(var i=0;i<nowBoxList.length;i++){
		bitmap = nowBoxList[i];
		x = bitmap.x / STEP;
		y = bitmap.y / STEP;
		if(list[y][x] == 4){
			bitmap.bitmapData = bitmapDataList[3];
		}else{
			bitmap.bitmapData = bitmapDataList[2];
			win = false;
		}
		list[y][x] += 10;
	}
	if(win)gameClearShow();
}

I intercepted the code directly from the program, so some new arrays and objects appeared.

stageList储存了所有的关卡信息,stageIndex是当前关卡的序号,stageList[stageIndex]就可以获取当前关卡的信息,bitmapDataList数组储存了图1中小图片的LBitmapData对象,这些暂且不说,关键是下面。

		if(list[y][x] == 4){
			bitmap.bitmapData = bitmapDataList[3];
		}else{
			bitmap.bitmapData = bitmapDataList[2];
			win = false;
		}

函数中循环了所有箱子的位置,如果他们的位置的序号为4,则表示该箱子已经归位,全部归位表示过关,否则游戏继续,返回false。

三,主人公登场,推动箱子。

同样准备一张图片,如下


图3

人物走动动画,当然就需要lufylegend引擎中另一个重要的对象LAnimation,它专门用来顺序播放图片以形成动画,具体用法请参照官方API文档。

下面是主人公的构造器

/**
 * 循环事件 
 * @param data 图片数据
 * @param row 图片分割行数
 * @param col 图片分割列数
 **/
function Character(data,row,col){
	base(this,LSprite,[]);
	var self = this;
	//设定人物动作速度
	self.speed = 2;
	self.speedIndex = 0;
	//设定人物大小
	data.setProperties(0,0,data.image.width/col,data.image.height/row);
	//得到人物图片拆分数组
	var list = LGlobal.pideCoordinate(data.image.width,data.image.height,row,col);
	//设定人物动画
	self.anime = new LAnimation(this,data,list);
	//设定不移动
	self.move = false;
	//在一个移动步长中的移动次数设定
	self.moveIndex = 0;
};

主人公如何推动箱子,看下面的onmove函数

/**
 * 开始移动 
 **/
Character.prototype.onmove = function (){
	var self = this;
	//设定一个移动步长中的移动次数
	var ml_cnt = 4;
	//计算一次移动的长度
	var ml = STEP/ml_cnt;
	//根据移动方向,开始移动
	switch (self.direction){
		case UP:
			self.y -= ml;
			if(box)box.y -= ml;
			break;
		case LEFT:
			self.x -= ml;
			if(box)box.x -= ml;
			break;
		case RIGHT:
			self.x += ml;
			if(box)box.x += ml;
			break;
		case DOWN:
			self.y += ml;
			if(box)box.y += ml;
			break;
	}
	self.moveIndex++;
	//当移动次数等于设定的次数,开始判断是否继续移动
	if(self.moveIndex >= ml_cnt){
		self.moveIndex = 0;
		box = null;
		self.move = false;
		checkBox();
	}
};

可以看到,箱子是不是跟着主人公一起走,关键是要看box这个变量,这个变量的值是在下面的checkRoad函数中设置的。

Character.prototype.checkRoad = function (dir){
	var self = this;
	var tox,toy;
	//开始计算移动目的地的坐标
	switch (dir){
		case UP:
			tox = 0;
			toy = -1;
			break;
		case LEFT:
			tox = -1;
			toy = 0;
			break;
		case RIGHT:
			tox = 1;
			toy = 0;
			break;
		case DOWN:
			tox = 0;
			toy = 1;
			break;
	}
	if(list[self.y/STEP + toy][self.x/STEP + tox]==1)return false;
	if(list[self.y/STEP + toy][self.x/STEP + tox]>4){
		if(list[self.y/STEP + toy*2][self.x/STEP + tox*2]==1 || list[self.y/STEP + toy*2][self.x/STEP + tox*2]>4)return false;
		box = getBox(self.x + tox*STEP,self.y + toy*STEP);
	}
	return true;
};

其实,就是判断一下主人公要走的方向的前方是不是有障碍物,如果障碍物是墙则不可移动,如果是箱子的话,就要看看箱子的后面是不是有障碍物,如果有则不可移动,否则箱子就需要跟着主人公一起移动,将box设置为主人公前方的箱子即可。
上面这个函数,是在人物即将发生移动的时候被调用的,如下。

/**
 * 改变人物方向,并判断是否可移动
 **/
Character.prototype.changeDir = function (dir){
	var self = this;
	if(self.move)return;
	self.direction = dir;
	self.anime.setAction(dir);
	if(!self.checkRoad(dir))return;
	self.move = true;
	steps.text = parseInt(steps.text) + 1;
};

当图1中的方向图标被按下的时候,根据点击的方向,来实现人物的移动。

点击方向图标的方法当然是鼠标事件

ctrlLayer.addEventListener(LMouseEvent.MOUSE_UP,onCtrl);

然后在onCtrl函数中根据点击的位置,来进行相应的移动。

function onCtrl(event){
	var ctrlSize = 60;
	if(event.selfX >= ctrlSize && event.selfX <= ctrlSize*2){
		if(event.selfY >= 0 && event.selfY <= ctrlSize){
			player.changeDir(UP);
		}else if(event.selfY >= ctrlSize*2 && event.selfY <= ctrlSize*3){
			player.changeDir(DOWN);
		}
	}else if(event.selfY >= ctrlSize && event.selfY <= ctrlSize*2){
		if(event.selfX >= 0 && event.selfX <= ctrlSize){
			player.changeDir(LEFT);
		}else if(event.selfX >= ctrlSize*2 && event.selfX <= ctrlSize*3){
			player.changeDir(RIGHT);
		}
	}
}

这样,游戏的主要功能部分,就介绍完了。

四,建一个开始画面

如下。


[html5 game development] Classic Sokoban

图4

使用lufylegend.js引擎做个界面,可以说毫无难度,代码如下。

function GameLogo(){
	base(this,LSprite,[]);
	var self = this;
	
	var logolist = [[1,1,1,1],[1,2,4,1],[1,4,2,1],[1,1,1,1]];
	var bitmap,logoLayer;
	
	logoLayer = new LSprite();
	logoLayer.graphics.drawRect(6,"#FF7F50",[0,0,LGlobal.width,LGlobal.height],true,"#FFDAB9");
	self.addChild(logoLayer);
	
	logoLayer = new LSprite();
	logoLayer.x = 50;
	logoLayer.y = 50;
	for(var i=0;i<logolist.length;i++){
		for(var j=0;j<logolist.length;j++){
			bitmap = new LBitmap(bitmapDataList[logolist[i][j]]);
			bitmap.x = j*STEP;
			bitmap.y = i*STEP;
			logoLayer.addChild(bitmap);
		}
	}
	bitmap = new LBitmap(new LBitmapData(imglist["player"],0,0,STEP,STEP));
	bitmap.x = STEP;
	bitmap.y = 2*STEP;
	logoLayer.addChild(bitmap);
	self.addChild(logoLayer);
	
	labelText = new LTextField();
	labelText.rotate = -20;
	labelText.color = "#4B0082";
	labelText.font = "HG行書体";
	labelText.size = 100;
	labelText.x = 300;
	labelText.y = 50;
	labelText.stroke = true;
	labelText.lineWidth = 4;
	labelText.text = "推";
	self.addChild(labelText);
	
	labelText = new LTextField();
	labelText.color = "#4B0082";
	labelText.font = "HG行書体";
	labelText.size = 100;
	labelText.x = 450;
	labelText.y = 60;
	labelText.stroke = true;
	labelText.lineWidth = 4;
	labelText.text = "箱";
	self.addChild(labelText);
	
	labelText = new LTextField();
	labelText.rotate = 20;
	labelText.color = "#4B0082";
	labelText.font = "HG行書体";
	labelText.size = 100;
	labelText.x = 600;
	labelText.y = 60;
	labelText.stroke = true;
	labelText.lineWidth = 4;
	labelText.text = "子";
	self.addChild(labelText);
	
	labelText = new LTextField();
	labelText.color = "#B22222";
	labelText.font = "HG行書体";
	labelText.size = 40;
	labelText.x = 100;
	labelText.y = 250;
	labelText.stroke = true;
	labelText.lineWidth = 4;
	labelText.text = "Click to Start Game !!";
	self.addChild(labelText);
	
	var social = new Social();
	social.x = 220;
	social.y = 330;
	self.addChild(social);
	
	labelText = new LTextField();
	labelText.font = "HG行書体";
	labelText.size = 14;
	labelText.x = 400;
	labelText.y = 390;
	labelText.text = "- Html5 Game Engine lufylegend.js";
	self.addChild(labelText);
	labelText = new LTextField();
	labelText.color = "#006400";
	labelText.font = "HG行書体";
	labelText.size = 14;
	labelText.x = 400;
	labelText.y = 410;
	labelText.text = "http://www.lufylegend.com/lufylegend";
	self.addChild(labelText);
	
	self.addEventListener(LMouseEvent.MOUSE_UP,menuShow);
};

就是显示几张图片,以及添加一些文字,LTextField对象的使用方法请参考官方API文档。

五,建一个选择画面

如下。


[html5 game development] Classic Sokoban

图5

代码如下。

function GameMenu(){
	base(this,LSprite,[]);
	var self = this;
	
	var menuLayer;
	menuLayer = new LSprite();
	menuLayer.graphics.drawRect(6,"#ADD8E6",[0,0,LGlobal.width,LGlobal.height],true,"#E6E6FA");
	self.addChild(menuLayer);
	
	labelText = new LTextField();
	labelText.color = "#B22222";
	labelText.font = "HG行書体";
	labelText.size = 40;
	labelText.x = 200;
	labelText.y = 30;
	labelText.stroke = true;
	labelText.lineWidth = 4;
	labelText.text = "Please select !!";
	menuLayer.addChild(labelText);
	for(var i=0;i<stageMenu.length;i++){
		self.stageVsMenu(stageMenu[i]);
	}
};
GameMenu.prototype.stageVsMenu = function(obj){
	var self = this;
	
	var menuButton,btn_up;
	if(obj.open){
		btn_up = new LSprite();
		btn_up.graphics.drawRect(2,"#000",[0,0,150,90],true,"#191970");
		labelText = new LTextField();
		labelText.color = "#ffffff";
		labelText.font = "HG行書体";
		labelText.size = 20;
		labelText.x = 40;
		labelText.y = 5;
		btn_up.addChild(labelText)
		labelText.text = "第"+(obj.index+1)+"关";
		
		labelText = new LTextField();
		labelText.color = "#ffffff";
		labelText.font = "HG行書体";
		labelText.size = 12;
		labelText.x = 10;
		labelText.y = 40;
		btn_up.addChild(labelText)
		labelText.text = "step:"+obj.step;
		labelText = new LTextField();
		labelText.color = "#ffffff";
		labelText.font = "HG行書体";
		labelText.size = 12;
		labelText.x = 10;
		labelText.y = 60;
		btn_up.addChild(labelText)
		labelText.text = "times:"+obj.times;
		
		
		var btn_down = new LSprite();
		btn_down.graphics.drawRect(2,"#000",[0,0,150,90],true,"#2F4F4F");
		labelText = new LTextField();
		labelText.color = "#ffffff";
		labelText.font = "HG行書体";
		labelText.size = 20;
		labelText.x = 40;
		labelText.y = 5;
		labelText.text = "第"+(obj.index+1)+"关";
		btn_down.addChild(labelText);
		
		labelText = new LTextField();
		labelText.color = "#ffffff";
		labelText.font = "HG行書体";
		labelText.size = 12;
		labelText.x = 10;
		labelText.y = 40;
		btn_down.addChild(labelText)
		labelText.text = "step:"+obj.step;
		labelText = new LTextField();
		labelText.color = "#ffffff";
		labelText.font = "HG行書体";
		labelText.size = 12;
		labelText.x = 10;
		labelText.y = 60;
		btn_down.addChild(labelText)
		labelText.text = "times:"+obj.times;
		
		menuButton = new LButton(btn_up,btn_down);
		menuButton.obj = obj;
		menuButton.addEventListener(LMouseEvent.MOUSE_UP,function(event,self){
			gameStart(self.obj.index);
		});
	}else{
		btn_up = new LSprite();
		btn_up.graphics.drawRect(2,"#000",[0,0,150,90],true,"#708090");
		labelText = new LTextField();
		labelText.color = "#ffffff";
		labelText.font = "HG行書体";
		labelText.size = 20;
		labelText.x = 40;
		labelText.y = 5;
		btn_up.addChild(labelText)
		labelText.text = "???";
		menuButton = btn_up;
	};
	self.addChild(menuButton);
	menuButton.x = obj.x * 220 + 100; 
	menuButton.y = obj.y * 140 + 130;
}

好了,游戏主要的代码已经都贴出来了。

源码

由于上面的代码比较零碎,而且我也只是挑中心部分说了一下,下面提供完整游戏源代码,想研究一下的朋友可以点击下面的连接下载。

http://lufylegend.com/lufylegend_download/box.rar

注意:该附件只包含本次文章源码,lufylegend.js引擎请到http://lufylegend.com/lufylegend进行下载。


 以上就是[html5游戏开发]经典的推箱子的内容,更多相关内容请关注PHP中文网(www.php.cn)!


Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
H5: New Features and Capabilities for Web DevelopmentH5: New Features and Capabilities for Web DevelopmentApr 29, 2025 am 12:07 AM

H5 brings a number of new functions and capabilities, greatly improving the interactivity and development efficiency of web pages. 1. Semantic tags such as enhance SEO. 2. Multimedia support simplifies audio and video playback through and tags. 3. Canvas drawing provides dynamic graphics drawing tools. 4. Local storage simplifies data storage through localStorage and sessionStorage. 5. The geolocation API facilitates the development of location-based services.

H5: Key Improvements in HTML5H5: Key Improvements in HTML5Apr 28, 2025 am 12:26 AM

HTML5 brings five key improvements: 1. Semantic tags improve code clarity and SEO effects; 2. Multimedia support simplifies video and audio embedding; 3. Form enhancement simplifies verification; 4. Offline and local storage improves user experience; 5. Canvas and graphics functions enhance the visualization of web pages.

HTML5: The Standard and its Impact on Web DevelopmentHTML5: The Standard and its Impact on Web DevelopmentApr 27, 2025 am 12:12 AM

The core features of HTML5 include semantic tags, multimedia support, offline storage and local storage, and form enhancement. 1. Semantic tags such as, etc. to improve code readability and SEO effect. 2. Simplify multimedia embedding with labels. 3. Offline storage and local storage such as ApplicationCache and LocalStorage support network-free operation and data storage. 4. Form enhancement introduces new input types and verification properties to simplify processing and verification.

H5 Code Examples: Practical Applications and TutorialsH5 Code Examples: Practical Applications and TutorialsApr 25, 2025 am 12:10 AM

H5 provides a variety of new features and functions, greatly enhancing the capabilities of front-end development. 1. Multimedia support: embed media through and elements, no plug-ins are required. 2. Canvas: Use elements to dynamically render 2D graphics and animations. 3. Local storage: implement persistent data storage through localStorage and sessionStorage to improve user experience.

The Connection Between H5 and HTML5: Similarities and DifferencesThe Connection Between H5 and HTML5: Similarities and DifferencesApr 24, 2025 am 12:01 AM

H5 and HTML5 are different concepts: HTML5 is a version of HTML, containing new elements and APIs; H5 is a mobile application development framework based on HTML5. HTML5 parses and renders code through the browser, while H5 applications need to run containers and interact with native code through JavaScript.

The Building Blocks of H5 Code: Key Elements and Their PurposeThe Building Blocks of H5 Code: Key Elements and Their PurposeApr 23, 2025 am 12:09 AM

Key elements of HTML5 include,,,,,, etc., which are used to build modern web pages. 1. Define the head content, 2. Used to navigate the link, 3. Represent the content of independent articles, 4. Organize the page content, 5. Display the sidebar content, 6. Define the footer, these elements enhance the structure and functionality of the web page.

HTML5 and H5: Understanding the Common UsageHTML5 and H5: Understanding the Common UsageApr 22, 2025 am 12:01 AM

There is no difference between HTML5 and H5, which is the abbreviation of HTML5. 1.HTML5 is the fifth version of HTML, which enhances the multimedia and interactive functions of web pages. 2.H5 is often used to refer to HTML5-based mobile web pages or applications, and is suitable for various mobile devices.

HTML5: The Building Blocks of the Modern Web (H5)HTML5: The Building Blocks of the Modern Web (H5)Apr 21, 2025 am 12:05 AM

HTML5 is the latest version of the Hypertext Markup Language, standardized by W3C. HTML5 introduces new semantic tags, multimedia support and form enhancements, improving web structure, user experience and SEO effects. HTML5 introduces new semantic tags, such as, ,, etc., to make the web page structure clearer and the SEO effect better. HTML5 supports multimedia elements and no third-party plug-ins are required, improving user experience and loading speed. HTML5 enhances form functions and introduces new input types such as, etc., which improves user experience and form verification efficiency.

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

Powerful PHP integrated development environment

mPDF

mPDF

mPDF is a PHP library that can generate PDF files from UTF-8 encoded HTML. The original author, Ian Back, wrote mPDF to output PDF files "on the fly" from his website and handle different languages. It is slower than original scripts like HTML2FPDF and produces larger files when using Unicode fonts, but supports CSS styles etc. and has a lot of enhancements. Supports almost all languages, including RTL (Arabic and Hebrew) and CJK (Chinese, Japanese and Korean). Supports nested block-level elements (such as P, DIV),

SecLists

SecLists

SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Integrate Eclipse with SAP NetWeaver application server.

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

This project is in the process of being migrated to osdn.net/projects/mingw, you can continue to follow us there. MinGW: A native Windows port of the GNU Compiler Collection (GCC), freely distributable import libraries and header files for building native Windows applications; includes extensions to the MSVC runtime to support C99 functionality. All MinGW software can run on 64-bit Windows platforms.