欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JAVA贪吃蛇游戏2.0版本

程序员文章站 2023-12-23 19:51:27
...
package com.test;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Panel;
import java.awt.Point;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Random;

public class SnakeGameFrame {
    public static void main(String[] args){
        new SnakeGameFrame();
    }

    public SnakeGameFrame(){
        Frame app=new Frame("贪吃蛇");
        app.addWindowListener(new WindowAdapter(){
            @Override
            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();
    }
}

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.height));
        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.height));
            if (snk.length < Snake.MAXLENGTH) {
                snk.length++;
            }
        }
    }

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


class Snake{
    GamePanel gamePanel;
    private Point[] body;
    public static final int MAXLENGTH=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){
        gamePanel=gp;
        body=new Point[MAXLENGTH];
        head=-1;
        tail=-1;
        length=1;
        speed=10;
        diameter=10;
    }

    public void update() {


        int direction=gamePanel.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 > gamePanel.width) {
            x = -diameter;
        }
        if (y > gamePanel.height) {
            y = -diameter;
        }
        if (x < -diameter) {
            x = gamePanel.width;
        }
        if (y < -diameter) {
            y = gamePanel.height;
        }

        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);
    }
}


class GamePanel extends Panel implements Runnable,KeyListener{
    private static final long serialVersionUID = 1L;
    public int width;
    public int height;
    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 NORTH=0;
    public static final int SOUTH=1;
    public static final int WEST=2;
    public static final int EAST=3;
    private Snake sk;
    private Food fd;

    public GamePanel(){
        width=300;
        height=300;
        setPreferredSize(new Dimension(width,height));
        sk=new Snake(this);
        fd=new Food(this,sk);
        setFocusable(true);
        requestFocus();
        addKeyListener(this);
    }

    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, height);
            if (im == null) {
                System.out.println("im is null");
            } else {
                dbg = im.getGraphics();
            }
        }

        dbg.setColor(Color.white);
        dbg.fillRect(0, 0, width, height);
        sk.draw(dbg);
        fd.draw(dbg);
        //  line.draw(dbg);
    }

    public void gameUpdate() {

        if (!isPaused) {
            sk.update();
            fd.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) {
    }
    public int getDirection() {
        return direction;
    }
}

JAVA贪吃蛇游戏2.0版本

相关标签: Java项目

上一篇:

下一篇: