Java GUI编程之贪吃蛇游戏简单实现方法【附demo源码下载】
本文实例讲述了Java GUI编程之贪吃蛇游戏简单实现方法。分享给大家供大家参考,具体如下:
例子简单,界面简陋 请见谅
项目结构如下
Constant.jvava 代码如下:
package snake; /** * * @author hjn * */ public class Constant { /** * 蛇方移动方向:左边 */ public static final int LEFT = 0; /** * 蛇方移动方向:右边 */ public static final int RIGHT = 1; /** * 蛇方移动方向:上边 */ public static final int UP = 3; /** * 蛇方移动方向:下边 */ public static final int DOWN = 4; /** * 界面列数 */ public static final int COLS = 30; /** * 界面行数 */ public static final int ROWS = 30; /** * 每个格子边长 */ public static final int BODER_SIZE = 15; }
Node.java代码如下:
package snake; /** * 格子 * * @author hjn * */ public class Node { /** * 所在行数 */ private int row; /** * 所在列数 */ private int col; public Node() { }; public Node(int row, int col) { this.row = row; this.col = col; }; /** * 蛇将要移动一格时头部格子将所到格子 * * @param dir * 蛇前进方向 * @param node * 蛇头所在的格子 */ public Node(int dir, Node node) { if (dir == Constant.LEFT) { this.col = node.getCol() - 1; this.row = node.getRow(); } else if (dir == Constant.RIGHT) { this.col = node.getCol() + 1; this.row = node.getRow(); } else if (dir == Constant.UP) { this.row = node.getRow() - 1; this.col = node.getCol(); } else { this.row = node.getRow() + 1; this.col = node.getCol(); } } /** * 重写equals方法 */ public boolean equals(Object obj) { if (obj instanceof Node) { Node node = (Node) obj; if (this.col == node.col && this.row == node.row) { return true; } else { return false; } } else { return false; } } public int getRow() { return row; } public void setRow(int row) { this.row = row; } public int getCol() { return col; } public void setCol(int col) { this.col = col; } public String toString() { return "col:" + this.col + " row:" + this.row; } }
Egg.java代码如下:
package snake; import java.awt.Color; import java.awt.Graphics; import java.util.Random; /** * 蛋,蛇的食物 * * @author Nan * */ public class Egg extends Node { /** * 蛋的颜色 */ Color color; /** * 随机函数 */ public static Random random = new Random(); /** * 构造函数 蛋出现在固定位置 * * @param row * 所在第几行数 * @param col * 所在第几列数 */ public Egg(int row, int col) { super(row, col); this.color = Color.green; } /** * 构造函数 蛋随机出现 * */ public Egg() { super(); int col = random.nextInt(Constant.COLS - 4) + 2; int row = random.nextInt(Constant.ROWS - 4) + 2; this.setCol(col); this.setRow(row); } /** * 画蛋 * @param g 画笔 */ void draw(Graphics g) { if (this.color == Color.green) { this.color = Color.red; } else { this.color = Color.green; } g.setColor(this.color); int boderSize = Constant.BODER_SIZE; g.fillOval(this.getCol() * boderSize, this.getRow() * boderSize, boderSize, boderSize); } public Color getColor() { return color; } public void setColor(Color color) { this.color = color; } }
Snake.java代码如下:
package snake; import java.awt.Color; import java.awt.Graphics; import java.awt.event.KeyEvent; import java.util.ArrayList; import java.util.List; /** * 蛇 * * @author hjn * */ public class Snake { /** * 前进的方向 */ int dir; /** * 蛇的身体,由一个格子Node集合组成 */ List<Node> nodeList = new ArrayList<Node>(); /** * 是否越界 */ boolean isOverstep = false; /** * 构造方法默认开始方向向左 ,蛇身有3个格子 ,位置在20行,15列 */ public Snake() { this.dir = Constant.LEFT; for (int i = 0; i < 3; i++) { Node node = new Node(20, 15 + i); this.nodeList.add(node); } } /** * 蛇前进 */ void forward() { addNode(); nodeList.remove(nodeList.size() - 1); } /** * 蛇前进的时候头部增加格子,私有方法 */ private void addNode() { Node node = nodeList.get(0); node = new Node(dir, node); nodeList.add(0, node); } /** * 是否吃到蛋,蛇身是否有格子跟蛋重叠,所以重写了Node的equals方法 * * @param egg蛋 * @return boolean */ boolean eatEgg(Egg egg) { if (nodeList.contains(egg)) { addNode(); return true; } else { return false; } } /** * 画自己 * * @param g画笔 */ void draw(Graphics g) { g.setColor(Color.black); for (int i = 0; i < this.nodeList.size(); i++) { Node node = this.nodeList.get(i); if (node.getCol() > (Constant.COLS - 2) || node.getCol() < 2 || node.getRow() > (Constant.ROWS - 2) || node.getRow() < 2) { this.isOverstep = true; } g.fillRect(node.getCol() * Constant.BODER_SIZE, node.getRow() * Constant.BODER_SIZE, Constant.BODER_SIZE, Constant.BODER_SIZE); } forward(); } /** * 键盘事件,来确定前进方向,有左右上下4个方向 * * @param e键盘监听事件 */ void keyPress(KeyEvent e) { int key = e.getKeyCode(); switch (key) { case KeyEvent.VK_LEFT: if (this.dir != Constant.LEFT) this.dir = Constant.LEFT; break; case KeyEvent.VK_RIGHT: if (this.dir != Constant.RIGHT) this.dir = Constant.RIGHT; break; case KeyEvent.VK_UP: if (this.dir != Constant.UP) this.dir = Constant.UP; break; case KeyEvent.VK_DOWN: if (this.dir != Constant.DOWN) this.dir = Constant.DOWN; break; default: break; } } public int getDir() { return dir; } public void setDir(int dir) { this.dir = dir; } public List<Node> getNodeList() { return nodeList; } public void setNodeList(List<Node> nodeList) { this.nodeList = nodeList; } public boolean isOverstep() { return isOverstep; } public void setOverstep(boolean isOverstep) { this.isOverstep = isOverstep; } }
主界面MainFrame.java代码如下:
package snake; import java.awt.Color; import java.awt.Font; import java.awt.Frame; import java.awt.Graphics; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; /** * 贪吃蛇展示页面 * * @author hjn * */ public class MainFrame extends Frame { /** * 版本 */ private static final long serialVersionUID = -5227266702753583633L; /** * 背景颜色 */ Color color = Color.gray; /** * 蛋 */ static Egg egg = new Egg(); /** * 蛇 */ Snake snake = new Snake(); /** * 游戏是否失败 */ boolean gameOver = false; /** * 给画笔起一个线程 */ PaintThread paintThread = new PaintThread(); /** * 构造方法 */ public MainFrame() { init(); } /** * 界面初始化 */ void init() { this.setBounds(200, 200, Constant.COLS * Constant.BODER_SIZE, Constant.ROWS * Constant.BODER_SIZE); this.setResizable(true); this.repaint(); /** * 窗口关闭监听事件 */ this.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { System.exit(0); } }); /** * 添加键盘监听事件 */ this.addKeyListener(new KeyMomiter()); /** * 画笔线程启动 */ new Thread(paintThread).start(); } /** * 画笔画界面 */ public void paint(Graphics g) { Color c = g.getColor(); g.setColor(Color.GRAY); g.fillRect(0, 0, Constant.COLS * Constant.BODER_SIZE, Constant.ROWS * Constant.BODER_SIZE); g.setColor(Color.DARK_GRAY); for (int i = 0; i < Constant.ROWS; i++) { g.drawLine(0, i * Constant.BODER_SIZE, Constant.COLS * Constant.BODER_SIZE, i * Constant.BODER_SIZE); } for (int i = 0; i < Constant.COLS; i++) { g.drawLine(i * Constant.BODER_SIZE, 0, i * Constant.BODER_SIZE, Constant.ROWS * Constant.BODER_SIZE); } g.setColor(Color.yellow); g.setFont(new Font("宋体", Font.BOLD, 20)); g.drawString("score:" + getScore(), 10, 60); if (gameOver) { g.setColor(Color.red); g.drawString("GAME OVER", 100, 60); this.paintThread.pause = true; } g.setColor(c); if (snake.eatEgg(egg)) { egg = new Egg(); } snake.draw(g); egg.draw(g); } /** * 获取分数 * * @return int 分数 */ int getScore() { return snake.getNodeList().size(); } /** * 画笔的线程 * * @author hjn */ class PaintThread implements Runnable { private boolean isRun = true; private boolean pause = false; @Override public void run() { while (isRun) { if (pause) { continue; } else { if (snake.isOverstep == true) { gameOver = true; } repaint(); } try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } } /** * 暂停 */ public void pause() { this.pause = true; } /** * 重新开始 */ public void restart() { this.pause = true; snake = new Snake(); } /** * 游戏结束 */ public void gameOver() { isRun = false; } } /** * 停止 */ void stop() { gameOver = true; } /** * 键盘监听器 * * @author hjn * */ class KeyMomiter extends KeyAdapter { @Override public void keyPressed(KeyEvent e) { super.keyPressed(e); int key = e.getKeyCode(); if (key == KeyEvent.VK_F2) { paintThread.restart(); } else { snake.keyPress(e); } } } /** * 启动程序入口 * * @param args */ @SuppressWarnings("deprecation") public static void main(String[] args) { MainFrame mainFrame = new MainFrame(); mainFrame.show(); } }
运行效果:
附:完整实例代码点击此处本站下载。
更多关于java算法相关内容感兴趣的读者可查看本站专题:《Java数据结构与算法教程》、《Java字符与字符串操作技巧总结》、《Java操作DOM节点技巧总结》、《Java文件与目录操作技巧汇总》和《Java缓存操作技巧汇总》
希望本文所述对大家java程序设计有所帮助。
相关文章
细说Springcloud eureka的几种主动下线服务的方式
这篇文章主要介绍了细说Springcloud eureka的几种主动下线服务的方式,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧2018-09-09Spring Boot 整合 Apache Dubbo的示例代码
Apache Dubbo是一款高性能、轻量级的开源 Java RPC 框架,这篇文章主要介绍了Spring Boot 整合 Apache Dubbo的方法,本文通过示例说明给大家讲解的非常详细,需要的朋友可以参考下2021-07-07解读@SpringBootApplication注解有什么用
@SpringBootApplication是SpringBoot的核心注解,主要包含@SpringBootConfiguration、@EnableAutoConfiguration和@ComponentScan三个注解,这些注解共同简化了Spring应用的配置工作,并使得通过主程序类就可以启动SpringBoot应用2024-09-09
最新评论