User prompt
Büyük davulun sağına ve soluna yuvarlak yeni iki tane çalgı asseti yerlestir. Bunlara ekleyeceğim sesler bunlara basinca loop çalsın, tekrar basınca sussun.
User prompt
Büyük davulun sağina sokuna yeni iki tane çalgı asseti yerlestir. Bunlara ekleyeceğim sesler basinca loop çalsın, tekrar basınca sussun.
User prompt
Idle pozunda baslat
User prompt
alt kolları ve alt bacaklari sag sol yer degistir.
User prompt
Tüm vücut parçalarını iyileştir
User prompt
Üst ve alt bacakları dizle bağla ve ayırma
User prompt
Üst ve alt bacakları dizle bağla ve ik kinematik olarak ayarla.
User prompt
Tüm parçalar diz, dirsek, kalça ve boyun ik kinematik olarak bağlı olmalı. Bü
User prompt
Boyun kare yada dikdörtgen olsun.
User prompt
Kafa biraz daha boyunun üstünde olsun.
User prompt
Boyun asseti ekle, sabit olsun ve tam olarak kafa ile vücut arasına yerleştir ve gözüksün. Kalça ölçüsü kadar olsun.
User prompt
Kafa, boyun ve vücut birbirine bağlı olsun. boyun hareketsiz bir body part.
User prompt
Boyunu vücuda doğru bağla.
User prompt
Boyun görünsün.
User prompt
Boyun gözükmüyor, düzelt.
User prompt
Kafa boyuna bağlı olsun.
User prompt
boyun asseti ekle ik kinematik ile vücuda bağla.
User prompt
Bir de boyun asseti ekle ik kinematik olarak vücuda bağla.
User prompt
Kalça bir tane olsun ve iki bacağa da bağlansın.
User prompt
Omuzları ve kalçayı da asset olarak ekle ik kinematik güncelleme gerekliyse yap.
User prompt
Zıplama için tüm body parts da ik kinematik tekrar ele al. Gerekirse dirsek ve diz asset ekle.
User prompt
drum_tap_right davula tıklayınca sese çok uzun reverb efekti uygula
User prompt
drum_tap_right davula tıklayınca sese çok uzun reverb efekti uygula
User prompt
Zıplama için tüm body parts da ik kinematik tekrar ele al. Gerekirse dirsek ve diz asset ekle.
User prompt
Zıplama sorunlu, body parts dağılıyor.
/**** * 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 }); // Single hip (center) var hip = 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 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 }); // 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 knee var rKnee = self.attachAsset('puppet_knee', { anchorX: 0.5, anchorY: 0.5, 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/NECK/BODY --- // Head position (above neck) head.x = 0; head.y = -bodyH / 2 - headH / 2 - 30; head.rotation = self.state.headAngle; // Neck: between head and body, sized to match hip var hipH = 44 * 1.5; var neckH = hipH; neck.x = 0; // Place neck so its top touches head bottom, bottom touches body top neck.y = -bodyH / 2 - neckH / 2 + 38; neck.rotation = 0; // Body body.x = 0; body.y = -bodyH / 2; // --- SHOULDER KINEMATICS --- // Shoulders are attached to top left/right of body var armY = -bodyH / 2 + 30; var armX = bodyW / 2 + upperArmW / 2 - 10; var lShoulderX = -armX; var lShoulderY = armY; var rShoulderX = armX; var rShoulderY = armY; lShoulder.x = lShoulderX; lShoulder.y = lShoulderY; rShoulder.x = rShoulderX; rShoulder.y = rShoulderY; // --- ARM KINEMATICS (IK) --- // Default arm pose angles var lUpperArmAngle = -0.18; var rUpperArmAngle = 0.18; var lLowerArmAngle = 0.25; var rLowerArmAngle = -0.25; if (self.state.pose === 'sit') { lUpperArmAngle = -1.25; rUpperArmAngle = 1.25; lLowerArmAngle = 1.5; rLowerArmAngle = -1.5; } else if (self.state.pose === 'jump') { lUpperArmAngle = -1.1; rUpperArmAngle = 1.1; 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: shoulder -> upper arm -> elbow -> lower arm (IK) lUpperArm.x = lShoulderX; lUpperArm.y = lShoulderY; lUpperArm.rotation = lUpperArmAngle; // Elbow position var lElbowX = lUpperArm.x + Math.sin(lUpperArmAngle) * upperArmH; var lElbowY = lUpperArm.y + Math.cos(lUpperArmAngle) * upperArmH; lElbow.x = lElbowX; lElbow.y = lElbowY; // Lower arm from elbow lLowerArm.x = lElbowX; lLowerArm.y = lElbowY; lLowerArm.rotation = lLowerArmAngle; // Right arm: shoulder -> upper arm -> elbow -> lower arm (IK) rUpperArm.x = rShoulderX; rUpperArm.y = rShoulderY; rUpperArm.rotation = rUpperArmAngle; var rElbowX = rUpperArm.x + Math.sin(rUpperArmAngle) * upperArmH; var rElbowY = rUpperArm.y + Math.cos(rUpperArmAngle) * upperArmH; rElbow.x = rElbowX; rElbow.y = rElbowY; rLowerArm.x = rElbowX; rLowerArm.y = rElbowY; rLowerArm.rotation = rLowerArmAngle; // --- HIP KINEMATICS --- // Hip is attached to bottom of body var legY = bodyH / 2 - 10; var legX = bodyW / 2 - 18; var hipX = 0; var hipY = legY; hip.x = hipX; hip.y = hipY; // --- LEG KINEMATICS (IK) --- // Both legs originate from the single hip var lHipX = hipX - legX; var lHipY = hipY; var rHipX = hipX + legX; var rHipY = hipY; var lUpperLegAngle = 0.18; var rUpperLegAngle = -0.18; var lLowerLegAngle = 0.25; var rLowerLegAngle = -0.25; if (self.state.pose === 'sit') { lUpperLegAngle = 1.35; rUpperLegAngle = 1.35; lLowerLegAngle = lUpperLegAngle - Math.PI / 2 + 0.15; rLowerLegAngle = rUpperLegAngle - Math.PI / 2 - 0.15; } else if (self.state.pose === 'jump') { lUpperLegAngle = -1.2; rUpperLegAngle = -1.2; lLowerLegAngle = lUpperLegAngle + 2.1; rLowerLegAngle = rUpperLegAngle + 2.1; } else if (self.state.pose === 'stand') { 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: hip -> upper leg -> knee -> lower leg (IK) lUpperLeg.x = hip.x - legX; lUpperLeg.y = hip.y; lUpperLeg.rotation = lUpperLegAngle; var lKneeX = lUpperLeg.x + Math.sin(lUpperLegAngle) * upperLegH; var lKneeY = lUpperLeg.y + Math.cos(lUpperLegAngle) * upperLegH; lKnee.x = lKneeX; lKnee.y = lKneeY; lLowerLeg.x = lKneeX; lLowerLeg.y = lKneeY; lLowerLeg.rotation = lLowerLegAngle; // Right leg: hip -> upper leg -> knee -> lower leg (IK) rUpperLeg.x = hip.x + legX; rUpperLeg.y = hip.y; rUpperLeg.rotation = rUpperLegAngle; var rKneeX = rUpperLeg.x + Math.sin(rUpperLegAngle) * upperLegH; var rKneeY = rUpperLeg.y + Math.cos(rUpperLegAngle) * upperLegH; rKnee.x = rKneeX; rKnee.y = rKneeY; rLowerLeg.x = rKneeX; rLowerLeg.y = rKneeY; rLowerLeg.rotation = rLowerLegAngle; // --- POSE ADJUSTMENTS (IK) --- if (self.state.pose === 'sit') { // Sitting: thighs forward, knees bent, shins down lUpperLeg.x = hip.x - legX; lUpperLeg.y = hip.y; lUpperLeg.rotation = 1.35; 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 - Math.PI / 2 + 0.15; rUpperLeg.x = hip.x + legX; rUpperLeg.y = hip.y; rUpperLeg.rotation = 1.35; 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 - Math.PI / 2 - 0.15; body.rotation = -0.18; } else if (self.state.pose === 'jump') { // Jump: legs up, knees bent, elbows and knees more pronounced lUpperLeg.x = hip.x - legX; lUpperLeg.y = hip.y; lUpperLeg.rotation = -1.2; 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.1; rUpperLeg.x = hip.x + legX; rUpperLeg.y = hip.y; rUpperLeg.rotation = -1.2; 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.1; // Elbows more bent in jump lUpperArm.rotation = -1.1; var lElbowX = lUpperArm.x + Math.sin(lUpperArm.rotation) * upperArmH; var lElbowY = lUpperArm.y + Math.cos(lUpperArm.rotation) * upperArmH; lElbow.x = lElbowX; lElbow.y = lElbowY; lLowerArm.x = lElbowX; lLowerArm.y = lElbowY; lLowerArm.rotation = 2.0; rUpperArm.rotation = 1.1; var rElbowX = rUpperArm.x + Math.sin(rUpperArm.rotation) * upperArmH; var rElbowY = rUpperArm.y + Math.cos(rUpperArm.rotation) * upperArmH; rElbow.x = rElbowX; rElbow.y = rElbowY; rLowerArm.x = rElbowX; rLowerArm.y = rElbowY; rLowerArm.rotation = -2.0; body.rotation = 0.12; } 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 ****/ // 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; } } // Start with a shuffled playlist var shuffledMusicOrder = []; function reshuffleMusicOrder() { shuffledMusicOrder = []; for (var i = 0; i < musicTracks.length; ++i) shuffledMusicOrder.push(i); shuffleArray(shuffledMusicOrder); } reshuffleMusicOrder(); var currentMusicOrderIndex = 0; 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]; 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
@@ -248,43 +248,41 @@
y: 0
};
// --- Positioning offsets (relative to puppet center) ---
function updateBodyParts() {
- // Head
+ // --- HEAD/NECK/BODY ---
+ // Head position (above neck)
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: between head and body, sized to match hip
+ 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
+ // Place neck so its top touches head bottom, bottom touches body top
+ neck.y = -bodyH / 2 - neckH / 2 + 38;
neck.rotation = 0;
// Body
body.x = 0;
body.y = -bodyH / 2;
- // Arms
+ // --- SHOULDER KINEMATICS ---
+ // Shoulders are attached to top left/right of body
var armY = -bodyH / 2 + 30;
var armX = bodyW / 2 + upperArmW / 2 - 10;
- // Shoulder positions
var lShoulderX = -armX;
var lShoulderY = armY;
var rShoulderX = armX;
var rShoulderY = armY;
- // Place shoulder assets at shoulder positions
lShoulder.x = lShoulderX;
lShoulder.y = lShoulderY;
rShoulder.x = rShoulderX;
rShoulder.y = rShoulderY;
- // --- Improved arm kinematics ---
+ // --- ARM KINEMATICS (IK) ---
// Default arm pose angles
var lUpperArmAngle = -0.18;
var rUpperArmAngle = 0.18;
var lLowerArmAngle = 0.25;
var rLowerArmAngle = -0.25;
- // Pose-based arm animation
if (self.state.pose === 'sit') {
lUpperArmAngle = -1.25;
rUpperArmAngle = 1.25;
lLowerArmAngle = 1.5;
@@ -294,59 +292,55 @@
rUpperArmAngle = 1.1;
lLowerArmAngle = 2.0;
rLowerArmAngle = -2.0;
} 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
+ // Left arm: shoulder -> upper arm -> elbow -> lower arm (IK)
lUpperArm.x = lShoulderX;
lUpperArm.y = lShoulderY;
lUpperArm.rotation = lUpperArmAngle;
- // Left elbow position
+ // Elbow position
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
+ // Lower arm from elbow
lLowerArm.x = lElbowX;
lLowerArm.y = lElbowY;
lLowerArm.rotation = lLowerArmAngle;
- // Right upper arm
+ // Right arm: shoulder -> upper arm -> elbow -> lower arm (IK)
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;
rElbow.x = rElbowX;
rElbow.y = rElbowY;
- // Right lower arm
rLowerArm.x = rElbowX;
rLowerArm.y = rElbowY;
rLowerArm.rotation = rLowerArmAngle;
- // --- Improved leg kinematics ---
+ // --- HIP KINEMATICS ---
+ // Hip is attached to bottom of body
var legY = bodyH / 2 - 10;
var legX = bodyW / 2 - 18;
- // Hip position (center)
var hipX = 0;
var hipY = legY;
hip.x = hipX;
hip.y = hipY;
+ // --- LEG KINEMATICS (IK) ---
// Both legs originate from the single hip
var lHipX = hipX - legX;
var lHipY = hipY;
var rHipX = hipX + legX;
var rHipY = hipY;
- // Default leg pose
var lUpperLegAngle = 0.18;
var rUpperLegAngle = -0.18;
var lLowerLegAngle = 0.25;
var rLowerLegAngle = -0.25;
- // Pose-based leg animation
if (self.state.pose === 'sit') {
lUpperLegAngle = 1.35;
rUpperLegAngle = 1.35;
lLowerLegAngle = lUpperLegAngle - Math.PI / 2 + 0.15;
@@ -356,42 +350,37 @@
rUpperLegAngle = -1.2;
lLowerLegAngle = lUpperLegAngle + 2.1;
rLowerLegAngle = rUpperLegAngle + 2.1;
} 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
+ // Left leg: hip -> upper leg -> knee -> lower leg (IK)
lUpperLeg.x = hip.x - legX;
lUpperLeg.y = hip.y;
lUpperLeg.rotation = lUpperLegAngle;
- // Calculate left knee position
var lKneeX = lUpperLeg.x + Math.sin(lUpperLegAngle) * upperLegH;
var lKneeY = lUpperLeg.y + Math.cos(lUpperLegAngle) * upperLegH;
lKnee.x = lKneeX;
lKnee.y = lKneeY;
- // Attach lower leg at knee, rotate for more natural foot placement
lLowerLeg.x = lKneeX;
lLowerLeg.y = lKneeY;
lLowerLeg.rotation = lLowerLegAngle;
- // Right upper leg
+ // Right leg: hip -> upper leg -> knee -> lower leg (IK)
rUpperLeg.x = hip.x + legX;
rUpperLeg.y = hip.y;
rUpperLeg.rotation = rUpperLegAngle;
- // Calculate right knee position
var rKneeX = rUpperLeg.x + Math.sin(rUpperLegAngle) * upperLegH;
var rKneeY = rUpperLeg.y + Math.cos(rUpperLegAngle) * upperLegH;
rKnee.x = rKneeX;
rKnee.y = rKneeY;
- // Attach lower leg at knee, rotate for more natural foot placement
rLowerLeg.x = rKneeX;
rLowerLeg.y = rKneeY;
rLowerLeg.rotation = rLowerLegAngle;
- // Pose adjustments
+ // --- POSE ADJUSTMENTS (IK) ---
if (self.state.pose === 'sit') {
// Sitting: thighs forward, knees bent, shins down
lUpperLeg.x = hip.x - legX;
lUpperLeg.y = hip.y;