canvas加面向对象方式的贪吃蛇 2016-08-25

这个小游戏可以增加对面向对象的理解,可以加强js逻辑能力,总之认真自己敲一两遍收获还是不少啊!!适合刚学canvas的同学练习!!

废话不多说,直接来讲思路和代码.

-----------------------------------------------------------------------------------------------------------------

开发思路:首先要有蛇吃的食物,就是一个个canvas随机画出的方块,然后是蛇,蛇也是方块组成。于是我们构造一个函数,功能是产生食物和蛇的原材料,和处理一些关于方块的函数(后面会上代码)。其次是,开始游戏的函数,当页面加载完成后开始游戏,然后是当游戏开始是时候,我们要初始化一个画布和随机产生食物,接着是关于画蛇和控制蛇的构造函数。最后是当触发游戏结束的条件时候的游戏结束函数。首先搭建一个整体思路然后再细细入手,博主是这样写的,大神别笑话.

初始代码如下:

------

<script>
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext('2d');
var gridWidth=10;
var foods=new Array(),snakes=new Array();//放食物和蛇的数组
//原料初始化
function Node(x,y,w){ } //生成一个画布和食物
function Farm(){ }
//画蛇
function Snake(x,y,len,speed){
}
}
//开始游戏
function gameStart(){
}
gameStart();
//结束游戏
function gameover(){}
<script>

------

接着,就是一个一个思考:首先是Node函数里面设置一些基本生成方块方法,由于,蛇和食物并不同,所以分成单独的2个函数,并且,蛇运动的时候要去掉尾部的方块,所以这里还要加一个去掉clear方法:

---

          var t=this;
t.x=x;
t.y=y;
t.w=w;
//食物
t.foodInit=function(){
ctx.fillStyle='red';
ctx.fillRect(x,y,w,w);
}
//蛇
t.snakeInit=function(){
ctx.fillStyle='black';
ctx.strokeStyle='white';
ctx.fillRect(x,y,w,w);
ctx.strokeRect(x,y,w,w);
}
//清除蛇尾
t.clear=function(){
ctx.fillStyle='white';
ctx.strokeStyle='white';
ctx.fillRect(x,y,w,w);
ctx.strokeRect(x,y,w,w);
}

----

接着是Fram函数里,要设置一个画布环境并且要随机产生食物:

----

     function Farm(){
var t=this;
ctx.fillStyle='white';
ctx.fillRect(0,0,canvas.width,canvas.height);
//随机生成食物
t.addfood=function(){
var x=parseInt(canvas.width/gridWidth*Math.random())*gridWidth;
var y=parseInt(canvas.height/gridWidth*Math.random())*gridWidth;
var food=new Node(x,y,gridWidth);
food.foodInit();
foods.push(food);
}
}

----

写到这里,当你启动gameStar函数时候会看到一些食物随机产生在画布上,颜色改一下,会有不同的画布环境:

---

     //开始游戏
function gameStart(){
var farm=new Farm();
setInterval(farm.addfood,2000);
}
gameStart();

---

现在到了最难的地方就是处理蛇,首先是画一条蛇并启动它和键盘事件取如下:

---

          function Snake(x,y,len,speed){
var t=this;
t.x=x;
t.y=y;
t.dir='R';
//t.len=len;
var nx=x;ny=y;
t.init=function(){
for (var i = 0; i <len; i++) {
var tempNode=new Node(nx,ny,gridWidth);
tempNode.snakeInit();
nx-=gridWidth=10;
snakes.push(tempNode);
};
//setInterval(t.move,speed)
} //取得键盘方向
document.onkeydown=function(e){
var code=e.keyCode;
switch(code){
case 37:
t.dir='L';
break;
case 38:
t.dir='U';
break;
case 39:
t.dir='R';
break;
case 40:
t.dir='D';
break;
}
}
}

---

这主要是让蛇动的move方法:

         //移动蛇
