Processing IDE 中的布娃娃物理问题

问题描述 投票:0回答:1

我创建了这个帐户,因为我没有其他地方可以询问这个问题。所以我总体上是编码的初学者(我之前尝试过 python、html 和 javascript)并且刚刚开始尝试处理。我的目标是制作一个布娃娃角色,具有可拖动的手臂和腿以及逼真的坠落物理效果。现在,当我启动程序时,手臂和腿会飞出框架,我不知道如何修复它。

这是我现在拥有的完整代码。

float rectWidth = 200, rectHeight = 250; // Body
float faceRectWidth = 150, faceRectHeight = 115; // Face
boolean dragging = false;
PVector target; 
PVector characterPos;
float gravity = 0.5;  // Reduced gravity to prevent limbs from falling too fast
float groundLevel;
boolean isSquinting = false;

float armLength = 60, legLength = 80;
PVector leftArm, rightArm, leftLeg, rightLeg;
PVector leftArmVel, rightArmVel, leftLegVel, rightLegVel;

// Static anchor points for the limbs
PVector leftArmAnchor, rightArmAnchor, leftLegAnchor, rightLegAnchor;

void setup() {
  size(800, 600);
  background(255);
  characterPos = new PVector(width / 2 - rectWidth / 2, height - rectHeight - 30);
  target = new PVector();

  // Set static anchor points relative to the torso position
  leftArmAnchor = new PVector(-20, rectHeight * 0.4);
  rightArmAnchor = new PVector(rectWidth + 20, rectHeight * 0.4);
  leftLegAnchor = new PVector(rectWidth * 0.3, rectHeight);
  rightLegAnchor = new PVector(rectWidth * 0.7, rectHeight);

  // Initialize limb positions at their anchored points
  leftArm = PVector.add(characterPos, leftArmAnchor);
  rightArm = PVector.add(characterPos, rightArmAnchor);
  leftLeg = PVector.add(characterPos, leftLegAnchor);
  rightLeg = PVector.add(characterPos, rightLegAnchor);

  leftArmVel = new PVector(0, 0);
  rightArmVel = new PVector(0, 0);
  leftLegVel = new PVector(0, 0);
  rightLegVel = new PVector(0, 0);

  groundLevel = height - rectHeight;
}

void draw() {
  background(255);

  if (dragging) {
    // Dragging character
    PVector difference = PVector.sub(target, characterPos);
    characterPos.add(difference.mult(0.2));
    target.set(mouseX, mouseY);
    isSquinting = true;
  } else {
    isSquinting = false;
    // Apply gravity
    if (characterPos.y < groundLevel) {
      characterPos.y += gravity;
    } else {
      characterPos.y = groundLevel;
    }
  }

  // Update limb positions, keeping them anchored
  updateLimb(leftArm, leftArmVel, leftArmAnchor);
  updateLimb(rightArm, rightArmVel, rightArmAnchor);
  updateLimb(leftLeg, leftLegVel, leftLegAnchor);
  updateLimb(rightLeg, rightLegVel, rightLegAnchor);

  // Draw character
  pushMatrix();
  translate(characterPos.x, characterPos.y);
  drawBmo();
  popMatrix();
}

