用户注册



邮箱:

密码:

用户登录


邮箱:

密码:
记住登录一个月忘记密码?

发表随想


还能输入:200字
云代码 - java代码库

贪吃蛇游戏

2017-03-11 作者: 陆痴举报

[java]代码库

11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
package game.mysanek.entities;
 
import game.mysanek.listener.SnakeListener;
import game.mysanek.util.Global;
 
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Set;
 
public class Snake {
    public static final int UP= -1;
    public static final int DOWN=1;
    public static final int LEFT=2;
    public static final int RIGHT= -2;
     
    //设置两个变量来存放原来的蛇头坐标--和--键盘输入的最后一次控制蛇的方向
    private int oldDirection, newDirection;
    //这个变量用来存放蛇的尾部,当蛇吃掉食物后身体边长。则在蛇的身体添加body.addLast(oldTail),节点的位置坐标
    private Point oldTail; 
     
    //存放蛇的节点位置坐标。
    private LinkedList<Point> body = new LinkedList<Point>();
    private Set<SnakeListener> listeners = new HashSet<SnakeListener>();
     
    public boolean life;    //这个变量用来判断蛇是否死亡(结速进程)
     
    /**
     * 构造方法初始化蛇的body身体、蛇头oldDirection和newDirection运行的方向
     */
    public Snake(){
        init();
    }
    public void init(){
        //取一个节点作为蛇头的位置坐标
        int x=Global.WIDTH/2;  
        int y=Global.HEIGHt/2;
        //蛇的长度初始化为--5个节点的长度
        for(int i=0; i<5; i++){
            body.addLast(new Point(x--, y));
        }
        oldDirection = newDirection = RIGHT;    //蛇头方向初始化
        life=true//蛇是活的,
    }
     
     
    /**
     * 蛇移动
     */
    public void move(){
        System.out.println("Snake's move");
         
        //1.去尾
        oldTail=body.removeLast(); //记录每次去尾时,尾巴的x,y坐标
         
        //获取蛇的蛇头坐标想x,y
        int x = body.getFirst().x;
        int y = body.getFirst().y;
         
        //当蛇的原来方向oldDirection和键盘输入的最后一个方向newDirection不相反时,再传递蛇最新的方式值
        if(!(oldDirection + newDirection ==0)){
            oldDirection = newDirection;
        }
         
        switch(oldDirection){
        case UP:
            y--;
            if(y <0){    //使蛇在GamePanel的范围内运动
                y =Global.HEIGHt - 1;
            }
            break;
        case DOWN:
            y++;
            if( y > Global.HEIGHt-1){    //使蛇在GamePanel的范围内运动
                y = 0;
            }
            break;
        case LEFT:
            x--;
            if( x<0 ){   //使蛇在GamePanel的范围内运动
                x=Global.WIDTH-1;
            }
            break;
        case RIGHT:
            x++;
            if(x> Global.WIDTH-1){   //使蛇在GamePanel的范围内运动
                x=0;
            }
            break;
        }
        //蛇变化方向后,蛇头的坐标位置
        Point newHead = new Point(x, y);
         
        //2.加头
        body.addFirst(newHead);
         
    }
     
    /**
     * 蛇改变方向
     * @param direction
     */
    public void changeDirection(int direction){
            newDirection=direction;
    }
     
    /**
     * 蛇吃食物
     * 蛇吃到食物后身体变长
     */
    public void eatFood(){
        System.out.println("Snake's eatFood");
         
        body.addLast(oldTail); //蛇吃到食物后身体变长
         
    }
     
    /**
     * 判断蛇是否吃到了自己的身体,吃到身体蛇死亡(即结束SankeDriver线程)
     * @return
     */
    public boolean isEatBody(){
        System.out.println("Sanek's isEatBody");
         
        //i=0表示蛇头,所以i要从1,2,3。。。开始
        for(int i=1; i<body.size(); i++){
            //判断蛇头与身体的其中一个坐标是否重贴
            if(body.get(i).equals(this.getHead())){
                return true;
            }
        }
        return false;
    }
     
     
    /**
     * 绘制蛇的图像
     * @param g
     */
    public void drawMe(Graphics g){
        System.out.println("Snake's drawMe");
         
        g.setColor(Color.BLUE);     //设置蛇头颜色
        for(Point p :body){
            g.fill3DRect(p.x * Global.cell_size, p.y * Global.cell_size,
                    Global.cell_size, Global.cell_size, true);
             
            if(p==body.getFirst()){ //设置蛇的身体颜色
                g.setColor(Color.MAGENTA);
            }
        }
    }
     