t.move=function(){
var newHead;
//初始化蛇头的位置从而确定方向
if(snakes[0].x+snakes[0].w>=canvas.width||snakes[0].x-snakes[0].w<0||snakes[0].y-snakes[0].w<0||snakes[0].y+snakes[0].w>canvas.height)
{
gameover();
}
else{
if(t.dir=='R'){
newHead=new Node(snakes[0].x+gridWidth,snakes[0].y,gridWidth);
}else if(t.dir=='L'){
newHead=new Node(snakes[0].x-gridWidth,snakes[0].y,gridWidth);
}else if(t.dir=='D'){
newHead=new Node(snakes[0].x,snakes[0].y+gridWidth,gridWidth);
}else if(t.dir=='U'){
newHead=new Node(snakes[0].x,snakes[0].y-gridWidth,gridWidth);
}
}
//画蛇头
newHead.snakeInit();
//追加到数组中(长度会自动加)
snakes.unshift(newHead);
//清除尾部
snakes[snakes.length-1].clear();
//并从数组中移除(长度会自动减)
snakes.pop(); //判断食物是否和蛇头相撞
for (var i = 0; i < foods.length; i++) {
if(foods[i].equal(snakes[0])){
//给蛇增加长度
t.addFood();
clearInterval(snake_interval);
}
} //给蛇增加长度(在尾巴加)
t.addFood=function(){
var tail1=snakes[snakes.length-1];
var tail2=snakes[snakes.length-2];
var addNode;
if(tail1.x==tail2.x){
if(tail1.y>=tail2.y)
addNode=new Node(tail1.x,tail1.y+gridWidth,gridWidth);
else
addNode=new Node(tail1.x,tail1.y-gridWidth,gridWidth);
}
else{
if(tail1.x>=tail2.x)
addNode=new Node(tail1.x+gridWidth,tail1.y,gridWidth);
else
addNode=new Node(tail1.x-gridWidth,tail1.y,gridWidth);
} //数组加入尾部
snakes.push(addNode);
addNode.snakeInit();
}//addFood函数
}//move函数结束

---

到现在就是一点 其他条件设置,比喻不能反方向穿,不能穿自己。设置游戏结束后的步骤,现在可以先自己 思考下怎么写。

---

所有的代码在这里,有不足的可以提出一起进步:

         <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>小游戏之贪吃蛇2次重写(面向对象)</title>