void drawBmo() {
  // Draw body
  stroke(#3C4342);
  strokeWeight(5);
  fill(#92D8D2);
  rect(0, 0, rectWidth, rectHeight, 20);  // Rounded corners

  // Draw face
  stroke(#3C4342);
  strokeWeight(5);
  fill(#C9F0EC);
  float faceRectX = (rectWidth - faceRectWidth) / 2;
  float faceRectY = 20; 
  rect(faceRectX, faceRectY, faceRectWidth, faceRectHeight, 20);  // Rounded corners

  // Draw eyes (squinting effect)
  fill(#102C29);
  noStroke();
  float eyeWidth = 10, eyeHeight = isSquinting ? 5 : 10;
  float leftEyeX = faceRectX + faceRectWidth * 0.25;
  float rightEyeX = faceRectX + faceRectWidth * 0.75;
  float eyeY = faceRectY + faceRectHeight * 0.4;
  ellipse(leftEyeX, eyeY, eyeWidth, eyeHeight);
  ellipse(rightEyeX, eyeY, eyeWidth, eyeHeight);

  // Draw mouth
  stroke(#102C29);
  strokeWeight(3);
  noFill();
  float mouthX = faceRectX + faceRectWidth / 2;
  float mouthY = faceRectY + faceRectHeight * 0.6;
  arc(mouthX, mouthY, 35, 10, 0, PI);

  // Draw buttons
  stroke(#102C29);
  strokeWeight(3);
  fill(#072723);
  rect(30, 150, 80, 10);

  fill(#171476);
  ellipse(150, 155, 10, 10);

  fill(#4AE5F5);
  triangle(135, 190, 125, 200, 145, 200);

  // Draw limbs
  drawLimb(leftArm, 10, armLength);
  drawLimb(rightArm, 10, armLength);
  drawLimb(leftLeg, 10, legLength);
  drawLimb(rightLeg, 10, legLength);

  // Other details
  stroke(#102C29);
  strokeWeight(3);
  fill(#2AF53F);
  ellipse(170, 195, 15, 15);
  fill(#F52A82);
  ellipse(150, 225, 25, 25);
}

void drawLimb(PVector pos, float width, float height) {
  // Draw limb as a rectangle
  stroke(#3C4342);
  strokeWeight(3);
  fill(#92D8D2);
  rect(pos.x - characterPos.x, pos.y - characterPos.y, width, height, 10);
}

void updateLimb(PVector pos, PVector vel, PVector anchor) {
  float elasticity = 0.2; // Increased elasticity to keep limbs closer to anchor
  float maxStretch = 50;  // Maximum distance limbs can stretch from the anchor

  PVector anchoredPos = PVector.add(characterPos, anchor);

  // Apply gravity to limbs
  vel.y += gravity * 0.5;  // Reduced gravity effect for limbs
  pos.add(vel);

  // Apply elasticity to keep the limb close to its anchor
  PVector stretch = PVector.sub(anchoredPos, pos);
  float stretchDist = stretch.mag();
  if (stretchDist > maxStretch) {
    stretch.normalize();
    pos.set(PVector.add(anchoredPos, stretch.mult(-maxStretch)));
  }
  pos.add(stretch.mult(elasticity));

  // Apply friction to slow down velocity
  vel.mult(0.95);
}

// Mouse interaction functions
void mousePressed() {
  if (mouseX > characterPos.x && mouseX < characterPos.x + rectWidth &&
      mouseY > characterPos.y && mouseY < characterPos.y + rectHeight) {
    dragging = true;
    target.set(mouseX, mouseY);
  }
}

void mouseDragged() {
  if (dragging) {
    target.set(mouseX, mouseY);
  }
}

void mouseReleased() {
  dragging = false;
}

processing game-physics ragdoll
1个回答
0
投票

以下演示创建了两个类:body 和leg。 两个对象都可以通过拖动来重新定位。腿可以独立地分离和重新定位,但在重新定位时始终跟随身体。您也许可以在您的应用程序中使用此技术。

boolean bodySelected = false;
boolean legSelected = false;
PVector bodyOffset;
PVector legOffset;

class Body {
  float x, y, w, h;

  Body(float xpos, float ypos, float wide, float ht) {
    x = xpos;
    y = ypos;
    w = wide;
    h = ht;
  }

  void display() {
    rect(x, y, w, h);
  }
}

Body body;

class Leg {
  float x, y, w, h;

  Leg(float xpos, float ypos, float wide, float ht) {
    x = xpos;
    y = ypos;
    w = wide;
    h = ht;
  }

  void display() {
    rect(x, y, w, h);
  }
}

Leg leg;

void setup() {
  size(800, 800);
  background(209);
  body = new Body(300, 200, 200, 200);
  bodyOffset = new PVector(0.0, 0.0, 0.0);
  leg = new Leg(body.x + 30, body.y + body.h, 20, 100);
  legOffset = new PVector(0.0, 0.0, 0.0);
}

void draw() {
  background(209);
  body.display();
  leg.display();
}

void mousePressed() {
  if ((mouseX >= body.x) && (mouseX <= body.x + body.w) && (mouseY >= body.y) && (mouseY <= body.y + body.h)) {
    bodySelected = true;
    println("mouse pressed x,y = " + mouseX + " : " + mouseY);
    println(body.x + " : " + body.y);
    bodyOffset.set(mouseX - body.x, mouseY - body.y, 0.0);
    // Change offset of leg also
    legOffset.set(mouseX - leg.x, mouseY - leg.y, 0.0);
    println("mouse pressed body offsets = " + bodyOffset.x + " : " + bodyOffset.y);
    println("mouse pressed leg offsets = " + legOffset.x + " : " + legOffset.y);
  } else {
    bodySelected = false;
  }

  if ((mouseX >= leg.x) && (mouseX <= leg.x + leg.w) && (mouseY >= leg.y) && (mouseY <= leg.y + leg.h)) {
    legSelected = true;
    println("mouse pressed x,y = " + mouseX + " : " + mouseY);
    println(leg.x + " : " + leg.y);
    legOffset.set(mouseX - leg.x, mouseY - leg.y, 0.0);
    println("mouse pressed offsets = " + legOffset.x + " : " + legOffset.y);
  } else {
    legSelected = false;
  }
}

void mouseDragged() {
  if (bodySelected) {
    body.x = mouseX - bodyOffset.x;
    body.y = mouseY - bodyOffset.y;
    println("dragged body rect x,y = "+ body.x + " : " + body.y);
    // Keep leg with the body
    leg.x = mouseX - legOffset.x;
    leg.y = mouseY - legOffset.y;
  }
  if (legSelected) {
    leg.x = mouseX - legOffset.x;
    leg.y = mouseY - legOffset.y;
    println("dragged leg rect x,y = " + leg.x + " : " + leg.y);
  }
}

© www.soinside.com 2019 - 2024. All rights reserved.