User prompt
If monsters hp goes down 5 from smite damage player lost, above that player wins
User prompt
Game dont end with 1 loss, let player play 10 round
User prompt
If player click smite value above 10 he win
User prompt
If go down from smite value make round lose for player
User prompt
Each round give random hp value and damage value
User prompt
Make one target, not three but give me a number for hp of monster. And give damage to smite and let me see it
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'flash')' in or related to this line: 'monster.flash(0xffcc00, 600);' Line Number: 337
User prompt
Please add numerous hp bar and, smite damage
User prompt
Make large not tall
User prompt
Make bar bigger please
User prompt
Please add hp bar and smite damage
User prompt
Please fix the bug: 'Uncaught TypeError: resultTxt.setFill is not a function' in or related to this line: 'resultTxt.setFill("#ffcc00");' Line Number: 246
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot set properties of undefined (setting 'fill')' in or related to this line: 'resultTxt.style.fill = "#ffcc00";' Line Number: 246
Code edit (1 edits merged)
Please save this source code
User prompt
Smite Timing Trainer
Initial prompt
Make me a League Of Legends "smite" practice tool game
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Monster class: handles monster sprite and health bar
var Monster = Container.expand(function () {
var self = Container.call(this);
// Monster sprite
var monsterSprite = self.attachAsset('monster', {
anchorX: 0.5,
anchorY: 0.5
});
monsterSprite.y = 0;
// Health bar background
var hpbarBg = self.attachAsset('hpbar_bg', {
anchorX: 0.5,
anchorY: 0.5,
y: 260
});
// Health bar foreground
var hpbarFg = self.attachAsset('hpbar_fg', {
anchorX: 0.5,
anchorY: 0.5,
y: 260
});
// Health bar value (0-1)
self.hp = 1;
self.maxHp = 1;
// Set health (0-1)
self.setHp = function (value) {
self.hp = Math.max(0, Math.min(1, value));
// Scale health bar foreground
hpbarFg.scaleX = self.hp;
// Anchor stays at left edge
hpbarFg.x = hpbarBg.x - 1000 * (1 - self.hp) / 2;
};
// Flash monster on smite
self.flash = function (color, duration) {
tween(monsterSprite, {
tint: color
}, {
duration: duration / 2,
easing: tween.linear,
onFinish: function onFinish() {
tween(monsterSprite, {
tint: 0x3cb371
}, {
duration: duration / 2,
easing: tween.linear
});
}
});
};
// Reset health bar
self.reset = function () {
self.setHp(1);
};
// Initialize
self.setHp(1);
return self;
});
// Smite effect (player or enemy)
var SmiteFX = Container.expand(function () {
var self = Container.call(this);
var fx = self.attachAsset('smite_fx', {
anchorX: 0.5,
anchorY: 0.5
});
self.play = function (x, y, isEnemy) {
self.x = x;
self.y = y;
fx.alpha = 1;
fx.scaleX = fx.scaleY = 1;
if (isEnemy) {
fx.tint = 0xff3333;
} else {
fx.tint = 0x3399ff;
}
tween(fx, {
alpha: 0,
scaleX: 2,
scaleY: 2
}, {
duration: 400,
easing: tween.easeOut,
onFinish: function onFinish() {
self.visible = false;
}
});
self.visible = true;
};
self.visible = false;
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x181c24
});
/****
* Game Code
****/
// Sound for smite
// Enemy smite: red ellipse
// Smite effect: blue ellipse
// Health bar foreground: yellow-green
// Health bar background: gray
// Monster: Big ellipse, green
// Game constants
var MONSTER_CENTER_X = 2048 / 2;
var MONSTER_CENTER_Y = 1100;
var HPBAR_Y_OFFSET = 320;
var SMITE_WINDOW = 0.12; // Smite is successful if HP <= this fraction
var ENEMY_SMITE_WINDOW = 0.10; // Enemy can smite if HP <= this
var ROUNDS_TOTAL = 10;
// Game state
var round = 1;
var score = 0;
var smiteUsed = false;
var enemySmiteUsed = false;
var monsterHp = 1;
var monsterHpSpeed = 0.003; // per tick
var monsterHpMinSpeed = 0.002;
var monsterHpMaxSpeed = 0.006;
var smiteFx, enemySmiteFx;
var monster;
var resultTxt, roundTxt, scoreTxt, infoTxt;
var lastTickTime = 0;
var smiteTime = 0;
var enemySmiteTime = 0;
var smiteAccuracy = [];
var smiteReaction = [];
var smiteSuccess = [];
var smiteAllowed = true;
var enemySmiteScheduled = false;
var enemySmiteTick = 0;
var enemySmiteActive = false;
// UI: Score, round, info
scoreTxt = new Text2('Score: 0', {
size: 90,
fill: "#fff"
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
roundTxt = new Text2('Round 1/10', {
size: 70,
fill: "#fff"
});
roundTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(roundTxt);
roundTxt.y = 110;
infoTxt = new Text2('Tap the monster to Smite!', {
size: 70,
fill: 0xB8E62E
});
infoTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(infoTxt);
infoTxt.y = 220;
// Result text (centered, hidden by default)
resultTxt = new Text2('', {
size: 120,
fill: "#fff"
});
resultTxt.anchor.set(0.5, 0.5);
resultTxt.visible = false;
LK.gui.center.addChild(resultTxt);
// Monster
monster = new Monster();
game.addChild(monster);
monster.x = MONSTER_CENTER_X;
monster.y = MONSTER_CENTER_Y;
// Smite damage value (as a fraction of max HP)
var SMITE_DAMAGE = 0.12;
// Smite damage text (shows the value)
var smiteDmgTxt = new Text2('Smite: ' + Math.round(SMITE_DAMAGE * 100) + '%', {
size: 70,
fill: 0x3399FF
});
smiteDmgTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(smiteDmgTxt);
smiteDmgTxt.y = 320;
// Smite damage marker on HP bar
var smiteMarker = LK.getAsset('hpbar_fg', {
anchorX: 0.5,
anchorY: 0.5,
width: 10,
height: 70,
tint: 0x3399ff
});
game.addChild(smiteMarker);
// Helper to update smite marker position
function updateSmiteMarker() {
// HP bar is at monster.x, monster.y + HPBAR_Y_OFFSET
// HP bar width is 1000, anchorX = 0.5 (centered)
var barWidth = 1000;
var barY = monster.y + HPBAR_Y_OFFSET;
var barX = monster.x;
// Smite marker should be at the position where HP = SMITE_DAMAGE
var markerFrac = 1 - SMITE_DAMAGE;
var markerX = barX - barWidth / 2 + barWidth * markerFrac;
smiteMarker.x = markerX;
smiteMarker.y = barY;
smiteMarker.width = 18;
smiteMarker.height = 120;
smiteMarker.visible = true;
}
updateSmiteMarker();
// Smite FX
smiteFx = new SmiteFX();
game.addChild(smiteFx);
smiteFx.x = MONSTER_CENTER_X;
smiteFx.y = MONSTER_CENTER_Y;
enemySmiteFx = new SmiteFX();
game.addChild(enemySmiteFx);
enemySmiteFx.x = MONSTER_CENTER_X;
enemySmiteFx.y = MONSTER_CENTER_Y;
// Helper: Start a new round
function startRound() {
// Reset state
monsterHp = 1;
monster.reset();
smiteUsed = false;
enemySmiteUsed = false;
smiteAllowed = true;
enemySmiteActive = false;
enemySmiteScheduled = false;
smiteFx.visible = false;
enemySmiteFx.visible = false;
resultTxt.visible = false;
// Randomize HP speed for this round
monsterHpSpeed = monsterHpMinSpeed + Math.random() * (monsterHpMaxSpeed - monsterHpMinSpeed);
// Schedule enemy smite (randomly, 60% chance)
if (Math.random() < 0.6) {
enemySmiteScheduled = true;
// Enemy smite will happen at a random HP between 0.08 and 0.13
var enemyHpTarget = 0.08 + Math.random() * 0.05;
// Calculate tick when enemy will smite
enemySmiteTick = Math.floor((1 - enemyHpTarget) / monsterHpSpeed);
} else {
enemySmiteScheduled = false;
}
// Update UI
roundTxt.setText('Round ' + round + '/' + ROUNDS_TOTAL);
scoreTxt.setText('Score: ' + score);
infoTxt.setText('Tap the monster to Smite!');
lastTickTime = LK.ticks;
updateSmiteMarker();
}
// Helper: End round, show result, schedule next
function endRound(success, isEnemy) {
smiteAllowed = false;
smiteSuccess.push(success ? 1 : 0);
// Show result
if (isEnemy) {
resultTxt.setText('Enemy Stole It!');
resultTxt.setStyle({
fill: 0xFF3333
});
LK.getSound('enemy').play();
} else if (success) {
resultTxt.setText('Smite Success!');
resultTxt.setStyle({
fill: 0x3399FF
});
LK.getSound('smite').play();
} else {
resultTxt.setText('Missed!');
resultTxt.setStyle({
fill: 0xFFCC00
});
LK.getSound('fail').play();
}
resultTxt.visible = true;
// Animate monster
if (isEnemy) {
monster.flash(0xff3333, 600);
} else if (success) {
monster.flash(0x3399ff, 600);
} else {
monster.flash(0xffcc00, 600);
}
// Next round or finish
LK.setTimeout(function () {
resultTxt.visible = false;
if (round < ROUNDS_TOTAL) {
round++;
startRound();
} else {
showSummary();
}
}, 1100);
}
// Helper: Show summary at end
function showSummary() {
// Calculate stats
var acc = 0,
react = 0,
hits = 0;
for (var i = 0; i < smiteAccuracy.length; ++i) {
acc += smiteAccuracy[i];
react += smiteReaction[i];
if (smiteSuccess[i]) hits++;
}
var avgAcc = smiteAccuracy.length ? acc / smiteAccuracy.length : 0;
var avgReact = smiteReaction.length ? react / smiteReaction.length : 0;
var summary = 'Game Over\n\n' + 'Score: ' + score + '/' + ROUNDS_TOTAL + '\n' + 'Avg. Accuracy: ' + (avgAcc * 100).toFixed(1) + '%\n' + 'Avg. Reaction: ' + (avgReact * 1000).toFixed(0) + 'ms';
resultTxt.setText(summary);
resultTxt.setStyle({
fill: 0xB8E62E
});
resultTxt.visible = true;
infoTxt.setText('Tap to play again!');
// Reset on tap
game.down = function (x, y, obj) {
// Reset state
round = 1;
score = 0;
smiteAccuracy = [];
smiteReaction = [];
smiteSuccess = [];
startRound();
game.down = handleDown;
};
}
// Handle player smite
function handleDown(x, y, obj) {
// Only allow if not already smited and round is active
if (!smiteAllowed || smiteUsed) return;
// Only allow if tap is on monster (ellipse)
var dx = x - monster.x;
var dy = y - monster.y;
var rx = monster.width / 2;
var ry = monster.height / 2;
if (dx * dx / (rx * rx) + dy * dy / (ry * ry) > 1) return;
smiteUsed = true;
smiteTime = LK.ticks - lastTickTime;
// Smite effect
smiteFx.play(monster.x, monster.y, false);
// Check if successful
var success = monsterHp <= SMITE_WINDOW && !enemySmiteActive;
if (success) {
score++;
}
// Record accuracy (how close to 0)
var acc = monsterHp <= 1 ? 1 - monsterHp / SMITE_WINDOW : 0;
acc = Math.max(0, Math.min(1, acc));
smiteAccuracy.push(1 - monsterHp);
smiteReaction.push(smiteTime / 60);
endRound(success, false);
}
// Attach event
game.down = handleDown;
// Main update loop
game.update = function () {
// If round is active
if (smiteAllowed && !smiteUsed) {
// Decrease HP
monsterHp -= monsterHpSpeed;
if (monsterHp < 0) monsterHp = 0;
monster.setHp(monsterHp);
// Enemy smite
if (enemySmiteScheduled && !enemySmiteUsed && LK.ticks - lastTickTime >= enemySmiteTick) {
enemySmiteUsed = true;
enemySmiteActive = true;
enemySmiteFx.play(monster.x, monster.y, true);
endRound(false, true);
}
// If player missed (HP reaches 0)
if (monsterHp <= 0 && !enemySmiteUsed) {
smiteUsed = true;
smiteAccuracy.push(0);
smiteReaction.push(1);
endRound(false, false);
}
}
};
// Start first round
startRound(); ===================================================================
--- original.js
+++ change.js
@@ -35,9 +35,9 @@
self.hp = Math.max(0, Math.min(1, value));
// Scale health bar foreground
hpbarFg.scaleX = self.hp;
// Anchor stays at left edge
- hpbarFg.x = hpbarBg.x - hpbarBg.width * (1 - self.hp) / 2;
+ hpbarFg.x = hpbarBg.x - 1000 * (1 - self.hp) / 2;
};
// Flash monster on smite
self.flash = function (color, duration) {
tween(monsterSprite, {
@@ -115,9 +115,9 @@
// Monster: Big ellipse, green
// Game constants
var MONSTER_CENTER_X = 2048 / 2;
var MONSTER_CENTER_Y = 1100;
-var HPBAR_Y_OFFSET = 260;
+var HPBAR_Y_OFFSET = 320;
var SMITE_WINDOW = 0.12; // Smite is successful if HP <= this fraction
var ENEMY_SMITE_WINDOW = 0.10; // Enemy can smite if HP <= this
var ROUNDS_TOTAL = 10;
// Game state
@@ -197,19 +197,19 @@
game.addChild(smiteMarker);
// Helper to update smite marker position
function updateSmiteMarker() {
// HP bar is at monster.x, monster.y + HPBAR_Y_OFFSET
- // HP bar width is 600, anchorX = 0.5 (centered)
- var barWidth = 600;
+ // HP bar width is 1000, anchorX = 0.5 (centered)
+ var barWidth = 1000;
var barY = monster.y + HPBAR_Y_OFFSET;
var barX = monster.x;
// Smite marker should be at the position where HP = SMITE_DAMAGE
var markerFrac = 1 - SMITE_DAMAGE;
var markerX = barX - barWidth / 2 + barWidth * markerFrac;
smiteMarker.x = markerX;
smiteMarker.y = barY;
- smiteMarker.width = 10;
- smiteMarker.height = 70;
+ smiteMarker.width = 18;
+ smiteMarker.height = 120;
smiteMarker.visible = true;
}
updateSmiteMarker();
// Smite FX