User prompt
ensure all monster types use their asset instead of tinting
User prompt
make purple moster use monster_shadow asset I just created
User prompt
make fast monster use monster_fast asset
User prompt
✅ Attach unique monster asset per type in Monster class
User prompt
make each monster use its own asset
User prompt
they are still not appearing
User prompt
please make other variations of mobs appear
User prompt
make all monster assets show on map
User prompt
I cant see other monsters fix that
User prompt
other variations are not showing fix that and make them show
User prompt
do not combine them into a single object give them their own asset
User prompt
combine monsters with their specific assets
User prompt
combine monsters with theirs assets
User prompt
give each monster and timer bar different asset
User prompt
if you dont shoot a moster in 5 seconds they will turn red and vibrate after 2 more seconds they will explode and will take your 5 seconds
User prompt
decrease it to 1.2x faster each stage and add 2 more variations.
User prompt
when stage goes up make the timer go down 1.5x faster and make the mosters go 1.5x faster
User prompt
remove progress bar and add 2 more variation
User prompt
there will be a screen duration on right top. and under screen duration there will be 5 stages: Very easy, easy, medium, hard, very hard. every 20 seconds it will go harder and harder
User prompt
there will be a screen time on right top. and under screen time there will be 5 stages: Very easy, easy, medium, hard, very hard. very easy will be between times of 0:00-0:15. easy; 0:15:0:45. medium; 0:45-1:30. hard; 1:30-2:30. very hard; 2:30-end of the game. do not touch timer
User prompt
Please fix the bug: 'Timeout.tick error: Cannot set properties of undefined (setting 'fill')' in or related to this line: 'stageTexts[i].style.fill = i === currentStageIndex ? "#fff" : "#aaa";' Line Number: 363
User prompt
there will be a screen time on right top. and under time there will be 5 stages: Very easy, easy, medium, hard, very hard. very easy will be between times of 0:00-0:15. easy; 0:15:0:45. medium; 0:45-1:30. hard; 1:30-2:30. very hard; 2:30-end of the game.
User prompt
let the timer go back to its place. instead put screen time on there
User prompt
Timer will stay normal. I said add normal time that goes up like normal. dont touch timer
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Monster class
var Monster = Container.expand(function () {
var self = Container.call(this);
// Monster type: "normal", "fast", "slow"
self.type = "normal";
// Attach monster asset
var monsterSprite = self.attachAsset('monster', {
anchorX: 0.5,
anchorY: 0.5
});
// Color by type after setType is called
self.updateTypeVisual = function () {
if (self.type === "fast") {
monsterSprite.tint = 0x3e8ecf; // blue for fast
} else if (self.type === "slow") {
monsterSprite.tint = 0xcfb53e; // gold for slow
} else {
monsterSprite.tint = 0x3ecf4c; // green for normal
}
};
var _oldSetType = self.setType;
self.setType = function (type) {
_oldSetType(type);
self.updateTypeVisual();
};
// Movement speed (pixels per tick)
self.speed = 0;
// Movement direction (radians)
self.direction = 0;
// Is monster alive
self.alive = true;
// Set monster type and speed
self.setType = function (type) {
self.type = type;
if (type === "fast") {
// Fast monsters: 5-8 px/tick
self.speed = 5 + Math.random() * 3;
} else if (type === "slow") {
// Slow monsters: 1-2.5 px/tick
self.speed = 1 + Math.random() * 1.5;
} else {
// Normal monsters: 2-6 px/tick
self.speed = 2 + Math.random() * 4;
}
};
// Set random movement
self.setRandomMovement = function () {
// Randomly assign type
var r = Math.random();
if (r < 0.2) {
self.setType("fast");
} else if (r > 0.8) {
self.setType("slow");
} else {
self.setType("normal");
}
// Direction: 0-2PI
self.direction = Math.random() * Math.PI * 2;
};
// Move monster
self.update = function () {
if (!self.alive) return;
// Move
self.x += Math.cos(self.direction) * self.speed;
self.y += Math.sin(self.direction) * self.speed;
// Bounce off walls
// Left
if (self.x - monsterSprite.width / 2 < 0) {
self.x = monsterSprite.width / 2;
self.direction = Math.PI - self.direction;
}
// Right
if (self.x + monsterSprite.width / 2 > 2048) {
self.x = 2048 - monsterSprite.width / 2;
self.direction = Math.PI - self.direction;
}
// Top
if (self.y - monsterSprite.height / 2 < 100) {
// leave top 100px for menu
self.y = 100 + monsterSprite.height / 2;
self.direction = -self.direction;
}
// Bottom
if (self.y + monsterSprite.height / 2 > 2732) {
self.y = 2732 - monsterSprite.height / 2;
self.direction = -self.direction;
}
};
// Handle tap
self.down = function (x, y, obj) {
if (!self.alive) return;
self.alive = false;
// Show hit effect
var hit = LK.getAsset('monsterHit', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 0,
scaleX: 1,
scaleY: 1,
alpha: 1,
tint: self.type === "fast" ? 0x3e8ecf : self.type === "slow" ? 0xcfb53e : 0xff4444
});
self.addChild(hit);
// Animate hit effect
tween(hit, {
scaleX: 1.5,
scaleY: 1.5,
alpha: 0
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
hit.destroy();
}
});
// Animate monster fade out
tween(monsterSprite, {
alpha: 0
}, {
duration: 200,
onFinish: function onFinish() {
self.destroy();
}
});
// Add time and score
if (self.type === "fast") {
addTime(3); // fast: +3s
} else if (self.type === "slow") {
addTime(1); // slow: +1s
} else {
addTime(2); // normal: +2s
}
setScore(getScore() + 1);
updateScoreText();
// Remove from monsters array
for (var i = 0; i < monsters.length; ++i) {
if (monsters[i] === self) {
monsters.splice(i, 1);
break;
}
}
};
return self;
});
// Tap effect class
var TapEffect = Container.expand(function () {
var self = Container.call(this);
var tap = self.attachAsset('tapEffect', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1,
scaleY: 1,
alpha: 0.7
});
// Animate
tween(tap, {
scaleX: 2,
scaleY: 2,
alpha: 0
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
self.destroy();
}
});
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x181c2a
});
/****
* Game Code
****/
// Global variables
// Monster: green ellipse, 160x160
// Monster hit effect: red ellipse, 160x160
// Tap effect: yellow ellipse, 100x100
var monsters = [];
var monsterSpawnInterval = 120; // ticks between spawns (2s)
var monsterSpawnIntervalTarget = 120; // target interval for smooth transitions
var monsterSpawnIntervalChangeTimer = 0; // ticks until next interval change
var monsterMax = 6; // max monsters on screen
var timerMax = 20; // seconds to start
var timer = timerMax; // current timer (seconds)
var timerInterval = null;
var timerBar = null;
var timerBarBg = null;
var timerText = null;
var score = 0;
var scoreText = null;
var lastTick = 0;
// Helper: get/set score
function getScore() {
return score;
}
function setScore(val) {
score = val;
}
function updateScoreText() {
scoreText.setText(score + "");
}
// Helper: add time
function addTime(sec) {
timer += sec;
if (timer > 99) timer = 99;
updateTimerText();
}
// Helper: update timer text
function updateTimerText() {
// Show as MM:SS
var t = Math.max(0, Math.ceil(timer));
var min = Math.floor(t / 60);
var sec = t % 60;
var txt = min + ":" + (sec < 10 ? "0" : "") + sec;
timerText.setText(txt);
// Calculate elapsed time
var elapsed = timerMax - timer;
updateStageHighlight(elapsed);
}
// Helper: update timer bar
function updateTimerBar() {
var pct = Math.max(0, Math.min(1, timer / timerMax));
timerBar.width = 800 * pct;
if (pct > 0.5) timerBar.tint = 0x3ecf4c;else if (pct > 0.2) timerBar.tint = 0xffe066;else timerBar.tint = 0xff4444;
}
// Spawn a monster at random position
function spawnMonster() {
if (monsters.length >= monsterMax) return;
var m = new Monster();
// Avoid top 100px (menu)
var margin = 100 + 80;
m.x = margin + Math.random() * (2048 - margin * 2);
m.y = margin + Math.random() * (2732 - margin * 2);
m.setRandomMovement();
m.updateTypeVisual && m.updateTypeVisual();
monsters.push(m);
game.addChild(m);
}
// GUI: Score
scoreText = new Text2("0", {
size: 120,
fill: "#fff"
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
// GUI: Timer bar background
timerBarBg = LK.getAsset('monster', {
anchorX: 0,
anchorY: 0.5,
x: 624,
y: 100,
width: 800,
height: 40,
tint: 0x222222
});
timerBarBg.alpha = 0.5;
game.addChild(timerBarBg);
// GUI: Timer bar
timerBar = LK.getAsset('monster', {
anchorX: 0,
anchorY: 0.5,
x: 624,
y: 100,
width: 800,
height: 40,
tint: 0x3ecf4c
});
game.addChild(timerBar);
// GUI: Timer text
timerText = new Text2(timerMax + "", {
size: 90,
fill: "#fff"
});
timerText.anchor.set(0.5, 0.5);
timerText.x = 2048 - 250;
timerText.y = 100 + 20;
game.addChild(timerText);
// GUI: Stage labels
var stageLabels = [{
name: "Very easy",
min: 0,
max: 15
}, {
name: "Easy",
min: 15,
max: 45
}, {
name: "Medium",
min: 45,
max: 90
}, {
name: "Hard",
min: 90,
max: 150
}, {
name: "Very hard",
min: 150,
max: 9999
}];
var stageTexts = [];
var stageYStart = timerText.y + 80;
for (var i = 0; i < stageLabels.length; ++i) {
var st = new Text2(stageLabels[i].name, {
size: 60,
fill: "#aaa"
});
st.anchor.set(0.5, 0);
st.x = timerText.x;
st.y = stageYStart + i * 70;
game.addChild(st);
stageTexts.push(st);
}
var currentStageIndex = 0;
function updateStageHighlight(elapsed) {
// elapsed is in seconds
var idx = 0;
for (var i = 0; i < stageLabels.length; ++i) {
if (elapsed >= stageLabels[i].min && elapsed < stageLabels[i].max) {
idx = i;
break;
}
}
if (currentStageIndex !== idx) {
currentStageIndex = idx;
}
for (var i = 0; i < stageTexts.length; ++i) {
stageTexts[i].style.fill = i === currentStageIndex ? "#fff" : "#aaa";
stageTexts[i].style.fontWeight = i === currentStageIndex ? "bold" : "normal";
}
}
// Position score at top center, below 100px
scoreText.x = 2048 / 2;
scoreText.y = 10 + 100;
// Spawn initial monsters
for (var i = 0; i < 3; ++i) {
spawnMonster();
}
// Timer tick
function timerTick() {
// Timer decreases faster as difficulty increases
var difficulty = 1 + Math.floor(LK.ticks / 60 / 10) * 0.1; // +10% every 10s
timer -= 0.1 * difficulty;
if (timer < 0) timer = 0;
updateTimerText();
updateTimerBar();
if (timer <= 0) {
// Game over
LK.showGameOver();
}
}
// Start timer interval
timerInterval = LK.setInterval(timerTick, 100);
// Game update
game.update = function () {
// Increase difficulty over time: timer drains faster, spawn rate increases
// Difficulty scaling factor: increases every 10 seconds
var difficulty = 1 + Math.floor(LK.ticks / 60 / 10) * 0.1; // +10% every 10s
// Randomly change spawn interval every 3-6 seconds, but minimum interval decreases with difficulty
if (monsterSpawnIntervalChangeTimer <= 0) {
// Minimum interval decreases as difficulty increases, but never below 15
var minInterval = Math.max(15, 40 - Math.floor((difficulty - 1) * 30));
var maxInterval = Math.max(minInterval + 10, 180 - Math.floor((difficulty - 1) * 100));
monsterSpawnIntervalTarget = minInterval + Math.floor(Math.random() * (maxInterval - minInterval + 1));
// Next change in 180-360 ticks (3-6s)
monsterSpawnIntervalChangeTimer = 180 + Math.floor(Math.random() * 180);
}
monsterSpawnIntervalChangeTimer--;
// Smoothly approach target interval for a less abrupt change
if (monsterSpawnInterval !== monsterSpawnIntervalTarget) {
if (monsterSpawnInterval < monsterSpawnIntervalTarget) monsterSpawnInterval++;else monsterSpawnInterval--;
}
// Spawn monsters
if (LK.ticks - lastTick >= monsterSpawnInterval) {
spawnMonster();
lastTick = LK.ticks;
}
// Move monsters
for (var i = 0; i < monsters.length; ++i) {
monsters[i].update();
}
// Update timer bar
updateTimerBar();
};
// Handle tap on monsters or empty space
game.down = function (x, y, obj) {
// Check if tap hits a monster (from topmost to bottom)
var tapped = false;
for (var i = monsters.length - 1; i >= 0; --i) {
var m = monsters[i];
// Only alive monsters
if (!m.alive) continue;
// Convert tap to monster local coords
var local = m.toLocal(game.toGlobal({
x: x,
y: y
}));
// Check if inside monster ellipse
var rx = m.children[0].width / 2;
var ry = m.children[0].height / 2;
if (local.x * local.x / (rx * rx) + local.y * local.y / (ry * ry) <= 1) {
m.down(x, y, obj);
tapped = true;
break;
}
}
// Tap effect
var tapFx = new TapEffect();
tapFx.x = x;
tapFx.y = y;
game.addChild(tapFx);
};
// Clean up on game over
game.on('destroy', function () {
LK.clearInterval(timerInterval);
monsters = [];
score = 0;
timer = timerMax;
updateScoreText();
updateTimerText();
updateTimerBar();
}); ===================================================================
--- original.js
+++ change.js
@@ -218,13 +218,20 @@
function addTime(sec) {
timer += sec;
if (timer > 99) timer = 99;
updateTimerText();
- updateStageDisplay();
}
// Helper: update timer text
function updateTimerText() {
- timerText.setText(timer > 0 ? Math.ceil(timer) + "" : "0");
+ // Show as MM:SS
+ var t = Math.max(0, Math.ceil(timer));
+ var min = Math.floor(t / 60);
+ var sec = t % 60;
+ var txt = min + ":" + (sec < 10 ? "0" : "") + sec;
+ timerText.setText(txt);
+ // Calculate elapsed time
+ var elapsed = timerMax - timer;
+ updateStageHighlight(elapsed);
}
// Helper: update timer bar
function updateTimerBar() {
var pct = Math.max(0, Math.min(1, timer / timerMax));
@@ -273,82 +280,70 @@
height: 40,
tint: 0x3ecf4c
});
game.addChild(timerBar);
-// GUI: Timer text (move to top right, under 100px)
+// GUI: Timer text
timerText = new Text2(timerMax + "", {
size: 90,
fill: "#fff"
});
-timerText.anchor.set(0.5, 0);
-timerText.x = 2048 - 200;
-timerText.y = 100;
+timerText.anchor.set(0.5, 0.5);
+timerText.x = 2048 - 250;
+timerText.y = 100 + 20;
game.addChild(timerText);
-// Stage labels (move under timerText)
+// GUI: Stage labels
var stageLabels = [{
- label: "Very easy",
+ name: "Very easy",
min: 0,
max: 15
}, {
- label: "Easy",
+ name: "Easy",
min: 15,
max: 45
}, {
- label: "Medium",
+ name: "Medium",
min: 45,
max: 90
}, {
- label: "Hard",
+ name: "Hard",
min: 90,
max: 150
}, {
- label: "Very hard",
+ name: "Very hard",
min: 150,
max: 9999
}];
var stageTexts = [];
-var stageActiveIndex = 0;
-var stageYOffset = 60;
+var stageYStart = timerText.y + 80;
for (var i = 0; i < stageLabels.length; ++i) {
- var st = new Text2(stageLabels[i].label, {
+ var st = new Text2(stageLabels[i].name, {
size: 60,
- fill: "#888"
+ fill: "#aaa"
});
st.anchor.set(0.5, 0);
- st.x = 2048 - 200;
- st.y = timerText.y + 60 + i * stageYOffset;
+ st.x = timerText.x;
+ st.y = stageYStart + i * 70;
game.addChild(st);
stageTexts.push(st);
}
-// Add screen time (elapsed) display where timerText was before (centered at previous timerText position)
-var screenTimeText = new Text2("0:00", {
- size: 90,
- fill: "#fff"
-});
-screenTimeText.anchor.set(0.5, 0.5);
-screenTimeText.x = 2048 - 200;
-screenTimeText.y = 100 + 20;
-game.addChild(screenTimeText);
-function updateStageDisplay() {
- // Find which stage we're in based on elapsed time
- var elapsed = timerMax - timer;
+var currentStageIndex = 0;
+function updateStageHighlight(elapsed) {
+ // elapsed is in seconds
var idx = 0;
for (var i = 0; i < stageLabels.length; ++i) {
if (elapsed >= stageLabels[i].min && elapsed < stageLabels[i].max) {
idx = i;
break;
}
}
- stageActiveIndex = idx;
+ if (currentStageIndex !== idx) {
+ currentStageIndex = idx;
+ }
for (var i = 0; i < stageTexts.length; ++i) {
- // Use setStyle to update fill color instead of direct style.fill assignment
- stageTexts[i].setStyle({
- fill: i === stageActiveIndex ? "#fff" : "#888"
- });
- stageTexts[i].setText(stageLabels[i].label);
+ stageTexts[i].style.fill = i === currentStageIndex ? "#fff" : "#aaa";
+ stageTexts[i].style.fontWeight = i === currentStageIndex ? "bold" : "normal";
}
}
-updateStageDisplay();
// Position score at top center, below 100px
scoreText.x = 2048 / 2;
scoreText.y = 10 + 100;
// Spawn initial monsters
@@ -362,15 +357,8 @@
timer -= 0.1 * difficulty;
if (timer < 0) timer = 0;
updateTimerText();
updateTimerBar();
- updateStageDisplay();
- // Update screen time (elapsed)
- var elapsed = timerMax - timer;
- if (elapsed < 0) elapsed = 0;
- var min = Math.floor(elapsed / 60);
- var sec = Math.floor(elapsed % 60);
- screenTimeText.setText(min + ":" + (sec < 10 ? "0" : "") + sec);
if (timer <= 0) {
// Game over
LK.showGameOver();
}
@@ -444,7 +432,5 @@
timer = timerMax;
updateScoreText();
updateTimerText();
updateTimerBar();
- updateStageDisplay();
- screenTimeText.setText("0:00");
});
\ No newline at end of file
round shaped monster. his mouth is open and his tongue is out . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
make it angry and blue
make it cocky and white
make it purple and suspicious
make it dark green and idiot
make it black and idioter
make it happy and cyan
skeletons, skull, death city, war, crime, illegal . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat