javascript+canvas实现小游戏-贪吃蛇

好吧。。这个东西已经被写烂了。。不过自己写出来其实感觉完全不一样。。这是我写的第一个东西。。算抄吧。。。毕竟是边写边看书啊。
游戏速度选择有个bug,本来是想用onblur是做难度选择的,结果发现每次都要点一下页面才会实现,也就是说如果不点页面,上下箭头控制蛇的时候也在不停的更改速度,结果室友说比正常的好玩。。那我就没改了。哈哈哈。要的就是魔性……..

        <style>
            *{
                margin: 0;
                padding: 0;
                font-family: "微软雅黑";
                font-size: 14px;
            }
            #gameBox{
                width: 100%;
                height: 650px;
                position: relative;
                overflow: hidden;
            }
            h1{
                width: 90%;
                height: 40px;
                position: absolute;
                left: 5%;
                top: 0;
                font-size: 2rem;
                line-height: 1.5;
                text-align: center;
            }
            #gameArea{
                width: 100%;
                height: 500px;
                position: absolute;
                top: 70px;
            }

            #gameArea #score{
                width: 20%;
                height: 20px;
                position: absolute;
                top: -20px;
                left: 10%;
            }

            #gameArea #tips{
                width: 70%;
                height: 20px;
                position: absolute;
                top: -20px;
                left: 30%;
            }

            #canvas{
                position: absolute;
                top: 0;
                margin-left: -600px;
                left: 50%;
            }

            #controlBox{
                width: 100%;
                text-align: center;
                position: absolute;
                bottom: 0;
            }
            #reStart{
                text-align: center;
                border: none;
                width: 70px;
                height: 30px;
                background-color: rgba(26,238,151,0.7);
            }
            #reStart:hover{
                color: antiquewhite;
                background-color: rgba(0,0,0,0.7);
            }
            #speed{
                color: antiquewhite;
                width: 70px;
                height: 30px;
                background-color: rgba(0,0,0,0.7);
                border: none;
            }
            #speed:hover{
                color: black;
                background-color: rgba(26,238,151,0.7);
            }
        </style>
    <body>
        <!--游戏盒子-->
        <div id="gameBox">
            <h1>贪吃蛇</h1>
            <!--游戏主体区域-->
            <div id="gameArea">
                <!--分数-->
                <span id="score">score:</span>
                <span id="tips">开始游戏之前请先选择速度,然后点击屏幕就可以开始游戏了</span>
                <canvas id="canvas" width="1200px" height="500px"></canvas>
            </div>
            <!--控制盒子-->
            <div id="controlBox">
                <!--重新开始-->
                <input type="button" id="reStart" value="reStart"/>
                <!--速度选择-->
                <select id="speed">
                    <option>fast</option>
                    <option>normal</option>
                    <option>slow</option>
                </select>
            </div>
        </div>
    </body>
