User prompt
Tüm kodları incele ve iyiléstir gereksiz herşeyi temizle.
User prompt
Testten çık
User prompt
Sit pozda kukla 45 piksel aşağıya taşı
User prompt
Sit pozda kukla 20 piksel aşağıya çek
User prompt
Sit pozda kuklayı buraz daha aşağıya taşı
User prompt
Sit pozda kuklayı buraz daha aşağıya taşı
User prompt
Sit pozda kuklayı dizler zemine değecek kadar aşağıya taşı.
User prompt
Kuklayı aşağıya al
User prompt
Sit pozda sağ alt bacak sola döndür
User prompt
Sit poz teste gir
User prompt
Sit pozda sag bacak sağa doğru olsun.
User prompt
Alt bacakları biraz daha kapat. Kuklayı çok az yukarı taşı.
User prompt
Alt bacakları biraz kapat
User prompt
Stand pozda üst bacakları biraz aç
User prompt
Stand pozda alt bacakları swap yap
User prompt
Alt bacakları biraz aç
User prompt
Alt bacaklar gözükmüyor
User prompt
Stand pozda alt bacakları swap yap
User prompt
Stand pozda üst bacakları swap yap
User prompt
Stand pozda üst bacakları biraz aç
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ 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') { 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; }); var Puppet = Container.expand(function () { var self = Container.call(this); 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; var head = self.attachAsset('puppet_head', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 1.5 }); var neck = self.attachAsset('puppet_neck', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, // match hip scale scaleY: 1.5 }); 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 }); var body = self.attachAsset('puppet_body', { anchorX: 0.5, anchorY: 0, scaleX: 1.5, scaleY: 1.5 }); 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 }); var lUpperArm = self.attachAsset('puppet_upperarm', { anchorX: 0.5, anchorY: 0, scaleX: 1.5, scaleY: 1.5 }); var lElbow = self.attachAsset('puppet_elbow', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 1.5 }); var lLowerArm = self.attachAsset('puppet_lowerarm', { anchorX: 0.5, anchorY: 0, scaleX: 1.5, scaleY: 1.5 }); var rUpperArm = self.attachAsset('puppet_upperarm', { anchorX: 0.5, anchorY: 0, scaleX: 1.5, scaleY: 1.5 }); var rElbow = self.attachAsset('puppet_elbow', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 1.5 }); var rLowerArm = self.attachAsset('puppet_lowerarm', { anchorX: 0.5, anchorY: 0, scaleX: 1.5, scaleY: 1.5 }); var lLowerLeg = self.attachAsset('puppet_lowerleg', { anchorX: 0.5, anchorY: 0, scaleX: 1.5, scaleY: 1.5 }); var rLowerLeg = self.attachAsset('puppet_lowerleg', { anchorX: 0.5, anchorY: 0, scaleX: 1.5, scaleY: 1.5 }); var lUpperLeg = self.attachAsset('puppet_upperleg', { anchorX: 0.5, anchorY: 0, scaleX: 1.5, scaleY: 1.5 }); var lKnee = self.attachAsset('puppet_knee', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 1.5 }); var rUpperLeg = self.attachAsset('puppet_upperleg', { anchorX: 0.5, anchorY: 0, scaleX: 1.5, scaleY: 1.5 }); var rKnee = self.attachAsset('puppet_knee', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 1.5 }); 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, 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 }; function updateBodyParts() { head.x = 0; head.y = -bodyH / 2 - headH / 2 - 30; head.rotation = self.state.headAngle; var hipH = 44 * 1.5; var neckH = hipH; neck.x = 0; neck.y = -bodyH / 2 - neckH / 2 + 38; neck.rotation = 0; body.x = 0; body.y = -bodyH / 2; 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; 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; 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; } 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; 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; var legY = bodyH / 2 - 10; var legX = bodyW / 2 - 18; var lHipX = -legX; var lHipY = legY; var rHipX = legX; var rHipY = legY; lHip.x = lHipX; lHip.y = lHipY; rHip.x = rHipX; rHip.y = rHipY; var legAbduction = 0.28; var lowerLegOutAngle = 0.16; 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); if (self.state.pose === 'sit') { lUpperLeg.x = lHip.x; lUpperLeg.y = lHip.y; rUpperLeg.x = rHip.x; rUpperLeg.y = rHip.y; var sitThighAngle = 0.55; // radians, larger outward angle for open thighs var sitKneeForward = upperLegH * 0.95; // how far forward knees are from hips var lKneeX = lUpperLeg.x + Math.sin(-sitThighAngle) * sitKneeForward; var lKneeY = lUpperLeg.y + Math.cos(-sitThighAngle) * sitKneeForward; var rKneeX = rUpperLeg.x + Math.sin(sitThighAngle) * sitKneeForward; var rKneeY = rUpperLeg.y + Math.cos(sitThighAngle) * sitKneeForward; var avgKneeY = (lKneeY + rKneeY) / 2; lKneeY = avgKneeY; rKneeY = avgKneeY; if (lKnee.parent) lKnee.parent.removeChild(lKnee); if (rKnee.parent) rKnee.parent.removeChild(rKnee); lKnee.x = lKneeX; lKnee.y = lKneeY; rKnee.x = rKneeX; rKnee.y = rKneeY; lUpperLeg.rotation = Math.atan2(lKnee.y - lUpperLeg.y, lKnee.x - lUpperLeg.x) - Math.PI / 2; rUpperLeg.rotation = Math.atan2(rKnee.y - rUpperLeg.y, rKnee.x - rUpperLeg.x) - Math.PI / 2; var groundY = 2732 - 80; var lowerLegH_px = 110 * 1.5; lLowerLeg.x = lKnee.x; lLowerLeg.y = lKnee.y; var lDeltaY = groundY - lLowerLeg.y; var lAngle = Math.acos(Math.max(-1, Math.min(1, lDeltaY / lowerLegH_px))) - Math.PI / 2; lLowerLeg.rotation = lAngle; rLowerLeg.x = rKnee.x; rLowerLeg.y = rKnee.y; var rDeltaY = groundY - rLowerLeg.y; var rAngle = Math.acos(Math.max(-1, Math.min(1, rDeltaY / lowerLegH_px))) - Math.PI / 2; rLowerLeg.rotation = rAngle - 0.55; self.addChild(lKnee); self.addChild(rKnee); body.rotation = 0; } else if (self.state.pose === 'jump') { var jumpThighAngle = 0.45; var jumpKneeBend = 1.25; // radians, how much the knee is bent (smaller = straighter, larger = more bent) var avgHipY = (lHip.y + rHip.y) / 2; var avgHipX = (lHip.x + rHip.x) / 2; var kneeYOffset = -upperLegH * Math.cos(jumpThighAngle); // vertical offset from hips to knees var kneeY = avgHipY + kneeYOffset; var kneeXLeft = lHip.x + Math.sin(-jumpThighAngle - legAbduction) * upperLegH; var kneeXRight = rHip.x + Math.sin(jumpThighAngle + legAbduction) * upperLegH; lKnee.x = kneeXLeft; lKnee.y = kneeY; rKnee.x = kneeXRight; rKnee.y = kneeY; lUpperLeg.x = lHip.x; lUpperLeg.y = lHip.y; lUpperLeg.rotation = Math.atan2(lKnee.y - lUpperLeg.y, lKnee.x - lUpperLeg.x) - Math.PI / 2; rUpperLeg.x = rHip.x; rUpperLeg.y = rHip.y; rUpperLeg.rotation = Math.atan2(rKnee.y - rUpperLeg.y, rKnee.x - rUpperLeg.x) - Math.PI / 2; lLowerLeg.x = lKnee.x; lLowerLeg.y = lKnee.y; var lJumpShinLen = lowerLegH; var lJumpAnkleX = lKnee.x + Math.sin(lUpperLeg.rotation + Math.PI / 2 + jumpKneeBend) * lJumpShinLen; var lJumpAnkleY = lKnee.y + Math.cos(lUpperLeg.rotation + Math.PI / 2 + jumpKneeBend) * lJumpShinLen; lLowerLeg.rotation = Math.atan2(lJumpAnkleY - lKnee.y, lJumpAnkleX - lKnee.x) - Math.PI / 2; rLowerLeg.x = rKnee.x; rLowerLeg.y = rKnee.y; var rJumpShinLen = lowerLegH; var rJumpAnkleX = rKnee.x + Math.sin(rUpperLeg.rotation + Math.PI / 2 + jumpKneeBend) * rJumpShinLen; var rJumpAnkleY = rKnee.y + Math.cos(rUpperLeg.rotation + Math.PI / 2 + jumpKneeBend) * rJumpShinLen; rLowerLeg.rotation = Math.atan2(rJumpAnkleY - rKnee.y, rJumpAnkleX - rKnee.x) - Math.PI / 2; 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') { var standThighAbduction = 0.32; // increased from 0.18 for more outward angle lUpperLegAngle -= standThighAbduction; rUpperLegAngle += standThighAbduction; 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; 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; var lStandShinLen = lowerLegH; var lStandAnkleX = lKneeX + Math.sin(rLowerLegAngle) * lStandShinLen; var lStandAnkleY = lKneeY + Math.cos(rLowerLegAngle) * lStandShinLen; lLowerLeg.rotation = Math.atan2(lStandAnkleY - lKneeY, lStandAnkleX - lKneeX) - Math.PI / 2; 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; var rStandShinLen = lowerLegH; var rStandAnkleX = rKneeX + Math.sin(lLowerLegAngle) * rStandShinLen; var rStandAnkleY = rKneeY + Math.cos(lLowerLegAngle) * rStandShinLen; rLowerLeg.rotation = Math.atan2(rStandAnkleY - rKneeY, rStandAnkleX - rKneeX) - Math.PI / 2; body.rotation = 0; } } self.pullHeadLeft = 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.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; self.state.grounded = false; self.state.pose = 'jump'; tween(self.state, {}, { duration: 0, onFinish: function onFinish() { LK.setTimeout(function () { self.state.pose = 'stand'; }, 400); } }); } }; self.sit = function () { if (self.state.grounded && self.state.pose !== 'sit') { self.state.pose = 'sit'; LK.setTimeout(function () { self.stand(); }, 600); } }; self.stand = function () { if (self.state.grounded && self.state.pose !== 'stand') { self.state.pose = 'stand'; } }; self.update = function () { self.state.vy += 3.2; // gravity self.state.x += self.state.vx; self.state.y += self.state.vy; if (self.state.grounded) { self.state.vx *= 0.82; } else { self.state.vx *= 0.98; } if (self.state.x < 0) self.state.x = 0; if (self.state.x > 2048) self.state.x = 2048; var groundY = 2732 - 80; var puppetFeetOffset = bodyH / 2 + upperLegH + lowerLegH - 20; var feetY = self.state.y + puppetFeetOffset; if (feetY >= groundY) { self.state.y = groundY - puppetFeetOffset; self.state.vy = 0; self.state.grounded = true; if (self.state.pose === 'jump') { self.state.pose = 'stand'; } } else { self.state.grounded = false; } self.x = self.state.x; self.y = self.state.y; updateBodyParts(); }; self.state.x = 600; // Moved puppet further right (was 180) var puppetFeetOffset = bodyH / 2 + upperLegH + lowerLegH - 20; self.state.y = 2732 - 80 - puppetFeetOffset - 40; updateBodyParts(); return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ // --- 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); // --- 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); }; // --- UX: drums are always on top --- for (var i = 0; i < drums.length; ++i) { game.addChild(drums[i]); }
===================================================================
--- original.js
+++ change.js
@@ -5,9 +5,8 @@
/****
* 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
@@ -70,12 +69,10 @@
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;
@@ -86,25 +83,21 @@
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,
@@ -115,16 +108,14 @@
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,
@@ -135,93 +126,80 @@
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,
@@ -233,53 +211,44 @@
// 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;
@@ -294,9 +263,8 @@
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;
@@ -305,9 +273,8 @@
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;
@@ -316,165 +283,128 @@
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;
- // Ava: Reduce outward angle of lower legs in stand pose (bring lower legs even closer together)
var lowerLegOutAngle = 0.16;
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') {
- // Parallel (not cross-legged) sit pose
- // Hips
lUpperLeg.x = lHip.x;
lUpperLeg.y = lHip.y;
rUpperLeg.x = rHip.x;
rUpperLeg.y = rHip.y;
- // Thighs angled more outward, knees forward
var sitThighAngle = 0.55; // radians, larger outward angle for open thighs
var sitKneeForward = upperLegH * 0.95; // how far forward knees are from hips
- // SWAP: Left knee uses -sitThighAngle, right knee uses +sitThighAngle
- // Left knee
var lKneeX = lUpperLeg.x + Math.sin(-sitThighAngle) * sitKneeForward;
var lKneeY = lUpperLeg.y + Math.cos(-sitThighAngle) * sitKneeForward;
- // Right knee
var rKneeX = rUpperLeg.x + Math.sin(sitThighAngle) * sitKneeForward;
var rKneeY = rUpperLeg.y + Math.cos(sitThighAngle) * sitKneeForward;
- // Knees at same y
var avgKneeY = (lKneeY + rKneeY) / 2;
lKneeY = avgKneeY;
rKneeY = avgKneeY;
- // Set knee positions
if (lKnee.parent) lKnee.parent.removeChild(lKnee);
if (rKnee.parent) rKnee.parent.removeChild(rKnee);
lKnee.x = lKneeX;
lKnee.y = lKneeY;
rKnee.x = rKneeX;
rKnee.y = rKneeY;
- // Upper leg rotations
lUpperLeg.rotation = Math.atan2(lKnee.y - lUpperLeg.y, lKnee.x - lUpperLeg.x) - Math.PI / 2;
rUpperLeg.rotation = Math.atan2(rKnee.y - rUpperLeg.y, rKnee.x - rUpperLeg.x) - Math.PI / 2;
- // Lower legs: straight down from knees, feet on ground
var groundY = 2732 - 80;
var lowerLegH_px = 110 * 1.5;
- // Left lower leg
lLowerLeg.x = lKnee.x;
lLowerLeg.y = lKnee.y;
var lDeltaY = groundY - lLowerLeg.y;
var lAngle = Math.acos(Math.max(-1, Math.min(1, lDeltaY / lowerLegH_px))) - Math.PI / 2;
lLowerLeg.rotation = lAngle;
- // Right lower leg
rLowerLeg.x = rKnee.x;
rLowerLeg.y = rKnee.y;
var rDeltaY = groundY - rLowerLeg.y;
var rAngle = Math.acos(Math.max(-1, Math.min(1, rDeltaY / lowerLegH_px))) - Math.PI / 2;
- // Ava: Rotate right lower leg to the left in sit pose
rLowerLeg.rotation = rAngle - 0.55;
- // Now set knee positions and re-add to ensure they are on top
self.addChild(lKnee);
self.addChild(rKnee);
body.rotation = 0;
} else if (self.state.pose === 'jump') {
- // Both upper legs up and slightly inward, knees together, feet up, using IK
- // --- Keep knees and upper legs connected in jump pose ---
- // --- Make both legs perfectly horizontally aligned in jump pose ---
var jumpThighAngle = 0.45;
var jumpKneeBend = 1.25; // radians, how much the knee is bent (smaller = straighter, larger = more bent)
- // Set both hips at same y, and both knees at same y, for perfect horizontal alignment
- // Calculate the average x between hips for knee position, and set a fixed y offset for knees
var avgHipY = (lHip.y + rHip.y) / 2;
var avgHipX = (lHip.x + rHip.x) / 2;
var kneeYOffset = -upperLegH * Math.cos(jumpThighAngle); // vertical offset from hips to knees
var kneeY = avgHipY + kneeYOffset;
var kneeXLeft = lHip.x + Math.sin(-jumpThighAngle - legAbduction) * upperLegH;
var kneeXRight = rHip.x + Math.sin(jumpThighAngle + legAbduction) * upperLegH;
- // Both knees at same y
lKnee.x = kneeXLeft;
lKnee.y = kneeY;
rKnee.x = kneeXRight;
rKnee.y = kneeY;
- // Upper legs: hips to knees
lUpperLeg.x = lHip.x;
lUpperLeg.y = lHip.y;
lUpperLeg.rotation = Math.atan2(lKnee.y - lUpperLeg.y, lKnee.x - lUpperLeg.x) - Math.PI / 2;
rUpperLeg.x = rHip.x;
rUpperLeg.y = rHip.y;
rUpperLeg.rotation = Math.atan2(rKnee.y - rUpperLeg.y, rKnee.x - rUpperLeg.x) - Math.PI / 2;
- // Lower legs: knees to ankles, both at same y
- // Left
lLowerLeg.x = lKnee.x;
lLowerLeg.y = lKnee.y;
var lJumpShinLen = lowerLegH;
var lJumpAnkleX = lKnee.x + Math.sin(lUpperLeg.rotation + Math.PI / 2 + jumpKneeBend) * lJumpShinLen;
var lJumpAnkleY = lKnee.y + Math.cos(lUpperLeg.rotation + Math.PI / 2 + jumpKneeBend) * lJumpShinLen;
lLowerLeg.rotation = Math.atan2(lJumpAnkleY - lKnee.y, lJumpAnkleX - lKnee.x) - Math.PI / 2;
- // Right
rLowerLeg.x = rKnee.x;
rLowerLeg.y = rKnee.y;
var rJumpShinLen = lowerLegH;
var rJumpAnkleX = rKnee.x + Math.sin(rUpperLeg.rotation + Math.PI / 2 + jumpKneeBend) * rJumpShinLen;
var rJumpAnkleY = rKnee.y + Math.cos(rUpperLeg.rotation + Math.PI / 2 + jumpKneeBend) * rJumpShinLen;
rLowerLeg.rotation = Math.atan2(rJumpAnkleY - rKnee.y, rJumpAnkleX - rKnee.x) - Math.PI / 2;
- // 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') {
- // Ava: Increase outward angle of upper thighs in stand pose (make thighs more open)
var standThighAbduction = 0.32; // increased from 0.18 for more outward angle
- // SWAP: swap left and right upper leg abduction
lUpperLegAngle -= standThighAbduction;
rUpperLegAngle += standThighAbduction;
- // 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;
- // SWAP: Attach left lower leg using right lower leg's angle
lLowerLeg.x = lKneeX;
lLowerLeg.y = lKneeY;
var lStandShinLen = lowerLegH;
var lStandAnkleX = lKneeX + Math.sin(rLowerLegAngle) * lStandShinLen;
var lStandAnkleY = lKneeY + Math.cos(rLowerLegAngle) * lStandShinLen;
lLowerLeg.rotation = Math.atan2(lStandAnkleY - lKneeY, lStandAnkleX - lKneeX) - Math.PI / 2;
- // 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;
- // SWAP: Attach right lower leg using left lower leg's angle
rLowerLeg.x = rKneeX;
rLowerLeg.y = rKneeY;
var rStandShinLen = lowerLegH;
var rStandAnkleX = rKneeX + Math.sin(lLowerLegAngle) * rStandShinLen;
@@ -482,11 +412,9 @@
rLowerLeg.rotation = Math.atan2(rStandAnkleY - rKneeY, rStandAnkleX - rKneeX) - Math.PI / 2;
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, {
@@ -510,15 +438,14 @@
}
};
self.jump = function () {
if (self.state.grounded) {
- self.state.vy = -48; // Increased jump velocity for higher jump
+ self.state.vy = -48;
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);
}
@@ -527,9 +454,8 @@
};
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);
}
@@ -538,24 +464,19 @@
if (self.state.grounded && self.state.pose !== 'stand') {
self.state.pose = 'stand';
}
};
- // --- Physics update ---
self.update = function () {
- // --- Physics update ---
self.state.vy += 3.2; // gravity
self.state.x += self.state.vx;
self.state.y += self.state.vy;
- // Friction
if (self.state.grounded) {
self.state.vx *= 0.82;
} else {
self.state.vx *= 0.98;
}
- // Clamp to world bounds
if (self.state.x < 0) self.state.x = 0;
if (self.state.x > 2048) self.state.x = 2048;
- // Ground collision
var groundY = 2732 - 80;
var puppetFeetOffset = bodyH / 2 + upperLegH + lowerLegH - 20;
var feetY = self.state.y + puppetFeetOffset;
if (feetY >= groundY) {
@@ -567,17 +488,13 @@
}
} else {
self.state.grounded = false;
}
- // Apply to container (keep puppet at current position)
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 ---
- // Move puppet slightly higher (raise by 40px)
var puppetFeetOffset = bodyH / 2 + upperLegH + lowerLegH - 20;
self.state.y = 2732 - 80 - puppetFeetOffset - 40;
updateBodyParts();
return self;
@@ -593,17 +510,8 @@
/****
* Game Code
****/
// --- Background music playlist (4 tracks, play in random order) ---
-// 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 musicTracks = [{
id: 'musicId',
volume: 0.1,
start: 0,
@@ -693,9 +601,8 @@
});
finishSign.x = 2048 - 120;
finishSign.y = 2732 - 80;
game.addChild(finishSign);
-// Finish text removed
// --- Puppet ---
var puppet = new Puppet();
game.addChild(puppet);
// --- Drums ---
@@ -812,10 +719,8 @@
// --- 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]);
}
\ No newline at end of file