Java贪吃蛇游戏

在这里插入图片描述
Food.java


import java.awt.*;
import java.util.Random;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
/**
 *
 * @author new
 */
public class Food {

    public Point location;
    public Point size;
    private GamePanel gameP;
    private Snake snk;
    private Random rand;

    public Food(GamePanel gp, Snake sk) {
        gameP = gp;
        snk = sk;
        rand = new Random();
        location = new Point(Math.abs(rand.nextInt() % gameP.width), Math.abs(rand.nextInt() % gameP.heigth));
        size = new Point(sk.diameter, sk.diameter);
    }

    public void update() {
        if ((Math.abs((snk.x + snk.diameter / 2) - (location.x + size.x / 2)) < snk.diameter) &&
                (Math.abs((snk.y + snk.diameter / 2) - (location.y + size.y / 2)) < snk.diameter)) {
            location = new Point(Math.abs(rand.nextInt() % gameP.width), Math.abs(rand.nextInt() % gameP.heigth));
            if (snk.length < Snake.MAXLENTH) {
                snk.length++;
            }
        }
    }

    public void draw(Graphics g) {
        g.setColor(Color.black);
        g.fillRect(location.x, location.y, size.x, size.y);
    }
}

Snake.java


import java.awt.*;


/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
/**
 *
 * @author new
 */
public class Snake {

    GamePanel gameP;
    private Point[] body;
    public static final int MAXLENTH = 20;
    private int head;
    private int tail;
    public int length;
    private int speed;
    public int x;
    public int y;
    public int diameter;

    public Snake(GamePanel gp) {
        gameP = gp;
        body = new Point[MAXLENTH];
        head = -1;
        tail = -1;
        length = 1;
        speed = 10;
        x = 50;
        y = 50;
        diameter = 10;
    }

    public void update() {


        int direction=gameP.getDirection();
        switch (direction) {
            case GamePanel.SOUTH:
                y += speed;
                break;
            case GamePanel.NORTH:
                y -= speed;
                break;
            case GamePanel.EAST:
                x += speed;
                break;
            case GamePanel.WEST:
                x -= speed;
                break;
        }

        if (x > gameP.width) {
            x = -diameter;
        }
        if (y > gameP.heigth) {
            y = -diameter;
        }
        if (x < -diameter) {
            x = gameP.width;
        }
        if (y < -diameter) {
            y = gameP.heigth;
        }

        head = (head + 1) % body.length;

        tail = (head + body.length - length + 1) % body.length;

        body[head] = new Point(x, y);

    }

    public void draw(Graphics g) {
        g.setColor(Color.blue);
        if (length > 1) {
            int i = tail;
            while (i != head) {
                g.fillOval(body[i].x, body[i].y, diameter, diameter);
                i = (i + 1) % body.length;
            }
        }

        g.setColor(Color.red);
        g.fillOval(body[head].x, body[head].y, diameter, diameter);
    }
}

GamePanel.java

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

import java.awt.*;
import java.awt.event.*;


/**
 *
 * @author Administrator
 */
public class GamePanel extends Panel implements Runnable, KeyListener{


    public int width;
    public int heigth;
    public int incre=1;
    private Image im;
    private Graphics dbg;
    private Thread gamethread;
    private static final int FPS = 30;
    private boolean running = false;
    private boolean isPaused = false;
    private int direction;
    public static final int SOUTH = 0;
    public static final int NORTH = 1;
    public static final int EAST = 2;
    public static final int WEST = 3;
    private Snake sk;
    private Food bk;

    public GamePanel() {

        width = 300;
        heigth = 300;
        setPreferredSize(new Dimension(width, heigth));

        sk = new Snake(this);
        bk = new Food(this, sk);

        setFocusable(true);
        requestFocus();
        addKeyListener(this);
    }

    public int getDirection() {
        return direction;
    }

    public void gameStart() {
        if (!running) {
            gamethread = new Thread(this);
            gamethread.start();
        }
    }

    public void gameStop() {
        running = false;
    }

    public void gamePaint() {
        Graphics g;
        try {
            g = this.getGraphics();
            if (g != null && im != null) {
                g.drawImage(im, 0, 0, null);
            }
            g.dispose();
        } catch (Exception e) {
        }
    }

    public void gameRender() {
        if (im == null) {
            im = createImage(width, heigth);
            if (im == null) {
                System.out.println("im is null");
            } else {
                dbg = im.getGraphics();
            }
        }

        dbg.setColor(Color.white);
        dbg.fillRect(0, 0, width, heigth);
        sk.draw(dbg);
        bk.draw(dbg);

    }

    public void gameUpdate() {

        if (!isPaused) {
            sk.update();
            bk.update();

        }
    }

    public void run() {
        long t1,t2,dt,sleepTime;  
        long period=1000/FPS;  //计算每一次循环需要的执行时间,单位毫秒
        t1=System.nanoTime();  //保存游戏循环执行前的系统时间,单位纳秒
          
        while(true){
           gameUpdate();
           gameRender();
           gamePaint();
           t2= System.nanoTime() ; //游戏循环执行后的系统时间,单位纳秒
           dt=(t2-t1)/1000000L;  //本次循环实际花费的时间,并转换为毫秒
           sleepTime = period - dt;//计算本次循环剩余的时间,单位毫秒
           if(sleepTime<=0)        //防止sleepTime值为负数
                 sleepTime=2;
           try {     
           Thread.sleep(sleepTime); //让线程休眠,由sleepTime值决定
          } catch (InterruptedException ex) { }
             t1 = System.nanoTime();  //重新获取当前系统时间
        }
    }

