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

Java Processing中拖拽垃圾入桶计分与重置的技术求助

解决方案

先看你代码里的核心问题:原碰撞检测逻辑完全错误,abs((canX+100)-(canX+450))化简后是abs(100-450)=350,永远不可能小于25,所以触发不了计分。另外还有几个小问题需要修正,下面是修复后的完整代码,关键修改点我会在后面说明:

PImage scene, can, brownB, blueB, greenB;

// 垃圾的位置和尺寸
int canX;
int canY;
int canWidth;
int canHeight;

// 绿色垃圾桶的位置和尺寸(单独定义,方便碰撞检测)
int greenBinX = 100;
int greenBinY = 450;
int greenBinWidth;
int greenBinHeight;

int score = 0;
int lives = 3;
int quit = 0;

boolean mouseInCan = false;

void setup() {
  size(800, 600, P2D);
  scene = loadImage("backround.png");
  can = loadImage("can.png");
  greenB = loadImage("green_bin.png");

  textureMode(NORMAL);
  blendMode(BLEND);
  noStroke();

  // 初始化垃圾尺寸(必须在size之后,否则width/height是0)
  canWidth = width / 8;
  canHeight = height / 8;
  // 初始化垃圾桶尺寸
  greenBinWidth = width / 8;
  greenBinHeight = height / 4;
  
  // 重置垃圾位置
  resetTrash();
}

// 检测鼠标是否点击在垃圾上
void mousePressed() {
  if (mouseX > canX && mouseX < canX + canWidth && 
      mouseY > canY && mouseY < canY + canHeight) {
    mouseInCan = true;
  }
}

// 拖拽垃圾
void mouseDragged() {
  if (mouseInCan) {
    // 直接让垃圾跟随鼠标中心,比delta更直观
    canX = mouseX - canWidth/2;
    canY = mouseY - canHeight/2;
  }
}

// 松开鼠标时检测是否放入垃圾桶
void mouseReleased() {
  if (mouseInCan) {
    // 检测垃圾与绿色垃圾桶的碰撞
    if (checkCollision(canX, canY, canWidth, canHeight, 
                       greenBinX, greenBinY, greenBinWidth, greenBinHeight)) {
      score++;
      resetTrash();
    }
  }
  mouseInCan = false;
}

// 通用碰撞检测函数:检测两个矩形是否重叠
boolean checkCollision(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2) {
  return !(x1 + w1 < x2 || x1 > x2 + w2 || y1 + h1 < y2 || y1 > y2 + h2);
}

// 重置垃圾到顶部随机位置
void resetTrash() {
  canX = (int)random(width - canWidth); // 避免垃圾超出屏幕左右
  canY = 0;
}

void draw() {
  background(scene);
  
  // 绘制垃圾桶和垃圾
  image(greenB, greenBinX, greenBinY, greenBinWidth, greenBinHeight);
  image(can, canX, canY, canWidth, canHeight);

  // 垃圾自动下落(只有未被拖拽时才下落)
  if (!mouseInCan) {
    canY += 1.5;
    // 垃圾落到屏幕底部,减少生命值并重置
    if (canY > height) {
      lives--;
      resetTrash();
    }
  }

  // 绘制计分和生命值
  textSize(18);
  fill(0);
  text("Lives: " + lives, 540, 20);
  text("Score: " + score, 640, 20);

  // 游戏结束逻辑
  if (lives < 1) {
    textSize(40);
    text("Game Over!", width/2 - 100, height/2);
    quit = 1;
  }
  
  if (quit == 1) {
    delay(5000);
    exit();
  }
}

关键修改点说明:

  1. 修复碰撞检测逻辑:

    • 删掉了原代码中无效的碰撞判断,新增了通用的checkCollision函数,检测两个矩形是否重叠,逻辑清晰且可靠。
    • 在mouseReleased时检测垃圾是否放入垃圾桶,符合拖拽操作的逻辑(松开鼠标时判定是否成功分类)。
  2. 修正尺寸初始化问题:

    • 原代码中canwidth = width/2在setup前定义,此时width还未被size()初始化,值为0,导致垃圾尺寸异常,现在移到setup里赋值。
    • 给绿色垃圾桶单独定义位置和尺寸变量,方便后续扩展其他颜色垃圾桶。
  3. 优化拖拽体验:

    • 拖拽时让垃圾中心跟随鼠标,比原代码的delta计算更直观,避免垃圾偏移。
    • 只有未被拖拽时,垃圾才会自动下落,符合游戏逻辑。
  4. 清理冗余代码:

    • 删掉了原代码中那个隐藏的pushMatrix绘制的垃圾(完全没用,还占资源)。
    • 把重置垃圾的逻辑封装成resetTrash函数,避免重复代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 19:40:27