|
|
Line 50: |
Line 50: |
| </style> | | </style> |
| <style> | | <style> |
− | #lay {
| + | *{ |
− | background: #222;
| + | margin:0px; |
| + | padding:0px; |
| } | | } |
− | | + | body{ |
− | h2 {
| + | |
− | color: #666;
| + | |
− | font-family: monospace;
| + | |
− | text-align: center;
| + | |
| } | | } |
− | | + | .game{ |
− | .background {
| + | width:560px; |
− | table-layout: fixed;
| + | margin:5px auto; |
− | border-spacing: 0;
| + | |
− | }
| + | |
− | | + | |
− | .background td {
| + | |
− | padding: 0;
| + | |
− | }
| + | |
− | | + | |
− | .lava, .actor {
| + | |
− | background: #e55;
| + | |
− | }
| + | |
− | | + | |
− | .wall {
| + | |
− | background: #444;
| + | |
− | border: solid 3px #333;
| + | |
− | box-sizing: content-box;
| + | |
− | }
| + | |
− | | + | |
− | .actor {
| + | |
− | position: absolute;
| + | |
− | }
| + | |
− | | + | |
− | .coin {
| + | |
− | background: #e2e838;
| + | |
− | border-radius: 50%;
| + | |
− | }
| + | |
− | | + | |
− | .player {
| + | |
− | background: #335699;
| + | |
− | box-shadow: none;
| + | |
− | }
| + | |
− | | + | |
− | .lost .player {
| + | |
− | background: #a04040;
| + | |
− | }
| + | |
− | | + | |
− | .won .player {
| + | |
− | background: green;
| + | |
− | }
| + | |
− | | + | |
− | .game { | + | |
− | position: relative;
| + | |
− | overflow: hidden;
| + | |
| } | | } |
| </style> | | </style> |
− | </head> | + | <body onkeydown="doKeyDown(event)"><!--身体--> |
− | | + | <div class="game"> |
− | <div id="lay"> | + | <canvas id="canvas" width="560" height="560"></canvas> |
− | | + | <div id="msg"></div> |
− | <h2>A SURPRISE GAME FROM TEAM TIANJIN</h2> | + | <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> |
| | | |
| + | <script type="text/javascript" src="https://2017.igem.org/Team:Tianjin/Resources/JS:gamemap?action=raw&ctype=text/javascript"></script> |
| <script> | | <script> |
− | var LEVELS = [ | + | var can = document.getElementById("canvas"); |
− | [" ", " ", " ", " ", " ", " ", " xxx ", " xx xx xx!xx ", " o o xx x!!!x ", " xx!xx ", " xxxxx xvx ", " xx ", " xx o o x ", " x o x ", " x xxxxx o x ", " x xxxx o x ", " x @ x x xxxxx x ", " xxxxxxxxxxxx xxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxx xxxxxxx xxxxxxxxx ", " x x x x ", " x!!!x x!!!!!x ", " x!!!x x!!!!!x ", " xxxxx xxxxxxx ", " ", " "],
| + | var msg = document.getElementById("msg"); |
− | [" x!!x xxxxxxx x!x ", " x!!x xxxx xxxx x!x ", " x!!xxxxxxxxxx xx xx x!x ", " xx!!!!!!!!!!xx xx xx x!x ", " xxxxxxxxxx!!x x o o o x!x ", " xx!x x o o xx!x ", " x!x x xxxxxxxxxxxxxxx!!x ", " xvx x x x !!!!!!!!!!!!!!xx ", " xx | | | xx xxxxxxxxxxxxxxxxxxxxx ", " xx!!!!!!!!!!!xx v ", " xxxx!!!!!xxxx ", " x x xxxxxxx xxx xxx ", " x x x x x x ", " x x x x ", " x x xx x ", " xx x x x ", " x x o o x x x x ", " xxxxxxx xxx xxx x x x x x x ", " xx xx x x x x xxxxxx x x xxxxxxxxx x ", " xx xx x o x x xx x x x x ", " @ x x x x x x x x x x ", " xxx x x x x x x x xxxxx xxxxxx x ", " x x x x xx o xx x x x o x x x ", "!!!!x x!!!!!!x x!!!!!!xx xx!!!!!!!!xx x!!!!!!!!!! x = x x x ", "!!!!x x!!!!!!x x!!!!!xx xxxxxxxxxx x!!!!!!!xx! xxxxxxxxxxxxx xx o o xx ", "!!!!x x!!!!!!x x!!!!!x o xx!!!!!!xx ! xx xx ", "!!!!x x!!!!!!x x!!!!!x xx!!!!!!xx ! xxxxxxx ", "!!!!x x!!!!!!x x!!!!!xx xxxxxxxxxxxxxx!!!!!!xx ! ", "!!!!x x!!!!!!x x!!!!!!xxxxxxxxx!!!!!!!!!!!!!!!!!!xx ! ", "!!!!x x!!!!!!x x!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!xx ! "], | + | var cxt = can.getContext("2d"); |
− | [" ", " ", " ", " ", " ", " o ", " ", " x ", " x ", " x ", " x ", " xxx ", " x x !!! !!! xxx ", " x x !x! !x! ", " xxx xxx x x ", " x x x oooo x xxx ", " x x x x x!!!x ", " x x xxxxxxxxxxxx xxx ", " xx xx x x x ", " x xxxxxxxxx xxxxxxxx x x ", " x x x x!!!x ", " x x x xxx ", " xx xx x ", " x x= = = = x xxx ", " x x x x!!!x ", " x x = = = =x o xxx xxx ", " xx xx x x!!!x ", " o o x x x x xxv xxx ", " x x x x x!!!x ", " xxx xxx xxx xxx o o x!!!!!!!!!!!!!!x vx ", " x xxx x x xxx x x!!!!!!!!!!!!!!x ", " x x xxxxxxxxxxxxxxxxxxxxxxx ", " xx xx xxx ", " xxx x x x x!!!x xxx ", " x x x xxx x xxx x x ", " x x xxx xxxxxxx xxxxx x ", " x x x x x x ", " x xx x x x x x ", " x x |xxxx| |xxxx| xxx xxx x ", " x xxx o o x x xxx x ", " x xxxxx xx x xxx x!!!x x x ", " x oxxxo x xxx x x x xxx xxx x ", " x xxx xxxxxxxxxxxxx x oo x x oo x x oo xx xx xxx x ", " x @ x x x!!x x!!!!x x!!!!x xx xx x x ", " xxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ", " ", " "], | + | var w = 35,h = 35; |
− | [" xxx x ", " x ", " xxxxx ", " x ", " x xxx ", " o x x x ", " o o oxxx x ", " xxx x ", " ! o ! xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx ", " x x x x x x x x x x x x x x x ", " x= o x x xxx x xxx x xxx x xxx x xxx x xxx x xxxxx ", " x x x x x x x x x x x x x x x ", " ! o ! o xxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxxxx ", " ", " o xxx xx ", " ", " ", " xx ", " xxx xxx ", " ", " o x x ", " xx xx ", " xxx xxx xxx x x ", " ", " || ", " xxxxxxxxxxx ", " x x o xxxxxxxxx o xxxxxxxxx o xx x ", " x x x x x x x || x x ", " x @ xxxxx o xxxxx o xxxxx ", " xxxxxxx xxxxx xx xx xxx ", " x= = =x x xxx ", " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx x!!!!!!!!!!!!!!!!!!!!!xxx!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", " "] | + | var curMap;//当前的地图 |
− | ];
| + | var curLevel;//当前等级的地图 |
− | | + | var curMan;//初始化小人 |
− | function Vector(x, y) {
| + | var iCurlevel = 0;//关卡数 |
− | this.x = x; | + | var moveTimes = 0;//移动了多少次 |
− | this.y = y; | + | //预加载所有图片 |
− | }
| + | var oImgs = { |
− | | + | "block" : "images/block.gif", |
− | Vector.prototype.plus = function(other) {
| + | "wall" : "images/wall.png", |
− | return new Vector(this.x + other.x, this.y + other.y); | + | "box" : "images/box.png", |
− | };
| + | "ball" : "images/ball.png", |
− | | + | "up" : "images/up.png", |
− | Vector.prototype.times = function(scale) {
| + | "down" : "images/down.png", |
− | return new Vector(this.x * scale, this.y * scale); | + | "left" : "images/left.png", |
− | };
| + | "right" : "images/right.png", |
− | | + | |
− | // Note: uppercase words are used that means constructor are values | + | |
− | var actorchars = { | + | |
− | "@": Player,
| + | |
− | "o": Coin,
| + | |
− | "=": Lava,
| + | |
− | "|": Lava,
| + | |
− | "v": Lava
| + | |
− | };
| + | |
− | | + | |
− | function Player(pos) {
| + | |
− | this.pos = pos.plus(new Vector(0, -.5));
| + | |
− | this.size = new Vector(.5, 1);
| + | |
− | this.speed = new Vector(0, 0);
| + | |
− | }
| + | |
− | Player.prototype.type = "player";
| + | |
− | | + | |
− | function Lava(pos, ch) {
| + | |
− | this.pos = pos;
| + | |
− | this.size = new Vector(1, 1);
| + | |
− | if (ch === "=") this.speed = new Vector(2, 0);
| + | |
− | else if (ch === '|') this.speed = new Vector(0, 2);
| + | |
− | else if (ch === 'v') {
| + | |
− | this.speed = new Vector(0, 3); | + | |
− | this.repeatPos = pos;
| + | |
| } | | } |
− | }
| + | function imgPreload(srcs,callback){ |
− | Lava.prototype.type = "Lava";
| + | var count = 0,imgNum = 0,images = {}; |
| | | |
− | function Coin(pos) {
| + | for(src in srcs){ |
− | this.basePos = this.pos = pos;
| + | imgNum++; |
− | this.size = new Vector(.6, .6);
| + | } |
− | // take a look back
| + | for(src in srcs ){ |
− | this.wobble = Math.random() * Math.PI * 2;
| + | images[src] = new Image(); |
− | }
| + | images[src].onload = function(){ |
− | Coin.prototype.type = "coin";
| + | //判断是否所有的图片都预加载完成 |
− | | + | if (++count >= imgNum) |
− | Level.prototype.isFinished = function() {
| + | { |
− | return this.status != null && this.finishDelay < 0;
| + | callback(images); |
− | };
| + | } |
− | | + | |
− | function Level(plan) {
| + | |
− | this.width = plan[0].length;
| + | |
− | this.height = plan.length;
| + | |
− | this.grid = [];
| + | |
− | this.actors = [];
| + | |
− | | + | |
− | for (var y = 0; y < this.height; y++) {
| + | |
− | var line = plan[y], | + | |
− | gridLine = [];
| + | |
− | for (var x = 0; x < this.width; x++) { | + | |
− | var ch = line[x], | + | |
− | fieldType = null;
| + | |
− | var Actor = actorchars[ch]; | + | |
− | if (Actor) this.actors.push(new Actor(new Vector(x, y), ch));
| + | |
− | else if (ch === "x") fieldType = "wall";
| + | |
− | else if (ch === "!") fieldType = "lava";
| + | |
− | else if (ch === "|") fieldType = "lava";
| + | |
− | else if (ch === "=") fieldType = "lava";
| + | |
− | else if (ch === "v") {
| + | |
− | fieldType = "lava"; | + | |
− | console.log(fieldType);
| + | |
| } | | } |
− | gridLine.push(fieldType) | + | images[src].src = srcs[src]; |
| } | | } |
− | this.grid.push(gridLine);
| |
| } | | } |
− | this.player = this.actors.filter(function(actor) { | + | var block,wall,box,ball,up,down,left,right; |
− | return actor.type === "player"
| + | imgPreload(oImgs,function(images){ |
− | })[0];
| + | //console.log(images.block); |
− | this.status = this.finishDelay = null; | + | block = images.block; |
− | }
| + | wall = images.wall; |
− | | + | box = images.box; |
− | function element(name, className) {
| + | ball = images.ball; |
− | var elem = document.createElement(name);
| + | up = images.up; |
− | if (className) elem.className = className;
| + | down = images.down; |
− | return elem;
| + | left = images.left; |
− | }
| + | right = images.right; |
− | | + | init(); |
− | function DOMDisplay(parent, level) { | + | |
− | this.wrap = parent.appendChild(element("div", "game"));
| + | |
− | this.level = level;
| + | |
− | | + | |
− | this.wrap.appendChild(this.drawBackground());
| + | |
− | this.actorLayer = null;
| + | |
− | this.drawFrame();
| + | |
− | }
| + | |
− | | + | |
− | var scale = 15;
| + | |
− | | + | |
− | DOMDisplay.prototype.drawBackground = function() {
| + | |
− | var table = element("table", "background");
| + | |
− | table.style.width = this.level.width * scale + "px";
| + | |
− | table.style.height = this.level.height * scale + "px";
| + | |
− | this.level.grid.forEach(function(row) {
| + | |
− | var rowElement = table.appendChild(element("tr")); | + | |
− | rowElement.style.height = scale + "px"; | + | |
− | row.forEach(function(type) { | + | |
− | rowElement.appendChild(element("td", type));
| + | |
− | }); | + | |
| }); | | }); |
− | return table; | + | //初始化游戏 |
− | };
| + | function init(){ |
− | | + | //InitMap(); |
− | DOMDisplay.prototype.drawActors = function() {
| + | //DrawMap(levels[0]); |
− | var wrap = element("div"); | + | initLevel();//初始化对应等级的游戏 |
− | this.level.actors.forEach(function(actor) {
| + | showMoveInfo();//初始化对应等级的游戏数据 |
− | var rect = wrap.appendChild(element("div", "actor " + actor.type)); | + | } |
− | rect.style.width = actor.size.x * scale + "px"; | + | //绘制地板 |
− | rect.style.height = actor.size.y * scale + "px";
| + | function InitMap(){ |
− | rect.style.left = actor.pos.x * scale + "px";
| + | for (var i=0;i<16 ;i++ ) |
− | rect.style.top = actor.pos.y * scale + "px";
| + | { |
− | });
| + | for (var j=0;j<16 ;j++ ) |
− | return wrap;
| + | { |
− | }
| + | cxt.drawImage(block,w*j,h*i,w,h); |
− | | + | } |
− | DOMDisplay.prototype.drawFrame = function() {
| + | |
− | if (this.actorLayer) this.wrap.removeChild(this.actorLayer);
| + | |
− | this.actorLayer = this.wrap.appendChild(this.drawActors());
| + | |
− | this.wrap.className = "game " + (this.level.status || "");
| + | |
− | this.scrollPlayerIntoView();
| + | |
− | };
| + | |
− | | + | |
− | // clear it later | + | |
− | DOMDisplay.prototype.scrollPlayerIntoView = function() {
| + | |
− | var width = this.wrap.clientWidth; | + | |
− | var height = this.wrap.clientHeight; | + | |
− | var margin = width / 3;
| + | |
− | | + | |
− | // The viewport
| + | |
− | var left = this.wrap.scrollLeft, | + | |
− | right = left + width;
| + | |
− | var top = this.wrap.scrollTop,
| + | |
− | bottom = top + height;
| + | |
− | | + | |
− | var player = this.level.player;
| + | |
− | var center = player.pos.plus(player.size.times(0.5)).times(scale);
| + | |
− | | + | |
− | if (center.x < left + margin) this.wrap.scrollLeft = center.x - margin;
| + | |
− | else if (center.x > right - margin) this.wrap.scrollLeft = center.x + margin - width;
| + | |
− | if (center.y < top + margin) this.wrap.scrollTop = center.y - margin;
| + | |
− | else if (center.y > bottom - margin) this.wrap.scrollTop = center.y + margin - height;
| + | |
− | };
| + | |
− | | + | |
− | DOMDisplay.prototype.clear = function() {
| + | |
− | this.wrap.parentNode.removeChild(this.wrap);
| + | |
− | };
| + | |
− | | + | |
− | Level.prototype.obstacleAt = function(pos, size) {
| + | |
− | var xStart = Math.floor(pos.x);
| + | |
− | var xEnd = Math.ceil(pos.x + size.x);
| + | |
− | var yStart = Math.floor(pos.y);
| + | |
− | var yEnd = Math.ceil(pos.y + size.y);
| + | |
− | | + | |
− | if (xStart < 0 || xEnd > this.width || yStart < 0) return "wall";
| + | |
− | if (yEnd > this.height) return "lava";
| + | |
− | for (var y = yStart; y < yEnd; y++) {
| + | |
− | for (var x = xStart; x < xEnd; x++) { | + | |
− | var fieldType = this.grid[y][x]; | + | |
− | if (fieldType) return fieldType;
| + | |
| } | | } |
| } | | } |
− | };
| + | //小人位置坐标 |
− | | + | function Point(x,y){ |
− | Level.prototype.actorAt = function(actor) {
| + | this.x = x; |
− | for (var i = 0; i < this.actors.length; i++) {
| + | this.y = y; |
− | var other = this.actors[i]; | + | |
− | if (other != actor && actor.pos.x + actor.size.x > other.pos.x && actor.pos.x < other.pos.x + other.size.x && actor.pos.y + actor.size.y > other.pos.y && actor.pos.y < other.pos.y + other.size.y) return other;
| + | |
| } | | } |
− | };
| + | var perPosition = new Point(5,5);//小人的初始标值 |
− | | + | //绘制每个游戏关卡地图 |
− | var maxStep = 0.05; | + | function DrawMap(level){ |
− | | + | for (var i=0;i<level.length ;i++ ) |
− | Level.prototype.animate = function(step, keys) {
| + | { |
− | if (this.status != null) this.finishDelay -= step;
| + | for (var j=0;j<level[i].length ;j++ ) |
− | | + | { |
− | while (step > 0) {
| + | var pic = block;//初始图片 |
− | var thisStep = Math.min(step, maxStep);
| + | switch (level[i][j]) |
− | this.actors.forEach(function(actor) {
| + | { |
− | actor.act(thisStep, this, keys);
| + | case 1://绘制墙壁 |
− | }, this);
| + | pic = wall; |
− | step -= thisStep; | + | 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(){ |
− | Lava.prototype.act = function(step, level) {
| + | curMap = copyArray(levels[iCurlevel]);//当前移动过的游戏地图 |
− | var newPos = this.pos.plus(this.speed.times(step)); | + | curLevel = levels[iCurlevel];//当前等级的初始地图 |
− | if (!level.obstacleAt(newPos, this.size)) this.pos = newPos; | + | curMan = down;//初始化小人 |
− | else if (this.repeatPos) this.pos = this.repeatPos;
| + | InitMap();//初始化地板 |
− | else this.speed = this.speed.times(-1);
| + | DrawMap(curMap);//绘制出当前等级的地图 |
− | };
| + | |
− | | + | |
− | var wobbleSpeed = 8,
| + | |
− | wobbleDist = 0.07;
| + | |
− | | + | |
− | Coin.prototype.act = function(step) {
| + | |
− | this.wobble += step * wobbleSpeed;
| + | |
− | var wobblePos = Math.sin(this.wobble) * wobbleDist;
| + | |
− | this.pos = this.basePos.plus(new Vector(0, wobblePos));
| + | |
− | };
| + | |
− | | + | |
− | var playerXSpeed = 10;
| + | |
− | | + | |
− | Player.prototype.moveX = function(step, level, keys) {
| + | |
− | this.speed.x = 0;
| + | |
− | if (keys.left) this.speed.x -= playerXSpeed;
| + | |
− | if (keys.right) this.speed.x += playerXSpeed;
| + | |
− | | + | |
− | var motion = new Vector(this.speed.x * step, 0);
| + | |
− | var newPos = this.pos.plus(motion);
| + | |
− | var obstacle = level.obstacleAt(newPos, this.size);
| + | |
− | if (obstacle) level.playerTouched(obstacle);
| + | |
− | else this.pos = newPos;
| + | |
− | };
| + | |
− | | + | |
− | var gravity = 30;
| + | |
− | var jumpSpeed = 17;
| + | |
− | | + | |
− | Player.prototype.moveY = function(step, level, keys) {
| + | |
− | this.speed.y += step * gravity;
| + | |
− | var motion = new Vector(0, this.speed.y * step);
| + | |
− | var newPos = this.pos.plus(motion);
| + | |
− | var obstacle = level.obstacleAt(newPos, this.size);
| + | |
− | if (obstacle) {
| + | |
− | level.playerTouched(obstacle); | + | |
− | if (keys.up && this.speed.y > 0) this.speed.y = -jumpSpeed; | + | |
− | else this.speed.y = 0;
| + | |
− | } else {
| + | |
− | this.pos = newPos;
| + | |
| } | | } |
− | };
| + | //下一关 |
− | | + | function NextLevel(i){ |
− | Player.prototype.act = function(step, level, keys) {
| + | //iCurlevel当前的地图关数 |
− | this.moveX(step, level, keys);
| + | iCurlevel = iCurlevel + i; |
− | this.moveY(step, level, keys);
| + | if (iCurlevel<0) |
− | | + | { |
− | var otherActor = level.actorAt(this);
| + | iCurlevel = 0; |
− | if (otherActor) level.playerTouched(otherActor.type, otherActor);
| + | return; |
− | | + | } |
− | // Losing animation
| + | var len = levels.length; |
− | if (level.status == "lost") {
| + | if (iCurlevel > len-1) |
− | this.pos.y += step; | + | { |
− | this.size.y -= step; | + | iCurlevel = len-1; |
| + | } |
| + | initLevel();//初始当前等级关卡 |
| + | moveTimes = 0;//游戏关卡移动步数清零 |
| + | showMoveInfo();//初始化当前关卡数据 |
| } | | } |
− | };
| + | //小人移动 |
− | | + | function go(dir){ |
− | Level.prototype.playerTouched = function(type, actor) {
| + | var p1,p2; |
− | if (type == "lava" && this.status == null) {
| + | switch (dir) |
− | this.status = "lost";
| + | { |
− | this.finishDelay = 1;
| + | case "up": |
− | } else if (type == "coin") {
| + | curMan = up; |
− | this.actors = this.actors.filter(function(other) { | + | //获取小人前面的两个坐标位置来进行判断小人是否能够移动 |
− | return other != actor; | + | p1 = new Point(perPosition.x-1,perPosition.y); |
− | }); | + | p2 = new Point(perPosition.x-2,perPosition.y); |
− | if (!this.actors.some(function(actor) { | + | break; |
− | return actor.type == "coin"; | + | case "down": |
− | })) { | + | curMan = down; |
− | this.status = "won"; | + | p1 = new Point(perPosition.x+1,perPosition.y); |
− | this.finishDelay = 1; | + | 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()) |
| + | { |
| + | alert("恭喜过关!!"); |
| + | NextLevel(1); |
| } | | } |
| } | | } |
− | };
| + | //判断是否推成功 |
− | | + | function checkFinish(){ |
− | var arrowCodes = {
| + | for (var i=0;i<curMap.length ;i++ ) |
− | 37: "left", | + | { |
− | 38: "up", | + | for (var j=0;j<curMap[i].length ;j++ ) |
− | 39: "right"
| + | { |
− | };
| + | //当前移动过的地图和初始地图进行比较,若果初始地图上的陷进参数在移动之后不是箱子的话就指代没推成功 |
− | | + | if (curLevel[i][j] == 2 && curMap[i][j] != 3 || curLevel[i][j] == 5 && curMap[i][j] != 3) |
− | function trackKeys(codes) { | + | { |
− | var pressed = Object.create(null);
| + | return false; |
− | | + | } |
− | function handler(event) {
| + | } |
− | if (codes.hasOwnProperty(event.keyCode)) { | + | |
− | var down = event.type == "keydown"; | + | |
− | pressed[codes[event.keyCode]] = down; | + | |
− | event.preventDefault(); | + | |
| } | | } |
| + | return true; |
| } | | } |
− | addEventListener("keydown", handler); | + | //判断小人是否能够移动 |
− | addEventListener("keyup", handler); | + | function Trygo(p1,p2){ |
− | return pressed;
| + | 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://左键头 |
| + | go("left"); |
| + | break; |
| + | case 38://上键头 |
| + | go("up"); |
| + | break; |
| + | case 39://右箭头 |
| + | go("right"); |
| + | break; |
| + | case 40://下箭头 |
| + | go("down"); |
| + | break; |
| + | } |
| | | |
− | function runAnimation(frameFunc) { | + | } |
− | var lastTime = null; | + | //完善关卡数据及游戏说明 |
− | | + | function showMoveInfo(){ |
− | function frame(time) { | + | msg.innerHTML = "第" + (iCurlevel+1) +"关 移动次数: "+ moveTimes; |
− | var stop = false; | + | } |
− | if (lastTime != null) { | + | //游戏说明 |
− | var timeStep = Math.min(time - lastTime, 100) / 1000; | + | var showhelp = false; |
− | stop = frameFunc(timeStep) === false; | + | function showHelp(){ |
| + | showhelp = !showhelp; |
| + | if (showhelp) |
| + | { |
| + | msg.innerHTML = "用键盘上的上、下、左、右键移动小人,把箱子全部推到小球的位置即可过关。箱子只可向前推,不能往后拉,并且小人一次只能推动一个箱子。"; |
| + | }else{ |
| + | showMoveInfo(); |
| } | | } |
− | lastTime = time;
| |
− | if (!stop) requestAnimationFrame(frame);
| |
| } | | } |
− | requestAnimationFrame(frame);
| |
− | }
| |
| | | |
− | var arrows = trackKeys(arrowCodes);
| + | //克隆二维数组 |
− | | + | function copyArray(arr){ |
− | function runLevel(level, Display, andThen) { | + | var b=[];//每次移动更新地图数据都先清空再添加新的地图 |
− | var display = new Display(document.body, level);
| + | for (var i=0;i<arr.length ;i++ ) |
− | runAnimation(function(step) {
| + | { |
− | level.animate(step, arrows); | + | b[i] = arr[i].concat();//链接两个数组 |
− | display.drawFrame(step);
| + | |
− | if (level.isFinished()) { | + | |
− | display.clear(); | + | |
− | if (andThen) andThen(level.status);
| + | |
− | return false;
| + | |
| } | | } |
− | });
| + | return b; |
− | }
| + | |
− | | + | |
− | function runGame(plans, Display) {
| + | |
− | function startLevel(n) {
| + | |
− | runLevel(new Level(plans[n]), Display, function(status) { | + | |
− | if (status == "lost") startLevel(n);
| + | |
− | else if (n < plans.length - 1) startLevel(n + 1);
| + | |
− | else alert("You win!");
| + | |
− | });
| + | |
| } | | } |
− | startLevel(0);
| + | </script> |
− | }
| + | |
− | | + | |
− | runGame(LEVELS, DOMDisplay); </script>
| + | |
− | | + | |
| | | |
| <div style="text-align:center;clear:both"> | | <div style="text-align:center;clear:both"> |
− | <script src="/gg_bd_ad_720x90.js" type="text/javascript"></script>
| |
− | <script src="/follow.js" type="text/javascript"></script>
| |
− | </div>
| |
| </div> | | </div> |
| + | </body> |
| | | |
| | | |
| </html> | | </html> |