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

从零开发Java坦克大战:架构设计与难点突破 (下)

  • 6. 游戏引擎类:

    • 6.1 完整源码展示: 

    • import javax.swing.*;
      import java.awt.*;
      import java.awt.event.KeyEvent;
      import java.awt.event.KeyListener;
      import java.util.ArrayList;
      import java.util.HashSet;
      import java.util.Random;
      import java.util.Set;public class GamePanel extends JPanel implements KeyListener {//GamePanel类是游戏的核心控制器,负责管理游戏循环、输入处理和游戏状态更新。private TankA tankA;private TankB tankB;private final Set<Integer> pressedKeys = new HashSet<>();private final Timer gameTimer;private final Random ran = new Random();private final BattleMaps map;private final scorePanel sPanel;private final ArrayList<Bullet> bullets = new ArrayList<>();private boolean gameOver = false;private String winner = "";public GamePanel() {map = new BattleMaps();sPanel = new scorePanel();// 生成坦克A的合法位置tankA = generatePositionA(45, 35);tankB = generatePositionB(45, 35);// 生成坦克B的合法位置(且不与A重叠)// 初始化游戏定时器(每16ms≈60FPS)//使用游戏循环(Timer)来定期处理按键状态,更新坦克位置。gameTimer = new Timer(7, e -> {processInput();// 处理输入updateGame();// 更新游戏状态SwingUtilities.invokeLater(this::repaint);// 请求重绘});gameTimer.start();setFocusable(true);addKeyListener(this);}private TankA generatePositionA(int width, int height) {Random ran = new Random();Rectangle tempRect;int x, y;do {x = 120 + ran.nextInt(900);y = 60 + ran.nextInt(750);tempRect = new Rectangle(x, y, width, height);} while (map.isCollidingWithWall(tempRect)); // 确保不生成在墙上return new TankA(x, y); // 或 TankB}private TankB generatePositionB(int width, int height) {Random ran = new Random();Rectangle tempRect;int x, y;do {x = 120 + ran.nextInt(900);y = 60 + ran.nextInt(750);tempRect = new Rectangle(x, y, width, height);} while (map.isCollidingWithWall(tempRect)); // 确保不生成在墙上return new TankB(x, y); // 或 TankB}private void processInput() {// 游戏结束时忽略所有输入if (gameOver) return;// 处理坦克A// 每次循环先重置速度tankA.setSpeedX(0);tankA.setSpeedY(0);// 根据当前按下的键设置速度if (pressedKeys.contains(KeyEvent.VK_A)) {tankA.setDirection(0);tankA.setSpeedX(-4);}if (pressedKeys.contains(KeyEvent.VK_D)) {tankA.setDirection(2);tankA.setSpeedX(4);}if (pressedKeys.contains(KeyEvent.VK_W)) {tankA.setDirection(1);tankA.setSpeedY(-4);}if (pressedKeys.contains(KeyEvent.VK_S)) {tankA.setDirection(3);tankA.setSpeedY(4);}// 处理坦克BtankB.setSpeedX(0);tankB.setSpeedY(0);if (pressedKeys.contains(KeyEvent.VK_LEFT)) {tankB.setDirection(0);tankB.setSpeedX(-4);}if (pressedKeys.contains(KeyEvent.VK_RIGHT)) {tankB.setDirection(2);tankB.setSpeedX(4);}if (pressedKeys.contains(KeyEvent.VK_UP)) {tankB.setDirection(1);tankB.setSpeedY(-4);}if (pressedKeys.contains(KeyEvent.VK_DOWN)) {tankB.setDirection(3);tankB.setSpeedY(4);}}private void updateGame() {if (gameOver) {return;}handleTankMovement(tankA);handleTankMovement(tankB);//更新子弹位置for (Bullet bullet : new ArrayList<>(bullets)) {bullet.move();//检测子弹与墙壁的碰撞if (map.isCollidingWithWall(bullet.getBounds())) {bullet.setActive(false);}//检测子弹与坦克碰撞if (bullet.isActive()) {
      
http://www.xdnf.cn/news/1186273.html

相关文章:

  • C++ 多线程同步机制详解:互斥锁、条件变量与原子操作
  • 电子电气架构 --- 车载软件与样件产品交付的方法
  • TDengine 转化函数 TO_TIMESTAMP 用户手册
  • Python 程序设计讲义(21):循环结构——while循环
  • Leetcode力扣解题记录--第21题(合并链表)
  • C++ 常用的数据结构(适配器容量:栈、队列、优先队列)
  • [NPUCTF2020]ReadlezPHP
  • 基于深度学习的图像分类:使用Vision Transformer(ViT)实现高效分类
  • 【RDMA】Adapters PRM Mellanox Adapters Programmer’s Reference mellanox网卡编程手册0.52
  • Lua(数据库访问)
  • 【开发杂谈】用AI玩AI聊天游戏:使用 Electron 和 Python 开发大模型语音聊天软件
  • Web攻防-业务逻辑篇密码找回重定向目标响应包检验流程跳过回显泄露验证枚举
  • 前端核心进阶:从原理到手写Promise、防抖节流与深拷贝
  • OneCode3.0 Gallery 组件前后端映射机制:从注解配置到前端渲染的完整链路
  • [NLP]UPF+RTL联合仿真的VCS命令及UPF-aware 波形工具的使用
  • FPGA Verilog 入门语法指南
  • centos7安装docker命令
  • Scrapy
  • Qwen3-235B-A22B-Thinking-2507 - 开源思维推理模型的新标杆
  • 第二十天(正则表达式与功能实际运用)
  • VR 技术在污水处理领域的创新性应用探索​
  • STM32与ADS1220实现多通道数据采集的完整分析和源程序
  • 算法:数组part02: 209. 长度最小的子数组 +
  • SpringBoot整合Liquibase提升数据库变更的可控性、安全性、自动化程度(最详细)
  • 嵌入式学习-(李宏毅)机器学习(3)-day30
  • 图片查重从设计到实现(4)图片向量化存储-Milvus 单机版部署
  • Android悬浮窗导致其它应用黑屏问题解决办法
  • The Magic Mask for Android:解锁无限可能的安卓自定义套件
  • FT和RAG如何选择
  • win11 使用adb 获取安卓系统日志