JavaGUI简易版贪吃蛇小游戏

news/2024/11/15 1:51:09/

做这个小游戏,主要是学习一下游戏制作的基本逻辑,加深对面向对象的理解。

游戏引擎:

/*** 大牛程序员写的游戏的公共类 * 使用Game.init()方法初始化游戏* 使用Game.gameOver()方法退出游戏*/
public class Game extends JPanel {private GameEngine engine;private Graphics2D g2d;private static JFrame frame;@Overridepublic void paint(Graphics g) {super.paint(g);g2d = (Graphics2D) g;g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);engine.renderUI(g2d);}/*** 使用游戏引擎初始化游戏的方法* @param title 游戏窗体的标题* @param width 游戏窗体的宽度* @param height 游戏窗体的高度* @param engine 游戏引擎*/public static void init(String title, int width, int height, GameEngine engine){frame = new JFrame(title);Game game = new Game();game.engine = engine;game.addKeyListener(engine.listener);game.setFocusable(true);game.setPreferredSize(new Dimension(width, height));frame.add(game);frame.pack();frame.setVisible(true);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);while (true) {engine.updateLogic();game.repaint();try {Thread.sleep(Config.SLEEP_TIME);} catch (InterruptedException e) {e.printStackTrace();}}}/*** 显示退出游戏对话框的方法* @param message 对话框提示的消息* @param title 对话框提示的标题*/public static void gameOver(String message,String title) {JOptionPane.showMessageDialog(frame, message, title, JOptionPane.YES_NO_OPTION);System.exit(ABORT);}
}
/*** 由大牛程序员编写的游戏引擎的抽象模板类* 需要调用者实现两个抽象方法, 更新逻辑方法updateLogic* 更新UI方法 renderUI*/
public abstract class GameEngine {KeyListener listener;private int currentPressedKeyCode;/*** 构造方法,创建出游戏引擎*/public  GameEngine(){this.listener = new KeyListener() {@Overridepublic void keyTyped(KeyEvent e) {}@Overridepublic void keyPressed(KeyEvent e) {currentPressedKeyCode = e.getKeyCode();}@Overridepublic void keyReleased(KeyEvent e) {currentPressedKeyCode = -1;}};}/*** 获取当前用户的按键代码 按键代码的定义在KeyEvent对象中定义* @return 返回KeyEvent的按键代码*/public int getCurrentPressedKeyCode(){return  currentPressedKeyCode;}/*** 根据用户行为或者游戏的时间更新游戏的逻辑*/public abstract void updateLogic();/*** 根据用户需求更新绘制图形化界面的内容* 示例代码,绘制矩形:    g2d.fillRect(左上角x的坐标, 左上角y的坐标, 矩形的宽度, 矩形的高度);* 示例代码:绘制椭圆形:  g2d.fillOval(椭圆外包裹矩形左上角x的坐标, 椭圆外包裹矩形y的坐标, 要填充椭圆形的宽度, 要填充椭圆形的高度);* @param g2d*/public abstract void renderUI(Graphics2D g2d);
}

分析过程:

其实游戏就是逻辑判断,页面更新的死循环。

我们要做的就是继承GameEngine,实现updateLogic,renderUI方法。

一开始我们可以画上网格线,方便程序的编写。等到完成之后,将网格线去除即可。

面向对象思想(指的是程序的最小单位是对象。对象之间彼此协调,相互调用,构成了程序):

我们需要什么,我们就创建什么类:我们需要一个蛇,于是创建了一个Snake类,然后蛇又是由一个个的节点组成,于是我们又创建了Node类,以此类推,我们又创建了Apple类…

贪吃蛇的具体实现代码:

