User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'addChild')' in or related to this line: 'game.addChild(projectile);' Line Number: 289
User prompt
add more cubes like gold diamond etc
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'addChild')' in or related to this line: 'game.addChild(self.healthBarContainer);' Line Number: 219
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'addChild')' in or related to this line: 'game.addChild(self.healthBarContainer);' Line Number: 219
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'addChild')' in or related to this line: 'game.addChild(self.healthBarContainer);' Line Number: 217
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'addChild')' in or related to this line: 'game.addChild(self.healthBarContainer);' Line Number: 217
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'addChild')' in or related to this line: 'game.addChild(self.healthBarContainer);' Line Number: 217
User prompt
There is a bug in the boss fight, it says error addchild etc. fix that bug
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'addChild')' in or related to this line: 'game.addChild(self.healthBarContainer);' Line Number: 216
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'addChild')' in or related to this line: 'game.addChild(self.healthBarContainer);' Line Number: 217
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'addChild')' in or related to this line: 'game.addChild(self.healthBarContainer);' Line Number: 217
User prompt
change the bosses face and fix the health bar and have different phases of the boss, have 3 different phases and make the boss's health bar at the top so that it is visible when the boss comes
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'y')' in or related to this line: 'var angle = Math.atan2(player.y - self.y, player.x - self.x);' Line Number: 142
User prompt
Make the boss a little better, let his type be different and let us have a health bar and the boss's health bar is crooked, fix that too and in the boss fight, all the green and red hearts will be scared and run away and then watch us ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Please fix the bug: 'TypeError: Cannot read properties of null (reading 'x')' in or related to this line: 'var dx = target.x - self.x;' Line Number: 521
User prompt
When you reach the final 2500 points, there will be a boss fight and when you win, all the cups will be saved and there will be enemies and then suddenly an alien will appear on the screen and it will say to be continued
User prompt
Let the game be finalized when you reach 5500 points instead of 50 levels.
User prompt
Let's develop the game more and level up etc., let's earn weapons etc. as we level up for every 100 points and let's have different cups to collect, for example 20 point or 30 point cups and let's see these as we level up
User prompt
Please fix the bug: 'TypeError: Cannot set properties of undefined (setting 'fill')' in or related to this line: 'timerText.style.fill = 0x2ecc71;' Line Number: 392
User prompt
Edit the game assests, make the main character's face visible and how many points we have at the moment, make the obstacles have faces and make the graphics better, make the background colorful ↪💡 Consider importing and using the following plugins: @upit/tween.v1
Code edit (1 edits merged)
Please save this source code
User prompt
Cube Collector
Initial prompt
Here’s the idea in English: Game Concept: "Collect the Cubes" Gameplay: The player controls a square (character) on the screen and the goal is to collect randomly placed small cubes. The cubes will appear at different locations each time, and the player gains points by collecting them. Mechanics: The player moves the square up, down, left, or right using arrow keys or touch controls. The cubes will randomly appear on the screen, and the player needs to collect them. Over time, the speed of the cubes increases, or more obstacles might appear on the screen, challenging the player to stay alert. Each collected cube earns the player a point. The game can either last for a set amount of time or end once the player reaches a specific score. Extra Features: Obstacles: Moving obstacles on the screen could limit the player's movement area or cause the game to end if hit. Time Limit: The player earns more points for collecting cubes within a certain time frame. Scoreboard: A high score table could be added to track the best scores. It’s a simple game, but with increasing difficulty, it can keep players engaged and challenged.
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var CollectableCube = Container.expand(function () {
var self = Container.call(this);
var cubeGraphics = self.attachAsset('collectableCube', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0x00ffff // Cyan color for the cube
});
// Create face features
var leftEye = LK.getAsset('collectableCube', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.2,
scaleY: 0.2,
tint: 0x000000,
// Black eyes
x: -15,
y: -10
});
var rightEye = LK.getAsset('collectableCube', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.2,
scaleY: 0.2,
tint: 0x000000,
// Black eyes
x: 15,
y: -10
});
var mouth = LK.getAsset('collectableCube', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.5,
scaleY: 0.15,
tint: 0x000000,
// Black mouth
x: 0,
y: 15
});
// Add the face features to the cube
self.addChild(leftEye);
self.addChild(rightEye);
self.addChild(mouth);
// Add point value text
var pointsTxt = new Text2('+10', {
size: 30,
fill: 0xFFFFFF
});
pointsTxt.anchor.set(0.5, 0.5);
pointsTxt.y = -40;
self.addChild(pointsTxt);
self.value = 10;
self.cubeType = 'normal';
self.spawnTime = 0;
self.pulseAnimation = function () {
tween(cubeGraphics, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 300,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(cubeGraphics, {
scaleX: 1,
scaleY: 1
}, {
duration: 300,
easing: tween.easeInOut
});
}
});
};
self.randomPosition = function (minX, maxX, minY, maxY) {
self.x = minX + Math.random() * (maxX - minX);
self.y = minY + Math.random() * (maxY - minY);
self.spawnTime = Date.now();
self.pulseAnimation();
};
self.setCubeType = function (type) {
self.cubeType = type;
switch (type) {
case 'silver':
self.value = 20;
pointsTxt.setText('+20');
cubeGraphics.tint = 0xC0C0C0; // Silver
break;
case 'gold':
self.value = 30;
pointsTxt.setText('+30');
cubeGraphics.tint = 0xFFD700; // Gold
break;
case 'normal':
default:
self.value = 10;
pointsTxt.setText('+10');
cubeGraphics.tint = 0x00FFFF; // Cyan
break;
}
// Update the facial expression based on cube type
if (type === 'gold') {
// Happy expression for gold cubes
mouth.scaleY = 0.2;
mouth.y = 10;
} else if (type === 'silver') {
// Neutral expression for silver cubes
mouth.scaleY = 0.15;
mouth.y = 15;
} else {
// Normal expression
mouth.scaleY = 0.15;
mouth.y = 15;
}
};
return self;
});
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var obstacleGraphics = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0xff5555 // Bright red for obstacles
});
// Create angry face for obstacle
var leftEye = LK.getAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.15,
scaleY: 0.25,
tint: 0xFFFFFF,
// White eyes
x: -40,
y: -5
});
var rightEye = LK.getAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.15,
scaleY: 0.25,
tint: 0xFFFFFF,
// White eyes
x: 40,
y: -5
});
var leftPupil = LK.getAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.06,
scaleY: 0.12,
tint: 0x000000,
// Black pupils
x: -40,
y: -2
});
var rightPupil = LK.getAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.06,
scaleY: 0.12,
tint: 0x000000,
// Black pupils
x: 40,
y: -2
});
var mouth = LK.getAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.5,
scaleY: 0.12,
tint: 0x000000,
// Black mouth
x: 0,
y: 10
});
// Add face features to obstacle
self.addChild(leftEye);
self.addChild(rightEye);
self.addChild(leftPupil);
self.addChild(rightPupil);
self.addChild(mouth);
self.speedX = 0;
self.speedY = 0;
self.update = function () {
self.x += self.speedX;
self.y += self.speedY;
// Bounce off screen edges
if (self.x < obstacleGraphics.width / 2 || self.x > 2048 - obstacleGraphics.width / 2) {
self.speedX *= -1;
}
if (self.y < obstacleGraphics.height / 2 || self.y > 2732 - obstacleGraphics.height / 2) {
self.speedY *= -1;
}
// Rotate obstacle slightly based on direction for visual effect
var targetRotation = Math.atan2(self.speedY, self.speedX) * 0.2;
self.rotation += (targetRotation - self.rotation) * 0.1;
};
self.setRandomSpeed = function (maxSpeed) {
// Ensure obstacle always moves by setting minimum speed
var minSpeed = maxSpeed * 0.3;
// Generate random speeds between min and max
self.speedX = (Math.random() > 0.5 ? 1 : -1) * (minSpeed + Math.random() * (maxSpeed - minSpeed));
self.speedY = (Math.random() > 0.5 ? 1 : -1) * (minSpeed + Math.random() * (maxSpeed - minSpeed));
// Give each obstacle a unique color variation
obstacleGraphics.tint = 0xff0000 + Math.floor(Math.random() * 0x5555);
};
self.randomPosition = function (minX, maxX, minY, maxY) {
self.x = minX + Math.random() * (maxX - minX);
self.y = minY + Math.random() * (maxY - minY);
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('playerCube', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0x3498db // Bright blue for player
});
// Create face for player
var leftEye = LK.getAsset('playerCube', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.2,
scaleY: 0.2,
tint: 0xFFFFFF,
// White eyes
x: -20,
y: -15
});
var rightEye = LK.getAsset('playerCube', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.2,
scaleY: 0.2,
tint: 0xFFFFFF,
// White eyes
x: 20,
y: -15
});
var leftPupil = LK.getAsset('playerCube', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.1,
scaleY: 0.1,
tint: 0x000000,
// Black pupils
x: -20,
y: -15
});
var rightPupil = LK.getAsset('playerCube', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.1,
scaleY: 0.1,
tint: 0x000000,
// Black pupils
x: 20,
y: -15
});
var mouth = LK.getAsset('playerCube', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.5,
scaleY: 0.2,
tint: 0x000000,
// Black mouth
x: 0,
y: 15
});
// Add score display on player
var scoreBubble = LK.getAsset('playerCube', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.7,
scaleY: 0.5,
tint: 0xFFFFFF,
// White bubble
x: 0,
y: -60
});
// Add face features to player
self.addChild(leftEye);
self.addChild(rightEye);
self.addChild(leftPupil);
self.addChild(rightPupil);
self.addChild(mouth);
self.addChild(scoreBubble);
// Create player score display
var playerScoreTxt = new Text2('0', {
size: 32,
fill: 0x000000
});
playerScoreTxt.anchor.set(0.5, 0.5);
playerScoreTxt.y = -60;
self.addChild(playerScoreTxt);
// Add weapon display
var weaponHolder = new Container();
self.addChild(weaponHolder);
weaponHolder.y = 50;
// Current weapon
self.weapon = new Weapon();
self.weapon.setWeaponType('basic', 1);
weaponHolder.addChild(self.weapon);
// Level indicators
var levelIndicator = new Text2('Lv.1', {
size: 24,
fill: 0xFFFFFF
});
levelIndicator.anchor.set(0.5, 0.5);
levelIndicator.y = 25;
weaponHolder.addChild(levelIndicator);
self.updateScore = function (newScore) {
playerScoreTxt.setText(newScore);
};
self.updateWeapon = function (type, level) {
self.weapon.setWeaponType(type, level);
levelIndicator.setText('Lv.' + level);
// Flash weapon effect
tween(weaponHolder, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 300,
easing: tween.elasticOut,
onFinish: function onFinish() {
tween(weaponHolder, {
scaleX: 1,
scaleY: 1
}, {
duration: 200,
easing: tween.easeOut
});
}
});
};
self.fireWeapon = function (targets, game, weaponEffects) {
if (self.weapon.canFire()) {
// Get weapon stats
var damage = self.weapon.fire();
var type = self.weapon.type;
// Create weapon effect
var effect = new WeaponEffect();
effect.setEffectType(type, damage);
// Position at player
effect.x = self.x;
effect.y = self.y;
// If we have targets, aim at the nearest one
var nearestTarget = null;
var minDistance = Number.MAX_VALUE;
for (var i = 0; i < targets.length; i++) {
var target = targets[i];
var dx = target.x - self.x;
var dy = target.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < minDistance) {
minDistance = distance;
nearestTarget = target;
}
}
if (nearestTarget) {
var angle = Math.atan2(nearestTarget.y - self.y, nearestTarget.x - self.x);
effect.rotation = angle;
} else {
// If no targets, fire forward
effect.rotation = 0;
}
game.addChild(effect);
weaponEffects.push(effect);
// Flash the weapon
self.weapon.alpha = 0.7;
tween(self.weapon, {
alpha: 1
}, {
duration: 200,
easing: tween.easeOut
});
return true;
}
return false;
};
self.speed = 10;
self.targetX = 0;
self.targetY = 0;
self.moving = false;
self.setTarget = function (x, y) {
self.targetX = x;
self.targetY = y;
self.moving = true;
// Animate eyes to look in move direction
var eyeAngle = Math.atan2(y - self.y, x - self.x);
var eyeOffsetX = Math.cos(eyeAngle) * 3;
var eyeOffsetY = Math.sin(eyeAngle) * 3;
tween(leftPupil, {
x: -20 + eyeOffsetX,
y: -15 + eyeOffsetY
}, {
duration: 200,
easing: tween.easeOut
});
tween(rightPupil, {
x: 20 + eyeOffsetX,
y: -15 + eyeOffsetY
}, {
duration: 200,
easing: tween.easeOut
});
};
self.update = function () {
if (self.moving) {
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < self.speed) {
self.x = self.targetX;
self.y = self.targetY;
self.moving = false;
} else {
var angle = Math.atan2(dy, dx);
self.x += Math.cos(angle) * self.speed;
self.y += Math.sin(angle) * self.speed;
}
}
// Update weapon cooldown
self.weapon.update();
};
return self;
});
var TimerBar = Container.expand(function () {
var self = Container.call(this);
var background = self.attachAsset('timerBarBackground', {
anchorX: 0,
anchorY: 0.5,
alpha: 0.7 // Semi-transparent background
});
var bar = self.attachAsset('timerBar', {
anchorX: 0,
anchorY: 0.5
});
// Add clock icon
var clockIcon = LK.getAsset('collectableCube', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.8,
tint: 0xFFFFFF,
x: -50,
y: 0
});
self.addChild(clockIcon);
// Add timer text
var timerText = new Text2('30s', {
size: 40,
fill: 0xFFFFFF
});
timerText.anchor.set(0, 0.5);
timerText.x = background.width + 20;
timerText.y = 0;
self.addChild(timerText);
self.maxTime = 30000; // 30 seconds in milliseconds
self.timeRemaining = self.maxTime;
self.update = function (delta) {
self.timeRemaining -= delta;
if (self.timeRemaining < 0) {
self.timeRemaining = 0;
}
var percentage = self.timeRemaining / self.maxTime;
bar.scale.x = percentage;
// Update timer text
var secondsLeft = Math.ceil(self.timeRemaining / 1000);
timerText.setText(secondsLeft + 's');
// Change color as time runs out
if (percentage < 0.2) {
bar.tint = 0xe74c3c; // Red
clockIcon.tint = 0xe74c3c;
timerText.setText(secondsLeft + 's', {
fill: 0xe74c3c
});
// Pulse animation when low on time
if (Math.floor(self.timeRemaining / 200) % 2 === 0) {
clockIcon.scale.x = 0.9;
clockIcon.scale.y = 0.9;
} else {
clockIcon.scale.x = 0.8;
clockIcon.scale.y = 0.8;
}
} else if (percentage < 0.5) {
bar.tint = 0xf39c12; // Orange
clockIcon.tint = 0xf39c12;
timerText.setText(secondsLeft + 's', {
fill: 0xf39c12
});
} else {
bar.tint = 0x2ecc71; // Green
clockIcon.tint = 0x2ecc71;
timerText.setText(secondsLeft + 's', {
fill: 0x2ecc71
});
}
};
self.reset = function () {
self.timeRemaining = self.maxTime;
bar.scale.x = 1;
bar.tint = 0x2ecc71;
clockIcon.tint = 0x2ecc71;
timerText.setText(Math.ceil(self.timeRemaining / 1000) + 's', {
fill: 0x2ecc71
});
};
return self;
});
var Weapon = Container.expand(function () {
var self = Container.call(this);
var weaponGraphics = self.attachAsset('collectableCube', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.4,
scaleY: 0.15,
tint: 0xFFFFFF
});
self.type = 'basic';
self.level = 1;
self.attackSpeed = 1;
self.damage = 1;
self.cooldown = 0;
self.setWeaponType = function (type, level) {
self.type = type;
self.level = level || 1;
switch (type) {
case 'laser':
weaponGraphics.tint = 0xFF0000; // Red laser
self.attackSpeed = 1.5;
self.damage = 1;
break;
case 'plasma':
weaponGraphics.tint = 0x00FF00; // Green plasma
self.attackSpeed = 1;
self.damage = 2;
break;
case 'wave':
weaponGraphics.tint = 0x0000FF; // Blue wave
self.attackSpeed = 0.7;
self.damage = 3;
break;
case 'basic':
default:
weaponGraphics.tint = 0xFFFFFF; // White basic
self.attackSpeed = 1;
self.damage = 1;
break;
}
// Apply level multipliers
self.attackSpeed *= 1 + (self.level - 1) * 0.1;
self.damage *= self.level;
};
self.update = function () {
if (self.cooldown > 0) {
self.cooldown--;
}
};
self.canFire = function () {
return self.cooldown <= 0;
};
self.fire = function () {
// Set cooldown based on attack speed (higher attack speed = lower cooldown)
self.cooldown = Math.round(60 / self.attackSpeed);
return self.damage;
};
return self;
});
var WeaponEffect = Container.expand(function () {
var self = Container.call(this);
var effectGraphics = self.attachAsset('collectableCube', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.3,
scaleY: 0.3
});
self.type = 'basic';
self.damage = 1;
self.speed = 15;
self.lifetime = 60; // frames
self.setEffectType = function (type, damage) {
self.type = type;
self.damage = damage || 1;
switch (type) {
case 'laser':
effectGraphics.tint = 0xFF0000; // Red laser
effectGraphics.scaleX = 0.2;
effectGraphics.scaleY = 0.5;
self.speed = 20;
break;
case 'plasma':
effectGraphics.tint = 0x00FF00; // Green plasma
effectGraphics.scaleX = 0.4;
effectGraphics.scaleY = 0.4;
self.speed = 15;
break;
case 'wave':
effectGraphics.tint = 0x0000FF; // Blue wave
effectGraphics.scaleX = 0.6;
effectGraphics.scaleY = 0.3;
self.speed = 10;
break;
case 'basic':
default:
effectGraphics.tint = 0xFFFFFF; // White basic
effectGraphics.scaleX = 0.3;
effectGraphics.scaleY = 0.3;
self.speed = 15;
break;
}
// Pulse animation
tween(effectGraphics, {
alpha: 0.7
}, {
duration: 100,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(effectGraphics, {
alpha: 1
}, {
duration: 100,
easing: tween.easeInOut
});
}
});
};
self.update = function () {
// Move in direction of rotation
self.x += Math.cos(self.rotation) * self.speed;
self.y += Math.sin(self.rotation) * self.speed;
// Update lifetime
self.lifetime--;
// Add trailing effect
if (self.lifetime % 3 === 0) {
var trail = LK.getAsset('collectableCube', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: effectGraphics.scaleX * 0.7,
scaleY: effectGraphics.scaleY * 0.7,
alpha: 0.5,
tint: effectGraphics.tint,
x: 0,
y: 0
});
trail.x = self.x;
trail.y = self.y;
trail.parent = self.parent;
self.parent.addChild(trail);
tween(trail, {
alpha: 0,
scaleX: trail.scaleX * 0.5,
scaleY: trail.scaleY * 0.5
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
if (trail.parent) {
trail.parent.removeChild(trail);
}
}
});
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x8e44ad // Vibrant purple background
});
/****
* Game Code
****/
// Game constants
var GAME_WIDTH = 2048;
var GAME_HEIGHT = 2732;
var PLAYER_SPEED_BASE = 10;
var OBSTACLE_SPEED_BASE = 3;
var CUBE_SPAWN_INTERVAL_BASE = 1500; // ms
var OBSTACLE_SPAWN_INTERVAL = 5000; // ms
var LEVEL_UP_SCORE = 100;
var TIME_BONUS_MAX = 50;
var TIME_BONUS_THRESHOLD = 1000; // ms
var WEAPON_UPGRADE_SCORE = 100; // Score needed for weapon upgrades
// Cube type probabilities
var CUBE_TYPES = {
normal: {
chance: 70,
value: 10
},
silver: {
chance: 20,
value: 20
},
gold: {
chance: 10,
value: 30
}
};
// Weapon types by level
var WEAPON_UPGRADES = [{
level: 1,
type: 'basic',
name: 'Basic Blaster'
}, {
level: 2,
type: 'laser',
name: 'Laser Beam'
}, {
level: 3,
type: 'plasma',
name: 'Plasma Cannon'
}, {
level: 4,
type: 'wave',
name: 'Wave Disruptor'
}];
// Game variables
var player;
var collectableCubes = [];
var obstacles = [];
var weaponEffects = [];
var timerBar;
var score = 0;
var level = 1;
var weaponLevel = 1;
var lastCubeSpawnTime = 0;
var lastObstacleSpawnTime = 0;
var lastWeaponFireTime = 0;
var cubeSpawnInterval = CUBE_SPAWN_INTERVAL_BASE;
var playerSpeed = PLAYER_SPEED_BASE;
var obstacleSpeed = OBSTACLE_SPEED_BASE;
var lastTime = Date.now();
var gameActive = true;
var highScore = storage.highScore || 0;
var nextWeaponUpgrade = WEAPON_UPGRADE_SCORE;
// UI Elements
var scoreTxt = new Text2('Score: 0', {
size: 70,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0, 0);
LK.gui.topRight.addChild(scoreTxt);
scoreTxt.x = -scoreTxt.width - 20;
scoreTxt.y = 20;
var levelTxt = new Text2('Level: 1', {
size: 70,
fill: 0xFFFFFF
});
levelTxt.anchor.set(0, 0);
LK.gui.topRight.addChild(levelTxt);
levelTxt.x = -levelTxt.width - 20;
levelTxt.y = scoreTxt.y + scoreTxt.height + 10;
var highScoreTxt = new Text2('High Score: ' + highScore, {
size: 70,
fill: 0xFFFFFF
});
highScoreTxt.anchor.set(0, 0);
LK.gui.topRight.addChild(highScoreTxt);
highScoreTxt.x = -highScoreTxt.width - 20;
highScoreTxt.y = levelTxt.y + levelTxt.height + 10;
// Initialize game elements
function initGame() {
// Create colorful background patterns
createBackgroundPatterns();
// Create and position player
player = new Player();
player.x = GAME_WIDTH / 2;
player.y = GAME_HEIGHT / 2;
player.speed = playerSpeed;
game.addChild(player);
// Add a welcome animation
tween(player, {
scaleX: 0,
scaleY: 0
}, {
duration: 0
});
tween(player, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 500,
easing: tween.elasticOut,
onFinish: function onFinish() {
tween(player, {
scaleX: 1,
scaleY: 1
}, {
duration: 300,
easing: tween.easeOut
});
}
});
// Create timer bar
timerBar = new TimerBar();
timerBar.x = (GAME_WIDTH - 1800) / 2;
timerBar.y = 100;
game.addChild(timerBar);
// Start with a few cubes and obstacles
spawnCollectableCube();
spawnObstacle();
// Play background music
LK.playMusic('gameMusic');
}
function createBackgroundPatterns() {
// Create some decorative background elements
for (var i = 0; i < 20; i++) {
var decoration = LK.getAsset('collectableCube', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.3 + Math.random() * 0.3,
scaleY: 0.3 + Math.random() * 0.3,
alpha: 0.15,
tint: Math.random() * 0xFFFFFF,
x: Math.random() * GAME_WIDTH,
y: Math.random() * GAME_HEIGHT
});
// Place decorations behind game elements
game.addChildAt(decoration, 0);
// Add subtle animation to background elements
var animDuration = 3000 + Math.random() * 5000;
tween(decoration, {
rotation: Math.random() * Math.PI * 2
}, {
duration: animDuration,
easing: tween.easeInOut
});
}
}
function updateGame() {
if (!gameActive) {
return;
}
var currentTime = Date.now();
var delta = currentTime - lastTime;
lastTime = currentTime;
// Update timer
timerBar.update(delta);
if (timerBar.timeRemaining <= 0) {
gameOver();
return;
}
// Spawn new cubes
if (currentTime - lastCubeSpawnTime > cubeSpawnInterval) {
spawnCollectableCube();
lastCubeSpawnTime = currentTime;
}
// Spawn new obstacles
if (currentTime - lastObstacleSpawnTime > OBSTACLE_SPAWN_INTERVAL) {
spawnObstacle();
lastObstacleSpawnTime = currentTime;
}
// Fire weapon automatically
if (currentTime - lastWeaponFireTime > 1000) {
if (player.fireWeapon(obstacles, game, weaponEffects)) {
lastWeaponFireTime = currentTime;
}
}
// Update weapon effects
for (var i = weaponEffects.length - 1; i >= 0; i--) {
var effect = weaponEffects[i];
// Update effect
effect.update();
// Check if effect is expired
if (effect.lifetime <= 0) {
game.removeChild(effect);
weaponEffects.splice(i, 1);
continue;
}
// Check for collisions with obstacles
for (var j = 0; j < obstacles.length; j++) {
var obstacle = obstacles[j];
if (effect.intersects(obstacle)) {
// Hit effect
var hitEffect = LK.getAsset('collectableCube', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.5,
scaleY: 0.5,
tint: effect.tint,
alpha: 0.8,
x: effect.x,
y: effect.y
});
game.addChild(hitEffect);
// Animate hit effect
tween(hitEffect, {
scaleX: 1.5,
scaleY: 1.5,
alpha: 0
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
game.removeChild(hitEffect);
}
});
// Remove effect
game.removeChild(effect);
weaponEffects.splice(i, 1);
// Destroy obstacle
game.removeChild(obstacle);
obstacles.splice(j, 1);
// Add score for destroying obstacle
addScore(5 * weaponLevel);
break;
}
}
}
// Check for collisions
checkCollisions();
}
function spawnCollectableCube() {
var cube = new CollectableCube();
// Determine cube type based on probabilities and level
var rand = Math.random() * 100;
var cubeType = 'normal';
// Adjust probabilities based on level (higher levels get better cubes)
var silverChance = CUBE_TYPES.silver.chance + level * 1.5;
var goldChance = CUBE_TYPES.gold.chance + level * 1;
if (rand < goldChance) {
cubeType = 'gold';
} else if (rand < goldChance + silverChance) {
cubeType = 'silver';
}
// Set the cube type
cube.setCubeType(cubeType);
cube.randomPosition(100, GAME_WIDTH - 100, 200, GAME_HEIGHT - 200);
// Make sure cube doesn't spawn on obstacles
var validPosition = false;
var maxAttempts = 10;
var attempts = 0;
while (!validPosition && attempts < maxAttempts) {
validPosition = true;
for (var i = 0; i < obstacles.length; i++) {
var obstacle = obstacles[i];
var dx = cube.x - obstacle.x;
var dy = cube.y - obstacle.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 150) {
validPosition = false;
cube.randomPosition(100, GAME_WIDTH - 100, 200, GAME_HEIGHT - 200);
break;
}
}
attempts++;
}
collectableCubes.push(cube);
game.addChild(cube);
// Animate cube entrance
cube.scale.x = 0;
cube.scale.y = 0;
tween(cube, {
scaleX: 1,
scaleY: 1
}, {
duration: 300,
easing: tween.elasticOut
});
}
function spawnObstacle() {
var obstacle = new Obstacle();
obstacle.randomPosition(100, GAME_WIDTH - 100, 200, GAME_HEIGHT - 200);
obstacle.setRandomSpeed(obstacleSpeed);
// Make sure obstacle doesn't spawn on player
var dx = obstacle.x - player.x;
var dy = obstacle.y - player.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 200) {
obstacle.x = GAME_WIDTH - obstacle.x;
obstacle.y = GAME_HEIGHT - obstacle.y;
}
obstacles.push(obstacle);
game.addChild(obstacle);
}
function checkCollisions() {
// Check collisions with collectables
for (var i = collectableCubes.length - 1; i >= 0; i--) {
var cube = collectableCubes[i];
if (player.intersects(cube)) {
// Calculate time bonus
var collectionTime = Date.now() - cube.spawnTime;
var timeBonus = 0;
if (collectionTime < TIME_BONUS_THRESHOLD) {
timeBonus = Math.round(TIME_BONUS_MAX * (1 - collectionTime / TIME_BONUS_THRESHOLD));
}
// Add score and remove cube
addScore(cube.value + timeBonus);
game.removeChild(cube);
collectableCubes.splice(i, 1);
// Play collect sound
LK.getSound('collect').play();
// Check for level up
checkLevelUp();
}
}
// Check collisions with obstacles
for (var j = 0; j < obstacles.length; j++) {
var obstacle = obstacles[j];
if (player.intersects(obstacle)) {
// Player hit an obstacle
LK.getSound('collision').play();
LK.effects.flashScreen(0xe74c3c, 300);
// Reduce timer as penalty
timerBar.timeRemaining -= 3000; // 3 second penalty
// Push player away from obstacle
var dx = player.x - obstacle.x;
var dy = player.y - obstacle.y;
var angle = Math.atan2(dy, dx);
player.x += Math.cos(angle) * 100;
player.y += Math.sin(angle) * 100;
// Keep player within bounds
player.x = Math.max(40, Math.min(GAME_WIDTH - 40, player.x));
player.y = Math.max(40, Math.min(GAME_HEIGHT - 40, player.y));
}
}
}
function addScore(points) {
score += points;
scoreTxt.setText('Score: ' + score);
// Update player's score display
if (player && player.updateScore) {
player.updateScore(score);
}
// Create floating points animation
var floatingPoints = new Text2("+" + points, {
size: 60,
fill: 0x00ff00
});
floatingPoints.anchor.set(0.5, 0.5);
floatingPoints.x = player.x;
floatingPoints.y = player.y - 100;
game.addChild(floatingPoints);
// Animate the floating points
tween(floatingPoints, {
y: floatingPoints.y - 150,
alpha: 0
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
game.removeChild(floatingPoints);
}
});
// Flash score text
tween(scoreTxt, {
scale: 1.2
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(scoreTxt, {
scale: 1
}, {
duration: 200,
easing: tween.easeIn
});
}
});
}
function checkLevelUp() {
// Check for weapon upgrades first
if (score >= nextWeaponUpgrade) {
// Find next weapon upgrade
var upgrade = null;
for (var i = 0; i < WEAPON_UPGRADES.length; i++) {
if (WEAPON_UPGRADES[i].level > weaponLevel) {
upgrade = WEAPON_UPGRADES[i];
break;
}
}
if (upgrade) {
weaponLevel = upgrade.level;
nextWeaponUpgrade += WEAPON_UPGRADE_SCORE * weaponLevel;
// Update player's weapon
player.updateWeapon(upgrade.type, weaponLevel);
// Show weapon upgrade notification
var upgradeText = new Text2("New Weapon: " + upgrade.name + "!", {
size: 80,
fill: 0xFFD700
});
upgradeText.anchor.set(0.5, 0.5);
upgradeText.x = GAME_WIDTH / 2;
upgradeText.y = GAME_HEIGHT / 2 - 200;
game.addChild(upgradeText);
// Animate the notification
tween(upgradeText, {
y: upgradeText.y - 100,
alpha: 0
}, {
duration: 2000,
easing: tween.easeOut,
onFinish: function onFinish() {
game.removeChild(upgradeText);
}
});
// Visual effect for weapon upgrade
LK.effects.flashScreen(0x00FFFF, 500);
}
}
// Regular level up check
if (score >= level * LEVEL_UP_SCORE) {
level++;
levelTxt.setText('Level: ' + level);
// Increase difficulty
cubeSpawnInterval = Math.max(500, CUBE_SPAWN_INTERVAL_BASE - (level - 1) * 150);
playerSpeed = PLAYER_SPEED_BASE + (level - 1) * 1;
obstacleSpeed = OBSTACLE_SPEED_BASE + (level - 1) * 0.5;
// Update player speed
player.speed = playerSpeed;
// Update obstacle speeds
for (var i = 0; i < obstacles.length; i++) {
obstacles[i].setRandomSpeed(obstacleSpeed);
}
// Visual feedback for level up
LK.effects.flashScreen(0x2ecc71, 500);
// Add time bonus for leveling up
timerBar.timeRemaining += 5000; // 5 second bonus
if (timerBar.timeRemaining > timerBar.maxTime) {
timerBar.timeRemaining = timerBar.maxTime;
}
// Flash level text
tween(levelTxt, {
scale: 1.3
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(levelTxt, {
scale: 1
}, {
duration: 300,
easing: tween.easeIn
});
}
});
}
}
function gameOver() {
gameActive = false;
// Update high score
if (score > highScore) {
highScore = score;
storage.highScore = highScore;
highScoreTxt.setText('High Score: ' + highScore);
}
// Show game over
LK.showGameOver();
}
function resetGame() {
// Reset game variables
score = 0;
level = 1;
weaponLevel = 1;
nextWeaponUpgrade = WEAPON_UPGRADE_SCORE;
cubeSpawnInterval = CUBE_SPAWN_INTERVAL_BASE;
playerSpeed = PLAYER_SPEED_BASE;
obstacleSpeed = OBSTACLE_SPEED_BASE;
lastTime = Date.now();
lastCubeSpawnTime = 0;
lastObstacleSpawnTime = 0;
lastWeaponFireTime = 0;
gameActive = true;
// Clear all game elements
while (collectableCubes.length > 0) {
var cube = collectableCubes.pop();
game.removeChild(cube);
}
while (obstacles.length > 0) {
var obstacle = obstacles.pop();
game.removeChild(obstacle);
}
while (weaponEffects.length > 0) {
var effect = weaponEffects.pop();
game.removeChild(effect);
}
if (player) {
game.removeChild(player);
}
if (timerBar) {
game.removeChild(timerBar);
}
// Reset UI
scoreTxt.setText('Score: 0');
levelTxt.setText('Level: 1');
highScoreTxt.setText('High Score: ' + highScore);
// Initialize game again
initGame();
}
// Event handlers
game.down = function (x, y, obj) {
if (gameActive) {
player.setTarget(x, y);
}
};
game.move = function (x, y, obj) {
if (gameActive && obj.down) {
player.setTarget(x, y);
}
};
game.update = function () {
updateGame();
// Update player
if (player) {
player.update();
}
// Update obstacles
for (var i = 0; i < obstacles.length; i++) {
obstacles[i].update();
}
// Update weapon effects
for (var i = 0; i < weaponEffects.length; i++) {
if (weaponEffects[i].update) {
weaponEffects[i].update();
}
}
};
// Initialize the game
initGame(); ===================================================================
--- original.js
+++ change.js
@@ -57,8 +57,9 @@
pointsTxt.anchor.set(0.5, 0.5);
pointsTxt.y = -40;
self.addChild(pointsTxt);
self.value = 10;
+ self.cubeType = 'normal';
self.spawnTime = 0;
self.pulseAnimation = function () {
tween(cubeGraphics, {
scaleX: 1.2,
@@ -81,11 +82,44 @@
self.x = minX + Math.random() * (maxX - minX);
self.y = minY + Math.random() * (maxY - minY);
self.spawnTime = Date.now();
self.pulseAnimation();
- // Random cube color for variety
- cubeGraphics.tint = Math.random() * 0xFFFFFF;
};
+ self.setCubeType = function (type) {
+ self.cubeType = type;
+ switch (type) {
+ case 'silver':
+ self.value = 20;
+ pointsTxt.setText('+20');
+ cubeGraphics.tint = 0xC0C0C0; // Silver
+ break;
+ case 'gold':
+ self.value = 30;
+ pointsTxt.setText('+30');
+ cubeGraphics.tint = 0xFFD700; // Gold
+ break;
+ case 'normal':
+ default:
+ self.value = 10;
+ pointsTxt.setText('+10');
+ cubeGraphics.tint = 0x00FFFF; // Cyan
+ break;
+ }
+ // Update the facial expression based on cube type
+ if (type === 'gold') {
+ // Happy expression for gold cubes
+ mouth.scaleY = 0.2;
+ mouth.y = 10;
+ } else if (type === 'silver') {
+ // Neutral expression for silver cubes
+ mouth.scaleY = 0.15;
+ mouth.y = 15;
+ } else {
+ // Normal expression
+ mouth.scaleY = 0.15;
+ mouth.y = 15;
+ }
+ };
return self;
});
var Obstacle = Container.expand(function () {
var self = Container.call(this);
@@ -265,11 +299,93 @@
});
playerScoreTxt.anchor.set(0.5, 0.5);
playerScoreTxt.y = -60;
self.addChild(playerScoreTxt);
+ // Add weapon display
+ var weaponHolder = new Container();
+ self.addChild(weaponHolder);
+ weaponHolder.y = 50;
+ // Current weapon
+ self.weapon = new Weapon();
+ self.weapon.setWeaponType('basic', 1);
+ weaponHolder.addChild(self.weapon);
+ // Level indicators
+ var levelIndicator = new Text2('Lv.1', {
+ size: 24,
+ fill: 0xFFFFFF
+ });
+ levelIndicator.anchor.set(0.5, 0.5);
+ levelIndicator.y = 25;
+ weaponHolder.addChild(levelIndicator);
self.updateScore = function (newScore) {
playerScoreTxt.setText(newScore);
};
+ self.updateWeapon = function (type, level) {
+ self.weapon.setWeaponType(type, level);
+ levelIndicator.setText('Lv.' + level);
+ // Flash weapon effect
+ tween(weaponHolder, {
+ scaleX: 1.3,
+ scaleY: 1.3
+ }, {
+ duration: 300,
+ easing: tween.elasticOut,
+ onFinish: function onFinish() {
+ tween(weaponHolder, {
+ scaleX: 1,
+ scaleY: 1
+ }, {
+ duration: 200,
+ easing: tween.easeOut
+ });
+ }
+ });
+ };
+ self.fireWeapon = function (targets, game, weaponEffects) {
+ if (self.weapon.canFire()) {
+ // Get weapon stats
+ var damage = self.weapon.fire();
+ var type = self.weapon.type;
+ // Create weapon effect
+ var effect = new WeaponEffect();
+ effect.setEffectType(type, damage);
+ // Position at player
+ effect.x = self.x;
+ effect.y = self.y;
+ // If we have targets, aim at the nearest one
+ var nearestTarget = null;
+ var minDistance = Number.MAX_VALUE;
+ for (var i = 0; i < targets.length; i++) {
+ var target = targets[i];
+ var dx = target.x - self.x;
+ var dy = target.y - self.y;
+ var distance = Math.sqrt(dx * dx + dy * dy);
+ if (distance < minDistance) {
+ minDistance = distance;
+ nearestTarget = target;
+ }
+ }
+ if (nearestTarget) {
+ var angle = Math.atan2(nearestTarget.y - self.y, nearestTarget.x - self.x);
+ effect.rotation = angle;
+ } else {
+ // If no targets, fire forward
+ effect.rotation = 0;
+ }
+ game.addChild(effect);
+ weaponEffects.push(effect);
+ // Flash the weapon
+ self.weapon.alpha = 0.7;
+ tween(self.weapon, {
+ alpha: 1
+ }, {
+ duration: 200,
+ easing: tween.easeOut
+ });
+ return true;
+ }
+ return false;
+ };
self.speed = 10;
self.targetX = 0;
self.targetY = 0;
self.moving = false;
@@ -310,8 +426,10 @@
self.x += Math.cos(angle) * self.speed;
self.y += Math.sin(angle) * self.speed;
}
}
+ // Update weapon cooldown
+ self.weapon.update();
};
return self;
});
var TimerBar = Container.expand(function () {
@@ -396,8 +514,164 @@
});
};
return self;
});
+var Weapon = Container.expand(function () {
+ var self = Container.call(this);
+ var weaponGraphics = self.attachAsset('collectableCube', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 0.4,
+ scaleY: 0.15,
+ tint: 0xFFFFFF
+ });
+ self.type = 'basic';
+ self.level = 1;
+ self.attackSpeed = 1;
+ self.damage = 1;
+ self.cooldown = 0;
+ self.setWeaponType = function (type, level) {
+ self.type = type;
+ self.level = level || 1;
+ switch (type) {
+ case 'laser':
+ weaponGraphics.tint = 0xFF0000; // Red laser
+ self.attackSpeed = 1.5;
+ self.damage = 1;
+ break;
+ case 'plasma':
+ weaponGraphics.tint = 0x00FF00; // Green plasma
+ self.attackSpeed = 1;
+ self.damage = 2;
+ break;
+ case 'wave':
+ weaponGraphics.tint = 0x0000FF; // Blue wave
+ self.attackSpeed = 0.7;
+ self.damage = 3;
+ break;
+ case 'basic':
+ default:
+ weaponGraphics.tint = 0xFFFFFF; // White basic
+ self.attackSpeed = 1;
+ self.damage = 1;
+ break;
+ }
+ // Apply level multipliers
+ self.attackSpeed *= 1 + (self.level - 1) * 0.1;
+ self.damage *= self.level;
+ };
+ self.update = function () {
+ if (self.cooldown > 0) {
+ self.cooldown--;
+ }
+ };
+ self.canFire = function () {
+ return self.cooldown <= 0;
+ };
+ self.fire = function () {
+ // Set cooldown based on attack speed (higher attack speed = lower cooldown)
+ self.cooldown = Math.round(60 / self.attackSpeed);
+ return self.damage;
+ };
+ return self;
+});
+var WeaponEffect = Container.expand(function () {
+ var self = Container.call(this);
+ var effectGraphics = self.attachAsset('collectableCube', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 0.3,
+ scaleY: 0.3
+ });
+ self.type = 'basic';
+ self.damage = 1;
+ self.speed = 15;
+ self.lifetime = 60; // frames
+ self.setEffectType = function (type, damage) {
+ self.type = type;
+ self.damage = damage || 1;
+ switch (type) {
+ case 'laser':
+ effectGraphics.tint = 0xFF0000; // Red laser
+ effectGraphics.scaleX = 0.2;
+ effectGraphics.scaleY = 0.5;
+ self.speed = 20;
+ break;
+ case 'plasma':
+ effectGraphics.tint = 0x00FF00; // Green plasma
+ effectGraphics.scaleX = 0.4;
+ effectGraphics.scaleY = 0.4;
+ self.speed = 15;
+ break;
+ case 'wave':
+ effectGraphics.tint = 0x0000FF; // Blue wave
+ effectGraphics.scaleX = 0.6;
+ effectGraphics.scaleY = 0.3;
+ self.speed = 10;
+ break;
+ case 'basic':
+ default:
+ effectGraphics.tint = 0xFFFFFF; // White basic
+ effectGraphics.scaleX = 0.3;
+ effectGraphics.scaleY = 0.3;
+ self.speed = 15;
+ break;
+ }
+ // Pulse animation
+ tween(effectGraphics, {
+ alpha: 0.7
+ }, {
+ duration: 100,
+ easing: tween.easeInOut,
+ onFinish: function onFinish() {
+ tween(effectGraphics, {
+ alpha: 1
+ }, {
+ duration: 100,
+ easing: tween.easeInOut
+ });
+ }
+ });
+ };
+ self.update = function () {
+ // Move in direction of rotation
+ self.x += Math.cos(self.rotation) * self.speed;
+ self.y += Math.sin(self.rotation) * self.speed;
+ // Update lifetime
+ self.lifetime--;
+ // Add trailing effect
+ if (self.lifetime % 3 === 0) {
+ var trail = LK.getAsset('collectableCube', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: effectGraphics.scaleX * 0.7,
+ scaleY: effectGraphics.scaleY * 0.7,
+ alpha: 0.5,
+ tint: effectGraphics.tint,
+ x: 0,
+ y: 0
+ });
+ trail.x = self.x;
+ trail.y = self.y;
+ trail.parent = self.parent;
+ self.parent.addChild(trail);
+ tween(trail, {
+ alpha: 0,
+ scaleX: trail.scaleX * 0.5,
+ scaleY: trail.scaleY * 0.5
+ }, {
+ duration: 300,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ if (trail.parent) {
+ trail.parent.removeChild(trail);
+ }
+ }
+ });
+ }
+ };
+ return self;
+});
/****
* Initialize Game
****/
@@ -417,23 +691,61 @@
var OBSTACLE_SPAWN_INTERVAL = 5000; // ms
var LEVEL_UP_SCORE = 100;
var TIME_BONUS_MAX = 50;
var TIME_BONUS_THRESHOLD = 1000; // ms
+var WEAPON_UPGRADE_SCORE = 100; // Score needed for weapon upgrades
+// Cube type probabilities
+var CUBE_TYPES = {
+ normal: {
+ chance: 70,
+ value: 10
+ },
+ silver: {
+ chance: 20,
+ value: 20
+ },
+ gold: {
+ chance: 10,
+ value: 30
+ }
+};
+// Weapon types by level
+var WEAPON_UPGRADES = [{
+ level: 1,
+ type: 'basic',
+ name: 'Basic Blaster'
+}, {
+ level: 2,
+ type: 'laser',
+ name: 'Laser Beam'
+}, {
+ level: 3,
+ type: 'plasma',
+ name: 'Plasma Cannon'
+}, {
+ level: 4,
+ type: 'wave',
+ name: 'Wave Disruptor'
+}];
// Game variables
var player;
var collectableCubes = [];
var obstacles = [];
+var weaponEffects = [];
var timerBar;
var score = 0;
var level = 1;
+var weaponLevel = 1;
var lastCubeSpawnTime = 0;
var lastObstacleSpawnTime = 0;
+var lastWeaponFireTime = 0;
var cubeSpawnInterval = CUBE_SPAWN_INTERVAL_BASE;
var playerSpeed = PLAYER_SPEED_BASE;
var obstacleSpeed = OBSTACLE_SPEED_BASE;
var lastTime = Date.now();
var gameActive = true;
var highScore = storage.highScore || 0;
+var nextWeaponUpgrade = WEAPON_UPGRADE_SCORE;
// UI Elements
var scoreTxt = new Text2('Score: 0', {
size: 70,
fill: 0xFFFFFF
@@ -549,13 +861,83 @@
if (currentTime - lastObstacleSpawnTime > OBSTACLE_SPAWN_INTERVAL) {
spawnObstacle();
lastObstacleSpawnTime = currentTime;
}
+ // Fire weapon automatically
+ if (currentTime - lastWeaponFireTime > 1000) {
+ if (player.fireWeapon(obstacles, game, weaponEffects)) {
+ lastWeaponFireTime = currentTime;
+ }
+ }
+ // Update weapon effects
+ for (var i = weaponEffects.length - 1; i >= 0; i--) {
+ var effect = weaponEffects[i];
+ // Update effect
+ effect.update();
+ // Check if effect is expired
+ if (effect.lifetime <= 0) {
+ game.removeChild(effect);
+ weaponEffects.splice(i, 1);
+ continue;
+ }
+ // Check for collisions with obstacles
+ for (var j = 0; j < obstacles.length; j++) {
+ var obstacle = obstacles[j];
+ if (effect.intersects(obstacle)) {
+ // Hit effect
+ var hitEffect = LK.getAsset('collectableCube', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 0.5,
+ scaleY: 0.5,
+ tint: effect.tint,
+ alpha: 0.8,
+ x: effect.x,
+ y: effect.y
+ });
+ game.addChild(hitEffect);
+ // Animate hit effect
+ tween(hitEffect, {
+ scaleX: 1.5,
+ scaleY: 1.5,
+ alpha: 0
+ }, {
+ duration: 300,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ game.removeChild(hitEffect);
+ }
+ });
+ // Remove effect
+ game.removeChild(effect);
+ weaponEffects.splice(i, 1);
+ // Destroy obstacle
+ game.removeChild(obstacle);
+ obstacles.splice(j, 1);
+ // Add score for destroying obstacle
+ addScore(5 * weaponLevel);
+ break;
+ }
+ }
+ }
// Check for collisions
checkCollisions();
}
function spawnCollectableCube() {
var cube = new CollectableCube();
+ // Determine cube type based on probabilities and level
+ var rand = Math.random() * 100;
+ var cubeType = 'normal';
+ // Adjust probabilities based on level (higher levels get better cubes)
+ var silverChance = CUBE_TYPES.silver.chance + level * 1.5;
+ var goldChance = CUBE_TYPES.gold.chance + level * 1;
+ if (rand < goldChance) {
+ cubeType = 'gold';
+ } else if (rand < goldChance + silverChance) {
+ cubeType = 'silver';
+ }
+ // Set the cube type
+ cube.setCubeType(cubeType);
cube.randomPosition(100, GAME_WIDTH - 100, 200, GAME_HEIGHT - 200);
// Make sure cube doesn't spawn on obstacles
var validPosition = false;
var maxAttempts = 10;
@@ -576,8 +958,18 @@
attempts++;
}
collectableCubes.push(cube);
game.addChild(cube);
+ // Animate cube entrance
+ cube.scale.x = 0;
+ cube.scale.y = 0;
+ tween(cube, {
+ scaleX: 1,
+ scaleY: 1
+ }, {
+ duration: 300,
+ easing: tween.elasticOut
+ });
}
function spawnObstacle() {
var obstacle = new Obstacle();
obstacle.randomPosition(100, GAME_WIDTH - 100, 200, GAME_HEIGHT - 200);
@@ -678,8 +1070,48 @@
}
});
}
function checkLevelUp() {
+ // Check for weapon upgrades first
+ if (score >= nextWeaponUpgrade) {
+ // Find next weapon upgrade
+ var upgrade = null;
+ for (var i = 0; i < WEAPON_UPGRADES.length; i++) {
+ if (WEAPON_UPGRADES[i].level > weaponLevel) {
+ upgrade = WEAPON_UPGRADES[i];
+ break;
+ }
+ }
+ if (upgrade) {
+ weaponLevel = upgrade.level;
+ nextWeaponUpgrade += WEAPON_UPGRADE_SCORE * weaponLevel;
+ // Update player's weapon
+ player.updateWeapon(upgrade.type, weaponLevel);
+ // Show weapon upgrade notification
+ var upgradeText = new Text2("New Weapon: " + upgrade.name + "!", {
+ size: 80,
+ fill: 0xFFD700
+ });
+ upgradeText.anchor.set(0.5, 0.5);
+ upgradeText.x = GAME_WIDTH / 2;
+ upgradeText.y = GAME_HEIGHT / 2 - 200;
+ game.addChild(upgradeText);
+ // Animate the notification
+ tween(upgradeText, {
+ y: upgradeText.y - 100,
+ alpha: 0
+ }, {
+ duration: 2000,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ game.removeChild(upgradeText);
+ }
+ });
+ // Visual effect for weapon upgrade
+ LK.effects.flashScreen(0x00FFFF, 500);
+ }
+ }
+ // Regular level up check
if (score >= level * LEVEL_UP_SCORE) {
level++;
levelTxt.setText('Level: ' + level);
// Increase difficulty
@@ -730,14 +1162,17 @@
function resetGame() {
// Reset game variables
score = 0;
level = 1;
+ weaponLevel = 1;
+ nextWeaponUpgrade = WEAPON_UPGRADE_SCORE;
cubeSpawnInterval = CUBE_SPAWN_INTERVAL_BASE;
playerSpeed = PLAYER_SPEED_BASE;
obstacleSpeed = OBSTACLE_SPEED_BASE;
lastTime = Date.now();
lastCubeSpawnTime = 0;
lastObstacleSpawnTime = 0;
+ lastWeaponFireTime = 0;
gameActive = true;
// Clear all game elements
while (collectableCubes.length > 0) {
var cube = collectableCubes.pop();
@@ -746,8 +1181,12 @@
while (obstacles.length > 0) {
var obstacle = obstacles.pop();
game.removeChild(obstacle);
}
+ while (weaponEffects.length > 0) {
+ var effect = weaponEffects.pop();
+ game.removeChild(effect);
+ }
if (player) {
game.removeChild(player);
}
if (timerBar) {
@@ -780,7 +1219,13 @@
// Update obstacles
for (var i = 0; i < obstacles.length; i++) {
obstacles[i].update();
}
+ // Update weapon effects
+ for (var i = 0; i < weaponEffects.length; i++) {
+ if (weaponEffects[i].update) {
+ weaponEffects[i].update();
+ }
+ }
};
// Initialize the game
initGame();
\ No newline at end of file