User prompt
Put your skin on the left from my photo in assets
User prompt
If we did the writing well, it should be green, if we did it badly, it should be red.
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot set properties of undefined (setting 'fill')' in or related to this line: 'self.textObj.style.fill = color;' Line Number: 80
Code edit (1 edits merged)
Please save this source code
User prompt
Arrow Rush: Reaction Challenge
Initial prompt
right arrow left arrow up and down arrow will come and when they come you will click on the right left up and down arrows on the screenright arrow left arrow up and down arrow will come and when they come you will click on the right left up and down arrows on the screen and if it is not read on time, write things like bad, very good, disgusting and if it is not read on time, write things like bad, very good, disgustingLet these arrows continue to go and all come from top to bottom.If you stop the arrows in time, you will get points and the game will not stop when you click on the screen.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // FallingArrow: a single falling arrow var FallingArrow = Container.expand(function () { var self = Container.call(this); // Arrow type: 'up', 'down', 'left', 'right' self.arrowType = 'up'; self.speed = 8; // Will be set on spawn // Attach arrow asset, set anchor to center self.arrowAsset = null; self.setArrowType = function (type) { self.arrowType = type; if (self.arrowAsset) { self.removeChild(self.arrowAsset); } var assetId = ''; if (type === 'up') assetId = 'arrowUp'; if (type === 'down') assetId = 'arrowDown'; if (type === 'left') assetId = 'arrowLeft'; if (type === 'right') assetId = 'arrowRight'; self.arrowAsset = self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5 }); // Rotate asset to match direction if (type === 'up') self.arrowAsset.rotation = 0; if (type === 'down') self.arrowAsset.rotation = Math.PI; if (type === 'left') self.arrowAsset.rotation = -Math.PI / 2; if (type === 'right') self.arrowAsset.rotation = Math.PI / 2; }; // Called every tick self.update = function () { self.y += self.speed; }; return self; }); // FeedbackText: floating feedback text (e.g. "Very Good", "Bad", etc) var FeedbackText = Container.expand(function () { var self = Container.call(this); self.textObj = new Text2('', { size: 120, fill: "#fff", font: "Impact" }); self.textObj.anchor.set(0.5, 0.5); self.addChild(self.textObj); self.show = function (msg, color) { self.textObj.setText(msg); self.textObj.style.fill = color; self.alpha = 1; // Animate up and fade out tween(self, { y: self.y - 120, alpha: 0 }, { duration: 700, easing: tween.cubicOut, onFinish: function onFinish() { if (self.parent) self.parent.removeChild(self); } }); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x181818 }); /**** * Game Code ****/ // No need to init Text2 assets, just use Text2 // Feedback text colors // Target zone highlight // Arrow shapes (up, down, left, right) - colored for clarity // --- Constants --- var ARROW_TYPES = ['left', 'down', 'up', 'right']; var ARROW_COLORS = { 'up': '#4fc3f7', 'down': '#ffb74d', 'left': '#81c784', 'right': '#e57373' }; var FEEDBACKS = [{ msg: "Very Good", color: 0x00E676 }, { msg: "Good", color: 0xFFD600 }, { msg: "Bad", color: 0xFF3D00 }, { msg: "Disgusting", color: 0xB71C1C }]; // --- Layout --- var GAME_W = 2048, GAME_H = 2732; var ARROW_SIZE = 180; var BUTTON_SIZE = 220; var BUTTON_MARGIN = 60; var TARGET_ZONE_HEIGHT = 220; var TARGET_ZONE_Y = GAME_H - 600; // --- State --- var fallingArrows = []; var arrowSpawnInterval = 60; // ticks between spawns (start slow) var arrowSpeed = 8; // px per tick (start slow) var minArrowInterval = 24; // fastest spawn interval var maxArrowSpeed = 32; // fastest speed var ticksSinceLastArrow = 0; var score = 0; var combo = 0; var lastArrowTypeTapped = null; var gameOver = false; // --- UI Elements --- // Target zone highlight var targetZone = LK.getAsset('targetZone', { anchorX: 0, anchorY: 0, x: 0, y: TARGET_ZONE_Y, width: GAME_W, height: TARGET_ZONE_HEIGHT }); targetZone.alpha = 0.18; game.addChild(targetZone); // Score text var scoreTxt = new Text2('0', { size: 120, fill: "#fff", font: "Impact" }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Feedback text (floating, created as needed) // --- Arrow Button Controls --- var buttonY = GAME_H - BUTTON_SIZE / 2 - 60; var buttonXs = [GAME_W / 2 - (BUTTON_SIZE * 1.5 + BUTTON_MARGIN), GAME_W / 2 - (BUTTON_SIZE / 2 + BUTTON_MARGIN / 2), GAME_W / 2 + (BUTTON_SIZE / 2 + BUTTON_MARGIN / 2), GAME_W / 2 + (BUTTON_SIZE * 1.5 + BUTTON_MARGIN)]; var arrowButtonOrder = ['left', 'down', 'up', 'right']; var arrowButtons = []; // Create arrow buttons for (var i = 0; i < 4; i++) { (function (i) { var type = arrowButtonOrder[i]; var btn = new Container(); var assetId = ''; if (type === 'up') assetId = 'arrowUp'; if (type === 'down') assetId = 'arrowDown'; if (type === 'left') assetId = 'arrowLeft'; if (type === 'right') assetId = 'arrowRight'; var arrowAsset = btn.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5, width: BUTTON_SIZE - 20, height: BUTTON_SIZE - 20 }); // Rotate to match direction if (type === 'up') arrowAsset.rotation = 0; if (type === 'down') arrowAsset.rotation = Math.PI; if (type === 'left') arrowAsset.rotation = -Math.PI / 2; if (type === 'right') arrowAsset.rotation = Math.PI / 2; btn.x = buttonXs[i]; btn.y = buttonY; btn.type = type; btn.interactive = true; // Add a subtle background highlight var bg = LK.getAsset('targetZone', { anchorX: 0.5, anchorY: 0.5, width: BUTTON_SIZE, height: BUTTON_SIZE, x: 0, y: 0 }); bg.alpha = 0.10; btn.addChildAt(bg, 0); // Touch/click handler btn.down = function (x, y, obj) { handleArrowButtonPress(type); }; game.addChild(btn); arrowButtons.push(btn); })(i); } // --- Helper: Find the closest arrow in the target zone for a given type --- function findMatchingArrowInZone(type) { var best = null; var bestDist = 99999; for (var i = 0; i < fallingArrows.length; i++) { var arr = fallingArrows[i]; if (arr.arrowType !== type) continue; // Check if in target zone var arrowY = arr.y; if (arrowY >= TARGET_ZONE_Y && arrowY <= TARGET_ZONE_Y + TARGET_ZONE_HEIGHT) { // Closer to center of zone is better var dist = Math.abs(arrowY - (TARGET_ZONE_Y + TARGET_ZONE_HEIGHT / 2)); if (dist < bestDist) { best = arr; bestDist = dist; } } } return best; } // --- Helper: Show feedback text at a position --- function showFeedback(msg, color, x, y) { var fb = new FeedbackText(); fb.x = x; fb.y = y; fb.show(msg, color); game.addChild(fb); } // --- Handle arrow button press --- function handleArrowButtonPress(type) { if (gameOver) return; var arr = findMatchingArrowInZone(type); if (arr) { // Good timing! var centerY = arr.y; var dist = Math.abs(centerY - (TARGET_ZONE_Y + TARGET_ZONE_HEIGHT / 2)); var feedback, points; if (dist < 30) { feedback = FEEDBACKS[0]; // Very Good points = 3; } else if (dist < 60) { feedback = FEEDBACKS[1]; // Good points = 2; } else { feedback = FEEDBACKS[2]; // Bad points = 1; } score += points; combo += 1; showFeedback(feedback.msg, feedback.color, arr.x, arr.y - 100); // Remove arrow arr.destroy(); for (var i = 0; i < fallingArrows.length; i++) { if (fallingArrows[i] === arr) { fallingArrows.splice(i, 1); break; } } // Animate button var btn = null; for (var i = 0; i < arrowButtons.length; i++) { if (arrowButtons[i].type === type) btn = arrowButtons[i]; } if (btn) { tween(btn, { scaleX: 1.2, scaleY: 1.2 }, { duration: 80, easing: tween.cubicOut, onFinish: function onFinish() { tween(btn, { scaleX: 1, scaleY: 1 }, { duration: 120, easing: tween.cubicIn }); } }); } } else { // No matching arrow in zone: mistake! combo = 0; showFeedback(FEEDBACKS[3].msg, FEEDBACKS[3].color, GAME_W / 2, TARGET_ZONE_Y + TARGET_ZONE_HEIGHT / 2); // Animate all buttons red for (var i = 0; i < arrowButtons.length; i++) { var btn = arrowButtons[i]; tween(btn, { alpha: 0.5 }, { duration: 80, onFinish: function onFinish() { tween(btn, { alpha: 1 }, { duration: 120 }); } }); } } scoreTxt.setText(score); } // --- Spawn a new falling arrow --- function spawnArrow() { var arr = new FallingArrow(); // Random type var type = ARROW_TYPES[Math.floor(Math.random() * 4)]; arr.setArrowType(type); arr.arrowType = type; arr.speed = arrowSpeed; // X position: match button var idx = arrowButtonOrder.indexOf(type); arr.x = buttonXs[idx]; arr.y = -ARROW_SIZE / 2; fallingArrows.push(arr); game.addChild(arr); } // --- Game update loop --- game.update = function () { if (gameOver) return; // Spawn arrows ticksSinceLastArrow++; if (ticksSinceLastArrow >= arrowSpawnInterval) { spawnArrow(); ticksSinceLastArrow = 0; } // Update arrows, check for misses for (var i = fallingArrows.length - 1; i >= 0; i--) { var arr = fallingArrows[i]; // If arrow passes target zone without being hit if (arr.y > TARGET_ZONE_Y + TARGET_ZONE_HEIGHT + ARROW_SIZE / 2) { // Missed! showFeedback(FEEDBACKS[2].msg, FEEDBACKS[2].color, arr.x, TARGET_ZONE_Y + TARGET_ZONE_HEIGHT / 2); combo = 0; arr.destroy(); fallingArrows.splice(i, 1); continue; } } // Gradually increase difficulty if (LK.ticks % 300 === 0) { // every 5 seconds if (arrowSpawnInterval > minArrowInterval) arrowSpawnInterval -= 2; if (arrowSpeed < maxArrowSpeed) arrowSpeed += 1; } }; // --- Touch handling for game area (ignore, only arrow buttons are interactive) --- game.down = function (x, y, obj) { // Do nothing }; game.move = function (x, y, obj) { // Do nothing }; game.up = function (x, y, obj) { // Do nothing }; // --- Reset state on game over --- game.onGameOver = function () { gameOver = true; // Remove all arrows for (var i = 0; i < fallingArrows.length; i++) { fallingArrows[i].destroy(); } fallingArrows = []; }; // --- Score display update --- scoreTxt.setText(score); // --- Start the game --- score = 0; combo = 0; arrowSpawnInterval = 60; arrowSpeed = 8; gameOver = false; fallingArrows = []; ticksSinceLastArrow = 0;
===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,372 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+
+/****
+* Classes
+****/
+// FallingArrow: a single falling arrow
+var FallingArrow = Container.expand(function () {
+ var self = Container.call(this);
+ // Arrow type: 'up', 'down', 'left', 'right'
+ self.arrowType = 'up';
+ self.speed = 8; // Will be set on spawn
+ // Attach arrow asset, set anchor to center
+ self.arrowAsset = null;
+ self.setArrowType = function (type) {
+ self.arrowType = type;
+ if (self.arrowAsset) {
+ self.removeChild(self.arrowAsset);
+ }
+ var assetId = '';
+ if (type === 'up') assetId = 'arrowUp';
+ if (type === 'down') assetId = 'arrowDown';
+ if (type === 'left') assetId = 'arrowLeft';
+ if (type === 'right') assetId = 'arrowRight';
+ self.arrowAsset = self.attachAsset(assetId, {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ // Rotate asset to match direction
+ if (type === 'up') self.arrowAsset.rotation = 0;
+ if (type === 'down') self.arrowAsset.rotation = Math.PI;
+ if (type === 'left') self.arrowAsset.rotation = -Math.PI / 2;
+ if (type === 'right') self.arrowAsset.rotation = Math.PI / 2;
+ };
+ // Called every tick
+ self.update = function () {
+ self.y += self.speed;
+ };
+ return self;
+});
+// FeedbackText: floating feedback text (e.g. "Very Good", "Bad", etc)
+var FeedbackText = Container.expand(function () {
+ var self = Container.call(this);
+ self.textObj = new Text2('', {
+ size: 120,
+ fill: "#fff",
+ font: "Impact"
+ });
+ self.textObj.anchor.set(0.5, 0.5);
+ self.addChild(self.textObj);
+ self.show = function (msg, color) {
+ self.textObj.setText(msg);
+ self.textObj.style.fill = color;
+ self.alpha = 1;
+ // Animate up and fade out
+ tween(self, {
+ y: self.y - 120,
+ alpha: 0
+ }, {
+ duration: 700,
+ easing: tween.cubicOut,
+ onFinish: function onFinish() {
+ if (self.parent) self.parent.removeChild(self);
+ }
+ });
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x181818
+});
+
+/****
+* Game Code
+****/
+// No need to init Text2 assets, just use Text2
+// Feedback text colors
+// Target zone highlight
+// Arrow shapes (up, down, left, right) - colored for clarity
+// --- Constants ---
+var ARROW_TYPES = ['left', 'down', 'up', 'right'];
+var ARROW_COLORS = {
+ 'up': '#4fc3f7',
+ 'down': '#ffb74d',
+ 'left': '#81c784',
+ 'right': '#e57373'
+};
+var FEEDBACKS = [{
+ msg: "Very Good",
+ color: 0x00E676
+}, {
+ msg: "Good",
+ color: 0xFFD600
+}, {
+ msg: "Bad",
+ color: 0xFF3D00
+}, {
+ msg: "Disgusting",
+ color: 0xB71C1C
+}];
+// --- Layout ---
+var GAME_W = 2048,
+ GAME_H = 2732;
+var ARROW_SIZE = 180;
+var BUTTON_SIZE = 220;
+var BUTTON_MARGIN = 60;
+var TARGET_ZONE_HEIGHT = 220;
+var TARGET_ZONE_Y = GAME_H - 600;
+// --- State ---
+var fallingArrows = [];
+var arrowSpawnInterval = 60; // ticks between spawns (start slow)
+var arrowSpeed = 8; // px per tick (start slow)
+var minArrowInterval = 24; // fastest spawn interval
+var maxArrowSpeed = 32; // fastest speed
+var ticksSinceLastArrow = 0;
+var score = 0;
+var combo = 0;
+var lastArrowTypeTapped = null;
+var gameOver = false;
+// --- UI Elements ---
+// Target zone highlight
+var targetZone = LK.getAsset('targetZone', {
+ anchorX: 0,
+ anchorY: 0,
+ x: 0,
+ y: TARGET_ZONE_Y,
+ width: GAME_W,
+ height: TARGET_ZONE_HEIGHT
+});
+targetZone.alpha = 0.18;
+game.addChild(targetZone);
+// Score text
+var scoreTxt = new Text2('0', {
+ size: 120,
+ fill: "#fff",
+ font: "Impact"
+});
+scoreTxt.anchor.set(0.5, 0);
+LK.gui.top.addChild(scoreTxt);
+// Feedback text (floating, created as needed)
+// --- Arrow Button Controls ---
+var buttonY = GAME_H - BUTTON_SIZE / 2 - 60;
+var buttonXs = [GAME_W / 2 - (BUTTON_SIZE * 1.5 + BUTTON_MARGIN), GAME_W / 2 - (BUTTON_SIZE / 2 + BUTTON_MARGIN / 2), GAME_W / 2 + (BUTTON_SIZE / 2 + BUTTON_MARGIN / 2), GAME_W / 2 + (BUTTON_SIZE * 1.5 + BUTTON_MARGIN)];
+var arrowButtonOrder = ['left', 'down', 'up', 'right'];
+var arrowButtons = [];
+// Create arrow buttons
+for (var i = 0; i < 4; i++) {
+ (function (i) {
+ var type = arrowButtonOrder[i];
+ var btn = new Container();
+ var assetId = '';
+ if (type === 'up') assetId = 'arrowUp';
+ if (type === 'down') assetId = 'arrowDown';
+ if (type === 'left') assetId = 'arrowLeft';
+ if (type === 'right') assetId = 'arrowRight';
+ var arrowAsset = btn.attachAsset(assetId, {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ width: BUTTON_SIZE - 20,
+ height: BUTTON_SIZE - 20
+ });
+ // Rotate to match direction
+ if (type === 'up') arrowAsset.rotation = 0;
+ if (type === 'down') arrowAsset.rotation = Math.PI;
+ if (type === 'left') arrowAsset.rotation = -Math.PI / 2;
+ if (type === 'right') arrowAsset.rotation = Math.PI / 2;
+ btn.x = buttonXs[i];
+ btn.y = buttonY;
+ btn.type = type;
+ btn.interactive = true;
+ // Add a subtle background highlight
+ var bg = LK.getAsset('targetZone', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ width: BUTTON_SIZE,
+ height: BUTTON_SIZE,
+ x: 0,
+ y: 0
+ });
+ bg.alpha = 0.10;
+ btn.addChildAt(bg, 0);
+ // Touch/click handler
+ btn.down = function (x, y, obj) {
+ handleArrowButtonPress(type);
+ };
+ game.addChild(btn);
+ arrowButtons.push(btn);
+ })(i);
+}
+// --- Helper: Find the closest arrow in the target zone for a given type ---
+function findMatchingArrowInZone(type) {
+ var best = null;
+ var bestDist = 99999;
+ for (var i = 0; i < fallingArrows.length; i++) {
+ var arr = fallingArrows[i];
+ if (arr.arrowType !== type) continue;
+ // Check if in target zone
+ var arrowY = arr.y;
+ if (arrowY >= TARGET_ZONE_Y && arrowY <= TARGET_ZONE_Y + TARGET_ZONE_HEIGHT) {
+ // Closer to center of zone is better
+ var dist = Math.abs(arrowY - (TARGET_ZONE_Y + TARGET_ZONE_HEIGHT / 2));
+ if (dist < bestDist) {
+ best = arr;
+ bestDist = dist;
+ }
+ }
+ }
+ return best;
+}
+// --- Helper: Show feedback text at a position ---
+function showFeedback(msg, color, x, y) {
+ var fb = new FeedbackText();
+ fb.x = x;
+ fb.y = y;
+ fb.show(msg, color);
+ game.addChild(fb);
+}
+// --- Handle arrow button press ---
+function handleArrowButtonPress(type) {
+ if (gameOver) return;
+ var arr = findMatchingArrowInZone(type);
+ if (arr) {
+ // Good timing!
+ var centerY = arr.y;
+ var dist = Math.abs(centerY - (TARGET_ZONE_Y + TARGET_ZONE_HEIGHT / 2));
+ var feedback, points;
+ if (dist < 30) {
+ feedback = FEEDBACKS[0]; // Very Good
+ points = 3;
+ } else if (dist < 60) {
+ feedback = FEEDBACKS[1]; // Good
+ points = 2;
+ } else {
+ feedback = FEEDBACKS[2]; // Bad
+ points = 1;
+ }
+ score += points;
+ combo += 1;
+ showFeedback(feedback.msg, feedback.color, arr.x, arr.y - 100);
+ // Remove arrow
+ arr.destroy();
+ for (var i = 0; i < fallingArrows.length; i++) {
+ if (fallingArrows[i] === arr) {
+ fallingArrows.splice(i, 1);
+ break;
+ }
+ }
+ // Animate button
+ var btn = null;
+ for (var i = 0; i < arrowButtons.length; i++) {
+ if (arrowButtons[i].type === type) btn = arrowButtons[i];
+ }
+ if (btn) {
+ tween(btn, {
+ scaleX: 1.2,
+ scaleY: 1.2
+ }, {
+ duration: 80,
+ easing: tween.cubicOut,
+ onFinish: function onFinish() {
+ tween(btn, {
+ scaleX: 1,
+ scaleY: 1
+ }, {
+ duration: 120,
+ easing: tween.cubicIn
+ });
+ }
+ });
+ }
+ } else {
+ // No matching arrow in zone: mistake!
+ combo = 0;
+ showFeedback(FEEDBACKS[3].msg, FEEDBACKS[3].color, GAME_W / 2, TARGET_ZONE_Y + TARGET_ZONE_HEIGHT / 2);
+ // Animate all buttons red
+ for (var i = 0; i < arrowButtons.length; i++) {
+ var btn = arrowButtons[i];
+ tween(btn, {
+ alpha: 0.5
+ }, {
+ duration: 80,
+ onFinish: function onFinish() {
+ tween(btn, {
+ alpha: 1
+ }, {
+ duration: 120
+ });
+ }
+ });
+ }
+ }
+ scoreTxt.setText(score);
+}
+// --- Spawn a new falling arrow ---
+function spawnArrow() {
+ var arr = new FallingArrow();
+ // Random type
+ var type = ARROW_TYPES[Math.floor(Math.random() * 4)];
+ arr.setArrowType(type);
+ arr.arrowType = type;
+ arr.speed = arrowSpeed;
+ // X position: match button
+ var idx = arrowButtonOrder.indexOf(type);
+ arr.x = buttonXs[idx];
+ arr.y = -ARROW_SIZE / 2;
+ fallingArrows.push(arr);
+ game.addChild(arr);
+}
+// --- Game update loop ---
+game.update = function () {
+ if (gameOver) return;
+ // Spawn arrows
+ ticksSinceLastArrow++;
+ if (ticksSinceLastArrow >= arrowSpawnInterval) {
+ spawnArrow();
+ ticksSinceLastArrow = 0;
+ }
+ // Update arrows, check for misses
+ for (var i = fallingArrows.length - 1; i >= 0; i--) {
+ var arr = fallingArrows[i];
+ // If arrow passes target zone without being hit
+ if (arr.y > TARGET_ZONE_Y + TARGET_ZONE_HEIGHT + ARROW_SIZE / 2) {
+ // Missed!
+ showFeedback(FEEDBACKS[2].msg, FEEDBACKS[2].color, arr.x, TARGET_ZONE_Y + TARGET_ZONE_HEIGHT / 2);
+ combo = 0;
+ arr.destroy();
+ fallingArrows.splice(i, 1);
+ continue;
+ }
+ }
+ // Gradually increase difficulty
+ if (LK.ticks % 300 === 0) {
+ // every 5 seconds
+ if (arrowSpawnInterval > minArrowInterval) arrowSpawnInterval -= 2;
+ if (arrowSpeed < maxArrowSpeed) arrowSpeed += 1;
+ }
+};
+// --- Touch handling for game area (ignore, only arrow buttons are interactive) ---
+game.down = function (x, y, obj) {
+ // Do nothing
+};
+game.move = function (x, y, obj) {
+ // Do nothing
+};
+game.up = function (x, y, obj) {
+ // Do nothing
+};
+// --- Reset state on game over ---
+game.onGameOver = function () {
+ gameOver = true;
+ // Remove all arrows
+ for (var i = 0; i < fallingArrows.length; i++) {
+ fallingArrows[i].destroy();
+ }
+ fallingArrows = [];
+};
+// --- Score display update ---
+scoreTxt.setText(score);
+// --- Start the game ---
+score = 0;
+combo = 0;
+arrowSpawnInterval = 60;
+arrowSpeed = 8;
+gameOver = false;
+fallingArrows = [];
+ticksSinceLastArrow = 0;
\ No newline at end of file