public class SnakeGameEngine extends GameEngine {Grid grid = new Grid();Snake snake = new Snake();Apple apple = new Apple();@Overridepublic void updateLogic() {boolean flag = snake.headHaveApple(apple);int keyCode = getCurrentPressedKeyCode();if (keyCode == KeyEvent.VK_RIGHT) {snake.moveRight(flag);}if (keyCode == KeyEvent.VK_LEFT) {snake.moveLeft(flag);}if (keyCode == KeyEvent.VK_UP) {snake.moveUp(flag);}if (keyCode == KeyEvent.VK_DOWN) {snake.moveDown(flag);}switch(snake.headDirection) {case Direction.RIGHT:snake.moveRight(flag);break;case Direction.LEFT:snake.moveLeft(flag);break;case Direction.UP:snake.moveUp(flag);break;case Direction.DOWN:snake.moveDown(flag);break;}}@Overridepublic void renderUI(Graphics2D g2d) {grid.draw(g2d);snake.draw(g2d);apple.draw(g2d);}
}
public class SnakeGame {public static void main(String[] args) {Game.init("贪吃蛇", Config.SCREEN_WIDTH, Config.SCREEN_HEIGHT, new SnakeGameEngine());}
}
public class Snake {LinkedList<Node> snake;int headDirection = Direction.RIGHT;public Snake() {snake = new LinkedList<Node>();snake.add(new Node(6, 4));snake.addLast(new Node(5, 4));snake.addLast(new Node(4, 4));snake.addLast(new Node(3, 4));}public void moveRight(boolean flag) {if (headDirection == Direction.LEFT) {return;}headDirection = Direction.RIGHT;Node node = new Node(snake.getFirst().x + 1, snake.getFirst().y);snake.addFirst(node);if (flag == true) {} else {snake.removeLast();}}public void moveLeft(boolean flag) {if (headDirection == Direction.RIGHT) {return;}headDirection = Direction.LEFT;Node node = new Node(snake.getFirst().x - 1, snake.getFirst().y);snake.addFirst(node);if (flag == true) {} else {snake.removeLast();}}public void moveUp(boolean flag) {if (headDirection == Direction.DOWN) {return;}headDirection = Direction.UP;Node node = new Node(snake.getFirst().x, snake.getFirst().y - 1);snake.addFirst(node);if (flag == true) {} else {snake.removeLast();}}public void moveDown(boolean flag) {if (headDirection == Direction.UP) {return;}headDirection = Direction.DOWN;Node node = new Node(snake.getFirst().x, snake.getFirst().y + 1);snake.addFirst(node);if (flag == true) {} else {snake.removeLast();}}public boolean headHaveApple(Apple apple) {if ((snake.getFirst().x == apple.getX()) && (snake.getFirst().y == apple.getY())) {apple.generateNext();return true;} else {return false;}}public void draw(Graphics2D g2d) {
//        for (Node node : snake) {
//            node.draw(g2d);
//        }g2d.drawString("蛇的长度:" + snake.size(), 50, 50);for (int i = 0; i < snake.size(); i ++ ) {if (i == 0) {g2d.setColor(Color.GREEN);} else {g2d.setColor(Color.BLACK);}snake.get(i).draw(g2d);}}
}
public class Config {public static final boolean DEBUG_FLAG = false;public static final int SCREEN_WIDTH = 1000;public static final int SCREEN_HEIGHT = 900;public static final int GRID_SiZE = 20;public static final int COLOUM = SCREEN_WIDTH / GRID_SiZE;public static final int ROW = SCREEN_HEIGHT / GRID_SiZE;public static final int SLEEP_TIME = 50;
}
apublic class Grid {int x1;int y1;int x2;int y2;public void draw(Graphics2D g2d) {if (Config.DEBUG_FLAG == true) {for (int i = 0; i < Config.ROW; i ++ ) {g2d.drawLine(0, Config.GRID_SiZE * i, Config.SCREEN_WIDTH, Config.GRID_SiZE * i);}for (int i = 0; i < Config.COLOUM; i ++ ) {g2d.drawLine(Config.GRID_SiZE * i, 0, Config.GRID_SiZE * i,Config.SCREEN_HEIGHT);}}}
}
public class Node {int x;int y;public Node(int x, int y) {this.x = x;this.y = y;}public void draw(Graphics2D g2d) {g2d.fillRect(x * Config.GRID_SiZE, y * Config.GRID_SiZE, Config.GRID_SiZE,Config.GRID_SiZE);}
}
public class Direction {public static final int UP = 1;public static final int DOWN = 2;public static final int LEFT = 3;public static final int RIGHT = 4;
}
public class Apple {Random random = new Random();Node apple;public Apple() {apple = new Node(random.nextInt(Config.COLOUM), random.nextInt(Config.ROW));}public int getX() {return apple.x;}public int getY() {return apple.y;}public void draw(Graphics2D g2d) {g2d.setColor(Color.RED);apple.draw(g2d);g2d.setColor(Color.BLACK);}public void generateNext() {apple = new Node(random.nextInt(Config.COLOUM), random.nextInt(Config.ROW));}
}

最终效果:

在这里插入图片描述

做的很简易,还有很多不足:

蛇不能超过屏幕的范围

地图添加障碍物

添加游戏关卡,蛇移动的速度越来越快

等等…


http://www.ppmy.cn/news/599779.html

相关文章

Dev-C++5.11游戏创作之贪吃蛇

各位朋友们好啊&#xff01;今天我为大家带来一个贪吃蛇游戏进阶版&#xff01; 如果点赞超过15个&#xff0c;1小时内立马更新哦&#xff01; em…音乐我就不说了&#xff0c;没有看过的小伙伴们可以在我的专栏里面看一看之前的飞机大战和自制金山打字通 OK&#xff01;上代…

Python版水果忍者源代码

切水果风靡一时的游戏&#xff0c;不知道为啥总是切刀炸掉&#xff0c;挺解压的游戏。完整程序包请在文末地址下载 主要程序 import pygame, sys import os import randomplayer_lives 3 #keep track of lives score 0 …

《游戏学习》| 水果忍者HTML5网页版在线游戏 | 源码分析

游戏介绍 这是一款由百度JS小组提供的HTML5版切水果游戏&#xff0c;这款基于HTML5实现的网页版切水果游戏虽然和原版的切水果游戏相比仍有美中不足之处&#xff0c;但也算有声有色&#xff0c;画面效果也十分炫目华丽。 游戏截图 主界面 游戏界面 结束界面 游戏目录 除了i…

Fruit Ninja(水果忍者)游戏源码 cocos2d

cocos2dx 实现的 风靡一时的智能机游戏 水果忍者 游戏《水果忍者》完整游戏源码&#xff0c;Android windows ios多平台编译运行 100%完整代码,源码编译 无bug运行 酷炫的梅花剑法(可以自己修改源码DIY 设计其他剑法) 冰冻技能 狂乱技能 双倍狂乱技能 普通模式 下载地址: 点我…

基于Cocos Creator的水果忍者游戏

基于cocos creater的水果忍者游戏 项目介绍主界面游戏界面游戏详情界面水果运动界面刀片切割界面游戏结束界面下载方式 项目介绍 互联网技术不断革新&#xff0c;用户对于应用的要求在不断提高&#xff0c;使得技术标准也在不断进步。JavaScript的产生使得互联网有了很大进步&…

2017级C语言大作业 - 水果忍者

水果忍者 C语言作业 分享17级同学大一上学期用C语言实现的水果忍者。分步骤代码、图片音乐素材、可执行程序可从百度网盘下载&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1i-e_MVChl4fIUSiPBnNp-Q 提取码&#xff1a;67lj 设计思路 我们小组经过在4399网站上试玩游戏…

Scratch少儿编程案例-水果忍者-简约风

专栏分享 点击跳转=>Unity3D特效百例点击跳转=>案例项目实战源码点击跳转=>游戏脚本-辅助自动化点击跳转=>Android控件全解手册点击跳转=>Scratch编程案例👉关于作者

HTML5 水果忍者游戏

HTML5 实现水果忍者小游戏 相信大家对于水果忍者这款游戏肯定不陌生&#xff0c;在几年前的移动端手机上随处可见到处切水果的身影 那我们现在就来了解一下PC端的水果忍者是怎么编写的 一、代码结构 图片归图片、音效和背景音乐放一起 二、HTML页面代码 主页面的代码很简单…