    //获取蛇头方向
    public Point getHead(){
        return body.getFirst();
         
    }
     
    /**
     * 蛇死亡,即结束进程的方法
     */
    public void die(){
        life=false;
    }
     
     
     
    /**
     * SnakeDirver类,控制蛇的进程
     * @author Administrator
     *
     */
    public class SnakeDriver implements Runnable{
 
        @Override
        public void run() {
            // TODO 自动生成的方法存根
            while(life){
                move();     //蛇运动
                //绘制图像--图像显示
                for(SnakeListener l : listeners){
                    l.snakeMoved();
                }
                try {
                    //设置线程休息时间
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    // TODO 自动生成的 catch 块
                    e.printStackTrace();
                }
                System.out.println("##########################################");
            }
        }
         
    }
     
    /**
     * start()方法是启动线程的方法
     */
    public void start(){
        new Thread(new SnakeDriver()).start();
    }
     
    /**
     * 往listens中添加 Snake类、Food类、Ground类、GamePnael类的-------类地址
     * @param l
     */
    public void addSnakeListener(SnakeListener l){
        if(l != null){
            this.listeners.add(l);
        }
    }
     
}
 
2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222
package game.mysanek.entities;
 
import game.mysanek.util.Global;
 
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
 
public class Food extends Point{
     
    //设置食物的x,y坐标
    public void newFood(Point p){ //生成食物
        this.setLocation(p);        //设置食物的坐标
        System.out.println("-------------"+p);
    }
     
    //比坐标---当蛇头的坐标与食物的坐标重合,则表示食物被蛇吃掉了
    public boolean isSnakeEatFood(Snake snake){
        System.out.println("Food's isSnakeEatFood");
        return this.equals(snake.getHead());
//      return false;
    }
     
     
    /**
     * 绘制食物的图像
     * @param g
     */
    public void drawMe(Graphics g){
        System.out.println("Food's drawMe");
     
        g.setColor(Color.CYAN);
        g.fill3DRect(x*Global.cell_size, y*Global.cell_size,
                        Global.cell_size, Global.cell_size, true);
    }
 
}
 
 
333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333
 
package game.mysanek.entities;
 
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.util.Random;
 
import game.mysanek.util.Global;
 
public class Ground {
    //用一个二维数组来存放rocks(障碍物)的坐标
    //大小为GamePanel的长宽的小格子数WIDTH和HEIGHT;
    private int[][] rocks= new int[Global.WIDTH][Global.HEIGHt];
     
    public Ground(){
        for(int x=0; x<Global.WIDTH; x++){
            //第一行和最后一行---为rocks(障碍物)
            rocks[x][0]=1;                 
            rocks[x][Global.HEIGHt-1]=1;
        }
    }
     
    //随机生成---newFood()食物的x,y坐标
    //而且不能使newFood(食物)的坐标和rocks(障碍物)坐标重合
    public Point getPoint(){
        Random random =new Random();
        int x,y;
        //newFood的坐标和rocks坐标重叠,则继续生成新的坐标---直到不重合
        do{
            x=random.nextInt(Global.WIDTH);
            y=random.nextInt(Global.HEIGHt);
        }while(rocks[x][y]==1);
            return new Point(x,y);
         
    }
     
