User prompt
Add a Main Menu with scene when human jump into river and transform in Canadian Geese with Human Types and Canadian Geese super abilities! (and geese scenes with geese and 2D assets of humans and geese in Dialogs! ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Fix all!
User prompt
Add a special fast geese mode and fix all errors! ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Error detected!
Code edit (1 edits merged)
Please save this source code
User prompt
Goose Invasion: The Great Migration
Initial prompt
Make a game with Canadian Geese as player (this is a infection game, goose infect humans into geese by Infected bite and Canadian Geese Transform (in start player is human)
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Dialog = Container.expand(function (text, characterType) {
var self = Container.call(this);
var dialogBackground = self.attachAsset('dialogBox', {
anchorX: 0.5,
anchorY: 0.5
});
dialogBackground.alpha = 0.8;
var dialogText = new Text2(text, {
size: 40,
fill: 0xFFFFFF,
wordWrap: true,
wordWrapWidth: 1700
});
dialogText.anchor.set(0.5, 0.5);
self.addChild(dialogText);
// Add character sprite based on type
var character = null;
if (characterType === 'human') {
character = LK.getAsset('human', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
character.x = -700;
character.y = -50;
} else if (characterType === 'goose') {
character = LK.getAsset('goose', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
character.x = -700;
character.y = -50;
}
if (character) {
self.addChild(character);
}
self.isVisible = false;
self.alpha = 0;
self.show = function () {
self.isVisible = true;
tween(self, {
alpha: 1
}, {
duration: 500
});
};
self.hide = function () {
self.isVisible = false;
tween(self, {
alpha: 0
}, {
duration: 500
});
};
return self;
});
var Goose = Container.expand(function (gooseType) {
var self = Container.call(this);
// Set goose type and abilities
self.gooseType = gooseType || 'normal';
var color = 0xf0f0f0; // Default white
self.speed = 3;
self.specialAbility = null;
self.abilityTimer = 0;
// Different goose types with special abilities
switch (self.gooseType) {
case 'speed':
color = 0x00ffff; // Cyan
self.speed = 5;
self.specialAbility = 'speedBoost';
break;
case 'magnetic':
color = 0xff69b4; // Hot pink
self.specialAbility = 'magneticPull';
break;
case 'honker':
color = 0xffd700; // Gold
self.specialAbility = 'massHonk';
break;
default:
break;
}
var gooseGraphics = self.attachAsset('goose', {
anchorX: 0.5,
anchorY: 0.5
});
gooseGraphics.tint = color;
self.targetX = self.x;
self.targetY = self.y;
self.isLeader = false;
self.followTarget = null;
self.followDistance = 80;
self.conversionRadius = 70;
self.update = function () {
if (self.isLeader) {
// Leader follows mouse/touch position
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;
}
} else if (self.followTarget) {
// Follower geese maintain formation
var dx = self.followTarget.x - self.x;
var dy = self.followTarget.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > self.followDistance) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
}
// Handle special abilities
if (self.specialAbility && self.abilityTimer > 0) {
self.abilityTimer--;
if (self.specialAbility === 'magneticPull') {
self.conversionRadius = 150;
}
}
};
self.activateAbility = function () {
if (self.specialAbility) {
self.abilityTimer = 300; // 5 seconds at 60fps
switch (self.specialAbility) {
case 'speedBoost':
self.speed = 8;
tween(gooseGraphics, {
tint: 0x00ff00
}, {
duration: 200
});
LK.setTimeout(function () {
self.speed = 5;
tween(gooseGraphics, {
tint: color
}, {
duration: 500
});
}, 5000);
break;
case 'massHonk':
LK.getSound('honk').play();
LK.effects.flashScreen(0xffd700, 300);
break;
}
}
};
return self;
});
var Human = Container.expand(function (humanType) {
var self = Container.call(this);
// Set human type and properties
self.humanType = humanType || 'normal';
var color = 0x8b4513; // Default brown
var size = 1;
// Different human types with special properties
switch (self.humanType) {
case 'athlete':
color = 0xff6347; // Red
self.speed = 2;
size = 1.2;
break;
case 'child':
color = 0xffd700; // Gold
self.speed = 0.5;
size = 0.8;
break;
case 'elder':
color = 0x708090; // Slate gray
self.speed = 0.3;
size = 0.9;
break;
default:
self.speed = 1;
break;
}
var humanGraphics = self.attachAsset('human', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: size,
scaleY: size
});
humanGraphics.tint = color;
self.isConverted = false;
self.wanderTimer = 0;
self.wanderDirection = Math.random() * Math.PI * 2;
self.update = function () {
if (!self.isConverted) {
// Random wandering behavior
self.wanderTimer++;
if (self.wanderTimer > 120) {
// Change direction every 2 seconds
self.wanderDirection = Math.random() * Math.PI * 2;
self.wanderTimer = 0;
}
self.x += Math.cos(self.wanderDirection) * self.speed;
self.y += Math.sin(self.wanderDirection) * self.speed;
// Keep humans within bounds
if (self.x < 100) self.x = 100;
if (self.x > 1948) self.x = 1948;
if (self.y < 100) self.y = 100;
if (self.y > 2632) self.y = 2632;
}
};
self.convert = function () {
if (!self.isConverted) {
self.isConverted = true;
humanGraphics.tint = 0x808080; // Gray out converted human
tween(humanGraphics, {
alpha: 0
}, {
duration: 500
});
LK.getSound('convert').play();
return true;
}
return false;
};
return self;
});
var MainMenu = Container.expand(function () {
var self = Container.call(this);
// Title
var titleText = new Text2('GOOSE INVASION', {
size: 80,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 300;
self.addChild(titleText);
var subtitleText = new Text2('The Great Migration', {
size: 50,
fill: 0xCCCCCC
});
subtitleText.anchor.set(0.5, 0.5);
subtitleText.x = 1024;
subtitleText.y = 400;
self.addChild(subtitleText);
// River scene
var river = self.attachAsset('river', {
anchorX: 0.5,
anchorY: 0.5
});
river.x = 1024;
river.y = 1500;
// Human character that will transform
var transformingHuman = LK.getAsset('human', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
transformingHuman.x = 1024;
transformingHuman.y = 1400;
self.addChild(transformingHuman);
// Start button
var startButton = self.attachAsset('menuButton', {
anchorX: 0.5,
anchorY: 0.5
});
startButton.x = 1024;
startButton.y = 2200;
var startButtonText = new Text2('START TRANSFORMATION', {
size: 35,
fill: 0xFFFFFF
});
startButtonText.anchor.set(0.5, 0.5);
startButtonText.x = 1024;
startButtonText.y = 2200;
self.addChild(startButtonText);
// Dialog system
var dialogs = [new Dialog("A peaceful human walks by the river...", "human"), new Dialog("Suddenly, mysterious forces call from the waters!", "human"), new Dialog("The transformation begins! You feel the power of the Canadian Goose!", "goose"), new Dialog("HONK! You are now the leader of the great migration!", "goose")];
var currentDialogIndex = 0;
var currentDialog = null;
var scenePhase = 'menu'; // 'menu', 'story', 'game'
// Position dialogs
for (var i = 0; i < dialogs.length; i++) {
dialogs[i].x = 1024;
dialogs[i].y = 1000;
self.addChild(dialogs[i]);
}
self.startStoryScene = function () {
scenePhase = 'story';
// Hide menu elements
tween(titleText, {
alpha: 0
}, {
duration: 500
});
tween(subtitleText, {
alpha: 0
}, {
duration: 500
});
tween(startButton, {
alpha: 0
}, {
duration: 500
});
tween(startButtonText, {
alpha: 0
}, {
duration: 500
});
// Show first dialog
currentDialogIndex = 0;
currentDialog = dialogs[currentDialogIndex];
currentDialog.show();
};
self.nextDialog = function () {
if (currentDialog) {
currentDialog.hide();
}
currentDialogIndex++;
// Transformation effects
if (currentDialogIndex === 2) {
// Human jumps into river
tween(transformingHuman, {
y: 1500
}, {
duration: 1000,
onFinish: function onFinish() {
LK.getSound('splash').play();
LK.effects.flashScreen(0x4169e1, 500);
}
});
} else if (currentDialogIndex === 3) {
// Transform human to goose
LK.getSound('transformation').play();
tween(transformingHuman, {
tint: 0xf0f0f0,
scaleX: 2,
scaleY: 2,
y: 1400
}, {
duration: 1500,
onFinish: function onFinish() {
LK.getSound('honk').play();
}
});
}
if (currentDialogIndex < dialogs.length) {
currentDialog = dialogs[currentDialogIndex];
LK.setTimeout(function () {
currentDialog.show();
}, 1000);
} else {
// Story complete, start game
LK.setTimeout(function () {
self.startGame();
}, 2000);
}
};
self.startGame = function () {
scenePhase = 'game';
gameState = 'playing';
self.visible = false;
initializeGameplay();
};
// Handle clicks
self.down = function (x, y, obj) {
if (scenePhase === 'menu') {
// Check if start button clicked
var dx = x - startButton.x;
var dy = y - startButton.y;
if (Math.abs(dx) < 150 && Math.abs(dy) < 40) {
self.startStoryScene();
}
} else if (scenePhase === 'story') {
// Advance dialog
self.nextDialog();
}
};
return self;
});
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var obstacleGraphics = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x4a5d23
});
/****
* Game Code
****/
// Game state management
var gameState = 'menu'; // 'menu', 'playing'
var mainMenu = null;
var geese = [];
var humans = [];
var obstacles = [];
var leaderGoose = null;
var conversionRadius = 70;
var totalHumans = 20;
var convertedCount = 0;
var scoreText = null;
// Initialize main menu
mainMenu = game.addChild(new MainMenu());
// Human types for variety
var humanTypes = ['normal', 'athlete', 'child', 'elder'];
var gooseTypes = ['normal', 'speed', 'magnetic', 'honker'];
function initializeGameplay() {
// Create score display
scoreText = new Text2('Flock Size: 1', {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
// Create leader goose with special abilities
leaderGoose = game.addChild(new Goose('speed'));
leaderGoose.x = 1024;
leaderGoose.y = 1366;
leaderGoose.isLeader = true;
geese.push(leaderGoose);
// Create humans with different types scattered around the map
for (var i = 0; i < totalHumans; i++) {
var randomType = humanTypes[Math.floor(Math.random() * humanTypes.length)];
var human = game.addChild(new Human(randomType));
human.x = 200 + Math.random() * 1648;
human.y = 200 + Math.random() * 2332;
humans.push(human);
}
// Create some obstacles
for (var i = 0; i < 8; i++) {
var obstacle = game.addChild(new Obstacle());
obstacle.x = 300 + Math.random() * 1448;
obstacle.y = 300 + Math.random() * 2132;
obstacles.push(obstacle);
}
}
function updateFlockFormation() {
// Update follower positions to maintain formation
for (var i = 1; i < geese.length; i++) {
var goose = geese[i];
var targetGoose = geese[i - 1];
goose.followTarget = targetGoose;
goose.followDistance = 60 + i * 10; // Increasing distance for formation
}
}
function checkConversions() {
for (var i = humans.length - 1; i >= 0; i--) {
var human = humans[i];
if (human.isConverted) continue;
// Check distance to any goose in the flock
for (var j = 0; j < geese.length; j++) {
var goose = geese[j];
var dx = human.x - goose.x;
var dy = human.y - goose.y;
var distance = Math.sqrt(dx * dx + dy * dy);
var effectiveRadius = goose.conversionRadius || conversionRadius;
if (distance < effectiveRadius) {
if (human.convert()) {
convertedCount++;
// Create new goose with special type based on human type
var newGooseType = 'normal';
if (human.humanType === 'athlete') {
newGooseType = 'speed';
} else if (human.humanType === 'child') {
newGooseType = 'honker';
} else if (human.humanType === 'elder') {
newGooseType = 'magnetic';
}
var newGoose = game.addChild(new Goose(newGooseType));
newGoose.x = human.x;
newGoose.y = human.y;
geese.push(newGoose);
updateFlockFormation();
// Update score
if (scoreText) {
scoreText.setText('Flock Size: ' + geese.length);
}
// Increase conversion radius slightly with flock size
conversionRadius = 70 + geese.length * 2;
// Play honk sound occasionally
if (Math.random() < 0.3) {
LK.getSound('honk').play();
}
// Special transformation effects
if (newGooseType !== 'normal') {
LK.effects.flashObject(newGoose, 0xffd700, 1000);
}
// Check win condition
if (convertedCount >= totalHumans) {
LK.setTimeout(function () {
LK.showYouWin();
}, 1000);
}
break;
}
}
}
}
}
// Touch/mouse controls
game.move = function (x, y, obj) {
if (gameState === 'playing' && leaderGoose) {
leaderGoose.targetX = x;
leaderGoose.targetY = y;
}
};
game.down = function (x, y, obj) {
if (gameState === 'menu') {
// Handle menu interactions
if (mainMenu) {
mainMenu.down(x, y, obj);
}
} else if (gameState === 'playing') {
if (leaderGoose) {
leaderGoose.targetX = x;
leaderGoose.targetY = y;
// Check for special ability activation (double tap on leader)
var dx = x - leaderGoose.x;
var dy = y - leaderGoose.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 100) {
leaderGoose.activateAbility();
}
}
}
};
// Fast mode variables
var fastModeActive = false;
var fastModeTimer = 0;
var fastModeDuration = 3000; // 3 seconds
var fastModeCooldown = 0;
var fastModeCooldownDuration = 5000; // 5 seconds cooldown
var fastModeButton = new Text2('FAST MODE', {
size: 40,
fill: 0xFFFF00
});
fastModeButton.anchor.set(1, 0);
LK.gui.topRight.addChild(fastModeButton);
// Fast mode button interaction
fastModeButton.interactive = true;
fastModeButton.down = function () {
if (!fastModeActive && fastModeCooldown <= 0) {
activateFastMode();
}
};
function activateFastMode() {
fastModeActive = true;
fastModeTimer = fastModeDuration;
// Increase speed of all geese
for (var i = 0; i < geese.length; i++) {
geese[i].speed = geese[i].speed * 3;
tween(geese[i], {
tint: 0x00FFFF
}, {
duration: 200
});
}
// Visual feedback
tween(fastModeButton, {
tint: 0x808080
}, {
duration: 100
});
LK.effects.flashScreen(0x00FFFF, 300);
}
function deactivateFastMode() {
fastModeActive = false;
fastModeTimer = 0;
fastModeCooldown = fastModeCooldownDuration;
// Reset speed of all geese
for (var i = 0; i < geese.length; i++) {
geese[i].speed = geese[i].isLeader ? 3 : 3;
tween(geese[i], {
tint: 0xFFFFFF
}, {
duration: 500
});
}
// Reset button to show cooldown
tween(fastModeButton, {
tint: 0x808080
}, {
duration: 500
});
}
game.update = function () {
if (gameState === 'playing') {
checkConversions();
// Handle fast mode timer
if (fastModeActive) {
fastModeTimer -= 16.67; // ~60fps
if (fastModeTimer <= 0) {
deactivateFastMode();
}
}
// Handle fast mode cooldown
if (fastModeCooldown > 0) {
fastModeCooldown -= 16.67; // ~60fps
if (fastModeCooldown <= 0) {
// Reset button appearance when cooldown ends
tween(fastModeButton, {
tint: 0xFFFFFF
}, {
duration: 300
});
}
}
// Clean up fully faded humans
for (var i = humans.length - 1; i >= 0; i--) {
var human = humans[i];
if (human.isConverted && human.alpha <= 0) {
human.destroy();
humans.splice(i, 1);
}
}
}
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Dialog = Container.expand(function (text, characterType) {
var self = Container.call(this);
var dialogBackground = self.attachAsset('dialogBox', {
anchorX: 0.5,
anchorY: 0.5
});
dialogBackground.alpha = 0.8;
var dialogText = new Text2(text, {
size: 40,
fill: 0xFFFFFF,
wordWrap: true,
wordWrapWidth: 1700
});
dialogText.anchor.set(0.5, 0.5);
self.addChild(dialogText);
// Add character sprite based on type
var character = null;
if (characterType === 'human') {
character = LK.getAsset('human', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
character.x = -700;
character.y = -50;
} else if (characterType === 'goose') {
character = LK.getAsset('goose', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
character.x = -700;
character.y = -50;
}
if (character) {
self.addChild(character);
}
self.isVisible = false;
self.alpha = 0;
self.show = function () {
self.isVisible = true;
tween(self, {
alpha: 1
}, {
duration: 500
});
};
self.hide = function () {
self.isVisible = false;
tween(self, {
alpha: 0
}, {
duration: 500
});
};
return self;
});
var Goose = Container.expand(function (gooseType) {
var self = Container.call(this);
// Set goose type and abilities
self.gooseType = gooseType || 'normal';
var color = 0xf0f0f0; // Default white
self.speed = 3;
self.specialAbility = null;
self.abilityTimer = 0;
// Different goose types with special abilities
switch (self.gooseType) {
case 'speed':
color = 0x00ffff; // Cyan
self.speed = 5;
self.specialAbility = 'speedBoost';
break;
case 'magnetic':
color = 0xff69b4; // Hot pink
self.specialAbility = 'magneticPull';
break;
case 'honker':
color = 0xffd700; // Gold
self.specialAbility = 'massHonk';
break;
default:
break;
}
var gooseGraphics = self.attachAsset('goose', {
anchorX: 0.5,
anchorY: 0.5
});
gooseGraphics.tint = color;
self.targetX = self.x;
self.targetY = self.y;
self.isLeader = false;
self.followTarget = null;
self.followDistance = 80;
self.conversionRadius = 70;
self.update = function () {
if (self.isLeader) {
// Leader follows mouse/touch position
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;
}
} else if (self.followTarget) {
// Follower geese maintain formation
var dx = self.followTarget.x - self.x;
var dy = self.followTarget.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > self.followDistance) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
}
// Handle special abilities
if (self.specialAbility && self.abilityTimer > 0) {
self.abilityTimer--;
if (self.specialAbility === 'magneticPull') {
self.conversionRadius = 150;
}
}
};
self.activateAbility = function () {
if (self.specialAbility) {
self.abilityTimer = 300; // 5 seconds at 60fps
switch (self.specialAbility) {
case 'speedBoost':
self.speed = 8;
tween(gooseGraphics, {
tint: 0x00ff00
}, {
duration: 200
});
LK.setTimeout(function () {
self.speed = 5;
tween(gooseGraphics, {
tint: color
}, {
duration: 500
});
}, 5000);
break;
case 'massHonk':
LK.getSound('honk').play();
LK.effects.flashScreen(0xffd700, 300);
break;
}
}
};
return self;
});
var Human = Container.expand(function (humanType) {
var self = Container.call(this);
// Set human type and properties
self.humanType = humanType || 'normal';
var color = 0x8b4513; // Default brown
var size = 1;
// Different human types with special properties
switch (self.humanType) {
case 'athlete':
color = 0xff6347; // Red
self.speed = 2;
size = 1.2;
break;
case 'child':
color = 0xffd700; // Gold
self.speed = 0.5;
size = 0.8;
break;
case 'elder':
color = 0x708090; // Slate gray
self.speed = 0.3;
size = 0.9;
break;
default:
self.speed = 1;
break;
}
var humanGraphics = self.attachAsset('human', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: size,
scaleY: size
});
humanGraphics.tint = color;
self.isConverted = false;
self.wanderTimer = 0;
self.wanderDirection = Math.random() * Math.PI * 2;
self.update = function () {
if (!self.isConverted) {
// Random wandering behavior
self.wanderTimer++;
if (self.wanderTimer > 120) {
// Change direction every 2 seconds
self.wanderDirection = Math.random() * Math.PI * 2;
self.wanderTimer = 0;
}
self.x += Math.cos(self.wanderDirection) * self.speed;
self.y += Math.sin(self.wanderDirection) * self.speed;
// Keep humans within bounds
if (self.x < 100) self.x = 100;
if (self.x > 1948) self.x = 1948;
if (self.y < 100) self.y = 100;
if (self.y > 2632) self.y = 2632;
}
};
self.convert = function () {
if (!self.isConverted) {
self.isConverted = true;
humanGraphics.tint = 0x808080; // Gray out converted human
tween(humanGraphics, {
alpha: 0
}, {
duration: 500
});
LK.getSound('convert').play();
return true;
}
return false;
};
return self;
});
var MainMenu = Container.expand(function () {
var self = Container.call(this);
// Title
var titleText = new Text2('GOOSE INVASION', {
size: 80,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 300;
self.addChild(titleText);
var subtitleText = new Text2('The Great Migration', {
size: 50,
fill: 0xCCCCCC
});
subtitleText.anchor.set(0.5, 0.5);
subtitleText.x = 1024;
subtitleText.y = 400;
self.addChild(subtitleText);
// River scene
var river = self.attachAsset('river', {
anchorX: 0.5,
anchorY: 0.5
});
river.x = 1024;
river.y = 1500;
// Human character that will transform
var transformingHuman = LK.getAsset('human', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
transformingHuman.x = 1024;
transformingHuman.y = 1400;
self.addChild(transformingHuman);
// Start button
var startButton = self.attachAsset('menuButton', {
anchorX: 0.5,
anchorY: 0.5
});
startButton.x = 1024;
startButton.y = 2200;
var startButtonText = new Text2('START TRANSFORMATION', {
size: 35,
fill: 0xFFFFFF
});
startButtonText.anchor.set(0.5, 0.5);
startButtonText.x = 1024;
startButtonText.y = 2200;
self.addChild(startButtonText);
// Dialog system
var dialogs = [new Dialog("A peaceful human walks by the river...", "human"), new Dialog("Suddenly, mysterious forces call from the waters!", "human"), new Dialog("The transformation begins! You feel the power of the Canadian Goose!", "goose"), new Dialog("HONK! You are now the leader of the great migration!", "goose")];
var currentDialogIndex = 0;
var currentDialog = null;
var scenePhase = 'menu'; // 'menu', 'story', 'game'
// Position dialogs
for (var i = 0; i < dialogs.length; i++) {
dialogs[i].x = 1024;
dialogs[i].y = 1000;
self.addChild(dialogs[i]);
}
self.startStoryScene = function () {
scenePhase = 'story';
// Hide menu elements
tween(titleText, {
alpha: 0
}, {
duration: 500
});
tween(subtitleText, {
alpha: 0
}, {
duration: 500
});
tween(startButton, {
alpha: 0
}, {
duration: 500
});
tween(startButtonText, {
alpha: 0
}, {
duration: 500
});
// Show first dialog
currentDialogIndex = 0;
currentDialog = dialogs[currentDialogIndex];
currentDialog.show();
};
self.nextDialog = function () {
if (currentDialog) {
currentDialog.hide();
}
currentDialogIndex++;
// Transformation effects
if (currentDialogIndex === 2) {
// Human jumps into river
tween(transformingHuman, {
y: 1500
}, {
duration: 1000,
onFinish: function onFinish() {
LK.getSound('splash').play();
LK.effects.flashScreen(0x4169e1, 500);
}
});
} else if (currentDialogIndex === 3) {
// Transform human to goose
LK.getSound('transformation').play();
tween(transformingHuman, {
tint: 0xf0f0f0,
scaleX: 2,
scaleY: 2,
y: 1400
}, {
duration: 1500,
onFinish: function onFinish() {
LK.getSound('honk').play();
}
});
}
if (currentDialogIndex < dialogs.length) {
currentDialog = dialogs[currentDialogIndex];
LK.setTimeout(function () {
currentDialog.show();
}, 1000);
} else {
// Story complete, start game
LK.setTimeout(function () {
self.startGame();
}, 2000);
}
};
self.startGame = function () {
scenePhase = 'game';
gameState = 'playing';
self.visible = false;
initializeGameplay();
};
// Handle clicks
self.down = function (x, y, obj) {
if (scenePhase === 'menu') {
// Check if start button clicked
var dx = x - startButton.x;
var dy = y - startButton.y;
if (Math.abs(dx) < 150 && Math.abs(dy) < 40) {
self.startStoryScene();
}
} else if (scenePhase === 'story') {
// Advance dialog
self.nextDialog();
}
};
return self;
});
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var obstacleGraphics = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x4a5d23
});
/****
* Game Code
****/
// Game state management
var gameState = 'menu'; // 'menu', 'playing'
var mainMenu = null;
var geese = [];
var humans = [];
var obstacles = [];
var leaderGoose = null;
var conversionRadius = 70;
var totalHumans = 20;
var convertedCount = 0;
var scoreText = null;
// Initialize main menu
mainMenu = game.addChild(new MainMenu());
// Human types for variety
var humanTypes = ['normal', 'athlete', 'child', 'elder'];
var gooseTypes = ['normal', 'speed', 'magnetic', 'honker'];
function initializeGameplay() {
// Create score display
scoreText = new Text2('Flock Size: 1', {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
// Create leader goose with special abilities
leaderGoose = game.addChild(new Goose('speed'));
leaderGoose.x = 1024;
leaderGoose.y = 1366;
leaderGoose.isLeader = true;
geese.push(leaderGoose);
// Create humans with different types scattered around the map
for (var i = 0; i < totalHumans; i++) {
var randomType = humanTypes[Math.floor(Math.random() * humanTypes.length)];
var human = game.addChild(new Human(randomType));
human.x = 200 + Math.random() * 1648;
human.y = 200 + Math.random() * 2332;
humans.push(human);
}
// Create some obstacles
for (var i = 0; i < 8; i++) {
var obstacle = game.addChild(new Obstacle());
obstacle.x = 300 + Math.random() * 1448;
obstacle.y = 300 + Math.random() * 2132;
obstacles.push(obstacle);
}
}
function updateFlockFormation() {
// Update follower positions to maintain formation
for (var i = 1; i < geese.length; i++) {
var goose = geese[i];
var targetGoose = geese[i - 1];
goose.followTarget = targetGoose;
goose.followDistance = 60 + i * 10; // Increasing distance for formation
}
}
function checkConversions() {
for (var i = humans.length - 1; i >= 0; i--) {
var human = humans[i];
if (human.isConverted) continue;
// Check distance to any goose in the flock
for (var j = 0; j < geese.length; j++) {
var goose = geese[j];
var dx = human.x - goose.x;
var dy = human.y - goose.y;
var distance = Math.sqrt(dx * dx + dy * dy);
var effectiveRadius = goose.conversionRadius || conversionRadius;
if (distance < effectiveRadius) {
if (human.convert()) {
convertedCount++;
// Create new goose with special type based on human type
var newGooseType = 'normal';
if (human.humanType === 'athlete') {
newGooseType = 'speed';
} else if (human.humanType === 'child') {
newGooseType = 'honker';
} else if (human.humanType === 'elder') {
newGooseType = 'magnetic';
}
var newGoose = game.addChild(new Goose(newGooseType));
newGoose.x = human.x;
newGoose.y = human.y;
geese.push(newGoose);
updateFlockFormation();
// Update score
if (scoreText) {
scoreText.setText('Flock Size: ' + geese.length);
}
// Increase conversion radius slightly with flock size
conversionRadius = 70 + geese.length * 2;
// Play honk sound occasionally
if (Math.random() < 0.3) {
LK.getSound('honk').play();
}
// Special transformation effects
if (newGooseType !== 'normal') {
LK.effects.flashObject(newGoose, 0xffd700, 1000);
}
// Check win condition
if (convertedCount >= totalHumans) {
LK.setTimeout(function () {
LK.showYouWin();
}, 1000);
}
break;
}
}
}
}
}
// Touch/mouse controls
game.move = function (x, y, obj) {
if (gameState === 'playing' && leaderGoose) {
leaderGoose.targetX = x;
leaderGoose.targetY = y;
}
};
game.down = function (x, y, obj) {
if (gameState === 'menu') {
// Handle menu interactions
if (mainMenu) {
mainMenu.down(x, y, obj);
}
} else if (gameState === 'playing') {
if (leaderGoose) {
leaderGoose.targetX = x;
leaderGoose.targetY = y;
// Check for special ability activation (double tap on leader)
var dx = x - leaderGoose.x;
var dy = y - leaderGoose.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 100) {
leaderGoose.activateAbility();
}
}
}
};
// Fast mode variables
var fastModeActive = false;
var fastModeTimer = 0;
var fastModeDuration = 3000; // 3 seconds
var fastModeCooldown = 0;
var fastModeCooldownDuration = 5000; // 5 seconds cooldown
var fastModeButton = new Text2('FAST MODE', {
size: 40,
fill: 0xFFFF00
});
fastModeButton.anchor.set(1, 0);
LK.gui.topRight.addChild(fastModeButton);
// Fast mode button interaction
fastModeButton.interactive = true;
fastModeButton.down = function () {
if (!fastModeActive && fastModeCooldown <= 0) {
activateFastMode();
}
};
function activateFastMode() {
fastModeActive = true;
fastModeTimer = fastModeDuration;
// Increase speed of all geese
for (var i = 0; i < geese.length; i++) {
geese[i].speed = geese[i].speed * 3;
tween(geese[i], {
tint: 0x00FFFF
}, {
duration: 200
});
}
// Visual feedback
tween(fastModeButton, {
tint: 0x808080
}, {
duration: 100
});
LK.effects.flashScreen(0x00FFFF, 300);
}
function deactivateFastMode() {
fastModeActive = false;
fastModeTimer = 0;
fastModeCooldown = fastModeCooldownDuration;
// Reset speed of all geese
for (var i = 0; i < geese.length; i++) {
geese[i].speed = geese[i].isLeader ? 3 : 3;
tween(geese[i], {
tint: 0xFFFFFF
}, {
duration: 500
});
}
// Reset button to show cooldown
tween(fastModeButton, {
tint: 0x808080
}, {
duration: 500
});
}
game.update = function () {
if (gameState === 'playing') {
checkConversions();
// Handle fast mode timer
if (fastModeActive) {
fastModeTimer -= 16.67; // ~60fps
if (fastModeTimer <= 0) {
deactivateFastMode();
}
}
// Handle fast mode cooldown
if (fastModeCooldown > 0) {
fastModeCooldown -= 16.67; // ~60fps
if (fastModeCooldown <= 0) {
// Reset button appearance when cooldown ends
tween(fastModeButton, {
tint: 0xFFFFFF
}, {
duration: 300
});
}
}
// Clean up fully faded humans
for (var i = humans.length - 1; i >= 0; i--) {
var human = humans[i];
if (human.isConverted && human.alpha <= 0) {
human.destroy();
humans.splice(i, 1);
}
}
}
};
a Canadian Goose no text on image!
water texture in full image. In-Game asset. 2d. High contrast. No shadows
Box. In-Game asset. 2d. High contrast. No shadows
Canadian Geese Style Menu button. In-Game asset. 2d. High contrast. No shadows no text on image!. In-Game asset. 2d. High contrast. No shadows
dialog box button with canadian geese style no text on image!. In-Game asset. 2d. High contrast. No shadows
human. In-Game asset. 2d. High contrast. No shadows