java控制台贪吃蛇小游戏(多线程版)

 

多线程版贪吃蛇

游戏说明: 本游戏运行在控制台中,直接运行SnakeTest.java文件,就能在控制台看到游戏画面,每按一个方向再按回车键就能控制蛇移动的方向
    a:向左移动
    d:向右移动
    s:向下移动
    w:向上移动
    其他字母键:暂停

 

源代码:

Snake.java

/**
 * Created by LIUFANGDA310 on 2018-8-27.
 */
import java.util.LinkedList;
import java.util.Random;
import java.util.Scanner;
/**
 * 多线程版本
 * @author lfd
 *有bug,不完美,比如蛇向左移动时,你让他向右移动,此时会暂停
 *界面刚出来时食物的位置跟你按方向键开始玩时的位置不一样
 */
public class Snake {
    private String[][] position = new String[24][30];//游戏界面的的大小
    private volatile LinkedList<String> snakeBody;
    private static final int FOOD_NUM = 10;//默认初始化的食物数量
    private volatile int speed = 600;//刚开始的移动速度
    private static final int INCREASE_SPEED = 15; //每吃一个食物增加的速度
    private volatile String operation;//用户的操作

    public Snake() {
        initWall();
        initSnake();
        initFood(FOOD_NUM);
        print();
    }

    public void move() {
        MoveThread moveThread = new MoveThread();//创建一个线程
        new Thread(moveThread).start();//启动线程
        while(true) {
            Scanner sc = new Scanner(System.in);
            operation = sc.next();//接收用户的输入
            if(operation.length()>=2) {
                operation = operation.substring(0,1);
            }
        }
    }

    //向上移动
    public void moveUp() {
        if((getX(0)-1 +","+ getY(0)).equals(snakeBody.get(1))) {//判断蛇头的方向是否是朝着自己身体的方向
            return;
        }
        if(position[getX(0)-1][getY(0)].equals("■")) {//判断是不是撞墙
            System.out.println("你死了");
            System.exit(0);
        }
        if(position[getX(0)-1][getY(0)].equals("●")) {//判断有没有吃到食物
            snakeBody.addFirst(getX(0)-1+","+getY(0));
            speed -= INCREASE_SPEED;//吃到一个食物,移动速度加快一些
            initFood(1);//产生一个食物
        }else {
            //没有吃到食物也没有撞墙
            snakeBody.addFirst(getX(0)-1+","+getY(0));//添加蛇头
            position[getX(snakeBody.size()-1)][getY(snakeBody.size()-1)] = " ";//移除蛇尾
            snakeBody.removeLast();
        }
        print();//每次移动后都重新打印界面
    }

    //向下移动
    public void moveDown() {
        if((getX(0)+1 +","+ getY(0)).equals(snakeBody.get(1))) {
            return;
        }
        if(position[getX(0)+1][getY(0)].equals("■")) {
            System.out.println("你死了");
            System.exit(0);
        }
        if(position[getX(0)+1][getY(0)].equals("●")) {
            snakeBody.addFirst(getX(0)+1+","+getY(0));
            speed -= INCREASE_SPEED;//吃到一个食物,移动速度加快一些
            initFood(1);//产生一个食物
        }else {
            snakeBody.addFirst(getX(0)+1+","+getY(0));
            position[getX(snakeBody.size()-1)][getY(snakeBody.size()-1)] = " ";
            snakeBody.removeLast();
        }
        print();//每次移动后都重新打印界面
    }

    //向右移动
    public void moveRight() {
        if((getX(0)+ ","+ (getY(0)+1)).equals(snakeBody.get(1))) {
            return;
        }
        if(position[getX(0)][getY(0)+1].equals("■")) {
            System.out.println("你死了");
            System.exit(0);
        }
        if(position[getX(0)][getY(0)+1].equals("●")) {
            snakeBody.addFirst(getX(0)+","+(getY(0)+1));
            speed -= INCREASE_SPEED;//吃到一个食物,移动速度加快一些
            initFood(1);//产生一个食物
        }else {
            snakeBody.addFirst(getX(0)+","+(getY(0)+1));
            position[getX(snakeBody.size()-1)][getY(snakeBody.size()-1)] = " ";
            snakeBody.removeLast();
        }
        print();//每次移动后都重新打印界面
    }

