User prompt
Please fix the bug: 'LayerManager is not defined' in or related to this line: 'var layerManager = new LayerManager();' Line Number: 704
Code edit (1 edits merged)
Please save this source code
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'length')' in or related to this line: 'this.graphics = this.attachAsset(assetName, Object.assign({' Line Number: 52
User prompt
Please fix the bug: 'LayerManager is not defined' in or related to this line: 'var layerManager = new LayerManager();' Line Number: 707
Code edit (1 edits merged)
Please save this source code
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'length')' in or related to this line: 'this.graphics = this.attachAsset(assetName, Object.assign({' Line Number: 52
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'length')' in or related to this line: 'this.graphics = this.attachAsset(assetName, Object.assign({' Line Number: 52
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'length')' in or related to this line: 'this.graphics = this.attachAsset(assetName, Object.assign({' Line Number: 52
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'length')' in or related to this line: 'this.graphics = this.attachAsset(assetName, Object.assign({' Line Number: 52
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'length')' in or related to this line: 'this.graphics = this.attachAsset(assetName, Object.assign({' Line Number: 52
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'length')' in or related to this line: 'this.graphics = this.attachAsset(assetName, Object.assign({' Line Number: 53
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'length')' in or related to this line: 'this.graphics = this.attachAsset(assetName, Object.assign({' Line Number: 52
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'length')' in or related to this line: 'this.graphics = this.attachAsset(assetName, Object.assign({' Line Number: 52
User prompt
Please fix the bug: 'LayerManager is not defined' in or related to this line: 'var layerManager = new LayerManager();' Line Number: 707
Code edit (1 edits merged)
Please save this source code
User prompt
Please fix the bug: '_SpawnManager is not a constructor' in or related to this line: 'var spawnManager = new _SpawnManager();' Line Number: 798
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'length')' in or related to this line: 'this.graphics = this.attachAsset(assetName, Object.assign({' Line Number: 52
User prompt
Please fix the bug: 'LayerManager is not defined' in or related to this line: 'var layerManager = new LayerManager();' Line Number: 707
Code edit (1 edits merged)
Please save this source code
User prompt
Please fix the bug: 'Timeout.tick error: totalClouds is not defined' in or related to this line: 'if (totalClouds > 5) {' Line Number: 1963
User prompt
Please fix the bug: 'Timeout.tick error: totalClouds is not defined' in or related to this line: 'if (totalClouds > 5) {' Line Number: 1963
User prompt
Please fix the bug: 'TypeError: self.movement.update is not a function' in or related to this line: 'self.movement.update();' Line Number: 86
User prompt
Please fix the bug: 'TypeError: self.movement.update is not a function' in or related to this line: 'self.movement.update();' Line Number: 86
User prompt
Please fix the bug: 'TypeError: self.movement.update is not a function' in or related to this line: 'self.movement.update();' Line Number: 86
User prompt
Please fix the bug: 'jet is not defined' in or related to this line: 'if (jet) {' Line Number: 3041
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var GameObject = Container.expand(function (assetName, layerIndex, options) {
var self = Container.call(this);
Container.call(this);
options = options || {};
this.graphics = this.attachAsset(assetName, Object.assign({
anchorX: 0.5,
anchorY: 0.5
}, options));
this.addChild(this.graphics);
// Common destroy method
var originalDestroy = this.destroy;
this.destroy = function () {
if (game.layerManager) {
game.layerManager.removeFromTracking(this);
}
if (this.movement && this.movement.cleanup) {
this.movement.cleanup();
}
originalDestroy.call(this);
};
// Common update method
this.update = function () {
if (this.movement) {
this.movement.update();
}
};
if (layerIndex !== undefined) {
game.layerManager.addToLayer(this, layerIndex);
}
return this;
});
var UFO2 = GameObject.expand(function () {
var self = GameObject.call(this);
GameObject.call(this, 'ufo2', LAYERS.UFO2);
this.type = 'ufo2';
this.movement = new GameObjectMovement(this, this.graphics, MovementConfigs.ufo2);
var originalUpdate = this.update;
this.update = function () {
originalUpdate.call(this);
if (!this.soundPlayed && this.x > 0 && this.x < 2048) {
LK.getSound('ufo1').play();
this.soundPlayed = true;
}
};
return this;
});
var UFO1 = GameObject.expand(function () {
var self = GameObject.call(this);
GameObject.call(this, 'ufo1', LAYERS.UFO1);
this.type = 'ufo1';
this.movement = new GameObjectMovement(this, this.graphics, MovementConfigs.ufo1);
var originalUpdate = this.update;
this.update = function () {
originalUpdate.call(this);
if (!this.soundPlayed && this.x > 0 && this.x < 2048) {
LK.getSound('ufo1').play();
this.soundPlayed = true;
}
};
return this;
});
var Tree2 = GameObject.expand(function () {
var self = GameObject.call(this);
return GameObject.call(this, 'tree2', LAYERS.TREE, {
anchorX: 0.5,
anchorY: 1
});
});
var Tree = GameObject.expand(function () {
var self = GameObject.call(this, 'tree1', LAYERS.TREE, {
anchorX: 0.5,
anchorY: 1,
antialias: true,
stroke: 0x000000,
strokeThickness: 15
});
return self;
});
var Sun = GameObject.expand(function () {
var self = GameObject.call(this);
GameObject.call(this, 'sun', LAYERS.SUN);
this.pulse = new SunPulse(this.graphics);
this.pulse.startPulsating();
return this;
});
var Stack1 = GameObject.expand(function () {
var self = GameObject.call(this);
GameObject.call(this, 'stack1', LAYERS.STACK, {
anchorX: 0.5,
anchorY: 0.5,
rotation: Math.PI / -12
});
return this;
});
var Reticle = GameObject.expand(function () {
var self = GameObject.call(this);
GameObject.call(this, 'reticle1', LAYERS.RETICLE);
var originalUpdate = this.update;
this.update = function () {
if (!this.pulse) {
this.pulse = new ReticlePulse(this.graphics);
this.pulse.startPulsating();
}
originalUpdate.call(this);
};
return this;
});
var Mirror = GameObject.expand(function () {
var self = GameObject.call(this);
GameObject.call(this, 'mirror1', LAYERS.MIRROR);
var scoreText = new Text2('0', {
size: 175,
fill: 0x800080,
font: "Courier New, Courier, monospace",
stroke: 0x00FF00,
strokeThickness: 15,
dropShadow: true,
dropShadowColor: 0x000000,
dropShadowBlur: 5,
dropShadowAngle: Math.PI / 6,
dropShadowDistance: 6
});
scoreText.y = 260 + 50;
scoreText.x = -155;
scoreText.rotation = (-83 - 3) * (Math.PI / 180);
this.addChild(scoreText);
this.updateScore = function (newScore) {
scoreText.setText(newScore);
};
return this;
});
var Light1 = GameObject.expand(function () {
var self = GameObject.call(this);
GameObject.call(this, 'light1', LAYERS.LIGHT1, {
anchorX: 0.5,
anchorY: 0.5,
alpha: 1.0
});
this.x = 450;
this.y = 450;
this.update = function () {
this.x += Math.sin(LK.ticks / 90) * 0.1;
};
this.pulse = new Light1Pulse(this.graphics);
this.pulse.startPulsating();
return this;
});
var Jet1 = GameObject.expand(function () {
var self = GameObject.call(this);
GameObject.call(this, 'jet1', LAYERS.JET1);
this.type = 'jet1';
this.movement = new GameObjectMovement(this, this.graphics, {
speed: 10,
speedRange: 0,
arcAmplitude: 0,
arcFrequency: 0,
isVertical: false,
canFlip: true,
moveSound: 'jet1'
});
this.soundPlayed = false;
var originalUpdate = this.update;
this.update = function () {
originalUpdate.call(this);
// Play jet1 sound when on screen
if (!this.soundPlayed && this.x > 0 && this.x < 2048) {
LK.getSound('jet1').play();
this.soundPlayed = true;
}
};
return this;
});
var GrassFront = GameObject.expand(function () {
var self = GameObject.call(this);
GameObject.call(this, 'grass-front', LAYERS.GRASS_FRONT, {
anchorX: 0.5,
anchorY: 1
});
this.lastX = this.x;
this.update = function () {
this.x += Math.sin((LK.ticks + 50) / 100) * 0.125; // Swaying effect, reduced by 50%
this.lastX = this.x;
};
return this;
});
var GrassBack = GameObject.expand(function () {
var self = GameObject.call(this);
GameObject.call(this, 'grass-back', LAYERS.GRASS_BACK, {
anchorX: 0.5,
anchorY: 1
});
this.update = function () {
this.x += Math.sin((LK.ticks + 100) / 90) * 0.15; // Swaying effect, increased speed
};
return this;
});
var Cloud = GameObject.expand(function () {
var self = GameObject.call(this);
var cloudType = CLOUD_TYPES[Math.floor(Math.random() * CLOUD_TYPES.length)];
var layerIndex = cloudType === 'cloud1' ? LAYERS.CLOUD1 : LAYERS.CLOUD2;
GameObject.call(this, cloudType, layerIndex, {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.8
});
this.cloudType = cloudType;
this.movement = new CloudMovement(this, this.graphics);
var originalDestroy = this.destroy;
this.destroy = function () {
if (spawnManager) {
spawnManager.objectCounts[this.cloudType === 'cloud1' ? 'cloud1' : 'cloud2']--;
}
originalDestroy.call(this);
};
return this;
});
var Cat = GameObject.expand(function () {
var self = GameObject.call(this);
GameObject.call(this, 'cat', LAYERS.CAT, {
anchorX: 0.5,
anchorY: 1
});
return this;
});
// Define cloud types at the beginning
var Bird2 = GameObject.expand(function () {
var self = GameObject.call(this);
GameObject.call(this, 'bird2', LAYERS.BIRD2);
this.type = 'bird2';
this.movement = new GameObjectMovement(this, this.graphics, MovementConfigs.bird2);
return this;
});
var Bird1 = GameObject.expand(function () {
var self = GameObject.call(this);
GameObject.call(this, 'bird1', LAYERS.BIRD1);
this.type = 'bird1';
this.movement = new GameObjectMovement(this, this.graphics, MovementConfigs.bird1);
return this;
});
var Background = GameObject.expand(function () {
var self = GameObject.call(this);
return GameObject.call(this, 'background', LAYERS.BACKGROUND);
});
var Laser = Container.expand(function (startX, startY, targetX, targetY) {
var self = Container.call(this);
var laserGraphics = self.attachAsset('laser2', {
anchorX: 0.5,
anchorY: 0.5,
brightness: 2.0
});
LK.getSound('laser1').play();
var dx = targetX - startX;
var dy = targetY - startY;
var distance = Math.sqrt(dx * dx + dy * dy);
var speed = 60;
self.vx = dx / distance * speed;
self.vy = dy / distance * speed;
self.x = startX;
self.y = startY;
self.lastIntersecting = false;
self.active = true;
var originalDestroy = self.destroy;
self.destroy = function () {
if (game.layerManager) {
game.layerManager.removeFromTracking(self);
}
originalDestroy.call(self);
};
self.update = function () {
if (!self.active) {
return;
}
// Move first
self.x += self.vx;
self.y += self.vy;
// Check collisions only with relevant layers
var targetLayers = [LAYERS.BIRD1, LAYERS.BIRD2, LAYERS.UFO1, LAYERS.UFO2];
var collided = false;
for (var i = 0; i < targetLayers.length && !collided; i++) {
var targets = game.layerManager.getLayerObjects(targetLayers[i]);
for (var j = 0; j < targets.length && !collided; j++) {
var target = targets[j];
if (!self.lastIntersecting && self.intersects(target)) {
var soundEffect = target instanceof UFO1 || target instanceof UFO2 ? 'dead3' : 'dead2';
LK.getSound(soundEffect).play();
// Update score based on target type
var scoreValue = 0;
if (target instanceof Bird1) {
scoreValue = 5;
} else if (target instanceof Bird2) {
scoreValue = 1;
} else if (target instanceof UFO1 || target instanceof UFO2) {
scoreValue = 25;
}
score += scoreValue;
if (game.mirror) {
game.mirror.updateScore(score);
}
target.destroy();
collided = true;
}
}
}
// Update intersection state
self.lastIntersecting = collided;
// Destroy if out of bounds
if (self.x < 0 || self.x > 2048 || self.y < 0 || self.y > 2732) {
self.destroy();
}
};
return self;
});
/****
* Initialize Game
****/
// BaseEntityManager removed - using EntityManager defined at the beginning of the file
// Initialize clouds array
var game = new LK.Game({
// No title, no description
backgroundColor: 0x87CEEB // Sky blue
});
/****
* Game Code
****/
// Base GameObject class to handle common functionality
// CloudMovement class to handle cloud movement and fade effects
// Unified GameObjectMovement class with improved movement patterns and sound management
function _typeof2(o) {
"@babel/helpers - typeof";
return _typeof2 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
return typeof o;
} : function (o) {
return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
}, _typeof2(o);
}
function _createForOfIteratorHelper(r, e) {
var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
if (!t) {
if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) {
t && (r = t);
var _n = 0,
F = function F() {};
return {
s: F,
n: function n() {
return _n >= r.length ? {
done: !0
} : {
done: !1,
value: r[_n++]
};
},
e: function e(r) {
throw r;
},
f: F
};
}
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
var o,
a = !0,
u = !1;
return {
s: function s() {
t = t.call(r);
},
n: function n() {
var r = t.next();
return a = r.done, r;
},
e: function e(r) {
u = !0, o = r;
},
f: function f() {
try {
a || null == t["return"] || t["return"]();
} finally {
if (u) {
throw o;
}
}
}
};
}
function _unsupportedIterableToArray(r, a) {
if (r) {
if ("string" == typeof r) {
return _arrayLikeToArray(r, a);
}
var t = {}.toString.call(r).slice(8, -1);
return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
}
}
function _arrayLikeToArray(r, a) {
(null == a || a > r.length) && (a = r.length);
for (var e = 0, n = Array(a); e < a; e++) {
n[e] = r[e];
}
return n;
}
function _classCallCheck2(a, n) {
if (!(a instanceof n)) {
throw new TypeError("Cannot call a class as a function");
}
}
function __defineProperties(e, r) {
for (var t = 0; t < r.length; t++) {
var o = r[t];
o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey2(o.key), o);
}
}
function _createClass2(e, r, t) {
return r && __defineProperties(e.prototype, r), t && __defineProperties(e, t), Object.defineProperty(e, "prototype", {
writable: !1
}), e;
}
function _toPropertyKey2(t) {
var i = _toPrimitive2(t, "string");
return "symbol" == _typeof2(i) ? i : i + "";
}
function _toPrimitive2(t, r) {
if ("object" != _typeof2(t) || !t) {
return t;
}
var e = t[Symbol.toPrimitive];
if (void 0 !== e) {
var i = e.call(t, r || "default");
if ("object" != _typeof2(i)) {
return i;
}
throw new TypeError("@@toPrimitive must return a primitive value.");
}
return ("string" === r ? String : Number)(t);
}
var EntityManager = /*#__PURE__*/function () {
function EntityManager() {
_classCallCheck2(this, EntityManager);
this.entities = [];
}
return _createClass2(EntityManager, [{
key: "add",
value: function add(entity) {
this.entities.push(entity);
if (game.layerManager && entity.layer !== undefined) {
game.layerManager.addToLayer(entity, entity.layer);
}
}
}, {
key: "remove",
value: function remove(entity) {
var index = this.entities.indexOf(entity);
if (index > -1) {
this.entities.splice(index, 1);
entity.destroy();
}
}
}, {
key: "update",
value: function update(deltaTime) {
var _iterator = _createForOfIteratorHelper(this.entities),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var entity = _step.value;
if (entity.update) {
entity.update(deltaTime);
}
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
}
}, {
key: "getAllOfType",
value: function getAllOfType(type) {
return this.entities.filter(function (entity) {
return entity instanceof type;
});
}
}, {
key: "clear",
value: function clear() {
this.entities.forEach(function (entity) {
return entity.destroy();
});
this.entities = [];
}
}]);
}(); // Define cloud types at the beginning
var CLOUD_TYPES = ['cloud1', 'cloud2'];
function respawnJet() {
if (game.jet === null) {
var jet = new Jet1();
jet.x = Math.random() < 0.5 ? 2048 + jet.width / 2 : -jet.width / 2;
jet.y = Math.random() * (2732 / 2);
game.addChild(jet);
game.layerManager.addToLayer(jet, LAYERS.JET1);
game.jet = jet;
}
game.jetSpawnTimer = null;
}
var GameObjectMovement = function GameObjectMovement(object, graphics, options) {
;
this.object = object;
this.graphics = graphics;
this.options = Object.assign({
speed: 2,
speedRange: 1.2,
arcAmplitude: 6.5,
arcFrequency: 100,
isVertical: false,
canFlip: true,
moveSound: null,
respawnTime: {
min: 20000,
max: 30000
},
screenWidth: 2048,
screenHeight: 2732
}, options);
this.speed = this.options.speed + Math.random() * this.options.speedRange;
this.direction = Math.random() < 0.5 ? 1 : -1;
this.lastX = this.object.x;
this.lastY = this.object.y;
this.soundPlayed = false;
this.soundTimer = null;
this.movementOffset = Math.random() * Math.PI * 2; // Random starting phase for smoother movement
this.update = function () {
var currentX = this.object.x;
var currentY = this.object.y;
var halfWidth = this.object.width / 2;
if (this.options.isVertical) {
this.object.y += this.speed;
// Improved sinusoidal movement with phase offset for smoother motion
this.object.x += Math.sin(this.object.y / this.options.arcFrequency + this.movementOffset) * this.options.arcAmplitude;
if (currentY > this.options.screenHeight + this.object.height) {
this.cleanup();
return;
}
} else {
// Improved horizontal movement with optional wave pattern
this.object.x += this.speed * this.direction;
if (this.options.arcAmplitude > 0) {
this.object.y += Math.sin(this.object.x / this.options.arcFrequency + this.movementOffset) * (this.options.arcAmplitude * 0.5);
}
if (currentX <= this.options.screenWidth + halfWidth && this.object.x > this.options.screenWidth + halfWidth || currentX >= -halfWidth && this.object.x < -halfWidth) {
this.cleanup();
return;
}
}
if (this.options.canFlip) {
flipImageVerticallyBasedOnDirection(this.graphics, currentX, this.object.x);
}
if (this.options.moveSound && !this.soundPlayed && this.object.x > 0 && this.object.x < this.options.screenWidth) {
this.playMovementSound();
}
this.lastX = this.object.x;
this.lastY = this.object.y;
}.bind(this);
this.cleanup = function () {
if (this.soundTimer) {
LK.clearTimeout(this.soundTimer);
this.soundTimer = null;
}
if (this.object && !this.object.destroyed) {
this.object.destroy();
if (spawnManager) {
spawnManager.scheduleRespawn(this.object.type, this.object.constructor);
}
}
};
this.playMovementSound = function () {
if (this.soundTimer) {
LK.clearTimeout(this.soundTimer);
}
var sound = LK.getSound(this.options.moveSound);
sound.volume = 0.1;
sound.play();
this.soundPlayed = true;
this.soundTimer = LK.setTimeout(function () {
this.soundPlayed = false;
this.soundTimer = null;
}.bind(this), Math.random() * (30000 - 20000) + 20000);
};
};
// Cloud class already defined above
function _typeof(o) {
"@babel/helpers - typeof";
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
return typeof o;
} : function (o) {
return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
}, _typeof(o);
}
function _classCallCheck(a, n) {
if (!(a instanceof n)) {
throw new TypeError("Cannot call a class as a function");
}
}
function _defineProperties(e, r) {
for (var t = 0; t < r.length; t++) {
var o = r[t];
o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o);
}
}
function _createClass(e, r, t) {
return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", {
writable: !1
}), e;
}
function _toPropertyKey(t) {
var i = _toPrimitive(t, "string");
return "symbol" == _typeof(i) ? i : i + "";
}
function _toPrimitive(t, r) {
if ("object" != _typeof(t) || !t) {
return t;
}
var e = t[Symbol.toPrimitive];
if (void 0 !== e) {
var i = e.call(t, r || "default");
if ("object" != _typeof(i)) {
return i;
}
throw new TypeError("@@toPrimitive must return a primitive value.");
}
return ("string" === r ? String : Number)(t);
}
/*****
* Layer Constants
******/
var LAYERS = {
BACKGROUND: 0,
SUN: 1,
LIGHT1: 2,
UFO2: 3,
CLOUD1: 4,
JET1: 5,
CLOUD2: 6,
UFO1: 7,
BIRD1: 8,
GRASS_BACK: 9,
TREE: 10,
STACK: 11,
BIRD2: 12,
MIRROR: 13,
GRASS_FRONT: 14,
CAT: 15,
LASER: 16,
RETICLE: 17
};
// Initialize LayerManager
var layerManager = new LayerManager();
game.layerManager = layerManager;
// Cloud management is now handled by SpawnManager
// Initialize birds array for tracking
var birds = [];
var score = 0;
var mirror = new Mirror();
mirror.x = 2048 / 2 + 400;
mirror.y = 2732 - 185 - 80 - 390 + 30 + 50;
game.addChild(mirror);
game.mirror = mirror;
var scoreDisplay = mirror;
var SoundManager = function SoundManager() {
this.soundTimers = {};
this.soundIntervals = {
ambient: {
min: 20000,
max: 30000
},
background: {
min: 20000,
max: 30000
},
ufo: {
min: 20000,
max: 30000
},
jet: {
min: 20000,
max: 30000
}
};
this.playSound = function (soundId, options) {
options = Object.assign({
interval: this.soundIntervals.ambient,
isMusic: false,
volume: 0.1,
loop: false,
autoRestart: true
}, options);
var playFunction = function () {
if (options.isMusic) {
LK.playMusic(soundId, {
volume: options.volume
});
} else {
var sound = LK.getSound(soundId);
sound.volume = options.volume;
if (options.loop) {
sound.loop = true;
}
sound.play();
}
if (options.autoRestart) {
var nextInterval = Math.random() * (options.interval.max - options.interval.min) + options.interval.min;
this.soundTimers[soundId] = LK.setTimeout(playFunction.bind(this), nextInterval);
}
}.bind(this);
playFunction();
return this.soundTimers[soundId];
};
// Start the game
var spawnManager = new _SpawnManager();
spawnManager.initialize();
this.initialize = function () {
var _this = this;
// Initialize ambient sounds with optimized intervals
var ambientSounds = [{
id: 'songbird1',
volume: 0.1
}, {
id: 'cricket1',
volume: 0.1
}, {
id: 'breeze1',
volume: 0.1
}, {
id: 'frog1',
volume: 0.1
}, {
id: 'chitter',
volume: 0.1
}];
// Stagger ambient sound starts for better distribution
ambientSounds.forEach(function (sound, index) {
LK.setTimeout(function () {
_this.playSound(sound.id, {
volume: sound.volume
});
}, index * 2000);
});
// Initialize background music
this.playSound('bgm1', {
isMusic: true,
volume: 0.1,
interval: this.soundIntervals.background
});
};
this.stopSound = function (soundId) {
if (this.soundTimers[soundId]) {
LK.clearTimeout(this.soundTimers[soundId]);
delete this.soundTimers[soundId];
}
LK.getSound(soundId).stop();
};
this.stopAllSounds = function () {
for (var soundId in this.soundTimers) {
this.stopSound(soundId);
}
};
};
// Bird spawning is now handled by SpawnManager
var soundManager = new SoundManager();
soundManager.initialize();
// Initialize spawn manager
var _SpawnManager = function SpawnManager() {
this.spawnTimers = {};
this.objectCounts = {
bird1: 0,
bird2: 0,
cloud1: 0,
cloud2: 0,
ufo1: 0,
ufo2: 0,
jet1: 0
};
this.spawnRules = {
bird1: {
max: 1,
layer: LAYERS.BIRD1,
movement: Bird1Movement,
scoreValue: 5
},
bird2: {
min: 3,
max: 3,
layer: LAYERS.BIRD2,
movement: Bird2Movement,
scoreValue: 1
},
cloud1: {
min: 1,
max: 3,
layer: LAYERS.CLOUD1,
movement: CloudMovement
},
cloud2: {
min: 1,
max: 3,
layer: LAYERS.CLOUD2,
movement: CloudMovement
},
// Ensure 3-5 total clouds
ufo1: {
max: 1,
respawnTime: {
min: 20000,
max: 30000
},
layer: LAYERS.UFO1,
movement: UFOMovement,
sound: 'ufo1',
scoreValue: 25
},
ufo2: {
max: 1,
respawnTime: {
min: 20000,
max: 30000
},
layer: LAYERS.UFO2,
movement: UFOMovement,
sound: 'ufo1',
scoreValue: 25
},
jet1: {
max: 1,
respawnTime: {
min: 20000,
max: 30000
},
layer: LAYERS.JET1,
movement: GameObjectMovement,
sound: 'jet1'
}
};
this.soundManager = new SoundManager();
this.scoreManager = new ScoreManager();
this.exclusiveGroups = [['ufo1', 'ufo2']];
// Correct layer order as per requirements
this.layerOrder = [LAYERS.BACKGROUND, LAYERS.LIGHT1, LAYERS.SUN, LAYERS.UFO2, LAYERS.CLOUD1, LAYERS.JET1, LAYERS.CLOUD2, LAYERS.UFO1, LAYERS.BIRD1, LAYERS.GRASS_BACK, LAYERS.TREE, LAYERS.STACK, LAYERS.BIRD2, LAYERS.MIRROR, LAYERS.GRASS_FRONT, LAYERS.RETICLE, LAYERS.LASER];
this.spawnObject = function (type, Constructor, options) {
var _this2 = this;
var rule = this.spawnRules[type];
if (!rule) {
return;
}
var count = this.objectCounts[type] || 0;
var maxCount = rule.max || 1;
// Early exit conditions
if (count >= maxCount) {
return;
}
// Check exclusive groups (UFO1 and UFO2)
if (this.exclusiveGroups.some(function (group) {
if (group.includes(type)) {
return group.some(function (groupType) {
return _this2.objectCounts[groupType] > 0;
});
}
return false;
})) {
return;
}
// Handle minimum count requirements
if (rule.min && count < rule.min) {
while (count < rule.min) {
this.createObject(type, Constructor, rule);
count++;
}
return;
}
// Ensure proper cloud count (3-5 total)
if (type === 'cloud1' || type === 'cloud2') {
var totalClouds = this.objectCounts.cloud1 + this.objectCounts.cloud2;
if (totalClouds >= 5) {
return;
}
if (totalClouds < 3) {
while (totalClouds < 3) {
this.createObject(type, Constructor, rule);
totalClouds++;
}
return;
}
}
// Ensure proper bird counts
if (type === 'bird1' && count >= 1) {
return;
} // Max 1 bird1
if (type === 'bird2' && count >= 3) {
return;
} // Max 3 bird2
// Create object with respawn timer for specific types
this.createObject(type, Constructor, rule);
if (rule.respawnTime) {
var respawnDelay = Math.random() * (rule.respawnTime.max - rule.respawnTime.min) + rule.respawnTime.min;
this.spawnTimers[type] = LK.setTimeout(function () {
delete _this2.spawnTimers[type];
_this2.spawnObject(type, Constructor, options);
}, respawnDelay);
}
};
this.createObject = function (type, Constructor, rule) {
if (!Constructor || !rule) {
return null;
}
var obj = new Constructor();
obj.type = type;
// Initialize position based on object type
var screenWidth = 2048;
var screenHeight = 2732;
var isVerticalMovement = type.startsWith('bird');
obj.x = isVerticalMovement ? Math.random() * screenWidth : Math.random() < 0.5 ? screenWidth + obj.width / 2 : -obj.width / 2;
obj.y = isVerticalMovement ? -obj.height : Math.random() * (screenHeight / 2);
// Add to game and layer manager in one step
game.layerManager.addToLayer(obj, rule.layer);
this.objectCounts[type] = (this.objectCounts[type] || 0) + 1;
// Initialize movement with appropriate options
if (rule.movement) {
// Define common movement parameters by object type
var MovementConfigs = {
bird1: {
speed: 2,
speedRange: 1.2,
arcAmplitude: 6.5,
arcFrequency: 100,
isVertical: true,
canFlip: true,
moveSound: 'wings1'
},
bird2: {
speed: 2.5,
speedRange: 1.2,
arcAmplitude: 6.5,
arcFrequency: 100,
isVertical: true,
canFlip: true,
moveSound: 'wings1'
},
ufo1: {
speed: 3.2,
speedRange: 0.8,
arcAmplitude: 4.5,
arcFrequency: 80,
isVertical: false,
canFlip: true,
moveSound: 'ufo1'
},
ufo2: {
speed: 3.2,
speedRange: 0.8,
arcAmplitude: 4.5,
arcFrequency: 80,
isVertical: false,
canFlip: true,
moveSound: 'ufo1'
},
jet1: {
speed: 10,
speedRange: 0,
arcAmplitude: 0,
arcFrequency: 0,
isVertical: false,
canFlip: true,
moveSound: 'jet1'
},
cloud1: {
speed: 0.25,
speedRange: 0.55,
arcAmplitude: 0,
arcFrequency: 0,
isVertical: false,
canFlip: false
},
cloud2: {
speed: 0.25,
speedRange: 0.55,
arcAmplitude: 0,
arcFrequency: 0,
isVertical: false,
canFlip: false
}
};
// Get movement configuration based on object type
var params = MovementConfigs[type] || MovementConfigs.bird1; // Default to bird1 if type not found
// Create movement options with the selected parameters
var movementOptions = {
speed: params.speed,
speedRange: params.speedRange,
arcAmplitude: params.arcAmplitude,
arcFrequency: params.arcFrequency,
isVertical: params.isVertical,
canFlip: params.canFlip,
moveSound: rule.sound,
respawnTime: rule.respawnTime
};
obj.movement = new rule.movement(obj, obj.children[0], movementOptions);
}
if (rule.respawnTime) {
this.scheduleRespawn(type, Constructor);
}
return obj;
};
this.scheduleRespawn = function (type, Constructor) {
var rule = this.spawnRules[type];
// Ensure respawn timers for ufo1, ufo2, and jet1 are set to 20-30 seconds
var respawnTime;
if (type === 'ufo1' || type === 'ufo2' || type === 'jet1') {
respawnTime = Math.random() * 10000 + 20000; // 20-30 seconds
} else if (rule.respawnTime) {
respawnTime = Math.random() * (rule.respawnTime.max - rule.respawnTime.min) + rule.respawnTime.min;
} else {
respawnTime = Math.random() * 10000 + 5000; // Default 5-15 seconds
}
if (this.spawnTimers[type]) {
LK.clearTimeout(this.spawnTimers[type]);
}
this.spawnTimers[type] = LK.setTimeout(function () {
if (this.objectCounts[type] > 0) {
this.objectCounts[type]--;
}
var shouldSpawn = true;
// Check exclusive groups (e.g., only one UFO type at a time)
for (var i = 0; i < this.exclusiveGroups.length; i++) {
var group = this.exclusiveGroups[i];
if (group.includes(type)) {
var groupTotal = 0;
for (var j = 0; j < group.length; j++) {
groupTotal += this.objectCounts[group[j]];
}
if (groupTotal > 0) {
shouldSpawn = false;
}
}
}
if (shouldSpawn) {
this.spawnObject(type, Constructor);
}
}.bind(this), respawnTime);
// Start the game
var spawnManager = new _SpawnManager();
spawnManager.initialize();
this.initialize = function () {
// Initialize birds - exactly 1 Bird1 and 3 Bird2s
this.spawnObject('bird1', Bird1);
for (var i = 0; i < this.spawnRules.bird2.min; i++) {
this.spawnObject('bird2', Bird2);
}
// Initialize clouds - ensure 3-5 total clouds
var totalCloudsToSpawn = Math.floor(Math.random() * 3) + 3;
var cloud1ToSpawn = Math.min(totalCloudsToSpawn, this.spawnRules.cloud1.max);
var cloud2ToSpawn = totalCloudsToSpawn - cloud1ToSpawn;
for (var i = 0; i < cloud1ToSpawn; i++) {
this.spawnObject('cloud1', Cloud);
}
for (var i = 0; i < cloud2ToSpawn; i++) {
this.spawnObject('cloud2', Cloud);
}
// Initialize UFOs and Jet with respawn timers
// Randomly choose between UFO1 and UFO2
if (Math.random() < 0.5) {
this.spawnObject('ufo1', UFO1);
} else {
this.spawnObject('ufo2', UFO2);
}
this.spawnObject('jet1', Jet1);
// Set up periodic check for object counts and layer ordering
LK.setInterval(function () {
// Update layer ordering
this.layerOrder.forEach(function (layerId, index) {
var objects = game.layerManager.getObjectsInLayer(layerId);
objects.forEach(function (obj) {
game.layerManager.setLayerIndex(obj, index);
});
}.bind(this));
// Maintain bird counts
if (this.objectCounts.bird1 < 1) {
this.spawnObject('bird1', Bird1);
}
while (this.objectCounts.bird2 < 3) {
this.spawnObject('bird2', Bird2);
}
// Maintain cloud counts
var totalClouds = this.objectCounts.cloud1 + this.objectCounts.cloud2;
if (totalClouds < 3) {
var cloudsNeeded = 3 - totalClouds;
for (var i = 0; i < cloudsNeeded; i++) {
if (Math.random() < 0.5 && this.objectCounts.cloud1 < this.spawnRules.cloud1.max) {
this.spawnObject('cloud1', Cloud);
} else if (this.objectCounts.cloud2 < this.spawnRules.cloud2.max) {
this.spawnObject('cloud2', Cloud);
}
}
}
// Ensure one UFO (either UFO1 or UFO2) is on screen
if (this.objectCounts.ufo1 + this.objectCounts.ufo2 === 0 && !this.spawnTimers.ufo1 && !this.spawnTimers.ufo2) {
if (Math.random() < 0.5) {
this.spawnObject('ufo1', UFO1);
} else {
this.spawnObject('ufo2', UFO2);
}
}
// Ensure one jet is on screen
if (this.objectCounts.jet1 === 0 && !this.spawnTimers.jet1) {
this.spawnObject('jet1', Jet1);
}
}.bind(this), 1000);
}.bind(this);
// Set up periodic check for object counts
LK.setInterval(function () {
// Maintain bird counts - exactly 1 Bird1
if (this.objectCounts.bird1 < 1) {
this.spawnObject('bird1', Bird1);
}
// Maintain bird counts - exactly 3 Bird2s
while (this.objectCounts.bird2 < 3) {
this.spawnObject('bird2', Bird2);
}
// Maintain cloud counts - ensure 3-5 total clouds
var totalClouds = this.objectCounts.cloud1 + this.objectCounts.cloud2;
if (totalClouds < 3) {
var cloudsNeeded = 3 - totalClouds;
for (var i = 0; i < cloudsNeeded; i++) {
if (Math.random() < 0.5 && this.objectCounts.cloud1 < this.spawnRules.cloud1.max) {
this.spawnObject('cloud1', Cloud);
} else {
this.spawnObject('cloud2', Cloud);
}
}
} else if (totalClouds > 5) {
// If there are more than 5 clouds, don't spawn any more until some are removed
// This is handled automatically when clouds move off-screen
}
// Ensure one UFO (either UFO1 or UFO2) is on screen
if (this.objectCounts.ufo1 + this.objectCounts.ufo2 < 1 && !this.spawnTimers.ufo1 && !this.spawnTimers.ufo2) {
if (Math.random() < 0.5) {
this.spawnObject('ufo1', UFO1);
} else {
this.spawnObject('ufo2', UFO2);
}
}
// Ensure one Jet1 is on screen
if (this.objectCounts.jet1 < 1 && !this.spawnTimers.jet1) {
this.spawnObject('jet1', Jet1);
}
}.bind(this), 1000);
};
var spawnManager = new _SpawnManager();
// Initialize the spawn manager
_SpawnManager.prototype.initialize = function () {
// Initialize sound and score managers
this.soundManager.initialize();
// Set up initial spawns with consistent behavior
this.spawnObject('bird1', Bird1);
for (var i = 0; i < 3; i++) {
this.spawnObject('bird2', Bird2);
}
};
// Set up cloud spawning - 3-5 total clouds
var totalClouds = Math.floor(Math.random() * 3) + 3;
var cloud1Count = Math.min(Math.ceil(totalClouds / 2), this.spawnRules.cloud1.max);
var cloud2Count = totalClouds - cloud1Count;
for (var i = 0; i < cloud1Count; i++) {
this.spawnObject('cloud1', Cloud);
}
for (var i = 0; i < cloud2Count; i++) {
this.spawnObject('cloud2', Cloud);
}
// Schedule initial UFO spawn (either UFO1 or UFO2)
if (Math.random() < 0.5) {
this.spawnObject('ufo1', UFO1);
} else {
this.spawnObject('ufo2', UFO2);
}
// Schedule initial Jet1 spawn
this.spawnObject('jet1', Jet1);
// Set up periodic checks for maintaining entity counts
LK.setInterval(function () {
// Maintain bird counts
if (this.objectCounts.bird1 < 1) {
this.spawnObject('bird1', Bird1);
}
while (this.objectCounts.bird2 < 3) {
this.spawnObject('bird2', Bird2);
}
// Maintain cloud counts (3-5 total)
var totalClouds = this.objectCounts.cloud1 + this.objectCounts.cloud2;
if (totalClouds < 3) {
var type = Math.random() < 0.5 ? 'cloud1' : 'cloud2';
this.spawnObject(type, Cloud);
}
// Ensure one UFO (either UFO1 or UFO2) is scheduled
if (this.objectCounts.ufo1 + this.objectCounts.ufo2 === 0 && !this.spawnTimers.ufo1 && !this.spawnTimers.ufo2) {
var ufoType = Math.random() < 0.5 ? 'ufo1' : 'ufo2';
this.scheduleRespawn(ufoType, ufoType === 'ufo1' ? UFO1 : UFO2);
}
// Ensure one Jet1 is scheduled
if (this.objectCounts.jet1 === 0 && !this.spawnTimers.jet1) {
this.scheduleRespawn('jet1', Jet1);
}
}.bind(this), 1000);
};
spawnManager.initialize();
// Main game update function
game.update = function () {
// Update all game objects
game.children.forEach(function (entity) {
if (entity.update) {
entity.update();
}
// Handle off-screen objects
if (entity instanceof Bird1 || entity instanceof Bird2) {
if (entity.y > 2732) {
entity.y = -entity.height;
entity.x = Math.random() * 2048;
}
}
});
// Update score display
if (game.mirror && game.mirror.updateScore) {
game.mirror.updateScore(game.score || 0);
}
// Ensure correct number of birds using SpawnManager
spawnManager.spawnObject('bird1', Bird1);
spawnManager.spawnObject('bird2', Bird2);
// Update UFOs and play sounds
game.children.forEach(function (entity) {
if ((entity instanceof UFO1 || entity instanceof UFO2) && !entity.soundPlayed && entity.x > 0 && entity.x < 2048) {
LK.getSound('ufo1').play();
entity.soundPlayed = true;
}
});
// Update each laser and check collisions
game.children.forEach(function (laser) {
if (laser instanceof Laser) {
laser.update();
checkLaserCollisions(laser);
}
});
};
function checkAndRespawnBirds() {
spawnManager.spawnBird(Bird1, 1);
spawnManager.spawnBird(Bird2, 3);
LK.setTimeout(checkAndRespawnBirds, Math.random() * 10000 + 20000);
}
// Update bird positions and states
function updateGameBirds() {
maintainBirdCount(Bird1, 1, LAYERS.BIRD1);
maintainBirdCount(Bird2, 3, LAYERS.BIRD2);
}
function maintainBirdCount(BirdType, targetCount, layerIndex) {
var birdCount = birds.filter(function (b) {
return b instanceof BirdType;
}).length;
if (birdCount < targetCount) {
for (var i = 0; i < targetCount - birdCount; i++) {
var newBird = new BirdType();
newBird.x = Math.random() * 2048;
newBird.y = Math.random() * (2732 / 2);
newBird.speed = 1 + Math.random() * 0.6;
game.addChild(newBird);
game.layerManager.addToLayer(newBird, layerIndex);
birds.push(newBird);
}
} else if (birdCount > targetCount) {
var extraBirds = birds.filter(function (b) {
return b instanceof BirdType;
}).slice(targetCount);
extraBirds.forEach(function (b) {
b.destroy();
birds.splice(birds.indexOf(b), 1);
});
}
}
// Update existing birds
birds.forEach(function (bird) {
bird.update();
if (bird.lastY <= 2732 && bird.y > 2732) {
bird.y = -bird.height;
bird.x = Math.random() * 2048;
bird.speed = 1 + Math.random() * 0.6;
}
});
// Maintain bird counts
maintainBirdCount(Bird1, 1, LAYERS.BIRD1);
maintainBirdCount(Bird2, 3, LAYERS.BIRD2);
// Update UFOs and play sounds
game.children.forEach(function (entity) {
if ((entity instanceof UFO1 || entity instanceof UFO2) && !entity.soundPlayed && entity.x > 0 && entity.x < 2048) {
LK.getSound('ufo1').play();
entity.soundPlayed = true;
}
});
// Update each laser and check collisions
game.children.forEach(function (laser) {
if (laser instanceof Laser) {
laser.update();
checkLaserCollisions(laser);
}
});
// Add a tree to the game
var tree = game.addChild(new Tree());
tree.x = 2048 / 2 + 600; // Move the tree 500px to the right
tree.y = 2500; // Position the tree on the grass
// Add tree to the proper layer
if (game.children.includes(tree)) {
game.layerManager.addToLayer(tree, LAYERS.TREE); // Use layer manager to set tree layer
}
var score = 0;
// Add stack1 image to the game
var stack1 = game.addChild(new Stack1());
stack1.x = 1700; // Move 700px to the right
stack1.y = 2250; // Move down by 800px
// Add stack1 to the proper layer
if (game.children.includes(stack1)) {
game.layerManager.addToLayer(stack1, LAYERS.STACK); // Use layer manager to set stack layer
}
// Add the grass floor to the game
var grassBack = new GrassBack();
grassBack.x = 1020;
grassBack.y = 2735; // Position grassBack at the bottom
game.addChild(grassBack);
// Add grassBack to the proper layer
if (game.children.includes(grassBack)) {
game.layerManager.addToLayer(grassBack, LAYERS.GRASS_BACK); // Use layer manager to set grass-back layer
}
var grassFront = new GrassFront();
grassFront.x = 1020;
grassFront.y = 2785; // Position grassFront at the bottom, moved down by 50px
game.addChild(grassFront);
// Add grassFront to the proper layer
if (game.children.includes(grassFront)) {
game.layerManager.addToLayer(grassFront, LAYERS.GRASS_FRONT); // Use layer manager to set grass-front layer
}
var scoreDisplay = new Mirror();
scoreDisplay.x = 2048 / 2 + 400; // Move the score display 400px to the right
scoreDisplay.y = 2732 - 185 - 80 - 390 + 30 + 50; // Move the score display up by an additional 80px and down by 30px + 50px
game.addChild(scoreDisplay);
var mirror = new Mirror();
mirror.x = 2048 / 2 + 400; // Move the mirror 400px to the right
mirror.y = 2732 - 185 - 80 - 390 + 30; // Move the mirror up by an additional 80px and down by 30px
game.addChild(mirror);
// Add mirror to the proper layer
if (game.children.includes(mirror)) {
game.layerManager.addToLayer(mirror, LAYERS.MIRROR); // Use layer manager to set mirror layer
}
// Function to handle bgm1 end event
function onBgm1End() {
// Set a timer to replay bgm1 after 50-80 seconds
var bgmTimer = LK.setTimeout(function () {
LK.playMusic('bgm1', {
loop: true,
fade: {
start: 0,
end: 1,
duration: 4000
},
onEnd: onBgm1End
});
}, Math.random() * 30000 + 50000);
}
;
// Add the cat to the game
var cat = game.addChild(new Cat());
cat.x = 230; // Move the cat 20px to the left
cat.y = 2732; // Position the cat at the bottom of the screen
// Add cat to the proper layer
if (game.children.includes(cat)) {
game.layerManager.addToLayer(cat, LAYERS.CAT); // Use layer manager to set cat layer
}
// Play bgm1 once on load and set a timer to replay it every 20-30 seconds
LK.playMusic('bgm1', {
loop: false,
fade: {
start: 0,
end: 0.1,
duration: 4000
},
onEnd: function onEnd() {
LK.setTimeout(function () {
LK.playMusic('bgm1', {
loop: false,
fade: {
start: 0,
end: 0.1,
duration: 4000
},
onEnd: onEnd
});
}, Math.random() * 10000 + 20000);
}
});
// Initialize a timer to play the wings1 sound at a random time between 10 and 30 seconds
var wingsTimer = LK.setTimeout(function () {
LK.getSound('wings1').play();
wingsTimer = LK.setTimeout(arguments.callee, Math.random() * 20000 + 10000);
}, Math.random() * 20000 + 10000);
// Create an array for all sounds except ufo1, including all birdsong sounds
var sounds = ['cricket1', 'frog1', 'wings1', 'songbird1'];
var currentAmbientSound = null;
// Sound volumes configuration
// Initialize random timers for each sound to play between 20-30 seconds
sounds.forEach(function (soundId) {
var sound = LK.getSound(soundId);
var ambientSoundTimer = LK.setTimeout(function () {
if (currentAmbientSound) {
currentAmbientSound.stop();
}
sound.play();
currentAmbientSound = sound;
LK.setTimeout(function () {
currentAmbientSound = null;
}, sound.duration * 1000);
ambientSoundTimer = LK.setTimeout(arguments.callee, Math.random() * 10000 + 20000);
}, Math.random() * 10000 + 20000);
});
// Using UFO sound ID as placeholder
// Using existing CLOUD_TYPES definition
var Pulse = function Pulse(graphics, options) {
this.graphics = graphics;
this.options = Object.assign({
minScale: 1.0,
maxScale: 1.2,
expandDuration: 1000,
contractDuration: 1000,
easing: tween.easeInOut
}, options);
this.startPulsating = function () {
function pulsate() {
tween(this.graphics, {
scaleX: this.options.maxScale,
scaleY: this.options.maxScale
}, {
duration: this.options.expandDuration,
easing: this.options.easing,
onFinish: function () {
tween(this.graphics, {
scaleX: this.options.minScale,
scaleY: this.options.minScale
}, {
duration: this.options.contractDuration,
easing: this.options.easing,
onFinish: pulsate.bind(this)
});
}.bind(this)
});
}
pulsate.call(this);
};
};
var SunPulse = function SunPulse(sunGraphics) {
return new Pulse(sunGraphics, {
maxScale: 1.1
});
};
// Light1Pulse class to handle the pulsating effect for Light1
var Light1Pulse = function Light1Pulse(graphics) {
;
this.graphics = graphics;
this.pulseTimer = null;
this.startPulsating = function () {
var self = this;
var brightness = 1.0;
var direction = 1;
this.pulseTimer = LK.setInterval(function () {
brightness += direction * 0.05;
if (brightness >= 2.0) {
direction = -1;
brightness = 2.0;
} else if (brightness <= 1.0) {
direction = 1;
brightness = 1.0;
}
self.graphics.brightness = brightness;
}, 50);
};
this.stopPulsating = function () {
if (this.pulseTimer) {
LK.clearInterval(this.pulseTimer);
}
};
};
var bird2; // Define bird2 variable in the global scope
// UFOMovement class to handle UFO movement
var UFOMovement = function UFOMovement(ufo, ufoGraphics) {
return new GameObjectMovement(ufo, ufoGraphics, {
speed: 3.2,
speedRange: 0.8,
arcAmplitude: 4.5,
arcFrequency: 80,
isVertical: false,
canFlip: true,
moveSound: 'ufo1'
});
};
;
var UFOSound = function UFOSound() {
;
this.play = function () {
LK.getSound('ufo1').play();
};
};
// BackgroundMusic class to manage background music
var BackgroundMusic = function BackgroundMusic() {
;
this.play = function () {
LK.playMusic('bgm1', {
loop: true,
fade: {
start: 0,
end: 1,
duration: 4000
},
onEnd: onBgm1End
});
};
};
// LaserSound class to manage laser sound effects
var LaserSound = function LaserSound() {
;
this.play = function () {
LK.getSound('laser1').play();
};
};
var Bird1Movement = function Bird1Movement(bird, birdGraphics) {
return new GameObjectMovement(bird, birdGraphics, {
speed: 2.5,
speedRange: 1.2,
arcAmplitude: 6.5,
arcFrequency: 100,
isVertical: true,
canFlip: true,
moveSound: 'wings1'
});
};
var Bird2Movement = function Bird2Movement(bird, birdGraphics) {
return new GameObjectMovement(bird, birdGraphics, {
speed: 2.5,
speedRange: 1.2,
arcAmplitude: 6.5,
arcFrequency: 100,
isVertical: true,
canFlip: true,
moveSound: 'wings1'
});
};
var Bird2Effects = function Bird2Effects(bird) {
;
this.bird = bird;
this.applyEffects = function () {};
};
var ReticlePulse = function ReticlePulse(reticleGraphics) {
;
return new Pulse(reticleGraphics, {
minScale: 0.9,
maxScale: 1.3,
expandDuration: 800,
contractDuration: 1200
});
};
// Bird1Effects class to handle effects and animations for Bird1
var Bird1Effects = function Bird1Effects(bird) {
;
this.bird = bird;
this.applyEffects = function () {
// Add any specific effects or animations for Bird1 here
};
};
function spawnBird2() {
var bird2Count = entityManager.getAllOfType(Bird2).length;
if (bird2Count < 3) {
var bird = new Bird2();
bird.y = Math.random() * (2732 / 2);
bird.x = Math.random() < 0.5 ? 0 : 2048;
bird.speed = 1 + Math.random() * 0.6;
bird.lastIntersecting = false;
bird.type = 'bird2';
bird.color = 0xFFFFFF;
entityManager.add(bird);
birds.push(bird);
}
LK.setTimeout(spawnBird2, Math.random() * 10000 + 20000);
}
// Add background to the BACKGROUND layer
var background = new Background();
background.x = 2048 / 2;
background.y = 2732 / 2 - 140;
game.layerManager.addToLayer(background, LAYERS.BACKGROUND);
// Initialize bird spawning
spawnBird2();
// ScoreManager class to manage score logic
var ScoreManager = function ScoreManager() {
;
var self = this;
var currentScore = 0;
var highScore = storage.highScore || 0;
self.scoreValues = {
bird1: 100,
bird2: 50,
ufo1: 250,
ufo2: 250
};
self.addScore = function (objectType) {
var points = self.scoreValues[objectType] || 0;
if (points > 0) {
currentScore += points;
if (currentScore > highScore) {
highScore = currentScore;
storage.highScore = highScore;
}
// Update score display
if (scoreDisplay && scoreDisplay.updateScore) {
scoreDisplay.updateScore(currentScore);
}
if (mirror && mirror.updateScore) {
mirror.updateScore(currentScore);
}
}
return currentScore;
};
self.resetScore = function () {
currentScore = 0;
if (scoreDisplay && scoreDisplay.updateScore) {
scoreDisplay.updateScore(currentScore);
}
if (mirror && mirror.updateScore) {
mirror.updateScore(currentScore);
}
return currentScore;
};
self.getScore = function () {
return currentScore;
};
self.getHighScore = function () {
return highScore;
};
};
var birds = [];
game.down = function (x, y, obj) {
if (obj && obj.event) {
x = obj.event.x;
y = obj.event.y;
}
if (!game.reticle) {
game.reticle = game.addChild(new Reticle());
if (game.children.includes(game.reticle)) {
game.layerManager.addToLayer(game.reticle, LAYERS.RETICLE);
}
}
game.reticle.x = x;
game.reticle.y = y;
if (typeof x === 'undefined' || typeof y === 'undefined') {
console.error('Invalid coordinates for laser');
return;
}
var laser = new Laser(cat.x - 140, cat.y - 440, x, y);
game.addChild(laser);
if (game.children.includes(laser) && game.children.includes(game.reticle)) {
game.layerManager.addToLayer(laser, LAYERS.LASER);
}
};
var VOLUME_BGM1 = 0.02;
var VOLUME_BREEZE1 = 0.02;
var VOLUME_CRICKET1 = 0.02;
var VOLUME_FROG1 = 0.02;
var VOLUME_SONGBIRD1 = 0.02;
var VOLUME_UFO1 = 0.02;
var VOLUME_WINGS1 = 0.02;
game.move = function (x, y, obj) {
if (!game.reticle) {
game.reticle = game.addChild(new Reticle());
}
if (obj.event) {
var x = obj.event.x;
var y = obj.event.y;
}
game.reticle.x = x;
game.reticle.y = y;
};
// Add a sun to the game in the top left corner
var sun = new Sun();
sun.x = 480;
sun.y = 680;
game.layerManager.addToLayer(sun, LAYERS.SUN);
var light1 = new Light1();
light1.x = 510;
light1.y = 1500;
game.layerManager.addToLayer(light1, LAYERS.LIGHT1);
light1.visible = true;
// Function to add a UFO to the game
// Using existing CLOUD_TYPES definition
// initializeClouds already called earlier
var bird1; // Define bird1 variable in the global scope
var bird; // Define bird variable in the global scope
var ufo; // Define the ufo variable in the global scope
var laser; // Define the laser variable in the global scope
var ufoTimer = LK.setTimeout(function () {
addUFO();
// Reset the timer for the UFO to reappear between 10-20 seconds
ufoTimer = LK.setTimeout(arguments.callee, Math.random() * 10000 + 10000);
}, Math.random() * 10000 + 10000); // Initial interval for UFO appearances between 10 to 20 seconds
// Helper functions for game update
function updateEntityPositions() {
game.children.forEach(function (entity) {
if (entity.update) {
entity.update();
}
// Handle off-screen objects
if ((entity instanceof Bird1 || entity instanceof Bird2) && entity.y > 2732) {
entity.y = -entity.height;
entity.x = Math.random() * 2048;
}
});
}
function handleCollisions() {
game.children.forEach(function (child) {
if (child instanceof Laser) {
child.update();
checkLaserCollisions(child);
}
});
}
function checkLaserCollisions(laser) {
game.children.forEach(function (target) {
if (!laser.lastIntersecting && AABBIntersect(laser, target)) {
handleCollisionPoints(laser, target);
}
});
laser.lastIntersecting = game.children.some(function (target) {
return (target instanceof Bird1 || target instanceof Bird2 || target instanceof UFO1 || target instanceof UFO2) && laser.intersects(target);
});
}
function handleCollisionPoints(laser, target) {
var points = 0;
var soundEffect = '';
if (target instanceof Bird1) {
points = 100;
soundEffect = 'dead1';
spawnManager.objectCounts.bird1--;
} else if (target instanceof Bird2) {
points = 50;
soundEffect = 'dead2';
spawnManager.objectCounts.bird2--;
} else if (target instanceof UFO1 || target instanceof UFO2) {
points = 250;
soundEffect = 'dead3';
spawnManager.objectCounts[target instanceof UFO1 ? 'ufo1' : 'ufo2']--;
}
if (points > 0) {
game.score = (game.score || 0) + points;
if (scoreDisplay && scoreDisplay.updateScore) {
scoreDisplay.updateScore(game.score);
}
if (game.mirror && game.mirror.updateScore) {
game.mirror.updateScore(game.score);
}
LK.getSound(soundEffect).play();
target.destroy();
laser.destroy();
}
game.update = function () {
updateEntityPositions();
handleCollisions();
if (ufo) {
ufo.customUpdate();
// Check if UFO is out of bounds
if (ufo.lastX <= 2048 + ufo.width / 2 && ufo.x > 2048 + ufo.width / 2 || ufo.lastX >= -ufo.width / 2 && ufo.x < -ufo.width / 2) {
ufo.destroy();
ufo = null;
ufoTimer = LK.setTimeout(function () {
ufo = addUFO();
}, Math.random() * 20000 + 30000);
}
ufo.lastX = ufo.x;
}
};
// Update existing birds
game.children.forEach(function (bird) {
if (bird instanceof Bird1 || bird instanceof Bird2) {
if (bird.y > 2732) {
bird.y = -bird.height;
bird.x = Math.random() * 2048;
}
}
});
}
// Update UFOs and play sounds
game.children.forEach(function (entity) {
if ((entity instanceof UFO1 || entity instanceof UFO2) && !entity.soundPlayed && entity.x > 0 && entity.x < 2048) {
LK.getSound('ufo1').play();
entity.soundPlayed = true;
}
});
// Update each laser and check collisions
game.children.forEach(function (laser) {
if (laser instanceof Laser) {
laser.update();
checkLaserCollisions(laser);
}
});
// Add a tree to the game
var tree = game.addChild(new Tree());
tree.x = 2048 / 2 + 600; // Move the tree 500px to the right
tree.y = 2500; // Position the tree on the grass
// Add tree to the proper layer
if (game.children.includes(tree)) {
game.layerManager.addToLayer(tree, LAYERS.TREE); // Use layer manager to set tree layer
}
var score = 0;
// Add stack1 image to the game
var stack1 = game.addChild(new Stack1());
stack1.x = 1700; // Move 700px to the right
stack1.y = 2250; // Move down by 800px
// Add stack1 to the proper layer
if (game.children.includes(stack1)) {
game.layerManager.addToLayer(stack1, LAYERS.STACK); // Use layer manager to set stack layer
}
// Add the grass floor to the game
var grassBack = new GrassBack();
grassBack.x = 1020;
grassBack.y = 2735; // Position grassBack at the bottom
game.addChild(grassBack);
// Add grassBack to the proper layer
if (game.children.includes(grassBack)) {
game.layerManager.addToLayer(grassBack, LAYERS.GRASS_BACK); // Use layer manager to set grass-back layer
}
var grassFront = new GrassFront();
grassFront.x = 1020;
grassFront.y = 2785; // Position grassFront at the bottom, moved down by 50px
game.addChild(grassFront);
// Add grassFront to the proper layer
if (game.children.includes(grassFront)) {
game.layerManager.addToLayer(grassFront, LAYERS.GRASS_FRONT); // Use layer manager to set grass-front layer
}
var scoreDisplay = new Mirror();
scoreDisplay.x = 2048 / 2 + 400; // Move the score display 400px to the right
scoreDisplay.y = 2732 - 185 - 80 - 390 + 30 + 50; // Move the score display up by an additional 80px and down by 30px + 50px
game.addChild(scoreDisplay);
var mirror = new Mirror();
mirror.x = 2048 / 2 + 400; // Move the mirror 400px to the right
mirror.y = 2732 - 185 - 80 - 390 + 30; // Move the mirror up by an additional 80px and down by 30px
game.addChild(mirror);
// Add mirror to the proper layer using the layer manager
// Add mirror to the proper layer
if (game.children.includes(mirror)) {
game.layerManager.addToLayer(mirror, LAYERS.MIRROR); // Use layer manager to set mirror layer
}
// Function to handle bgm1 end event
// Add the cat to the game
var cat = game.addChild(new Cat());
cat.x = 230; // Move the cat 20px to the left
cat.y = 2732; // Position the cat at the bottom of the screen
// Add cat to the proper layer
if (game.children.includes(cat)) {
game.layerManager.addToLayer(cat, LAYERS.CAT); // Use layer manager to set cat layer
}
// Play bgm1 once on load and set a timer to replay it every 20-50 seconds
LK.playMusic('bgm1', {
loop: false,
// Play once
fade: {
start: 0,
end: 0.02,
// Set to the lowest volume
duration: 4000
},
onEnd: function onEnd() {
// Set a timer to replay bgm1 every 20-50 seconds
LK.setTimeout(function () {
LK.playMusic('bgm1', {
loop: false,
// Play once
fade: {
start: 0,
end: 0.5,
// Set to the lowest volume
duration: 4000
},
onEnd: onEnd // Set the onEnd function to replay bgm1
});
}, Math.random() * 30000 + 20000); // Random time between 20-50 seconds
}
});
// Initialize a timer to play the wings1 sound at a random time between 10 and 30 seconds
var wingsTimer = LK.setTimeout(function () {
LK.getSound('wings1').play();
wingsTimer = LK.setTimeout(arguments.callee, Math.random() * 20000 + 10000);
}, Math.random() * 20000 + 10000);
// Create an array for all sounds except ufo1, including all birdsong sounds
var sounds = ['cricket1', 'frog1', 'wings1', 'songbird1'];
var currentAmbientSound = null;
// Initialize random timers for each sound to play between 20-30 seconds
sounds.forEach(function (soundId) {
var sound = LK.getSound(soundId);
var ambientSoundTimer = LK.setTimeout(function () {
if (currentAmbientSound) {
currentAmbientSound.stop();
}
sound.play();
currentAmbientSound = sound;
LK.setTimeout(function () {
currentAmbientSound = null;
}, sound.duration * 1000);
ambientSoundTimer = LK.setTimeout(arguments.callee, Math.random() * 10000 + 20000);
}, Math.random() * 10000 + 20000);
});
// Initialize EntityManager
var entityManager = new EntityManager();
// Initial entity spawning will be handled by the managers
if (typeof x !== 'undefined' && typeof y !== 'undefined') {
var laser = new Laser(cat.x - 140, cat.y - 440, x, y); // laser starting point
entityManager.add(laser);
} else {
console.error('Invalid coordinates for laser creation');
}
// Ensure timers for ambient sounds and bgm1 are set to repeat every 20-30 seconds
function initializeAmbientSounds() {
var _playAmbientSounds = function playAmbientSounds() {
LK.getSound('songbird1').play();
LK.getSound('cricket1').play();
LK.setTimeout(_playAmbientSounds, Math.random() * 10000 + 20000); // 20-30 seconds
};
_playAmbientSounds();
// Set initial interval
LK.setInterval(_playAmbientSounds, 25000); // Average of 20-30 seconds
}
function initializeBGM() {
var playBGM = function playBGM() {
LK.playMusic('bgm1');
};
playBGM();
// Set regular interval for background music
LK.setInterval(playBGM, 25000); // Average of 20-30 seconds
}
// Fix scoring
var scoreManager = new ScoreManager();
var score = 0;
game.down = function (x, y, obj) {
if (obj && obj.event) {
x = obj.event.x;
y = obj.event.y;
}
if (!game.reticle) {
game.reticle = game.addChild(new Reticle());
if (game.children.includes(game.reticle)) {
game.layerManager.addToLayer(game.reticle, LAYERS.RETICLE);
}
}
game.reticle.x = x;
game.reticle.y = y;
if (typeof x === 'undefined' || typeof y === 'undefined') {
console.error('Invalid coordinates for laser');
return;
}
var laser = new Laser(cat.x - 140, cat.y - 440, x, y);
game.addChild(laser);
if (game.children.includes(laser) && game.children.includes(game.reticle)) {
game.layerManager.addToLayer(laser, LAYERS.LASER);
}
};
// Adjust layer display order
// Ensure light1 layer is displayed after background
if (light1) {
game.layerManager.addToLayer(light1, LAYERS.LIGHT1);
}
// Ensure jet layer is displayed before cloud2 layer
if (jet) {
game.layerManager.addToLayer(jet, LAYERS.JET1);
}
// Ensure mirror layer is displayed behind grass-front
if (mirror) {
game.layerManager.addToLayer(mirror, LAYERS.MIRROR);
}
// Ensure jet1 and ufo1 sounds play when on screen
Jet1.prototype.update = function () {
// Fix: Use 'this' instead of 'self' since this is a prototype method
var jetGraphics = this.children[0];
flipImageVerticallyBasedOnDirection(jetGraphics, this.lastX, this.x);
this.x += this.speed * this.direction;
// Play jet sound when on screen
if (!this.soundPlayed && this.x > 0 && this.x < 2048) {
LK.getSound('jet1').play();
this.soundPlayed = true;
}
// Stop sound and destroy when off screen
if (this.lastX <= 2048 + this.width / 2 && this.x > 2048 + this.width / 2 || this.lastX >= -this.width / 2 && this.x < -this.width / 2) {
LK.getSound('jet1').stop();
this.destroy();
game.jet = null;
// Set respawn timer to 20-30 seconds
var respawnTime = Math.random() * 10000 + 20000;
game.jetSpawnTimer = LK.setTimeout(function () {
var jet = new Jet1();
jet.x = Math.random() < 0.5 ? 2048 + jet.width / 2 : -jet.width / 2;
jet.y = Math.random() * (2732 / 2);
game.addChild(jet);
game.layerManager.addToLayer(jet, LAYERS.JET1);
game.jet = jet;
game.jetSpawnTimer = null;
}, respawnTime);
}
this.lastX = this.x;
};
UFOMovement.prototype.update = function () {
var currentX = this.x;
var screenWidth = 2048;
var halfWidth = this.width / 2;
var tickCos = Math.cos(LK.ticks / 60);
var tickSin = Math.sin(LK.ticks / 120);
this.x += this.speed * tickCos;
this.y = 100 + tickSin * 250;
if (this.x > 0 && this.x < screenWidth && !this.soundPlayed) {
LK.getSound('ufo1').play();
this.soundPlayed = true;
}
if (this.x < 0 || this.x > screenWidth) {
this.soundPlayed = false;
}
if (currentX <= screenWidth + halfWidth && this.x > screenWidth + halfWidth || currentX >= -halfWidth && this.x < -halfWidth) {
LK.getSound('ufo1').stop();
this.destroy();
}
this.lastX = this.x;
}; ===================================================================
--- original.js
+++ change.js
@@ -6,254 +6,118 @@
/****
* Classes
****/
-var Background = Container.expand(function () {
+var GameObject = Container.expand(function (assetName, layerIndex, options) {
var self = Container.call(this);
- var backgroundGraphics = self.attachAsset('background', {
+ Container.call(this);
+ options = options || {};
+ this.graphics = this.attachAsset(assetName, Object.assign({
anchorX: 0.5,
anchorY: 0.5
- });
- self.addChild(backgroundGraphics);
- game.layerManager.addToLayer(self, LAYERS.BACKGROUND);
-});
-var Bird1 = Container.expand(function () {
- var self = Container.call(this);
- return BirdEntity.call(this, 'bird1', LAYERS.BIRD1, Bird1Movement);
-});
-var Bird2 = Container.expand(function () {
- var self = Container.call(this);
- return BirdEntity.call(this, 'bird2', LAYERS.BIRD2, Bird2Movement);
-});
-var BirdEntity = Container.expand(function (birdType, layerIndex, MovementClass) {
- var self = Container.call(this);
- var birdGraphics = self.attachAsset(birdType, {
- anchorX: 0.5,
- anchorY: 0.5
- });
- self.movement = new (MovementClass || DefaultMovement)(self, birdGraphics);
- if (typeof self.movement.update !== 'function') {
- self.movement.update = function () {
- // Default update logic
- };
- }
- // Override destroy method to remove from layer tracking
- var originalDestroy = self.destroy;
- self.destroy = function () {
- // Remove from layer tracking before destroying
+ }, options));
+ this.addChild(this.graphics);
+ // Common destroy method
+ var originalDestroy = this.destroy;
+ this.destroy = function () {
if (game.layerManager) {
- game.layerManager.removeFromTracking(self);
+ game.layerManager.removeFromTracking(this);
}
- // Call the original destroy method
- originalDestroy.call(self);
+ if (this.movement && this.movement.cleanup) {
+ this.movement.cleanup();
+ }
+ originalDestroy.call(this);
};
- self.update = function () {
- self.movement.update();
+ // Common update method
+ this.update = function () {
+ if (this.movement) {
+ this.movement.update();
+ }
};
- game.layerManager.addToLayer(self, layerIndex);
- return self;
+ if (layerIndex !== undefined) {
+ game.layerManager.addToLayer(this, layerIndex);
+ }
+ return this;
});
-var Cat = Container.expand(function () {
- var self = Container.call(this);
- var catGraphics = self.attachAsset('cat', {
- anchorX: 0.5,
- anchorY: 1
- });
- self.update = function () {};
- game.layerManager.addToLayer(self, LAYERS.CAT);
+var UFO2 = GameObject.expand(function () {
+ var self = GameObject.call(this);
+ GameObject.call(this, 'ufo2', LAYERS.UFO2);
+ this.type = 'ufo2';
+ this.movement = new GameObjectMovement(this, this.graphics, MovementConfigs.ufo2);
+ var originalUpdate = this.update;
+ this.update = function () {
+ originalUpdate.call(this);
+ if (!this.soundPlayed && this.x > 0 && this.x < 2048) {
+ LK.getSound('ufo1').play();
+ this.soundPlayed = true;
+ }
+ };
+ return this;
});
-// Define cloud types at the beginning
-var Cloud = Container.expand(function () {
- var self = Container.call(this);
- var cloudType = CLOUD_TYPES[Math.floor(Math.random() * CLOUD_TYPES.length)];
- var layerIndex = cloudType === 'cloud1' ? LAYERS.CLOUD1 : LAYERS.CLOUD2;
- return MovingEntity.call(this, cloudType, layerIndex, CloudMovement, {
- alpha: 0.8,
- updateCounts: true
- });
+var UFO1 = GameObject.expand(function () {
+ var self = GameObject.call(this);
+ GameObject.call(this, 'ufo1', LAYERS.UFO1);
+ this.type = 'ufo1';
+ this.movement = new GameObjectMovement(this, this.graphics, MovementConfigs.ufo1);
+ var originalUpdate = this.update;
+ this.update = function () {
+ originalUpdate.call(this);
+ if (!this.soundPlayed && this.x > 0 && this.x < 2048) {
+ LK.getSound('ufo1').play();
+ this.soundPlayed = true;
+ }
+ };
+ return this;
});
-var GrassBack = Container.expand(function () {
- var self = Container.call(this);
- var grassGraphics = self.attachAsset('grass-back', {
+var Tree2 = GameObject.expand(function () {
+ var self = GameObject.call(this);
+ return GameObject.call(this, 'tree2', LAYERS.TREE, {
anchorX: 0.5,
anchorY: 1
});
- self.update = function () {
- self.x += Math.sin((LK.ticks + 100) / 90) * 0.15; // Swaying effect, increased speed
- };
- self.addChild(grassGraphics); // Add grass graphics to the container
- // Set the layer index for grass-back
- game.layerManager.addToLayer(self, LAYERS.GRASS_BACK);
});
-var GrassFront = Container.expand(function () {
- var self = Container.call(this);
- var grass2Graphics = self.attachAsset('grass-front', {
+var Tree = GameObject.expand(function () {
+ var self = GameObject.call(this, 'tree1', LAYERS.TREE, {
anchorX: 0.5,
- anchorY: 1
+ anchorY: 1,
+ antialias: true,
+ stroke: 0x000000,
+ strokeThickness: 15
});
- self.lastX = self.x; // Initialize lastX for tracking changes on X
- self.addChild(grass2Graphics); // Add grass2 graphics to the container
- self.update = function () {
- self.x += Math.sin((LK.ticks + 50) / 100) * 0.125; // Swaying effect, reduced by 50%
- self.lastX = self.x; // Update lastX after movement
- };
- // Set the layer index for grass-front
- game.layerManager.addToLayer(self, LAYERS.GRASS_FRONT);
-});
-var Jet1 = Container.expand(function () {
- var self = Container.call(this, 'jet1', LAYERS.JET1, JetMovement, {
- flipX: true,
- flipOnMove: true,
- soundType: 'jet1'
- });
- self.speed = 10;
- self.direction = Math.random() < 0.5 ? 1 : -1;
- self.x = Math.random() < 0.5 ? 2048 + self.width / 2 : -self.width / 2;
- self.y = Math.random() * (2732 / 2);
- self.lastX = self.x;
- self.soundPlayed = false;
- self.update = function () {
- self.lastX = self.x;
- // Play sound when jet is on screen
- if (!self.soundPlayed && self.x > 0 && self.x < 2048) {
- LK.getSound('jet1').play();
- self.soundPlayed = true;
- }
- // Check if jet has moved off screen
- if (self.lastX <= 2048 + self.width / 2 && self.x > 2048 + self.width / 2 || self.lastX >= -self.width / 2 && self.x < -self.width / 2) {
- if (game.jetSpawnTimer) {
- LK.clearTimeout(game.jetSpawnTimer);
- }
- self.destroy();
- game.jet = null;
- // Schedule respawn after 20-30 seconds
- var respawnTime = Math.random() * 10000 + 20000;
- game.jetSpawnTimer = LK.setTimeout(function () {
- if (game.jet === null) {
- var jet = new Jet1();
- game.addChild(jet);
- game.layerManager.addToLayer(jet, LAYERS.JET1);
- game.jet = jet;
- }
- game.jetSpawnTimer = null;
- }, respawnTime);
- }
- };
return self;
});
-var Laser = Container.expand(function (startX, startY, targetX, targetY) {
- var self = Container.call(this);
- var laserGraphics = self.attachAsset('laser2', {
+var Sun = GameObject.expand(function () {
+ var self = GameObject.call(this);
+ GameObject.call(this, 'sun', LAYERS.SUN);
+ this.pulse = new SunPulse(this.graphics);
+ this.pulse.startPulsating();
+ return this;
+});
+var Stack1 = GameObject.expand(function () {
+ var self = GameObject.call(this);
+ GameObject.call(this, 'stack1', LAYERS.STACK, {
anchorX: 0.5,
anchorY: 0.5,
- brightness: 2.0
+ rotation: Math.PI / -12
});
- game.soundManager.playSound('laser1');
- var dx = targetX - startX;
- var dy = targetY - startY;
- var distance = Math.sqrt(dx * dx + dy * dy);
- var speed = 60;
- self.vx = dx / distance * speed;
- self.vy = dy / distance * speed;
- self.x = startX;
- self.y = startY;
- self.lastIntersecting = false;
- self.active = true;
- var originalDestroy = self.destroy;
- self.destroy = function () {
- if (game.layerManager) {
- game.layerManager.removeFromTracking(self);
- }
- originalDestroy.call(self);
- };
- self.update = function () {
- if (!self.active) {
- return;
- }
- var targets = game.children.filter(function (child) {
- return child instanceof Bird1 || child instanceof Bird2 || child instanceof UFO1 || child instanceof UFO2;
- });
- if (!self.lastIntersecting && game.collisionManager.checkCollisions(self, targets, function (laser, target) {
- var soundEffect = target instanceof UFO1 || target instanceof UFO2 ? 'dead3' : 'dead2';
- var scoreValue = 0;
- // Determine score based on target type
- if (target instanceof Bird1) {
- scoreValue = 5;
- } else if (target instanceof Bird2) {
- scoreValue = 1;
- } else if (target instanceof UFO1 || target instanceof UFO2) {
- scoreValue = 25;
- }
- // Update score and play sound
- if (spawnManager && spawnManager.scoreManager) {
- spawnManager.scoreManager.addScore(scoreValue);
- }
- game.soundManager.playSound(soundEffect);
- // Clean up target and update spawn manager
- if (spawnManager) {
- spawnManager.objectCounts[target.type] = Math.max(0, spawnManager.objectCounts[target.type] - 1);
- spawnManager.scheduleRespawn(target.type, target.constructor);
- }
- // Destroy target and laser
- target.destroy();
- self.active = false;
- self.destroy();
- // Update score display
- if (mirror && mirror.updateScore && spawnManager && spawnManager.scoreManager) {
- mirror.updateScore(spawnManager.scoreManager.getScore());
- }
- })) {
- return;
- }
- self.x += self.vx;
- self.y += self.vy;
- self.lastIntersecting = game.collisionManager.checkCollisions(self, targets);
- if (self.x < 0 || self.x > 2048 || self.y < 0 || self.y > 2732) {
- self.destroy();
- }
- };
- game.layerManager.addToLayer(self, LAYERS.LASER);
+ return this;
});
-var Light1 = Container.expand(function () {
- var self = Container.call(this);
- var lightGraphics = self.attachAsset('light1', {
- anchorX: 0.5,
- anchorY: 0.5
- });
- self.addChild(lightGraphics);
- game.layerManager.addToLayer(self, LAYERS.LIGHT1);
- var originalDestroy = self.destroy;
- self.destroy = function () {
- if (game.layerManager) {
- game.layerManager.removeFromTracking(self);
+var Reticle = GameObject.expand(function () {
+ var self = GameObject.call(this);
+ GameObject.call(this, 'reticle1', LAYERS.RETICLE);
+ var originalUpdate = this.update;
+ this.update = function () {
+ if (!this.pulse) {
+ this.pulse = new ReticlePulse(this.graphics);
+ this.pulse.startPulsating();
}
- originalDestroy.call(self);
+ originalUpdate.call(this);
};
- var lightGraphics = self.attachAsset('light1', {
- anchorX: 0.5,
- anchorY: 0.5,
- alpha: 1.0
- });
- self.addChild(lightGraphics);
- self.x = 450;
- self.y = 450;
- self.update = function () {
- self.x += Math.sin(LK.ticks / 90) * 0.1;
- };
- self.pulse = new Light1Pulse(lightGraphics);
- self.pulse.startPulsating();
- game.layerManager.addToLayer(self, LAYERS.LIGHT1);
+ return this;
});
-var Mirror = Container.expand(function () {
- var self = Container.call(this);
- var mirrorGraphics = self.attachAsset('mirror1', {
- anchorX: 0.5,
- anchorY: 0.5
- });
- self.addChild(mirrorGraphics);
- // Set the layer index for mirror
- game.layerManager.addToLayer(self, LAYERS.MIRROR);
- // Score display functionality
+var Mirror = GameObject.expand(function () {
+ var self = GameObject.call(this);
+ GameObject.call(this, 'mirror1', LAYERS.MIRROR);
var scoreText = new Text2('0', {
size: 175,
fill: 0x800080,
font: "Courier New, Courier, monospace",
@@ -264,177 +128,203 @@
dropShadowBlur: 5,
dropShadowAngle: Math.PI / 6,
dropShadowDistance: 6
});
- scoreText.y = 260 + 50; // Move down 50px
+ scoreText.y = 260 + 50;
scoreText.x = -155;
- scoreText.rotation = (-83 - 3) * (Math.PI / 180); // Rotate left by 3 degrees
- self.addChild(scoreText);
- self.updateScore = function (newScore) {
+ scoreText.rotation = (-83 - 3) * (Math.PI / 180);
+ this.addChild(scoreText);
+ this.updateScore = function (newScore) {
scoreText.setText(newScore);
};
- return self;
+ return this;
});
-var MovingEntity = Container.expand(function (assetType, layerIndex, MovementClass, options) {
- var self = Container.call(this);
- options = options || {};
- var graphics = self.attachAsset(assetType, {
+var Light1 = GameObject.expand(function () {
+ var self = GameObject.call(this);
+ GameObject.call(this, 'light1', LAYERS.LIGHT1, {
anchorX: 0.5,
- anchorY: options.anchorY || 0.5,
- alpha: options.alpha || 1,
- flipX: options.flipX || false
+ anchorY: 0.5,
+ alpha: 1.0
});
- self.type = assetType;
- self.movement = new MovementClass(self, graphics, {
- spawnManager: game.spawnManager
- });
- self.lastX = self.x;
- self.soundPlayed = false;
- // Override destroy method to remove from layer tracking
- var originalDestroy = self.destroy;
- self.destroy = function () {
- // Stop all associated sounds
- if (options.soundType) {
- game.soundManager.stopSound(options.soundType);
- }
- // Clear movement timers and sounds
- if (self.movement) {
- if (self.movement.soundTimer) {
- LK.clearTimeout(self.movement.soundTimer);
- self.movement.soundTimer = null;
- }
- if (self.movement.respawnTimer) {
- LK.clearTimeout(self.movement.respawnTimer);
- self.movement.respawnTimer = null;
- }
- }
- // Update entity counts and schedule respawn
- if (options.updateCounts && spawnManager) {
- spawnManager.objectCounts[self.type] = Math.max(0, spawnManager.objectCounts[self.type] - 1);
- if (spawnManager.spawnRules[self.type]) {
- spawnManager.scheduleRespawn(self.type, self.constructor);
- }
- }
- // Remove from layer management
- if (game.layerManager) {
- game.layerManager.removeFromTracking(self);
- }
- // Call original destroy
- originalDestroy.call(self);
+ this.x = 450;
+ this.y = 450;
+ this.update = function () {
+ this.x += Math.sin(LK.ticks / 90) * 0.1;
};
- self.update = function () {
- if (options.flipOnMove) {
- flipImageVerticallyBasedOnDirection(graphics, self.lastX, self.x);
- }
- self.movement.update();
- if (options.soundType && !self.soundPlayed && self.x > 0 && self.x < 2048) {
- LK.getSound(options.soundType).play();
- self.soundPlayed = true;
- }
- self.lastX = self.x;
- };
- game.layerManager.addToLayer(self, layerIndex);
- return self;
+ this.pulse = new Light1Pulse(this.graphics);
+ this.pulse.startPulsating();
+ return this;
});
-var Reticle = Container.expand(function () {
- var self = Container.call(this);
- var reticleGraphics = self.attachAsset('reticle1', {
- anchorX: 0.5,
- anchorY: 0.5
+var Jet1 = GameObject.expand(function () {
+ var self = GameObject.call(this);
+ GameObject.call(this, 'jet1', LAYERS.JET1);
+ this.type = 'jet1';
+ this.movement = new GameObjectMovement(this, this.graphics, {
+ speed: 10,
+ speedRange: 0,
+ arcAmplitude: 0,
+ arcFrequency: 0,
+ isVertical: false,
+ canFlip: true,
+ moveSound: 'jet1'
});
- self.update = function () {
- if (!self.pulse) {
- self.pulse = new ReticlePulse(reticleGraphics);
- self.pulse.startPulsating();
+ this.soundPlayed = false;
+ var originalUpdate = this.update;
+ this.update = function () {
+ originalUpdate.call(this);
+ // Play jet1 sound when on screen
+ if (!this.soundPlayed && this.x > 0 && this.x < 2048) {
+ LK.getSound('jet1').play();
+ this.soundPlayed = true;
}
};
- game.layerManager.addToLayer(self, LAYERS.RETICLE);
+ return this;
});
-var Reticle1 = Container.expand(function () {
- var self = Container.call(this);
- var reticle1Graphics = self.attachAsset('reticle1', {
+var GrassFront = GameObject.expand(function () {
+ var self = GameObject.call(this);
+ GameObject.call(this, 'grass-front', LAYERS.GRASS_FRONT, {
anchorX: 0.5,
- anchorY: 0.5
+ anchorY: 1
});
- self.addChild(reticle1Graphics);
- // Set the layer index for reticle
- game.layerManager.addToLayer(self, LAYERS.RETICLE);
+ this.lastX = this.x;
+ this.update = function () {
+ this.x += Math.sin((LK.ticks + 50) / 100) * 0.125; // Swaying effect, reduced by 50%
+ this.lastX = this.x;
+ };
+ return this;
});
-var Stack1 = Container.expand(function () {
- var self = Container.call(this);
- var stackGraphics = self.attachAsset('stack1', {
+var GrassBack = GameObject.expand(function () {
+ var self = GameObject.call(this);
+ GameObject.call(this, 'grass-back', LAYERS.GRASS_BACK, {
anchorX: 0.5,
- anchorY: 0.5,
- rotation: Math.PI / -12
+ anchorY: 1
});
- self.update = function () {
- // Add any specific update logic for stack1 here
+ this.update = function () {
+ this.x += Math.sin((LK.ticks + 100) / 90) * 0.15; // Swaying effect, increased speed
};
- // Set the layer index for stack
- game.layerManager.addToLayer(self, LAYERS.STACK);
+ return this;
});
-var Sun = Container.expand(function () {
- var self = Container.call(this);
- var sunGraphics = self.attachAsset('sun', {
+var Cloud = GameObject.expand(function () {
+ var self = GameObject.call(this);
+ var cloudType = CLOUD_TYPES[Math.floor(Math.random() * CLOUD_TYPES.length)];
+ var layerIndex = cloudType === 'cloud1' ? LAYERS.CLOUD1 : LAYERS.CLOUD2;
+ GameObject.call(this, cloudType, layerIndex, {
anchorX: 0.5,
- anchorY: 0.5
+ anchorY: 0.5,
+ alpha: 0.8
});
- self.pulse = new SunPulse(sunGraphics);
- self.pulse.startPulsating();
- // Set the layer index for sun
- game.layerManager.addToLayer(self, LAYERS.SUN);
-});
-var Tree = Container.expand(function () {
- var self = Container.call(this);
- var treeGraphics = self.attachAsset('tree1', {
- anchorX: 0.5,
- anchorY: 1,
- antialias: true,
- // Apply antialias effect
- stroke: 0x000000,
- // Add a black stroke
- strokeThickness: 15 // Set stroke thickness to 15px
- });
- self.update = function () {
- // Add any specific update logic for the tree here
+ this.cloudType = cloudType;
+ this.movement = new CloudMovement(this, this.graphics);
+ var originalDestroy = this.destroy;
+ this.destroy = function () {
+ if (spawnManager) {
+ spawnManager.objectCounts[this.cloudType === 'cloud1' ? 'cloud1' : 'cloud2']--;
+ }
+ originalDestroy.call(this);
};
- // Set the layer index for tree
- game.layerManager.addToLayer(self, LAYERS.TREE);
+ return this;
});
-var Tree2 = Container.expand(function () {
- var self = Container.call(this);
- var tree2Graphics = self.attachAsset('tree2', {
+var Cat = GameObject.expand(function () {
+ var self = GameObject.call(this);
+ GameObject.call(this, 'cat', LAYERS.CAT, {
anchorX: 0.5,
anchorY: 1
});
- self.addChild(tree2Graphics);
- // Set the layer index for tree2
- game.layerManager.addToLayer(self, LAYERS.TREE);
+ return this;
});
-var UFO = Container.expand(function () {
+// Define cloud types at the beginning
+var Bird2 = GameObject.expand(function () {
+ var self = GameObject.call(this);
+ GameObject.call(this, 'bird2', LAYERS.BIRD2);
+ this.type = 'bird2';
+ this.movement = new GameObjectMovement(this, this.graphics, MovementConfigs.bird2);
+ return this;
+});
+var Bird1 = GameObject.expand(function () {
+ var self = GameObject.call(this);
+ GameObject.call(this, 'bird1', LAYERS.BIRD1);
+ this.type = 'bird1';
+ this.movement = new GameObjectMovement(this, this.graphics, MovementConfigs.bird1);
+ return this;
+});
+var Background = GameObject.expand(function () {
+ var self = GameObject.call(this);
+ return GameObject.call(this, 'background', LAYERS.BACKGROUND);
+});
+var Laser = Container.expand(function (startX, startY, targetX, targetY) {
var self = Container.call(this);
- var ufoGraphics = self.attachAsset('ufo2', {
+ var laserGraphics = self.attachAsset('laser2', {
anchorX: 0.5,
- anchorY: 0.5
+ anchorY: 0.5,
+ brightness: 2.0
});
- self.movement = new UFOMovement(self, ufoGraphics);
- game.layerManager.addToLayer(self, LAYERS.UFO2);
-});
-var UFO1 = Container.expand(function () {
- var self = Container.call(this);
- return MovingEntity.call(this, 'ufo1', LAYERS.UFO1, UFOMovement, {
- soundType: 'ufo1'
- });
-});
-var UFO2 = Container.expand(function () {
- var self = Container.call(this, 'ufo2', LAYERS.UFO2, UFOMovement, {});
- game.layerManager.addToLayer(self, LAYERS.UFO2);
+ LK.getSound('laser1').play();
+ var dx = targetX - startX;
+ var dy = targetY - startY;
+ var distance = Math.sqrt(dx * dx + dy * dy);
+ var speed = 60;
+ self.vx = dx / distance * speed;
+ self.vy = dy / distance * speed;
+ self.x = startX;
+ self.y = startY;
+ self.lastIntersecting = false;
+ self.active = true;
+ var originalDestroy = self.destroy;
+ self.destroy = function () {
+ if (game.layerManager) {
+ game.layerManager.removeFromTracking(self);
+ }
+ originalDestroy.call(self);
+ };
+ self.update = function () {
+ if (!self.active) {
+ return;
+ }
+ // Move first
+ self.x += self.vx;
+ self.y += self.vy;
+ // Check collisions only with relevant layers
+ var targetLayers = [LAYERS.BIRD1, LAYERS.BIRD2, LAYERS.UFO1, LAYERS.UFO2];
+ var collided = false;
+ for (var i = 0; i < targetLayers.length && !collided; i++) {
+ var targets = game.layerManager.getLayerObjects(targetLayers[i]);
+ for (var j = 0; j < targets.length && !collided; j++) {
+ var target = targets[j];
+ if (!self.lastIntersecting && self.intersects(target)) {
+ var soundEffect = target instanceof UFO1 || target instanceof UFO2 ? 'dead3' : 'dead2';
+ LK.getSound(soundEffect).play();
+ // Update score based on target type
+ var scoreValue = 0;
+ if (target instanceof Bird1) {
+ scoreValue = 5;
+ } else if (target instanceof Bird2) {
+ scoreValue = 1;
+ } else if (target instanceof UFO1 || target instanceof UFO2) {
+ scoreValue = 25;
+ }
+ score += scoreValue;
+ if (game.mirror) {
+ game.mirror.updateScore(score);
+ }
+ target.destroy();
+ collided = true;
+ }
+ }
+ }
+ // Update intersection state
+ self.lastIntersecting = collided;
+ // Destroy if out of bounds
+ if (self.x < 0 || self.x > 2048 || self.y < 0 || self.y > 2732) {
+ self.destroy();
+ }
+ };
return self;
});
/****
* Initialize Game
****/
+// BaseEntityManager removed - using EntityManager defined at the beginning of the file
// Initialize clouds array
var game = new LK.Game({
// No title, no description
backgroundColor: 0x87CEEB // Sky blue
@@ -442,85 +332,11 @@
/****
* Game Code
****/
-// Define cloud types at the beginning
-var DefaultMovement = function DefaultMovement(entity, graphics) {
- this.entity = entity;
- this.graphics = graphics;
- this.update = function () {
- // Default update logic, can be customized
- this.entity.x += 1; // Example movement logic
- }.bind(this);
-};
-var JetManager = function JetManager() {
- this.jets = [];
- this.addJet = function (jet) {
- this.jets.push(jet);
- game.addChild(jet);
- };
- this.removeJet = function (jet) {
- var index = this.jets.indexOf(jet);
- if (index > -1) {
- this.jets.splice(index, 1);
- jet.destroy();
- }
- };
- this.update = function () {
- this.jets.forEach(function (jet) {
- jet.update();
- });
- };
-};
-var UFOManager = function UFOManager() {
- this.ufos = [];
- this.addUFO = function (ufo) {
- this.ufos.push(ufo);
- game.addChild(ufo);
- };
- this.removeUFO = function (ufo) {
- var index = this.ufos.indexOf(ufo);
- if (index > -1) {
- this.ufos.splice(index, 1);
- ufo.destroy();
- }
- };
- this.update = function () {
- this.ufos.forEach(function (ufo) {
- ufo.update();
- });
- };
-};
-var BirdManager = function BirdManager() {
- this.birds = [];
- this.addBird = function (bird) {
- this.birds.push(bird);
- game.addChild(bird);
- };
- this.removeBird = function (bird) {
- var index = this.birds.indexOf(bird);
- if (index > -1) {
- this.birds.splice(index, 1);
- bird.destroy();
- }
- };
- this.update = function () {
- this.birds.forEach(function (bird) {
- bird.update();
- });
- };
-};
-var JetMovement = function JetMovement(jet, jetGraphics) {
- return new GameObjectMovement(jet, jetGraphics, {
- speed: 10,
- speedRange: 0,
- arcAmplitude: 0,
- arcFrequency: 0,
- isVertical: false,
- canFlip: true,
- moveSound: 'jet1'
- });
-};
+// Base GameObject class to handle common functionality
+// CloudMovement class to handle cloud movement and fade effects
+// Unified GameObjectMovement class with improved movement patterns and sound management
function _typeof2(o) {
"@babel/helpers - typeof";
return _typeof2 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
return typeof o;
@@ -577,8 +393,24 @@
}
}
};
}
+function _unsupportedIterableToArray(r, a) {
+ if (r) {
+ if ("string" == typeof r) {
+ return _arrayLikeToArray(r, a);
+ }
+ var t = {}.toString.call(r).slice(8, -1);
+ return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
+ }
+}
+function _arrayLikeToArray(r, a) {
+ (null == a || a > r.length) && (a = r.length);
+ for (var e = 0, n = Array(a); e < a; e++) {
+ n[e] = r[e];
+ }
+ return n;
+}
function _classCallCheck2(a, n) {
if (!(a instanceof n)) {
throw new TypeError("Cannot call a class as a function");
}
@@ -611,74 +443,79 @@
throw new TypeError("@@toPrimitive must return a primitive value.");
}
return ("string" === r ? String : Number)(t);
}
-function _slicedToArray(r, e) {
- return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();
-}
-function _nonIterableRest() {
- throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
-}
-function _unsupportedIterableToArray(r, a) {
- if (r) {
- if ("string" == typeof r) {
- return _arrayLikeToArray(r, a);
- }
- var t = {}.toString.call(r).slice(8, -1);
- return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
+var EntityManager = /*#__PURE__*/function () {
+ function EntityManager() {
+ _classCallCheck2(this, EntityManager);
+ this.entities = [];
}
-}
-function _arrayLikeToArray(r, a) {
- (null == a || a > r.length) && (a = r.length);
- for (var e = 0, n = Array(a); e < a; e++) {
- n[e] = r[e];
- }
- return n;
-}
-function _iterableToArrayLimit(r, l) {
- var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
- if (null != t) {
- var e,
- n,
- i,
- u,
- a = [],
- f = !0,
- o = !1;
- try {
- if (i = (t = t.call(r)).next, 0 === l) {
- if (Object(t) !== t) {
- return;
- }
- f = !1;
- } else {
- for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0) {
- ;
- }
+ return _createClass2(EntityManager, [{
+ key: "add",
+ value: function add(entity) {
+ this.entities.push(entity);
+ if (game.layerManager && entity.layer !== undefined) {
+ game.layerManager.addToLayer(entity, entity.layer);
}
- } catch (r) {
- o = !0, n = r;
- } finally {
+ }
+ }, {
+ key: "remove",
+ value: function remove(entity) {
+ var index = this.entities.indexOf(entity);
+ if (index > -1) {
+ this.entities.splice(index, 1);
+ entity.destroy();
+ }
+ }
+ }, {
+ key: "update",
+ value: function update(deltaTime) {
+ var _iterator = _createForOfIteratorHelper(this.entities),
+ _step;
try {
- if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) {
- return;
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
+ var entity = _step.value;
+ if (entity.update) {
+ entity.update(deltaTime);
+ }
}
+ } catch (err) {
+ _iterator.e(err);
} finally {
- if (o) {
- throw n;
- }
+ _iterator.f();
}
}
- return a;
+ }, {
+ key: "getAllOfType",
+ value: function getAllOfType(type) {
+ return this.entities.filter(function (entity) {
+ return entity instanceof type;
+ });
+ }
+ }, {
+ key: "clear",
+ value: function clear() {
+ this.entities.forEach(function (entity) {
+ return entity.destroy();
+ });
+ this.entities = [];
+ }
+ }]);
+}(); // Define cloud types at the beginning
+var CLOUD_TYPES = ['cloud1', 'cloud2'];
+function respawnJet() {
+ if (game.jet === null) {
+ var jet = new Jet1();
+ jet.x = Math.random() < 0.5 ? 2048 + jet.width / 2 : -jet.width / 2;
+ jet.y = Math.random() * (2732 / 2);
+ game.addChild(jet);
+ game.layerManager.addToLayer(jet, LAYERS.JET1);
+ game.jet = jet;
}
+ game.jetSpawnTimer = null;
}
-function _arrayWithHoles(r) {
- if (Array.isArray(r)) {
- return r;
- }
-}
-var CLOUD_TYPES = ['cloud1', 'cloud2'];
var GameObjectMovement = function GameObjectMovement(object, graphics, options) {
+ ;
this.object = object;
this.graphics = graphics;
this.options = Object.assign({
speed: 2,
@@ -691,79 +528,77 @@
respawnTime: {
min: 20000,
max: 30000
},
- maxInstances: 5
+ screenWidth: 2048,
+ screenHeight: 2732
}, options);
this.speed = this.options.speed + Math.random() * this.options.speedRange;
this.direction = Math.random() < 0.5 ? 1 : -1;
this.lastX = this.object.x;
this.lastY = this.object.y;
this.soundPlayed = false;
this.soundTimer = null;
- this.respawnTimer = null;
- // Initialize spawn tracking
- if (this.options.spawnManager) {
- if (!this.options.spawnManager.objectCounts[object.type]) {
- this.options.spawnManager.objectCounts[object.type] = 1;
- } else {
- this.options.spawnManager.objectCounts[object.type]++;
- }
- }
+ this.movementOffset = Math.random() * Math.PI * 2; // Random starting phase for smoother movement
this.update = function () {
var currentX = this.object.x;
var currentY = this.object.y;
- var screenWidth = 2048;
- var screenHeight = 2732;
var halfWidth = this.object.width / 2;
if (this.options.isVertical) {
this.object.y += this.speed;
- this.object.x += Math.sin(this.object.y / this.options.arcFrequency) * this.options.arcAmplitude;
- if (currentY > screenHeight + this.object.height) {
- this.object.destroy();
- if (this.options.spawnManager) {
- this.options.spawnManager.scheduleRespawn(this.object.type, this.object.constructor);
- }
+ // Improved sinusoidal movement with phase offset for smoother motion
+ this.object.x += Math.sin(this.object.y / this.options.arcFrequency + this.movementOffset) * this.options.arcAmplitude;
+ if (currentY > this.options.screenHeight + this.object.height) {
+ this.cleanup();
return;
}
} else {
+ // Improved horizontal movement with optional wave pattern
this.object.x += this.speed * this.direction;
- if (currentX <= screenWidth + halfWidth && this.object.x > screenWidth + halfWidth || currentX >= -halfWidth && this.object.x < -halfWidth) {
- this.object.destroy();
- if (this.options.spawnManager) {
- this.options.spawnManager.scheduleRespawn(this.object.type, this.object.constructor);
- }
+ if (this.options.arcAmplitude > 0) {
+ this.object.y += Math.sin(this.object.x / this.options.arcFrequency + this.movementOffset) * (this.options.arcAmplitude * 0.5);
+ }
+ if (currentX <= this.options.screenWidth + halfWidth && this.object.x > this.options.screenWidth + halfWidth || currentX >= -halfWidth && this.object.x < -halfWidth) {
+ this.cleanup();
return;
}
}
if (this.options.canFlip) {
flipImageVerticallyBasedOnDirection(this.graphics, currentX, this.object.x);
}
- if (this.options.moveSound && !this.soundPlayed && this.object.x > 0 && this.object.x < screenWidth) {
- if (this.soundTimer) {
- LK.clearTimeout(this.soundTimer);
- }
- var sound = LK.getSound(this.options.moveSound);
- sound.volume = 0.1;
- sound.play();
- this.soundPlayed = true;
- this.soundTimer = LK.setTimeout(function () {
- this.soundPlayed = false;
- this.soundTimer = null;
- }.bind(this), Math.random() * (30000 - 20000) + 20000);
+ if (this.options.moveSound && !this.soundPlayed && this.object.x > 0 && this.object.x < this.options.screenWidth) {
+ this.playMovementSound();
}
this.lastX = this.object.x;
this.lastY = this.object.y;
}.bind(this);
+ this.cleanup = function () {
+ if (this.soundTimer) {
+ LK.clearTimeout(this.soundTimer);
+ this.soundTimer = null;
+ }
+ if (this.object && !this.object.destroyed) {
+ this.object.destroy();
+ if (spawnManager) {
+ spawnManager.scheduleRespawn(this.object.type, this.object.constructor);
+ }
+ }
+ };
+ this.playMovementSound = function () {
+ if (this.soundTimer) {
+ LK.clearTimeout(this.soundTimer);
+ }
+ var sound = LK.getSound(this.options.moveSound);
+ sound.volume = 0.1;
+ sound.play();
+ this.soundPlayed = true;
+ this.soundTimer = LK.setTimeout(function () {
+ this.soundPlayed = false;
+ this.soundTimer = null;
+ }.bind(this), Math.random() * (30000 - 20000) + 20000);
+ };
};
-var CloudMovement = function CloudMovement(cloud, cloudGraphics) {
- return new GameObjectMovement(cloud, cloudGraphics, {
- speed: 0.25,
- speedRange: 0.55,
- isVertical: false,
- canFlip: false
- });
-};
+// Cloud class already defined above
function _typeof(o) {
"@babel/helpers - typeof";
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
return typeof o;
@@ -804,681 +639,43 @@
throw new TypeError("@@toPrimitive must return a primitive value.");
}
return ("string" === r ? String : Number)(t);
}
-/*****
+/*****
* Layer Constants
-****/
-// Shared layer configuration with metadata
-var LAYER_CONFIG = {
- BACKGROUND: {
- index: 0,
- zIndex: 0
- },
- SUN: {
- index: 1,
- zIndex: 10
- },
- LIGHT1: {
- index: 2,
- zIndex: 20
- },
- UFO2: {
- index: 3,
- zIndex: 30
- },
- CLOUD1: {
- index: 4,
- zIndex: 40
- },
- JET1: {
- index: 5,
- zIndex: 50
- },
- CLOUD2: {
- index: 6,
- zIndex: 60
- },
- UFO1: {
- index: 7,
- zIndex: 70
- },
- BIRD1: {
- index: 8,
- zIndex: 80
- },
- GRASS_BACK: {
- index: 9,
- zIndex: 90
- },
- TREE: {
- index: 10,
- zIndex: 100
- },
- STACK: {
- index: 11,
- zIndex: 110
- },
- BIRD2: {
- index: 12,
- zIndex: 120
- },
- MIRROR: {
- index: 13,
- zIndex: 130
- },
- GRASS_FRONT: {
- index: 14,
- zIndex: 140
- },
- CAT: {
- index: 15,
- zIndex: 150
- },
- LASER: {
- index: 16,
- zIndex: 160
- },
- RETICLE: {
- index: 17,
- zIndex: 170
- }
+******/
+var LAYERS = {
+ BACKGROUND: 0,
+ SUN: 1,
+ LIGHT1: 2,
+ UFO2: 3,
+ CLOUD1: 4,
+ JET1: 5,
+ CLOUD2: 6,
+ UFO1: 7,
+ BIRD1: 8,
+ GRASS_BACK: 9,
+ TREE: 10,
+ STACK: 11,
+ BIRD2: 12,
+ MIRROR: 13,
+ GRASS_FRONT: 14,
+ CAT: 15,
+ LASER: 16,
+ RETICLE: 17
};
-// Maintain backward compatibility
-var LAYERS = Object.fromEntries(Object.entries(LAYER_CONFIG).map(function (_ref) {
- var _ref2 = _slicedToArray(_ref, 2),
- key = _ref2[0],
- value = _ref2[1];
- return [key, value.index];
-}));
-/*****
-* Layer Management System
-****/
-var LayerManager = /*#__PURE__*/function () {
- function LayerManager(gameInstance) {
- _classCallCheck(this, LayerManager);
- this.game = gameInstance;
- this.layerMap = {};
- // Layer order mapping to ensure correct rendering order
- this.layerOrder = [LAYERS.BACKGROUND, LAYERS.SUN, LAYERS.LIGHT1, LAYERS.UFO2, LAYERS.CLOUD1, LAYERS.JET1, LAYERS.CLOUD2, LAYERS.UFO1, LAYERS.BIRD1, LAYERS.GRASS_BACK, LAYERS.TREE, LAYERS.STACK, LAYERS.BIRD2, LAYERS.MIRROR, LAYERS.GRASS_FRONT, LAYERS.CAT, LAYERS.LASER, LAYERS.RETICLE];
- }
- return _createClass(LayerManager, [{
- key: "setLayerIndex",
- value: function setLayerIndex(object, layerId) {
- if (!object || !this.game.children.includes(object)) {
- return;
- }
- // Ensure the layer ID is valid and within bounds
- layerId = Math.max(0, Math.min(layerId, this.game.children.length));
- // Set the child index
- if (layerId < this.game.children.length) {
- this.game.setChildIndex(object, layerId);
- }
- // Update the layer map
- this.layerMap[object.id] = layerId;
- }
- }, {
- key: "getObjectsInLayer",
- value: function getObjectsInLayer(layerId) {
- var objects = [];
- for (var id in this.layerMap) {
- if (this.layerMap[id] === layerId) {
- // Find the object in the game's children
- for (var i = 0; i < this.game.children.length; i++) {
- var child = this.game.children[i];
- if (child.id === id) {
- objects.push(child);
- break;
- }
- }
- }
- }
- return objects;
- }
- /**
- * Add an object to a specific layer
- * @param {Object} object - The game object to add
- * @param {Number} layerId - The layer ID
- */
- }, {
- key: "addToLayer",
- value: function addToLayer(object, layerId) {
- if (!object || !object.id) {
- return;
- }
- // Add the object if it's not already a child
- if (!this.game.children.includes(object)) {
- this.game.addChild(object);
- }
- // Set the child index to match the LAYERS order
- this.game.setChildIndex(object, layerId);
- // Update the layer map
- this.layerMap[object.id] = layerId;
- }
- /**
- * Get the layer of an object
- * @param {Object} object - The game object
- * @return {Number} The layer ID or -1 if not found
- */
- }, {
- key: "getObjectLayer",
- value: function getObjectLayer(object) {
- if (!object || !object.id) {
- return -1;
- }
- return this.layerMap[object.id] !== undefined ? this.layerMap[object.id] : -1;
- }
- /**
- * Remove an object from layer tracking
- * @param {Object} object - The game object to remove
- */
- }, {
- key: "removeFromTracking",
- value: function removeFromTracking(object) {
- if (!object || !object.id) {
- return;
- }
- delete this.layerMap[object.id];
- }
- /**
- * Bring an object to the front of its layer
- * @param {Object} object - The game object
- */
- }, {
- key: "bringToFrontOfLayer",
- value: function bringToFrontOfLayer(object) {
- if (!object || !object.id) {
- return;
- }
- var layerId = this.getObjectLayer(object);
- if (layerId === -1) {
- return;
- }
- // Find the highest index within this layer
- var highestIndex = layerId;
- for (var id in this.layerMap) {
- if (this.layerMap[id] === layerId) {
- // Find the object in the game's children
- for (var i = 0; i < this.game.children.length; i++) {
- var child = this.game.children[i];
- if (child.id === id && i > highestIndex) {
- highestIndex = i;
- }
- }
- }
- }
- // Set the object to the highest index within its layer
- this.game.setChildIndex(object, highestIndex);
- }
- /**
- * Send an object to the back of its layer
- * @param {Object} object - The game object
- */
- }, {
- key: "sendToBackOfLayer",
- value: function sendToBackOfLayer(object) {
- if (!object || !object.id) {
- return;
- }
- var layerId = this.getObjectLayer(object);
- if (layerId === -1) {
- return;
- }
- // Find the lowest index within this layer
- var lowestIndex = layerId;
- for (var id in this.layerMap) {
- if (this.layerMap[id] === layerId) {
- // Find the object in the game's children
- for (var i = 0; i < this.game.children.length; i++) {
- var child = this.game.children[i];
- if (child.id === id && i < lowestIndex) {
- lowestIndex = i;
- }
- }
- }
- }
- // Set the object to the lowest index within its layer
- this.game.setChildIndex(object, lowestIndex);
- }
- /**
- * Helper function to add multiple objects to a layer at once
- * @param {Array} objects - Array of game objects
- * @param {Number} layerId - The layer ID
- */
- }, {
- key: "addMultipleToLayer",
- value: function addMultipleToLayer(objects, layerId) {
- var _this2 = this;
- if (!Array.isArray(objects)) {
- return;
- }
- objects.forEach(function (object) {
- return _this2.addToLayer(object, layerId);
- });
- }
- }]);
-}();
-game.layerManager = new LayerManager(game);
-// Using UFO sound ID as placeholder
-function flipImageVerticallyBasedOnDirection(graphics, lastX, currentX) {
- if (graphics) {
- if (lastX < currentX && graphics.scaleX < 0) {
- graphics.scaleX *= -1; // Flip horizontally to face right
- } else if (lastX > currentX && graphics.scaleX > 0) {
- graphics.scaleX *= -1; // Flip horizontally to face left
- }
- }
-}
-function flipImageBasedOnDirection(graphics, lastX, currentX) {
- if (graphics) {
- if (lastX < currentX) {
- graphics.scaleY = Math.abs(graphics.scaleY); // Face right when moving right by ensuring scaleY is positive
- } else if (lastX > currentX) {
- graphics.scaleY = -Math.abs(graphics.scaleY); // Face left when moving left by ensuring scaleY is negative
- }
- }
-}
-// SunPulse class to handle the pulsating effect for Sun
-var CollisionManager = function CollisionManager() {
- this.checkIntersection = function (obj1, obj2) {
- if (!obj1 || !obj2) {
- return false;
- }
- return obj1.x < obj2.x + obj2.width && obj1.x + obj1.width > obj2.x && obj1.y < obj2.y + obj2.height && obj1.y + obj1.height > obj2.y;
- };
- this.checkCollisions = function (source, targets, onCollision) {
- if (!Array.isArray(targets)) {
- targets = [targets];
- }
- for (var i = 0; i < targets.length; i++) {
- if (this.checkIntersection(source, targets[i])) {
- if (onCollision) {
- onCollision(source, targets[i]);
- }
- return true;
- }
- }
- return false;
- };
-};
-// Initialize collision manager
-game.collisionManager = new CollisionManager();
-// Using existing CLOUD_TYPES definition
-var Pulse = function Pulse(graphics, options) {
- this.graphics = graphics;
- this.options = Object.assign({
- minScale: 1.0,
- maxScale: 1.2,
- expandDuration: 1000,
- contractDuration: 1000,
- easing: tween.easeInOut
- }, options);
- this.startPulsating = function () {
- function pulsate() {
- tween(this.graphics, {
- scaleX: this.options.maxScale,
- scaleY: this.options.maxScale
- }, {
- duration: this.options.expandDuration,
- easing: this.options.easing,
- onFinish: function () {
- tween(this.graphics, {
- scaleX: this.options.minScale,
- scaleY: this.options.minScale
- }, {
- duration: this.options.contractDuration,
- easing: this.options.easing,
- onFinish: pulsate.bind(this)
- });
- }.bind(this)
- });
- }
- pulsate.call(this);
- };
-};
-// Reusable pulse configurations
-var PULSE_CONFIGS = {
- sun: {
- maxScale: 1.1
- },
- light: {
- maxScale: 1.6,
- contractDuration: 1500
- },
- reticle: {
- maxScale: 1.2
- }
-};
-var SunPulse = function SunPulse(graphics) {
- return new Pulse(graphics, PULSE_CONFIGS.sun);
-};
-var Light1Pulse = function Light1Pulse(graphics) {
- return new Pulse(graphics, PULSE_CONFIGS.light);
-};
-var ReticlePulse = function ReticlePulse(graphics) {
- return new Pulse(graphics, PULSE_CONFIGS.reticle);
-};
-var bird2; // Define bird2 variable in the global scope
-// UFOMovement class to handle UFO movement
-var UFOMovement = function UFOMovement(ufo, ufoGraphics) {
- return new GameObjectMovement(ufo, ufoGraphics, {
- speed: 3.2,
- speedRange: 0.8,
- arcAmplitude: 0,
- isVertical: false,
- canFlip: true,
- moveSound: 'ufo1',
- customMovement: function customMovement(object) {
- var tickCos = Math.cos(LK.ticks / 60);
- var tickSin = Math.sin(LK.ticks / 120);
- object.x += object.speed * tickCos;
- object.y = 100 + tickSin * 250;
- }
- });
-};
-// Unified sound management system
-var SoundManager = function SoundManager() {
- var soundConfigs = {
- ufo1: {
- volume: 0.1,
- loop: false
- },
- bgm1: {
- volume: 0.1,
- loop: true,
- fade: {
- start: 0,
- end: 1,
- duration: 4000
- }
- },
- laser1: {
- volume: 0.1,
- loop: false
- },
- wings1: {
- volume: 0.1,
- loop: false
- },
- dead1: {
- volume: 0.1,
- loop: false
- },
- dead2: {
- volume: 0.1,
- loop: false
- },
- dead3: {
- volume: 0.1,
- loop: false
- },
- jet1: {
- volume: 0.1,
- loop: false
- },
- breeze1: {
- volume: 0.1,
- loop: true
- },
- chitter: {
- volume: 0.1,
- loop: true
- },
- cricket1: {
- volume: 0.1,
- loop: true
- },
- frog1: {
- volume: 0.1,
- loop: true
- },
- songbird1: {
- volume: 0.1,
- loop: true
- }
- };
- var activeLoopingSounds = {};
- this.playSound = function (soundId, options) {
- var config = Object.assign({}, soundConfigs[soundId] || {}, options || {});
- var sound = LK.getSound(soundId);
- if (sound) {
- sound.volume = config.volume;
- if (config.fade) {
- sound.fade(config.fade.start, config.fade.end, config.fade.duration);
- }
- if (config.loop) {
- sound.loop();
- activeLoopingSounds[soundId] = sound;
- }
- sound.play();
- return sound;
- }
- return null;
- };
- this.stopSound = function (soundId) {
- var sound = LK.getSound(soundId);
- if (sound) {
- sound.stop();
- if (activeLoopingSounds[soundId]) {
- delete activeLoopingSounds[soundId];
- }
- }
- };
- this.stopAllSounds = function () {
- Object.keys(soundConfigs).forEach(this.stopSound);
- activeLoopingSounds = {};
- };
- this.cleanupAmbientSounds = function () {
- ['breeze1', 'chitter', 'cricket1', 'frog1', 'songbird1'].forEach(this.stopSound);
- };
-};
-// Initialize sound manager
-game.soundManager = new SoundManager();
-var Bird1Movement = function Bird1Movement(bird, birdGraphics) {
- return new GameObjectMovement(bird, birdGraphics, {
- speed: 1,
- speedRange: 1.6,
- arcAmplitude: 6.5,
- arcFrequency: 100,
- isVertical: true,
- canFlip: true,
- moveSound: 'wings1'
- });
-};
-// Bird2Movement reuses Bird1Movement configuration since they share the same behavior
-var Bird2Movement = Bird1Movement;
-var UFOMovement = function UFOMovement(ufo, ufoGraphics) {
- return new GameObjectMovement(ufo, ufoGraphics, {
- speed: 3.2,
- speedRange: 0.8,
- isVertical: false,
- canFlip: true,
- moveSound: 'ufo1'
- });
-};
-// Shared entity effects configuration
-var ENTITY_EFFECTS = {
- bird1: {},
- bird2: {}
-};
-// Base EntityEffects class for all entities
-var EntityEffects = function EntityEffects(entity, config) {
- this.entity = entity;
- this.config = config || {};
- this.applyEffects = function () {
- // Common effects logic here
- if (this.config.onApplyEffects) {
- this.config.onApplyEffects(this.entity);
- }
- };
-};
-// Simplified Bird effects using shared base class
-var Bird1Effects = function Bird1Effects(bird) {
- return new EntityEffects(bird, ENTITY_EFFECTS.bird1);
-};
-var Bird2Effects = function Bird2Effects(bird) {
- return new EntityEffects(bird, ENTITY_EFFECTS.bird2);
-};
-// Add background to the BACKGROUND layer
-var background = new Background();
-background.x = 2048 / 2;
-background.y = 2732 / 2 - 140;
-game.addChild(background);
-game.layerManager.addToLayer(background, LAYERS.BACKGROUND);
-// ScoreManager class to manage score logic
-var ScoreManager = function ScoreManager() {
- var self = this;
- var currentScore = 0;
- var highScore = storage.highScore || 0;
- self.scoreValues = {
- bird1: 5,
- // Fix: bird1 should be worth 5 points
- bird2: 1,
- // Fix: bird2 should be worth 1 point
- ufo1: 25,
- ufo2: 25 // Fix: match the value in spawnRules
- };
- self.addScore = function (objectType) {
- var points = self.scoreValues[objectType] || 0;
- if (points > 0) {
- currentScore += points;
- if (currentScore > highScore) {
- highScore = currentScore;
- storage.highScore = highScore;
- }
- // Update score display
- if (scoreDisplay && scoreDisplay.updateScore) {
- scoreDisplay.updateScore(currentScore);
- }
- if (mirror && mirror.updateScore) {
- mirror.updateScore(currentScore);
- }
- }
- return currentScore;
- };
- self.resetScore = function () {
- currentScore = 0;
- if (scoreDisplay && scoreDisplay.updateScore) {
- scoreDisplay.updateScore(currentScore);
- }
- if (mirror && mirror.updateScore) {
- mirror.updateScore(currentScore);
- }
- return currentScore;
- };
- self.getScore = function () {
- return currentScore;
- };
- self.getHighScore = function () {
- return highScore;
- };
-};
-// Use the existing scoreManager from spawnManager
-var score = 0;
+// Initialize LayerManager
+var layerManager = new LayerManager();
+game.layerManager = layerManager;
+// Cloud management is now handled by SpawnManager
+// Initialize birds array for tracking
var birds = [];
-game.down = function (x, y, obj) {
- if (obj && obj.event) {
- x = obj.event.x;
- y = obj.event.y;
- }
- if (!game.reticle) {
- game.reticle = game.addChild(new Reticle());
- if (game.children.includes(game.reticle)) {
- game.layerManager.addToLayer(game.reticle, LAYERS.RETICLE);
- }
- }
- game.reticle.x = x;
- game.reticle.y = y;
- if (typeof x === 'undefined' || typeof y === 'undefined') {
- console.error('Invalid coordinates for laser');
- return;
- }
- var laser = new Laser(cat.x - 140, cat.y - 440, x, y);
- game.addChild(laser);
- if (game.children.includes(laser) && game.children.includes(game.reticle)) {
- game.layerManager.addToLayer(laser, LAYERS.LASER);
- }
-};
-game.move = function (x, y, obj) {
- if (!game.reticle) {
- game.reticle = game.addChild(new Reticle());
- }
- if (obj.event) {
- var x = obj.event.x;
- var y = obj.event.y;
- }
- game.reticle.x = x;
- game.reticle.y = y;
-};
-// Add a sun to the game in the top left corner
-var sun = new Sun();
-sun.x = 480;
-sun.y = 680;
-game.layerManager.addToLayer(sun, LAYERS.SUN);
-var light1 = new Light1();
-light1.x = 510;
-light1.y = 1500;
-game.layerManager.addToLayer(light1, LAYERS.LIGHT1);
-light1.visible = true;
-// Function to add a UFO to the game
-function addUFO() {
- var ufo = new UFO1();
- game.addChild(ufo);
- game.layerManager.addToLayer(ufo, LAYERS.UFO1);
- ufo.x = Math.random() < 0.5 ? 2048 + ufo.width / 2 : -ufo.width / 2;
- ufo.y = Math.random() * (2732 / 2 - ufo.height);
- ufo.customUpdate = function () {
- if (!ufo.soundPlayed && ufo.x > 0 && ufo.x < 2048) {
- LK.getSound('ufo1').play();
- ufo.soundPlayed = true;
- }
- ufo.update();
- };
- return ufo;
-}
-// Initialize clouds array
-var clouds = [];
-// Group all initialization functions together
-function initializeClouds() {
- function ensureCloudCount() {
- // Remove off-screen clouds
- clouds = clouds.filter(function (cloud) {
- if (cloud.x < -cloud.width || cloud.x > 2048 + cloud.width) {
- cloud.destroy();
- return false;
- }
- return true;
- });
- // Add new clouds if needed, maintaining 3-5 clouds
- while (clouds.length < 5) {
- var cloud = new Cloud();
- cloud.x = Math.random() * 2048;
- cloud.y = Math.random() * (2732 / 2);
- game.addChild(cloud);
- game.layerManager.addToLayer(cloud, clouds.length < 3 ? LAYERS.CLOUD1 : LAYERS.CLOUD2);
- clouds.push(cloud);
- }
- }
- // Initial cloud setup
- ensureCloudCount();
- // Check cloud count every second
- LK.setInterval(ensureCloudCount, 1000);
-}
-var bird1; // Define bird1 variable in the global scope
-var bird; // Define bird variable in the global scope
-// Initialize birds and score
-// Initialize game objects and managers
-var spawnManager = new SpawnManager();
-spawnManager.initialize();
-// ScoreManager is already initialized in the SpawnManager
-// Initialize mirror for score display
+var score = 0;
var mirror = new Mirror();
mirror.x = 2048 / 2 + 400;
mirror.y = 2732 - 185 - 80 - 390 + 30 + 50;
game.addChild(mirror);
game.mirror = mirror;
-game.layerManager.addToLayer(mirror, LAYERS.MIRROR);
-// Set up score display - use the same mirror object
var scoreDisplay = mirror;
var SoundManager = function SoundManager() {
this.soundTimers = {};
this.soundIntervals = {
@@ -1527,22 +724,44 @@
}.bind(this);
playFunction();
return this.soundTimers[soundId];
};
+ // Start the game
+ var spawnManager = new _SpawnManager();
+ spawnManager.initialize();
this.initialize = function () {
- // Initialize ambient sounds with 20-30 second intervals
- this.playSound('songbird1', {
- volume: 0.1,
- interval: this.soundIntervals.ambient
+ var _this = this;
+ // Initialize ambient sounds with optimized intervals
+ var ambientSounds = [{
+ id: 'songbird1',
+ volume: 0.1
+ }, {
+ id: 'cricket1',
+ volume: 0.1
+ }, {
+ id: 'breeze1',
+ volume: 0.1
+ }, {
+ id: 'frog1',
+ volume: 0.1
+ }, {
+ id: 'chitter',
+ volume: 0.1
+ }];
+ // Stagger ambient sound starts for better distribution
+ ambientSounds.forEach(function (sound, index) {
+ LK.setTimeout(function () {
+ _this.playSound(sound.id, {
+ volume: sound.volume
+ });
+ }, index * 2000);
});
- this.playSound('cricket1', {
+ // Initialize background music
+ this.playSound('bgm1', {
+ isMusic: true,
volume: 0.1,
- interval: this.soundIntervals.ambient
+ interval: this.soundIntervals.background
});
- this.playSound('breeze1', {
- volume: 0.1,
- interval: this.soundIntervals.ambient
- });
};
this.stopSound = function (soundId) {
if (this.soundTimers[soundId]) {
LK.clearTimeout(this.soundTimers[soundId]);
@@ -1555,15 +774,13 @@
this.stopSound(soundId);
}
};
};
-// Initialize sound system
+// Bird spawning is now handled by SpawnManager
var soundManager = new SoundManager();
soundManager.initialize();
-function SpawnManager() {
- if (!(this instanceof SpawnManager)) {
- return new SpawnManager();
- }
+// Initialize spawn manager
+var _SpawnManager = function SpawnManager() {
this.spawnTimers = {};
this.objectCounts = {
bird1: 0,
bird2: 0,
@@ -1572,59 +789,35 @@
ufo1: 0,
ufo2: 0,
jet1: 0
};
- // Cleanup function to properly clear timers
- this.cleanup = function () {
- for (var type in this.spawnTimers) {
- if (this.spawnTimers[type]) {
- LK.clearTimeout(this.spawnTimers[type]);
- this.spawnTimers[type] = null;
- }
- }
- };
this.spawnRules = {
bird1: {
max: 1,
layer: LAYERS.BIRD1,
movement: Bird1Movement,
- scoreValue: 5,
- respawnTime: {
- min: 5000,
- max: 10000
- }
+ scoreValue: 5
},
bird2: {
min: 3,
max: 3,
layer: LAYERS.BIRD2,
movement: Bird2Movement,
- scoreValue: 1,
- respawnTime: {
- min: 5000,
- max: 10000
- }
+ scoreValue: 1
},
cloud1: {
min: 1,
max: 3,
layer: LAYERS.CLOUD1,
- movement: CloudMovement,
- respawnTime: {
- min: 5000,
- max: 10000
- }
+ movement: CloudMovement
},
cloud2: {
min: 1,
max: 3,
layer: LAYERS.CLOUD2,
- movement: CloudMovement,
- respawnTime: {
- min: 5000,
- max: 10000
- }
+ movement: CloudMovement
},
+ // Ensure 3-5 total clouds
ufo1: {
max: 1,
respawnTime: {
min: 20000,
@@ -1659,122 +852,155 @@
};
this.soundManager = new SoundManager();
this.scoreManager = new ScoreManager();
this.exclusiveGroups = [['ufo1', 'ufo2']];
- // Layer order matching LAYERS constant
- this.layerOrder = [LAYERS.BACKGROUND, LAYERS.SUN, LAYERS.LIGHT1, LAYERS.UFO2, LAYERS.CLOUD1, LAYERS.JET1, LAYERS.CLOUD2, LAYERS.UFO1, LAYERS.BIRD1, LAYERS.GRASS_BACK, LAYERS.TREE, LAYERS.STACK, LAYERS.BIRD2, LAYERS.MIRROR, LAYERS.GRASS_FRONT, LAYERS.CAT, LAYERS.LASER, LAYERS.RETICLE];
+ // Correct layer order as per requirements
+ this.layerOrder = [LAYERS.BACKGROUND, LAYERS.LIGHT1, LAYERS.SUN, LAYERS.UFO2, LAYERS.CLOUD1, LAYERS.JET1, LAYERS.CLOUD2, LAYERS.UFO1, LAYERS.BIRD1, LAYERS.GRASS_BACK, LAYERS.TREE, LAYERS.STACK, LAYERS.BIRD2, LAYERS.MIRROR, LAYERS.GRASS_FRONT, LAYERS.RETICLE, LAYERS.LASER];
this.spawnObject = function (type, Constructor, options) {
+ var _this2 = this;
var rule = this.spawnRules[type];
if (!rule) {
return;
}
var count = this.objectCounts[type] || 0;
- // Check if we've reached the maximum count for this type
- if (count >= (rule.max || 1)) {
+ var maxCount = rule.max || 1;
+ // Early exit conditions
+ if (count >= maxCount) {
return;
}
- // Check if we need to maintain a minimum count
+ // Check exclusive groups (UFO1 and UFO2)
+ if (this.exclusiveGroups.some(function (group) {
+ if (group.includes(type)) {
+ return group.some(function (groupType) {
+ return _this2.objectCounts[groupType] > 0;
+ });
+ }
+ return false;
+ })) {
+ return;
+ }
+ // Handle minimum count requirements
if (rule.min && count < rule.min) {
- var spawnCount = Math.min(rule.min - count, (rule.max || 1) - count);
- for (var i = 0; i < spawnCount; i++) {
+ while (count < rule.min) {
this.createObject(type, Constructor, rule);
+ count++;
}
return;
}
- // Check exclusive groups (e.g., only one UFO type at a time)
- for (var i = 0; i < this.exclusiveGroups.length; i++) {
- var group = this.exclusiveGroups[i];
- if (group.includes(type)) {
- var groupTotal = 0;
- for (var j = 0; j < group.length; j++) {
- groupTotal += this.objectCounts[group[j]];
- }
- if (groupTotal > 0) {
- return;
- }
- }
- }
- // Check total cloud count to ensure 3-5 clouds
+ // Ensure proper cloud count (3-5 total)
if (type === 'cloud1' || type === 'cloud2') {
var totalClouds = this.objectCounts.cloud1 + this.objectCounts.cloud2;
if (totalClouds >= 5) {
return;
- } // Don't spawn more if we already have 5
+ }
+ if (totalClouds < 3) {
+ while (totalClouds < 3) {
+ this.createObject(type, Constructor, rule);
+ totalClouds++;
+ }
+ return;
+ }
}
+ // Ensure proper bird counts
+ if (type === 'bird1' && count >= 1) {
+ return;
+ } // Max 1 bird1
+ if (type === 'bird2' && count >= 3) {
+ return;
+ } // Max 3 bird2
+ // Create object with respawn timer for specific types
this.createObject(type, Constructor, rule);
+ if (rule.respawnTime) {
+ var respawnDelay = Math.random() * (rule.respawnTime.max - rule.respawnTime.min) + rule.respawnTime.min;
+ this.spawnTimers[type] = LK.setTimeout(function () {
+ delete _this2.spawnTimers[type];
+ _this2.spawnObject(type, Constructor, options);
+ }, respawnDelay);
+ }
};
this.createObject = function (type, Constructor, rule) {
+ if (!Constructor || !rule) {
+ return null;
+ }
var obj = new Constructor();
obj.type = type;
- // Position the object based on its type
- if (type === 'bird1' || type === 'bird2') {
- obj.x = Math.random() * 2048;
- obj.y = -obj.height;
- } else {
- obj.x = Math.random() < 0.5 ? 2048 + obj.width / 2 : -obj.width / 2;
- obj.y = Math.random() * (2732 / 2);
- }
- game.addChild(obj);
+ // Initialize position based on object type
+ var screenWidth = 2048;
+ var screenHeight = 2732;
+ var isVerticalMovement = type.startsWith('bird');
+ obj.x = isVerticalMovement ? Math.random() * screenWidth : Math.random() < 0.5 ? screenWidth + obj.width / 2 : -obj.width / 2;
+ obj.y = isVerticalMovement ? -obj.height : Math.random() * (screenHeight / 2);
+ // Add to game and layer manager in one step
game.layerManager.addToLayer(obj, rule.layer);
- this.objectCounts[type]++;
+ this.objectCounts[type] = (this.objectCounts[type] || 0) + 1;
// Initialize movement with appropriate options
if (rule.movement) {
// Define common movement parameters by object type
- var movementParams = {
- // Birds share the same movement parameters
- bird: {
+ var MovementConfigs = {
+ bird1: {
speed: 2,
- speedRange: 1.6,
+ speedRange: 1.2,
arcAmplitude: 6.5,
arcFrequency: 100,
isVertical: true,
canFlip: true,
moveSound: 'wings1'
},
- // UFOs share the same movement parameters
- ufo: {
+ bird2: {
+ speed: 2.5,
+ speedRange: 1.2,
+ arcAmplitude: 6.5,
+ arcFrequency: 100,
+ isVertical: true,
+ canFlip: true,
+ moveSound: 'wings1'
+ },
+ ufo1: {
speed: 3.2,
speedRange: 0.8,
arcAmplitude: 4.5,
arcFrequency: 80,
isVertical: false,
canFlip: true,
moveSound: 'ufo1'
},
- // Jets have their own movement parameters
- jet: {
+ ufo2: {
+ speed: 3.2,
+ speedRange: 0.8,
+ arcAmplitude: 4.5,
+ arcFrequency: 80,
+ isVertical: false,
+ canFlip: true,
+ moveSound: 'ufo1'
+ },
+ jet1: {
speed: 10,
speedRange: 0,
arcAmplitude: 0,
arcFrequency: 0,
isVertical: false,
canFlip: true,
moveSound: 'jet1'
},
- // Clouds have their own movement parameters
- cloud: {
+ cloud1: {
speed: 0.25,
speedRange: 0.55,
arcAmplitude: 0,
arcFrequency: 0,
isVertical: false,
canFlip: false
+ },
+ cloud2: {
+ speed: 0.25,
+ speedRange: 0.55,
+ arcAmplitude: 0,
+ arcFrequency: 0,
+ isVertical: false,
+ canFlip: false
}
};
- // Select the appropriate movement parameters based on object type
- var params;
- if (type === 'bird1' || type === 'bird2') {
- params = movementParams.bird;
- } else if (type === 'ufo1' || type === 'ufo2') {
- params = movementParams.ufo;
- } else if (type === 'jet1') {
- params = movementParams.jet;
- } else if (type === 'cloud1' || type === 'cloud2') {
- params = movementParams.cloud;
- } else {
- // Default parameters
- params = movementParams.bird;
- }
+ // Get movement configuration based on object type
+ var params = MovementConfigs[type] || MovementConfigs.bird1; // Default to bird1 if type not found
// Create movement options with the selected parameters
var movementOptions = {
speed: params.speed,
speedRange: params.speedRange,
@@ -1793,17 +1019,9 @@
return obj;
};
this.scheduleRespawn = function (type, Constructor) {
var rule = this.spawnRules[type];
- if (!rule) {
- return;
- }
- // Clear existing timer if any
- if (this.spawnTimers[type]) {
- LK.clearTimeout(this.spawnTimers[type]);
- this.spawnTimers[type] = null;
- }
- // Calculate respawn time based on entity type
+ // Ensure respawn timers for ufo1, ufo2, and jet1 are set to 20-30 seconds
var respawnTime;
if (type === 'ufo1' || type === 'ufo2' || type === 'jet1') {
respawnTime = Math.random() * 10000 + 20000; // 20-30 seconds
} else if (rule.respawnTime) {
@@ -1834,20 +1052,16 @@
}
if (shouldSpawn) {
this.spawnObject(type, Constructor);
}
- this.spawnTimers[type] = null;
}.bind(this), respawnTime);
+ // Start the game
+ var spawnManager = new _SpawnManager();
+ spawnManager.initialize();
this.initialize = function () {
- // Cleanup any existing timers
- this.cleanup();
- // Reset object counts
- for (var type in this.objectCounts) {
- this.objectCounts[type] = 0;
- }
// Initialize birds - exactly 1 Bird1 and 3 Bird2s
this.spawnObject('bird1', Bird1);
- for (var i = 0; i < 3; i++) {
+ for (var i = 0; i < this.spawnRules.bird2.min; i++) {
this.spawnObject('bird2', Bird2);
}
// Initialize clouds - ensure 3-5 total clouds
var totalCloudsToSpawn = Math.floor(Math.random() * 3) + 3;
@@ -1858,68 +1072,80 @@
}
for (var i = 0; i < cloud2ToSpawn; i++) {
this.spawnObject('cloud2', Cloud);
}
- // Initialize UFOs and Jet with proper respawn timers
- var ufoType = Math.random() < 0.5 ? 'ufo1' : 'ufo2';
- var UFOConstructor = ufoType === 'ufo1' ? UFO1 : UFO2;
- this.spawnObject(ufoType, UFOConstructor);
+ // Initialize UFOs and Jet with respawn timers
+ // Randomly choose between UFO1 and UFO2
+ if (Math.random() < 0.5) {
+ this.spawnObject('ufo1', UFO1);
+ } else {
+ this.spawnObject('ufo2', UFO2);
+ }
this.spawnObject('jet1', Jet1);
// Set up periodic check for object counts and layer ordering
LK.setInterval(function () {
+ // Update layer ordering
+ this.layerOrder.forEach(function (layerId, index) {
+ var objects = game.layerManager.getObjectsInLayer(layerId);
+ objects.forEach(function (obj) {
+ game.layerManager.setLayerIndex(obj, index);
+ });
+ }.bind(this));
// Maintain bird counts
if (this.objectCounts.bird1 < 1) {
this.spawnObject('bird1', Bird1);
}
while (this.objectCounts.bird2 < 3) {
this.spawnObject('bird2', Bird2);
}
- // Maintain cloud counts (3-5 total)
- var totalClouds = this.objectCounts.cloud1 + this.objectCounts.cloud2 || 0;
+ // Maintain cloud counts
+ var totalClouds = this.objectCounts.cloud1 + this.objectCounts.cloud2;
if (totalClouds < 3) {
- var cloudsNeeded = Math.floor(Math.random() * 3) + 3 - totalClouds;
+ var cloudsNeeded = 3 - totalClouds;
for (var i = 0; i < cloudsNeeded; i++) {
- this.spawnObject(Math.random() < 0.5 ? 'cloud1' : 'cloud2', Cloud);
+ if (Math.random() < 0.5 && this.objectCounts.cloud1 < this.spawnRules.cloud1.max) {
+ this.spawnObject('cloud1', Cloud);
+ } else if (this.objectCounts.cloud2 < this.spawnRules.cloud2.max) {
+ this.spawnObject('cloud2', Cloud);
+ }
}
}
- // Check UFO and Jet spawns
+ // Ensure one UFO (either UFO1 or UFO2) is on screen
if (this.objectCounts.ufo1 + this.objectCounts.ufo2 === 0 && !this.spawnTimers.ufo1 && !this.spawnTimers.ufo2) {
- var ufoType = Math.random() < 0.5 ? 'ufo1' : 'ufo2';
- var UFOConstructor = ufoType === 'ufo1' ? UFO1 : UFO2;
- this.scheduleRespawn(ufoType, UFOConstructor);
+ if (Math.random() < 0.5) {
+ this.spawnObject('ufo1', UFO1);
+ } else {
+ this.spawnObject('ufo2', UFO2);
+ }
}
+ // Ensure one jet is on screen
if (this.objectCounts.jet1 === 0 && !this.spawnTimers.jet1) {
- this.scheduleRespawn('jet1', Jet1);
+ this.spawnObject('jet1', Jet1);
}
- // Update layer ordering
- this.layerOrder.forEach(function (layerId, index) {
- var objects = game.layerManager.getObjectsInLayer(layerId);
- objects.forEach(function (obj) {
- game.layerManager.setLayerIndex(obj, index);
- });
- }.bind(this));
}.bind(this), 1000);
}.bind(this);
- // Set up periodic check for object counts and spawn management
+ // Set up periodic check for object counts
LK.setInterval(function () {
- // Validate and maintain entity counts
- for (var type in this.spawnRules) {
- var rule = this.spawnRules[type];
- var count = this.objectCounts[type] || 0;
- // Ensure minimum counts are maintained
- if (rule.min && count < rule.min) {
- var spawnCount = Math.min(rule.min - count, (rule.max || 1) - count);
- for (var i = 0; i < spawnCount; i++) {
- this.spawnObject(type, type === 'bird1' ? Bird1 : type === 'bird2' ? Bird2 : type === 'cloud1' || type === 'cloud2' ? Cloud : type === 'ufo1' ? UFO1 : type === 'ufo2' ? UFO2 : type === 'jet1' ? Jet1 : null);
+ // Maintain bird counts - exactly 1 Bird1
+ if (this.objectCounts.bird1 < 1) {
+ this.spawnObject('bird1', Bird1);
+ }
+ // Maintain bird counts - exactly 3 Bird2s
+ while (this.objectCounts.bird2 < 3) {
+ this.spawnObject('bird2', Bird2);
+ }
+ // Maintain cloud counts - ensure 3-5 total clouds
+ var totalClouds = this.objectCounts.cloud1 + this.objectCounts.cloud2;
+ if (totalClouds < 3) {
+ var cloudsNeeded = 3 - totalClouds;
+ for (var i = 0; i < cloudsNeeded; i++) {
+ if (Math.random() < 0.5 && this.objectCounts.cloud1 < this.spawnRules.cloud1.max) {
+ this.spawnObject('cloud1', Cloud);
+ } else {
+ this.spawnObject('cloud2', Cloud);
}
}
- // Schedule respawns for UFOs and Jets if needed
- if ((type === 'ufo1' || type === 'ufo2' || type === 'jet1') && count === 0 && !this.spawnTimers[type]) {
- this.scheduleRespawn(type, type === 'ufo1' ? UFO1 : type === 'ufo2' ? UFO2 : Jet1);
- }
- }
- var totalClouds = this.objectCounts.cloud1 + this.objectCounts.cloud2 || 0; // Initialize totalClouds
- if (totalClouds > 5) {
+ } else if (totalClouds > 5) {
// If there are more than 5 clouds, don't spawn any more until some are removed
// This is handled automatically when clouds move off-screen
}
// Ensure one UFO (either UFO1 or UFO2) is on screen
@@ -1935,30 +1161,30 @@
this.spawnObject('jet1', Jet1);
}
}.bind(this), 1000);
};
+ var spawnManager = new _SpawnManager();
// Initialize the spawn manager
- SpawnManager.prototype.initialize = function () {
+ _SpawnManager.prototype.initialize = function () {
// Initialize sound and score managers
this.soundManager.initialize();
- // Set up initial spawns - exactly 1 Bird1
+ // Set up initial spawns with consistent behavior
this.spawnObject('bird1', Bird1);
- // Set up initial spawns - exactly 3 Bird2s
for (var i = 0; i < 3; i++) {
this.spawnObject('bird2', Bird2);
}
- // Set up cloud spawning - 3-5 total clouds
- var totalClouds = Math.floor(Math.random() * 3) + 3;
- var cloud1Count = Math.min(Math.ceil(totalClouds / 2), this.spawnRules.cloud1.max);
- var cloud2Count = totalClouds - cloud1Count;
- for (var i = 0; i < cloud1Count; i++) {
- this.spawnObject('cloud1', Cloud);
- }
- for (var i = 0; i < cloud2Count; i++) {
- this.spawnObject('cloud2', Cloud);
- }
- // Schedule initial UFO spawn (either UFO1 or UFO2)
};
+ // Set up cloud spawning - 3-5 total clouds
+ var totalClouds = Math.floor(Math.random() * 3) + 3;
+ var cloud1Count = Math.min(Math.ceil(totalClouds / 2), this.spawnRules.cloud1.max);
+ var cloud2Count = totalClouds - cloud1Count;
+ for (var i = 0; i < cloud1Count; i++) {
+ this.spawnObject('cloud1', Cloud);
+ }
+ for (var i = 0; i < cloud2Count; i++) {
+ this.spawnObject('cloud2', Cloud);
+ }
+ // Schedule initial UFO spawn (either UFO1 or UFO2)
if (Math.random() < 0.5) {
this.spawnObject('ufo1', UFO1);
} else {
this.spawnObject('ufo2', UFO2);
@@ -1989,10 +1215,9 @@
if (this.objectCounts.jet1 === 0 && !this.spawnTimers.jet1) {
this.scheduleRespawn('jet1', Jet1);
}
}.bind(this), 1000);
-}
-;
+};
spawnManager.initialize();
// Main game update function
game.update = function () {
// Update all game objects
@@ -2011,242 +1236,86 @@
// Update score display
if (game.mirror && game.mirror.updateScore) {
game.mirror.updateScore(game.score || 0);
}
- // Ensure correct number of birds with sound effects
- var bird1Count = birds.filter(function (b) {
- return b instanceof Bird1;
- }).length;
- var bird2Count = birds.filter(function (b) {
- return b instanceof Bird2;
- }).length;
- // Maintain exactly 1 Bird1
- if (bird1Count < 1) {
- var newBird1 = new Bird1();
- newBird1.x = Math.random() * 2048;
- newBird1.y = -newBird1.height;
- newBird1.speed = Math.random() * 1.6 + 1;
- newBird1.lastIntersecting = false;
- newBird1.type = 'bird1';
- newBird1.color = 0x746130;
- game.addChild(newBird1);
- game.layerManager.addToLayer(newBird1, LAYERS.BIRD1);
- birds.push(newBird1);
- LK.getSound('bird1').play();
- } else if (bird1Count > 1) {
- var extraBird1s = birds.filter(function (b) {
- return b instanceof Bird1;
- }).slice(1);
- extraBird1s.forEach(function (b) {
- b.destroy();
- birds.splice(birds.indexOf(b), 1);
- });
- }
- // Maintain exactly 3 Bird2s
- if (bird2Count < 3) {
- for (var i = 0; i < 3 - bird2Count; i++) {
- var newBird2 = new Bird2();
- newBird2.x = Math.random() < 0.5 ? 0 : 2048;
- newBird2.y = Math.random() * (2732 / 2);
- newBird2.speed = 1 + Math.random() * 0.6;
- newBird2.lastIntersecting = false;
- newBird2.type = 'bird2';
- newBird2.color = 0xFFFFFF;
- game.addChild(newBird2);
- game.layerManager.addToLayer(newBird2, LAYERS.BIRD2);
- birds.push(newBird2);
- LK.getSound('bird2').play();
- }
- } else if (bird2Count > 3) {
- var extraBird2s = birds.filter(function (b) {
- return b instanceof Bird2;
- }).slice(3);
- extraBird2s.forEach(function (b) {
- b.destroy();
- birds.splice(birds.indexOf(b), 1);
- });
- }
- // Update UFOs, jets, and check for collisions
+ // Ensure correct number of birds using SpawnManager
+ spawnManager.spawnObject('bird1', Bird1);
+ spawnManager.spawnObject('bird2', Bird2);
+ // Update UFOs and play sounds
game.children.forEach(function (entity) {
- if (entity instanceof UFO1 || entity instanceof UFO2) {
- if (!entity.soundPlayed && entity.x > 0 && entity.x < 2048) {
- LK.getSound('ufo1').play();
- entity.soundPlayed = true;
- }
- entity.update();
+ if ((entity instanceof UFO1 || entity instanceof UFO2) && !entity.soundPlayed && entity.x > 0 && entity.x < 2048) {
+ LK.getSound('ufo1').play();
+ entity.soundPlayed = true;
}
});
// Update each laser and check collisions
- game.children.forEach(function (child) {
- if (child instanceof Laser) {
- child.update();
- // Check for intersections with birds
- game.children.forEach(function (target) {
- if (!child.lastIntersecting && AABBIntersect(child, target)) {
- var soundEffect = '';
- if (target instanceof Bird1) {
- soundEffect = 'dead1';
- spawnManager.objectCounts.bird1--;
- spawnManager.scoreManager.addScore('bird1');
- } else if (target instanceof Bird2) {
- soundEffect = 'dead2';
- spawnManager.objectCounts.bird2--;
- spawnManager.scoreManager.addScore('bird2');
- } else if (target instanceof UFO1) {
- soundEffect = 'dead3';
- spawnManager.objectCounts.ufo1--;
- spawnManager.scoreManager.addScore('ufo1');
- } else if (target instanceof UFO2) {
- soundEffect = 'dead3';
- spawnManager.objectCounts.ufo2--;
- spawnManager.scoreManager.addScore('ufo2');
- }
- // Update score display
- if (game.mirror && game.mirror.updateScore) {
- game.mirror.updateScore(spawnManager.scoreManager.getScore());
- }
- LK.getSound(soundEffect).play();
- target.destroy();
- child.destroy();
- }
- });
- // Update lastIntersecting state
- child.lastIntersecting = game.children.some(function (target) {
- return (target instanceof Bird1 || target instanceof Bird2 || target instanceof UFO1 || target instanceof UFO2) && child.intersects(target);
- });
+ game.children.forEach(function (laser) {
+ if (laser instanceof Laser) {
+ laser.update();
+ checkLaserCollisions(laser);
}
});
};
-// Initialize game objects and start spawning
-spawnManager.initialize();
-function spawnBird2() {
- var bird2Count = birds.filter(function (b) {
- return b instanceof Bird2;
- }).length;
- // Fix: Ensure there are always 3 bird2 on screen
- if (bird2Count < 3) {
- var bird2 = new Bird2();
- bird2.x = Math.random() * 2048;
- bird2.y = -bird2.height;
- bird2.speed = Math.random() * 1.6 + 1;
- bird2.lastIntersecting = false;
- bird2.type = 'bird2';
- bird2.color = 0x746130;
- game.addChild(bird2);
- if (game.children.includes(bird2)) {
- game.layerManager.addToLayer(bird2, LAYERS.BIRD2);
- birds.push(bird2);
- }
- }
- LK.setTimeout(spawnBird2, Math.random() * 10000 + 20000);
+function checkAndRespawnBirds() {
+ spawnManager.spawnBird(Bird1, 1);
+ spawnManager.spawnBird(Bird2, 3);
+ LK.setTimeout(checkAndRespawnBirds, Math.random() * 10000 + 20000);
}
// Update bird positions and states
-function updateBirds() {
- // Update each bird
- birds.forEach(function (bird) {
- bird.update();
- // Check if the bird has moved off-screen
- if (bird.lastY <= 2732 && bird.y > 2732) {
- bird.y = -bird.height; // Respawn the bird at the top
- bird.x = Math.random() * 2048; // Randomize the x position
- bird.speed = 1 + Math.random() * 0.6; // Reset speed for new bird
- }
- });
- // Ensure correct number of birds
- var bird1Count = birds.filter(function (b) {
- return b instanceof Bird1;
+function updateGameBirds() {
+ maintainBirdCount(Bird1, 1, LAYERS.BIRD1);
+ maintainBirdCount(Bird2, 3, LAYERS.BIRD2);
+}
+function maintainBirdCount(BirdType, targetCount, layerIndex) {
+ var birdCount = birds.filter(function (b) {
+ return b instanceof BirdType;
}).length;
- var bird2Count = birds.filter(function (b) {
- return b instanceof Bird2;
- }).length;
- // Maintain exactly 1 Bird1
- if (bird1Count < 1) {
- var newBird1 = new Bird1();
- newBird1.x = Math.random() * 2048;
- newBird1.y = Math.random() * (2732 / 2);
- game.addChild(newBird1);
- game.layerManager.addToLayer(newBird1, LAYERS.BIRD1);
- birds.push(newBird1);
- } else if (bird1Count > 1) {
- var extraBird1s = birds.filter(function (b) {
- return b instanceof Bird1;
- }).slice(1);
- extraBird1s.forEach(function (b) {
- b.destroy();
- birds.splice(birds.indexOf(b), 1);
- });
- }
- // Maintain exactly 3 Bird2s
- if (bird2Count < 3) {
- for (var i = 0; i < 3 - bird2Count; i++) {
- var newBird2 = new Bird2();
- newBird2.x = Math.random() * 2048;
- newBird2.y = Math.random() * (2732 / 2);
- game.addChild(newBird2);
- game.layerManager.addToLayer(newBird2, LAYERS.BIRD2);
- birds.push(newBird2);
+ if (birdCount < targetCount) {
+ for (var i = 0; i < targetCount - birdCount; i++) {
+ var newBird = new BirdType();
+ newBird.x = Math.random() * 2048;
+ newBird.y = Math.random() * (2732 / 2);
+ newBird.speed = 1 + Math.random() * 0.6;
+ game.addChild(newBird);
+ game.layerManager.addToLayer(newBird, layerIndex);
+ birds.push(newBird);
}
- } else if (bird2Count > 3) {
- var extraBird2s = birds.filter(function (b) {
- return b instanceof Bird2;
- }).slice(3);
- extraBird2s.forEach(function (b) {
+ } else if (birdCount > targetCount) {
+ var extraBirds = birds.filter(function (b) {
+ return b instanceof BirdType;
+ }).slice(targetCount);
+ extraBirds.forEach(function (b) {
b.destroy();
birds.splice(birds.indexOf(b), 1);
});
}
- // Update UFOs, jets, and check for collisions
- game.children.forEach(function (entity) {
- if (entity instanceof UFO1 || entity instanceof UFO2) {
- if (!entity.soundPlayed && entity.x > 0 && entity.x < 2048) {
- LK.getSound('ufo1').play();
- entity.soundPlayed = true;
- }
- entity.update();
- }
- });
- // Update each laser and check collisions
- game.children.forEach(function (child) {
- if (child instanceof Laser) {
- child.update();
- // Check for intersections with birds
- game.children.forEach(function (target) {
- if (!child.lastIntersecting && AABBIntersect(child, target)) {
- var soundEffect = '';
- if (target instanceof Bird1) {
- soundEffect = 'dead1';
- spawnManager.objectCounts.bird1--;
- spawnManager.scoreManager.addScore('bird1');
- } else if (target instanceof Bird2) {
- soundEffect = 'dead2';
- spawnManager.objectCounts.bird2--;
- spawnManager.scoreManager.addScore('bird2');
- } else if (target instanceof UFO1) {
- soundEffect = 'dead3';
- spawnManager.objectCounts.ufo1--;
- spawnManager.scoreManager.addScore('ufo1');
- } else if (target instanceof UFO2) {
- soundEffect = 'dead3';
- spawnManager.objectCounts.ufo2--;
- spawnManager.scoreManager.addScore('ufo2');
- }
- // Update score display
- if (game.mirror && game.mirror.updateScore) {
- game.mirror.updateScore(spawnManager.scoreManager.getScore());
- }
- LK.getSound(soundEffect).play();
- target.destroy();
- child.destroy();
- }
- });
- // Update lastIntersecting state
- child.lastIntersecting = game.children.some(function (target) {
- return (target instanceof Bird1 || target instanceof Bird2 || target instanceof UFO1 || target instanceof UFO2) && child.intersects(target);
- });
- }
- });
}
-;
+// Update existing birds
+birds.forEach(function (bird) {
+ bird.update();
+ if (bird.lastY <= 2732 && bird.y > 2732) {
+ bird.y = -bird.height;
+ bird.x = Math.random() * 2048;
+ bird.speed = 1 + Math.random() * 0.6;
+ }
+});
+// Maintain bird counts
+maintainBirdCount(Bird1, 1, LAYERS.BIRD1);
+maintainBirdCount(Bird2, 3, LAYERS.BIRD2);
+// Update UFOs and play sounds
+game.children.forEach(function (entity) {
+ if ((entity instanceof UFO1 || entity instanceof UFO2) && !entity.soundPlayed && entity.x > 0 && entity.x < 2048) {
+ LK.getSound('ufo1').play();
+ entity.soundPlayed = true;
+ }
+});
+// Update each laser and check collisions
+game.children.forEach(function (laser) {
+ if (laser instanceof Laser) {
+ laser.update();
+ checkLaserCollisions(laser);
+ }
+});
// Add a tree to the game
var tree = game.addChild(new Tree());
tree.x = 2048 / 2 + 600; // Move the tree 500px to the right
tree.y = 2500; // Position the tree on the grass
@@ -2279,12 +1348,19 @@
// Add grassFront to the proper layer
if (game.children.includes(grassFront)) {
game.layerManager.addToLayer(grassFront, LAYERS.GRASS_FRONT); // Use layer manager to set grass-front layer
}
-// Mirror and scoreDisplay are already initialized earlier in the code
-// Ensure proper layer ordering for existing mirror
-if (game.mirror) {
- game.layerManager.addToLayer(game.mirror, LAYERS.MIRROR);
+var scoreDisplay = new Mirror();
+scoreDisplay.x = 2048 / 2 + 400; // Move the score display 400px to the right
+scoreDisplay.y = 2732 - 185 - 80 - 390 + 30 + 50; // Move the score display up by an additional 80px and down by 30px + 50px
+game.addChild(scoreDisplay);
+var mirror = new Mirror();
+mirror.x = 2048 / 2 + 400; // Move the mirror 400px to the right
+mirror.y = 2732 - 185 - 80 - 390 + 30; // Move the mirror up by an additional 80px and down by 30px
+game.addChild(mirror);
+// Add mirror to the proper layer
+if (game.children.includes(mirror)) {
+ game.layerManager.addToLayer(mirror, LAYERS.MIRROR); // Use layer manager to set mirror layer
}
// Function to handle bgm1 end event
function onBgm1End() {
// Set a timer to replay bgm1 after 50-80 seconds
@@ -2394,210 +1470,135 @@
maxScale: 1.1
});
};
// Light1Pulse class to handle the pulsating effect for Light1
-var Light1Pulse = function Light1Pulse(lightGraphics) {
- return new Pulse(lightGraphics, {
- maxScale: 1.6,
- contractDuration: 1500
- });
+var Light1Pulse = function Light1Pulse(graphics) {
+ ;
+ this.graphics = graphics;
+ this.pulseTimer = null;
+ this.startPulsating = function () {
+ var self = this;
+ var brightness = 1.0;
+ var direction = 1;
+ this.pulseTimer = LK.setInterval(function () {
+ brightness += direction * 0.05;
+ if (brightness >= 2.0) {
+ direction = -1;
+ brightness = 2.0;
+ } else if (brightness <= 1.0) {
+ direction = 1;
+ brightness = 1.0;
+ }
+ self.graphics.brightness = brightness;
+ }, 50);
+ };
+ this.stopPulsating = function () {
+ if (this.pulseTimer) {
+ LK.clearInterval(this.pulseTimer);
+ }
+ };
};
var bird2; // Define bird2 variable in the global scope
// UFOMovement class to handle UFO movement
var UFOMovement = function UFOMovement(ufo, ufoGraphics) {
- this.ufo = ufo;
- this.ufoGraphics = ufoGraphics;
- this.ufo.speed = 3.2; // Decrease speed by 20%
- this.ufo.direction = Math.random() < 0.5 ? 1 : -1; // Random direction: 1 for right, -1 for left
- this.ufo.lastX = this.ufo.x; // Track last X position for future checks
- this.ufo.update = function () {
- var _this5 = this;
- // Cache current position and dimensions
- var currentX = this.x;
- var screenWidth = 2048;
- var halfWidth = this.width / 2;
- // Update position based on pattern
- this.x += this.speed * Math.cos(LK.ticks / 60);
- this.y = 100 + Math.sin(LK.ticks / 120) * 250;
- // Optimize movement pattern
- var distanceFromCenter = Math.abs(this.x - screenWidth / 2);
- if (distanceFromCenter > screenWidth / 3) {
- this.speed *= -0.95; // Smooth direction change
- }
- // Cache intersection checks
- var isIntersectingCloud = clouds.some(function (cloud) {
- return _this5.intersects(cloud);
- });
- if (isIntersectingCloud && !this.lastIntersecting) {
- this.speed *= 1.2;
- LK.getSound('ufo1').play();
- }
- this.lastIntersecting = isIntersectingCloud;
- // Stop playing ufo1 sound after UFO leaves the screen
- if (this.lastX <= screenWidth + halfWidth && this.x > screenWidth + halfWidth || this.lastX >= -halfWidth && this.x < -halfWidth) {
- this.destroy();
- ufo = null;
- LK.getSound('ufo1').stop();
- }
- this.lastX = this.x; // Update lastX after movement
+ return new GameObjectMovement(ufo, ufoGraphics, {
+ speed: 3.2,
+ speedRange: 0.8,
+ arcAmplitude: 4.5,
+ arcFrequency: 80,
+ isVertical: false,
+ canFlip: true,
+ moveSound: 'ufo1'
+ });
+};
+;
+var UFOSound = function UFOSound() {
+ ;
+ this.play = function () {
+ LK.getSound('ufo1').play();
};
};
-// Unified sound management system
-var SoundManager = function SoundManager() {
- var soundConfigs = {
- ufo1: {
- volume: 0.1,
- loop: false
- },
- bgm1: {
- volume: 0.1,
+// BackgroundMusic class to manage background music
+var BackgroundMusic = function BackgroundMusic() {
+ ;
+ this.play = function () {
+ LK.playMusic('bgm1', {
loop: true,
fade: {
start: 0,
end: 1,
duration: 4000
- }
- },
- laser1: {
- volume: 0.1,
- loop: false
- },
- wings1: {
- volume: 0.1,
- loop: false
- },
- dead1: {
- volume: 0.1,
- loop: false
- },
- dead2: {
- volume: 0.1,
- loop: false
- },
- dead3: {
- volume: 0.1,
- loop: false
- },
- jet1: {
- volume: 0.1,
- loop: false
- },
- breeze1: {
- volume: 0.1,
- loop: true
- },
- chitter: {
- volume: 0.1,
- loop: true
- },
- cricket1: {
- volume: 0.1,
- loop: true
- },
- frog1: {
- volume: 0.1,
- loop: true
- },
- songbird1: {
- volume: 0.1,
- loop: true
- }
+ },
+ onEnd: onBgm1End
+ });
};
- var activeLoopingSounds = {};
- this.playSound = function (soundId, options) {
- var config = Object.assign({}, soundConfigs[soundId] || {}, options || {});
- var sound = LK.getSound(soundId);
- if (sound) {
- sound.volume = config.volume;
- if (config.fade) {
- sound.fade(config.fade.start, config.fade.end, config.fade.duration);
- }
- if (config.loop) {
- sound.loop();
- activeLoopingSounds[soundId] = sound;
- }
- sound.play();
- return sound;
- }
- return null;
+};
+// LaserSound class to manage laser sound effects
+var LaserSound = function LaserSound() {
+ ;
+ this.play = function () {
+ LK.getSound('laser1').play();
};
- this.stopSound = function (soundId) {
- var sound = LK.getSound(soundId);
- if (sound) {
- sound.stop();
- if (activeLoopingSounds[soundId]) {
- delete activeLoopingSounds[soundId];
- }
- }
- };
- this.stopAllSounds = function () {
- Object.keys(soundConfigs).forEach(this.stopSound);
- activeLoopingSounds = {};
- };
- this.cleanupAmbientSounds = function () {
- ['breeze1', 'chitter', 'cricket1', 'frog1', 'songbird1'].forEach(this.stopSound);
- };
};
-// Initialize sound manager
-game.soundManager = new SoundManager();
var Bird1Movement = function Bird1Movement(bird, birdGraphics) {
- this.bird = bird;
- this.birdGraphics = birdGraphics;
- this.bird.speed = Math.random() * 1.6 + 1;
- this.bird.lastY = this.bird.y;
- this.bird.lastX = this.bird.x;
- this.bird.update = function () {
- this.y += this.speed;
- this.x += Math.sin(this.y / 100) * 6.5;
- this.lastY = this.y;
- this.lastX = this.x;
- }.bind(this.bird);
+ return new GameObjectMovement(bird, birdGraphics, {
+ speed: 2.5,
+ speedRange: 1.2,
+ arcAmplitude: 6.5,
+ arcFrequency: 100,
+ isVertical: true,
+ canFlip: true,
+ moveSound: 'wings1'
+ });
};
var Bird2Movement = function Bird2Movement(bird, birdGraphics) {
+ return new GameObjectMovement(bird, birdGraphics, {
+ speed: 2.5,
+ speedRange: 1.2,
+ arcAmplitude: 6.5,
+ arcFrequency: 100,
+ isVertical: true,
+ canFlip: true,
+ moveSound: 'wings1'
+ });
+};
+var Bird2Effects = function Bird2Effects(bird) {
+ ;
this.bird = bird;
- this.birdGraphics = birdGraphics;
- this.bird.speed = Math.random() * 1.6 + 1;
- this.bird.lastY = storage.bird2_lastY || this.bird.y; // Initialize lastY for tracking changes on Y
- this.bird.lastX = storage.bird2_lastX || this.bird.x; // Initialize lastX for tracking changes on X
- this.bird.update = function () {
- this.y += this.speed;
- this.x += Math.sin(this.y / 100) * 6.5; // Increase the swooping motion of the bird's movement by 30%
- flipImageVerticallyBasedOnDirection(birdGraphics, this.lastX, this.x); // Use flipImageVerticallyBasedOnDirection to flip on X axis
- // Check if the bird has moved off-screen
- if (this.lastY <= 2732 && this.y > 2732) {
- this.y = Math.random() * 2732; // Random initial y position within the screen height
- this.x = Math.random() < 0.5 ? 0 : 2048; // Start from either the left or right side
- }
- this.lastX = this.x; // Track position for next update
- this.lastY = this.y; // Update lastY after movement
- storage.bird2_lastX = this.lastX; // Store lastX using storage plugin
- storage.bird2_lastY = this.lastY; // Store lastY using storage plugin
- };
+ this.applyEffects = function () {};
};
-// Shared entity effects configuration
-var ENTITY_EFFECTS = {
- bird1: {},
- bird2: {}
+var ReticlePulse = function ReticlePulse(reticleGraphics) {
+ ;
+ return new Pulse(reticleGraphics, {
+ minScale: 0.9,
+ maxScale: 1.3,
+ expandDuration: 800,
+ contractDuration: 1200
+ });
};
-// Base EntityEffects class for all entities
-var EntityEffects = function EntityEffects(entity, config) {
- this.entity = entity;
- this.config = config || {};
+// Bird1Effects class to handle effects and animations for Bird1
+var Bird1Effects = function Bird1Effects(bird) {
+ ;
+ this.bird = bird;
this.applyEffects = function () {
- // Common effects logic here
- if (this.config.onApplyEffects) {
- this.config.onApplyEffects(this.entity);
- }
+ // Add any specific effects or animations for Bird1 here
};
};
-// Simplified Bird effects using shared base class
-var Bird1Effects = function Bird1Effects(bird) {
- return new EntityEffects(bird, ENTITY_EFFECTS.bird1);
-};
-var Bird2Effects = function Bird2Effects(bird) {
- return new EntityEffects(bird, ENTITY_EFFECTS.bird2);
-};
-// ReticlePulse is already handled by PULSE_CONFIGS
+function spawnBird2() {
+ var bird2Count = entityManager.getAllOfType(Bird2).length;
+ if (bird2Count < 3) {
+ var bird = new Bird2();
+ bird.y = Math.random() * (2732 / 2);
+ bird.x = Math.random() < 0.5 ? 0 : 2048;
+ bird.speed = 1 + Math.random() * 0.6;
+ bird.lastIntersecting = false;
+ bird.type = 'bird2';
+ bird.color = 0xFFFFFF;
+ entityManager.add(bird);
+ birds.push(bird);
+ }
+ LK.setTimeout(spawnBird2, Math.random() * 10000 + 20000);
+}
// Add background to the BACKGROUND layer
var background = new Background();
background.x = 2048 / 2;
background.y = 2732 / 2 - 140;
@@ -2605,8 +1606,9 @@
// Initialize bird spawning
spawnBird2();
// ScoreManager class to manage score logic
var ScoreManager = function ScoreManager() {
+ ;
var self = this;
var currentScore = 0;
var highScore = storage.highScore || 0;
self.scoreValues = {
@@ -2707,89 +1709,113 @@
// initializeClouds already called earlier
var bird1; // Define bird1 variable in the global scope
var bird; // Define bird variable in the global scope
var ufo; // Define the ufo variable in the global scope
-var jet; // Define the jet variable in the global scope
var laser; // Define the laser variable in the global scope
var ufoTimer = LK.setTimeout(function () {
addUFO();
// Reset the timer for the UFO to reappear between 10-20 seconds
ufoTimer = LK.setTimeout(arguments.callee, Math.random() * 10000 + 10000);
}, Math.random() * 10000 + 10000); // Initial interval for UFO appearances between 10 to 20 seconds
-game.update = function () {
- // Update clouds
- for (var i = 0; i < clouds.length; i++) {
- clouds[i].update();
+// Helper functions for game update
+function updateEntityPositions() {
+ game.children.forEach(function (entity) {
+ if (entity.update) {
+ entity.update();
+ }
+ // Handle off-screen objects
+ if ((entity instanceof Bird1 || entity instanceof Bird2) && entity.y > 2732) {
+ entity.y = -entity.height;
+ entity.x = Math.random() * 2048;
+ }
+ });
+}
+function handleCollisions() {
+ game.children.forEach(function (child) {
+ if (child instanceof Laser) {
+ child.update();
+ checkLaserCollisions(child);
+ }
+ });
+}
+function checkLaserCollisions(laser) {
+ game.children.forEach(function (target) {
+ if (!laser.lastIntersecting && AABBIntersect(laser, target)) {
+ handleCollisionPoints(laser, target);
+ }
+ });
+ laser.lastIntersecting = game.children.some(function (target) {
+ return (target instanceof Bird1 || target instanceof Bird2 || target instanceof UFO1 || target instanceof UFO2) && laser.intersects(target);
+ });
+}
+function handleCollisionPoints(laser, target) {
+ var points = 0;
+ var soundEffect = '';
+ if (target instanceof Bird1) {
+ points = 100;
+ soundEffect = 'dead1';
+ spawnManager.objectCounts.bird1--;
+ } else if (target instanceof Bird2) {
+ points = 50;
+ soundEffect = 'dead2';
+ spawnManager.objectCounts.bird2--;
+ } else if (target instanceof UFO1 || target instanceof UFO2) {
+ points = 250;
+ soundEffect = 'dead3';
+ spawnManager.objectCounts[target instanceof UFO1 ? 'ufo1' : 'ufo2']--;
}
- // Add a jet to the game if it doesn't exist and no jet spawn timer is active
- if (!game.jet && !game.jetSpawnTimer) {
- var jet = new Jet1();
- jet.x = Math.random() < 0.5 ? 2048 + jet.width / 2 : -jet.width / 2;
- jet.y = Math.random() * (2732 / 2);
- game.addChild(jet);
- game.jet = jet;
- game.layerManager.addToLayer(jet, LAYERS.JET1);
- LK.getSound('jet1').play();
+ if (points > 0) {
+ game.score = (game.score || 0) + points;
+ if (scoreDisplay && scoreDisplay.updateScore) {
+ scoreDisplay.updateScore(game.score);
+ }
+ if (game.mirror && game.mirror.updateScore) {
+ game.mirror.updateScore(game.score);
+ }
+ LK.getSound(soundEffect).play();
+ target.destroy();
+ laser.destroy();
}
- // Update jet
- if (game.jet) {
- game.jet.update();
- }
- if (ufo) {
- ufo.customUpdate();
- // Cache game children to avoid repeated property access
- var gameChildren = game.children;
- // Update lasers and check collisions
- gameChildren.forEach(function (child) {
- if (child instanceof Laser) {
- child.update();
- // Check for intersections with birds and UFO
- var hasIntersection = birds.some(function (bird) {
- if (!child.lastIntersecting && AABBIntersect(child, bird)) {
- score += bird instanceof Bird1 ? 5 : bird instanceof Bird2 ? 1 : 0;
- scoreDisplay.updateScore(score);
- LK.getSound('dead1').play();
- bird.destroy();
- birds.splice(birds.indexOf(bird), 1);
- child.destroy();
- return true;
- }
- return child.intersects(bird);
- });
- if (!hasIntersection && ufo && !child.lastIntersecting && AABBIntersect(child, ufo)) {
- score += 25;
- scoreDisplay.updateScore(score);
- scoreDisplay.updateScore(score);
- child.destroy();
- }
- child.lastIntersecting = hasIntersection || ufo && child.intersects(ufo);
+ game.update = function () {
+ updateEntityPositions();
+ handleCollisions();
+ if (ufo) {
+ ufo.customUpdate();
+ // Check if UFO is out of bounds
+ if (ufo.lastX <= 2048 + ufo.width / 2 && ufo.x > 2048 + ufo.width / 2 || ufo.lastX >= -ufo.width / 2 && ufo.x < -ufo.width / 2) {
+ ufo.destroy();
+ ufo = null;
+ ufoTimer = LK.setTimeout(function () {
+ ufo = addUFO();
+ }, Math.random() * 20000 + 30000);
}
- });
- // Check for intersections between UFO and birds
- var ufoIntersection = birds.some(function (bird) {
- if (!ufo.lastIntersecting && ufo.intersects(bird)) {
- bird.destroy();
- birds.splice(birds.indexOf(bird), 1);
- LK.getSound('dead2').play();
- return true;
+ ufo.lastX = ufo.x;
+ }
+ };
+ // Update existing birds
+ game.children.forEach(function (bird) {
+ if (bird instanceof Bird1 || bird instanceof Bird2) {
+ if (bird.y > 2732) {
+ bird.y = -bird.height;
+ bird.x = Math.random() * 2048;
}
- return ufo.intersects(bird);
- });
- ufo.lastIntersecting = ufoIntersection;
- // Check if UFO is out of bounds
- if (ufo.lastX <= 2048 + ufo.width / 2 && ufo.x > 2048 + ufo.width / 2 || ufo.lastX >= -ufo.width / 2 && ufo.x < -ufo.width / 2) {
- ufo.destroy();
- ufo = null;
- ufoTimer = LK.setTimeout(function () {
- ufo = addUFO();
- }, Math.random() * 20000 + 30000);
}
- ufo.lastX = ufo.x;
+ });
+}
+// Update UFOs and play sounds
+game.children.forEach(function (entity) {
+ if ((entity instanceof UFO1 || entity instanceof UFO2) && !entity.soundPlayed && entity.x > 0 && entity.x < 2048) {
+ LK.getSound('ufo1').play();
+ entity.soundPlayed = true;
}
-};
-// Function to spawn a third kind of bird
-// Update bird positions and states
-;
+});
+// Update each laser and check collisions
+game.children.forEach(function (laser) {
+ if (laser instanceof Laser) {
+ laser.update();
+ checkLaserCollisions(laser);
+ }
+});
// Add a tree to the game
var tree = game.addChild(new Tree());
tree.x = 2048 / 2 + 600; // Move the tree 500px to the right
tree.y = 2500; // Position the tree on the grass
@@ -2822,12 +1848,20 @@
// Add grassFront to the proper layer
if (game.children.includes(grassFront)) {
game.layerManager.addToLayer(grassFront, LAYERS.GRASS_FRONT); // Use layer manager to set grass-front layer
}
-// Mirror and scoreDisplay are already initialized earlier in the code
-// Ensure proper layer ordering for existing mirror
-if (game.mirror) {
- game.layerManager.addToLayer(game.mirror, LAYERS.MIRROR);
+var scoreDisplay = new Mirror();
+scoreDisplay.x = 2048 / 2 + 400; // Move the score display 400px to the right
+scoreDisplay.y = 2732 - 185 - 80 - 390 + 30 + 50; // Move the score display up by an additional 80px and down by 30px + 50px
+game.addChild(scoreDisplay);
+var mirror = new Mirror();
+mirror.x = 2048 / 2 + 400; // Move the mirror 400px to the right
+mirror.y = 2732 - 185 - 80 - 390 + 30; // Move the mirror up by an additional 80px and down by 30px
+game.addChild(mirror);
+// Add mirror to the proper layer using the layer manager
+// Add mirror to the proper layer
+if (game.children.includes(mirror)) {
+ game.layerManager.addToLayer(mirror, LAYERS.MIRROR); // Use layer manager to set mirror layer
}
// Function to handle bgm1 end event
// Add the cat to the game
var cat = game.addChild(new Cat());
@@ -2886,101 +1920,38 @@
}, sound.duration * 1000);
ambientSoundTimer = LK.setTimeout(arguments.callee, Math.random() * 10000 + 20000);
}, Math.random() * 10000 + 20000);
});
-var EntityManager = /*#__PURE__*/function () {
- function EntityManager() {
- _classCallCheck2(this, EntityManager);
- this.entities = [];
- }
- return _createClass2(EntityManager, [{
- key: "add",
- value: function add(entity) {
- this.entities.push(entity);
- // Add to the game world (e.g., addChild)
- game.addChild(entity);
- }
- }, {
- key: "remove",
- value: function remove(entity) {
- var index = this.entities.indexOf(entity);
- if (index > -1) {
- this.entities.splice(index, 1);
- // Remove from the game world (e.g., destroy)
- entity.destroy();
- }
- }
- }, {
- key: "update",
- value: function update(deltaTime) {
- var _iterator = _createForOfIteratorHelper(this.entities),
- _step;
- try {
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
- var entity = _step.value;
- entity.update(deltaTime);
- }
- } catch (err) {
- _iterator.e(err);
- } finally {
- _iterator.f();
- }
- }
- }, {
- key: "getAllOfType",
- value: function getAllOfType(type) {
- return this.entities.filter(function (entity) {
- return entity instanceof type;
- });
- }
- }, {
- key: "clear",
- value: function clear() {
- this.entities.forEach(function (entity) {
- return entity.destroy();
- });
- this.entities = [];
- }
- }]);
-}(); // Initialize entity managers
-var deltaTime = 1 / 60; // Assuming 60 FPS for deltaTime calculation
-var birdManager = new BirdManager();
-var ufoManager = new UFOManager();
-var jetManager = new JetManager();
-// Update all entity managers
-birdManager.update(deltaTime);
-ufoManager.update(deltaTime);
-jetManager.update(deltaTime);
+// Initialize EntityManager
+var entityManager = new EntityManager();
// Initial entity spawning will be handled by the managers
if (typeof x !== 'undefined' && typeof y !== 'undefined') {
var laser = new Laser(cat.x - 140, cat.y - 440, x, y); // laser starting point
entityManager.add(laser);
} else {
console.error('Invalid coordinates for laser creation');
}
// Ensure timers for ambient sounds and bgm1 are set to repeat every 20-30 seconds
-// Group all initialization functions together
function initializeAmbientSounds() {
- function playAmbientSounds() {
+ var _playAmbientSounds = function playAmbientSounds() {
LK.getSound('songbird1').play();
LK.getSound('cricket1').play();
- LK.setTimeout(playAmbientSounds, Math.random() * 10000 + 20000); // 20-30 seconds
- }
- playAmbientSounds();
+ LK.setTimeout(_playAmbientSounds, Math.random() * 10000 + 20000); // 20-30 seconds
+ };
+ _playAmbientSounds();
// Set initial interval
- LK.setInterval(playAmbientSounds, 25000); // Average of 20-30 seconds
+ LK.setInterval(_playAmbientSounds, 25000); // Average of 20-30 seconds
}
-// Part of grouped initialization functions
function initializeBGM() {
- function playBGM() {
+ var playBGM = function playBGM() {
LK.playMusic('bgm1');
- }
+ };
playBGM();
// Set regular interval for background music
LK.setInterval(playBGM, 25000); // Average of 20-30 seconds
}
// Fix scoring
-// ScoreManager is already initialized in the SpawnManager
+var scoreManager = new ScoreManager();
var score = 0;
game.down = function (x, y, obj) {
if (obj && obj.event) {
x = obj.event.x;
@@ -3064,20 +2035,7 @@
}
if (currentX <= screenWidth + halfWidth && this.x > screenWidth + halfWidth || currentX >= -halfWidth && this.x < -halfWidth) {
LK.getSound('ufo1').stop();
this.destroy();
- game.ufo = null;
- scheduleUFOSpawn(Math.random() * 10000 + 20000);
}
this.lastX = this.x;
-};
-function scheduleUFOSpawn(delay) {
- LK.setTimeout(function () {
- var ufo = new UFO();
- ufo.x = Math.random() < 0.5 ? 2048 + ufo.width / 2 : -ufo.width / 2;
- ufo.y = Math.random() * (2732 / 2);
- game.addChild(ufo);
- game.layerManager.addToLayer(ufo, LAYERS.UFO1);
- game.ufo = ufo;
- }, delay);
-}
-// End of Game Implementation
\ No newline at end of file
+};
\ No newline at end of file
an orange and white cat facing away from the camera. the cat is sitting straight up and looking up, ready to pounce. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
remove black box
fluffy translucent cloud. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
bright sun with wincing cartoon face and a black eye. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
a goofy ufo. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
red gaming reticle. Minimal. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
sunny day, hilly landscape. there is an alien invasion taking place in the distance. cities burning.
large AUTUMN SHADES tree with sparse bunches of leaves. branches are exposed, but the tree is tough and old.. true-color, realistic, Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
glowing orange sphere. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
sideway view of a fighter jet. . . In-Game 2d asset. transparent background. horizontal. No shadows.
shiny purple and black attack ufo.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
wings1
Sound effect
ufo1
Sound effect
cricket1
Sound effect
frog1
Sound effect
bgm1
Music
breeze1
Sound effect
songbird1
Sound effect
laser1
Sound effect
teslacoil
Sound effect
chitter
Sound effect
laser2
Sound effect
dead1
Sound effect
electro
Sound effect