您的位置:首页 > Web前端 > HTML5

limej 写一个HTML5的贪吃蛇小游戏

2013-05-09 12:06 302 查看
        之前用limejs框架写了一个贪吃蛇的小游戏。现在想迁移到cocos2d-x上。可是一直找不到好的贪吃蛇的移动算法。想想还是用之前js写的笨方法吧,可是才过了个5.1就忘了。还是赶紧回顾一下代码,先把思路记录一下。
这个贪吃蛇移动的方法有几个不理想的地方。
身体块必须是正方形的。//这样就限制了给蛇渲染图片的限制。
每次移动必须是一个身体块的大小。
只能上下左右4个方向移动
其他
如果有好的方法,欢迎指教。谢谢!
思路
先把我的思路记录一下吧。
首先是把蛇的身体分成N个正方形的精灵(Sprite),"000000o"精灵个数就是蛇的长度,通过在尾部增加精灵个数来增加蛇的长度。每个精灵是一个实体,在动画帧变化的时候每个精灵都跟着变化。
蛇运动最复杂的就是转弯的时候。必须考虑到多次转弯的情况。比如下面这种情况:
0000
0     000o
0000
我的思路是,给身体的每一个点都设置一个移动方向,每次运动,后一个点就跟着上一个的移动方向移动,就可以完成上面的效果了。
3. 把蛇身体的精灵大小作为每次移动的举例,比如向上,就Y轴增加一个bodysize。所以要求精灵必须是正方形的。
4. 通过帧率或者多少帧运动一次来控制蛇运动的速度。

代码
直接结合注释,贴上代码吧。
1、 蛇的对象类。snake_playe.js





goog.provide('snake.game');

goog.require('lime.Sprite');

goog.require('lime.fill.LinearGradient');

goog.require("snake.food");

snake.game = function(level){

lime.Sprite.call(this);
this.foodList
= [] ;
this.level
= level ;
this.WIDTH
= 300 ;
this.HEIGHT
= 440 ;
this.nFrame
= 10 ; //10帧的运动1次
this.bodyList
= [] ;//存放蛇身体块的数组
this.bodySize
= 10 ; //蛇身体块的大小
this.length
= 5 ;//初始蛇的长度,也就是精灵个数。
this.score
= 0 ;

this.setAnchorPoint(0,0);
this.setSize(320,460);

//设置背景
var back
= new lime.fill.LinearGradient().addColorStop(1,'#FF8000').addColorStop(1,'#FF8000');
this.setFill(back);

this.scoreLabel
= new lime.Label().setText('score: 0').setPosition(30,5).setFontSize(12);
this.appendChild(this.scoreLabel);

this.world
= new lime.Sprite().setFill('#FFFFFF').setSize(this.WIDTH,this.HEIGHT).setPosition(10,10).setAnchorPoint(0,0);
this.appendChild(this.world);

this.start();

}

goog.inherits(snake.game, lime.Sprite);

snake.game.prototype.start =
function(){
//初始化蛇的身体
this.initBody();
this.addFood();
//随机生成食物,注意不要和墙壁和蛇重合就可以了。

goog.events.listen(this,
'keydown', this.kdControl);//监听按键事件

lime.scheduleManager.schedule(this.step,this);
//祯运动方法

}

snake.game.prototype.addFood =
function(){
if(this.foodList.length>
0 ){
for(var i=
0 ; i<this.foodList.length ; i++){
this[/b].world.removeChild(this.foodList[i]);

}
this.foodList
= [];

}
var food
= new snake.food();
var fSize
= food.getSize();
var rx,ry;
while(true){

rx = Math.round(Math.random()* (this.WIDTH- food.getSize().width)) ;

rx = Math.round(rx
/ 10) *10 ;

ry = Math.round(Math.random()* (this.HEIGHT- food.getSize().height)) ;

ry = Math.round(ry
/ 10) *10 ;
var flag
= true ;
for(var i=0 ; i<this.bodyList.length
; i++){
var bPos,bSize ;

bPos = this.bodyList[i].getPosition();

bSize = this.bodyList[i].getSize();
if(((rx
+ fSize.width) > bPos.x)
&& ( rx < (bPos.x
+ bSize.width))){
if(((ry
+ fSize.height) > bPos.y )&&( ry< (bPos.y
+ bSize.height))){

flag = false ;

}

}

}
if(flag) {

food.setPosition(rx,ry);
this.foodList.push(food);
this.world.appendChild(food);
return;

}

}

}