    /**
     * 蛇是否吃到石头(障碍物)
     * @param snake
     * @return
     */
    public boolean isSnakeEatRock(Snake snake){
        System.out.println("Ground's isSnakeEatRock");
         
        //判断snake(蛇)是否吃到了rocks(障碍物)
        for(int x=0; x<Global.WIDTH; x++){
            for(int y=0; y<Global.HEIGHt; y++){
                if(rocks[x][y]==1 &&
                    (x==snake.getHead().x && y==snake.getHead().y) ){//getHead()方法可以获得蛇头的坐标
                        return true;
                }
            }
        }
         
        return false;
    }
     
     
    /**
     * 当rocks[x][y]==1时,绘制石头(障碍物)
     * @param g
     */
    public void drawMe(Graphics g){
        System.out.println("Ground's drawMe");
         
        g.setColor(Color.gray);
        for(int x=0; x<Global.WIDTH; x++){
            for(int y=0; y<Global.HEIGHt; y++){
                if(rocks[x][y] ==1 ){
                    g.fill3DRect(x*Global.cell_size, y*Global.cell_size,
                                    Global.cell_size, Global.cell_size, true);
                }
            }
        }
         
    }
}
 
 
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
 
 
package game.mysanek.view;
 
import game.mysanek.entities.Food;
import game.mysanek.entities.Ground;
import game.mysanek.entities.Snake;
import game.mysanek.util.Global;
 
import java.awt.Color;
import java.awt.Graphics;
 
import javax.swing.JPanel;
 
public class GamePanel extends JPanel{
    private Snake snake;
    private Food food;
    private Ground ground;
     
     
    /**
     * 将蛇、食物、石头(障碍物)显示出来
     *snake、food、ground---传递的都是Snaek类、Food类、Ground类的***地址。
     * @param snake         传递地址
     * @param food
     * @param ground
     */
    public void display(Snake snake, Food food, Ground ground){//传递各个class的地址
        System.out.println("GamePanel's display");
        this.snake=snake;
        this.food=food;
        this.ground=ground;
         
        //绘图----调用下方的--画图功能
        this.repaint();
    }
    @Override
    protected void paintComponent(Graphics g) {
        // TODO 自动生成的方法存根
        //显示
        g.setColor(new Color(0xcfcfcf));
        //绘制一个GamePnanl大小的--矩形--遮盖掉前一个时间的蛇、食物、石头(障碍物),---相当于橡皮差
        g.fillRect(0, 0, Global.WIDTH * Global.cell_size,
                                   Global.HEIGHt *Global.cell_size);
         
        //当snake、food、ground字段----都有对应的Snake类、Food类、Ground类的地址时---画图
        if(snake != null && food != null && ground !=null){
            this.ground.drawMe(g);
            this.snake.drawMe(g);
            this.food.drawMe(g);
        }
         
    }
}
 
 
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
 
 
package game.mysanek.controller;
 
import game.mysanek.entities.Food;
import game.mysanek.entities.Ground;
import game.mysanek.entities.Snake;
import game.mysanek.listener.SnakeListener;
import game.mysanek.util.Global;
import game.mysanek.view.GamePanel;
 
import java.awt.Point;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Random;
 
public class Controller extends KeyAdapter implements SnakeListener{
     
