如何在Bullet类中实现子弹击中敌人时移除敌人并更新分数?
问题分析与修改方案
先直接说你的Bullet类存在的核心问题:
- 分数变量放在Bullet类里完全不合理,分数是全局游戏状态,不该归单个子弹所有
- 每次绘制子弹都调用
resize会频繁修改图片数据,直接导致性能崩溃 - 碰撞判断逻辑错误,且没处理碰撞后的敌人移除、分数更新、子弹销毁逻辑
- 遍历列表时如果从前往后删元素,会触发索引越界,也是崩溃的常见原因
修正后的Bullet类代码
class Bullet { float bulletX, bulletY; float angle; static final float BULLET_SPEED = 5; // 删掉Bullet类里的score,分数移到全局管理 Bullet(float x, float y, float angle) { this.bulletX = x; this.bulletY = y; this.angle = angle; } void update() { bulletX += cos(angle) * BULLET_SPEED; bulletY += sin(angle) * BULLET_SPEED; } void show() { image(Bulletimg, bulletX, bulletY); } // 删掉重复的drawBullet方法,直接在show里调用image就行 // 图片resize只在初始化时做一次,别每次绘制都折腾 boolean offScreen() { return bulletX < 0 || bulletX > width || bulletY < 0 || bulletY > height; } // 碰撞判断改成返回布尔值,让主程序处理后续移除逻辑 boolean checkCollision(Enemy e) { // 假设Enemy类有size属性表示敌人直径,用半径做碰撞判断 float enemyRadius = e.size / 2; float distance = dist(bulletX, bulletY, e.x, e.y); return distance < enemyRadius; } }
主程序(Sketch)关键逻辑修改
子弹和敌人的列表、分数都放在主程序里管理,这才是合理的游戏状态管理方式:
ArrayList<Bullet> bullets = new ArrayList<>(); ArrayList<Enemy> enemies = new ArrayList<>(); PImage Bulletimg; int score = 0; void setup() { size(800, 600); Bulletimg = loadImage("bullet.png"); Bulletimg.resize(30, 30); // 只在初始化时调整图片尺寸,避免重复操作崩溃 // 初始化一个敌人示例 enemies.add(new Enemy(random(width), random(height), 40)); } void draw() { background(0); // 从后往前遍历子弹,避免删元素时索引越界 for (int i = bullets.size() - 1; i >= 0; i--) { Bullet b = bullets.get(i); b.update(); b.show(); // 子弹出界就移除 if (b.offScreen()) { bullets.remove(i); continue; } // 检查碰撞同样从后往前遍历敌人 for (int j = enemies.size() - 1; j >= 0; j--) { Enemy e = enemies.get(j); if (b.checkCollision(e)) { // 碰撞成功:加分、删敌人、删当前子弹 score += 10; enemies.remove(j); bullets.remove(i); break; // 一颗子弹只能撞一个敌人,直接跳出循环 } } } // 更新绘制敌人 for (Enemy e : enemies) { e.update(); e.show(); } // 显示分数 fill(255); textSize(20); text("Score: " + score, 20, 30); } // 鼠标点击发射子弹的示例方法 void mousePressed() { float angle = atan2(mouseY - height/2, mouseX - width/2); bullets.add(new Bullet(width/2, height/2, angle)); }
配套Enemy类补充(你可能需要完善)
Enemy类至少要有位置、尺寸属性和基础的更新绘制方法:
class Enemy { float x, y; float size; float speed = 1; Enemy(float x, float y, float size) { this.x = x; this.y = y; this.size = size; } void update() { // 示例:敌人向屏幕中心移动 float dx = width/2 - x; float dy = height/2 - y; float angle = atan2(dy, dx); x += cos(angle) * speed; y += sin(angle) * speed; } void show() { fill(255, 0, 0); ellipse(x, y, size, size); } }
内容的提问来源于stack exchange,提问作者Tauruie
相关产品推荐
相关产品推荐

