JavaScript 开发贪吃蛇游戏

写于:2014/11/13
预计阅读时间:8 分钟

用JavaScript写游戏?一直以来,使用JS都是写一些交互和特效而已,从没写过游戏,加之一个月没有更新博客了,蜘蛛都不来了……所以这次就贴一个前段时间写的贪吃蛇游戏吧,这个贪吃蛇游戏规则不同于小时候掌上游戏机的那种类型,这个贪吃蛇每吃完一个果子,果子就会变成果核,蛇身自动加长一截,蛇吃到果核也会死掉,随着吃的果子越来越多,蛇身越来越长,游戏难度将会越来越大。

贪吃蛇的基本原理很简单:蛇在运动的过程中只要蛇头运动,然后其他每一截蛇身的位置等于前面一截蛇身的位置。

HTML和CSS就不贴代码出来了。首先创建蛇:蛇的每一截都可以用html标签元素来模拟,假设外部的容器对象为oWrap,在oWrap里面添加一只四截的蛇:

/*
    创建蛇:
    oWrap:最外层容器,包含游戏画布所有内容
    oSnake[]:存放蛇身的每一截,HTML元素:<b></b>
    row:列、line:行
    initX:初始行数、initY:初始列数
    initLeng:蛇的初始长度
*/
var oWrap = document.getElementById('wrap');
var oSnake=[], initX = 15, initY = 11, initLeng = 4;
for( var i = 0; i < initLeng; i++ ) {
    oSnake[i] = document.createElement('b');
    oSnake[i].line = initX+i;
    oSnake[i].row = initY+1;
    setPosition(oSnake[i]);
    oWrap.appendChild(oSnake[i]);
}
oSnake[0].style.background = '#070'; // 蛇头深色

这样就在oWrap里添加了四个b元素,然后在CSS里要将b设定为块级元素,宽高各为16PX(var scale=16),画布暂设为560px×400px,25行,35列。完成之后就是一条安静的蛇躺在中间:

用setInterval()使蛇运动起来,以及贪吃蛇的所有核心部分都在定时器里面执行。首先是监听键盘事件,通过键盘的方向键来控制蛇的方向(键盘值为:← 37,↑ 38,→ 39,↓ 40;当然,游戏方向键也有必要考虑下:A 65,W 83,D 65,S 87)

var key = null, direction = "left";
document.onkeydown = function( e ) { //监听键盘
    var eve = e || event;
    key = eve.keyCode || eve.which || eve.charCode;
    // 根据按下的方向键确定移动方向:
    switch( key ) {
        case null: case 37: case 65: direction="left"; break;
        case 38: case 87: direction = "up"; break;
        case 39: case 68: direction = "right"; break;
        case 40: case 83: direction = "down"; break;
        default:direction = "left";
    }
}// keydown end

键盘key值获取之后,然后就是回到贪吃蛇的运动原理了:每一截的位置等于前面一截的位置,以此类推:

// 蛇身后面一截的位置等于前面一截:
for( var i = oSnake.length-1; i > 0; i-- ) {
    oSnake[i].line = oSnake[i-1].line;
    oSnake[i].row = oSnake[i-1].row;
}
// 改变方向:(只需改变蛇头的方向)
switch( direction ) {
    case 'left': {
        if( oSnake[0].line > 1 ) oSnake[0].line--;
        else death(oSnake);
    };break;
    case 'up': {
        if( oSnake[0].row > 1 ) oSnake[0].row--;
        else death(oSnake);
    };break;
    case 'right': {
        if( oSnake[0].line < 33 ) oSnake[0].line++;
        else death(oSnake);
    };break;
    case 'down': {
        if( oSnake[0].row < 23 ) oSnake[0].row++;
        else death(oSnake);
    };break;
    default: return;
}
// 获取新的坐标之后重新设置每一截的位置
for( var i = 0, len = oSnake.length; i < len; i++ ) {
    oSnake[i].style.left = scale*oSnake[i].line + 'px';
    oSnake[i].style.top = scale*oSnake[i].row + 'px';
}

