-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathgame.html
317 lines (313 loc) · 8.44 KB
/
game.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="Keywords" content="关键词">
<meta name="Description" content="描述">
<title>Document</title>
<style>
*{
margin:0px;
padding:0px;
}
body{
overflow:hidden;
}
.game{
width:560px;
margin:50px auto;
}
</style>
</head>
<body onkeydown="doKeyDown(event)"><!--身体-->
<div class="game">
<canvas id="canvas" width="560" height="560"></canvas>
<div id="msg"></div>
<input type="button" value="上一关" onclick="NextLevel(-1)">
<input type="button" value="下一关" onclick="NextLevel(1)">
<input type="button" value="重玩本关" onclick="NextLevel(0)">
<input type="button" value="游戏说明" onclick="showHelp()">
</div>
</body>
<script src="js/mapdata100.js"></script>
<script>
var can = document.getElementById("canvas");
var msg = document.getElementById("msg");
var cxt = can.getContext("2d");
var w = 35,h = 35;
var curMap;//当前的地图
var curLevel;//当前等级的地图
var curMan;//初始化小人
var iCurlevel = 0;//关卡数
var moveTimes = 0;//移动了多少次
//预加载所有图片
var oImgs = {
"block" : "images/block.gif",
"wall" : "images/wall.png",
"box" : "images/box.png",
"ball" : "images/ball.png",
"up" : "images/up.png",
"down" : "images/down.png",
"left" : "images/left.png",
"right" : "images/right.png",
}
function imgPreload(srcs,callback){
var count = 0,imgNum = 0,images = {};
for(src in srcs){
imgNum++;
}
for(src in srcs ){
images[src] = new Image();
images[src].onload = function(){
//判断是否所有的图片都预加载完成
if (++count >= imgNum)
{
callback(images);
}
}
images[src].src = srcs[src];
}
}
var block,wall,box,ball,up,down,left,right;
imgPreload(oImgs,function(images){
//console.log(images.block);
block = images.block;
wall = images.wall;
box = images.box;
ball = images.ball;
up = images.up;
down = images.down;
left = images.left;
right = images.right;
init();
});
//初始化游戏
function init(){
//InitMap();
//DrawMap(levels[0]);
initLevel();//初始化对应等级的游戏
showMoveInfo();//初始化对应等级的游戏数据
}
//绘制地板
function InitMap(){
for (var i=0;i<16 ;i++ )
{
for (var j=0;j<16 ;j++ )
{
cxt.drawImage(block,w*j,h*i,w,h);
}
}
}
//小人位置坐标
function Point(x,y){
this.x = x;
this.y = y;
}
var perPosition = new Point(5,5);//小人的初始标值
//绘制每个游戏关卡地图
function DrawMap(level){
for (var i=0;i<level.length ;i++ )
{
for (var j=0;j<level[i].length ;j++ )
{
var pic = block;//初始图片
switch (level[i][j])
{
case 1://绘制墙壁
pic = wall;
break;
case 2://绘制陷进
pic = ball;
break;
case 3://绘制箱子
pic = box;
break;
case 4://绘制小人
pic = curMan;//小人有四个方向 具体显示哪个图片需要和上下左右方位值关联
//获取小人的坐标位置
perPosition.x = i;
perPosition.y = j;
break;
case 5://绘制箱子及陷进位置
pic = box;
break;
}
//每个图片不一样宽 需要在对应地板的中心绘制地图
cxt.drawImage(pic,w*j-(pic.width-w)/2,h*i-(pic.height-h),pic.width,pic.height)
}
}
}
//初始化游戏等级
function initLevel(){
curMap = copyArray(levels[iCurlevel]);//当前移动过的游戏地图
curLevel = levels[iCurlevel];//当前等级的初始地图
curMan = down;//初始化小人
InitMap();//初始化地板
DrawMap(curMap);//绘制出当前等级的地图
}
//下一关
function NextLevel(i){
//iCurlevel当前的地图关数
iCurlevel = iCurlevel + i;
if (iCurlevel<0)
{
iCurlevel = 0;
return;
}
var len = levels.length;
if (iCurlevel > len-1)
{
iCurlevel = len-1;
}
initLevel();//初始当前等级关卡
moveTimes = 0;//游戏关卡移动步数清零
showMoveInfo();//初始化当前关卡数据
}
//小人移动
function go(dir){
var p1,p2;
switch (dir)
{
case "up":
curMan = up;
//获取小人前面的两个坐标位置来进行判断小人是否能够移动
p1 = new Point(perPosition.x-1,perPosition.y);
p2 = new Point(perPosition.x-2,perPosition.y);
break;
case "down":
curMan = down;
p1 = new Point(perPosition.x+1,perPosition.y);
p2 = new Point(perPosition.x+2,perPosition.y);
break;
case "left":
curMan = left;
p1 = new Point(perPosition.x,perPosition.y-1);
p2 = new Point(perPosition.x,perPosition.y-2);
break;
case "right":
curMan = right;
p1 = new Point(perPosition.x,perPosition.y+1);
p2 = new Point(perPosition.x,perPosition.y+2);
break;
}
//若果小人能够移动的话,更新游戏数据,并重绘地图
if (Trygo(p1,p2))
{
moveTimes ++;
showMoveInfo();
}
//重绘地板
InitMap();
//重绘当前更新了数据的地图
DrawMap(curMap);
//若果移动完成了进入下一关
if (checkFinish())
{
//定时器解决渲染地图后再弹窗
setTimeout(()=>{
alert("恭喜过关!!");
NextLevel(1);
},0)
}
}
//判断是否推成功
function checkFinish(){
for (var i=0;i<curMap.length ;i++ )
{
for (var j=0;j<curMap[i].length ;j++ )
{
//当前移动过的地图和初始地图进行比较,若果初始地图上的陷进参数在移动之后不是箱子的话就指代没推成功
if (curLevel[i][j] == 2 && curMap[i][j] != 3 || curLevel[i][j] == 5 && curMap[i][j] != 3)
{
return false;
}
}
}
return true;
}
//判断小人是否能够移动
function Trygo(p1,p2){
if(p1.x<0) return false;//若果超出地图的上边,不通过
if(p1.y<0) return false;//若果超出地图的左边,不通过
if(p1.x>curMap.length) return false;//若果超出地图的下边,不通过
if(p1.y>curMap[0].length) return false;//若果超出地图的右边,不通过
if(curMap[p1.x][p1.y]==1) return false;//若果前面是墙,不通过
if (curMap[p1.x][p1.y]==3 || curMap[p1.x][p1.y]==5)
{//若果小人前面是箱子那就还需要判断箱子前面有没有障碍物(箱子/墙)
if (curMap[p2.x][p2.y]==1 || curMap[p2.x][p2.y]==3)
{
return false;
}
//若果判断不成功小人前面的箱子前进一步
curMap[p2.x][p2.y] = 3;//更改地图对应坐标点的值
//console.log(curMap[p2.x][p2.y]);
}
//若果都没判断成功小人前进一步
curMap[p1.x][p1.y] = 4;//更改地图对应坐标点的值
//若果小人前进了一步,小人原来的位置如何显示
var v = curLevel[perPosition.x][perPosition.y];
if (v!=2)//若果刚开始小人位置不是陷进的话
{
if (v==5)//可能是5 既有箱子又陷进
{
v=2;//若果小人本身就在陷进里面的话移开之后还是显示陷进
}else{
v=0;//小人移开之后之前小人的位置改为地板
}
}
//重置小人位置的地图参数
curMap[perPosition.x][perPosition.y] = v;
//若果判断小人前进了一步,更新坐标值
perPosition = p1;
//若果小动了 返回true 指代能够移动小人
return true;
}
//判断是否推成功
//与键盘上的上下左右键关联
function doKeyDown(event){
switch (event.keyCode)
{
case 37://左键头
case 65:
go("left");
break;
case 38://上键头
case 87:
go("up");
break;
case 39://右箭头
case 68:
go("right");
break;
case 40://下箭头
case 83:
go("down");
break;
}
}
//完善关卡数据及游戏说明
function showMoveInfo(){
msg.innerHTML = "第" + (iCurlevel+1) +"/100关 移动次数: "+ moveTimes;
}
//游戏说明
var showhelp = false;
function showHelp(){
showhelp = !showhelp;
if (showhelp)
{
msg.innerHTML = "用键盘上的上、下、左、右键移动小人,把箱子全部推到小球的位置即可过关。箱子只可向前推,不能往后拉,并且小人一次只能推动一个箱子。";
}else{
showMoveInfo();
}
}
//克隆二维数组
function copyArray(arr){
var b=[];//每次移动更新地图数据都先清空再添加新的地图
for (var i=0;i<arr.length ;i++ )
{
b[i] = arr[i].concat();//链接两个数组
}
return b;
}
</script>
</html>