003_推箱子-事件

1. 事件方法

1.1. 新建事件方法

1.2. 键盘按键值对象

 1.3. 初始化事件方法

 1.4. 给body元素添加按键方法

1.5. 添加事件方法, 可以传递参数

1.6. 下一关卡方法

1.7. 帮助方法

1.8. 初始化事件 

2. 测试事件

2.1. 配置3关数据

2.2. 点击上一关按钮

2.3. 点击下一关和重玩本关按钮

2.4. 点击游戏说明按钮

2.5. 上、下、左、右键和w、a、s、d键

3. 切换人物图片 

3.1. 定义当前人物图片变量

3.2. 给事件传递图片对象 

3.3. 人物行走的方法

3.4. 调用go方法

3.5. 修改绘制人物的图片为当前图片

 3.6. index.html

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title>推箱子</title>

		<style type="text/css">
			* {
				margin: 0;
				padding: 0;
			}
			body {
				background-color: #000;
			}
			#game {
				width: 560px;
				margin: 0 auto;
			}
			#canvas {
				background: #fff;
			}
			#msg {
				color: #fff;
				font-size: 16px;
				height: 40px;
				line-height: 40px;
				background-color: #000;
			}
			#btn {
				height: 50px;
				line-height: 50px;
				background-color: #FFF;
			}
			#btn input {
				height: 30px;
				width: 100px;
				-webkit-appearance: button;
			}
		</style>
	</head>
	<body>
		<div id="game">
			<canvas id="canvas" width="560px" height="560px"></canvas>
			<div id="msg">第1关, 移动次数: 0</div>
			<div id="btn">
				<input type="button" id="previous" value="上一关" />
				<input type="button" id="next" value="下一关" />
				<input type="button" id="replay" value="重玩本关" />
				<input type="button" id="descript" value="游戏说明" />
			</div>
		</div>

		<script type="text/javascript" src="mapdata.js"></script>
		<script type="text/javascript">
			// 加载图片
			function loadImages(){
				var imageSrc = {
					"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"
				};

				var exports = {};
				exports.images = {};
				exports.succeed = false;
				
				exports.init = function(callback){
					var count = 0, imgCount = 0;

					for (let key in imageSrc) {
						imgCount++;
					}

					for(let key in imageSrc){
						this.images[key] = new Image();
						this.images[key].onload = function(){
							count++;

							if(count == imgCount){
								exports.succeed = true;
							}

							callback(count, imgCount);
						};
						this.images[key].src = imageSrc[key];
					}
				};

				return exports;
			}

			// 初始化场景
			function initScene(level, images){
				var block = images["block"];

				for(let i = 0, ilen = level.length; i < ilen; i++){
					for(let j = 0, jlen = level[i].length; j < jlen; j++){
						let data = level[i][j];
						let img = block;

						switch(data){
							case dataItem.wall:
								img = images["wall"];
							break;
							case dataItem.ball:
								img = images["ball"];
							break;
							case dataItem.box:
								img = images["box"];
							break;
							case dataItem.down:
								// img = images["down"];
								img = curManImg; // 人物初始化使用向下的图片, 看起来是面向屏幕外
							break;
						}

						// 画砖块
						ctx.drawImage(block, j * w, i * h, block.width, block.height);
						// 画墙、小球、箱子和人物
						if(level[i][j] != 0){
							ctx.drawImage(img, j * w + (w - img.width) / 2, i * h + (h - img.height), img.width, img.height);
						}
					}
				}
			}

			// 事件方法
			function doEvent(images){
				// 键盘按键值对象
				var keyCode = {
					up: 38, // 键盘上的上键, 人物向上走
					w: 87, // 键盘上的w键, 人物向上走
					down: 40, // 键盘上的下键, 人物向下走
					s: 83, // 键盘上的s键, 人物向下走
					left: 37, // 键盘上的左键, 人物向左走
					a: 65, // 键盘上的a键, 人物向左走
					right: 39, // 键盘上的右键, 人物向右走
					d: 68 // 键盘上的d键, 人物向右走
				};

				var exports = {};
				// 初始化事件方法
				exports.init = function(){
					var previous = document.getElementById('previous');
					var next = document.getElementById('next');
					var replay = document.getElementById('replay');
					var descript = document.getElementById('descript');

					document.body.addEventListener('keyup', this.bodyKeyup, false);

					this.addEventListener(previous, 'click', this.nextLevel, -1);
					this.addEventListener(next, 'click', this.nextLevel, 1);
					this.addEventListener(replay, 'click', this.nextLevel, 0);
					this.addEventListener(descript, 'click', this.descript);
				};

				// 给body元素添加按键方法
				exports.bodyKeyup = function(e){
					switch(e.keyCode){
						case keyCode.up:
						case keyCode.w:
							console.log('人物向上走');
							exports.go('up');
						break;
						case keyCode.down:
						case keyCode.s:
							console.log('人物向下走');
							exports.go('down');
						break;
						case keyCode.left:
						case keyCode.a:
							console.log('人物向左走');
							exports.go('left');
						break;
						case keyCode.right:
						case keyCode.d:
							console.log('人物向右走');
							exports.go('right');

						break;
					}
				};

				// 添加事件方法, 可以传递参数
				exports.addEventListener = function(obj, name, fn, args){
					var addfn = function(){
						fn.call(obj, args);
					};

					obj.addEventListener(name, addfn, false);
				};

				// 下一关卡方法
				exports.nextLevel = function(l){
					curLevel += l;

					if(curLevel < 0) {
						curLevel = 0;
					}

					if(curLevel >= levels.length){
						curLevel = levels.length - 1;
					}

					console.log('当前关卡: ' + curLevel);
				};

				// 帮助方法
				exports.descript = function(){
					alert("用键盘上的上、下、左、右键移动人物, 把箱子全部推到小球的位置即可过关。箱子只可向前推, 并且人物一次只能推动一个箱子。");
				};

				// 人物行走的方法
				exports.go = function(dir){ // 人物图片key、方向
					curManImg = images[dir];

					initScene(levels[0], images);
				};

				return exports;
			}

			(function(global){
				// 获取画布
				global.can = document.getElementById('canvas');
				// 获取画笔(实际上是CanvasRenderingContext2D对象)
				global.ctx = global.can.getContext("2d");

				global.w = 35, global.h = 35; // w矩阵元素的宽度, h矩阵元素的高度

				// 0: 代表砖块; 1: 代表墙壁; 2: 代表小球; 3: 代表箱子; 4: 代表人物
				global.dataItem = {block: 0, wall: 1, ball: 2, box: 3, down: 4};

				global.curLevel = 0; // 当前关卡


				var li = loadImages();
				li.init(function(count, imgCount){
					console.log(count / imgCount * 100 + '%');

					if(li.succeed){
						initScene(levels[0], li.images);
					}
				});
				
				// 初始化事件
				doEvent(li.images).init();

				global.curManImg = li.images['down']; // 当前人物图片, 默认向下的人物图片
			})(window);
		</script>
	</body>
