<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> <style type="text/css"> * { margin: 0; padding: 0; } #myCanvas { background-color: burlywood; } </style> </head> <body> <input type="button" name="btn" id="btn" value="开始" /><br /> <canvas id="myCanvas" width="1000" height="600"></canvas> </body> <script type="text/javascript"> var canvas = document.getElementById("myCanvas"); var pen = canvas.getContext("2d"); var btn = document.getElementById("btn"); var sankeLength = 5; var timer = null; btn.onclick = function() { function Snake() { this.x = -40; this.y = 40; this.w = 40; this.h = 40; this.color = "gray"; this.speed = 40; // 方向 this.left = false; this.top = false; // 默认往右 this.right = true; this.bottom = false; // 用于装蛇的每个矩形块的信息(包括头部的) this.bodys = []; } //snake相关的方法 Snake.prototype.drawSnake = function() { for(var i = 0; i < this.bodys.length; i++) { var snakeRect = this.bodys[i]; pen.beginPath(); if(i == this.bodys.length - 1) { //找出蛇身颜色黄色 pen.fillStyle = "yellow"; //其实"蛇头"是在数组中的最后一位 } else { //找出蛇头 pen.fillStyle = this.color; } pen.fillRect(snakeRect.x, snakeRect.y, snakeRect.w, snakeRect.h) pen.closePath(); } } //处理保存蛇身的数组 Snake.prototype.savePath = function() { var posi = { x: this.x, y: this.y, w: this.w, h: this.h } //把所有位置信息保存数组里 if(this.bodys.length == sankeLength) { //控制蛇长 this.bodys.shift(); } this.bodys.push(posi); //改变数组长度 }; //画蛇 //蛇移动 Snake.prototype.move = function() { if(this.top) { this.y -= this.speed; } else if(this.bottom) { this.y += this.speed; } else if(this.left) { this.x -= this.speed; } else if(this.right) { this.x += this.speed; } //自己吃自己 for(var i = 0; i < this.bodys.length; i++) { var tempRect = this.bodys[i]; if(tempRect.x == this.x && tempRect.y == this.y) { clearInterval(timer); alert("game over"); } }; //移动到超出边界的位置 if(this.x < 0 || this.x > canvas.width || this.y < 0 || this.y > canvas.height) { clearInterval(timer); alert("game over"); } }; //上下左右 document.onkeydown = function(ev) { var evObj = ev || window.event; switch(ev.keyCode) { case 37: if(!sna.right) { sna.left = true; sna.top = false; sna.right = false; sna.bottom = false; } break; case 38: if(!sna.bottom) { sna.left = false; sna.top = true; sna.right = false; sna.bottom = false; } break; case 39: if(!sna.left) { sna.left = false; sna.top = false; sna.bottom = false; sna.right = true; } break; case 40: if(!sna.top) { sna.left = false; sna.top = false; sna.bottom = true; sna.right = false; } break; default: break; } }; var sna = new Snake(); //食物food function Food() { this.x = 0; this.y = 0; this.w = 40; this.h = 40; this.color = "red"; } //在A类的方法中使用B类的属性 //1 声明全局变量接受 //2 将b作为形参传给 a的方法中 //3 在A方法之前声明一个A类的对象 //Food相关方法 Food.prototype.drawFood = function() { pen.beginPath(); pen.fillStyle = this.color; pen.fillRect(this.x, this.y, this.w, this.h); pen.closePath(); }; function rand(max, min) { return parseInt(Math.random() * (max + 1 - min) + min); } //给食物设置位置 Food.prototype.setFoodPosition = function() { //随机位置 this.x = rand(0, (canvas.width - this.w) / 40) * 40; console.log(this.x); this.y = rand(0, (canvas.height - this.h) / 40) * 40; console.log(this.y); for(var i = 0; i < sna.bodys.length; i++) { var tempRect = sna.bodys[i]; //当食物出现在蛇身上 if(tempRect.x == this.x && tempRect == this.y) { break; } } // this.setFoodPosition(); }; var food = new Food(); food.setFoodPosition(); //验证 timer = setInterval(function() { pen.clearRect(0, 0, canvas.width, canvas.height); sna.move(); sna.savePath(); sna.drawSnake(); // food.drawFood(); var result = checkCrash(sna, food); if(result) { food.setFoodPosition(); sankeLength++; } }, 300) //公共方法 //矩形碰撞检测 //这个方法的使用前提:两个对象必须有x,y,w,h属性 function checkCrash(obj1, obj2) { //求临界值 var disX = obj1.w / 2 + obj2.w / 2; var disY = obj1.h / 2 + obj2.h / 2; //计算两个中心点的距离 var centerX = Math.abs( (obj2.x + obj2.w / 2) - (obj1.x + obj1.w / 2) ); var centerY = Math.abs( (obj2.y + obj2.h / 2) - (obj1.y + obj1.h / 2) ); if(centerX < disX && centerY < disY) { return true; } else { return false; } }; } </script> </html>