当前位置: 首页 > news >正文

球球大作战 JAVA项目

UI类 GameUI

​ import javax.swing.*; import java.awt.*; import java.util.ArrayList; public class GameUI { ArrayList<Player> playerList = new ArrayList<>(); GameListener gameListener = new GameListener(); KeyBoardListener keyBoardListener = new KeyBoardListener(); Player hero; JFrame jf = new JFrame("球球大作战"); public GameUI() { jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jf.setSize(500, 800); jf.setLocationRelativeTo(null); jf.setVisible(true); jf.addMouseListener(gameListener); jf.addMouseMotionListener(gameListener); gameListener.gameUI = this; jf.addKeyListener(keyBoardListener); keyBoardListener.gameUI = this; hero = new Player(225, 375, 50, 0, 0, new Color(255, 0, 218)); GameLoop gameLoop = new GameLoop(this); gameLoop.start(); } public static void main(String[] args) { new GameUI(); } } ​

采用传统UI构造方法,并创建玩家类hero,用start开始线程

游戏监听类 Gamelitener

import java.awt.*; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.util.Random; public class GameListener implements MouseListener, MouseMotionListener { GameUI gameUI; @Override public void mouseDragged(MouseEvent e) { int x = e.getX(); int y = e.getY(); } @Override public void mousePressed(MouseEvent e) { Random random = new Random(); int x = e.getX(); int y = e.getY(); int size = random.nextInt(40) + 30; int speedx = random.nextInt(5) - 2; int speedy = random.nextInt(5) - 2; Color color = new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255)); Player player = new Player(x, y, size, speedx, speedy, color); gameUI.playerList.add(player); } @Override public void mouseClicked(MouseEvent e) { } @Override public void mouseReleased(MouseEvent e) { } @Override public void mouseEntered(MouseEvent e) { } @Override public void mouseExited(MouseEvent e) { } @Override public void mouseMoved(MouseEvent e) { } }

监听类继承mouselistener和mousemotionlistener两类,重写鼠标点击方法,当鼠标按下时,随机生成不同大小颜色速度的小球,并加入动态列表

键盘监听类 KeyBoardListener

