经典推箱子游戏:训练逻辑思考能力的日本古老游戏解析与玩法指南

日期: 2025-02-23 07:06:29 |浏览: 22|编号: 75588

友情提醒:信息内容由网友发布,本站并不对内容真实性负责,请自鉴内容真实性。

经典推箱子游戏:训练逻辑思考能力的日本古老游戏解析与玩法指南

Classic Push Box是日本的古老游戏,旨在训练玩家的逻辑思维技能。在一个小仓库中,有必要将木箱放在指定的位置。如果您不小心,将不会移动盒子,否则将被阻塞。因此,您需要巧妙地使用有限的空间和渠道,并合理地安排行动顺序。仅通过成功完成任务才能通过定位完成。

盒子推游戏功能如下:

游戏运行并加载相应的地图。一个推盒的工人出现在屏幕上,周围是墙壁,人们可以走路,几个可移动的盒子和盒子,以放置盒子。让玩家控制工人通过按下向上,向下,左右按钮来推动盒子。将框推到目的地时,将出现通行信息,并将显示下一个级别。如果玩家推了错误的方式,他可以撤消运动或再次发挥水平,直到所有级别通过。

盒子游戏的运行接口如上图所示。

该游戏中使用的图片元素的含义如图9-2所示。

01。盒子游戏的想法

让我们首先确定发展困难。工人的操作非常简单,只需向4个方向移动即可。请注意,当工人移动时,盒子也会移动,此效果也需要简单的密钥处理。当盒子到达目的地位置时,将生成游戏通行证事件,这需要逻辑判断。然后仔细考虑一下,所有这些事件都发生在一个地图中。该地图包括盒子的初始化位置,盒子的最后放置以及墙壁屏障。每个级别的地图都必须更改,也必须更改这些位置。因此,每个级别的地图数据是最关键的,它决定了每个级别的不同场景和对象位置。然后,让我们专注于分析下面的地图。

假设您将地图视为网格,每个网格是工人和盒子移动的距离的每个移动的步长,因此问题将得到大大简化。首先,设计一个16×16的二维阵列curmap。根据此框架考虑一下。对于网格的X和Y,可以从二维列表下标转换两个屏幕像素坐标。

每个网格状态值使用值(0)表示通道块,(1)表示墙,(2)表示目标球,(3)表示框盒,(4)代表工人库尔曼,(5)表示位置。目标盒红框。存储在文件中的原始映射中的网格的状态值以相应的整数形式存储。

当玩家控制工人以通过键盘推动盒子时,他需要判断是否对关键说明进行了响应。以下是对工人对所有规则和相应算法进行总结的分析。为了方便描述,可以假定工人的运动趋势方向是正确的,而其他方向原则是一致的。如图9-4所示,P1和P2代表了工人运动趋势方向的前两个网格。

图9-4工人移动趋势(右边)

游戏规则被判断为如下。

(1)确定P1是否超出边界。如果它超出了范围,它将退出规则判断,并且布局不会更改。

if(p1.x< 0) return false;
if(pl.y< 0) return false;
if(pl.y>= curMap.length) return false;
if(p1.x>= curMap[0].length) return false;

(2)前方的P1是一堵墙。

如果工人前面有墙(即,阻止工人的路线)

退出规则判断,也没有对布局进行任何更改;