    //向左移动
    public void moveLeft() {
        if((getX(0)+","+ (getY(0)-1)).equals(snakeBody.get(1))) {
            return;
        }
        if(position[getX(0)][getY(0)-1].equals("■")) {
            System.out.println("你死了");
            System.exit(0);
        }
        if(position[getX(0)][getY(0)-1].equals("●")) {
            snakeBody.addFirst(getX(0)+","+(getY(0)-1));
            speed -= INCREASE_SPEED;
            initFood(1);//产生一个食物
        }else {
            snakeBody.addFirst(getX(0)+","+(getY(0)-1));
            position[getX(snakeBody.size()-1)][getY(snakeBody.size()-1)] = " ";
            snakeBody.removeLast();
        }
        print();//每次移动后都重新打印界面
    }

    //得到某节蛇身的x坐标
    public int getX(int index) {
        return Integer.parseInt(snakeBody.get(index).split(",")[0]);
    }

    //得到某节蛇身的y坐标
    public int getY(int index) {
        return Integer.parseInt(snakeBody.get(index).split(",")[1]);
    }

    public void print() {
        for(int i = 0; i< snakeBody.size(); i++) {
            int x = getX(i);
            int y = getY(i);
            if(i==0) {
                position[x][y] = "□"; //蛇头是□
                continue;
            }
            position[x][y] = "■";//身体是■
        }
        for(int i = 0;i<position.length;i++) {
            System.out.println();
            for(int j=0;j<position[i].length;j++) {
                System.out.print(position[i][j]+"  ");
            }
        }
    }

    //初始化墙
    public void initWall() {
        for(int i = 0;i<position.length;i++) {
            for(int j=0;j<position[i].length;j++) {
                position[i][j] = " ";
            }
        }
        //初始化第一列和最后一列
        for(int i=0;i<position.length;i++) {
            position[i][0] = "■";
            position[i][position[0].length-1] = "■";
        }
        //初始化第一行和最后一行
        for(int i=0;i<position[0].length;i++) {
            position[0][i] = "■";
            position[position.length-1][i] = "■";
        }
        //在界面中产生一道墙
        for(int i=0;i<position.length/2;i++) {
            position[(position.length/4)+i][position[0].length/4] = "■";
        }
    }

    //初始化蛇的位置
    public void initSnake() {
        snakeBody = new LinkedList<>();
        snakeBody.add(position.length/2 + "," + (position[0].length/2));
        snakeBody.add(position.length/2 + "," + (position[0].length/2+1));
        snakeBody.add(position.length/2 + "," + (position[0].length/2+2));
        snakeBody.add(position.length/2 + "," + (position[0].length/2+3));
    }

    /**
     * 初始化食物数量
     * @param number 食物数量
     */
    public void initFood(int number) {
        int flag = 0;
        while(flag != number) {
            int x = new Random().nextInt(position.length-1) + 1;
            int y = new Random().nextInt(position[0].length-1) + 1;
            if(position[x][y] == " ") {
                position[x][y] = "●";
                flag++;
            }else {
                continue;
            }
        }
    }

    //实现自动移动的线程类
    class MoveThread implements Runnable{
        @Override
        public void run() {
            while(true) {
                if("w".equals(operation)) {//若用户输入的是w,向上移动
                    moveUp();
                }else if("s".equals(operation)) {//若用户输入的是s,向下移动
                    moveDown();
                }else if("a".equals(operation)) {//若用户输入的是a,向左移动
                    moveLeft();
                }else if("d".equals(operation)) {//若用户输入的是d,向上移动
                    moveRight();
                }else{
                    Thread.yield();//输入除asdw之外的其他字母,暂停移动
                }
                try {
                    Thread.sleep(speed);//每次移动后让线程睡眠一段时间
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}

SnakeTest.java

 

 

public class SnakeTest {
	public static void main(String[] args) {
		Snake snake = new Snake();
		snake.move();
	}
}

 

 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值