码迷,mamicode.com
首页 > 编程语言 > 详细

Java小游戏实战开发——贪吃蛇小游戏

时间:2021-06-18 20:09:10      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:resizable   时间   keyevent   over   gety   turn   定时器   就是   clear   

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

 

Java小游戏实战开发——贪吃蛇小游戏

标签:resizable   时间   keyevent   over   gety   turn   定时器   就是   clear   

原文地址:https://www.cnblogs.com/heyu123/p/14899951.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!