if(curMap[p1.y][p1.x] == 1
return false; //如果是墙,不能通行

(3)前面的P1是盒子,如图9-5所示。

图9-5工人前面有一个盒子

(3)前面的P1是盒子,如图9-5所示。

在上一种情况下,可以确定工人是否可以根据框前的P1对象移动。在第三种情况下,有必要确定工人是否可以移动。目前有几种可能性。

p1处的盒子是放在目的地的盒子或盒子,P2处的墙壁或盒子是墙壁。

如果工人在P1的前面,将一个盒子或盒子放在目的地,P2是墙壁或盒子,请退出规则判断,并且没有对布局进行更改。

if(curMap[pl.y][p1.x]== 3 curMap[p1.y][p1.x]== 5)
//如果是箱子,继续判断前一格
if(curMap[p2.y][p2.x] == 1  curMap[ p2.y][p2.x]== 3
curMap[p2.y][p2.x]== 5)
return false;
//前一格如果是墙或箱子,则不能前进

p1处的盒子是一个盒子或盒子放在目的地,P2处的通道是通道。

如果工人在P1的前面,并且工人在频道中,则工人可以进入P1网格,并且P2网格状态在框中。修改相关位置网格的状态值。

③PlaceP1是放置在目的地中的盒子或盒子,而P2是目的地。

如果工人在P1的前面,并且工人在目的地,则工人可以输入P1网格,并且P2网格状态在放置的框中。修改相关位置网格的状态值。

//如果是箱子,继续判断前一格
if(curMap[pl.y][p1.x]== 3 curMap[p1.y][p1.x]== 5)if(curMap[p2.y][p2.x]==0 curMap[p2.y][p2.x]== 2) //如果 P2 为通道或者目的地
//记录现在的地图
oldMap = copyArray(curMap);//箱子前进一格
curMap[p2.y][ p2.x]= 3;//如果原始地图是目的地或者是放到目的地的箱子if(CurLevel[p2.y][p2.x] == 2 CurLevel[p2.y][p2.x] == 5)curMap[p2.y][p2.x] = 5;
canReDo = true;//工人前进一格
curMap[ p1.y][p1.x] = 4; //4 代表工人
//处理工人原来位置是显示目的地还是通道平地//获取工人原来位置原始地图信息var v= CurLevel[per position.y][per position.x];if(v== 2 v== 5)[ //如果原来位置是目的地或者放到目的地的箱子curMap[per_position.y][per position.x]=2;
//显示目的地
else
//显示通道平地
curMap[per position.y][per position.x]=0;

根据先前的分析,我们可以设计整个游戏的实现过程。

02。设计盒子游戏的步骤

游戏页面推箱。 html


< head >
推箱子游戏
< meta http - equiv = content - type content = "text/html; charset = utf - 8">
浏览器还不支持哦
< img id ="wall"src ="img/wall.gif"style = "display:none;">< img id= "redbox”src ="img/redbox.gif"style ="display:none;">< img id="pleft"src = "img/left.png"style ="display:none;'< img id="pdown”src ="img/down.pngstyle ="display:none;">< input type ="button"value ="下一关"onclick ="NextLevel(1)"> < input type="button"value ="撤销移动”onclick ="Redo()"> < input type="button"value ="游戏说明”onclick ="DoHelp()">< script type = "text/javascript"src = "mapdata100.js">

游戏页面主要设置图片材料的相应ID。例如,框图片的ID是“框”,目的地图片的ID为“球”,频道图片的ID为“块”,目的地中的框的ID是“ Redbox” “,墙壁的ID为“墙”。角色的向上,向下,左右方向的ID是“ pleft”,“ pright”,“ pup”和“ pdown”。

将5个功能按钮添加到接口中,以实现“上一个级别”,“下一级别”,“撤消移动”,“重播此级别”和“游戏指令”的功能。

设计脚本(PushBox1.js)1。设计游戏地图

整个游戏都在16×16区域,使用二维阵列curmap存储游戏的状态。在其中,平方态值0代表通道,1表示墙,2代表目的地,3表示框,4代表工人,5表示放置在目的地中的盒子。例如,图9-1中所示的盒子推广游戏界面的相应数据如下:

每个级别映射的平方状态值存储在级别数组中,例如级别[0]存储第一个级别,级别[1]存储第二级,依此类推。该游戏存储100个信息,因此数组级别分别放置在“ mapdata100.js”脚本文件中。

第一级如下:

var levels =[];
levels[0]=[
[00,00,000000000000
[00,000000000000001
[0,0,0,0,0,0,00000000001
0.000.0000000000001
[0.0.0.0.0.0.11.0.00.0.0.001
0000000,0,0,0,0.0.01
0000001,0,0,0,01
[0,0,0,01.1.0.0.0.07
[0,0,0,0,1,2,03,4,1,1,10000]
[0.0,0,0,1,1,11,3,1,0000001
[0,0,0,0,0,0,0,1,2,1,0,0,00001
[0,0,0,0,0,0,01,1,1,0000001
[0,0,0,0,0,0,000,0,0,0,00001
[0,0,0,0,0,0,00,0,0,0,0,0,0001
[0,0,00,0,0,0,0,0,0,0,0,0,000]
[0,0,0,0,0,0,0,00,0,0,0000

第二层如下:

[0,0,0,0,1,4,0,0,1,0,0,0,0,0,0,01[0,0,0,0,1,0,3,3,1,0,1,1,1,0,0,0][0,0,0,0,1,0,3,0,1,0,1,2,1,0,0,0][0,0,0,0,1,1,1,0,1,1,1,2,1,0,0,01[0,0,0,0,0,1,1,0,0,0,0,2,1,0,0,0]
[0,0,0,0,0,1,0,0,0,1,00,10,001
[0,0,0,0,0,10,0,0,1,1,110001
0,0,0,0,0,1,1,1,1,1,00,00001
0.0.0.0.0.0.0.0.0.00000001
00.0.0.0.00.0.00000001
0000000000000000
00,0000,0,00,0,00,00001l;

在程序的开头,获取相应的图片,然后将此级别的地图信息级别[ICURLEVEL]复制到当前的游戏地图数据阵列curmap和curlevel。 Curmap最初与Curlevel相同,并且游戏状态在游戏中不断变化。 Curlevel是当前的游戏地图数据,在游戏中保持不变。它主要用于获取框目的地并确定游戏是否结束。

var w= 32;
var h = 32;
var curMap;
var oldMap;
var CurLevel;
var iCurLevel=0;
var curMan;
var UseTime = 0;
var MoveTimes = 0;
//当前游戏地图数据数组,初始与 CurLevel 相同,游戏中改变//保存上次人物移动前地图数据数组
//当前关游戏地图数据,游戏中不变,用来判断游戏是否结束
//当前是第几关//当前小人图片
//当前关用时,单位为秒
//移动次数
var mycanvas = document.getElementById('myCanvas');
var context = mycanvas.getContext(2d');
var block = document.getElementById("block");
var box = document.getElementById("box");
var wall= document.getElementById("wall")
var ball = document.getElementById("ball");
var redbox = document.getElementById("redbox");
var pdown = document.getElementById("pdown");
var pup = document.getElementById("pup”);
var pleft = document.getElementById("pleft");
var pright = document.getElementById("pright");var msg = document.getElementById("msg”);
function init()
initLevel();
showMoveInfo();

initlevel()函数将此级别的地图信息复制到当前的游戏地图数据数组curmap和curlevel,并在屏幕上绘制通道,框,墙,角色和目标信息。

function initLevel()
curMap = copyArray(levels[iCurLevel]);
oldMap = copyArray(curMap);
CurLevel = copyArray(levels[ iCurLevel]);
curMan = pdown;
DrawMap(curMap)
function copyArray(arr)
//画出通道、箱子、墙、人物、目的地信息
//复制二维数组
var b =[];
for(i= 0;i

要保存工人的位置,请使用per_position保存。初始位置在(5,5)坐标处。当然,在绘制游戏时,将根据地图信息修改工人的位置per_position。

function Point(x,y)
this.x =x;
this.y= y;
var per_position = new Point(5,5);

2。绘制整个游戏区域图形

在整个游戏区域中绘制图形是根据地图级别存储图形代码,获取相应的图像,然后在画布上显示。全局变量per_position代表工人的当前位置(x,y)。如果是4(工人值为4),则per_position记录当前位置。为了在游戏中实现屏幕清除效果,每次工人移动时,他都会用频道重新绘制整个游戏区域,这相当于清除原始屏幕,然后绘制新模式。

function InitMap(
//西通道,平铺方块
for(var i= 0;i< CurLevel.length;i++)ffor(var j= 0;j< CurLevel[i].length;j++)(context.drawImage(block,w*i,h*j,w,h);
function DrawMap(level)
//画箱子、墙、人物、目的地
//context.clearRect ( 0 ,0 ,w*16 ,h*16 );//画通道,平铺方块InitMap();//行号
for(i= 0;i< level.length;i++)
//列号for(j= 0;j< level[i].length;j++)var pic=block;
switch(level[il[j])
//通道
case 0:
pic = block;break;case 1:
//墙
pic = wall;
break;case 2:
//目的地
pic = ball;
break;
case 3:
//箱子
pic = box;
break;
case 5:
//放到目的地的箱子
pic =redbox;
break;
case 4:
pic = curMan;
per position.x=j;
//工人
//per_position 记录工人当前位置x,y
per position.y=i;
break;
//绘制图像context.drawImage(pic,w*j- (pic.width - w)/2,h *(i) -(pic.height - h),picwidth,pic.height);

3。关键事件处理

游戏中用户的按键操作由画布对象的按键密钥事件处理。 Keypress密钥处理功能DOKEYDOWN(事件)根据用户的密钥消息计算了工人运动趋势方向中前两个正方形的位置P1和P2。所有位置都称为判断和更新地图的参数。

function DoKeyDown(event)
switch(event.keyCode)
case 37:
//判断用户按键,获取移动方向
//left 向左键
go('left');
msg.innerHTML ="left";
break;
case 38:
//up 向上键
go( 'up') ;
break;
case 39:
//right 向右键
go('right');
break;
case 40:
//down 向下键
go('down');
break;
function go(dir)
var p1,p2;
switch(dir)
case"left"
//按键处理
//分别代表工人移动趋势方向前两个方格//分析按键消息
//向左
//人物图片为向左走的图片pl =new Point(per_position.x- 1,per_position.y);p2 = new Point(per_position.x- 2,per_position.y);
curMan = pleft;
break;//向右case"right"//人物图片为向右走的图片curMan = pright;pl = new Point(per_position.x+1,per_position.y);p2 = new Point(per_position.x +2per_position.y);
break;//向上"up"case//人物图片为向上走的图片curMan=pup;p1 =new Point(per_position.x,per_position.y- 1);p2 = new Point(per_position.x,per_position.y- 2);case
break;"斐督瘁d卵板钞阿蚌豢wn"//向下//人物图片为向下走的图片curMan = pdown;pl = new Point(per_position.x,per_position.y+1);p2 = new Point(per position.x,per position.y+2);break;
if(TryGo(p1,p2))
this.MoveTimes++;showMoveInfo();
DrawMap(curMap);if(CheckFinish())
alert("恭喜过关。");NextLevel(1);
//如果能够移动
//次数加 1
//显示移动次数信息
}
DrawMap(curMap);
if(CheckFinish())
{
alert("恭喜过关。");
NextLevel(1);
}
}

Trygo(P1,P2)方法是最复杂的部分,实现了前面分析的所有规则和相应的算法。

function TryGo(p1,p2)
//判断是否可以移动
//判断是否在游戏区域
if(p1.x<0) return false;
if(pl.y< 0) return false;
if(pl.y>= curMap.length) return false;
if(pl.x>= curMap[0].length) return false;
//如果是墙,不能通行if(curMap[pl.y][p1.x]== 1)return false;if(curMap[pl.y][p1.x]==3 curMap[pl.y][p1.x]==5) //如果是箱子,继续判断前一格
if(curMap[p2.y][p2.x]== 1  curMap[p2.y][p2.x] == 3curMap[p2.y][p2.x] == 5)//前一格如果是墙或箱子,则不能前进return false;if(curMap[p2.y][p2.x]== 0 curMap[p2.y][p2.x]== 2) //如果 P2 为通道或者目的地
oldMap = copyArray(curMap);//记录现在地图//箱子前进一格curMap[p2.y][p2.x] = 3;//如果原始地图是目的地或者是放到目的地的箱子if(CurLevel[p2.y][p2.x] == 2CurLevel[ p2.y][p2.x]== 5)curMap[ p2.y][p2.x]= 5;
canReDo = true;
//工人前进一格
curMap[p1.y][p1.x] = 4;
//以下处理工人原来位置是显示目的地还是通道平地var v= CurLevel[per_position.y][per_position.x];
if(v== 2v== 5)curMap[per_position.y][per_position.x]=2else
curMap[per_position.y][per_position.x]=0;
per_position=pl;
//获取工人原来位置原始地图信息//如果原来是目的地
//显示通道平地
//记录位置
return true;

CheckFinish()函数用于确定此级别是否已完成。如果原始地图目标位置没有放置盒子(也就是说,该位置不是放置在目标curmap [i] [j]!= 5的框,则意味着没有放置盒子,并且游戏尚未过去。否则,游戏将过去。

function CheckFinish(
for(var i= 0;i< curMap.length;i++)
//验证是否过关
//行号
[j]!= 5)
for(var j= 0;j< curMap[ i].length;j++)//如果原始地图的目标位置上没放箱子,则还没结束if(CurLevel[i][j]== 2 && curMap[i]lj]!= 5 CurLevel[i][j]== 5 && curMap[i
//列号
return false;
return true;

4。显示帮助信息

var showHelp = false;
function DoHelp()
showHelp =!showHelp;
if(showHelp)
msg.innerHTML="用键盘的上、下、左右键移动小人,把箱子全部推到小球的位置即可关.箱子只可向前推,不能往后拉,并且小人一次只能推动一个箱子.";
else
showMoveInfo();
function showMoveInfo()
msq.innerHTML="第"+(CurLevel + 1)+"关移动次数:”+ MoveTimes;showHelp = false;

5。撤消功能

在游戏中,OldMap用于在每次移动之前保存地图信息。执行撤消是将旧图还原到当前地图curmap。同时,根据地图中记录的信息查找工人的位置,修改工人的位置信息记录在per_position中,最后重新绘制整个游戏屏幕以还原到以前的状态。

var canReDo = false;
function Redo()if (canReDo == false)
//撤销功能
//不能撤销
return;
//恢复上次地图
curMap = copyArray(oldMap);
for (var i=0;i< curMap.length; i++)
//行号
//列号for (var j= 0;j< curMap[i].length; j++)
if (curMap[i][j]== 4)per_position = new Point(j,i);
//如果此处是工人
this.MoveTimes --
canReDo = false;
showMoveInfo();
DrawMap(curMap);
//次数减 1
//显示移动次数信息
//画箱子、墙、人物、目的地信息

6。选择功能

游戏中有三个级别的选择功能:“上一个级别”,“下一级别”和“重播此级别”。这三个级别选择功能的实现方法是相同的。如果参数I是1,则是“下一级别”;如果参数I为-1,则是“先前的级别”;如果参数I为0,则是“重播此级别”。主要基于级别的iCurlevel,调用initlevel()函数以初始化此级别的映射,并在屏幕上绘制框,墙壁,角色和目标信息。

function NextLevel(i)
//初始化 i
iCurLevel=iCurLevel + i;if(iCurLevel<0)
iCurLevel= 0;
return;
var len = levels.length;if(iCurLevel> len - 1)
iCurLevel = len - 1;
return;
initLevel();UseTime = 0;MoveTimes = 0:showMoveInfo();

在这一点上,完成经典的盒子推游戏。

提醒:请联系我时一定说明是从铂牛网上看到的!