var FrameTemp
= 0 ;
//控制10帧运动一次,以控制速度。

snake.game.prototype.step =
function(){
// var pos = this.player.getPosition(), size = this.world.getSize(),pSize = this.player.getSize();

FrameTemp ++ ;
if(FrameTemp
> this.nFrame){

FrameTemp = 0 ;

}
if(FrameTemp
== this.nFrame){
//蛇运动
this.snakeRun();

}

}

snake.game.prototype.snakeRun =
function(){
var i , pDirection;
var bodyList
= this.bodyList;
//遍历每一个点
for(i
= 0 ; i < bodyList.length ; i++){
var bx
= bodyList[i].getPosition().x;
var by
= bodyList[i].getPosition().y;
//根据当前运动方向控制精灵的运动
if(bodyList[i].m_direction
== 'up'){

by -= this.bodySize ;

}else
if(bodyList[i].m_direction =='down'){

by += this.bodySize ;

}else
if(bodyList[i].m_direction =='left'){

bx -= this.bodySize ;

}else
if(bodyList[i].m_direction =='right'){

bx += this.bodySize ;

}
//控制游戏结束,只有i==0,也就头撞到墙才会游戏结束。
if(i
== 0 &&this.endRule()) {
this.endGame();
return;

}

bodyList[i].setPosition(bx,by);
//改变每一个节点的运动方向,即运动完之后,自己运动方向向后传递。
if(bodyList[i]._type
== "header"){

pDirection = bodyList[i].m_direction;

}else{

_tempDir = pDirection;
//bodyList[i].p_direction = bodyList[i].m_direction ;

pDirection = bodyList[i].m_direction;

bodyList[i].m_direction = _tempDir;

}

}
//食物碰撞检验
this.searchFood();

}

snake.game.prototype.searchFood =
function(){
var hBlock
= this.bodyList[0];
var hPos
= hBlock.getPosition();
var hSize
= hBlock.getSize();
var food
= this.foodList[0];
var fPos ,fSize , food ;
if(this.foodList.length>
0 ){

food = this.foodList[0] ;

fPos = food.getPosition();

fSize = food.getSize();
// console.log("hPos.x :" + hPos.x + " y:" + hPos.y);
// console.log("fPos.x :" + fPos.x + " y:" + fPos.y);
if(((hPos.x
+ hSize.width) > fPos.x)
&& (hPos.x < fPos.x
+ fSize.width) && ((hPos.y
+ hSize.height) > fPos.y)
&& (hPos.y < fPos.y
+fSize.height)){
this.world.removeChild(food);
this.foodList.splice(0,1);
this.addBlock();
this.addFood();
this.score++;
this.scoreLabel.setText("score : "+
this.score);

}

}

}

snake.game.prototype.kdControl =
function(e){
var direction ;
if(e.event.keyCode
== 37){ //左

direction = "left" ;

}else
if(e.event.keyCode ==
38){ //上

direction = "up" ;

}else
if(e.event.keyCode ==
39){ //右

direction = "right" ;

}else
if(e.event.keyCode ==
40){ //下

direction = "down" ;

}
this.bodyList[0].m_direction= direction ;
//改变头的方向

this.snakeRun();

};

//在尾部增加一个身体块

snake.game.prototype.addBlock =
function(){
var tBlock
= this.bodyList[this.bodyList.length-
1] ;
var tDirection
= tBlock.m_direction;
var tPos
= tBlock.getPosition();

var front_color
= '#AACDEF';
var back_color
= '#AACDEF';
var grad
= new lime.fill.LinearGradient().

addColorStop(0, back_color).

addColorStop(1, front_color);

var bodyBlock
= new lime.RoundedRect().setSize(this.bodySize,this.bodySize).setFill(grad).setAnchorPoint(0,0);
if(tDirection
== "up"){

bodyBlock.setPosition(tPos.x ,tPos.y +
this.bodySize);

}else
if(tDirection ==
"down"){

bodyBlock.setPosition(tPos.x ,tPos.y -
this.bodySize);

}else
if(tDirection ==
"left"){

bodyBlock.setPosition(tPos.x +
this.bodySize ,tPos.y);

}else
if(tDirection ==
"right"){

bodyBlock.setPosition(tPos.x -
this.bodySize ,tPos.y);

}

bodyBlock.m_direction = tBlock.m_direction ;

bodyBlock.p_direction = tBlock.m_direction ;
this.world.appendChild(bodyBlock);
this.bodyList.push(bodyBlock);

}

