Processing 贪吃蛇

上、下、左、右或者W、S、A、D键控制蛇的移动,P 键为暂停键,游戏结束可以按下 R 键重新开始游戏,相比参考文献,增加了吃的越多速度(speed)越快的玩法,原先想通过 frameRate() 函数来调节帧率,但是太不靠谱了,参数稍微改变一下,蛇就飞了-_-,后来想到昨天写的Processing实现定时器,借鉴了下思想,使用millis()函数来调节速率,最快每秒可以移动15步。效果如下:
贪吃蛇

贴出源代码:

int backgroundColor = 244;
int snakeLength = 2;    //Initial length of snake
int snakeHeadX;         //head(x,y)
int snakeHeadY;
char snakeDirection = 'R';  //UP/DOWN/LEFT/RIGHT
char snakeDirectionTemp;
int pause = 0;              //use for pause

int w=20;   //SnakeHead's Food's and oneStep's length(pix)

int maxSnakeLength = 400;
int[] x = new int [maxSnakeLength];
int[] y = new int [maxSnakeLength];

boolean foodKey = true;
int foodX;
int foodY;

int bestScore = snakeLength;
boolean gameOverKey = false;

int savedTime; 
int totalTime;
int passedTime;

void setup(){
    size(500,500);
    frameRate(30);
    noStroke();
    savedTime = millis(); 
}

int speed = 5;  //范围1~20比较好些,每秒移动的步数

void draw(){
    totalTime = 1000/speed; 
    passedTime = millis()- savedTime;

    if ( snakeDirection!='P' && passedTime > totalTime ) {
        if(isGameOver() ){
            speed = 5;  //set the orogin speed
            return;
        }

        background(backgroundColor);

        switch(snakeDirection){
            case 'L':
                snakeHeadX -= w;
                break;
            case 'R':
                snakeHeadX += w;
                break;
            case 'D':
                snakeHeadY += w;
                break;
            case 'U':
                snakeHeadY -= w;
                break;

        }

        //add another food
        drawFood(width,height);

        //eat it
        if( snakeHeadX == foodX && snakeHeadY == foodY){
            snakeLength++;
            //set the speed
            speed ++;
            speed = min(15,speed);  //speed's max value is 15
            foodKey = true;
        }

        //store snake body
        for(int i=snakeLength-1; i>0; i--){
            x[i] = x[i-1];
            y[i] = y[i-1];
        }

        //store snake new head
        y[0] = snakeHeadY;
        x[0] = snakeHeadX;

        stroke(0);  //Black
        strokeWeight(1);    //线宽为1

        //draw snakeHead
        fill(#ED1818);
        rect(x[0],y[0],w,w);

        //draw snakeBody
        fill(#7B6DB7);
        for(int i=1; i<snakeLength; i++){
            rect(x[i],y[i],w,w);
        }

        if(snakeDirection!='P' && isSnakeDie()){
            return;
        }

        savedTime = millis(); //passedTime=millis()-savedTime
    }

}//end draw()

//keyboard interrupt
void keyPressed() {
    if(key == 'p' || key == 'P'){
        pause++;
        if(pause%2==1){
            snakeDirectionTemp = snakeDirection;
            snakeDirection = 'P';
        }else{
            snakeDirection = snakeDirectionTemp;
        }

    }
    if(snakeDirection != 'P' && key == CODED){
        switch(keyCode){
            case LEFT:
                snakeDirection = 'L';
                break;
            case RIGHT:
                snakeDirection = 'R';
                break;
            case DOWN:
                snakeDirection = 'D';
                break;
            case UP:
                snakeDirection = 'U';
                break;
        }
    }else if(snakeDirection != 'P'){
        switch(key){
            case 'A':
            case 'a':
                snakeDirection = 'L';
                break;
            case 'D':
            case 'd':
                snakeDirection = 'R';
                break;
            case 'S':
            case 's':
                snakeDirection = 'D';
                break;
            case 'W':
            case 'w':
                snakeDirection = 'U';
                break;
        }
    }else{
        ;
    }
}   //end keyPressed()

void snakeInit(){
    background(backgroundColor);
    snakeLength = 2;
    gameOverKey = false;
    snakeHeadX = 0;
    snakeHeadY = 0;
    snakeDirection = 'R';
}

void drawFood(int maxWidth, int maxHeight){
    fill(#ED1818);
    if(foodKey){
        foodX = int( random(0, maxWidth)/w ) * w;
        foodY = int( random(0, maxHeight)/w) * w;
    }
    rect(foodX, foodY, w, w);
    foodKey = false;
}

boolean isGameOver(){
    if(gameOverKey && keyPressed && (key=='r'||key=='R') ){
        snakeInit();
    }
    return gameOverKey;
}

boolean isSnakeDie(){
    //hitting the wall
    if(snakeHeadX<0 || snakeHeadX>=width || snakeHeadY<0 || snakeHeadY>=height){
        showGameOver();
        return true;
    }

    //eat itself
    if(snakeLength>2){
        for(int i=1; i<snakeLength; i++){
            if(snakeHeadX==x[i] && snakeHeadY == y[i]){
                showGameOver();
                return true;
            }
        }
    }

    return false;
}

void showGameOver(){
    pushMatrix();
    gameOverKey = true;
    bestScore = bestScore > snakeLength ? bestScore : snakeLength;

    background(0);  //black
    translate(width/2, height/2 - 50);
    fill(255);  //white
    textAlign(CENTER);  //居中对齐
    textSize(84);
    text(snakeLength + "/" + bestScore, 0, 0);

    fill(120);
    textSize(18);
    text("Score / best",0,230);
    text("Game Over, Press 'R' to restart.", 0, 260);

    popMatrix();
}

参考自:
GitHub processing-snake

  • 15
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值