    //------这时的snake只是个字段,它的值为--null。 没有Snake类的地址
    private Snake snake;
    private Food food;
    private Ground ground;
    private GamePanel gamePanel;
     
     
    /**
     * Controller 构造方法----传递Snaek类、Food类、Ground类、GamePanel类--的***地址。
     * @param snake
     * @param food
     * @param ground
     * @param gamePanel
     */
    public Controller(Snake snake, Food food, Ground ground, GamePanel gamePanel) {
        //传递各个class的地址
        this.snake = snake;
        this.food = food;
        this.ground = ground;
        this.gamePanel = gamePanel;
    }
 
     
    /**
     * 键盘控制-------实现键盘控制-蛇-的方向移动。
     */
    @Override
    public void keyPressed(KeyEvent e) {
        // TODO 自动生成的方法存根
        switch(e.getKeyCode()){
        case KeyEvent.VK_UP:
            snake.changeDirection(Snake.UP);
            break;
        case KeyEvent.VK_DOWN:
            snake.changeDirection(Snake.DOWN);
            break;
        case KeyEvent.VK_LEFT:
            snake.changeDirection(Snake.LEFT);
            break;
        case KeyEvent.VK_RIGHT:
            snake.changeDirection(Snake.RIGHT);
            break;
        }
    }
 
     
    /**
     * 实现SnakeLisener接口中的方法。
     */
    @Override
    public void snakeMoved() {
         
        //判断食物是否被蛇吃掉,吃掉后产生新的---新食物
        if(food.isSnakeEatFood(snake)){
            snake.eatFood();    //蛇吃掉食物
            food.newFood(ground.getPoint());    //产生新的食物
        }
         
        //判断蛇头的位置与石头的位置是否重合---蛇是否吃到石头
        if(ground.isSnakeEatRock(snake)){ 
            snake.die();    //蛇蛇死亡---结束SnakeDriver线程
        }
         
        //判断蛇是否吃到了自己的身体
        if(snake.isEatBody()){
            snake.die();    //蛇蛇死亡---结束SnakeDriver线程
        }
         
         
        //绘图-------在GamePanel的面板上绘制蛇、食物、石头(障碍物)。
        //snake、food、ground---传递的都是Snaek类、Food类、Ground类的***地址。
        gamePanel.display(snake, food, ground);//传递各个class的地址
         
    }
     
//  //随机生成---食物的x,y坐标
//  public Point getPoint(){
//      Random random =new Random();
//      int x=random.nextInt(Global.WIDTH);
//      int y=random.nextInt(Global.HEIGHt);
//      return new Point(x,y);
//  }
 
    /**
     * 将Snake类中的start()方法,放在在Controller中
     * 逻辑控制
     */
    public void newGame(){
        snake.start();
        food.newFood(ground.getPoint());
    }
 
}
 
 
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
 
 
package game.mysanek.listener;
 
/**
 * 设置一个借口----用来存放(Snake snake, Food food, Ground ground) 的类的地址
 * @author Administrator
 *
 */
public interface SnakeListener {
     
    public void snakeMoved();
}
 
 
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
 
 
package game.mysanek.util;
 
public class Global {
    //贪吃蛇中的每个小方格的边长--20
    public static final int cell_size=20;
    //设置游戏界面GameJPanel的大小
    public static final int WIDTH=40;   //宽度为40个小方格
    public static final int HEIGHt =25;     //高度为25个小方格
}
 
 
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
 
 
package game.mysanek.game;
 
import java.awt.BorderLayout;
 
import game.mysanek.controller.Controller;
import game.mysanek.entities.Food;
import game.mysanek.entities.Ground;
import game.mysanek.entities.Snake;
import game.mysanek.util.Global;
import game.mysanek.view.GamePanel;
 
import javax.swing.JFrame;
 
public class Game {
     
    public static void main(String[] args) {
        Snake snake = new Snake();
        Food food = new Food();
        Ground ground = new Ground();
        GamePanel gamePanel = new GamePanel();
         
        //传递各个class的地址
        Controller controller = new Controller(snake, food, ground, gamePanel);
         
        JFrame frame = new JFrame("贪吃蛇游戏");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        gamePanel.setSize(Global.WIDTH * Global.cell_size,
                                          Global.HEIGHt * Global.cell_size);
        frame.setSize(Global.WIDTH * Global.cell_size +10,
                                     Global.HEIGHt * Global.cell_size+35);
        frame.add(gamePanel, BorderLayout.CENTER);
        frame.setLocationRelativeTo(null);
         
        gamePanel.addKeyListener(controller);
        snake.addSnakeListener(controller);
         
        frame.addKeyListener(controller);
         
        frame.setVisible(true);
        controller.newGame();
    }
}

[代码运行效果截图]


贪吃蛇游戏


网友评论    (发表评论)

共3 条评论 1/1页

发表评论:

评论须知:

  • 1、评论每次加2分,每天上限为30;
  • 2、请文明用语,共同创建干净的技术交流环境;
  • 3、若被发现提交非法信息,评论将会被删除,并且给予扣分处理,严重者给予封号处理;
  • 4、请勿发布广告信息或其他无关评论,否则将会删除评论并扣分,严重者给予封号处理。


扫码下载

加载中,请稍后...

输入口令后可复制整站源码

加载中,请稍后...