1. 程式人生 > 其它 >Java小遊戲實戰開發——貪吃蛇小遊戲

Java小遊戲實戰開發——貪吃蛇小遊戲

Java小遊戲實戰開發——貪吃蛇小遊戲1、Direction類。

Direction:用於存放上下左右四個鍵。

package com.games;

/*
 *列舉:就是幾個固定的常量
 */
public enum  Direction{
    UP,DOWN,LEFT,RIGHT
 }

2、Snake類

Snake,蛇類:一條蛇有多個節點,使用LinkedList集合出儲存Node節點
初始化蛇身體,蛇出生地有6個節點

package com.games;

import java.util.LinkedList;

/**
 *Snake類表示蛇
 * 一條蛇有多個節點,使用LinkedList集合儲存Node節點
 * 蛇出生的地方有6個節點
 
*/ public class Snake { //蛇的身體 private LinkedList<Node> body; //蛇的運動方向 private Direction direction = Direction.LEFT; //蛇是否活著 private boolean isLiving = true; //構造方法,在創造Snake物件時執行 public Snake(){ //初始化蛇身體 initSnake(); } //初始化蛇身體 private void initSnake(){
//建立集合 body= new LinkedList<>(); //建立6個節點放在集合中 body.add(new Node(16,20)); body.add(new Node(17,20)); body.add(new Node(18,20)); body.add(new Node(19,20)); body.add(new Node(20,20)); body.add(new Node(21,20)); } //蛇會沿著蛇頭的方向移動 //控制蛇移動:在蛇頭的運動方向新增一個節點,然後把蛇尾的最後一個節點刪除
public void move(){ if(isLiving) { //獲取蛇頭 Node head = body.getFirst(); switch (direction) { case UP: //在蛇頭上邊頭新增節點 body.addFirst(new Node(head.getX(), head.getY() - 1)); break; case DOWN: body.addFirst(new Node(head.getX(), head.getY() + 1)); break; case LEFT: body.addFirst(new Node(head.getX() - 1, head.getY())); break; case RIGHT: body.addFirst(new Node(head.getX() + 1, head.getY())); break; } //刪除蛇尾的最後節點 body.removeLast(); //判斷蛇是否撞牆 head = body.getFirst(); if(head.getX() < 0 || head.getY() < 0 || head.getX() >= 40 || head.getY() >= 40){ isLiving = false; } //判斷蛇是否碰到自己的身體 for(int i = 1; i < body.size(); i++){ Node node = body.get(i); if(head.getX() == node.getX() && head.getY() == node.getY()){ isLiving = false; } } } } public LinkedList<Node> getBody() { return body; } public void setBody(LinkedList<Node> body) { this.body = body; } public Direction getDirection() { return direction; } public void setDirection(Direction direction) { this.direction = direction; } //吃食物;沿著蛇頭的移動方向新增一個節點 public void eat(Node food){ //獲取蛇頭 Node head = body.getFirst(); switch (direction) { case UP: //在蛇頭上邊頭新增節點 body.addFirst(new Node(head.getX(), head.getY() - 1)); break; case DOWN: body.addFirst(new Node(head.getX(), head.getY() + 1)); break; case LEFT: body.addFirst(new Node(head.getX() - 1, head.getY())); break; case RIGHT: body.addFirst(new Node(head.getX() + 1, head.getY())); break; } } }

3、Node類

節點類:每一條蛇是由若干個節點組成的,每一個節點有橫縱座標來確定位置

package com.games;

import java.util.Random;

/**
 *節點類:每一條蛇是由若干個節點組成的,每一個節點有橫縱座標來確定位置
 */
public class Node {
    private int x;
    private int y;

    public Node(){

    }

    public Node(int x,int y){
        this.x = x;
        this.y = y;
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

    //隨機生成位置
    public void random(){
        //建立Random物件
        Random r = new Random();
        //隨機生成橫座標
        this.x = r.nextInt(40);
        //隨機生成縱座標
        this.y = r.nextInt(40);
    }
}

4、MainFrame類
實現:
(1)initFrame()方法:初始化窗體引數;設定窗體寬高、窗體預設位置、關閉按鈕的作用和窗體大小不可變。
(2)initGamePanel()方法:繼承JPanel()類,重寫paint()方法,初始化遊戲棋盤,在paint()方法中繪製棋盤中的內容,即清空棋盤、繪製橫豎線條、繪製蛇和食物,最後把棋盤新增到窗體中。
(3)initSnake()方法:初始化蛇;建立Snake類,在Snake類中初始化蛇的初始位置、構造move()方法和eat()方法。move()方法實現蛇沿著蛇頭方向移動、判斷蛇是否撞牆和碰到自己身體的功能;eat()方法實現當食物與蛇頭重合,會沿蛇頭的移動方向新增一個節點。。
(4)initFood()方法:初始化食物;建立Node類,在Node類中用隨機數實現食物位置的隨機生成。
(5)initTimer()方法:初始化定時器;設定定時任務,根據遊戲狀態和direction變數設定蛇移動操作,進行食物判定,判斷食物與蛇頭是否重合,如果重合呼叫eat()方法並再次隨機生成食物。使用定時器,呼叫repaint()方法實時更新介面。
(6)setKeyListener()方法:設定鍵盤監聽,當鍵盤按下時,呼叫keyPressed(KeyEvent e)方法,獲取鍵盤輸入,根據鍵盤輸入讓蛇隨著Direction方向移動。
程式碼如下:

package com.games;

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Timer;
import java.util.LinkedList;
import java.util.TimerTask;

public class MainFrame extends JFrame {
    //
    private Snake snake;
    //遊戲棋盤
    private JPanel jPanel;
    //定時器,在規定時間內呼叫蛇移動的方法
    private Timer timer;
    //食物
    private Node food;

    public MainFrame() throws HeadlessException {
        //初始化窗體引數
        initFrame();
        //初始化遊戲棋盤
        initGamePanel();
        //初始化蛇
        initSnake();
        //初始化食物
        initFood();
        //初始化定時器
        initTimer();
        //設定鍵盤監聽,讓蛇隨著上下左右方向移動
        setKeyListener();
    }

    private void initFood(){
        food = new Node();
        food.random();
    }

    private void setKeyListener(){
        addKeyListener(new KeyAdapter() {
            //當鍵盤按下時,會自動呼叫此方法
            @Override
            public void keyPressed(KeyEvent e) {
                //鍵盤中的每一個鍵都有一個自己的編號
                switch (e.getKeyCode()){
                    case KeyEvent.VK_UP://上鍵
                        if(snake.getDirection() != Direction.DOWN){
                            //修改蛇的運動方向
                            snake.setDirection(Direction.UP);
                        }
                        break;
                    case KeyEvent.VK_DOWN://下鍵
                        if(snake.getDirection() != Direction.UP){
                            snake.setDirection(Direction.DOWN);
                        }
                        break;
                    case KeyEvent.VK_LEFT://左鍵
                        if(snake.getDirection() != Direction.RIGHT){
                            snake.setDirection(Direction.LEFT);
                        }
                        break;
                    case KeyEvent.VK_RIGHT://右鍵
                        if(snake.getDirection() != Direction.LEFT){
                            snake.setDirection(Direction.RIGHT);
                        }
                        break;
                }
            }
        });
    }

    private void initTimer(){
        timer = new Timer();

        TimerTask timerTask = new TimerTask() {
            @Override
            public void run() {
                snake.move();
                //判斷食物與蛇頭是否重合
                Node head = snake.getBody().getFirst();
                if(head.getX() == food.getX() && head.getY() == food.getY()){
                    snake.eat(food);
                    food.random();
                }
                //重繪遊戲棋盤
                jPanel.repaint();
            }
        };

        //每100毫秒,執行一次定時任務
        //蛇的移動速度,如果想改變移動速度,改變最後一個引數即可
        timer.scheduleAtFixedRate(timerTask,0,200);
    }

    private void initSnake(){
        snake = new Snake();
    }

    public void initGamePanel(){
         jPanel = new JPanel(){

            //繪製棋盤中的內容
            public void paint(Graphics g){
                //清空棋盤
                g.clearRect(0,0,600,600);

                //Graphics g    可以看做是一個畫筆,提供了很多方法可以來繪製一些基本圖形(直線、矩形)
                //繪製40條橫線
                for(int i = 0;i <= 40; i++){
                    g.drawLine(0,i*15,600,i*15);
                }

                //繪製40條豎線
                for(int i = 0; i <= 40; i++){
                    g.drawLine(i*15,0,i*15,600);
                }

                //繪製蛇
                LinkedList<Node> body = snake.getBody();
                for(Node node : body){
                    g.fillRect(node.getX()*15,node.getY()*15,15,15);
                }

                //繪製食物
                g.fillRect(food.getX()*15,food.getY()*15,15,15);

            }

        };

        //把棋盤新增到窗體中
        add(jPanel);

    }

    //初始化窗體引數
    public void initFrame(){
        //設定窗體寬高
        setSize(610,640);
        //設定窗體預設位置
        setLocation(408,408);
        //設定關閉按鈕的作用
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //設定窗體大小不可變
        setResizable(false);
    }

    public static void main(String[] args) {
        //建立窗體物件,並顯示
        new MainFrame().setVisible(true);
    }
}