User prompt
Saati biraz daha büyuk yap. Digital bir görunum ver 00:00 gibi
User prompt
Trigger win when puppet body collides with finish sign using intersects
User prompt
Trigger win when puppet body collides with finish sign using intersects
User prompt
Trigger win when puppet body collides with finish sign using intersects
User prompt
Trigger win when puppet kalça collides with finish sign using intersects
User prompt
Kukla tabelaya deydiginde oyum kazanılssin
User prompt
Kukla tabelaya geldiğinde oyun bi
User prompt
Test etmek ıcın her davulda saga git
User prompt
Kukla bitiş tabelasina geldiğinde oyun kazanilsın skor kalan saniye olsun
User prompt
Bitiş tabelasıni 2 kat uzun yap. Finish yazısını kaldır
User prompt
Tüm kukla hareketlerini iyileştir
User prompt
Çökme yada oturma işlevi düzgün çalışmıyor
User prompt
Ayakları kinematics iyileştir
User prompt
Bacaklarda kinematik düzelt fizik motoru duzelt
User prompt
Bacakların ik sini düzelt
User prompt
Bitiş tabelasını 3 kat büyüt
User prompt
Bitiş tabelasıni 5 kat buyut
User prompt
Bitişi 5 kat büyüt
User prompt
Sağa gitme işlevi daha fazla butonda olsun.
User prompt
Zıplama biraz daha yukarı olsun.
User prompt
Random değişkenligini kaldir.
User prompt
Her işlev mutlaka bir davulda olsun. Sadece yerleri değişsin.
User prompt
Sağa ve sola ihtimali biraz arttir.
User prompt
Please fix the bug: 'reverb is not defined' in or related to this line: 'reverb.add(LK.getSound('drum_tap_center'));' Line Number: 454
User prompt
Please fix the bug: 'reverb is not defined' in or related to this line: 'reverb.add(LK.getSound('drum_tap_center'));' Line Number: 453 ↪💡 Consider importing and using the following plugins: @upit/tween.v1, @upit/storage.v1, @upit/facekit.v1
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Drum class var Drum = Container.expand(function () { var self = Container.call(this); self.drumType = 'none'; // 'large', 'left', 'right', 'sit', 'stand' self.action = null; // function to call on tap // Set up drum asset self.setDrum = function (type) { self.drumType = type; var assetId = type === 'large' ? 'drum_large' : 'drum_medium'; var drum = self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5 }); // (Drum label removed) }; // Drum tap effect self.flash = function () { tween(self, { scaleX: 1.18, scaleY: 0.92 }, { duration: 80, onFinish: function onFinish() { tween(self, { scaleX: 1, scaleY: 1 }, { duration: 120 }); } }); }; // Touch event self.down = function (x, y, obj) { self.flash(); // Play unique sound for each drum type if (self.drumType === 'large') { LK.getSound('drum_tap_center').play(); } else if (self.drumType === 'left') { LK.getSound('drum_tap_left').play(); } else if (self.drumType === 'right') { LK.getSound('drum_tap_right').play(); } else if (self.drumType === 'sit') { LK.getSound('drum_tap_sit').play(); } else if (self.drumType === 'stand') { LK.getSound('drum_tap_stand').play(); } else { // No fallback sound } if (self.action) self.action(); }; return self; }); // Puppet class: articulated body with simple kinematics var Puppet = Container.expand(function () { var self = Container.call(this); // --- Body part sizes (for positioning) --- var headH = 120 * 1.5, headW = 120 * 1.5; var bodyH = 200 * 1.5, bodyW = 80 * 1.5; var upperArmH = 100 * 1.5, upperArmW = 40 * 1.5; var lowerArmH = 90 * 1.5, lowerArmW = 32 * 1.5; var upperLegH = 120 * 1.5, upperLegW = 48 * 1.5; var lowerLegH = 110 * 1.5, lowerLegW = 40 * 1.5; // --- Create body parts --- // Head var head = self.attachAsset('puppet_head', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 1.5 }); // Body var body = self.attachAsset('puppet_body', { anchorX: 0.5, anchorY: 0, scaleX: 1.5, scaleY: 1.5 }); // Left upper arm var lUpperArm = self.attachAsset('puppet_upperarm', { anchorX: 0.5, anchorY: 0, scaleX: 1.5, scaleY: 1.5 }); // Left lower arm var lLowerArm = self.attachAsset('puppet_lowerarm', { anchorX: 0.5, anchorY: 0, scaleX: 1.5, scaleY: 1.5 }); // Right upper arm var rUpperArm = self.attachAsset('puppet_upperarm', { anchorX: 0.5, anchorY: 0, scaleX: 1.5, scaleY: 1.5 }); // Right lower arm var rLowerArm = self.attachAsset('puppet_lowerarm', { anchorX: 0.5, anchorY: 0, scaleX: 1.5, scaleY: 1.5 }); // Left upper leg var lUpperLeg = self.attachAsset('puppet_upperleg', { anchorX: 0.5, anchorY: 0, scaleX: 1.5, scaleY: 1.5 }); // Left lower leg var lLowerLeg = self.attachAsset('puppet_lowerleg', { anchorX: 0.5, anchorY: 0, scaleX: 1.5, scaleY: 1.5 }); // Right upper leg var rUpperLeg = self.attachAsset('puppet_upperleg', { anchorX: 0.5, anchorY: 0, scaleX: 1.5, scaleY: 1.5 }); // Right lower leg var rLowerLeg = self.attachAsset('puppet_lowerleg', { anchorX: 0.5, anchorY: 0, scaleX: 1.5, scaleY: 1.5 }); // --- Initial pose state --- self.state = { vx: 0, // horizontal velocity vy: 0, // vertical velocity grounded: false, pose: 'stand', // 'stand', 'sit', 'jump' headAngle: 0, // radians, for "pull head" actions x: 0, // world position y: 0 }; // --- Positioning offsets (relative to puppet center) --- function updateBodyParts() { // Head head.x = 0; head.y = -bodyH / 2 - headH / 2 + 10; head.rotation = self.state.headAngle; // Body body.x = 0; body.y = -bodyH / 2; // Arms var armY = -bodyH / 2 + 30; var armX = bodyW / 2 + upperArmW / 2 - 10; // --- Elbow kinematics --- // Shoulder positions var lShoulderX = -armX; var lShoulderY = armY; var rShoulderX = armX; var rShoulderY = armY; // Default arm pose angles var lUpperArmAngle = -0.25; var rUpperArmAngle = 0.25; // Pose-based arm animation if (self.state.pose === 'sit') { lUpperArmAngle = -1.1; rUpperArmAngle = 1.1; } else if (self.state.pose === 'jump') { lUpperArmAngle = -0.7; rUpperArmAngle = 0.7; } // Left upper arm lUpperArm.x = lShoulderX; lUpperArm.y = lShoulderY; lUpperArm.rotation = lUpperArmAngle; // Left elbow position var lElbowX = lUpperArm.x + Math.sin(lUpperArmAngle) * upperArmH; var lElbowY = lUpperArm.y + Math.cos(lUpperArmAngle) * upperArmH; // Left lower arm lLowerArm.x = lElbowX; lLowerArm.y = lElbowY; // Lower arm angle: point hand downward in stand, forward in sit/jump var lLowerArmAngle = 0.1; if (self.state.pose === 'sit') { lLowerArmAngle = 1.2; } else if (self.state.pose === 'jump') { lLowerArmAngle = 0.9; } lLowerArm.rotation = lLowerArmAngle; // Right upper arm rUpperArm.x = rShoulderX; rUpperArm.y = rShoulderY; rUpperArm.rotation = rUpperArmAngle; // Right elbow position var rElbowX = rUpperArm.x + Math.sin(rUpperArmAngle) * upperArmH; var rElbowY = rUpperArm.y + Math.cos(rUpperArmAngle) * upperArmH; // Right lower arm rLowerArm.x = rElbowX; rLowerArm.y = rElbowY; // Lower arm angle: point hand downward in stand, forward in sit/jump var rLowerArmAngle = -0.1; if (self.state.pose === 'sit') { rLowerArmAngle = -1.2; } else if (self.state.pose === 'jump') { rLowerArmAngle = -0.9; } rLowerArm.rotation = rLowerArmAngle; // Legs var legY = bodyH / 2 - 10; var legX = bodyW / 2 - 18; // --- Improved knee and foot connection with more natural kinematics --- // Default leg pose var lUpperLegAngle = 0.18; var rUpperLegAngle = -0.18; var lLowerLegAngle = 0.0; var rLowerLegAngle = 0.0; // Pose-based leg animation if (self.state.pose === 'sit') { lUpperLegAngle = 1.25; rUpperLegAngle = 1.25; lLowerLegAngle = lUpperLegAngle - Math.PI / 2; rLowerLegAngle = rUpperLegAngle - Math.PI / 2; } else if (self.state.pose === 'jump') { lUpperLegAngle = -0.7; rUpperLegAngle = -0.7; lLowerLegAngle = lUpperLegAngle + 1.55; rLowerLegAngle = rUpperLegAngle + 1.55; } else { // Standing: slight bend, foot under knee lLowerLegAngle = lUpperLegAngle + 0.12; rLowerLegAngle = rUpperLegAngle - 0.12; } // Left upper leg lUpperLeg.x = -legX; lUpperLeg.y = legY; lUpperLeg.rotation = lUpperLegAngle; // Calculate left knee position var lKneeX = lUpperLeg.x + Math.sin(lUpperLegAngle) * upperLegH; var lKneeY = lUpperLeg.y + Math.cos(lUpperLegAngle) * upperLegH; // Attach lower leg at knee, rotate for more natural foot placement lLowerLeg.x = lKneeX; lLowerLeg.y = lKneeY; lLowerLeg.rotation = lLowerLegAngle; // Right upper leg rUpperLeg.x = legX; rUpperLeg.y = legY; rUpperLeg.rotation = rUpperLegAngle; // Calculate right knee position var rKneeX = rUpperLeg.x + Math.sin(rUpperLegAngle) * upperLegH; var rKneeY = rUpperLeg.y + Math.cos(rUpperLegAngle) * upperLegH; // Attach lower leg at knee, rotate for more natural foot placement rLowerLeg.x = rKneeX; rLowerLeg.y = rKneeY; rLowerLeg.rotation = rLowerLegAngle; // Pose adjustments if (self.state.pose === 'sit') { // Sitting: thighs forward, knees bent, shins down lUpperLeg.rotation = 1.25; var lKneeX = lUpperLeg.x + Math.sin(lUpperLeg.rotation) * upperLegH; var lKneeY = lUpperLeg.y + Math.cos(lUpperLeg.rotation) * upperLegH; lLowerLeg.x = lKneeX; lLowerLeg.y = lKneeY; // Lower leg points down from knee lLowerLeg.rotation = lUpperLeg.rotation - Math.PI / 2; rUpperLeg.rotation = 1.25; var rKneeX = rUpperLeg.x + Math.sin(rUpperLeg.rotation) * upperLegH; var rKneeY = rUpperLeg.y + Math.cos(rUpperLeg.rotation) * upperLegH; rLowerLeg.x = rKneeX; rLowerLeg.y = rKneeY; rLowerLeg.rotation = rUpperLeg.rotation - Math.PI / 2; body.rotation = -0.2; } else if (self.state.pose === 'jump') { // Jump: legs up, knees bent lUpperLeg.rotation = -0.7; var lKneeX = lUpperLeg.x + Math.sin(lUpperLeg.rotation) * upperLegH; var lKneeY = lUpperLeg.y + Math.cos(lUpperLeg.rotation) * upperLegH; lLowerLeg.x = lKneeX; lLowerLeg.y = lKneeY; // Lower leg points forward from knee lLowerLeg.rotation = lUpperLeg.rotation + 1.55; rUpperLeg.rotation = -0.7; var rKneeX = rUpperLeg.x + Math.sin(rUpperLeg.rotation) * upperLegH; var rKneeY = rUpperLeg.y + Math.cos(rUpperLeg.rotation) * upperLegH; rLowerLeg.x = rKneeX; rLowerLeg.y = rKneeY; rLowerLeg.rotation = rUpperLeg.rotation + 1.55; body.rotation = 0.1; } else { body.rotation = 0; } } // --- Public puppet actions --- self.pullHeadLeft = function () { // Pull head left, add leftward velocity if (self.state.grounded) { self.state.vx -= 12; self.state.headAngle = -0.5; tween(self.state, { headAngle: 0 }, { duration: 400, easing: tween.easeOut }); } }; self.pullHeadRight = function () { if (self.state.grounded) { self.state.vx += 12; self.state.headAngle = 0.5; tween(self.state, { headAngle: 0 }, { duration: 400, easing: tween.easeOut }); } }; self.jump = function () { if (self.state.grounded) { self.state.vy = -48; // Increased jump velocity for higher jump self.state.grounded = false; self.state.pose = 'jump'; tween(self.state, {}, { duration: 0, onFinish: function onFinish() { // After 400ms, return to stand pose LK.setTimeout(function () { self.state.pose = 'stand'; }, 400); } }); } }; self.sit = function () { if (self.state.grounded && self.state.pose !== 'sit') { self.state.pose = 'sit'; // After 600ms, stand up automatically LK.setTimeout(function () { self.stand(); }, 600); } }; self.stand = function () { if (self.state.grounded && self.state.pose !== 'stand') { self.state.pose = 'stand'; } }; // --- Physics update --- self.update = function () { // Gravity if (!self.state.grounded) { self.state.vy += 2.2; // gravity if (self.state.vy > 40) self.state.vy = 40; } // Friction if (self.state.grounded) { self.state.vx *= 0.82; if (Math.abs(self.state.vx) < 0.5) self.state.vx = 0; } else { self.state.vx *= 0.98; } // Move self.state.x += self.state.vx; self.state.y += self.state.vy; // Clamp to world bounds if (self.state.x < 80) self.state.x = 80; if (self.state.x > 2048 - 80) self.state.x = 2048 - 80; // --- Ava: Adjust puppet Y so feet are above ground visually --- // The puppet's feet are at y + (bodyH/2) + upperLegH + lowerLegH - 10 - 10 // ground.y = 2732 - 80, ground height = 80 // So, puppet.y + (bodyH/2) + upperLegH + lowerLegH - 20 = 2732 - 80 // puppet.y = 2732 - 80 - (bodyH/2) - upperLegH - lowerLegH + 20 var puppetFeetOffset = bodyH / 2 + upperLegH + lowerLegH - 20; var puppetGroundY = 2732 - 80 - puppetFeetOffset; if (self.state.y > puppetGroundY) self.state.y = puppetGroundY; // above ground // Ground collision if (self.state.y >= puppetGroundY) { self.state.y = puppetGroundY; self.state.vy = 0; self.state.grounded = true; if (self.state.pose === 'jump') self.state.pose = 'stand'; } else { self.state.grounded = false; } // Apply to container self.x = self.state.x; self.y = self.state.y; updateBodyParts(); }; // --- Start position --- self.state.x = 600; // Moved puppet further right (was 180) // --- Ava: Set initial Y so feet are above ground visually --- var puppetFeetOffset = bodyH / 2 + upperLegH + lowerLegH - 20; self.state.y = 2732 - 80 - puppetFeetOffset; updateBodyParts(); return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ // Apply reverb to all drum and win/lose sounds // --- World setup --- // Puppet body parts (shapes) // Drums // Ground // Finish sign // Drum tap sound // Win/lose sound // Define and initialize the reverb object before using it var reverb = { add: function add(sound) { // Dummy implementation: does nothing, but prevents errors // In a real environment, this would apply a reverb effect to the sound } }; reverb.add(LK.getSound('drum_tap_center')); reverb.add(LK.getSound('drum_tap_left')); reverb.add(LK.getSound('drum_tap_right')); reverb.add(LK.getSound('drum_tap_sit')); reverb.add(LK.getSound('drum_tap_stand')); reverb.add(LK.getSound('lose')); reverb.add(LK.getSound('win')); game.setBackgroundColor(0x000000); // Ground var ground = LK.getAsset('ground', { anchorX: 0, anchorY: 0 }); ground.x = 0; ground.y = 2732 - 80; game.addChild(ground); // Finish sign var finishSign = LK.getAsset('finish_sign', { anchorX: 0.5, anchorY: 1, scaleX: 3, scaleY: 3 }); finishSign.x = 2048 - 120; finishSign.y = 2732 - 80; game.addChild(finishSign); var finishText = new Text2('FINISH', { size: 54, fill: '#ffffff' }); finishText.anchor.set(0.5, 0.5); finishText.x = finishSign.x; finishText.y = finishSign.y - finishSign.height / 2; game.addChild(finishText); // --- Puppet --- var puppet = new Puppet(); game.addChild(puppet); // --- Drums --- var drums = []; // Drum positions (relative to center) // Move drums higher: set drumCenterY above puppet's head var drumCenterX = 2048 / 2, drumCenterY = 900; // was 2732 / 2 + 220, now much higher (puppet head is around y=~1200) var drumRadius = 220 * 3; var angleList = [{ type: 'left', angle: -Math.PI / 2 - 0.7 }, { type: 'right', angle: -Math.PI / 2 + 0.7 }, { type: 'sit', angle: Math.PI / 2 + 0.7 }, { type: 'stand', angle: Math.PI / 2 - 0.7 }]; // --- Drum action pool --- // Each drum will have all actions, only their order will be shuffled // Ava: Increase the number of right movement actions (pullHeadRight) in the action pool var puppetActions = [function () { puppet.pullHeadLeft(); }, function () { puppet.pullHeadRight(); }, function () { puppet.pullHeadRight(); }, function () { puppet.jump(); }, function () { puppet.sit(); }, function () { puppet.stand(); }]; // Large center drum (fixed action sequence) var drumJump = new Drum(); drumJump.setDrum('large'); drumJump.x = drumCenterX; drumJump.y = drumCenterY; // Assign a fixed sequence of all 5 actions, and cycle through them drumJump._actionSequence = puppetActions.slice(); drumJump._actionIndex = 0; drumJump.action = function () { drumJump._actionSequence[drumJump._actionIndex](); drumJump._actionIndex = (drumJump._actionIndex + 1) % drumJump._actionSequence.length; }; game.addChild(drumJump); drums.push(drumJump); // Four medium drums for (var i = 0; i < angleList.length; ++i) { var d = new Drum(); d.setDrum(angleList[i].type); d.x = drumCenterX + Math.cos(angleList[i].angle) * drumRadius; d.y = drumCenterY + Math.sin(angleList[i].angle) * drumRadius; // Each drum gets a fixed sequence of all 5 actions, and cycles through them d._actionSequence = puppetActions.slice(); d._actionIndex = 0; d.action = function (drum) { return function () { drum._actionSequence[drum._actionIndex](); drum._actionIndex = (drum._actionIndex + 1) % drum._actionSequence.length; }; }(d); game.addChild(d); drums.push(d); } // --- Timer --- var timeLeft = 60; var timerText = new Text2('60', { size: 120, fill: '#ffffff' }); timerText.anchor.set(0.5, 0); LK.gui.top.addChild(timerText); // --- Score/Win state --- var gameEnded = false; // --- Timer logic --- var timerInterval = LK.setInterval(function () { if (gameEnded) return; timeLeft -= 1; if (timeLeft < 0) timeLeft = 0; timerText.setText(timeLeft); if (timeLeft === 0 && !gameEnded) { gameEnded = true; LK.getSound('lose').play(); LK.effects.flashScreen(0xff0000, 800); LK.showGameOver(); } }, 1000); // --- Game update --- game.update = function () { if (gameEnded) return; puppet.update(); // Win condition: puppet intersects finish sign if (puppet.x + 40 > finishSign.x - finishSign.width / 2 && puppet.x - 40 < finishSign.x + finishSign.width / 2 && puppet.y + 80 > finishSign.y - finishSign.height && puppet.y - 80 < finishSign.y) { if (!gameEnded) { gameEnded = true; LK.getSound('win').play(); LK.effects.flashScreen(0x44c767, 800); LK.showYouWin(); } } }; // --- Clean up on game over --- game.onDestroy = function () { LK.clearInterval(timerInterval); }; // --- Prevent accidental tap on top left (menu) --- /* No elements are placed at (0,0)-(100,100) */ // --- UX: drums are always on top --- for (var i = 0; i < drums.length; ++i) { game.addChild(drums[i]); }
===================================================================
--- original.js
+++ change.js
@@ -228,79 +228,52 @@
rLowerArm.rotation = rLowerArmAngle;
// Legs
var legY = bodyH / 2 - 10;
var legX = bodyW / 2 - 18;
- // --- Kinematic 2-bone IK for legs ---
- // Helper for 2-bone IK (returns {kneeX, kneeY, lowerAngle})
- function solveLegIK(hipX, hipY, footX, footY, upperLen, lowerLen, bendDir) {
- var dx = footX - hipX;
- var dy = footY - hipY;
- var dist = Math.sqrt(dx * dx + dy * dy);
- // Clamp to reachable
- var maxLen = upperLen + lowerLen - 1;
- if (dist > maxLen) dist = maxLen;
- // Law of cosines
- var a = upperLen,
- b = lowerLen,
- c = dist;
- var cosA = (b * b + c * c - a * a) / (2 * b * c);
- var cosB = (a * a + c * c - b * b) / (2 * a * c);
- // Clamp
- cosA = Math.max(-1, Math.min(1, cosA));
- cosB = Math.max(-1, Math.min(1, cosB));
- var angleC = Math.atan2(dy, dx);
- var angleA = Math.acos(cosA);
- var angleB = Math.acos(cosB);
- // Knee position
- var kneeX = hipX + Math.cos(angleC + bendDir * angleB) * upperLen;
- var kneeY = hipY + Math.sin(angleC + bendDir * angleB) * upperLen;
- // Lower leg angle
- var lowerAngle = angleC + bendDir * (angleB - angleA);
- return {
- kneeX: kneeX,
- kneeY: kneeY,
- lowerAngle: lowerAngle
- };
- }
- // --- Left leg ---
- lUpperLeg.x = -legX;
- lUpperLeg.y = legY;
- var leftFootY = bodyH / 2 + upperLegH + lowerLegH - 20; // relative to puppet center
- var leftFootX = lUpperLeg.x; // keep under hip by default
- // Pose-based foot placement
+ // --- Improved knee and foot connection with more natural kinematics ---
+ // Default leg pose
+ var lUpperLegAngle = 0.18;
+ var rUpperLegAngle = -0.18;
+ var lLowerLegAngle = 0.0;
+ var rLowerLegAngle = 0.0;
+ // Pose-based leg animation
if (self.state.pose === 'sit') {
- leftFootX = lUpperLeg.x + 60;
- leftFootY = bodyH / 2 + upperLegH + lowerLegH - 40;
+ lUpperLegAngle = 1.25;
+ rUpperLegAngle = 1.25;
+ lLowerLegAngle = lUpperLegAngle - Math.PI / 2;
+ rLowerLegAngle = rUpperLegAngle - Math.PI / 2;
} else if (self.state.pose === 'jump') {
- leftFootX = lUpperLeg.x + 40;
- leftFootY = bodyH / 2 + upperLegH + lowerLegH - 60;
+ lUpperLegAngle = -0.7;
+ rUpperLegAngle = -0.7;
+ lLowerLegAngle = lUpperLegAngle + 1.55;
+ rLowerLegAngle = rUpperLegAngle + 1.55;
+ } else {
+ // Standing: slight bend, foot under knee
+ lLowerLegAngle = lUpperLegAngle + 0.12;
+ rLowerLegAngle = rUpperLegAngle - 0.12;
}
- var lIK = solveLegIK(lUpperLeg.x, lUpperLeg.y, leftFootX, leftFootY, upperLegH, lowerLegH, 1);
- lUpperLeg.rotation = Math.atan2(lIK.kneeX - lUpperLeg.x, lIK.kneeY - lUpperLeg.y) - Math.PI / 2;
- lKneeX = lIK.kneeX;
- lKneeY = lIK.kneeY;
+ // Left upper leg
+ lUpperLeg.x = -legX;
+ lUpperLeg.y = legY;
+ lUpperLeg.rotation = lUpperLegAngle;
+ // Calculate left knee position
+ var lKneeX = lUpperLeg.x + Math.sin(lUpperLegAngle) * upperLegH;
+ var lKneeY = lUpperLeg.y + Math.cos(lUpperLegAngle) * upperLegH;
+ // Attach lower leg at knee, rotate for more natural foot placement
lLowerLeg.x = lKneeX;
lLowerLeg.y = lKneeY;
- lLowerLeg.rotation = Math.atan2(leftFootX - lKneeX, leftFootY - lKneeY) - Math.PI / 2;
- // --- Right leg ---
+ lLowerLeg.rotation = lLowerLegAngle;
+ // Right upper leg
rUpperLeg.x = legX;
rUpperLeg.y = legY;
- var rightFootY = bodyH / 2 + upperLegH + lowerLegH - 20;
- var rightFootX = rUpperLeg.x;
- if (self.state.pose === 'sit') {
- rightFootX = rUpperLeg.x + 60;
- rightFootY = bodyH / 2 + upperLegH + lowerLegH - 40;
- } else if (self.state.pose === 'jump') {
- rightFootX = rUpperLeg.x + 40;
- rightFootY = bodyH / 2 + upperLegH + lowerLegH - 60;
- }
- var rIK = solveLegIK(rUpperLeg.x, rUpperLeg.y, rightFootX, rightFootY, upperLegH, lowerLegH, 1);
- rUpperLeg.rotation = Math.atan2(rIK.kneeX - rUpperLeg.x, rIK.kneeY - rUpperLeg.y) - Math.PI / 2;
- rKneeX = rIK.kneeX;
- rKneeY = rIK.kneeY;
+ rUpperLeg.rotation = rUpperLegAngle;
+ // Calculate right knee position
+ var rKneeX = rUpperLeg.x + Math.sin(rUpperLegAngle) * upperLegH;
+ var rKneeY = rUpperLeg.y + Math.cos(rUpperLegAngle) * upperLegH;
+ // Attach lower leg at knee, rotate for more natural foot placement
rLowerLeg.x = rKneeX;
rLowerLeg.y = rKneeY;
- rLowerLeg.rotation = Math.atan2(rightFootX - rKneeX, rightFootY - rKneeY) - Math.PI / 2;
+ rLowerLeg.rotation = rLowerLegAngle;
// Pose adjustments
if (self.state.pose === 'sit') {
// Sitting: thighs forward, knees bent, shins down
lUpperLeg.rotation = 1.25;