Code edit (1 edits merged)
Please save this source code
User prompt
Black Hat's Breakfast: The Great Chomp Chase
Initial prompt
Okay, here are the comic panels depicting Mr. Black Hat eating Oren, Raddy, and Clukr, in a visual style reminiscent of Sprunki Animation, focusing on exaggerated expressions and action, with no dialogue. Panel 1 [Image: Wide shot showing a cartoony stylized landscape. Foreground: Mr. Black Hat (a tall, thin, black figure with a comically large top hat) stands menacingly, eyes glinting. Oren (an orange, simple shape with big, scared eyes and stick limbs) stands trembling before him.] [Caption: A terrible morning dawns...] Panel 2 [Image: Close up on Black Hat's face. His mouth is open wide, revealing a disproportionately large set of sharp, cartoonish teeth. His eyes are wide and crazy. Oren is tiny in comparison, right in front of his mouth] [Caption: ... for Oren.] Panel 3 [Image: Action shot! Mr. Black Hat is mid-chomp! Oren is being swallowed. Exaggerated cartoon dust cloud/motion lines surround the action. Small "CRUNCH" sound effect implied with jagged lines.] [Caption: NOM!] Panel 4 [Image: Mr. Black Hat stands, now with a slight bulge in his stomach. He pats his stomach with a satisfied, yet still menacing, smirk.] [Caption: But Oren is only the beginning.] Panel 5 [Image: Raddy (a round, red character with big, scared eyes and stick limbs) and Clukr (a shiny silver, vaguely chicken-shaped character with bugged-out eyes) are running away from the direction Black Hat is standing, they are filled with fear] [Caption: Raddy and Clukr flee in Terror.] Panel 6 [Image: A blur of black! Mr. Black Hat is suddenly in front of Raddy and Clukr, arms stretched wide.] [Caption: But there is no escape.] Panel 7 [Image: Close up on Black Hat's face. His mouth is open wide, revealing a disproportionately large set of sharp, cartoonish teeth. His eyes are wide and crazy. Raddy and Clukr are tiny in comparison, right in front of his mouth] [Caption: Their fate is sealed.] Panel 8 [Image: Action shot! Mr. Black Hat is mid-chomp! Raddy and Clukr are being swallowed. Exaggerated cartoon dust cloud/motion lines surround the action. Small "CRUNCH" sound effect implied with jagged lines.] [Caption: NOM!] Panel 9 [Image: Mr. Black Hat stands, now with a BIG bulge in his stomach. He pats his stomach with a satisfied, yet still menacing, smirk.] [Caption: All is well for Mr. Black Hat!] Explanation of the Choices: Sprunki Style: I'm imagining a very simplistic, almost crude animation style. Think bold outlines, bright colors, characters that are essentially simple shapes, and exaggerated expressions. No Dialogue: The story is told entirely through visual cues. Exaggeration: The size of Black Hat's mouth, the violence of the chomp, the fear on the other characters' faces, and the expanding bulge in Black Hat's stomach are all played up for comedic effect. Captions: I used captions to provide minimal narration and emphasis. Action Lines/Dust Clouds: These are standard cartoon conventions to show movement and speed. Sound Effects: While there are no words, the implied "CRUNCH" sound can be visualized with jagged lines. This approach aims for the darkly humorous, slightly disturbing, but ultimately silly tone that is typical of some simpler animations. With Keyboard
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Chomp effect (cartoon flash) var ChompEffect = Container.expand(function () { var self = Container.call(this); var effect = self.attachAsset('chompEffect', { anchorX: 0.5, anchorY: 0.5, alpha: 0.7 }); self.effect = effect; self.play = function (x, y) { self.x = x; self.y = y; self.alpha = 0.7; self.scaleX = 1; self.scaleY = 1; tween(self, { alpha: 0, scaleX: 2.2, scaleY: 2.2 }, { duration: 320, easing: tween.easeOut, onFinish: function onFinish() { self.destroy(); } }); }; return self; }); // Clukr (yellow, chicken, beak) var Clukr = Container.expand(function () { var self = Container.call(this); var body = self.attachAsset('clukrBody', { anchorX: 0.5, anchorY: 0.5 }); var beak = self.attachAsset('clukrBeak', { anchorX: 0.5, anchorY: 0.5, y: 32 }); var eyeL = self.attachAsset('clukrEyeWhite', { anchorX: 0.5, anchorY: 0.5, x: -12, y: -12 }); var eyeR = self.attachAsset('clukrEyeWhite', { anchorX: 0.5, anchorY: 0.5, x: 12, y: -12 }); var pupilL = self.attachAsset('clukrPupil', { anchorX: 0.5, anchorY: 0.5, x: -12, y: -12 }); var pupilR = self.attachAsset('clukrPupil', { anchorX: 0.5, anchorY: 0.5, x: 12, y: -12 }); var mouth = self.attachAsset('clukrMouth', { anchorX: 0.5, anchorY: 0.5, y: 38, scaleY: 1.1 }); self.eyeL = eyeL; self.eyeR = eyeR; self.pupilL = pupilL; self.pupilR = pupilR; self.mouth = mouth; self.isScared = false; self.isEaten = false; self.speed = 7.8; self.direction = 0; self.setScared = function (scared) { self.isScared = scared; if (scared) { tween(mouth, { scaleY: 1.7 }, { duration: 120 }); } else { tween(mouth, { scaleY: 1.1 }, { duration: 120 }); } }; self.lookAt = function (targetX, targetY) { var dx = targetX - self.x; var dy = targetY - self.y; var mag = Math.sqrt(dx * dx + dy * dy); var maxOffset = 5; var ox = mag > 0 ? dx / mag * maxOffset : 0; var oy = mag > 0 ? dy / mag * maxOffset : 0; self.pupilL.x = -12 + ox; self.pupilL.y = -12 + oy; self.pupilR.x = 12 + ox; self.pupilR.y = -12 + oy; }; return self; }); // Mr. Black Hat (Player) var MrBlackHat = Container.expand(function () { var self = Container.call(this); // Body var body = self.attachAsset('mrBlackHat', { anchorX: 0.5, anchorY: 0.5 }); // Hat var brim = self.attachAsset('hatBrim', { anchorX: 0.5, anchorY: 0.5, y: -110 }); var top = self.attachAsset('hatTop', { anchorX: 0.5, anchorY: 1, y: -170 }); // Eyes var eyeL = self.attachAsset('eyeWhite', { anchorX: 0.5, anchorY: 0.5, x: -40, y: -30 }); var eyeR = self.attachAsset('eyeWhite', { anchorX: 0.5, anchorY: 0.5, x: 40, y: -30 }); var pupilL = self.attachAsset('eyePupil', { anchorX: 0.5, anchorY: 0.5, x: -40, y: -30 }); var pupilR = self.attachAsset('eyePupil', { anchorX: 0.5, anchorY: 0.5, x: 40, y: -30 }); // Mouth var mouth = self.attachAsset('mouth', { anchorX: 0.5, anchorY: 0.5, y: 50, scaleY: 0.7 }); self.mouth = mouth; self.eyeL = eyeL; self.eyeR = eyeR; self.pupilL = pupilL; self.pupilR = pupilR; self.isChomping = false; self.chompingTimer = 0; // Chomp animation self.chomp = function () { if (self.isChomping) return; self.isChomping = true; tween(mouth, { scaleY: 1.3 }, { duration: 90, easing: tween.easeOut, onFinish: function onFinish() { tween(mouth, { scaleY: 0.7 }, { duration: 120, easing: tween.easeIn, onFinish: function onFinish() { self.isChomping = false; } }); } }); }; // Animate eyes to look at a point self.lookAt = function (targetX, targetY) { var dx = targetX - self.x; var dy = targetY - self.y; var mag = Math.sqrt(dx * dx + dy * dy); var maxOffset = 10; var ox = mag > 0 ? dx / mag * maxOffset : 0; var oy = mag > 0 ? dy / mag * maxOffset : 0; self.pupilL.x = -40 + ox; self.pupilL.y = -30 + oy; self.pupilR.x = 40 + ox; self.pupilR.y = -30 + oy; }; return self; }); // Oren (orange, round, scared) var Oren = Container.expand(function () { var self = Container.call(this); var body = self.attachAsset('orenBody', { anchorX: 0.5, anchorY: 0.5 }); var eyeL = self.attachAsset('orenEyeWhite', { anchorX: 0.5, anchorY: 0.5, x: -22, y: -18 }); var eyeR = self.attachAsset('orenEyeWhite', { anchorX: 0.5, anchorY: 0.5, x: 22, y: -18 }); var pupilL = self.attachAsset('orenPupil', { anchorX: 0.5, anchorY: 0.5, x: -22, y: -18 }); var pupilR = self.attachAsset('orenPupil', { anchorX: 0.5, anchorY: 0.5, x: 22, y: -18 }); var mouth = self.attachAsset('orenMouth', { anchorX: 0.5, anchorY: 0.5, y: 28, scaleY: 1.1 }); self.eyeL = eyeL; self.eyeR = eyeR; self.pupilL = pupilL; self.pupilR = pupilR; self.mouth = mouth; self.isScared = false; self.isEaten = false; self.speed = 7.5; self.direction = 0; // radians self.setScared = function (scared) { self.isScared = scared; if (scared) { tween(mouth, { scaleY: 1.7 }, { duration: 120 }); } else { tween(mouth, { scaleY: 1.1 }, { duration: 120 }); } }; self.lookAt = function (targetX, targetY) { var dx = targetX - self.x; var dy = targetY - self.y; var mag = Math.sqrt(dx * dx + dy * dy); var maxOffset = 7; var ox = mag > 0 ? dx / mag * maxOffset : 0; var oy = mag > 0 ? dy / mag * maxOffset : 0; self.pupilL.x = -22 + ox; self.pupilL.y = -18 + oy; self.pupilR.x = 22 + ox; self.pupilR.y = -18 + oy; }; return self; }); // Raddy (red, rabbit-like, long ears) var Raddy = Container.expand(function () { var self = Container.call(this); var body = self.attachAsset('raddyBody', { anchorX: 0.5, anchorY: 0.5 }); var earL = self.attachAsset('raddyEar', { anchorX: 0.5, anchorY: 1, x: -28, y: -70, rotation: -0.3 }); var earR = self.attachAsset('raddyEar', { anchorX: 0.5, anchorY: 1, x: 28, y: -70, rotation: 0.3 }); var eyeL = self.attachAsset('raddyEyeWhite', { anchorX: 0.5, anchorY: 0.5, x: -16, y: -16 }); var eyeR = self.attachAsset('raddyEyeWhite', { anchorX: 0.5, anchorY: 0.5, x: 16, y: -16 }); var pupilL = self.attachAsset('raddyPupil', { anchorX: 0.5, anchorY: 0.5, x: -16, y: -16 }); var pupilR = self.attachAsset('raddyPupil', { anchorX: 0.5, anchorY: 0.5, x: 16, y: -16 }); var mouth = self.attachAsset('raddyMouth', { anchorX: 0.5, anchorY: 0.5, y: 22, scaleY: 1.1 }); self.eyeL = eyeL; self.eyeR = eyeR; self.pupilL = pupilL; self.pupilR = pupilR; self.mouth = mouth; self.isScared = false; self.isEaten = false; self.speed = 8.2; self.direction = 0; self.setScared = function (scared) { self.isScared = scared; if (scared) { tween(mouth, { scaleY: 1.7 }, { duration: 120 }); } else { tween(mouth, { scaleY: 1.1 }, { duration: 120 }); } }; self.lookAt = function (targetX, targetY) { var dx = targetX - self.x; var dy = targetY - self.y; var mag = Math.sqrt(dx * dx + dy * dy); var maxOffset = 6; var ox = mag > 0 ? dx / mag * maxOffset : 0; var oy = mag > 0 ? dy / mag * maxOffset : 0; self.pupilL.x = -16 + ox; self.pupilL.y = -16 + oy; self.pupilR.x = 16 + ox; self.pupilR.y = -16 + oy; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0xf6f6e9 }); /**** * Game Code ****/ // Chomp effect // Clukr (yellow, chicken, beak) // Raddy (red, rabbit-like, long ears) // Oren (orange, round, scared) // Mr. Black Hat (player) // Game state var player = null; var targets = []; var targetsEaten = 0; var dragNode = null; var lastTouchX = 0; var lastTouchY = 0; var chompReady = true; var chompCooldown = 0; var chompRadius = 120; var chompedThisPress = false; // Score text var scoreTxt = new Text2('0/3', { size: 120, fill: 0x222222 }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Helper: spawn all targets function spawnTargets() { targets = []; targetsEaten = 0; // Oren var oren = new Oren(); oren.x = 400; oren.y = 900; targets.push(oren); game.addChild(oren); // Raddy var raddy = new Raddy(); raddy.x = 1648; raddy.y = 700; targets.push(raddy); game.addChild(raddy); // Clukr var clukr = new Clukr(); clukr.x = 1024; clukr.y = 2100; targets.push(clukr); game.addChild(clukr); } // Helper: reset player position function resetPlayer() { player.x = 1024; player.y = 1500; } // Initialize player and targets player = new MrBlackHat(); game.addChild(player); resetPlayer(); spawnTargets(); scoreTxt.setText('0/3'); // Helper: update score function updateScore() { scoreTxt.setText(targetsEaten + '/3'); if (targetsEaten >= 3) { LK.setScore(3); LK.showYouWin(); } } // Helper: chomp at current position function tryChomp() { if (!chompReady || player.isChomping) return; chompReady = false; chompedThisPress = true; player.chomp(); // Chomp effect var effect = new ChompEffect(); game.addChild(effect); effect.play(player.x, player.y + 80); // Check for targets in range for (var i = 0; i < targets.length; ++i) { var t = targets[i]; if (t.isEaten) continue; var dx = t.x - player.x; var dy = t.y - (player.y + 80); var dist = Math.sqrt(dx * dx + dy * dy); if (dist < chompRadius) { // Eat! t.isEaten = true; targetsEaten += 1; updateScore(); // Cartoon bulge and fade tween(t, { scaleX: 1.5, scaleY: 0.5, alpha: 0 }, { duration: 400, easing: tween.bounceOut, onFinish: function onFinish() { t.destroy(); } }); // Slapstick flash LK.effects.flashObject(player, 0xffff00, 200); } } // Chomp cooldown chompCooldown = 18; // ~0.3s } // Touch/move logic game.down = function (x, y, obj) { // Don't allow drag from top left 100x100 if (x < 100 && y < 100) return; dragNode = player; lastTouchX = x; lastTouchY = y; chompedThisPress = false; }; game.move = function (x, y, obj) { if (dragNode) { // Clamp to game area var px = Math.max(120, Math.min(2048 - 120, x)); var py = Math.max(220, Math.min(2732 - 120, y)); dragNode.x = px; dragNode.y = py; lastTouchX = px; lastTouchY = py; } // Eyes look at last touch player.lookAt(lastTouchX, lastTouchY); for (var i = 0; i < targets.length; ++i) { var t = targets[i]; if (!t.isEaten) t.lookAt(player.x, player.y); } }; game.up = function (x, y, obj) { dragNode = null; chompReady = true; chompedThisPress = false; }; // Chomp on tap (if not dragging) game.tap = function (x, y, obj) { if (!dragNode && !chompedThisPress) { tryChomp(); } }; // For mobile: treat quick tap as chomp game.down = function (x, y, obj) { if (x < 100 && y < 100) return; dragNode = player; lastTouchX = x; lastTouchY = y; chompedThisPress = false; // If tap (not drag), chomp immediately tryChomp(); }; game.up = function (x, y, obj) { dragNode = null; chompReady = true; chompedThisPress = false; }; // Main update loop game.update = function () { // Chomp cooldown if (chompCooldown > 0) { chompCooldown -= 1; if (chompCooldown <= 0) { chompReady = true; } } // Targets flee from player for (var i = 0; i < targets.length; ++i) { var t = targets[i]; if (t.isEaten) continue; var dx = t.x - player.x; var dy = t.y - player.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < 400) { // Scared, run away t.setScared(true); var fleeAngle = Math.atan2(dy, dx); var speed = t.speed + 2.5 * (400 - dist) / 400; t.x += Math.cos(fleeAngle) * speed; t.y += Math.sin(fleeAngle) * speed; // Clamp to game area t.x = Math.max(80, Math.min(2048 - 80, t.x)); t.y = Math.max(120, Math.min(2732 - 80, t.y)); } else { t.setScared(false); // Idle bounce t.y += Math.sin(LK.ticks / 18 + i * 2) * 0.7; } // Eyes look at player t.lookAt(player.x, player.y); } // Player eyes look at last touch player.lookAt(lastTouchX, lastTouchY); }; // Reset game on game over or win LK.on('gameover', function () { // Reset everything player.x = 1024; player.y = 1500; for (var i = 0; i < targets.length; ++i) { targets[i].destroy(); } spawnTargets(); targetsEaten = 0; updateScore(); }); LK.on('youwin', function () { // Reset everything player.x = 1024; player.y = 1500; for (var i = 0; i < targets.length; ++i) { targets[i].destroy(); } spawnTargets(); targetsEaten = 0; updateScore(); });
===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,608 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+
+/****
+* Classes
+****/
+// Chomp effect (cartoon flash)
+var ChompEffect = Container.expand(function () {
+ var self = Container.call(this);
+ var effect = self.attachAsset('chompEffect', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ alpha: 0.7
+ });
+ self.effect = effect;
+ self.play = function (x, y) {
+ self.x = x;
+ self.y = y;
+ self.alpha = 0.7;
+ self.scaleX = 1;
+ self.scaleY = 1;
+ tween(self, {
+ alpha: 0,
+ scaleX: 2.2,
+ scaleY: 2.2
+ }, {
+ duration: 320,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ self.destroy();
+ }
+ });
+ };
+ return self;
+});
+// Clukr (yellow, chicken, beak)
+var Clukr = Container.expand(function () {
+ var self = Container.call(this);
+ var body = self.attachAsset('clukrBody', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ var beak = self.attachAsset('clukrBeak', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ y: 32
+ });
+ var eyeL = self.attachAsset('clukrEyeWhite', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: -12,
+ y: -12
+ });
+ var eyeR = self.attachAsset('clukrEyeWhite', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: 12,
+ y: -12
+ });
+ var pupilL = self.attachAsset('clukrPupil', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: -12,
+ y: -12
+ });
+ var pupilR = self.attachAsset('clukrPupil', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: 12,
+ y: -12
+ });
+ var mouth = self.attachAsset('clukrMouth', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ y: 38,
+ scaleY: 1.1
+ });
+ self.eyeL = eyeL;
+ self.eyeR = eyeR;
+ self.pupilL = pupilL;
+ self.pupilR = pupilR;
+ self.mouth = mouth;
+ self.isScared = false;
+ self.isEaten = false;
+ self.speed = 7.8;
+ self.direction = 0;
+ self.setScared = function (scared) {
+ self.isScared = scared;
+ if (scared) {
+ tween(mouth, {
+ scaleY: 1.7
+ }, {
+ duration: 120
+ });
+ } else {
+ tween(mouth, {
+ scaleY: 1.1
+ }, {
+ duration: 120
+ });
+ }
+ };
+ self.lookAt = function (targetX, targetY) {
+ var dx = targetX - self.x;
+ var dy = targetY - self.y;
+ var mag = Math.sqrt(dx * dx + dy * dy);
+ var maxOffset = 5;
+ var ox = mag > 0 ? dx / mag * maxOffset : 0;
+ var oy = mag > 0 ? dy / mag * maxOffset : 0;
+ self.pupilL.x = -12 + ox;
+ self.pupilL.y = -12 + oy;
+ self.pupilR.x = 12 + ox;
+ self.pupilR.y = -12 + oy;
+ };
+ return self;
+});
+// Mr. Black Hat (Player)
+var MrBlackHat = Container.expand(function () {
+ var self = Container.call(this);
+ // Body
+ var body = self.attachAsset('mrBlackHat', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ // Hat
+ var brim = self.attachAsset('hatBrim', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ y: -110
+ });
+ var top = self.attachAsset('hatTop', {
+ anchorX: 0.5,
+ anchorY: 1,
+ y: -170
+ });
+ // Eyes
+ var eyeL = self.attachAsset('eyeWhite', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: -40,
+ y: -30
+ });
+ var eyeR = self.attachAsset('eyeWhite', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: 40,
+ y: -30
+ });
+ var pupilL = self.attachAsset('eyePupil', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: -40,
+ y: -30
+ });
+ var pupilR = self.attachAsset('eyePupil', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: 40,
+ y: -30
+ });
+ // Mouth
+ var mouth = self.attachAsset('mouth', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ y: 50,
+ scaleY: 0.7
+ });
+ self.mouth = mouth;
+ self.eyeL = eyeL;
+ self.eyeR = eyeR;
+ self.pupilL = pupilL;
+ self.pupilR = pupilR;
+ self.isChomping = false;
+ self.chompingTimer = 0;
+ // Chomp animation
+ self.chomp = function () {
+ if (self.isChomping) return;
+ self.isChomping = true;
+ tween(mouth, {
+ scaleY: 1.3
+ }, {
+ duration: 90,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ tween(mouth, {
+ scaleY: 0.7
+ }, {
+ duration: 120,
+ easing: tween.easeIn,
+ onFinish: function onFinish() {
+ self.isChomping = false;
+ }
+ });
+ }
+ });
+ };
+ // Animate eyes to look at a point
+ self.lookAt = function (targetX, targetY) {
+ var dx = targetX - self.x;
+ var dy = targetY - self.y;
+ var mag = Math.sqrt(dx * dx + dy * dy);
+ var maxOffset = 10;
+ var ox = mag > 0 ? dx / mag * maxOffset : 0;
+ var oy = mag > 0 ? dy / mag * maxOffset : 0;
+ self.pupilL.x = -40 + ox;
+ self.pupilL.y = -30 + oy;
+ self.pupilR.x = 40 + ox;
+ self.pupilR.y = -30 + oy;
+ };
+ return self;
+});
+// Oren (orange, round, scared)
+var Oren = Container.expand(function () {
+ var self = Container.call(this);
+ var body = self.attachAsset('orenBody', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ var eyeL = self.attachAsset('orenEyeWhite', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: -22,
+ y: -18
+ });
+ var eyeR = self.attachAsset('orenEyeWhite', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: 22,
+ y: -18
+ });
+ var pupilL = self.attachAsset('orenPupil', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: -22,
+ y: -18
+ });
+ var pupilR = self.attachAsset('orenPupil', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: 22,
+ y: -18
+ });
+ var mouth = self.attachAsset('orenMouth', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ y: 28,
+ scaleY: 1.1
+ });
+ self.eyeL = eyeL;
+ self.eyeR = eyeR;
+ self.pupilL = pupilL;
+ self.pupilR = pupilR;
+ self.mouth = mouth;
+ self.isScared = false;
+ self.isEaten = false;
+ self.speed = 7.5;
+ self.direction = 0; // radians
+ self.setScared = function (scared) {
+ self.isScared = scared;
+ if (scared) {
+ tween(mouth, {
+ scaleY: 1.7
+ }, {
+ duration: 120
+ });
+ } else {
+ tween(mouth, {
+ scaleY: 1.1
+ }, {
+ duration: 120
+ });
+ }
+ };
+ self.lookAt = function (targetX, targetY) {
+ var dx = targetX - self.x;
+ var dy = targetY - self.y;
+ var mag = Math.sqrt(dx * dx + dy * dy);
+ var maxOffset = 7;
+ var ox = mag > 0 ? dx / mag * maxOffset : 0;
+ var oy = mag > 0 ? dy / mag * maxOffset : 0;
+ self.pupilL.x = -22 + ox;
+ self.pupilL.y = -18 + oy;
+ self.pupilR.x = 22 + ox;
+ self.pupilR.y = -18 + oy;
+ };
+ return self;
+});
+// Raddy (red, rabbit-like, long ears)
+var Raddy = Container.expand(function () {
+ var self = Container.call(this);
+ var body = self.attachAsset('raddyBody', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ var earL = self.attachAsset('raddyEar', {
+ anchorX: 0.5,
+ anchorY: 1,
+ x: -28,
+ y: -70,
+ rotation: -0.3
+ });
+ var earR = self.attachAsset('raddyEar', {
+ anchorX: 0.5,
+ anchorY: 1,
+ x: 28,
+ y: -70,
+ rotation: 0.3
+ });
+ var eyeL = self.attachAsset('raddyEyeWhite', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: -16,
+ y: -16
+ });
+ var eyeR = self.attachAsset('raddyEyeWhite', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: 16,
+ y: -16
+ });
+ var pupilL = self.attachAsset('raddyPupil', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: -16,
+ y: -16
+ });
+ var pupilR = self.attachAsset('raddyPupil', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: 16,
+ y: -16
+ });
+ var mouth = self.attachAsset('raddyMouth', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ y: 22,
+ scaleY: 1.1
+ });
+ self.eyeL = eyeL;
+ self.eyeR = eyeR;
+ self.pupilL = pupilL;
+ self.pupilR = pupilR;
+ self.mouth = mouth;
+ self.isScared = false;
+ self.isEaten = false;
+ self.speed = 8.2;
+ self.direction = 0;
+ self.setScared = function (scared) {
+ self.isScared = scared;
+ if (scared) {
+ tween(mouth, {
+ scaleY: 1.7
+ }, {
+ duration: 120
+ });
+ } else {
+ tween(mouth, {
+ scaleY: 1.1
+ }, {
+ duration: 120
+ });
+ }
+ };
+ self.lookAt = function (targetX, targetY) {
+ var dx = targetX - self.x;
+ var dy = targetY - self.y;
+ var mag = Math.sqrt(dx * dx + dy * dy);
+ var maxOffset = 6;
+ var ox = mag > 0 ? dx / mag * maxOffset : 0;
+ var oy = mag > 0 ? dy / mag * maxOffset : 0;
+ self.pupilL.x = -16 + ox;
+ self.pupilL.y = -16 + oy;
+ self.pupilR.x = 16 + ox;
+ self.pupilR.y = -16 + oy;
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
+ backgroundColor: 0xf6f6e9
+});
+
+/****
+* Game Code
+****/
+// Chomp effect
+// Clukr (yellow, chicken, beak)
+// Raddy (red, rabbit-like, long ears)
+// Oren (orange, round, scared)
+// Mr. Black Hat (player)
+// Game state
+var player = null;
+var targets = [];
+var targetsEaten = 0;
+var dragNode = null;
+var lastTouchX = 0;
+var lastTouchY = 0;
+var chompReady = true;
+var chompCooldown = 0;
+var chompRadius = 120;
+var chompedThisPress = false;
+// Score text
+var scoreTxt = new Text2('0/3', {
+ size: 120,
+ fill: 0x222222
+});
+scoreTxt.anchor.set(0.5, 0);
+LK.gui.top.addChild(scoreTxt);
+// Helper: spawn all targets
+function spawnTargets() {
+ targets = [];
+ targetsEaten = 0;
+ // Oren
+ var oren = new Oren();
+ oren.x = 400;
+ oren.y = 900;
+ targets.push(oren);
+ game.addChild(oren);
+ // Raddy
+ var raddy = new Raddy();
+ raddy.x = 1648;
+ raddy.y = 700;
+ targets.push(raddy);
+ game.addChild(raddy);
+ // Clukr
+ var clukr = new Clukr();
+ clukr.x = 1024;
+ clukr.y = 2100;
+ targets.push(clukr);
+ game.addChild(clukr);
+}
+// Helper: reset player position
+function resetPlayer() {
+ player.x = 1024;
+ player.y = 1500;
+}
+// Initialize player and targets
+player = new MrBlackHat();
+game.addChild(player);
+resetPlayer();
+spawnTargets();
+scoreTxt.setText('0/3');
+// Helper: update score
+function updateScore() {
+ scoreTxt.setText(targetsEaten + '/3');
+ if (targetsEaten >= 3) {
+ LK.setScore(3);
+ LK.showYouWin();
+ }
+}
+// Helper: chomp at current position
+function tryChomp() {
+ if (!chompReady || player.isChomping) return;
+ chompReady = false;
+ chompedThisPress = true;
+ player.chomp();
+ // Chomp effect
+ var effect = new ChompEffect();
+ game.addChild(effect);
+ effect.play(player.x, player.y + 80);
+ // Check for targets in range
+ for (var i = 0; i < targets.length; ++i) {
+ var t = targets[i];
+ if (t.isEaten) continue;
+ var dx = t.x - player.x;
+ var dy = t.y - (player.y + 80);
+ var dist = Math.sqrt(dx * dx + dy * dy);
+ if (dist < chompRadius) {
+ // Eat!
+ t.isEaten = true;
+ targetsEaten += 1;
+ updateScore();
+ // Cartoon bulge and fade
+ tween(t, {
+ scaleX: 1.5,
+ scaleY: 0.5,
+ alpha: 0
+ }, {
+ duration: 400,
+ easing: tween.bounceOut,
+ onFinish: function onFinish() {
+ t.destroy();
+ }
+ });
+ // Slapstick flash
+ LK.effects.flashObject(player, 0xffff00, 200);
+ }
+ }
+ // Chomp cooldown
+ chompCooldown = 18; // ~0.3s
+}
+// Touch/move logic
+game.down = function (x, y, obj) {
+ // Don't allow drag from top left 100x100
+ if (x < 100 && y < 100) return;
+ dragNode = player;
+ lastTouchX = x;
+ lastTouchY = y;
+ chompedThisPress = false;
+};
+game.move = function (x, y, obj) {
+ if (dragNode) {
+ // Clamp to game area
+ var px = Math.max(120, Math.min(2048 - 120, x));
+ var py = Math.max(220, Math.min(2732 - 120, y));
+ dragNode.x = px;
+ dragNode.y = py;
+ lastTouchX = px;
+ lastTouchY = py;
+ }
+ // Eyes look at last touch
+ player.lookAt(lastTouchX, lastTouchY);
+ for (var i = 0; i < targets.length; ++i) {
+ var t = targets[i];
+ if (!t.isEaten) t.lookAt(player.x, player.y);
+ }
+};
+game.up = function (x, y, obj) {
+ dragNode = null;
+ chompReady = true;
+ chompedThisPress = false;
+};
+// Chomp on tap (if not dragging)
+game.tap = function (x, y, obj) {
+ if (!dragNode && !chompedThisPress) {
+ tryChomp();
+ }
+};
+// For mobile: treat quick tap as chomp
+game.down = function (x, y, obj) {
+ if (x < 100 && y < 100) return;
+ dragNode = player;
+ lastTouchX = x;
+ lastTouchY = y;
+ chompedThisPress = false;
+ // If tap (not drag), chomp immediately
+ tryChomp();
+};
+game.up = function (x, y, obj) {
+ dragNode = null;
+ chompReady = true;
+ chompedThisPress = false;
+};
+// Main update loop
+game.update = function () {
+ // Chomp cooldown
+ if (chompCooldown > 0) {
+ chompCooldown -= 1;
+ if (chompCooldown <= 0) {
+ chompReady = true;
+ }
+ }
+ // Targets flee from player
+ for (var i = 0; i < targets.length; ++i) {
+ var t = targets[i];
+ if (t.isEaten) continue;
+ var dx = t.x - player.x;
+ var dy = t.y - player.y;
+ var dist = Math.sqrt(dx * dx + dy * dy);
+ if (dist < 400) {
+ // Scared, run away
+ t.setScared(true);
+ var fleeAngle = Math.atan2(dy, dx);
+ var speed = t.speed + 2.5 * (400 - dist) / 400;
+ t.x += Math.cos(fleeAngle) * speed;
+ t.y += Math.sin(fleeAngle) * speed;
+ // Clamp to game area
+ t.x = Math.max(80, Math.min(2048 - 80, t.x));
+ t.y = Math.max(120, Math.min(2732 - 80, t.y));
+ } else {
+ t.setScared(false);
+ // Idle bounce
+ t.y += Math.sin(LK.ticks / 18 + i * 2) * 0.7;
+ }
+ // Eyes look at player
+ t.lookAt(player.x, player.y);
+ }
+ // Player eyes look at last touch
+ player.lookAt(lastTouchX, lastTouchY);
+};
+// Reset game on game over or win
+LK.on('gameover', function () {
+ // Reset everything
+ player.x = 1024;
+ player.y = 1500;
+ for (var i = 0; i < targets.length; ++i) {
+ targets[i].destroy();
+ }
+ spawnTargets();
+ targetsEaten = 0;
+ updateScore();
+});
+LK.on('youwin', function () {
+ // Reset everything
+ player.x = 1024;
+ player.y = 1500;
+ for (var i = 0; i < targets.length; ++i) {
+ targets[i].destroy();
+ }
+ spawnTargets();
+ targetsEaten = 0;
+ updateScore();
});
\ No newline at end of file