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

类实现故障求助:旋转追踪鼠标的三角形敌人无法绘制

问题排查与修复方案

看起来你在重构Enemy类后遇到了几个关键问题,导致敌人无法渲染,甚至影响了后续图形的显示。我们一步步拆解问题并给出修复方案:

1. Setup方法中的循环错误(最致命的初始化问题)

你的setup代码里有一个多余的分号,导致循环完全没有执行添加敌人的逻辑,最终只添加了一个敌人:

for (i = 0; i<difficulty; i++); // 这里的分号让循环体为空!
enemies.add(new Enemy(i*5));

修正后要去掉分号,把add操作放进循环体,同时显式声明变量类型避免隐式错误:

for (int i = 0; i < difficulty; i++) {
  enemies.add(new Enemy(i*5));
}

2. RotateEnemy方法中的参数与逻辑错误

你的旋转方法存在多处致命问题:

  • theta2变量在Enemy类中完全没有声明,会直接导致编译失败;
  • 调用旋转方法时错误地传入了x2作为y坐标参数(比如rotateX(x2, x2, theta2, 0)),应该传入对应点的x和y值(x2和y2);
  • 旋转后的赋值逻辑混乱,比如x2 = rotateY(...)后又立刻用x2Rotated覆盖,完全丢失了旋转结果。

我们可以直接用三角函数实现顶点旋转,同时添加角度变量:

// 在Enemy类成员变量中添加
float theta;

void rotateEnemy() {
  // 计算敌人朝向鼠标的角度
  theta = atan2(mouseY - y, mouseX - x);
  
  // 旋转三角形的三个顶点(基于自身中心)
  float x1Rotated = cos(theta) * x1 - sin(theta) * y1;
  float y1Rotated = sin(theta) * x1 + cos(theta) * y1;
  
  float x2Rotated = cos(theta) * x2 - sin(theta) * y2;
  float y2Rotated = sin(theta) * x2 + cos(theta) * y2;
  
  float x3Rotated = cos(theta) * x3 - sin(theta) * y3;
  float y3Rotated = sin(theta) * x3 + cos(theta) * y3;
  
  // 更新顶点坐标
  x1 = x1Rotated;
  y1 = y1Rotated;
  x2 = x2Rotated;
  y2 = y2Rotated;
  x3 = x3Rotated;
  y3 = y3Rotated;
}

3. DrawEnemy方法的两个关键错误

  • 三角形参数错误:你写的triangle(x1, y1, x2, x2, x3, x3)会把第二个点设为(x2, x2),第三个点设为(x3, x3),这根本不是你定义的三角形顶点,应该用(x2, y2)和(x3, y3);
  • 坐标系未重置:translate(x,y)会修改全局坐标系,如果不用pushMatrix()和popMatrix()包裹,后续的图形绘制都会受到影响(比如你提到的椭圆不显示)。

修正后的drawEnemy方法:

void drawEnemy() {
  pushMatrix(); // 保存当前坐标系状态
  translate(x, y);
  triangle(x1, y1, x2, y2, x3, y3);
  popMatrix(); // 恢复坐标系,不影响后续绘制
}

4. 未定义的变量问题

你的Enemy类中使用了speedChange、isDeadly、energy、points等变量,但这些变量既没有在Enemy类中声明,也没有作为参数传入。你需要:

  • 如果是全局变量,确保在主程序中定义为全局;
  • 如果是Enemy的属性,在Enemy类中添加成员变量并初始化。

比如在Enemy类中补充:

float speedChange = 0; // 根据需求调整默认值
boolean isDeadly = true;

主程序中补充全局变量:

float energy;
int points;
int difficulty = 5; // 示例值,根据你的需求设置

5. Respawn方法的范围错误

你的respawn逻辑中存在无效的随机范围,比如x = random(0, -width/2),random函数要求第一个参数小于第二个,应该修正为:

if (ranQuadrant1 == 0) {
  if (ranSide1 == 0) {
    x = random(-width/2, 0); // 左边界外
  } else {
    x = random(width, width + width/2); // 右边界外
    y = random(-height/2, height + height/2);
  }
}
// 其他分支同理修正random的参数顺序

修正后的核心Enemy类片段

class Enemy {
  float x = random(-width, 0);
  float y = random(0, height);
  // 三角形顶点(基于自身中心的相对坐标)
  float x1 = 0;
  float y1 = (sqrt(3)/3)*40;
  float x2 = -20;
  float y2 = -(sqrt(3)/3)*40;
  float x3 = 20;
  float y3 = -(sqrt(3)/3)*40;
  float speed;
  float theta; // 旋转角度
  float speedChange = 0;
  boolean isDeadly = true;

  Enemy(float tempSpeed) {
    speed = tempSpeed;
  }

  void rotateEnemy() {
    theta = atan2(mouseY - y, mouseX - x);
    
    float x1Rotated = cos(theta) * x1 - sin(theta) * y1;
    float y1Rotated = sin(theta) * x1 + cos(theta) * y1;
    
    float x2Rotated = cos(theta) * x2 - sin(theta) * y2;
    float y2Rotated = sin(theta) * x2 + cos(theta) * y2;
    
    float x3Rotated = cos(theta) * x3 - sin(theta) * y3;
    float y3Rotated = sin(theta) * x3 + cos(theta) * y3;
    
    x1 = x1Rotated;
    y1 = y1Rotated;
    x2 = x2Rotated;
    y2 = y2Rotated;
    x3 = x3Rotated;
    y3 = y3Rotated;
  }

  void move() {
    theta = atan2(mouseY - y, mouseX - x);
    x += cos(theta) * (speed + speedChange);
    y += sin(theta) * (speed + speedChange);
  }

  void drawEnemy() {
    pushMatrix();
    translate(x, y);
    triangle(x1, y1, x2, y2, x3, y3);
    popMatrix();
  }

  void collisionDetect() {
    if (abs(mouseX-x) + abs(mouseY-y) < 80) {
      if (isDeadly) {
        respawn();
        energy -= height/16;
        points += 500;
      } else {
        energy = 0;
      }
    }
  }

  void respawn() {
    int ranQuadrant1 = (int)random(0, 2);
    int ranSide1 = (int)random(0, 2);
    if (ranQuadrant1 == 0) {
      if (ranSide1 == 0) {
        x = random(-width/2, 0);
      } else {
        x = random(width, width + width/2);
        y = random(-height/2, height + height/2);
      }
    } else if (ranSide1 == 0) {
      y = random(-height/2, 0);
    } else {
      y = random(height, height + height/2);
      x = random(-width/2, width + width/2);
    }
  }
}

这些修正应该能解决敌人不显示的问题,同时恢复后续图形的正常渲染。记得确保主程序中的全局变量都正确定义并初始化。

内容的提问来源于stack exchange,提问作者Ethan Graney

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:28:45