import java.awt.event.KeyEvent; import java.awt.event.KeyListener; public class KeyBoardListener implements KeyListener { GameUI gameUI; // 四个方向标记 public boolean up, down, left, right; @Override public void keyPressed(KeyEvent e) { int keyCode = e.getKeyCode(); switch (keyCode) { case KeyEvent.VK_UP: up = true; break; case KeyEvent.VK_DOWN: down = true; break; case KeyEvent.VK_LEFT: left = true; break; case KeyEvent.VK_RIGHT: right = true; break; } } @Override public void keyReleased(KeyEvent e) { int keyCode = e.getKeyCode(); switch (keyCode) { case KeyEvent.VK_UP: up = false; break; case KeyEvent.VK_DOWN: down = false; break; case KeyEvent.VK_LEFT: left = false; break; case KeyEvent.VK_RIGHT: right = false; break; } } @Override public void keyTyped(KeyEvent e) { } }

继承keylistener,监听键盘动作,通过上下左右四个按键移动玩家小球移动

玩家类 Player

import java.awt.*; import java.util.ArrayList; public class Player { private int x, y, size; private int speedx; private int speedy; private Color color; public Player(int x, int y, int size, int speedx, int speedy, Color color) { this.x = x; this.y = y; this.size = size; this.speedx = speedx; this.speedy = speedy; this.color = color; } // 绘制方法 public void draw(Graphics g) { g.setColor(color); g.fillOval(x, y, size, size); } // 移动方法 public void move() { if (x < 0 || x > 500 - size) { speedx = -speedx; } if (y < 0 || y > 800 - size) { speedy = -speedy; } x += speedx; y += speedy; } // 获取圆心X public int getCenterX(){ return this.x + size / 2; } // 获取圆心Y public int getCenterY(){ return this.y + size / 2; } // 获取半径 public double getRadius(){ return size / 2.0; } // 碰撞检测 public void hit(ArrayList<Player> playerList) { int index = playerList.indexOf(this); for (int i = index + 1; i < playerList.size(); i++) { Player otPlayer = playerList.get(i); double dx = otPlayer.getCenterX() - this.getCenterX(); double dy = otPlayer.getCenterY() - this.getCenterY(); double dist = Math.sqrt(dx * dx + dy * dy); double sumRadius = this.getRadius() + otPlayer.getRadius(); if (dist < sumRadius) { double overlap = sumRadius - dist; // 单位法线向量 double nx = dx / dist; double ny = dy / dist; this.x -= overlap * nx / 2; this.y -= overlap * ny / 2; otPlayer.x += overlap * nx / 2; otPlayer.y += overlap * ny / 2; int tempSpeedx = speedx; int tempSpeedy = speedy; speedx = otPlayer.getSpeedx(); speedy = otPlayer.getSpeedy(); otPlayer.setSpeedx(tempSpeedx); otPlayer.setSpeedy(tempSpeedy); } } } 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 int getSize() { return size; } public void setSize(int size) { this.size = size; } public int getSpeedx() { return speedx; } public void setSpeedx(int speedx) { this.speedx = speedx; } public int getSpeedy() { return speedy; } public void setSpeedy(int speedy) { this.speedy = speedy; } public Color getColor() { return color; } public void setColor(Color color) { this.color = color; } }

绘制与移动小球,创建列表playlist储存小球信息并判断是否碰撞,碰撞后速度交换

游戏循环线程 GameLoop

import java.awt.*; import java.util.ArrayList; public class GameLoop extends Thread{ private GameUI gameUI; private GameListener gameListener; private KeyBoardListener keyBoardListener; private ArrayList<Player> playerList; private Graphics g; private final int playerSpeed = 5; public GameLoop(GameUI gameUI) { this.gameUI = gameUI; gameListener = gameUI.gameListener; playerList = gameUI.playerList; keyBoardListener = gameUI.keyBoardListener; g=gameUI.jf.getGraphics(); } @Override public void run() { while(true){ try { Thread.sleep(30); } catch (InterruptedException e) { throw new RuntimeException(e); } g.clearRect(0,0,500,800); Player hero = gameUI.hero; // 重置临时速度 int dx = 0; int dy = 0; if(keyBoardListener.up) dy -= playerSpeed; if(keyBoardListener.down) dy += playerSpeed; if(keyBoardListener.left) dx -= playerSpeed; if(keyBoardListener.right) dx += playerSpeed; hero.setX(hero.getX() + dx); hero.setY(hero.getY() + dy); int w = 500, h = 800; int size = hero.getSize(); if(hero.getX() < 0) hero.setX(0); if(hero.getX() > w - size) hero.setX(w - size); if(hero.getY() < 0) hero.setY(0); if(hero.getY() > h - size) hero.setY(h - size); hero.hit(playerList); for (int i = 0; i < playerList.size(); i++) { Player player = playerList.get(i); player.draw(g); player.move(); player.hit(playerList); } hero.draw(g); } } public GameListener getGameListener() { return gameListener; } public GameUI getGameUI() { return gameUI; } }

继承thread类,重写run方法,实现控制玩家小球并参与碰撞

http://www.jsqmd.com/news/1166213/

相关文章:

  • VSCode Verilog 开发环境:3款Linter工具(xvlog/iverilog/verilator)性能与精度对比
  • 深度解析:高校 AI 通识课现成教学包推荐,EDU360 Cloud AI 通识课2.0教学运行包特点解析
  • 【Springboot毕设全套源码+文档】基于SpringBoot的高校校园网故障管理系统(丰富项目+远程调试+讲解+定制)
  • Compressor.js图像压缩:如何在浏览器中高效处理用户上传的图片?
  • RS485 总线故障排查:因上下拉电阻导致的 Modbus 通讯异常与 3 步修复
  • 2026年7月最新青岛美度官方售后客户服务热线与维修网点地址汇总 - 亨得利钟表维修中心
  • C++实现灰度共生矩阵(GLCM)进行图像纹理分析与工业应用实战
  • RVC、GPT-SoVITS、SVC 3款AI声音克隆方案对比:从5秒素材到商用音质的实测
  • 别再盲目打卡一万步!研究发现:每天走够这个数,健康性价比最高!
  • 参量阵浅剖仪 GeoPass100 解析:ROV/AUV集成3大要点与数据融合方案
  • 闭包的概念与应用
  • 7天实战AI原生游戏:LLM NPC与神经渲染管线集成指南
  • STM32F4 DMA 双缓冲区模式实战:ADC 连续采样 1024 点零 CPU 中断处理
  • 理解力债:AI 生成代码背后被忽视的“隐形成本”
  • 2026实测视频去水印提取工具教程:电脑手机免费在线软件汇总
  • CSAPP Data Lab 13个位运算函数:从 bitXor 到 float_f2i 的完整解题思路
  • 2027地理学(及相关)考研科目/参考书目调整信息汇总
  • 2026年7月最新大连雅典官方售后服务网点地址及客服电话一览 - 亨得利官方服务中心
  • Claude 中转配置完整指南:从密钥到 settings.json
  • ClaudeCode:面向工程协作的上下文感知开发基础设施
  • 直播录屏本地管理系统:视频索引、关键帧提取与内容检索实践
  • GEO系统源码主体爱搜索GEO:基于源码的AI搜索优化自主部署全攻略 - 品牌报告
  • LTC1864与PIC24FV16KA301的高精度ADC系统设计
  • GitHub Copilot 新版计费翻车:2天消耗49美元,天价引爆开发者吐槽,国产开源 AI 迎来替代窗口期
  • LlamaIndex PDF加载实战:解决中文技术文档解析的10大陷阱
  • Skill 负责编排判断,CLI 稳定交付的执行边界
  • C# WinForm CAN 上位机开发:3步连接Kvaser卡与电机握手通信
  • Cursor 3.0实战:用自然语言开发安卓APP
  • League Akari:英雄联盟LCU API工具包实战指南
  • WK2124 SPI转4串口Linux驱动移植:RK3288平台适配3大关键步骤与排错