snake.game.prototype.initBody =
function(){
//如果游戏开始就存在bodyList , 则清空
if(this.bodyList.length>
0 ){
for(var i=
0 ; i<this.bodyList.length ; i++){
this.world.removeChild(this.bodyList[i]);

}
this.bodyList
= [];

}
var i ;
this.start_direction
= "left" ;
//开始前进方向
var front_color
= '#AACDEF';
var back_color
= '#AACDEF';
var grad
= new lime.fill.LinearGradient().

addColorStop(0, back_color).

addColorStop(1, front_color);
for(i
= 0 ; i<this.length ; i++){
var bodyBlock
= new lime.RoundedRect().setSize(this.bodySize,this.bodySize).setFill(grad).setAnchorPoint(0,0);//绘制蛇的身体精灵

bodyBlock.setPosition(250+i*this.bodySize,250);//设置初始坐标
if (i
== 0){

bodyBlock._type =
"header" ; // 设置_type为头

bodyBlock.m_direction =
this.start_direction ; //设置当前移动方向

}else
if(i == (this.length-
1)){

bodyBlock._type =
"tail";

bodyBlock.m_direction =
this.start_direction ;
// bodyBlock.p_direction = this.start_direction ;

}else {

bodyBlock._type =
"body" ;

bodyBlock.m_direction =
this.start_direction ;
// bodyBlock.p_direction = this.start_direction ;

}

this.bodyList.push(bodyBlock);
this.world.appendChild(bodyBlock);

}

}

snake.game.prototype.endRule =
function(){
var hBlock
= this.bodyList[0];
var hPos
= hBlock.getPosition() , hSize = hBlock.getSize();
var hDirection
= hBlock.m_direction;
if((hDirection
== "up") && ((hPos.y-
this.bodySize)<
0 )){
return true ;

}else
if( (hDirection ==
"down") && ((hPos.y
+ this.bodySize)
>= this.HEIGHT ) ){
return true ;

}else
if((hDirection ==
"left") && ((hPos.x
- this.bodySize)
< 0 )) {
return true ;

}else
if((hDirection ==
"right") && ((hPos.x
+ this.bodySize)
>= this.WIDTH )){
return true ;

}
for(var i=
1 ; i<this.bodyList.length ; i++){
var bPos,bSize ;

bPos = this.bodyList[i].getPosition();

bSize = this.bodyList[i].getSize();
if(((hPos.x
+ hSize.width) > bPos.x)
&& ( hPos.x < (bPos.x
+ bSize.width))){
if(((hPos.y
+ hSize.height) > bPos.y )&&( hPos.y< (bPos.y
+ bSize.height))){
return true ;

}

}

}
return false;

}

snake.game.prototype.endGame =
function(){

lime.scheduleManager.unschedule(this.step,this);

goog.events.unlisten(this,"keydown",this.kdControl);
// this.dispatchEvent("keydown");
this.score
= 0 ;

var back
= new lime.fill.LinearGradient().addColorStop(0,255,
150, 0, .4)

.addColorStop(0.9,250,
150, 0, .05).addColorStop(1,0,
0, 0,
0);
var notice
= new lime.RoundedRect();

notice.setSize(150,
100).setFill(back).setAnchorPoint(.5,
0);

var title
= new lime.Label().setText("GAME OVER").setPosition(0,20);

notice.appendChild(title);

notice.setPosition(150 ,250);
this.world.appendChild(notice);

//var show = new lime.animation.FadeTo(1);

goog.events.listen(notice, "click",
function() {

notice.setHidden(true);
this.start();

},false, this);
//notice.runAction(show);

}

demo运行查看地址(上下左右键控制方向):http://www.517one.com/demo/snake.html 
源码百度网盘下载地址:http://pan.baidu.com/share/link?shareid=428666&uk=1477240704
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  HTML5 limejs 游戏开发