/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Bull = Container.expand(function () { var self = Container.call(this); var bullGraphics = self.attachAsset('bull', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 8; self.direction = { x: 0, y: 0 }; self.fromDirection = ''; // 'left', 'right', 'top', 'bottom' self.lastX = 0; self.lastY = 0; self.hasTriggeredNearMiss = false; self.isDrone = false; self.transformTimer = 0; self.transformDelay = 300; // 5 seconds before transformation self.setDirection = function (dx, dy, from) { self.direction.x = dx; self.direction.y = dy; self.fromDirection = from; // Use different assets based on movement direction for better visual clarity if (dx !== 0) { // Horizontal movement - use horizontal bull asset self.removeChild(bullGraphics); bullGraphics = self.attachAsset('bullHorizontal', { anchorX: 0.5, anchorY: 0.5 }); if (dx < 0) bullGraphics.rotation = Math.PI; // Face left } else if (dy !== 0) { // Vertical movement - use vertical bull asset self.removeChild(bullGraphics); bullGraphics = self.attachAsset('bullVertical', { anchorX: 0.5, anchorY: 0.5 }); if (dy < 0) bullGraphics.rotation = Math.PI; // Face up } }; self.update = function () { self.lastX = self.x; self.lastY = self.y; // Handle drone transformation if (!self.isDrone) { self.transformTimer++; if (self.transformTimer >= self.transformDelay) { // Transform to drone self.isDrone = true; self.removeChild(bullGraphics); bullGraphics = self.attachAsset('drone', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 12; // Drones are faster // Add floating animation tween(bullGraphics, { y: -10 }, { duration: 1000, yoyo: true, repeat: -1 }); } } // Update movement based on type if (self.isDrone && matador) { // Drone follows matador var dx = matador.x - self.x; var dy = matador.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 0) { self.direction.x = dx / distance; self.direction.y = dy / distance; } } self.x += self.direction.x * self.speed; self.y += self.direction.y * self.speed; // Check for near miss with matador if (!self.hasTriggeredNearMiss && matador) { var distance = Math.sqrt(Math.pow(self.x - matador.x, 2) + Math.pow(self.y - matador.y, 2)); if (distance < 150 && distance > 100) { self.hasTriggeredNearMiss = true; nearMissScore += 5; LK.getSound('nearMiss').play(); LK.effects.flashScreen(0xffd700, 200); } } }; return self; }); var Matador = Container.expand(function () { var self = Container.call(this); var matadorGraphics = self.attachAsset('matador', { anchorX: 0.5, anchorY: 0.5 }); self.isDragging = false; self.targetX = 0; self.targetY = 0; self.speed = 12; self.update = function () { // Smooth movement towards target position if (self.isDragging) { var dx = self.targetX - self.x; var dy = self.targetY - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 5) { self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; } } // Keep matador within game bounds self.x = Math.max(50, Math.min(1998, self.x)); self.y = Math.max(50, Math.min(2682, self.y)); }; self.setTarget = function (x, y) { self.targetX = x; self.targetY = y; }; return self; }); var Mine = Container.expand(function () { var self = Container.call(this); var mineGraphics = self.attachAsset('mine', { anchorX: 0.5, anchorY: 0.5 }); self.isArmed = false; self.armTimer = 0; self.armDelay = 30; // 0.5 seconds to arm self.update = function () { // Arm the mine after delay if (!self.isArmed) { self.armTimer++; if (self.armTimer >= self.armDelay) { self.isArmed = true; mineGraphics.tint = 0xff0000; // Turn red when armed // Add pulsing effect to show mine is active tween(mineGraphics, { scaleX: 1.2, scaleY: 1.2 }, { duration: 300, yoyo: true, repeat: -1 }); } } }; self.explode = function () { // Visual explosion effect LK.effects.flashScreen(0xffaa00, 300); tween(mineGraphics, { scaleX: 3, scaleY: 3, alpha: 0 }, { duration: 500, onFinish: function onFinish() { self.destroy(); } }); LK.getSound('explosion').play(); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0xcd853f }); /**** * Game Code ****/ // Game variables var matador; var bulls = []; var mines = []; var bullSpawnTimer = 0; var bullSpawnInterval = 120; // Start spawning every 2 seconds var gameSpeed = 1; var nearMissScore = 0; var difficultyTimer = 0; var mineSkillCooldown = 0; var mineSkillCooldownMax = 60; // 1 second cooldown var lastTapTime = 0; var tapCount = 0; var doubleTapDelay = 500; // 500ms window for double tap var gameStartTime = Date.now(); var gameTimer = 0; // Create arena background var arenaBackground = game.attachAsset('arena', { anchorX: 0, anchorY: 0, x: 0, y: 0 }); // Create matador matador = game.addChild(new Matador()); matador.x = 1024; matador.y = 1366; // Create timer display var timerTxt = new Text2('00:00', { size: 100, fill: 0xFFFFFF }); timerTxt.anchor.set(0.5, 0); LK.gui.top.addChild(timerTxt); // Create near miss indicator var nearMissText = new Text2('¡Olé!', { size: 80, fill: 0xFFD700 }); nearMissText.anchor.set(0.5, 0.5); nearMissText.alpha = 0; LK.gui.center.addChild(nearMissText); // Bull spawning function function spawnBull() { var bull = new Bull(); var spawnSide = Math.floor(Math.random() * 4); // Determine spawn position and direction switch (spawnSide) { case 0: // Left side bull.x = -60; bull.y = Math.random() * 2732; bull.setDirection(1, 0, 'left'); break; case 1: // Right side bull.x = 2108; bull.y = Math.random() * 2732; bull.setDirection(-1, 0, 'right'); break; case 2: // Top side bull.x = Math.random() * 2048; bull.y = -40; bull.setDirection(0, 1, 'top'); break; case 3: // Bottom side bull.x = Math.random() * 2048; bull.y = 2772; bull.setDirection(0, -1, 'bottom'); break; } bulls.push(bull); game.addChild(bull); LK.getSound('charge').play(); } // Handle mouse/touch movement function handleMove(x, y, obj) { if (matador && matador.isDragging) { matador.setTarget(x, y); } } // Mouse/touch down handler game.down = function (x, y, obj) { if (matador) { matador.isDragging = true; matador.setTarget(x, y); // Double tap detection var currentTime = Date.now(); if (currentTime - lastTapTime < doubleTapDelay) { tapCount++; } else { tapCount = 1; } lastTapTime = currentTime; // Lay mine if double tap detected and skill is available if (tapCount >= 2 && mineSkillCooldown <= 0) { var mine = new Mine(); mine.x = matador.x; mine.y = matador.y; mines.push(mine); game.addChild(mine); mineSkillCooldown = mineSkillCooldownMax; tapCount = 0; // Reset tap count after laying mine } } }; // Mouse/touch up handler game.up = function (x, y, obj) { if (matador) { matador.isDragging = false; } }; // Mouse/touch move handler game.move = handleMove; // Track collision state var lastColliding = false; // Main game update loop game.update = function () { // Update bull spawn timer bullSpawnTimer++; if (bullSpawnTimer >= bullSpawnInterval) { spawnBull(); bullSpawnTimer = 0; } // Increase difficulty over time difficultyTimer++; if (difficultyTimer >= 1800) { // Every 30 seconds difficultyTimer = 0; gameSpeed += 0.2; bullSpawnInterval = Math.max(60, bullSpawnInterval - 10); } // Update mine cooldown if (mineSkillCooldown > 0) { mineSkillCooldown--; } // Update and check bulls for (var i = bulls.length - 1; i >= 0; i--) { var bull = bulls[i]; var bullExploded = false; // Check collision with mines for (var j = mines.length - 1; j >= 0; j--) { var mine = mines[j]; if (mine.isArmed && bull.intersects(mine)) { // Mine explosion mine.explode(); mines.splice(j, 1); bull.destroy(); bulls.splice(i, 1); bullExploded = true; break; } } if (bullExploded) continue; // Check collision with matador var currentColliding = bull.intersects(matador); if (!lastColliding && currentColliding) { // Collision detected - game over LK.effects.flashScreen(0xff0000, 1000); LK.showGameOver(); return; } // Remove bulls that are off screen var offScreen = false; if (bull.fromDirection === 'left' && bull.x > 2100) offScreen = true; if (bull.fromDirection === 'right' && bull.x < -100) offScreen = true; if (bull.fromDirection === 'top' && bull.y > 2800) offScreen = true; if (bull.fromDirection === 'bottom' && bull.y < -100) offScreen = true; if (offScreen) { bull.destroy(); bulls.splice(i, 1); } } // Update timer display gameTimer = Math.floor((Date.now() - gameStartTime) / 1000); var minutes = Math.floor(gameTimer / 60); var seconds = gameTimer % 60; var timeString = (minutes < 10 ? '0' : '') + minutes + ':' + (seconds < 10 ? '0' : '') + seconds; timerTxt.setText(timeString); // Show near miss text effect if (nearMissScore > 0) { nearMissText.alpha = 1; tween(nearMissText, { alpha: 0 }, { duration: 1000 }); nearMissScore = 0; } }; // Start background music LK.playMusic('flamenco');
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Bull = Container.expand(function () {
var self = Container.call(this);
var bullGraphics = self.attachAsset('bull', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8;
self.direction = {
x: 0,
y: 0
};
self.fromDirection = ''; // 'left', 'right', 'top', 'bottom'
self.lastX = 0;
self.lastY = 0;
self.hasTriggeredNearMiss = false;
self.isDrone = false;
self.transformTimer = 0;
self.transformDelay = 300; // 5 seconds before transformation
self.setDirection = function (dx, dy, from) {
self.direction.x = dx;
self.direction.y = dy;
self.fromDirection = from;
// Use different assets based on movement direction for better visual clarity
if (dx !== 0) {
// Horizontal movement - use horizontal bull asset
self.removeChild(bullGraphics);
bullGraphics = self.attachAsset('bullHorizontal', {
anchorX: 0.5,
anchorY: 0.5
});
if (dx < 0) bullGraphics.rotation = Math.PI; // Face left
} else if (dy !== 0) {
// Vertical movement - use vertical bull asset
self.removeChild(bullGraphics);
bullGraphics = self.attachAsset('bullVertical', {
anchorX: 0.5,
anchorY: 0.5
});
if (dy < 0) bullGraphics.rotation = Math.PI; // Face up
}
};
self.update = function () {
self.lastX = self.x;
self.lastY = self.y;
// Handle drone transformation
if (!self.isDrone) {
self.transformTimer++;
if (self.transformTimer >= self.transformDelay) {
// Transform to drone
self.isDrone = true;
self.removeChild(bullGraphics);
bullGraphics = self.attachAsset('drone', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 12; // Drones are faster
// Add floating animation
tween(bullGraphics, {
y: -10
}, {
duration: 1000,
yoyo: true,
repeat: -1
});
}
}
// Update movement based on type
if (self.isDrone && matador) {
// Drone follows matador
var dx = matador.x - self.x;
var dy = matador.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
self.direction.x = dx / distance;
self.direction.y = dy / distance;
}
}
self.x += self.direction.x * self.speed;
self.y += self.direction.y * self.speed;
// Check for near miss with matador
if (!self.hasTriggeredNearMiss && matador) {
var distance = Math.sqrt(Math.pow(self.x - matador.x, 2) + Math.pow(self.y - matador.y, 2));
if (distance < 150 && distance > 100) {
self.hasTriggeredNearMiss = true;
nearMissScore += 5;
LK.getSound('nearMiss').play();
LK.effects.flashScreen(0xffd700, 200);
}
}
};
return self;
});
var Matador = Container.expand(function () {
var self = Container.call(this);
var matadorGraphics = self.attachAsset('matador', {
anchorX: 0.5,
anchorY: 0.5
});
self.isDragging = false;
self.targetX = 0;
self.targetY = 0;
self.speed = 12;
self.update = function () {
// Smooth movement towards target position
if (self.isDragging) {
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 5) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
}
// Keep matador within game bounds
self.x = Math.max(50, Math.min(1998, self.x));
self.y = Math.max(50, Math.min(2682, self.y));
};
self.setTarget = function (x, y) {
self.targetX = x;
self.targetY = y;
};
return self;
});
var Mine = Container.expand(function () {
var self = Container.call(this);
var mineGraphics = self.attachAsset('mine', {
anchorX: 0.5,
anchorY: 0.5
});
self.isArmed = false;
self.armTimer = 0;
self.armDelay = 30; // 0.5 seconds to arm
self.update = function () {
// Arm the mine after delay
if (!self.isArmed) {
self.armTimer++;
if (self.armTimer >= self.armDelay) {
self.isArmed = true;
mineGraphics.tint = 0xff0000; // Turn red when armed
// Add pulsing effect to show mine is active
tween(mineGraphics, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 300,
yoyo: true,
repeat: -1
});
}
}
};
self.explode = function () {
// Visual explosion effect
LK.effects.flashScreen(0xffaa00, 300);
tween(mineGraphics, {
scaleX: 3,
scaleY: 3,
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
self.destroy();
}
});
LK.getSound('explosion').play();
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xcd853f
});
/****
* Game Code
****/
// Game variables
var matador;
var bulls = [];
var mines = [];
var bullSpawnTimer = 0;
var bullSpawnInterval = 120; // Start spawning every 2 seconds
var gameSpeed = 1;
var nearMissScore = 0;
var difficultyTimer = 0;
var mineSkillCooldown = 0;
var mineSkillCooldownMax = 60; // 1 second cooldown
var lastTapTime = 0;
var tapCount = 0;
var doubleTapDelay = 500; // 500ms window for double tap
var gameStartTime = Date.now();
var gameTimer = 0;
// Create arena background
var arenaBackground = game.attachAsset('arena', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
});
// Create matador
matador = game.addChild(new Matador());
matador.x = 1024;
matador.y = 1366;
// Create timer display
var timerTxt = new Text2('00:00', {
size: 100,
fill: 0xFFFFFF
});
timerTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(timerTxt);
// Create near miss indicator
var nearMissText = new Text2('¡Olé!', {
size: 80,
fill: 0xFFD700
});
nearMissText.anchor.set(0.5, 0.5);
nearMissText.alpha = 0;
LK.gui.center.addChild(nearMissText);
// Bull spawning function
function spawnBull() {
var bull = new Bull();
var spawnSide = Math.floor(Math.random() * 4);
// Determine spawn position and direction
switch (spawnSide) {
case 0:
// Left side
bull.x = -60;
bull.y = Math.random() * 2732;
bull.setDirection(1, 0, 'left');
break;
case 1:
// Right side
bull.x = 2108;
bull.y = Math.random() * 2732;
bull.setDirection(-1, 0, 'right');
break;
case 2:
// Top side
bull.x = Math.random() * 2048;
bull.y = -40;
bull.setDirection(0, 1, 'top');
break;
case 3:
// Bottom side
bull.x = Math.random() * 2048;
bull.y = 2772;
bull.setDirection(0, -1, 'bottom');
break;
}
bulls.push(bull);
game.addChild(bull);
LK.getSound('charge').play();
}
// Handle mouse/touch movement
function handleMove(x, y, obj) {
if (matador && matador.isDragging) {
matador.setTarget(x, y);
}
}
// Mouse/touch down handler
game.down = function (x, y, obj) {
if (matador) {
matador.isDragging = true;
matador.setTarget(x, y);
// Double tap detection
var currentTime = Date.now();
if (currentTime - lastTapTime < doubleTapDelay) {
tapCount++;
} else {
tapCount = 1;
}
lastTapTime = currentTime;
// Lay mine if double tap detected and skill is available
if (tapCount >= 2 && mineSkillCooldown <= 0) {
var mine = new Mine();
mine.x = matador.x;
mine.y = matador.y;
mines.push(mine);
game.addChild(mine);
mineSkillCooldown = mineSkillCooldownMax;
tapCount = 0; // Reset tap count after laying mine
}
}
};
// Mouse/touch up handler
game.up = function (x, y, obj) {
if (matador) {
matador.isDragging = false;
}
};
// Mouse/touch move handler
game.move = handleMove;
// Track collision state
var lastColliding = false;
// Main game update loop
game.update = function () {
// Update bull spawn timer
bullSpawnTimer++;
if (bullSpawnTimer >= bullSpawnInterval) {
spawnBull();
bullSpawnTimer = 0;
}
// Increase difficulty over time
difficultyTimer++;
if (difficultyTimer >= 1800) {
// Every 30 seconds
difficultyTimer = 0;
gameSpeed += 0.2;
bullSpawnInterval = Math.max(60, bullSpawnInterval - 10);
}
// Update mine cooldown
if (mineSkillCooldown > 0) {
mineSkillCooldown--;
}
// Update and check bulls
for (var i = bulls.length - 1; i >= 0; i--) {
var bull = bulls[i];
var bullExploded = false;
// Check collision with mines
for (var j = mines.length - 1; j >= 0; j--) {
var mine = mines[j];
if (mine.isArmed && bull.intersects(mine)) {
// Mine explosion
mine.explode();
mines.splice(j, 1);
bull.destroy();
bulls.splice(i, 1);
bullExploded = true;
break;
}
}
if (bullExploded) continue;
// Check collision with matador
var currentColliding = bull.intersects(matador);
if (!lastColliding && currentColliding) {
// Collision detected - game over
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
return;
}
// Remove bulls that are off screen
var offScreen = false;
if (bull.fromDirection === 'left' && bull.x > 2100) offScreen = true;
if (bull.fromDirection === 'right' && bull.x < -100) offScreen = true;
if (bull.fromDirection === 'top' && bull.y > 2800) offScreen = true;
if (bull.fromDirection === 'bottom' && bull.y < -100) offScreen = true;
if (offScreen) {
bull.destroy();
bulls.splice(i, 1);
}
}
// Update timer display
gameTimer = Math.floor((Date.now() - gameStartTime) / 1000);
var minutes = Math.floor(gameTimer / 60);
var seconds = gameTimer % 60;
var timeString = (minutes < 10 ? '0' : '') + minutes + ':' + (seconds < 10 ? '0' : '') + seconds;
timerTxt.setText(timeString);
// Show near miss text effect
if (nearMissScore > 0) {
nearMissText.alpha = 1;
tween(nearMissText, {
alpha: 0
}, {
duration: 1000
});
nearMissScore = 0;
}
};
// Start background music
LK.playMusic('flamenco');
war drone scifi model In-Game asset. 2d. High contrast. No shadows
scifi quad copter drone. In-Game asset. 2d. High contrast. No shadows
top down view scifi quad copter drone. red scorpion In-Game asset. 2d. High contrast. No shadows
sci fi floating war mine with red light In-Game asset. 2d. High contrast. No shadows
red and yellow mix orb. In-Game asset. 2d. High contrast. No shadows
langit malam dikejauhan kota modern dengan lampu lampu sorot ke atas langit . anime 2d. High contrast. No shadows