User prompt
When I press the arrows, the volume of the KSK music increases for a second
User prompt
When I press the arrows, the game sound increases for a second
User prompt
When I press the arrows, the game sound will increase for 0.5 seconds
User prompt
can you add ksk from music to the game
User prompt
bring arrows single
User prompt
bring the arrows together
User prompt
Always in pairs and not at the same time, one in front and one a little further back
User prompt
arrows come in pairs
User prompt
slightly speed up monster activity
User prompt
slightly speed up monster activity
User prompt
slow down monster activity
User prompt
It shouldn't be that hard, when the monster comes, reduce the arrows a little
User prompt
It shouldn't be that hard, when the monster comes, reduce the arrows a little
User prompt
At the twentieth second of the game, the monster comes and the arrows suddenly become very fast and multiply, then return to normal after ten seconds.
User prompt
Move the skin's location a little higher from assets
User prompt
let the clouds be white
User prompt
Make the background sky cloudy
User prompt
make background
Initial prompt
Let it be a little bigger, let it be a little higher
/****
* 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);
// Use setStyle to update fill color, as direct assignment may not work in this context
self.textObj.setStyle({
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: 0x87ceeb // Sky blue background for a sky effect
});
/****
* Game Code
****/
// Add several semi-transparent white ellipses as clouds
// --- Clouds background ---
// 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 cloudConfigs = [{
x: 400,
y: 350,
width: 520,
height: 180
}, {
x: 1200,
y: 420,
width: 400,
height: 140
}, {
x: 900,
y: 200,
width: 320,
height: 110
}, {
x: 1700,
y: 300,
width: 380,
height: 120
}, {
x: 600,
y: 700,
width: 600,
height: 200
}, {
x: 1500,
y: 800,
width: 500,
height: 170
}];
for (var i = 0; i < cloudConfigs.length; i++) {
var cfg = cloudConfigs[i];
var cloud = LK.getAsset('cloudShape' + i, {
width: cfg.width,
height: cfg.height,
color: 0xffffff,
shape: 'ellipse',
anchorX: 0.5,
anchorY: 0.5,
x: cfg.x,
y: cfg.y
});
cloud.alpha = 1;
game.addChildAt(cloud, 0); // Add behind all other elements
}
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;
// --- Monster event state ---
var monsterEventActive = false;
var monsterEventStartTick = null;
var monsterEventDuration = 600; // 10 seconds at 60fps
var monsterEventTriggered = false;
var normalArrowSpawnInterval = 60;
var normalArrowSpeed = 8;
// --- UI Elements ---
// Add player's skin image to the left side of the screen
var skinImg = LK.getAsset('Skin', {
anchorX: 0.5,
anchorY: 0.5,
x: 200,
// Move higher: raise the y position by 220px (was 120px)
y: TARGET_ZONE_Y + TARGET_ZONE_HEIGHT / 2 - 220,
width: 320,
height: 320
});
game.addChild(skinImg);
// 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) {
// Determine color: green for good, red for bad
var feedbackColor;
if (msg === "Very Good" || msg === "Good") {
feedbackColor = "#00e676"; // green
} else {
feedbackColor = "#ff1744"; // red
}
var fb = new FeedbackText();
fb.x = x;
fb.y = y;
fb.show(msg, feedbackColor);
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) {
if (monsterEventActive) {
// Spawn 3 arrows at once, all random types
for (var i = 0; i < 3; i++) {
spawnArrow();
}
} else {
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;
}
}
// --- Monster event logic ---
if (!monsterEventTriggered && LK.ticks >= 1200) {
// 20 seconds * 60fps
monsterEventActive = true;
monsterEventTriggered = true;
monsterEventStartTick = LK.ticks;
// Save normal values
normalArrowSpawnInterval = arrowSpawnInterval;
normalArrowSpeed = arrowSpeed;
// Make arrows very fast and multiply
arrowSpawnInterval = 10; // much faster
arrowSpeed = 32; // max speed
}
if (monsterEventActive && LK.ticks - monsterEventStartTick >= monsterEventDuration) {
// Revert to normal after 10 seconds
monsterEventActive = false;
arrowSpawnInterval = normalArrowSpawnInterval;
arrowSpeed = normalArrowSpeed;
}
// Gradually increase difficulty (skip if monster event is active)
if (!monsterEventActive && 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 = [];
monsterEventActive = false;
monsterEventTriggered = false;
monsterEventStartTick = null;
arrowSpawnInterval = normalArrowSpawnInterval;
arrowSpeed = normalArrowSpeed;
};
// --- Score display update ---
scoreTxt.setText(score);
// --- Start the game ---
score = 0;
combo = 0;
arrowSpawnInterval = 60;
arrowSpeed = 8;
normalArrowSpawnInterval = 60;
normalArrowSpeed = 8;
monsterEventActive = false;
monsterEventTriggered = false;
monsterEventStartTick = null;
gameOver = false;
fallingArrows = [];
ticksSinceLastArrow = 0; ===================================================================
--- original.js
+++ change.js
@@ -173,8 +173,15 @@
var score = 0;
var combo = 0;
var lastArrowTypeTapped = null;
var gameOver = false;
+// --- Monster event state ---
+var monsterEventActive = false;
+var monsterEventStartTick = null;
+var monsterEventDuration = 600; // 10 seconds at 60fps
+var monsterEventTriggered = false;
+var normalArrowSpawnInterval = 60;
+var normalArrowSpeed = 8;
// --- UI Elements ---
// Add player's skin image to the left side of the screen
var skinImg = LK.getAsset('Skin', {
anchorX: 0.5,
@@ -386,9 +393,16 @@
if (gameOver) return;
// Spawn arrows
ticksSinceLastArrow++;
if (ticksSinceLastArrow >= arrowSpawnInterval) {
- spawnArrow();
+ if (monsterEventActive) {
+ // Spawn 3 arrows at once, all random types
+ for (var i = 0; i < 3; i++) {
+ spawnArrow();
+ }
+ } else {
+ spawnArrow();
+ }
ticksSinceLastArrow = 0;
}
// Update arrows, check for misses
for (var i = fallingArrows.length - 1; i >= 0; i--) {
@@ -402,10 +416,29 @@
fallingArrows.splice(i, 1);
continue;
}
}
- // Gradually increase difficulty
- if (LK.ticks % 300 === 0) {
+ // --- Monster event logic ---
+ if (!monsterEventTriggered && LK.ticks >= 1200) {
+ // 20 seconds * 60fps
+ monsterEventActive = true;
+ monsterEventTriggered = true;
+ monsterEventStartTick = LK.ticks;
+ // Save normal values
+ normalArrowSpawnInterval = arrowSpawnInterval;
+ normalArrowSpeed = arrowSpeed;
+ // Make arrows very fast and multiply
+ arrowSpawnInterval = 10; // much faster
+ arrowSpeed = 32; // max speed
+ }
+ if (monsterEventActive && LK.ticks - monsterEventStartTick >= monsterEventDuration) {
+ // Revert to normal after 10 seconds
+ monsterEventActive = false;
+ arrowSpawnInterval = normalArrowSpawnInterval;
+ arrowSpeed = normalArrowSpeed;
+ }
+ // Gradually increase difficulty (skip if monster event is active)
+ if (!monsterEventActive && LK.ticks % 300 === 0) {
// every 5 seconds
if (arrowSpawnInterval > minArrowInterval) arrowSpawnInterval -= 2;
if (arrowSpeed < maxArrowSpeed) arrowSpeed += 1;
}
@@ -427,15 +460,25 @@
for (var i = 0; i < fallingArrows.length; i++) {
fallingArrows[i].destroy();
}
fallingArrows = [];
+ monsterEventActive = false;
+ monsterEventTriggered = false;
+ monsterEventStartTick = null;
+ arrowSpawnInterval = normalArrowSpawnInterval;
+ arrowSpeed = normalArrowSpeed;
};
// --- Score display update ---
scoreTxt.setText(score);
// --- Start the game ---
score = 0;
combo = 0;
arrowSpawnInterval = 60;
arrowSpeed = 8;
+normalArrowSpawnInterval = 60;
+normalArrowSpeed = 8;
+monsterEventActive = false;
+monsterEventTriggered = false;
+monsterEventStartTick = null;
gameOver = false;
fallingArrows = [];
ticksSinceLastArrow = 0;
\ No newline at end of file