Canvas 贪吃蛇游戏
450*450
实现原理
思路分析
- 蛇的移动
- 改变蛇的方向
- 产生苹果
- 吃苹果蛇会增长
- 咬到自己就结束游戏
关键步骤:
1. 准备画布和做动画需要的变量
window.onload = function(){
var cvs = document.getElementById("cvs");
var ctx = cvs.getContext("2d");
function draw(){
// 声明需要的变量
var sceneSize = 30; // 场景大小
var size = 20; // 格子的大小
var snake = [{x:10, y:12}, {x:10, y:13}, {x:10, y:14}]; // 蛇的身体
var direction = 1;// 蛇的方向 0: 左 1: 上 2:右 3:下
var apples = []; // 所有的苹果
var countFrame = 0;
// 清除画布
ctx.clearRect(0, 0, cvs.width, cvs.height);
}
setInterval(draw, 500);
}
2. 绘制场景
var sceneSize = 30; // 场景大小
var size = 20; // 格子的大小
function draw(){
// 清除画布
ctx.clearRect(0, 0, cvs.width, cvs.height);// 绘制场景
drawScene();
drawSnake();
}
// 绘制场景
function drawScene(){
ctx.strokeStyle = "blue";
for(var x = 0; x < sceneSize; x++){
for(var y = 0; y < sceneSize; y++){
ctx.strokeRect(x*size, y*size, size, size);
}
}
}
3. 绘制蛇
// 蛇的身体是由很多的正方形组成的, 考虑蛇的长度是多少个正方形, 每个正方形的宽和高
function drawSnake(){
ctx.fillStyle = "purple";
for (var i = 0; i < snake.length; i++) {
ctx.fillRect(snake[i].x*size, snake[i].y*size, size, size);
}
}
4. 蛇头的移动
// 绘制一帧
function draw(){
// 清除画布
ctx.clearRect(0, 0, cvs.width, cvs.height);
// 绘制场景
drawScene();
// 绘制蛇
drawSnake();
// 每一帧更新数据
update();
}
// 每一帧更新数据
function update(){
snake[0].y--;
}
5. 移动方向控制
// 每一帧更新数据
function update(){
// 移动
move();
}
// 移动
function move(){
switch(direction){
case 0: snake[0].x--; break;
case 1: snake[0].y--; break;
case 2: snake[0].x++; break;
case 3: snake[0].y++; break;
}
}
6. 身体的移动
// 在move方法里
// 移动function move(){
// 蛇的身体的移动
for(var i=snake.length-1; i >= 1; i--){
// 把当前身体移动上一节身体所在的位置
snake[i].x = snake[i-1].x;
snake[i].y = snake[i-1].y;
}
// 蛇头的移动
switch(direction){
case 0: snake[0].x--; break;
case 1: snake[0].y--; break;
case 2: snake[0].x++; break;
case 3: snake[0].y++; break;
}
}
7. 产生苹果
var apples = []; // 所有的苹果
// 绘制苹果
function drawApples(){
ctx.fillStyle = "orange";
for (var i = 0; i < apples.length; i++) {
ctx.fillRect(apples[i].x*size, apples[i].y*size, size, size);
}
}
// 产生苹果
function generateApple(){
var x = parseInt(Math.random()*sceneSize);
var y = parseInt(Math.random()*sceneSize);
apples.push({x:x, y:y});
}
8. 吃苹果
function draw(){
// 清除画布
ctx.clearRect(0, 0, cvs.width, cvs.height);
// 绘制场景
drawScene();
// 绘制苹果
drawApples();
// 绘制蛇
drawSnake();
// 每一帧更新数据
update();
}
// 每一帧更新数据
function update(){
// 移动
move();
if (countFrame % 20 == 0)
generateApple();
countFrame++;
}
// 移动
function move(){
// 蛇的身体的移动
for(var i=snake.length-1 ; i >= 1; i--){
// 把当前身体移动上一节身体所在的位置
snake[i].x = snake[i-1].x;
snake[i].y = snake[i-1].y;
}
// 蛇头的移动
switch(direction){
case 0: snake[0].x--; break;
case 1: snake[0].y--; break;
case 2: snake[0].x++; break;
case 3: snake[0].y++; break;
}
// 吃苹果
for (var i = 0; i < apples.length; i++) {
if (apples[i].x === snake[0].x &&
apples[i].y === snake[0].y) {
apples.splice(i, 1);
}
}
}
9. 身体增长
// 身体增长方法
function grow(){
var body = {
x: snake[snake.length-1].x,
y: snake[snake.length-1].y
};
snake.push(body);
}
// 在move方法里的吃苹果里,调用grow()
for (var i = 0; i < apples.length; i++) {
if (apples[i].x === snake[0].x &&
apples[i].y === snake[0].y) {
// 吃到苹果了
apples.splice(i, 1);
grow();
}
}
10. 穿墙
// 在move方法里做实现穿墙的功能
// 判断蛇头和场景大小的关系, 蛇头到达边缘会返回到当前边缘的另一边
if(snake[0].x >= sceneSize) snake[0].x = 0;
if(snake[0].x < 0) snake[0].x = sceneSize-1;
if(snake[0].y >= sceneSize) snake[0].y = 0;
if(snake[0].y < 0) snake[0].y = sceneSize-1;
11. 蛇头咬到自己 游戏结束
// 咬到自己
for (var i=1; i < snake.length; i++){
if (snake[i].x === snake[0].x &&
snake[i].y === snake[0].y) {
clearInterval(handle);
alert("aaaaaaaaaaaaaa");
}
}
12. 全部源代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style type="text/css">
body{
overflow: hidden;
}
</style>
<script type="text/javascript">
window.onload = function(){
var cvs = document.getElementById("cvs");
var ctx = cvs.getContext("2d");
var sceneSize = 30; // 场景大小
var size = 20; // 格子的大小
var snake = [{x:10, y:12}, {x:10, y:13}, {x:10, y:14}]; // 蛇的身体
var direction = 1;// 蛇的方向 0: 左 1: 上 2:右 3:下
var apples = []; // 所有的苹果
var countFrame = 0;
// 绘制一帧
function draw(){
// 清除画布
ctx.clearRect(0, 0, cvs.width, cvs.height);
// 绘制场景
drawScene();
// 绘制苹果
drawApples();
// 绘制蛇
drawSnake();
// 每一帧更新数据
update();
}
// 每一帧更新数据
function update(){
// 移动
move();
if (countFrame % 20 == 0)
generateApple();
countFrame++;
}
// 移动
function move(){
// 蛇的身体的移动
for(var i=snake.length-1 ; i >= 1; i--){
// 把当前身体移动上一节身体所在的位置
snake[i].x = snake[i-1].x;
snake[i].y = snake[i-1].y;
}
// 蛇头的移动
switch(direction){
case 0: snake[0].x--; break;
case 1: snake[0].y--; break;
case 2: snake[0].x++; break;
case 3: snake[0].y++; break;
}
// 穿墙
if(snake[0].x >= sceneSize) snake[0].x = 0;
if(snake[0].x < 0) snake[0].x = sceneSize-1;
if(snake[0].y >= sceneSize) snake[0].y = 0;
if(snake[0].y < 0) snake[0].y = sceneSize-1;
// 吃苹果
for (var i = 0; i < apples.length; i++) {
if (apples[i].x === snake[0].x &&
apples[i].y === snake[0].y) {
// 吃到苹果了
apples.splice(i, 1);
grow();
}
}
// 咬到自己
for (var i=1; i < snake.length; i++){
if (snake[i].x === snake[0].x &&
snake[i].y === snake[0].y) {
clearInterval(handle);
alert("aaaaaaaaaaaaaa");
}
}
}
// 绘制场景
function drawScene(){
ctx.strokeStyle = "gray";
for(var x = 0; x < sceneSize; x++){
for(var y = 0; y < sceneSize; y++){
ctx.strokeRect(x*size, y*size, size, size);
}
}
}
// 绘制蛇
function drawSnake(){
ctx.fillStyle = "purple";
for (var i = 0; i < snake.length; i++) {
ctx.fillRect(snake[i].x*size, snake[i].y*size, size, size);
}
}
// 绘制苹果
function drawApples(){
ctx.fillStyle = "orange";
for (var i = 0; i < apples.length; i++) {
ctx.fillRect(apples[i].x*size, apples[i].y*size, size, size);
}
}
// 产生苹果
function generateApple(){
var x = parseInt(Math.random()*sceneSize);
var y = parseInt(Math.random()*sceneSize);
apples.push({x:x, y:y});
}
// 身体增长
function grow(){
var body = {
x: snake[snake.length-1].x,
y: snake[snake.length-1].y
};
snake.push(body);
}
generateApple();
generateApple();
generateApple();
var handle = setInterval(draw, 50);
window.onkeydown=function(e){
switch(e.keyCode){
case 37:
if (direction != 2)
direction=0;
break;
case 38: if (direction != 3) direction=1; break;
case 39: if (direction != 0) direction=2; break;
case 40: if (direction != 1) direction=3; break;
}
}
}
</script>
</head>
<body>
<canvas id="cvs" width="800" height="800">您的浏览器不支持Canvas</canvas>
</body>
</html>