我创建了这个帐户,因为我没有其他地方可以询问这个问题。所以我总体上是编码的初学者(我之前尝试过 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;
}
以下演示创建了两个类: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);
}
}