<script>
        var body=document.getElementsByTagName("body")[0];
            scoreTxt=document.getElementById("score"),
            score=0,
            canvas=document.getElementById("canvas"),
            ctx=canvas.getContext("2d"),
            reStart=document.getElementById("reStart"),
            speed=document.getElementById("speed"),
            speedVal=document.getElementById("speed").value;
        var width=canvas.width,
            height=canvas.height;//游戏的宽高
            //将画布分为10*10 的小格子
        var blockSize=10,
            widthInBlocks=width/blockSize,
            heightInBlocks=height/blockSize;
        //游戏边框绘制
        var drawBorder=function(){
            ctx.beginPath();
            ctx.fillStyle="dimgray";
            //上边距
            ctx.fillRect(0,0,width,blockSize);
            //下边距
            ctx.fillRect(0,height-blockSize,width,height);
            //左边框
            ctx.fillRect(0,0,blockSize,height);
            //右边框
            ctx.fillRect(width-blockSize,0,width,height);
        };
        //结束游戏
        var gameOver=function(){
            //清楚定时器
            clearInterval(time);
            ctx.font="100px 微软雅黑";//字体&大小
            ctx.fillStyle="black";//字体颜色
            ctx.textAlign="center";//位置
            ctx.textBaseline="middle";//位置
            ctx.fillText("Game Over", width/2, height/2);
        };
        //速度改变,通过改变时间来改变速度
        var speedChange=function(speed){
            if(speed=="fast"){
                return moveTime=30;
            }else if(speed=="normal"){
                return moveTime=50;
            }else if(speed=="slow"){
                return moveTime=70;
            }
        };


        //block对象表示画布中的每个10*10的 图块
        var Block=function(col,row){
            this.col=col;
            this.row=row;
        };
        //给对象添加画块的方法,用来构建snake
        Block.prototype.drawBlock=function(color){
            var x=this.col*blockSize;//block的横坐标
            var y=this.row*blockSize;//block的纵坐标
            ctx.fillStyle=color;
            ctx.fillRect(x,y,blockSize,blockSize);//长宽为10
        };

        //添加画圆的方法,这是apple,画圆注意的是保证x,y在方块的中心位置
        Block.prototype.drawCircle=function(color){
            //保证点位置在方块中心,给x,y各加上blockSize的一半
            ctx.fillStyle=color;
            var x=this.col*blockSize+blockSize / 2; 
            var y=this.row*blockSize+blockSize / 2;
            ctx.arc(x,y,blockSize/2,0,Math.PI*2,true);
            ctx.fill();
        };

        //创建对比函数,对比两个块是否在同一位置
        Block.prototype.equal=function(secondBlock){
            return (this.col==secondBlock.col)&&(this.row==secondBlock.row);
        };
        //equal测试
            // var apple=new Block(10,10);
            //var snake=new Block(10,10);
            //alert(snake.equal(apple));
        //apple测试
            //var block=new Block(10,10);
            //block.drawCircle("gray");
        //创建snake对象,将蛇存为一个snakeStr的数组,snakeStr[0]表示蛇头


        var Snake=function(){
            this.snakeStr=[
                new Block(25,10),
                new Block(24,10),
                new Block(23,10)
            ];//初始snake所在位置
            this.direction="right";//现在的行进方向
            this.nextDirection="right";//下一步的行进方向
        };
        //snake绘制
        Snake.prototype.drawSnake=function(){
            for(var i=0;i<this.snakeStr.length;i++){
                this.snakeStr[i].drawBlock("green");
            }
        };
        //sanke测试
            //var snake=new Snake();
            //snake.drawSnake();
        //snake移动方法,right向右加一个blocksize。。。,检查方向,
        //检查snake状态,如果snake和border或者自身有块重合,则gameOver
        Snake.prototype.move=function(){
            var head=this.snakeStr[0];//第一位为snake头部
            var newHead;//新的头部
            this.direction=this.nextDirection;
            //判断方向
            if(this.direction=="right"){
                newHead=new Block(head.col+1,head.row);//newHead的位置
            }else if(this.direction=="left"){
                newHead=new Block(head.col-1,head.row);
            }else if(this.direction=="up"){
                newHead=new Block(head.col,head.row-1);
            }else if(this.direction=="down"){
                newHead=new Block(head.col,head.row+1);
            }
            //判断newhead是否和自身或者border同一位置,如在同一位置就gameOver
            if(this.checkSnake(newHead)){
                gameOver();
                return;
            }
            //把newhead加入snakeStr
            this.snakeStr.unshift(newHead);
            //检查apple和newhead在不在同一位置,如果在,score+1,不用删除增加出来的newhead
            if(newHead.equal(apple.position)){
                apple.move();//apple随机生成新地点
                score++;
                scoreTxt.innerHTML="score:"+score;
            }else{
                this.snakeStr.pop();//删除snakeStr末尾
            }
        };
        //snake和border或者self的碰撞检测
        Snake.prototype.checkSnake=function(head){
            var leftBorder=0,
                topBorder=0,
                rightBorder=widthInBlocks-1,
                bottomBorder=heightInBlocks-1;
                //检查head的位置是否在四边框上
            var border=(leftBorder==head.col||rightBorder==head.col||topBorder==head.row||bottomBorder==head.row);
            var self=false;
            for(var i=0;i<this.snakeStr.length;i++){
                if(head.equal(this.snakeStr[i])){
                    self=true;
                }
            }
            return border||self;//返回border和self,二者有一项为true,则结束游戏
        };

        //setDirection检查方向的是正确性,snake不能反方向移动
        Snake.prototype.setDirection=function(newDirection){
            if(this.direction=="up"&&newDirection=="down"){
                return;
            }else if(this.direction=="left"&&newDirection=="right"){
                return;
            }else if(this.direction=="down"&&newDirection=="up"){
                return;
            }else if(this.direction=="right"&&newDirection=="left"){
                return;
            }
            this.nextDirection=newDirection;
        }

        //apple绘制
        var Apple=function(){
            this.position=new Block(30,30);//Apple的原型是Block
        };//apple的初始位置
        //apple绘制
        Apple.prototype.drawApple=function(){
            this.position.drawCircle("red");
        }
        //apple的move函数需要重新绘制apple的位置
        Apple.prototype.move=function(){
            var posX=Math.floor(Math.random()*(widthInBlocks-2))+1;//Math.floor(Math.random()*(widthInBlocks-2))随机生成0-98的数字
            var posY=Math.floor(Math.random()*(heightInBlocks-2))+1;
            this.position=new Block(posX,posY);

        };
        //apple检测
          //apple.move();
          //apple.drawApple();
        //游戏开始
        //var snake=new Snake();
        //var apple=new Apple();

        //var time=setInterval(function(){
        //  ctx.clearRect(0,0,width,height);
        //  snake.move();
        //  snake.drawSnake();
        //  apple.drawApple();
        //  drawBorder();
        //},speedTime)


        //键盘事件
        var directions={
            37:"left",
            38:"up",
            39:"right",
            40:"down"
        };
        //绑定键盘事件
        body.onkeydown=function(event){
            var newDirection=directions[event.keyCode];
            if(newDirection!==undefined){
                snake.setDirection(newDirection);
                //按键测试alert(newDirection);
            }
        };
        //reStart事件
        reStart.onclick=function(){
            window.location.reload();
        };
        //选择速度然后开始游戏
        var apple=new Apple();
        var snake=new Snake();
        var time=null;//存放定时器
        //判断速度之后就开始游戏
        //初始界面绘制一次apple,snake,border
        apple.drawApple();
        snake.drawSnake();
        drawBorder();
        //这本来是个bug,但是突然觉得挺好玩的,就留下了,如果不点击屏幕,snake的速度会变
        speed.onchange=function(speedVal){
            clearInterval(time);
            time=setInterval(function(){
                startGame();
            },speedChange(speed.value))
        };
        //开始游戏
        var startGame=function(){
            ctx.clearRect(0,0,width,height);
            snake.move();
            snake.drawSnake();
            apple.drawApple();
            drawBorder();
        };
    </script>
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值