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. MySql中增加一列

    如果想在一个已经建好的表中添加一列,可以用诸如: alter table TABLE_NAME add column NEW_COLUMN_NAME varchar(20) not null; 这条语 ...

  2. esriSRProjCS3Type Constants

    ArcGIS Developer Help  (Geometry)   esriSRProjCS3Type Constants See Also esriSRProjCSType Constants ...

  3. Maven依赖范围及依赖传递

    一: 依赖范围scope 共5种,compile (编译).test (测试).runtime (运行时).provided.system 不指定,则依赖范围默认为compile. compile:编 ...

  4. FPGA一个博客学习

    FPGA一个博客学习 http://bbs.ednchina.com/BLOG_PERSONALCAT_100185_2001619.HTM

  5. 在SoCEDS环境下编译和更新preloader和uboot程序的方法

    在SoCEDS环境下编译和更新preloader和uboot程序的方法   前面有介绍preloader在HPS boot过程中的的作用,接下来讲述下用户在SoCEDS环境下改如何编译preloade ...

  6. Hibernate——主键配置

    <id>元素中的<generator>用来为该持久化类的实例生成唯一的标识,hibernate提供了很多内置的实现. Increment:由hibernate自动递增生成标识符 ...

  7. Android设置不被系统设置改变的字体大小

    原因 从4.0开始,系统设置中“显示”可以对字体大小进行配置,这会影响到TextView等控件中文字显示的大小. 解决方案 在自定义的Activity中重写getResources方法 @Overri ...

  8. MySQL数据库优化技术之数据库表的设计

    三范式介绍表的范式:只有符合的第一范式,才能满足第二范式,进一步才能满足第三范式. 1. 第一范式:表的列具有原子性,不可再分解.只要是关系型数据库都自动满足第一范式.数据库的分类:关系型数据库:My ...

  9. Oracle VM VirtualBox 安装笔记

    [CentOS 6] 1.在官网下载VirtualBox-4.2-4.2.16_86992_el6-1.x86_64.rpm安装. 2.YUM安装kernel-devel包. 3.把用户加入vboxu ...

  10. CSS3 border-radius 属性和CSS outline 属性

    CSS3 border-radius 属性 border-radius 属性是一个简写属性,用于设置四个 border-*-radius 属性. 提示:该属性允许为元素添加圆角边框! 注释:按此顺序设 ...