    public void keyTyped(KeyEvent e) {
    }

    public void keyPressed(KeyEvent e) {
        int keycode = e.getKeyCode();

        if (keycode == KeyEvent.VK_P) {
            isPaused = !isPaused;
            System.out.println("key is P");
        }

        if (!isPaused ) {
            switch (keycode) {

                case KeyEvent.VK_DOWN:
                    direction = SOUTH;
                    System.out.println("key is down" + direction);
                    break;
                case KeyEvent.VK_UP:
                    direction = NORTH;
                    System.out.println("key is up" + direction);
                    break;
                case KeyEvent.VK_RIGHT:
                    direction = EAST;
                    System.out.println("key is right" + direction);
                    break;
                case KeyEvent.VK_LEFT:
                    direction = WEST;
                    System.out.println("key is left" + direction);
                    break;
            }
        }
    }

    public void keyReleased(KeyEvent e) {
    }
}


GameFrame.java

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author Administrator
 */
import java.awt.*;
import java.awt.event.*;

public class GameFrame {

    public GameFrame() {
        Frame app = new Frame("GameFrame");

        app.addWindowListener(new WindowAdapter() {

            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        app.setLocation(100, 100);
        GamePanel drawB = new GamePanel();
        app.add(drawB, BorderLayout.CENTER);

        app.pack();
        app.setResizable(false);
        app.setVisible(true);
        drawB.gameStart();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        new GameFrame();
    // TODO code application logic here
    }
}
可以运行! (以下代码只是其中的一个类) package chy.snake.entities; import java.awt.Color; import java.awt.Graphics; import java.awt.Point; import java.util.HashSet; import java.util.LinkedList; import java.util.Set; import chy.snake.listener.SnakeListener; import chy.snake.util.Global; 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; //newDirection:一次时间 间隔内输入的最后方向 private Point oldTail; private boolean life; //life 为 true或者false,初始为true, 用于118行 private LinkedList<Point> body = new LinkedList<Point> (); //需要经常访问蛇的第一个和最后一个节点,使用链表LinkedList存放蛇的身体节点,因为它有getFirst(),getLast(),removeLast(),方法 private Set<SnakeListener> listeners = new HashSet<SnakeListener>(); public Snake(){ init(); } public void init(){ //初始化 int x = Global.WIDTH/2; int y = Global.HEIGHT/2; for(int i=0;i<3;i++){ //初始长度3 body.addLast(new Point(x-i,y)); //是addLast } oldDirection = newDirection = right; //初始方向 右 life = true; } public void die(){ life = false; } public void move(){ System.out.println("Snake's move"); if (!(oldDirection + newDirection == 0)){ oldDirection = newDirection; } //1.去尾 oldTail = body.removeLast(); int x = body.getFirst().x; int y = body.getFirst().y; //蛇头的x,y坐标 switch(oldDirection){ case up: y--; break; case down: y++; break; case left: x--; break; case right: x++; break; } Point newHead = new Point(x,y); //2.加头 body.addFirst(newHead); } public void changeDirection(int direction){ /*无效方向:在蛇的这一次移动之后和下一次移动之前的 这个时间间隔内输入了多个方向,只有最后一个方向 是 有效方向,其余的都为无效方向*/ System.out.println("Snake's changeDirection"); newDirection = direction; //将一个时间间隔内按得最后方向,赋给 newDirection } public void eatFood(){ System.out.println("Snake's eatFood"); body.addLast(oldTail); //后面的节点不去掉 } public boolean isEatFood(){ System.out.println("Snake's isEatFood"); return false; } public boolean isEatBody(Snake snake){ //比较蛇是否吃到身体 System.out.println("snake's isEatBody"); for(int i= 1;i<body.size();i++){ //i 从蛇头结点的下一个节点开始,排除蛇头结点 if(body.get(i).equals(this.getHead())){ //如果i 的节点 和 头结点 相同 return true; } } return false; } public void drawMe(Graphics g){ System.out.println("Snake's drawMe"); g.setColor(Color.GREEN); //设置蛇的颜色 for(Point p : body){ g.fill3DRect(p.x * Global.CELL_SIZE, p.y * Global.CELL_SIZE, Global.CELL_SIZE, Global.CELL_SIZE, true); } } public Point getHead(){ //得到蛇头节点,判断吃食物 return body.getFirst(); } private class SnakeDriver implements Runnable{ //线程,不停的调用move方法 @Override public void run() { // TODO 自动生成的方法存根 while(life){ // 42和46行,life为true 或者false move(); for(SnakeListener l : listeners){ l.snakeMoved(Snake.this); //循环,依次调用SnakeMoved方法 } try { Thread.sleep(300); } catch (InterruptedException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } } } } public void start(){ new Thread(new SnakeDriver()).start(); //启动线程的方法 } public void addSnakeListener(SnakeListener l){ if(l != null){ this.listeners.add(l); } } }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值