/****
* 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