User prompt
Bacakları bağdaş yap
User prompt
Sadece sit pozda sabit kal test için
User prompt
Sadece zıplama pozda sabit kalmayı kaldır test bitti.
User prompt
Bacaklar aynı hizada olsun
User prompt
Jum pozda alt bacaklar simetrik olsun
User prompt
Jump pozda üst bacakları swap yap
User prompt
Jump pozda diz bağlı kalsın
User prompt
Alt bacaklar jump pozda ust bacaklara bağlı değil
User prompt
Sadece zıplama pozda sabit kal test için
User prompt
Dizler ve alt bacakları düzgün bağla
User prompt
Dizler ve üst bacakları düzgün bağla
User prompt
Üst bacakları swap yap
User prompt
Alt bacakları swap yap
User prompt
Sol ve sağ vücut parçaları simetrik pozisyonda dursun ve tüm pozlarda simetrik hareket etsin
User prompt
Omuzlar vücudun sol üst ve sağ üst köşede olmalı
User prompt
Ayaklar en altta zemine deysin diğer uzuvlar njnun üstünde yükselsin.
User prompt
Sol dirsek sol omuza sag dirsek sağ omuza. Sag omuz sag kalçaya sol omuz sol kalçaya. Sol ayak bileği sol dize sol diz sol kalçaya. Sağ ayak bilegi sağ dize sağ diz sağ kalçaya bağlansın ik
User prompt
Bileklerin pozisyonunu alt bacakların alt kenarina bitişik yap.
User prompt
Ayaklar zeminde bilekler üstünde ve alt bacaklar ve kukla aynı hizada olsun
User prompt
Alt ayakların tam uçlarına koy bilekleri
User prompt
Sol sağ ayak bileği ve ayak assetleri ekle. Alt bacaklarla ayakları bileklerle birbirine bağla ik.
User prompt
Üst bacaklar alt bacaklardan önde gözüksün
User prompt
Alt bacakları swap yap.
User prompt
Alt bacakları yer değiştir.
User prompt
Alt bacakları biraz daha dışa aç
/**** * 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') { // Play with very long reverb effect if (typeof reverb !== "undefined" && reverb.add) { var leftSound = LK.getSound('drum_tap_left'); reverb.add(leftSound, { reverbTime: 3.5 }); // simulate very long reverb (if plugin supports param) leftSound.play(); } else { LK.getSound('drum_tap_left').play(); } } else if (self.drumType === 'right') { // Play with very long reverb effect if (typeof reverb !== "undefined" && reverb.add) { var rightSound = LK.getSound('drum_tap_right'); reverb.add(rightSound, { reverbTime: 3.5 }); // simulate very long reverb (if plugin supports param) rightSound.play(); } else { LK.getSound('drum_tap_right').play(); } } else if (self.drumType === 'sit') { var sitSound = LK.getSound('drum_tap_sit'); sitSound.play(); LK.setTimeout(function () { sitSound.play(); }, 120); } else if (self.drumType === 'stand') { // Play the sound with 3 fast delay effects (echoes) var base = LK.getSound('drum_tap_stand'); base.play(); LK.setTimeout(function () { base.play(); }, 45); LK.setTimeout(function () { base.play(); }, 90); } 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 }); // Neck (between head and body, sized to match hip) var neck = self.attachAsset('puppet_neck', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, // match hip scale scaleY: 1.5 }); // Shoulders (left and right) var lShoulder = self.attachAsset('puppet_shoulder', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 1.5 }); var rShoulder = self.attachAsset('puppet_shoulder', { 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 }); // Dual hips (left and right) var lHip = self.attachAsset('puppet_hip', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 1.5 }); var rHip = self.attachAsset('puppet_hip', { anchorX: 0.5, anchorY: 0.5, 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 elbow var lElbow = self.attachAsset('puppet_elbow', { anchorX: 0.5, anchorY: 0.5, 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 elbow var rElbow = self.attachAsset('puppet_elbow', { anchorX: 0.5, anchorY: 0.5, 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 lower leg var lLowerLeg = self.attachAsset('puppet_lowerleg', { 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 }); // Left upper leg var lUpperLeg = self.attachAsset('puppet_upperleg', { anchorX: 0.5, anchorY: 0, scaleX: 1.5, scaleY: 1.5 }); // Left knee var lKnee = self.attachAsset('puppet_knee', { anchorX: 0.5, anchorY: 0.5, 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 knee var rKnee = self.attachAsset('puppet_knee', { anchorX: 0.5, anchorY: 0.5, 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, // --- Ava: Leg rotation controls --- lUpperLegRotation: 0, // additional rotation for left upper leg rUpperLegRotation: 0, // additional rotation for right upper leg lLowerLegRotation: 0, // additional rotation for left lower leg rLowerLegRotation: 0 // additional rotation for right lower leg }; // --- Positioning offsets (relative to puppet center) --- function updateBodyParts() { // Head head.x = 0; head.y = -bodyH / 2 - headH / 2 - 30; head.rotation = self.state.headAngle; // Neck var hipH = 44 * 1.5; var neckH = hipH; neck.x = 0; neck.y = -bodyH / 2 - neckH / 2 + 38; neck.rotation = 0; // Body body.x = 0; body.y = -bodyH / 2; // --- Symmetric Arms --- var armY = -bodyH / 2 + 30; var armX = bodyW / 2 + upperArmW / 2 - 10; // Shoulders var lShoulderX = -armX; var lShoulderY = armY; var rShoulderX = armX; var rShoulderY = armY; lShoulder.x = lShoulderX; lShoulder.y = lShoulderY; rShoulder.x = rShoulderX; rShoulder.y = rShoulderY; // Default symmetric arm pose var armAbduction = 0.32; var baseUpperArmAngle = 0.0; var baseLowerArmAngle = 0.0; var lUpperArmAngle = -armAbduction + baseUpperArmAngle; var rUpperArmAngle = armAbduction + baseUpperArmAngle; var lLowerArmAngle = baseLowerArmAngle; var rLowerArmAngle = baseLowerArmAngle; // Symmetric pose-based arm animation if (self.state.pose === 'sit') { lUpperArmAngle = -1.25 - armAbduction; rUpperArmAngle = 1.25 + armAbduction; lLowerArmAngle = 1.5; rLowerArmAngle = -1.5; } else if (self.state.pose === 'jump') { lUpperArmAngle = -1.6 - armAbduction; rUpperArmAngle = 1.6 + armAbduction; lLowerArmAngle = 2.0; rLowerArmAngle = -2.0; } else if (self.state.pose === 'stand') { lUpperArmAngle += self.state.vx * 0.01; rUpperArmAngle -= self.state.vx * 0.01; lLowerArmAngle += Math.sin(Date.now() * 0.003) * 0.08; rLowerArmAngle -= Math.sin(Date.now() * 0.003) * 0.08; } // Left arm lUpperArm.x = lShoulderX; lUpperArm.y = lShoulderY; var lElbowX = lUpperArm.x + Math.sin(lUpperArmAngle) * upperArmH; var lElbowY = lUpperArm.y + Math.cos(lUpperArmAngle) * upperArmH; lElbow.x = lElbowX; lElbow.y = lElbowY; lUpperArm.rotation = Math.atan2(lElbow.y - lUpperArm.y, lElbow.x - lUpperArm.x) - Math.PI / 2; lLowerArm.x = lElbowX; lLowerArm.y = lElbowY; lLowerArm.rotation = lLowerArmAngle; // Right arm (mirror of left) rUpperArm.x = rShoulderX; rUpperArm.y = rShoulderY; var rElbowX = rUpperArm.x + Math.sin(rUpperArmAngle) * upperArmH; var rElbowY = rUpperArm.y + Math.cos(rUpperArmAngle) * upperArmH; rElbow.x = rElbowX; rElbow.y = rElbowY; rUpperArm.rotation = Math.atan2(rElbow.y - rUpperArm.y, rElbow.x - rUpperArm.x) - Math.PI / 2; rLowerArm.x = rElbowX; rLowerArm.y = rElbowY; rLowerArm.rotation = rLowerArmAngle; // --- Symmetric Legs --- var legY = bodyH / 2 - 10; var legX = bodyW / 2 - 18; // Hips var lHipX = -legX; var lHipY = legY; var rHipX = legX; var rHipY = legY; lHip.x = lHipX; lHip.y = lHipY; rHip.x = rHipX; rHip.y = rHipY; // Default symmetric leg pose var legAbduction = 0.28; var lowerLegOutAngle = 0.38; var lUpperLegAngle = legAbduction + (self.state.lUpperLegRotation || 0); var rUpperLegAngle = -legAbduction + (self.state.rUpperLegRotation || 0); var lLowerLegAngle = lowerLegOutAngle + (self.state.lLowerLegRotation || 0); var rLowerLegAngle = -lowerLegOutAngle + (self.state.rLowerLegRotation || 0); // Symmetric pose-based leg animation if (self.state.pose === 'sit') { // Both thighs forward, knees together, shins down, using IK var hipsMidX = (lHip.x + rHip.x) / 2; var hipsMidY = (lHip.y + rHip.y) / 2; var thighAngle = 1.32; var kneeOffsetX = Math.sin(thighAngle) * upperLegH; var kneeOffsetY = Math.cos(thighAngle) * upperLegH; var kneeX = hipsMidX + kneeOffsetX; var kneeY = hipsMidY + kneeOffsetY; // Both upper legs: hips to common knee lUpperLeg.x = lHip.x; lUpperLeg.y = lHip.y; lUpperLeg.rotation = Math.atan2(kneeY - lUpperLeg.y, kneeX - lUpperLeg.x) - Math.PI / 2; rUpperLeg.x = rHip.x; rUpperLeg.y = rHip.y; rUpperLeg.rotation = Math.atan2(kneeY - rUpperLeg.y, kneeX - rUpperLeg.x) - Math.PI / 2; // Both knees at same position lKnee.x = kneeX; lKnee.y = kneeY; rKnee.x = kneeX; rKnee.y = kneeY; // Both lower legs: from knee, bent downward, mirrored lLowerLeg.x = kneeX; lLowerLeg.y = kneeY; lLowerLeg.rotation = lUpperLeg.rotation - Math.PI / 2 + 0.18; rLowerLeg.x = kneeX; rLowerLeg.y = kneeY; rLowerLeg.rotation = rUpperLeg.rotation - Math.PI / 2 - 0.18; body.rotation = 0; } else if (self.state.pose === 'jump') { // Both upper legs up and slightly inward, knees together, feet up, using IK var jumpThighAngle = 0.45; // Left leg lUpperLeg.x = lHip.x; lUpperLeg.y = lHip.y; lUpperLeg.rotation = -jumpThighAngle - legAbduction; var lKneeX = lUpperLeg.x + Math.sin(lUpperLeg.rotation) * upperLegH; var lKneeY = lUpperLeg.y + Math.cos(lUpperLeg.rotation) * upperLegH; lKnee.x = lKneeX; lKnee.y = lKneeY; lLowerLeg.x = lKneeX; lLowerLeg.y = lKneeY; lLowerLeg.rotation = lUpperLeg.rotation + 2.5; // Right leg (mirror) rUpperLeg.x = rHip.x; rUpperLeg.y = rHip.y; rUpperLeg.rotation = jumpThighAngle + legAbduction; var rKneeX = rUpperLeg.x + Math.sin(rUpperLeg.rotation) * upperLegH; var rKneeY = rUpperLeg.y + Math.cos(rUpperLeg.rotation) * upperLegH; rKnee.x = rKneeX; rKnee.y = rKneeY; rLowerLeg.x = rKneeX; rLowerLeg.y = rKneeY; rLowerLeg.rotation = rUpperLeg.rotation + 2.5; // Elbows more bent in jump lLowerArm.x = lElbow.x; lLowerArm.y = lElbow.y; lLowerArm.rotation = 2.0; rLowerArm.x = rElbow.x; rLowerArm.y = rElbow.y; rLowerArm.rotation = -2.0; body.rotation = 0; } else if (self.state.pose === 'stand') { // Gentle walk cycle if moving var walk = Math.abs(self.state.vx) > 0.5 ? Math.sin(Date.now() * 0.008) * 0.25 : 0; lUpperLegAngle += walk; rUpperLegAngle -= walk; lLowerLegAngle += walk * 0.5; rLowerLegAngle -= walk * 0.5; // Left leg lUpperLeg.x = lHip.x; lUpperLeg.y = lHip.y; var lKneeX = lUpperLeg.x + Math.sin(lUpperLegAngle) * upperLegH; var lKneeY = lUpperLeg.y + Math.cos(lUpperLegAngle) * upperLegH; lKnee.x = lKneeX; lKnee.y = lKneeY; lUpperLeg.rotation = Math.atan2(lKnee.y - lUpperLeg.y, lKnee.x - lUpperLeg.x) - Math.PI / 2; lLowerLeg.x = lKneeX; lLowerLeg.y = lKneeY; lLowerLeg.rotation = lLowerLegAngle; // Right leg (mirror) rUpperLeg.x = rHip.x; rUpperLeg.y = rHip.y; var rKneeX = rUpperLeg.x + Math.sin(rUpperLegAngle) * upperLegH; var rKneeY = rUpperLeg.y + Math.cos(rUpperLegAngle) * upperLegH; rKnee.x = rKneeX; rKnee.y = rKneeY; rUpperLeg.rotation = Math.atan2(rKnee.y - rUpperLeg.y, rKnee.x - rUpperLeg.x) - Math.PI / 2; rLowerLeg.x = rKneeX; rLowerLeg.y = rKneeY; rLowerLeg.rotation = rLowerLegAngle; 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 ****/ // Define and initialize the reverb object before using it // Win/lose sound // Drum tap sound // Finish sign // Ground // Drums // Puppet body parts (shapes) // --- World setup --- // Apply reverb to all drum and win/lose sounds // Ava: background asset 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')); // --- Background music playlist (4 tracks, play in random order) --- var musicTracks = [{ id: 'musicId', volume: 0.1, start: 0, end: 1 }, { id: 'musicId2', volume: 0.1, start: 0, end: 1 }, { id: 'musicId3', volume: 0.1, start: 0, end: 1 }, { id: 'musicId4', volume: 0.1, start: 0, end: 1 }]; // Shuffle helper (Fisher-Yates) function shuffleArray(arr) { for (var i = arr.length - 1; i > 0; i--) { var j = Math.floor(Math.random() * (i + 1)); var temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } } // Maintain a shuffled playlist order var shuffledMusicOrder = []; function reshuffleMusicOrder() { shuffledMusicOrder = []; for (var i = 0; i < musicTracks.length; ++i) shuffledMusicOrder.push(i); shuffleArray(shuffledMusicOrder); } reshuffleMusicOrder(); var currentMusicOrderIndex = 0; // Play the next music track in the shuffled order, and keep playing forever function playNextMusic() { // If we've played all, reshuffle for a new random order if (currentMusicOrderIndex >= shuffledMusicOrder.length) { reshuffleMusicOrder(); currentMusicOrderIndex = 0; } var trackIndex = shuffledMusicOrder[currentMusicOrderIndex]; var track = musicTracks[trackIndex]; // Play music and set up onFinish to play the next one LK.playMusic(track.id, { loop: false, volume: track.volume, start: track.start, end: track.end, onFinish: function onFinish() { currentMusicOrderIndex++; playNextMusic(); } }); } playNextMusic(); game.setBackgroundColor(0x000000); // --- Background --- // Ava: Add background image behind all elements var background = LK.getAsset('background', { anchorX: 0, anchorY: 0, x: 0, y: 0, scaleX: 1, scaleY: 1 }); game.addChild(background); // 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: 6 // 2x as tall as before }); finishSign.x = 2048 - 120; finishSign.y = 2732 - 80; game.addChild(finishSign); // Finish text removed // --- 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; function formatTimeDigital(secs) { var m = Math.floor(secs / 60); var s = secs % 60; var mm = m < 10 ? "0" + m : "" + m; var ss = s < 10 ? "0" + s : "" + s; return mm + ":" + ss; } var timerText = new Text2(formatTimeDigital(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(formatTimeDigital(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 body collides with finish sign using intersects if (!gameEnded && puppet.intersects(finishSign)) { gameEnded = true; LK.setScore(timeLeft); // Set score to remaining seconds 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
@@ -209,36 +209,8 @@
anchorY: 0,
scaleX: 1.5,
scaleY: 1.5
});
- // Left ankle
- var lAnkle = self.attachAsset('puppet_ankle', {
- anchorX: 0.5,
- anchorY: 0.5,
- scaleX: 1.5,
- scaleY: 1.5
- });
- // Right ankle
- var rAnkle = self.attachAsset('puppet_ankle', {
- anchorX: 0.5,
- anchorY: 0.5,
- scaleX: 1.5,
- scaleY: 1.5
- });
- // Left foot
- var lFoot = self.attachAsset('puppet_foot', {
- anchorX: 0.5,
- anchorY: 0.2,
- scaleX: 1.5,
- scaleY: 1.5
- });
- // Right foot
- var rFoot = self.attachAsset('puppet_foot', {
- anchorX: 0.5,
- anchorY: 0.2,
- scaleX: 1.5,
- scaleY: 1.5
- });
// Left upper leg
var lUpperLeg = self.attachAsset('puppet_upperleg', {
anchorX: 0.5,
anchorY: 0,
@@ -292,324 +264,190 @@
// --- Positioning offsets (relative to puppet center) ---
function updateBodyParts() {
// Head
head.x = 0;
- // Move head higher above the neck for a more natural look (was +10, now -30 for more separation)
head.y = -bodyH / 2 - headH / 2 - 30;
head.rotation = self.state.headAngle;
- // Neck: place between head and body, sized to match hip
- // Use hip asset size for neck size/placement
- var hipH = 44 * 1.5; // puppet_hip height * scale
+ // Neck
+ var hipH = 44 * 1.5;
var neckH = hipH;
neck.x = 0;
- neck.y = -bodyH / 2 - neckH / 2 + 38; // 38 is a small offset to visually connect neck, adjust as needed
+ neck.y = -bodyH / 2 - neckH / 2 + 38;
neck.rotation = 0;
// Body
body.x = 0;
body.y = -bodyH / 2;
- // Arms
+ // --- Symmetric Arms ---
var armY = -bodyH / 2 + 30;
var armX = bodyW / 2 + upperArmW / 2 - 10;
- // Shoulder positions: place at top left and top right corners of the body
- var lShoulderX = -bodyW / 2;
- var lShoulderY = -bodyH / 2;
- var rShoulderX = bodyW / 2;
- var rShoulderY = -bodyH / 2;
- // Place shoulder assets at shoulder positions
+ // Shoulders
+ var lShoulderX = -armX;
+ var lShoulderY = armY;
+ var rShoulderX = armX;
+ var rShoulderY = armY;
lShoulder.x = lShoulderX;
lShoulder.y = lShoulderY;
rShoulder.x = rShoulderX;
rShoulder.y = rShoulderY;
- // --- Improved arm kinematics ---
- // Default arm pose angles (arms down, but slightly outward)
- var armAbduction = 0.32; // outward angle in radians (~18deg)
- var lUpperArmAngle = -armAbduction; // left arm slightly outward
- var rUpperArmAngle = armAbduction; // right arm slightly outward
- var lLowerArmAngle = 0; // straight
- var rLowerArmAngle = 0; // straight
- // Pose-based arm animation
+ // Default symmetric arm pose
+ var armAbduction = 0.32;
+ var baseUpperArmAngle = 0.0;
+ var baseLowerArmAngle = 0.0;
+ var lUpperArmAngle = -armAbduction + baseUpperArmAngle;
+ var rUpperArmAngle = armAbduction + baseUpperArmAngle;
+ var lLowerArmAngle = baseLowerArmAngle;
+ var rLowerArmAngle = baseLowerArmAngle;
+ // Symmetric pose-based arm animation
if (self.state.pose === 'sit') {
lUpperArmAngle = -1.25 - armAbduction;
rUpperArmAngle = 1.25 + armAbduction;
lLowerArmAngle = 1.5;
rLowerArmAngle = -1.5;
} else if (self.state.pose === 'jump') {
- // In jump pose, upper arms are raised up and slightly outward
- lUpperArmAngle = -1.6 - armAbduction; // sol üst kol yukarı ve dışa
- rUpperArmAngle = 1.6 + armAbduction; // sağ üst kol yukarı ve dışa
+ lUpperArmAngle = -1.6 - armAbduction;
+ rUpperArmAngle = 1.6 + armAbduction;
lLowerArmAngle = 2.0;
rLowerArmAngle = -2.0;
- // --- Maintain shoulder-elbow connection in jump pose ---
- var lElbowX = lUpperArm.x + Math.sin(lUpperArmAngle) * upperArmH;
- var lElbowY = lUpperArm.y + Math.cos(lUpperArmAngle) * upperArmH;
- lElbow.x = lElbowX;
- lElbow.y = lElbowY;
- var rElbowX = rUpperArm.x + Math.sin(rUpperArmAngle) * upperArmH;
- var rElbowY = rUpperArm.y + Math.cos(rUpperArmAngle) * upperArmH;
- rElbow.x = rElbowX;
- rElbow.y = rElbowY;
} else if (self.state.pose === 'stand') {
- // Gentle swing based on horizontal velocity for more life
lUpperArmAngle += self.state.vx * 0.01;
rUpperArmAngle -= self.state.vx * 0.01;
lLowerArmAngle += Math.sin(Date.now() * 0.003) * 0.08;
rLowerArmAngle -= Math.sin(Date.now() * 0.003) * 0.08;
}
- // Left upper arm: connect from left shoulder to left elbow
- lUpperArm.x = lShoulder.x;
- lUpperArm.y = lShoulder.y;
- lUpperArm.rotation = Math.atan2(lElbow.y - lShoulder.y, lElbow.x - lShoulder.x) - Math.PI / 2;
+ // Left arm
+ lUpperArm.x = lShoulderX;
+ lUpperArm.y = lShoulderY;
var lElbowX = lUpperArm.x + Math.sin(lUpperArmAngle) * upperArmH;
var lElbowY = lUpperArm.y + Math.cos(lUpperArmAngle) * upperArmH;
lElbow.x = lElbowX;
lElbow.y = lElbowY;
- // Left lower arm: connect from left elbow outward
+ lUpperArm.rotation = Math.atan2(lElbow.y - lUpperArm.y, lElbow.x - lUpperArm.x) - Math.PI / 2;
lLowerArm.x = lElbowX;
lLowerArm.y = lElbowY;
lLowerArm.rotation = lLowerArmAngle;
- // Right upper arm: connect from right shoulder to right elbow
- rUpperArm.x = rShoulder.x;
- rUpperArm.y = rShoulder.y;
- rUpperArm.rotation = Math.atan2(rElbow.y - rShoulder.y, rElbow.x - rShoulder.x) - Math.PI / 2;
+ // Right arm (mirror of left)
+ rUpperArm.x = rShoulderX;
+ rUpperArm.y = rShoulderY;
var rElbowX = rUpperArm.x + Math.sin(rUpperArmAngle) * upperArmH;
var rElbowY = rUpperArm.y + Math.cos(rUpperArmAngle) * upperArmH;
rElbow.x = rElbowX;
rElbow.y = rElbowY;
- // Right lower arm: connect from right elbow outward
+ rUpperArm.rotation = Math.atan2(rElbow.y - rUpperArm.y, rElbow.x - rUpperArm.x) - Math.PI / 2;
rLowerArm.x = rElbowX;
rLowerArm.y = rElbowY;
rLowerArm.rotation = rLowerArmAngle;
- // Connect shoulders to hips
- lShoulder.x = lHip.x;
- lShoulder.y = lHip.y - 120; // offset up from hip for shoulder
- rShoulder.x = rHip.x;
- rShoulder.y = rHip.y - 120;
- // Left ankle to left knee, left knee to left hip
- lKnee.x = lHip.x + Math.sin(lUpperLegAngle) * upperLegH;
- lKnee.y = lHip.y + Math.cos(lUpperLegAngle) * upperLegH;
- lLowerLeg.x = lKnee.x;
- lLowerLeg.y = lKnee.y;
- lLowerLeg.rotation = lLowerLegAngle;
- lAnkle.x = lLowerLeg.x + Math.sin(lLowerLeg.rotation) * (lowerLegH - 28 * 1.5 / 2);
- lAnkle.y = lLowerLeg.y + Math.cos(lLowerLeg.rotation) * (lowerLegH - 28 * 1.5 / 2);
- // Right ankle to right knee, right knee to right hip
- rKnee.x = rHip.x + Math.sin(rUpperLegAngle) * upperLegH;
- rKnee.y = rHip.y + Math.cos(rUpperLegAngle) * upperLegH;
- rLowerLeg.x = rKnee.x;
- rLowerLeg.y = rKnee.y;
- rLowerLeg.rotation = rLowerLegAngle;
- rAnkle.x = rLowerLeg.x + Math.sin(rLowerLeg.rotation) * (lowerLegH - 28 * 1.5 / 2);
- rAnkle.y = rLowerLeg.y + Math.cos(rLowerLeg.rotation) * (lowerLegH - 28 * 1.5 / 2);
- // Left foot at left ankle
- lFoot.x = lAnkle.x;
- lFoot.y = lAnkle.y;
- lFoot.rotation = lLowerLeg.rotation;
- // Right foot at right ankle
- rFoot.x = rAnkle.x;
- rFoot.y = rAnkle.y;
- rFoot.rotation = rLowerLeg.rotation;
- // --- Improved leg kinematics ---
+ // --- Symmetric Legs ---
var legY = bodyH / 2 - 10;
var legX = bodyW / 2 - 18;
- // Hip positions (left and right)
+ // Hips
var lHipX = -legX;
var lHipY = legY;
var rHipX = legX;
var rHipY = legY;
lHip.x = lHipX;
lHip.y = lHipY;
rHip.x = rHipX;
rHip.y = rHipY;
- // Default leg pose (narrower stance)
- var legAbduction = 0.28; // outward angle in radians (~16deg), reduced for a more closed stance
- // --- Ava: Make lower legs angle outward more ---
- var lowerLegOutAngle = 0.38; // outward angle for lower legs (was 0.25, now more open)
+ // Default symmetric leg pose
+ var legAbduction = 0.28;
+ var lowerLegOutAngle = 0.38;
var lUpperLegAngle = legAbduction + (self.state.lUpperLegRotation || 0);
var rUpperLegAngle = -legAbduction + (self.state.rUpperLegRotation || 0);
var lLowerLegAngle = lowerLegOutAngle + (self.state.lLowerLegRotation || 0);
var rLowerLegAngle = -lowerLegOutAngle + (self.state.rLowerLegRotation || 0);
- // Pose-based leg animation
+ // Symmetric pose-based leg animation
if (self.state.pose === 'sit') {
- lUpperLegAngle = 1.35 + (self.state.lUpperLegRotation || 0);
- rUpperLegAngle = 1.35 + (self.state.rUpperLegRotation || 0);
- lLowerLegAngle = lUpperLegAngle - Math.PI / 2 + 0.32 + (self.state.lLowerLegRotation || 0); // was 0.15, now more outward
- rLowerLegAngle = rUpperLegAngle - Math.PI / 2 - 0.32 + (self.state.rLowerLegRotation || 0); // was 0.15, now more outward
- } else if (self.state.pose === 'jump') {
- // In jump pose, upper legs are raised up and slightly outward
- lUpperLegAngle = -0.9 - legAbduction + (self.state.lUpperLegRotation || 0); // sol üst bacak yukarı ve dışa
- rUpperLegAngle = 0.9 + legAbduction + (self.state.rUpperLegRotation || 0); // sağ üst bacak yukarı ve dışa
- lLowerLegAngle = lUpperLegAngle + 2.35 + (self.state.lLowerLegRotation || 0); // was 2.1, now more outward
- rLowerLegAngle = rUpperLegAngle + 2.35 + (self.state.rLowerLegRotation || 0); // was 2.1, now more outward
- } else if (self.state.pose === 'stand') {
- // Gentle walk cycle if moving
- var walk = Math.abs(self.state.vx) > 0.5 ? Math.sin(Date.now() * 0.008) * 0.25 : 0;
- lUpperLegAngle += walk;
- rUpperLegAngle -= walk;
- lLowerLegAngle += walk * 0.5;
- rLowerLegAngle -= walk * 0.5;
- }
- // Left upper leg: connect from right hip to left knee (swapped knees)
- lUpperLeg.x = rHip.x;
- lUpperLeg.y = rHip.y;
- // Calculate left knee position (swapped)
- var lKneeX = lUpperLeg.x + Math.sin(lUpperLegAngle) * upperLegH;
- var lKneeY = lUpperLeg.y + Math.cos(lUpperLegAngle) * upperLegH;
- lKnee.x = lKneeX;
- lKnee.y = lKneeY;
- lUpperLeg.rotation = Math.atan2(lKnee.y - lUpperLeg.y, lKnee.x - lUpperLeg.x) - Math.PI / 2;
- // Attach right lower leg at left knee (swap lower legs)
- rLowerLeg.x = lKneeX;
- rLowerLeg.y = lKneeY;
- rLowerLeg.rotation = lLowerLegAngle;
- // --- Ankles and feet (default pose) ---
- // Right lower leg (attached at left knee) → right ankle
- // Place ankle so its top edge is flush with the bottom of the lower leg
- var rAnkleRadius = 28 * 1.5 / 2; // puppet_ankle height * scale / 2
- var rAnkleX = rLowerLeg.x + Math.sin(rLowerLeg.rotation) * (lowerLegH - rAnkleRadius);
- var rAnkleY = rLowerLeg.y + Math.cos(rLowerLeg.rotation) * (lowerLegH - rAnkleRadius);
- rAnkle.x = rAnkleX;
- rAnkle.y = rAnkleY;
- // Right foot at right ankle, pointing forward
- rFoot.x = rAnkleX;
- rFoot.y = rAnkleY;
- rFoot.rotation = rLowerLeg.rotation;
- // Right upper leg: connect from left hip to right knee (swapped knees)
- rUpperLeg.x = lHip.x;
- rUpperLeg.y = lHip.y;
- // Calculate right knee position (swapped)
- var rKneeX = rUpperLeg.x + Math.sin(rUpperLegAngle) * upperLegH;
- var rKneeY = rUpperLeg.y + Math.cos(rUpperLegAngle) * upperLegH;
- rKnee.x = rKneeX;
- rKnee.y = rKneeY;
- rUpperLeg.rotation = Math.atan2(rKnee.y - rUpperLeg.y, rKnee.x - rUpperLeg.x) - Math.PI / 2;
- // Attach left lower leg at right knee (swap lower legs)
- lLowerLeg.x = rKneeX;
- lLowerLeg.y = rKneeY;
- lLowerLeg.rotation = rLowerLegAngle;
- // Left lower leg (attached at right knee) → left ankle
- // Place ankle so its top edge is flush with the bottom of the lower leg
- var lAnkleRadius = 28 * 1.5 / 2; // puppet_ankle height * scale / 2
- var lAnkleX = lLowerLeg.x + Math.sin(lLowerLeg.rotation) * (lowerLegH - lAnkleRadius);
- var lAnkleY = lLowerLeg.y + Math.cos(lLowerLeg.rotation) * (lowerLegH - lAnkleRadius);
- lAnkle.x = lAnkleX;
- lAnkle.y = lAnkleY;
- // Left foot at left ankle, pointing forward
- lFoot.x = lAnkleX;
- lFoot.y = lAnkleY;
- lFoot.rotation = lLowerLeg.rotation;
- // Pose adjustments
- if (self.state.pose === 'sit') {
- // Sitting: both thighs forward, knees bent, knees together, shins down, using IK
- // Both upper legs start from hips and point forward, knees together in the middle
- // Calculate a common knee position between the two hips for "knees together"
+ // Both thighs forward, knees together, shins down, using IK
var hipsMidX = (lHip.x + rHip.x) / 2;
var hipsMidY = (lHip.y + rHip.y) / 2;
- // Angle for thighs: forward (down), slightly inward
var thighAngle = 1.32;
- // Distance from hip to knee
var kneeOffsetX = Math.sin(thighAngle) * upperLegH;
var kneeOffsetY = Math.cos(thighAngle) * upperLegH;
- // Both knees at the same position (knees together)
var kneeX = hipsMidX + kneeOffsetX;
var kneeY = hipsMidY + kneeOffsetY;
- // Left upper leg: right hip to common knee
- lUpperLeg.x = rHip.x;
- lUpperLeg.y = rHip.y;
+ // Both upper legs: hips to common knee
+ lUpperLeg.x = lHip.x;
+ lUpperLeg.y = lHip.y;
lUpperLeg.rotation = Math.atan2(kneeY - lUpperLeg.y, kneeX - lUpperLeg.x) - Math.PI / 2;
+ rUpperLeg.x = rHip.x;
+ rUpperLeg.y = rHip.y;
+ rUpperLeg.rotation = Math.atan2(kneeY - rUpperLeg.y, kneeX - rUpperLeg.x) - Math.PI / 2;
+ // Both knees at same position
lKnee.x = kneeX;
lKnee.y = kneeY;
- // Right lower leg: from knee, bent downward (swap lower legs)
- rLowerLeg.x = kneeX;
- rLowerLeg.y = kneeY;
- rLowerLeg.rotation = lUpperLeg.rotation - Math.PI / 2 + 0.18;
- // Right ankle and foot (sit)
- // Place ankle so its top edge is flush with the bottom of the lower leg
- var rAnkleRadius = 28 * 1.5 / 2;
- var rAnkleX = rLowerLeg.x + Math.sin(rLowerLeg.rotation) * (lowerLegH - rAnkleRadius);
- var rAnkleY = rLowerLeg.y + Math.cos(rLowerLeg.rotation) * (lowerLegH - rAnkleRadius);
- rAnkle.x = rAnkleX;
- rAnkle.y = rAnkleY;
- rFoot.x = rAnkleX;
- rFoot.y = rAnkleY;
- rFoot.rotation = rLowerLeg.rotation;
- // Right upper leg: left hip to common knee
- rUpperLeg.x = lHip.x;
- rUpperLeg.y = lHip.y;
- rUpperLeg.rotation = Math.atan2(kneeY - rUpperLeg.y, kneeX - rUpperLeg.x) - Math.PI / 2;
rKnee.x = kneeX;
rKnee.y = kneeY;
- // Left lower leg: from knee, bent downward (swap lower legs)
+ // Both lower legs: from knee, bent downward, mirrored
lLowerLeg.x = kneeX;
lLowerLeg.y = kneeY;
- lLowerLeg.rotation = rUpperLeg.rotation - Math.PI / 2 - 0.18;
- // Left ankle and foot (sit)
- // Place ankle so its top edge is flush with the bottom of the lower leg
- var lAnkleRadius = 28 * 1.5 / 2;
- var lAnkleX = lLowerLeg.x + Math.sin(lLowerLeg.rotation) * (lowerLegH - lAnkleRadius);
- var lAnkleY = lLowerLeg.y + Math.cos(lLowerLeg.rotation) * (lowerLegH - lAnkleRadius);
- lAnkle.x = lAnkleX;
- lAnkle.y = lAnkleY;
- lFoot.x = lAnkleX;
- lFoot.y = lAnkleY;
- lFoot.rotation = lLowerLeg.rotation;
- body.rotation = -0.18;
+ lLowerLeg.rotation = lUpperLeg.rotation - Math.PI / 2 + 0.18;
+ rLowerLeg.x = kneeX;
+ rLowerLeg.y = kneeY;
+ rLowerLeg.rotation = rUpperLeg.rotation - Math.PI / 2 - 0.18;
+ body.rotation = 0;
} else if (self.state.pose === 'jump') {
- // Jump: both legs bend at the knees, knees close together, feet up, using IK
- // --- Left leg (right hip to left knee) ---
- lUpperLeg.x = rHip.x;
- lUpperLeg.y = rHip.y;
- // Both upper legs point downward but slightly inward for knees-together
- lUpperLeg.rotation = -0.45 - legAbduction; // up and slightly inward
+ // Both upper legs up and slightly inward, knees together, feet up, using IK
+ var jumpThighAngle = 0.45;
+ // Left leg
+ lUpperLeg.x = lHip.x;
+ lUpperLeg.y = lHip.y;
+ lUpperLeg.rotation = -jumpThighAngle - legAbduction;
var lKneeX = lUpperLeg.x + Math.sin(lUpperLeg.rotation) * upperLegH;
var lKneeY = lUpperLeg.y + Math.cos(lUpperLeg.rotation) * upperLegH;
lKnee.x = lKneeX;
lKnee.y = lKneeY;
- // Right lower leg bends sharply upward, keeping connected at left knee (swap lower legs)
- rLowerLeg.x = lKnee.x;
- rLowerLeg.y = lKnee.y;
- rLowerLeg.rotation = lUpperLeg.rotation + 2.5; // sharp bend
- // Right ankle and foot (jump)
- // Place ankle so its top edge is flush with the bottom of the lower leg
- var rAnkleRadius = 28 * 1.5 / 2;
- var rAnkleX = rLowerLeg.x + Math.sin(rLowerLeg.rotation) * (lowerLegH - rAnkleRadius);
- var rAnkleY = rLowerLeg.y + Math.cos(rLowerLeg.rotation) * (lowerLegH - rAnkleRadius);
- rAnkle.x = rAnkleX;
- rAnkle.y = rAnkleY;
- rFoot.x = rAnkleX;
- rFoot.y = rAnkleY;
- rFoot.rotation = rLowerLeg.rotation;
- // --- Right leg (left hip to right knee) ---
- rUpperLeg.x = lHip.x;
- rUpperLeg.y = lHip.y;
- rUpperLeg.rotation = 0.45 + legAbduction; // up and slightly inward
+ lLowerLeg.x = lKneeX;
+ lLowerLeg.y = lKneeY;
+ lLowerLeg.rotation = lUpperLeg.rotation + 2.5;
+ // Right leg (mirror)
+ rUpperLeg.x = rHip.x;
+ rUpperLeg.y = rHip.y;
+ rUpperLeg.rotation = jumpThighAngle + legAbduction;
var rKneeX = rUpperLeg.x + Math.sin(rUpperLeg.rotation) * upperLegH;
var rKneeY = rUpperLeg.y + Math.cos(rUpperLeg.rotation) * upperLegH;
rKnee.x = rKneeX;
rKnee.y = rKneeY;
- // Left lower leg bends sharply upward, keeping connected at right knee (swap lower legs)
- lLowerLeg.x = rKneeX;
- lLowerLeg.y = rKneeY;
- lLowerLeg.rotation = rUpperLeg.rotation + 2.5; // sharp bend
- // Left ankle and foot (jump)
- // Place ankle so its top edge is flush with the bottom of the lower leg
- var lAnkleRadius = 28 * 1.5 / 2;
- var lAnkleX = lLowerLeg.x + Math.sin(lLowerLeg.rotation) * (lowerLegH - lAnkleRadius);
- var lAnkleY = lLowerLeg.y + Math.cos(lLowerLeg.rotation) * (lowerLegH - lAnkleRadius);
- lAnkle.x = lAnkleX;
- lAnkle.y = lAnkleY;
- lFoot.x = lAnkleX;
- lFoot.y = lAnkleY;
- lFoot.rotation = lLowerLeg.rotation;
+ rLowerLeg.x = rKneeX;
+ rLowerLeg.y = rKneeY;
+ rLowerLeg.rotation = rUpperLeg.rotation + 2.5;
// Elbows more bent in jump
lLowerArm.x = lElbow.x;
lLowerArm.y = lElbow.y;
lLowerArm.rotation = 2.0;
rLowerArm.x = rElbow.x;
rLowerArm.y = rElbow.y;
rLowerArm.rotation = -2.0;
- body.rotation = 0.12;
- } else {
body.rotation = 0;
+ } else if (self.state.pose === 'stand') {
+ // Gentle walk cycle if moving
+ var walk = Math.abs(self.state.vx) > 0.5 ? Math.sin(Date.now() * 0.008) * 0.25 : 0;
+ lUpperLegAngle += walk;
+ rUpperLegAngle -= walk;
+ lLowerLegAngle += walk * 0.5;
+ rLowerLegAngle -= walk * 0.5;
+ // Left leg
+ lUpperLeg.x = lHip.x;
+ lUpperLeg.y = lHip.y;
+ var lKneeX = lUpperLeg.x + Math.sin(lUpperLegAngle) * upperLegH;
+ var lKneeY = lUpperLeg.y + Math.cos(lUpperLegAngle) * upperLegH;
+ lKnee.x = lKneeX;
+ lKnee.y = lKneeY;
+ lUpperLeg.rotation = Math.atan2(lKnee.y - lUpperLeg.y, lKnee.x - lUpperLeg.x) - Math.PI / 2;
+ lLowerLeg.x = lKneeX;
+ lLowerLeg.y = lKneeY;
+ lLowerLeg.rotation = lLowerLegAngle;
+ // Right leg (mirror)
+ rUpperLeg.x = rHip.x;
+ rUpperLeg.y = rHip.y;
+ var rKneeX = rUpperLeg.x + Math.sin(rUpperLegAngle) * upperLegH;
+ var rKneeY = rUpperLeg.y + Math.cos(rUpperLegAngle) * upperLegH;
+ rKnee.x = rKneeX;
+ rKnee.y = rKneeY;
+ rUpperLeg.rotation = Math.atan2(rKnee.y - rUpperLeg.y, rKnee.x - rUpperLeg.x) - Math.PI / 2;
+ rLowerLeg.x = rKneeX;
+ rLowerLeg.y = rKneeY;
+ rLowerLeg.rotation = rLowerLegAngle;
+ body.rotation = 0;
}
}
// --- Public puppet actions ---
self.pullHeadLeft = function () {