Processing射击游戏:子弹与敌人碰撞失效问题求助
解决子弹与敌人碰撞后不消失的问题
问题分析
当前代码存在几个关键问题导致子弹穿过敌人不消失:
- 主程序中调用
W.update(),但Weapons类并没有update方法,实际应调用shooting()方法 - 尝试用
enemies.crash(W)检查碰撞,但enemies是ArrayList<Enemy>,没有该方法,需遍历每个敌人单独检查 - 未在碰撞后从
bullets列表中移除子弹 - 未处理子弹超出屏幕后的移除逻辑
修改后的代码
1. 修正Weapons类
class Weapons{ PImage bullet; int speed; int imageSize = 20; float x = 20; float y = 20; float m; int damage = 5; int[] src = new int[2]; float[] dest = new float[2]; Weapons(int x, int y){ speed = 12; dest[0] = mouseX; dest[1] = mouseY; src[0] = x; src[1] = y; // 避免鼠标在角色正上方/正下方时除以0的错误 if(dest[0] - src[0] != 0){ m = (dest[1]-src[1]) / (dest[0]-src[0]); } else { m = 0; } this.x = x; this.y = y; bullet = loadImage("bullet.png"); bullet.resize(imageSize,imageSize); } // 重命名为update,更贴合游戏逻辑习惯 boolean update(){ image(bullet, x, y); // 优化移动逻辑,让子弹朝鼠标点击方向移动(原逻辑仅朝右) float dx = dest[0] - src[0]; float dy = dest[1] - src[1]; float distance = sqrt(dx*dx + dy*dy); if(distance > 0){ x += (dx/distance) * speed; y += (dy/distance) * speed; } // 判断子弹是否超出屏幕范围 return (x < 0 || x > width || y < 0 || y > height); } boolean crash(Enemy enemy) { // 更准确的矩形碰撞检测:判断两个矩形是否重叠 return this.x < enemy.x + enemy.width && this.x + bullet.width > enemy.x && this.y < enemy.y + enemy.height && this.y + bullet.height > enemy.y; } }
2. 修正主程序的draw()方法
Maincharacter MC; Goal G; ArrayList<Enemy> enemies = new ArrayList<>(); ArrayList<Weapons> bullets = new ArrayList<>(); final int Playing = 0; final int Finish = 1; int gameMode = Playing; PImage background; int bgX = 0; void setup(){ size(800,500); MC = new Maincharacter(100,3); G = new Goal(100,20); background = loadImage("Battleground1.png"); background.resize(width*2,height); for(int i = 0; i<2; i++){ enemies.add(new Enemy((int)random(200,850), (int)random(0, height- 150) ) ); } } void draw(){ if(gameMode == Playing){ background(); MC.display(); G.display(); // 更新敌人并检查主角碰撞 for(int i = enemies.size()-1; i >= 0; i--){ Enemy E = enemies.get(i); E.update(); if (MC.crash(E)){ gameMode = Finish; break; } } // 更新子弹并检查与敌人的碰撞(倒序遍历避免索引异常) for(int i = bullets.size()-1; i >= 0; i--){ Weapons W = bullets.get(i); boolean isOutOfScreen = W.update(); boolean hitEnemy = false; // 遍历敌人检查碰撞 for(int j = enemies.size()-1; j >= 0; j--){ Enemy E = enemies.get(j); if(W.crash(E)){ // 此处可添加敌人受击逻辑,比如扣血、移除等,示例为直接移除敌人 enemies.remove(j); hitEnemy = true; break; } } // 子弹超出屏幕或击中敌人时,从列表中移除 if(isOutOfScreen || hitEnemy){ bullets.remove(i); } } } } void keyPressed(){ if (keyCode == RIGHT || keyCode == 68 ){ MC.x += 10; } else if (keyCode == UP || keyCode == 87) { MC.y -=10; } else if (keyCode == LEFT || keyCode == 65){ MC.x -= 10; } else if(keyCode == DOWN || keyCode == 83 ){ MC.y += 10; } else if (keyCode == 32) { MC.attack_function(); } } void mousePressed(){ MC.attack_function(); } void background(){ image(background, bgX, height/2); image(background, bgX+background.width, height/2); bgX -= 4; if(bgX == -background.width ){ bgX=0; } }
关键修改点说明
- 子弹移动逻辑优化:原逻辑仅朝右移动,修改为根据鼠标点击方向计算单位向量,让子弹精准朝目标点移动
- 碰撞检测优化:使用矩形重叠检测替代简单坐标差判断,提升碰撞准确性
- 遍历方式调整:倒序遍历
ArrayList,避免移除元素时出现索引越界或并发修改异常 - 子弹移除逻辑:当子弹超出屏幕或击中敌人时,从
bullets列表中移除,实现子弹消失效果 - 异常处理:添加斜率计算时分母为0的判断,避免鼠标在角色正上方/正下方时出现运行错误
内容的提问来源于stack exchange,提问作者Cuptius
相关产品推荐
相关产品推荐

