You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 18:55:30