</html>

 3.7. mapdata.js

var levels=[]; // 关卡地图配置数据
levels[0]=[
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0],
[0,0,0,0,0,0,1,2,1,0,0,0,0,0,0,0],
[0,0,0,0,0,0,1,0,1,1,1,1,0,0,0,0],
[0,0,0,0,1,1,1,3,0,3,2,1,0,0,0,0],
[0,0,0,0,1,2,0,3,4,1,1,1,0,0,0,0],
[0,0,0,0,1,1,1,1,3,1,0,0,0,0,0,0],
[0,0,0,0,0,0,0,1,2,1,0,0,0,0,0,0],
[0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]];


levels[1]=[
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,0,0,0,0,0,0,0],
[0,0,0,0,1,4,0,0,1,0,0,0,0,0,0,0],
[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,0],
[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,0,0,1,0,0,0],
[0,0,0,0,0,1,0,0,0,1,1,1,1,0,0,0],
[0,0,0,0,0,1,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]];


levels[2]=[
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,1,0,0,0,0,0],
[0,0,0,0,1,0,0,0,0,0,1,1,1,0,0,0],
[0,0,0,1,1,3,1,1,1,0,0,0,1,0,0,0],
[0,0,0,1,0,4,0,3,0,0,3,0,1,0,0,0],
[0,0,0,1,0,2,2,1,0,3,0,1,1,0,0,0],
[0,0,0,1,1,2,2,1,0,0,0,1,0,0,0,0],
[0,0,0,0,1,1,1,1,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,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]];

3.8. 运行程序

3.8.1. 效果图

3.8.2. 向右移动  

3.8.3. 向上移动

3.8.4. 向左移动 

3.8.5. 向下移动 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值