上面的变量scale为蛇的每一截尺寸,设置为16px,到这一步就能实现方向键控制蛇的运动方向了。下面一步就是创建一个随机位置的果实构造函数,拥有创建果实的方法createFruit()和记录吃剩记录beStone():

function Fruit( obj ) {
    /*
        fx:2~34随机行数,
        fy:2~24随机列数
        Math.random()*(上限-下限+1)+下限
    */
    this.fruit = null;
    this.createFruit = function() { // 创建产生果实的方法
        this.fx = parseInt( Math.random()*33 + 2 );
        this.fy = parseInt( Math.random()*23 + 2 );
        deathLine.push( this.fx - 1 );
        deathRow.push( this.fy - 1 );
        this.fruit = document.createElement('div'); // 创建一个果实
        var xAxis = ( this.fx - 1 ) * scale;
        var yAxis = ( this.fy - 1 ) * scale;
        this.fruit.style.cssText = "position:absolute;
        left: "+xAxis + "px;
        top: "+yAxis + "px;
        width: 16px;
        height: 16px;
        background: #F60;
        z-index: 4;
        background: url(fruit.png) no-repeat;";
        obj.appendChild(this.fruit);
    }
    this.beStone = function() { // 吃掉的果实变为果核
        this.fruit.style.background = "url(eaten.png) no-repeat";
    }
}

然后就是实例化蛇:

/* 创建果实: */
var oFruit= new Fruit(oWrap);
oFruit.createFruit();

蛇头吃到自身的任何一个部位都要死掉:

// 蛇身任意一处重叠时(吃到自己,蛇头与身体任意一截重叠)挂掉!
for( var i = 1, len = oSnake.length; i < len; i++ ) {
    if( oSnake[i].line == oSnake[0].line &amp;&amp; oSnake[i].row == oSnake[0].row ) {
        alert("Game Over!");
    }
}

蛇吃到果实后自身增加一截,并且判断是否吃到果核,如果是吃到果核也要挂掉:

// 蛇头首次吃到果实后:
var deathLine = [], deathRow=[], score = 0, degree = 10; // 存放每一个果核的位置
if( oSnake[0].line + 1 == oFruit.fx &amp;&amp; oSnake[0].row+1 == oFruit.fy ) {
    // 分数增加:
    document.getElementById('score').innerHTML = score += degree;
    // 吃掉果实后蛇身增加一截(加到最后一截):
    var newSnake = document.createElement('b');
    newSnake.line = oSnake[oSnake.length-1].line;
    newSnake.row = oSnake[oSnake.length-1].row;
    oSnake.push(newSnake);
    for( var i = 0, len = oSnake.length; i < len; i++ ) {
        oSnake[i].style.left = scale*oSnake[i].line + 'px';
        oSnake[i].style.top = scale*oSnake[i].row + 'px';
    }
    oWrap.appendChild(oSnake[oSnake.length-1]);
    // 标记果核已经被吃掉(变成果核)
    oFruit.beStone();
    // 吃完后再重新生成一个“果实”
    window.setTimeout(function() {
        oFruit.createFruit();
    }, speed);
}else { // 蛇头吃到果核:
    for( var i = 0, len = deathLine.length; i < len; i++ ) {
        if( oSnake[0].line == deathLine[i] &amp;&amp; oSnake[0].row == deathRow[i] ) {
            alert("Game Over!");
        }
    }
}

至此,大致原理就扯完了,不知道网友们能看得懂么?水平有限啊~可以在线试玩一下,(能玩到600分就很厉害了哦!):在线贪吃蛇游戏

评论列表
果果不甜
如果能加上音效就更好了!
梦飞扬0809
苹果有时候出现在蛇身里面了,看不到在哪~
不会玩的小CC
很不错!厉害!最多玩到640分