js 贪吃蛇
不管是写法 还是逻辑结构上 都有待提高 希望园子里的高手拍砖 提意见
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head> <title>Untitled Page</title> <style> .snake_table { border:1px solid black; } .snake_table td { width:10px; height:10px; } .snake_table_over { background:black; } .snake_table_over td { width:10px; height:10px; } .snake_tdSelect { background:black; } .snake_tdFood { background:blue; } </style> <script> function FixFunc(_this, func) { if (arguments.length > 2) { var f = function () { func.apply(_this, Array.prototype.slice.call(arguments, 2)); } } else { var f = function () { return func.apply(_this); } } return f; } var Snake = {}; Snake.Subject = function (user) { this.Center = user; } Snake.Subject.prototype = { Center: null, Channel: [{ x: 9, y: 9 }, { x: 9, y: 10 }, { x: 9, y: 11}], speed: 50, length: 3, fix: "right", lastfix: null } Snake.Control = function () { } Snake.Control.prototype = { KeyBoard: function (evt) { if (window.event) { evt = window.event; } var keycode = evt.keyCode || evt.charCode; Snake.Game.ChangeFix(keycode); } } Snake.Map = function () { } Snake.Map.prototype = { x: 20, y: 20, element: null, config: { subClass: "snake_tdSelect", foodClass: "snake_tdFood" }, Build: function () { var t = []; t.push("<table class='snake_table'>"); for (var i = 1; i <= this.x; i++) { t.push("<tr>"); for (var j = 1; j <= this.y; j++) { t.push("<td></td>"); } t.push("</tr>"); } t.push("</table>"); if (document.getElementById("snake_div")) { // document.getElementById("snake_div").innerHTML = t.join(""); this.element = document.getElementById("snake_div").firstChild; } else { alert("没有找到指定容器"); } }, BuildFrom: function () { }, //暂时搁置 FindCell: function (x, y) { return this.element.rows[x].cells[y]; }, //找到某行某列的cell SelectCell: function (x, y) { var el = this.FindCell(x, y); el.className = this.config.subClass; }, UnSelectCell: function (x, y) { var el = this.FindCell(x, y); el.className = ""; }, FoodCell: function (x, y) { var el = this.FindCell(x, y); el.className = this.config.foodClass; }, UnFoodCell: function (x, y) { var el = this.FindCell(x, y); el.className = ""; } } Snake.Game = { element: null, hasBorder: false, map: null, control: null, subject: null, LxObj: null, hasNew: false, keytime: 0, score: 0, config: { subClass: "snake_tdSelect", foodClass: "snake_tdFood", GameOver: "snake_table_over" }, food: { x: 0, y: 0 }, Init: function () { //初始化对象 this.map = new Snake.Map(this); this.control = new Snake.Control(this); this.subject = new Snake.Subject(this); document.onkeydown = this.control.KeyBoard; //注册键盘事件 this.map.Build(); //创建画布 this.element = this.map.element; //填充element this.InitSnake(); //初始化 subject this.NewFood(); //初始化 食物 this.LxObj = setInterval(FixFunc(this, this.OnTime), this.subject.speed); //开始 }, OnTime: function () { this.Move(); }, InitSnake: function () { var td; for (var i = 0; i < this.subject.Channel.length; i++) { td = this.map.FindCell(this.subject.Channel[i].x, this.subject.Channel[i].y); td.className = this.config.subClass; } td = null; }, Move: function () { var s = this.subject, first = s.Channel.length - 1; var newSubject = { x: s.Channel[first].x, y: s.Channel[first].y }; this.NextPlace(s.fix, newSubject); if (!this.Afoul(newSubject)) return; if (!this.hasNew) { //是否有新的 var lastel = s.Channel.shift(); this.map.UnSelectCell(lastel.x, lastel.y); } else { this.hasNew = false; } s.Channel.push(newSubject); this.InitSnake(); //画snake }, NextPlace: function (fix, cur) { // switch (fix) { case "right": if (!this.hasBorder && cur.y >= (this.map.y - 1)) { cur.y = 0; } else if (cur.y >= (this.map.y - 1)) { this.End(); } else { cur.y = cur.y + 1; } break; case "left": if (!this.hasBorder && cur.y <= 0) { cur.y = this.map.y - 1; } else if (cur.y <= 0) { this.End(); } else { cur.y = cur.y - 1; } break; case "up": if (!this.hasBorder && cur.x <= 0) { cur.x = this.map.x - 1; } else if (cur.x <= 0) { this.End(); } else { cur.x = cur.x - 1; } break; case "down": if (!this.hasBorder && cur.x >= (this.map.x - 1)) { cur.x = 0; } else if (cur.x >= (this.map.x - 1)) { this.End(); } else { cur.x = cur.x + 1; } break; } }, NewFood: function () { //新食物 var x = parseInt(Math.random() * 19); var y = parseInt(Math.random() * 19); for (var i = 0; i < this.subject.Channel.length; i++) { if (x == this.subject.Channel[i].x && y == this.subject.Channel[i].y) { return this.NewFood(); } } this.food = { "x": x, "y": y }; this.map.FoodCell(x, y); //设定className }, Afoul: function (json) { //撞击 this.EatFootd(json); if (this.hasBorder) { //有边界的情况 if ((this.map.x - 1) < json.x || (this.map.y - 1) < json.y || json.x < 0 || json.y < 0) { this.End(); return false; } } var arr = this.subject.Channel; for (var i = 0; i < arr.length; i++) { if (arr[i].x == json.x && arr[i].y == json.y) { this.End(); return false; } } return true; //可以穿墙的情况 }, EatFootd: function (json) { if (this.food.x == json.x && this.food.y == json.y) { this.ScoreTotal(); this.NewFood(); this.hasNew = true; } }, ScoreTotal: function () { this.score += 500 / this.subject.speed; document.getElementById("score_span").innerText = this.score; }, End: function () { clearInterval(this.LxObj); //先结束 //this.element.className = this.config.GameOver; }, ChangeFix: function (code) { ///*Snake.Game*/ var tmpTime = new Date().getTime(); if ((tmpTime - this.keytime) < this.subject.speed) return; this.keytime = tmpTime; this.subject.lastfix = this.subject.fix; switch (code) { case 37: //left if (this.subject.fix == "right" || this.subject.fix == "left") return; this.subject.fix = "left"; break; case 38: //up if (this.subject.fix == "down" || this.subject.fix == "up") return; this.subject.fix = "up"; break; case 39: //right if (this.subject.fix == "left" || this.subject.fix == "right") return; this.subject.fix = "right"; break; case 40: //down if (this.subject.fix == "up" || this.subject.fix == "down") return; this.subject.fix = "down"; break; } } } window.onload = function () { Snake.Game.Init(); } </script> </head> <body> <div id="snake_div"> </div> <div id="score_div"> 得分:<span id="score_span"></span> </div> </body> </html>