Code edit (3 edits merged)
Please save this source code
Code edit (1 edits merged)
Please save this source code
User prompt
Ok mach bitte
User prompt
Please fix the bug: 'Timeout.tick error: target is not an Object. (evaluating 'key in target')' in or related to this line: 'tween(echo.scale, {' Line Number: 483 ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Also improve the Intro screen
User prompt
Please fix the bug: 'Error: Error: Invalid color format. Expected 0xRRGGBB format, received: undefined' in or related to this line: 'backgroundTween = tween(game, {' Line Number: 947
User prompt
Please fix the bug: 'Error: Error: Invalid color format. Expected 0xRRGGBB format, received: undefined' in or related to this line: 'backgroundTween = tween(game, {' Line Number: 947
User prompt
Please fix the bug: 'Error: Error: Invalid color format. Expected 0xRRGGBB format, received: undefined' in or related to this line: 'backgroundTween = tween(game, tweenTarget, {' Line Number: 945
User prompt
Please fix the bug: 'Error: Error: Invalid color format. Expected 0xRRGGBB format, received: undefined' in or related to this line: 'backgroundTween = tween(game, tweenTarget, {' Line Number: 943
User prompt
Please fix the bug: 'Error: Error: Invalid color format. Expected 0xRRGGBB format, received: undefined' in or related to this line: 'backgroundTween = tween(game, {' Line Number: 939 ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Please fix the bug: 'Error: Error: Invalid color format. Expected 0xRRGGBB format, received: undefined' in or related to this line: 'backgroundTween = tween(game, {' Line Number: 937
User prompt
Please fix the bug: 'Error: Error: Invalid color format. Expected 0xRRGGBB format, received: undefined' in or related to this line: 'backgroundTween = tween(game, {' Line Number: 935
User prompt
Please fix the bug: 'Error: Error: Invalid color format. Expected 0xRRGGBB format, received: undefined' in or related to this line: 'backgroundTween = tween(game, {' Line Number: 933
User prompt
Make the Game more psychedelic
User prompt
Make the Game faster from time to time
User prompt
Please fix the bug: 'TypeError: target is not an Object. (evaluating 'key in target')' in or related to this line: 'tween(sampleBird.scale, {' Line Number: 263 ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Please fix the bug: 'Timeout.tick error: sampleBird.scale.set is not a function. (In 'sampleBird.scale.set(0)', 'sampleBird.scale.set' is undefined)' in or related to this line: 'sampleBird.scale.set(0);' Line Number: 253
User prompt
Ok can you Make the start screen custom and Add an cool Intro animation
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// BackgroundPatterns class to create psychedelic moving patterns
var BackgroundPatterns = Container.expand(function () {
var self = Container.call(this);
// Pattern elements
var patterns = [];
var patternCount = 15;
// Initialize patterns
self.init = function () {
// Create various geometric shapes
for (var i = 0; i < patternCount; i++) {
var pattern = LK.getAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.2 + Math.random() * 0.1,
rotation: Math.random() * Math.PI * 2,
scale: 0.2 + Math.random() * 0.3
});
// Randomize starting positions
pattern.x = Math.random() * 2048;
pattern.y = Math.random() * 2732;
// Set movement parameters
pattern.speedX = (Math.random() - 0.5) * 2;
pattern.speedY = (Math.random() - 0.5) * 2;
pattern.rotSpeed = (Math.random() - 0.5) * 0.05;
pattern.pulseSpeed = 0.02 + Math.random() * 0.03;
pattern.pulsePhase = Math.random() * Math.PI * 2;
patterns.push(pattern);
self.addChild(pattern);
}
};
// Update method for movement and effects
self.update = function () {
for (var i = 0; i < patterns.length; i++) {
var pattern = patterns[i];
// Move pattern
pattern.x += pattern.speedX;
pattern.y += pattern.speedY;
// Rotate pattern
pattern.rotation += pattern.rotSpeed;
// Pulse size
pattern.pulsePhase += pattern.pulseSpeed;
pattern.scale.x = pattern.scale.y = 0.2 + Math.sin(pattern.pulsePhase) * 0.15;
// Cycle colors
pattern.tint = Math.random() * 0xFFFFFF;
// Wrap around screen edges
if (pattern.x < -100) {
pattern.x = 2148;
}
if (pattern.x > 2148) {
pattern.x = -100;
}
if (pattern.y < -100) {
pattern.y = 2832;
}
if (pattern.y > 2832) {
pattern.y = -100;
}
}
};
return self;
});
// Bird class representing the player character
var Bird = Container.expand(function () {
var self = Container.call(this);
// Constants for physics
var GRAVITY = 1.0; // Reduced gravity for easier play
var FLAP_STRENGTH = -20; // Reduced flap strength for smoother control
var MAX_ROTATION = Math.PI / 4; // Max tilt angle (45 degrees)
var MIN_ROTATION = -Math.PI / 6; // Min tilt angle (-30 degrees)
// Bird's vertical velocity
self.velocityY = 0;
// Attach the bird graphic asset
var birdGraphics = self.attachAsset('bird', {
anchorX: 0.5,
anchorY: 0.5
});
// Public method for flapping
self.flap = function () {
self.velocityY = FLAP_STRENGTH;
LK.getSound('flapSound').play(); // Play flap sound
// Optional: Add a quick visual feedback tween on flap
tween.stop(birdGraphics); // Stop previous scale tweens
birdGraphics.scale.set(1.1, 1.1);
tween(birdGraphics.scale, {
x: 1,
y: 1
}, {
duration: 100
});
};
// Flag to track if player is holding down
self.isHolding = false;
// Method to set holding state
self.setHolding = function (holding) {
self.isHolding = holding;
};
// Update method called every frame by the engine
self.update = function () {
// Only apply gravity if the game has started
if (gameStarted) {
// Auto-flap when player is holding down and bird is falling
if (self.isHolding && self.velocityY > 5) {
self.flap();
}
// Apply gravity
self.velocityY += GRAVITY;
self.y += self.velocityY;
// Clamp position to screen bounds (leaving some margin)
if (self.y < birdGraphics.height / 2) {
self.y = birdGraphics.height / 2;
self.velocityY = 0; // Stop moving up if hitting the ceiling
}
// Note: Ground collision is handled in the main game update loop
// Apply rotation based on velocity
var targetRotation = 0;
if (self.velocityY < 0) {
// Moving up
targetRotation = MIN_ROTATION; // Tilt slightly up
} else if (self.velocityY > 10) {
// Moving down fast
// Gradually tilt down based on velocity, capped at MAX_ROTATION
targetRotation = Math.min(MAX_ROTATION, self.velocityY / 50 * MAX_ROTATION);
}
// Smoothly rotate towards the target rotation
birdGraphics.rotation += (targetRotation - birdGraphics.rotation) * 0.1;
}
};
return self;
});
// KaleidoscopeEffect class for creating trippy kaleidoscope-like effects
var KaleidoscopeEffect = Container.expand(function () {
var self = Container.call(this);
// Kaleidoscope properties
self.segments = 6; // Number of reflection segments
self.angleOffset = 0; // Current rotation offset
self.rotationSpeed = 0.01; // Speed of rotation
self.particles = []; // Particles for the effect
self.particleCount = 8; // Number of particles
// Initialize the kaleidoscope effect
self.init = function () {
// Create particles that will be reflected in the kaleidoscope
for (var i = 0; i < self.particleCount; i++) {
var particle = LK.getAsset('bird', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.5,
scale: 0.5 + Math.random() * 0.5,
tint: Math.random() * 0xFFFFFF
});
// Position particles in a circular pattern
var angle = i / self.particleCount * Math.PI * 2;
var distance = 200 + Math.random() * 300;
particle.x = Math.cos(angle) * distance;
particle.y = Math.sin(angle) * distance;
// Movement parameters
particle.orbitSpeed = 0.01 + Math.random() * 0.02;
particle.orbitDistance = distance;
particle.orbitAngle = angle;
particle.pulseSpeed = 0.05 + Math.random() * 0.05;
particle.pulsePhase = Math.random() * Math.PI * 2;
self.particles.push(particle);
self.addChild(particle);
}
};
// Update the kaleidoscope effect
self.update = function () {
// Rotate the entire kaleidoscope
self.angleOffset += self.rotationSpeed;
self.rotation = self.angleOffset;
// Update particles
for (var i = 0; i < self.particles.length; i++) {
var particle = self.particles[i];
// Orbit motion
particle.orbitAngle += particle.orbitSpeed;
particle.x = Math.cos(particle.orbitAngle) * particle.orbitDistance;
particle.y = Math.sin(particle.orbitAngle) * particle.orbitDistance;
// Pulse size
particle.pulsePhase += particle.pulseSpeed;
particle.scale.x = particle.scale.y = 0.5 + Math.sin(particle.pulsePhase) * 0.3;
// Cycle colors
particle.tint = Math.floor(Math.random() * 0xFFFFFF);
}
};
return self;
});
// Flag to track if player is holding down
// ObstaclePair class representing a top and bottom obstacle
var ObstaclePair = Container.expand(function () {
var self = Container.call(this);
// Constants for obstacles
var GAP_HEIGHT = 800; // Space between top and bottom obstacles (increased from 550)
var OBSTACLE_WIDTH = 200; // Keep consistent with asset init
// Create top and bottom obstacles
self.topObstacle = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 1.0 // Anchor at the bottom-center
});
self.bottomObstacle = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.0 // Anchor at the top-center
});
// Property to track if score has been awarded for this pair
self.scored = false;
// Method to set the position and gap
self.setup = function (xPos, gapCenterY) {
self.x = xPos;
// Position obstacles relative to the container's position
self.topObstacle.y = gapCenterY - GAP_HEIGHT / 2;
self.bottomObstacle.y = gapCenterY + GAP_HEIGHT / 2;
// Randomize color for psychedelic effect
var randomColor = Math.random() * 0xFFFFFF;
self.topObstacle.tint = randomColor;
self.bottomObstacle.tint = randomColor;
};
// Method to check collision with the bird using built-in intersects
self.collidesWith = function (bird) {
// Check intersection between the bird container and the top/bottom obstacle assets.
// The intersects() method compares the bounding boxes of the display objects.
if (bird.intersects(self.topObstacle) || bird.intersects(self.bottomObstacle)) {
return true;
}
return false;
};
// Update method for movement
self.update = function (speed) {
self.x -= speed;
};
return self;
});
// StartScreen class to show the intro screen with enhanced animations
var StartScreen = Container.expand(function () {
var self = Container.call(this);
// Create container for title letters
var titleContainer = new Container();
titleContainer.y = -300;
self.addChild(titleContainer);
// Individual letter animation for title
var titleText = "TRIPPY FLAP";
var letterSpacing = 80;
var letters = [];
var letterColors = [];
// Create individual letter sprites for animated title
for (var i = 0; i < titleText.length; i++) {
var letter = new Text2(titleText[i], {
size: 220,
fill: 0xFFFFFF
});
letter.anchor.set(0.5, 0.5);
letter.x = (i - titleText.length / 2) * letterSpacing;
letter.y = 0;
letter.alpha = 0;
letter.scale.set(0);
letterColors[i] = Math.random() * 0xFFFFFF;
letter.origY = letter.y;
letters.push(letter);
titleContainer.addChild(letter);
}
// Create instruction text with cool styling
var instructionText = new Text2('Tap to Start', {
size: 140,
fill: 0xFFFFFF
});
instructionText.anchor.set(0.5, 0.5);
instructionText.y = 100;
instructionText.alpha = 0;
self.addChild(instructionText);
// Create control instructions text
var controlText = new Text2('Tap to flap, hold to auto-flap!', {
size: 80,
fill: 0xFFFFFF
});
controlText.anchor.set(0.5, 0.5);
controlText.y = 250;
controlText.alpha = 0;
self.addChild(controlText);
// Create bird trail container
var birdTrailContainer = new Container();
self.addChild(birdTrailContainer);
// Create a sample bird to show on start screen
var sampleBird = LK.getAsset('bird', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: -100,
scale: 0
});
self.addChild(sampleBird);
// Create decorative particles
var particles = [];
for (var i = 0; i < 30; i++) {
var particle = LK.getAsset('bird', {
anchorX: 0.5,
anchorY: 0.5,
scale: 0.2 + Math.random() * 0.3,
alpha: 0.2 + Math.random() * 0.3
});
particle.x = (Math.random() - 0.5) * 1500;
particle.y = (Math.random() - 0.5) * 2000;
particle.speedX = (Math.random() - 0.5) * 5;
particle.speedY = (Math.random() - 0.5) * 5;
particle.rotSpeed = (Math.random() - 0.5) * 0.1;
particles.push(particle);
self.addChild(particle);
}
// Properties for animation effects
var colorPhase = 0;
var floatPhase = 0;
var introAnimationStarted = false;
var introAnimationCompleted = false;
var trailTimer = 0;
// Initialize with intro animation
self.startIntroAnimation = function () {
if (introAnimationStarted) {
return;
}
introAnimationStarted = true;
// Animate title letters sequentially
letters.forEach(function (letter, index) {
LK.setTimeout(function () {
tween(letter, {
alpha: 1,
y: letter.origY - 200
}, {
duration: 300,
easing: tween.easeOut
});
tween(letter.scale, {
x: 1.5,
y: 1.5
}, {
duration: 400,
easing: tween.elastic,
onFinish: function onFinish() {
tween(letter.scale, {
x: 1,
y: 1
}, {
duration: 300,
easing: tween.easeOut
});
tween(letter, {
y: letter.origY
}, {
duration: 500,
easing: tween.bounce
});
}
});
}, index * 120);
});
// Animate bird after title
LK.setTimeout(function () {
// Bird dramatic entrance
sampleBird.scaleX = 0;
sampleBird.scaleY = 0;
sampleBird.alpha = 1;
tween(sampleBird, {
x: 2.5,
y: 2.5,
scaleX: 0,
scaleY: 0
}, {
duration: 600,
easing: tween.elastic,
onFinish: function onFinish() {
tween(sampleBird, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 400,
easing: tween.easeOut
});
// Flash screen for dramatic effect
LK.effects.flashScreen(0xFFFFFF, 300);
// Show instructions after bird appears
tween(instructionText, {
alpha: 1
}, {
duration: 500,
easing: tween.easeIn
});
tween(controlText, {
alpha: 1
}, {
duration: 500,
easing: tween.easeIn
});
introAnimationCompleted = true;
}
});
}, letters.length * 120 + 200);
};
self.update = function () {
// Start intro animation if not started yet
if (!introAnimationStarted) {
self.startIntroAnimation();
}
// Update background particles
particles.forEach(function (particle) {
particle.x += particle.speedX;
particle.y += particle.speedY;
particle.rotation += particle.rotSpeed;
// Wrap particles around screen
if (particle.x < -1000) {
particle.x = 1000;
}
if (particle.x > 1000) {
particle.x = -1000;
}
if (particle.y < -1500) {
particle.y = 1500;
}
if (particle.y > 1500) {
particle.y = -1500;
}
// Pulsate particles
colorPhase += 0.0001;
particle.scale.x = particle.scale.y = 0.2 + Math.sin(colorPhase + particle.x) * 0.1;
particle.tint = Math.random() * 0xFFFFFF;
});
// Only run these effects once intro is complete
if (introAnimationCompleted) {
// Floating animation for bird
floatPhase += 0.05;
sampleBird.y = -100 + Math.sin(floatPhase) * 50;
// Color cycling for title letters
colorPhase += 0.02;
letters.forEach(function (letter, index) {
var r = Math.sin(colorPhase + index * 0.3) * 127 + 128;
var g = Math.sin(colorPhase + index * 0.3 + 2) * 127 + 128;
var b = Math.sin(colorPhase + index * 0.3 + 4) * 127 + 128;
var letterColor = Math.floor(r) << 16 | Math.floor(g) << 8 | Math.floor(b);
letter.fill = letterColor;
// Make letters dance
letter.y = letter.origY + Math.sin(floatPhase + index * 0.3) * 20;
letter.rotation = Math.sin(floatPhase * 0.5 + index) * 0.1;
});
// Pulse the instruction text with glow effect
instructionText.scale.x = 1 + Math.sin(floatPhase * 2) * 0.15;
instructionText.scale.y = 1 + Math.sin(floatPhase * 2) * 0.15;
var pulseColor = Math.floor(Math.sin(floatPhase) * 127 + 128) << 16 | Math.floor(Math.sin(floatPhase + 2) * 127 + 128) << 8 | Math.floor(Math.sin(floatPhase + 4) * 127 + 128);
instructionText.fill = pulseColor;
// Apply trippy effect to sample bird
sampleBird.rotation = Math.sin(floatPhase) * 0.2;
sampleBird.tint = Math.floor(Math.random() * 0xFFFFFF);
// Create bird trails
trailTimer++;
if (trailTimer >= 8) {
trailTimer = 0;
var trail = LK.getAsset('bird', {
anchorX: 0.5,
anchorY: 0.5,
x: sampleBird.x,
y: sampleBird.y,
rotation: sampleBird.rotation,
scale: 1.2,
alpha: 0.4,
tint: Math.random() * 0xFFFFFF
});
birdTrailContainer.addChild(trail);
// Animate trail fade out
tween(trail, {
alpha: 0,
scale: 0.5
}, {
duration: 700,
easing: tween.easeOut,
onFinish: function onFinish() {
if (trail.parent) {
trail.parent.removeChild(trail);
}
}
});
}
}
};
return self;
});
// TrailEffect class to create psychedelic trailing effect behind objects
var TrailEffect = Container.expand(function () {
var self = Container.call(this);
// Trail properties
self.maxTrails = 10; // Maximum number of trail elements
self.fadeSpeed = 0.1; // How quickly trails fade out
self.trailElements = []; // Array to store trail elements
self.target = null; // The object to trail
self.trailSpacing = 3; // Frames between trail elements
self.frameCount = 0; // Counter for spacing
// Initialize the trail effect for a target
self.init = function (target, assetId) {
self.target = target;
self.assetId = assetId;
// Clear any existing trails
self.clearTrails();
};
// Clear all trail elements
self.clearTrails = function () {
for (var i = 0; i < self.trailElements.length; i++) {
if (self.trailElements[i].parent) {
self.trailElements[i].parent.removeChild(self.trailElements[i]);
}
}
self.trailElements = [];
};
// Update the trail effect
self.update = function () {
if (!self.target) {
return;
}
self.frameCount++;
// Add new trail element at intervals
if (self.frameCount >= self.trailSpacing) {
self.frameCount = 0;
// Create new trail element
var trail = LK.getAsset(self.assetId, {
anchorX: 0.5,
anchorY: 0.5,
x: self.target.x,
y: self.target.y,
rotation: self.target.rotation,
alpha: 0.6
});
// Apply random psychedelic color
trail.tint = Math.random() * 0xFFFFFF;
// Add to game and track
game.addChild(trail);
self.trailElements.push(trail);
// Remove oldest trail if we exceed max
if (self.trailElements.length > self.maxTrails) {
var oldest = self.trailElements.shift();
if (oldest.parent) {
oldest.parent.removeChild(oldest);
}
}
}
// Fade out all trail elements
for (var i = 0; i < self.trailElements.length; i++) {
self.trailElements[i].alpha -= self.fadeSpeed;
self.trailElements[i].scale.x += 0.03;
self.trailElements[i].scale.y += 0.03;
// Remove if fully faded
if (self.trailElements[i].alpha <= 0) {
if (self.trailElements[i].parent) {
self.trailElements[i].parent.removeChild(self.trailElements[i]);
}
self.trailElements.splice(i, 1);
i--;
}
}
};
return self;
});
// WaveEffect class to create psychedelic visual distortions
var WaveEffect = Container.expand(function () {
var self = Container.call(this);
// Effect properties
self.amplitude = 20; // Wave height
self.frequency = 0.005; // Wave frequency
self.speed = 0.05; // Wave speed
self.colorSpeed = 0.01; // Color change speed
self.phase = 0; // Current phase of the wave
self.colorPhase = 0; // Current phase of the color cycle
// Apply wave distortion to a target object
self.applyDistortion = function (target) {
if (!target) {
return;
}
// Update phases
self.phase += self.speed;
self.colorPhase += self.colorSpeed;
// Apply wave effect to scale/rotation
target.scale.x = 1 + Math.sin(self.phase) * 0.1;
target.scale.y = 1 + Math.cos(self.phase * 1.3) * 0.1;
target.rotation = Math.sin(self.phase * 0.7) * 0.1;
// Apply trippy color effect
var r = Math.sin(self.colorPhase) * 127 + 128;
var g = Math.sin(self.colorPhase + 2) * 127 + 128;
var b = Math.sin(self.colorPhase + 4) * 127 + 128;
var color = r << 16 | g << 8 | b;
target.tint = color;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a001a // Start with a dark purple background
});
/****
* Game Code
****/
// Game constants
// Define assets for the game. These will be created automatically by the engine.
// Bird asset
// Obstacle asset (will be tinted/resized later)
// Sound for flapping (optional, but good practice)
// Sound for passing obstacle (optional)
// Sound for collision (optional)
// Include the tween plugin for animations and effects
var GAME_WIDTH = 2048;
var GAME_HEIGHT = 2732;
var BASE_OBSTACLE_SPEED = 5; // Base speed that will increase over time
var OBSTACLE_SPEED = BASE_OBSTACLE_SPEED; // Current speed
var MAX_OBSTACLE_SPEED = 15; // Maximum speed cap
var SPEED_INCREASE_RATE = 0.2; // How much to increase speed each time
var SPEED_INCREASE_INTERVAL = 10000; // Increase speed every 10 seconds (in ms)
var OBSTACLE_SPAWN_RATE = 180; // Ticks between spawns (approx 3 seconds at 60fps)
var MIN_OBSTACLE_SPAWN_RATE = 60; // Minimum spawn rate (faster spawning)
var OBSTACLE_START_X = GAME_WIDTH + 150; // Start spawning off-screen right
var OBSTACLE_MIN_Y = 600; // Min center Y for the gap
var OBSTACLE_MAX_Y = GAME_HEIGHT - 600; // Max center Y for the gap
var speedIncreaseTimer = null; // Timer for speed increases
// Game variables
var bird;
var obstacles = [];
var spawnTimer = 0;
var isGameOver = false;
var gameStarted = false; // New variable to track if game has started
var backgroundChangeTimer = 0;
var backgroundTween = null; // To manage background color tween
var startScreen; // Variable to hold the start screen
// Psychedelic effect variables
var waveEffect;
var birdTrail;
var globalDistortionPhase = 0;
var screenShakeIntensity = 0;
// Score display with psychedelic styling
var scoreTxt = new Text2('0', {
size: 180,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Position score text slightly down from the top center, avoiding top-left corner
scoreTxt.y = 100;
// Setup score text color animation
LK.setInterval(function () {
var r = Math.floor(Math.random() * 255);
var g = Math.floor(Math.random() * 255);
var b = Math.floor(Math.random() * 255);
var randomColor = r << 16 | g << 8 | b;
// Animate score text color change
tween(scoreTxt, {
fill: randomColor
}, {
duration: 500,
easing: tween.easeInOut
});
// Add pulsating scale effect
tween(scoreTxt.scale, {
x: 1.2,
y: 1.2
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(scoreTxt.scale, {
x: 1.0,
y: 1.0
}, {
duration: 250,
easing: tween.easeIn
});
}
});
}, 1000);
// Initialize bird
bird = new Bird();
bird.x = GAME_WIDTH / 4; // Start position
bird.y = GAME_HEIGHT / 2;
game.addChild(bird);
// Initialize psychedelic effects
waveEffect = new WaveEffect();
birdTrail = new TrailEffect();
birdTrail.init(bird, 'bird');
// Handle player input (flap and hold)
game.down = function (x, y, obj) {
if (!gameStarted) {
// Start the game on first tap with enhanced transition
gameStarted = true;
// Dramatic zoom effect on the start screen
tween(startScreen.scale, {
x: 1.2,
y: 1.2
}, {
duration: 300,
easing: tween.easeIn,
onFinish: function onFinish() {
// Create explosive particle effect
for (var i = 0; i < 30; i++) {
var particle = LK.getAsset('bird', {
anchorX: 0.5,
anchorY: 0.5,
x: startScreen.x,
y: startScreen.y,
scale: 0.2 + Math.random() * 0.3,
alpha: 0.7 + Math.random() * 0.3,
tint: Math.random() * 0xFFFFFF
});
var angle = Math.random() * Math.PI * 2;
var distance = 500 + Math.random() * 1000;
var duration = 500 + Math.random() * 1000;
game.addChild(particle);
tween(particle, {
x: startScreen.x + Math.cos(angle) * distance,
y: startScreen.y + Math.sin(angle) * distance,
alpha: 0,
rotation: Math.random() * Math.PI * 4
}, {
duration: duration,
easing: tween.easeOut,
onFinish: function onFinish() {
if (particle.parent) {
particle.parent.removeChild(particle);
}
}
});
}
// Flash screen for transition effect
LK.effects.flashScreen(0xFFFFFF, 300);
// Fade out start screen
tween(startScreen, {
alpha: 0
}, {
duration: 500,
easing: tween.easeOut,
onFinish: function onFinish() {
game.removeChild(startScreen);
}
});
}
});
// Reset score
LK.setScore(0);
scoreTxt.setText('0');
// Start game with a small delay to allow fade transition
LK.setTimeout(function () {
// Show score text with animation
scoreTxt.alpha = 0;
scoreTxt.scale.set(2);
tween(scoreTxt, {
alpha: 1
}, {
duration: 500,
easing: tween.easeOut
});
tween(scoreTxt.scale, {
x: 1,
y: 1
}, {
duration: 800,
easing: tween.elastic
});
}, 600);
} else if (!isGameOver) {
bird.flap();
// Set holding state to true
bird.setHolding(true);
// Add extra psychedelic effects on flap
screenShakeIntensity = 15; // Increased screen shake intensity
// Flash screen with random vivid color
var flashColor = Math.random() * 0xFFFFFF;
LK.effects.flashScreen(flashColor, 150);
// Create a radial burst of colorful particles from the bird position
for (var i = 0; i < 8; i++) {
var angle = i / 8 * Math.PI * 2;
var particle = LK.getAsset('bird', {
anchorX: 0.5,
anchorY: 0.5,
x: bird.x,
y: bird.y,
scale: 0.3,
alpha: 0.7,
tint: Math.random() * 0xFFFFFF
});
game.addChild(particle);
tween(particle, {
x: bird.x + Math.cos(angle) * 200,
y: bird.y + Math.sin(angle) * 200,
alpha: 0,
rotation: Math.random() * Math.PI * 2
}, {
duration: 500,
easing: tween.easeOut,
onFinish: function onFinish() {
if (particle.parent) {
particle.parent.removeChild(particle);
}
}
});
}
// Temporary background color flash
var currentBg = game.backgroundColor;
game.backgroundColor = 0xFFFFFF;
LK.setTimeout(function () {
game.backgroundColor = currentBg;
}, 50);
// Start the speed increase timer if it hasn't been started yet
if (!speedIncreaseTimer) {
speedIncreaseTimer = LK.setInterval(function () {
if (!isGameOver && gameStarted) {
// Increase obstacle speed
OBSTACLE_SPEED = Math.min(MAX_OBSTACLE_SPEED, OBSTACLE_SPEED + SPEED_INCREASE_RATE);
// Decrease spawn rate (for more obstacles)
OBSTACLE_SPAWN_RATE = Math.max(MIN_OBSTACLE_SPAWN_RATE, OBSTACLE_SPAWN_RATE - 5);
// Visual feedback for speed increase
LK.effects.flashScreen(0xFFFFFF, 200);
// Show speed increase text
var speedMsg = new Text2("Speed Up!", {
size: 100,
fill: 0xFFFF00
});
speedMsg.anchor.set(0.5, 0.5);
speedMsg.x = GAME_WIDTH / 2;
speedMsg.y = GAME_HEIGHT / 2;
game.addChild(speedMsg);
// Animate and remove the text
tween(speedMsg, {
alpha: 0,
y: speedMsg.y - 100
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
if (speedMsg.parent) {
speedMsg.parent.removeChild(speedMsg);
}
}
});
}
}, SPEED_INCREASE_INTERVAL);
}
}
};
// Handle player releasing the screen
game.up = function (x, y, obj) {
if (gameStarted && !isGameOver) {
// Set holding state to false when player releases
bird.setHolding(false);
}
};
// Function to spawn a new obstacle pair
function spawnObstacle() {
var newObstacle = new ObstaclePair();
var gapCenterY = Math.random() * (OBSTACLE_MAX_Y - OBSTACLE_MIN_Y) + OBSTACLE_MIN_Y;
newObstacle.setup(OBSTACLE_START_X, gapCenterY);
obstacles.push(newObstacle);
game.addChild(newObstacle);
}
// Function for psychedelic background effect
function changeBackgroundColor() {
if (backgroundTween) {
tween.stop(game); // Stop existing background tween if any
}
// Generate more intense psychedelic colors - using ultra high saturation/values
var h = Math.random();
var s = 1.0; // Maximum saturation
var v = 0.9 + Math.random() * 0.1; // High value (0.9-1.0)
// Prefer certain hue ranges for more vibrant psychedelic colors
if (Math.random() < 0.7) {
// 70% chance to use these psychedelic color ranges:
var ranges = [[0.7, 0.9],
// purples
[0.45, 0.55],
// cyans
[0.1, 0.2],
// yellows/greens
[0.95, 1.0] // deep reds
];
var selectedRange = ranges[Math.floor(Math.random() * ranges.length)];
h = selectedRange[0] + Math.random() * (selectedRange[1] - selectedRange[0]);
}
// HSV to RGB conversion for more vibrant colors
var i = Math.floor(h * 6);
var f = h * 6 - i;
var p = v * (1 - s);
var q = v * (1 - f * s);
var t = v * (1 - (1 - f) * s);
var r, g, b;
switch (i % 6) {
case 0:
r = v;
g = t;
b = p;
break;
case 1:
r = q;
g = v;
b = p;
break;
case 2:
r = p;
g = v;
b = t;
break;
case 3:
r = p;
g = q;
b = v;
break;
case 4:
r = t;
g = p;
b = v;
break;
case 5:
r = v;
g = p;
b = q;
break;
}
var nextColor = Math.floor(r * 255) << 16 | Math.floor(g * 255) << 8 | Math.floor(b * 255);
// Ensure a valid color value is used (default to purple if undefined)
nextColor = nextColor || 0x800080;
// Ensure we have a valid color before starting the tween
if (isNaN(nextColor) || nextColor === undefined) {
nextColor = 0x800080; // Default to purple if undefined or NaN
}
backgroundTween = tween(game, {
backgroundColor: nextColor
}, {
duration: 800,
// Faster transitions for more trippy effect
easing: tween.easeInOut,
onFinish: function onFinish() {
backgroundTween = null;
} // Clear the tween reference on finish
});
}
// Initialize background patterns and kaleidoscope effect
var backgroundPatterns = new BackgroundPatterns();
backgroundPatterns.init();
game.addChild(backgroundPatterns);
// Initialize kaleidoscope effect
var kaleidoscopeEffect = new KaleidoscopeEffect();
kaleidoscopeEffect.init();
kaleidoscopeEffect.x = GAME_WIDTH / 2;
kaleidoscopeEffect.y = GAME_HEIGHT / 2;
game.addChild(kaleidoscopeEffect);
// Game update loop
game.update = function () {
if (!gameStarted) {
// Only update start screen when game hasn't started
startScreen.update();
// Also update background patterns and kaleidoscope for pre-game effects
backgroundPatterns.update();
kaleidoscopeEffect.update();
return;
}
if (isGameOver) {
return;
} // Stop updates if game over
// Update global distortion phase
globalDistortionPhase += 0.05; // Increased for more intense effects
// Apply screen shake effect (gradually reduces intensity)
if (screenShakeIntensity > 0) {
game.x = (Math.random() * 2 - 1) * screenShakeIntensity;
game.y = (Math.random() * 2 - 1) * screenShakeIntensity;
screenShakeIntensity *= 0.9;
if (screenShakeIntensity < 0.5) {
screenShakeIntensity = 0;
game.x = 0;
game.y = 0;
}
}
// Update background patterns and kaleidoscope for more psychedelic effects
backgroundPatterns.update();
kaleidoscopeEffect.update();
// Apply occasional camera zoom effects for trippy sensation
if (Math.random() < 0.01) {
var zoomScale = 0.95 + Math.random() * 0.1; // Random zoom between 0.95 and 1.05
tween(game.scale, {
x: zoomScale,
y: zoomScale
}, {
duration: 400,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(game.scale, {
x: 1,
y: 1
}, {
duration: 400,
easing: tween.easeInOut
});
}
});
}
// Update bird and psychedelic effects
bird.update(); // Calls bird's internal update for physics
waveEffect.applyDistortion(bird.children[0]);
birdTrail.update();
// Check ground collision
if (bird.y >= GAME_HEIGHT - bird.children[0].height / 2) {
LK.getSound('hitSound').play();
LK.effects.flashScreen(0xFF0000, 300); // Flash red on hit
isGameOver = true;
// Reset speed-related values for next game
OBSTACLE_SPEED = BASE_OBSTACLE_SPEED;
OBSTACLE_SPAWN_RATE = 180;
if (speedIncreaseTimer) {
LK.clearInterval(speedIncreaseTimer);
speedIncreaseTimer = null;
}
LK.showGameOver();
return; // Stop further processing this frame
}
// Update obstacles
spawnTimer++;
if (spawnTimer >= OBSTACLE_SPAWN_RATE) {
spawnObstacle();
spawnTimer = 0;
}
// Move and check obstacles
for (var i = obstacles.length - 1; i >= 0; i--) {
var obstacle = obstacles[i];
obstacle.update(OBSTACLE_SPEED); // Move obstacle left
// Check for collision with bird
if (obstacle.collidesWith(bird)) {
LK.getSound('hitSound').play();
LK.effects.flashObject(bird, 0xFF0000, 300); // Flash bird red
isGameOver = true;
// Reset speed-related values for next game
OBSTACLE_SPEED = BASE_OBSTACLE_SPEED;
OBSTACLE_SPAWN_RATE = 180;
if (speedIncreaseTimer) {
LK.clearInterval(speedIncreaseTimer);
speedIncreaseTimer = null;
}
LK.showGameOver();
return; // Stop further processing this frame
}
// Check for scoring
if (!obstacle.scored && obstacle.x + obstacle.topObstacle.width / 2 < bird.x) {
obstacle.scored = true;
LK.setScore(LK.getScore() + 1);
scoreTxt.setText(LK.getScore());
LK.getSound('scoreSound').play();
// Optional: Flash score text or screen briefly on score
LK.effects.flashObject(scoreTxt, 0x00FF00, 150);
}
// Remove obstacles that are off-screen left
// Obstacle pair's x is its center. Remove when its right edge (x + width/2) is less than 0.
// Use the actual width of the obstacle graphic instance.
if (obstacle.x + obstacle.topObstacle.width / 2 < 0) {
obstacle.destroy();
obstacles.splice(i, 1);
}
}
// Psychedelic background effect timer - more frequent changes
backgroundChangeTimer++;
if (backgroundChangeTimer >= 30) {
// Twice as frequent (every half second)
// Change color more frequently
changeBackgroundColor();
backgroundChangeTimer = 0;
// Sometimes apply a more dramatic flash effect
if (Math.random() < 0.2) {
var flashColor = Math.random() * 0xFFFFFF;
LK.effects.flashScreen(flashColor, 100);
}
}
// Apply ultra intense psychedelic effects to obstacles
obstacles.forEach(function (obs, index) {
// Even more intense distortion effects
var individualPhase = globalDistortionPhase + index * 0.3;
// Extreme scaling with different frequencies for each obstacle
var pulseScaleX = 1 + Math.sin(individualPhase * 1.5) * 0.2;
var pulseScaleY = 1 + Math.cos(individualPhase * 1.2) * 0.25;
// Apply to top obstacle with warping effect
obs.topObstacle.scale.x = pulseScaleX;
obs.topObstacle.scale.y = pulseScaleY;
obs.topObstacle.rotation = Math.sin(individualPhase * 0.9) * 0.15;
// Apply to bottom obstacle with different phase
obs.bottomObstacle.scale.x = pulseScaleX * 0.9;
obs.bottomObstacle.scale.y = pulseScaleY * 1.1;
obs.bottomObstacle.rotation = Math.cos(individualPhase * 0.8) * 0.18;
// Cycle colors using ultra-saturated neon colors
var r = Math.sin(individualPhase * 1.2) * 127 + 128;
var g = Math.sin(individualPhase * 1.2 + 2) * 127 + 128;
var b = Math.sin(individualPhase * 1.2 + 4) * 127 + 128;
// Enhance color saturation for more vivid results
r = Math.min(255, r * 1.2);
g = Math.min(255, g * 1.2);
b = Math.min(255, b * 1.2);
var topColor = Math.floor(r) << 16 | Math.floor(g) << 8 | Math.floor(b);
var bottomColor = 255 - Math.floor(r) << 16 | 255 - Math.floor(g) << 8 | 255 - Math.floor(b);
// Apply colors with occasional random flashes
if (Math.random() < 0.05) {
// Random flash color
topColor = Math.random() * 0xFFFFFF;
bottomColor = Math.random() * 0xFFFFFF;
}
obs.topObstacle.tint = topColor;
obs.bottomObstacle.tint = bottomColor;
});
};
// Start the first background color change
changeBackgroundColor();
// Initialize start screen with enhanced animation
startScreen = new StartScreen();
startScreen.x = GAME_WIDTH / 2;
startScreen.y = GAME_HEIGHT / 2;
game.addChild(startScreen);
// Apply psychedelic background pulse effect for start screen
LK.setInterval(function () {
// Only pulse background before game starts
if (!gameStarted) {
var h = Math.random();
var s = 0.7 + Math.random() * 0.3;
var v = 0.6 + Math.random() * 0.4;
// HSV to RGB conversion
var i = Math.floor(h * 6);
var f = h * 6 - i;
var p = v * (1 - s);
var q = v * (1 - f * s);
var t = v * (1 - (1 - f) * s);
var r, g, b;
switch (i % 6) {
case 0:
r = v;
g = t;
b = p;
break;
case 1:
r = q;
g = v;
b = p;
break;
case 2:
r = p;
g = v;
b = t;
break;
case 3:
r = p;
g = q;
b = v;
break;
case 4:
r = t;
g = p;
b = v;
break;
case 5:
r = v;
g = p;
b = q;
break;
}
var targetColor = Math.floor(r * 255) << 16 | Math.floor(g * 255) << 8 | Math.floor(b * 255);
// Animate background color change
tween(game, {
backgroundColor: targetColor
}, {
duration: 1500,
easing: tween.easeInOut
});
}
}, 2000);
// Hide score text initially
scoreTxt.alpha = 0; ===================================================================
--- original.js
+++ change.js
@@ -923,9 +923,11 @@
var nextColor = Math.floor(r * 255) << 16 | Math.floor(g * 255) << 8 | Math.floor(b * 255);
// Ensure a valid color value is used (default to purple if undefined)
nextColor = nextColor || 0x800080;
// Ensure we have a valid color before starting the tween
- nextColor = nextColor || 0x800080; // Default to purple if undefined
+ if (isNaN(nextColor) || nextColor === undefined) {
+ nextColor = 0x800080; // Default to purple if undefined or NaN
+ }
backgroundTween = tween(game, {
backgroundColor: nextColor
}, {
duration: 800,