<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<title></title>

<style type="text/css">

#btn{

width: 200px;

height: 300px;

position: absolute;

left: 620px;top: 10px;

}

[type=button]{

width: 70px;

height: 50px;

margin-left: 20px;

margin-top: 20px;

background: lawngreen;

outline: none;

}

#score{

width: 50px;

height: 50px;

margin: 10px auto;

line-height: 50px;

font-size: 40px;

text-align: center;

}

</style>

</head>

<body>

<canvas id="board" width="601" height="601" style="background: #ccc;display: block;"></canvas>

<div id="btn">

<input type="button" name="start" id="start" value="开始" onclick="startBtn()"/>

<input type="button" name="end" id="end" value="暂停" onclick="endBtn()"/>

<br /><br /><br />

<p><center>得分:</center></p>

<div id="score"></div>

</div>

</body>

</html>

<script type="text/javascript">

var board = document.getElementById('board');

var score = document.getElementById('score');

var context = board.getContext('2d');

//主要类

var num = 0;

score.innerHTML = num;//定义一个分数记录器

var snakeArray = [];//定义一个存储每一节身体的数组;

var aSnake = new Snake(20,0,'yellow')//游戏开始一节身体;

snakeArray.push(aSnake)

aSnake.drwaSnake(context);

var aFood = new Food(200,400)//定义一个食物

var aboard = new canvasBoard();//定义一个画布

aboard.drwaCanvas();

aFood.drawFood();//定义一个食物;

//控制方向和前进像素个数

var speedX = 20;

var speedY = 0;

var x = 0;

var y = 0;

var timer = null;

var lock = false;

//游戏开始函数

function startGame(t){

var t = t;

timer = setInterval(function(){

context.clearRect(0,0,board.width,board.height);//清除画布

var aboard = new canvasBoard();//定义一个画布

aboard.drwaCanvas();

aFood.drawFood();//定义一个食物;

var FoodHit = FoodHitCheck(snakeArray[0],aFood);//检测和食物碰撞

if(FoodHit){

clearInterval(timer);

timer = null;

num++;

score.innerHTML = num;//分数;

aFood.x = randPlace();//改变随机位置

aFood.y = randPlace();

aFood.drawFood();

addSnake(snakeArray);

t -=10

if(t <= 100){

t=100;

}

startGame(t);

}

//操作上下左右

document.onkeydown = function(event){

var ev = event || window.event;

Handle(ev);

}

var len = snakeArray.length;//缓存数组的长度

snakeArray[len-1].x = snakeArray[0].x+speedX;

snakeArray[len-1].y = snakeArray[0].y+speedY;

var a = snakeArray.pop();

snakeArray.unshift(a);

for(var i = 0;i < snakeArray.length;i++){

snakeArray[i].drwaSnake(context)

}

//判断和墙壁碰撞

var isHit = HitCheck(snakeArray[0],board);

if(isHit){

clearInterval(timer)

timer = null;

alert('GAMEOVER');

}

//判断和身体相撞;

for(var i = 2;i < snakeArray.length;i++){

var selfHit = FoodHitCheck(snakeArray[0],snakeArray[i]);

if(selfHit){

clearInterval(timer)

timer = null;

alert('GAMEOVER');

}

}

},t)

}

//开始按钮

function startBtn(){

if(!lock){

startGame(200);

lock = true;

}

}

function endBtn(){

clearInterval(timer);

lock = false;

}

//操作类

function Handle(ev){

var evKeyCode = ev.keyCode;

switch(evKeyCode){

case 65:{

if(speedX <= 0){speedX = -20;speedY = 0;}

break;

}

case 87:{

if(speedY <= 0){speedX = 0;speedY = -20;}

break;

}

case 68:{

if(speedX >= 0){speedX = 20;speedY = 0;}

break;

}

case 83:{

if(speedY >= 0){speedX = 0;speedY = 20;}

break;

}

}

}

//加长身体;

function addSnake(snakeArray){

var l = snakeArray.length;

var sX = snakeArray[l-1].x;

var sY = snakeArray[l-1].y;

var snake = new Snake(sX,sY,'red');

snakeArray.push(snake);

}

//检测碰撞墙壁

function HitCheck(snake,board){

if(snake.x < 0 || snake.x > board.width || snake.y < 0 || snake.y > board.height){

return true

}

return false;

}

//检测碰撞食物

function FoodHitCheck(snake,food){

if(!(snake.x < food.x || snake.x > food.x+18 || snake.y < food.y || snake.y > food.y+18)){

return true

}

return false;

}

//随机位置

function randPlace(){

return (parseInt(Math.random()*30))*20;

}

//画布类

function canvasBoard(){

this.x = 20;//间距

this.y = 20;//

this.drwaCanvas = function(){

context.beginPath();

context.strokeStyle = '#ddd';

context.lineWidth = 1;

for(var i = 0;i < board.width/this.x;i++){

context.moveTo(i*this.x+0.5,0);

context.lineTo(i*this.x+0.5,board.height);

}

for(var i = 0;i < board.height/this.y;i++){

context.moveTo(0,i*this.y+0.5);

context.lineTo(board.width,i*this.y+0.5);

}

context.stroke();

}

}

//蛇类

function Snake(x,y,color){

this.x = x;

this.y = y;

this.width = 20;

this.height = 20;

this.color = color;

this.drwaSnake = function(context){

context.beginPath();

context.strokeStyle = "#ccc";

context.strokeRect(this.x,this.y,this.width,this.height);

context.fillStyle = this.color;

context.fillRect(this.x,this.y,this.width,this.height)

context.save();

}

}