<style>
#canvas{border: 1px solid red;}
</style>
</head>
<body>
<canvas id='canvas' width='' height=''></canvas>
<script>
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext('2d');
var gridWidth=;
var foods=new Array(),snakes=new Array();//放食物和蛇的数组
//原料初始化
function Node(x,y,w){
var t=this;
t.x=x;
t.y=y;
t.w=w;
//食物
t.foodInit=function(){
ctx.fillStyle='red';
ctx.fillRect(x,y,w,w);
}
//蛇
t.snakeInit=function(){
ctx.fillStyle='black';
ctx.strokeStyle='white';
ctx.fillRect(x,y,w,w);
ctx.strokeRect(x,y,w,w);
}
//清除蛇尾
t.clear=function(){
ctx.fillStyle='white';
ctx.strokeStyle='white';
ctx.fillRect(x,y,w,w);
ctx.strokeRect(x,y,w,w);
}
//判断是否重合
t.equal=function(node){
if(this.x==node.x&&this.y==node.y) {
return true;
}else{
return false;
}
}
} //生成一个画布和食物
function Farm(){
var t=this;
ctx.fillStyle='white';
ctx.fillRect(,,canvas.width,canvas.height);
//随机生成食物
t.addfood=function(){
var x=parseInt(canvas.width/gridWidth*Math.random())*gridWidth;
var y=parseInt(canvas.height/gridWidth*Math.random())*gridWidth;
var food=new Node(x,y,gridWidth);
food.foodInit();
foods.push(food);
}
}
//画蛇
function Snake(x,y,len,speed){
var t=this;
t.x=x;
t.y=y;
t.dir='R';
//t.len=len;
var nx=x;ny=y;
t.init=function(){
for (var i = ; i <len; i++) {
var tempNode=new Node(nx,ny,gridWidth);
tempNode.snakeInit();
nx-=gridWidth;
snakes.push(tempNode);
};
snake_interval=setInterval(t.move,speed)
} //取得键盘方向
document.onkeydown=function(e){
var code=e.keyCode;
t.odir=t.dir;
switch(code){
case :
t.dir='L';
break;
case :
t.dir='U';
break;
case :
t.dir='R';
break;
case :
t.dir='D';
break;
}
}
//移动蛇
t.move=function(){
var newHead;
//初始化蛇头的位置从而确定方向
if(snakes[].x+snakes[].w>=canvas.width||snakes[].x-snakes[].w<||snakes[].y-snakes[].w<||snakes[].y+snakes[].w>canvas.height)
{
gameover();
}
else{
if(t.dir=='R'){
newHead=new Node(snakes[].x+gridWidth,snakes[].y,gridWidth);
}else if(t.dir=='L'){
newHead=new Node(snakes[].x-gridWidth,snakes[].y,gridWidth);
}else if(t.dir=='D'){
newHead=new Node(snakes[].x,snakes[].y+gridWidth,gridWidth);
}else if(t.dir=='U'){
newHead=new Node(snakes[].x,snakes[].y-gridWidth,gridWidth);
}
} //禁止反向跑
if(newHead.x==snakes[1].x&&newHead.y==snakes[1].y){
t.dir=t.odir;
return;
} //画蛇头
newHead.snakeInit();
//追加到数组中(长度会自动加)
snakes.unshift(newHead);
//清除尾部
snakes[snakes.length-].clear();
//并从数组中移除(长度会自动减)
snakes.pop(); //判断食物是否和蛇头相撞
for (var i = ; i < foods.length; i++) {
if(foods[i].equal(snakes[])){
//给蛇增加长度
t.addFood();
clearInterval(snake_interval);
speed=speed<?speed:speed-;
snake_interval=setInterval(t.move,speed);
}
} //判断是否与自己相撞
for (var i = ; i < snakes.length; i++) {
if(snakes[i].equal(snakes[])){
gameover();
}
}; //给蛇增加长度(在尾巴加)
t.addFood=function(){
var tail1=snakes[snakes.length-];
var tail2=snakes[snakes.length-];
var addNode;
if(tail1.x==tail2.x){
if(tail1.y>=tail2.y)
addNode=new Node(tail1.x,tail1.y+gridWidth,gridWidth);
else
addNode=new Node(tail1.x,tail1.y-gridWidth,gridWidth);
}
else{
if(tail1.x>=tail2.x)
addNode=new Node(tail1.x+gridWidth,tail1.y,gridWidth);
else
addNode=new Node(tail1.x-gridWidth,tail1.y,gridWidth);
} //数组加入尾部
snakes.push(addNode);
addNode.snakeInit();
console.log(snakes.length); }//addFood函数
}//move函数结束 }/*snake函数结束*/ //开始游戏
function gameStart(){
var farm=new Farm();
food_interval=setInterval(farm.addfood,); //画蛇
snakes=[];//重新初始化数组,不要把前一次的数组元素遗留
var snake=new Snake(,,,);
snake.init();
}
gameStart();
//结束
function gameover(){
var judge=confirm("游戏结束,是否重新开始");
clearInterval(snake_interval);
clearInterval(food_interval);
while(!judge){
//res= confirm("游戏结束,是否重新开始");
return false;
}
gameStart(); }
</script>
</body>
</html>

html5面向对象做一个贪吃蛇小游戏的更多相关文章

  1. Java 用java GUI写一个贪吃蛇小游戏

    目录 主要用到 swing 包下的一些类 上代码 游戏启动类 游戏数据类 游戏面板类 代码地址 主要用到 swing 包下的一些类 JFrame 窗口类 JPanel 面板类 KeyListener ...

  2. 用js写一个贪吃蛇小游戏

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. 贪吃蛇小游戏-----C语言实现

    1.分析 众所周知,贪吃蛇游戏是一款经典的益智游戏,有PC和手机等多平台版本,既简单又耐玩.该游戏通过控制蛇头方向吃食物,从而使得蛇变得越来越长,蛇不能撞墙,也不能装到自己,否则游戏结束.玩过贪吃蛇的 ...

  4. JS高级---案例:贪吃蛇小游戏

    案例:贪吃蛇小游戏 可以玩的小游戏,略复杂,过了2遍,先pass吧 先创建构造函数,再给原型添加方法.分别创建食物,小蛇和游戏对象. 食物,小蛇的横纵坐标,设置最大最小值,运动起来的函数,按上下左右键 ...

  5. Java GUI学习,贪吃蛇小游戏

    JAVA GUI练习 贪吃蛇小游戏 前几天虽然生病了,但还是跟着狂神学习了GUI的方面,跟着练习了贪吃蛇的小项目,这里有狂神写的源码点我下载,还有我跟着敲的点我下载,嘿嘿,也就注释了下重要的地方,这方 ...

  6. 用GUI实现java版贪吃蛇小游戏

    项目结构 新建一个JFrame窗口,作为程序入口 public class GameStart{ public static void main(String[] args) { JFrame jFr ...

  7. C++ 简单的控制台贪吃蛇小游戏

    由于比较懒,所以不怎么写,觉得这样不应该.我应该对自己学的做出整理,不管是高端低端,写出来是自己的. // 贪吃蛇.cpp : 定义控制台应用程序的入口点. // #include "std ...

  8. 一个控制台贪吃蛇小游戏(wsad控制移动)

    /******************************************** * 程序名称:MR.DUAN 的贪吃蛇游戏(链表法) * 作 者:WindAutumn <flutti ...

  9. 用python+pygame写贪吃蛇小游戏

    因为python语法简单好上手,前两天在想能不能用python写个小游戏出来,就上网搜了一下发现了pygame这个写2D游戏的库.了解了两天再参考了一些资料就开始写贪吃蛇这个小游戏. 毕竟最开始的练手 ...

随机推荐

  1. testng.xml创建及解析

    项目右键---TestNG -----> Convert to TestNG 会自动产生一个testng.xml的文件 http://www.cnblogs.com/choosewang/art ...

  2. javascript闭包的一个例子

    <html> <head> <title>elementFromPoint</title> <script type="text/jav ...

  3. ArcGIS Server建立缓存(切图)原理解析[图解] (转载)

    GoogleMap ,VirtualEarth ,YahooMap 等,目前所有的WebGIS都使用了缓存机制 以提高地图访问速度.原理都是将地图设定为多个比例尺,对于每个比例尺提前将地图分成若干小图 ...

  4. {JavaScript}栈和堆内存,作用域

    1.栈 stack”和“堆 heap”:         简单的来讲,stack上分配的内存系统自动释放,heap上分配的内存,系统不释放,哪怕程序退出,那一块内存还是在那里.stack一般是静态分配 ...

  5. 阻止Application_End事件的解决方案

    在做项目时,遇到同步ERP数据的问题,客户要求是:程序中,设置一个开始时间,再设置一个时间间隔,让程序每隔一段时间导出销售记录,这个开始时间和时间间隔可以手动修改设定.     这问题纠缠了我好几天, ...

  6. 立体匹配:关于理解middlebury提供的立体匹配代码后的精减

    Middlebury立体匹配源码总结 优化方法 图像可否预处理 代价计算可否采用BT方式 可选代价计算方法 可否代价聚合 可否MinFilter优化原始代价 WTA-Box 可以 可以 AD/SD 可 ...

  7. JavaWeb四个域

    一.ServletContext对象(Context域)1.服务器启动的时候,会为每一个webapp创建一个对应的ServletContext对象,他代表该webapp,当服务器停止或将webapp从 ...

  8. Appium + Python -------------元素定位

    说在前面 1.https://github.com/appium/python-client/tree/master/test  里面有一些test ,可以看看,研究研究 2.学会使用 uiautom ...

  9. opecv轮廓匹配,可以用于去噪

    一个跟轮廓相关的最常用到的功能是匹配两个轮廓.如果有两个轮廓,如何比较它们;或者如何比较一个轮廓和另一个抽象模板. 矩 比较两个轮廓最简洁的方式是比较他们的轮廓矩.这里先简短介绍一个矩的含义.简单的说 ...

  10. rsync 参数断点续传

    断点续传是使用大写P参数,-P这个参数是综合了--partial --progress两个参数 rsync -avzP /home/hadoop/jdk1..0_73.tar.gz root@10.2 ...