//食物类

function Food(x,y){

this.x = x;

this.y = y;

this.w = 20;

this.h = 20;

this.color = 'green';

this.drawFood = function(){

context.beginPath();

context.fillStyle = this.color;

context.fillRect(this.x,this.y,this.w,this.h)

context.save();

}

}

</script>

效果如下图

原理是将每一节身体视为一个对象,将对象放入一个数组里,用定时器每次改变最后一节身体的位置放在最前面,同时改变数组里对象的位置,从而实现向前走的动画

自己用canvas写的贪吃蛇代码的更多相关文章

  1. 以前写的canvas 小游戏 贪吃蛇代码

    效果如图,完成了贪吃蛇的基本的功能 代码地址 :https://github.com/my-new-git-hub/canvasSnake.git 预览地址:https://www.kzc275.to ...

  2. 一步一步用Canvas写一个贪吃蛇

    之前在慕课网看了几集Canvas的视频,一直想着写点东西练练手.感觉贪吃蛇算是比较简单的了,当年大学的时候还写过C语言字符版的,没想到还是遇到了很多问题. 最终效果如下(图太大的话 时间太长 录制gi ...

  3. JavaScript与html5写的贪吃蛇完整代码

    JavaScript与html5写的贪吃蛇完整代码 查看运行效果可访问http://www.codesocang.com/texiao/youxitexiao/2014/0402/7045.html# ...

  4. 原生js写的贪吃蛇网页版游戏特效

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <bo ...

  5. 使用Python写一个贪吃蛇

    参考代码http://blog.csdn.net/leepwang/article/details/7640880 我在程序中加入了分数显示,三种特殊食物,将贪吃蛇的游戏逻辑写到了SnakeGame的 ...

  6. Python写的贪吃蛇游戏例子

    第一次用Python写这种比较实用且好玩的东西,权当练手吧 游戏说明: * P键控制“暂停/开始”* 方向键控制贪吃蛇的方向 源代码如下: 复制代码代码如下: from Tkinter import ...

  7. 如何用Python写一个贪吃蛇AI

    前言 这两天在网上看到一张让人涨姿势的图片,图片中展示的是贪吃蛇游戏, 估计大部分人都玩过.但如果仅仅是贪吃蛇游戏,那么它就没有什么让人涨姿势的地方了. 问题的关键在于,图片中的贪吃蛇真的很贪吃XD, ...

  8. 【C/C++】10分钟教你用C++写一个贪吃蛇附带AI功能(附源代码详解和下载)

    C++编写贪吃蛇小游戏快速入门 刚学完C++.一时兴起,就花几天时间手动做了个贪吃蛇,后来觉得不过瘾,于是又加入了AI功能.希望大家Enjoy It. 效果图示 AI模式演示 imageimage 整 ...

  9. html 贪吃蛇代码

    最近在搞自己的网站,维护的时候准备放个贪吃蛇上去,顶一下原有的页面. 这个贪吃蛇有一点毒.原来设定了100级:100级刚开局就挂了.后来改掉了选项菜单,修复了. 还有什么bug,欢迎点击侧边的QQ按钮 ...

随机推荐

  1. document.compatMode,quirks mode and standards mode

    Document.compatMode Indicates whether the document is rendered in Quirks mode or Standards mode. Syn ...

  2. glViewport函数用法

    一. 其函数原型为glViewport(GLint x,GLint y,GLsizei width,GLsizei height) x,y 以像素为单位,指定了窗口的左下角位置. width,heig ...

  3. ESXi与物理交换机静态链路聚合配置过程中的小陷阱

    作者:陆斌文章来自微信公众号:平台人生 内容简介:ESXi与物理交换机之间配置静态链路聚合时,因为静态链路聚合的特点,在进行down网卡和从虚拟交换机移除网卡的操作时,可能会无法完成故障流量切换,影响 ...

  4. C++使用socket传输图片

    Client: #include <WinSock2.h> #include <Windows.h> #include <stdio.h> #pragma comm ...

  5. python 单元测试_读写Excel及配置文件(八)

    一.安装openpyxl模块 openpyxl模块:是用于解决Excel(WPS等均可使用)中扩展名为xlsx/xlsm/xltx/xltm的文件读写的第三方库.xls文件要使用xlwt .wlrd两 ...

  6. 【hiho1087】Hamiltonian Cycle

    题目大意:给定一个 N 个点的有向图,计数图上哈密顿回路的条数. 题解:哈密顿回路需要经过除了初始位置,每个点恰好一次.如果已知一条哈密顿回路的方向,那么从这条路上任意一个点出发,得到的都是同样的结果 ...

  7. .NET Compiler Platform,一个.NET编译平台

    .NET Compiler Platform,一个.NET编译平台 如何利用C# Roslyn编译器写一个简单的代码提示/错误检查?   OK, 废话不多说,这些天在写C#代码时突然对于IDE提示有了 ...

  8. 'EF.Utility.CS.ttinclude' returned a null or empty string.

    需要安装https://www.microsoft.com/en-us/download/details.aspx?id=40762

  9. vs code 写VUE代码 注释 html出现 //

    装个插件 "Vuter" 解决

  10. 【leetcode】1253. Reconstruct a 2-Row Binary Matrix

    题目如下: Given the following details of a matrix with n columns and 2 rows : The matrix is a binary mat ...