User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'expand')' in or related to this line: 'var GrassFront = GameObject.expand(function () {' Line Number: 49
Code edit (1 edits merged)
Please save this source code
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'expand')' in or related to this line: 'var GrassFront = GameObject.expand(function () {' Line Number: 49
Code edit (1 edits merged)
Please save this source code
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'expand')' in or related to this line: 'var Laser = Container.expand(function (startX, startY, targetX, targetY) {' Line Number: 48
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'expand')' in or related to this line: 'var Laser = Container.expand(function (startX, startY, targetX, targetY) {' Line Number: 48
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'expand')' in or related to this line: 'var Laser = Container.expand(function (startX, startY, targetX, targetY) {' Line Number: 48
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'expand')' in or related to this line: 'var Laser = Container.expand(function (startX, startY, targetX, targetY) {' Line Number: 48
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'expand')' in or related to this line: 'var Laser = Container.expand(function (startX, startY, targetX, targetY) {' Line Number: 48
Code edit (2 edits merged)
Please save this source code
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'expand')' in or related to this line: 'var Laser = Container.expand(function (startX, startY, targetX, targetY) {' Line Number: 48
Code edit (3 edits merged)
Please save this source code
User prompt
Please fix the bug: 'LayerManager is not defined' in or related to this line: 'var layerManager = new LayerManager();' Line Number: 843
Code edit (1 edits merged)
Please save this source code
User prompt
Please fix the bug: 'LayerManager is not defined' in or related to this line: 'var layerManager = new LayerManager();' Line Number: 699
Code edit (2 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: 690
Code edit (1 edits merged)
Please save this source code
User prompt
Please fix the bug: 'Cannot set properties of undefined (setting 'x')' in or related to this line: 'return this.soundTimers[soundId];' Line Number: 1497
User prompt
Please fix the bug: 'Cannot set properties of undefined (setting 'x')' in or related to this line: 'return this.soundTimers[soundId];' Line Number: 1491
User prompt
Please fix the bug: 'Cannot set properties of undefined (setting 'x')' in or related to this line: 'return this.soundTimers[soundId];' Line Number: 1491
User prompt
Please fix the bug: 'spawnManager.initialize is not a function' in or related to this line: 'return this.soundTimers[soundId];' Line Number: 1491
User prompt
Please fix the bug: 'spawnManager.initialize is not a function' in or related to this line: 'return this.soundTimers[soundId];' Line Number: 1491
User prompt
Please fix the bug: 'spawnManager.initialize is not a function' in or related to this line: 'return this.soundTimers[soundId];' Line Number: 1491
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ 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 collided = false; var targets = game.layerManager.getAllInteractiveLayers(); for (var i = 0; i < targets.length && !collided; i++) { for (var j = 0; j < targets.length && !collided; j++) { var target = targets[j]; if (!self.lastIntersecting && self.intersects(target)) { var soundEffect = game.layerManager.isInLayer(target, 'ufos') ? 'dead3' : 'dead2'; LK.getSound(soundEffect).play(); // Update score based on target type var scoreValue = 0; if (game.layerManager.isInLayer(target, LAYERS.BIRD1)) { scoreValue = 5; } else if (game.layerManager.isInLayer(target, LAYERS.BIRD2)) { scoreValue = 1; } else if (game.layerManager.isInLayer(target, LAYERS.UFO1) || game.layerManager.isInLayer(target, LAYERS.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; }); var Cat = GameObject.expand(function () { var self = GameObject.call(this); GameObject.call(this, 'cat', { anchorX: 0.5, anchorY: 1 }); return this; }); // Define cloud types at the beginning // Using GrassLayer class for grass-back implementation var GrassFront = GameObject.expand(function () { var self = GameObject.call(this); GameObject.call(this, 'grass-front', { anchorX: 0.5, anchorY: 1 }); this.update = function () { // Swaying effect with bounds checking and smoother movement var maxOffset = 2.0; var offset = Math.sin(LK.ticks / 90) * 0.15; this.x += Math.max(-maxOffset, Math.min(maxOffset, offset)); }; return this; }); var Light1 = GameObject.expand(function () { var self = GameObject.call(this); GameObject.call(this, 'light1', null, { anchorX: 0.5, anchorY: 0.5, alpha: 1.0 }); this.x = 450; this.y = 450; this.update = function () { // Swaying effect with bounds checking and smoother movement var maxOffset = 1.5; var offset = Math.sin(LK.ticks / 90) * 0.1; this.x += Math.max(-maxOffset, Math.min(maxOffset, offset)); }; this.pulse = new Light1Pulse(this.graphics); this.pulse.startPulsating(); return this; }); var Mirror = GameObject.expand(function () { var self = GameObject.call(this); GameObject.call(this, 'mirror1'); 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); addEntityToLayer(scoreText, LAYERS.UI); this.updateScore = function (newScore) { scoreText.setText(newScore); }; return this; }); var Reticle = GameObject.expand(function () { var self = GameObject.call(this); GameObject.call(this, 'reticle1'); 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 Stack1 = GameObject.expand(function () { var self = GameObject.call(this); GameObject.call(this, 'stack1', { anchorX: 0.5, anchorY: 0.5, rotation: Math.PI / -12 }); return this; }); var Sun = GameObject.expand(function () { var self = GameObject.call(this); GameObject.call(this, 'sun'); this.pulse = new SunPulse(this.graphics); this.pulse.startPulsating(); return this; }); /**** * Initialize Game ****/ // BaseEntityManager removed - using EntityManager defined at the beginning of the file // Initialize clouds array var game = new LK.Game({ backgroundColor: 0x87CEEB // Sky blue }); /**** * Game Code ****/ // Base GameObject class to handle common functionality // Unified GameObjectMovement class with improved movement patterns and sound management function _defineProperty(e, r, t) { return (r = _toPropertyKey2(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; } function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); } function _possibleConstructorReturn(t, e) { if (e && ("object" == _typeof2(e) || "function" == typeof e)) { return e; } if (void 0 !== e) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(t); } function _assertThisInitialized(e) { if (void 0 === e) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return e; } function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); } function _superPropGet(t, o, e, r) { var p = _get(_getPrototypeOf(1 & r ? t.prototype : t), o, e); return 2 & r && "function" == typeof p ? function (t) { return p.apply(e, t); } : p; } function _get() { return _get = "undefined" != typeof Reflect && Reflect.get ? Reflect.get.bind() : function (e, t, r) { var p = _superPropBase(e, t); if (p) { var n = Object.getOwnPropertyDescriptor(p, t); return n.get ? n.get.call(arguments.length < 3 ? e : r) : n.value; } }, _get.apply(null, arguments); } function _superPropBase(t, o) { for (; !{}.hasOwnProperty.call(t, o) && null !== (t = _getPrototypeOf(t));) { ; } return t; } function _getPrototypeOf(t) { return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) { return t.__proto__ || Object.getPrototypeOf(t); }, _getPrototypeOf(t); } function _inherits(t, e) { if ("function" != typeof e && null !== e) { throw new TypeError("Super expression must either be null or a function"); } t.prototype = Object.create(e && e.prototype, { constructor: { value: t, writable: !0, configurable: !0 } }), Object.defineProperty(t, "prototype", { writable: !1 }), e && _setPrototypeOf(t, e); } function _setPrototypeOf(t, e) { return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) { return t.__proto__ = e, t; }, _setPrototypeOf(t, e); } 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 _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 SoundManager = /*#__PURE__*/function () { function SoundManager(config) { _classCallCheck2(this, SoundManager); this.config = config || {}; this.soundTimers = {}; this.soundIntervals = { ambient: { min: 20000, max: 30000 }, background: { min: 20000, max: 30000 }, ufo: { min: 20000, max: 30000 }, jet: { min: 20000, max: 30000 } }; } return _createClass2(SoundManager, [{ key: "initialize", value: function initialize() { var _this = this; var ambientSounds = [{ id: 'songbird1', volume: 0.1, minDelay: 5000, maxDelay: 15000 }, { id: 'cricket1', volume: 0.1, minDelay: 8000, maxDelay: 20000 }, { id: 'breeze1', volume: 0.1, minDelay: 10000, maxDelay: 25000 }, { id: 'frog1', volume: 0.1, minDelay: 12000, maxDelay: 30000 }, { id: 'chitter', volume: 0.1, minDelay: 15000, maxDelay: 35000 }]; ambientSounds.forEach(function (sound) { var initialDelay = Math.random() * (sound.maxDelay - sound.minDelay) + sound.minDelay; LK.setTimeout(function () { _this.playSound(sound.id, { volume: sound.volume, interval: { min: sound.minDelay, max: sound.maxDelay } }); }, initialDelay); }); this.playSound('bgm1', { isMusic: true, volume: 0.1, loop: true, autoRestart: false }); } }, { key: "playSound", value: function playSound(soundId, options) { var _this2 = this; options = Object.assign({ interval: this.soundIntervals.ambient, isMusic: false, volume: 0.1, loop: false, autoRestart: true }, options); var _playFunction = function playFunction() { if (options.isMusic) { LK.playMusic(soundId, { volume: options.volume }); } else { var sound = LK.getSound(soundId); if (sound) { 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; _this2.soundTimers[soundId] = LK.setTimeout(_playFunction.bind(_this2), nextInterval); } }; _playFunction(); return this.soundTimers[soundId]; } }, { key: "stopSound", value: function stopSound(soundId) { if (this.soundTimers[soundId]) { LK.clearTimeout(this.soundTimers[soundId]); delete this.soundTimers[soundId]; } var sound = LK.getSound(soundId); if (sound) { sound.stop(); } } }, { key: "stopAllSounds", value: function stopAllSounds() { var _this3 = this; Object.keys(this.soundTimers).forEach(function (soundId) { _this3.stopSound(soundId); }); } }]); }(); var Container = /*#__PURE__*/function () { function Container() { _classCallCheck2(this, Container); this.children = []; } return _createClass2(Container, [{ key: "attachAsset", value: function attachAsset(assetName, options) { if (!assetName) { console.error('Asset name is required for attachAsset'); return null; } var asset = LK.getImage(assetName); if (!asset) { console.error('Failed to load asset:', assetName); return null; } var sprite = new Sprite(asset); if (options) { Object.assign(sprite, options); } this.addChild(sprite); return sprite; } }, { key: "addChild", value: function addChild(child) { if (child && !this.children.includes(child)) { this.children.push(child); } return child; } }, { key: "destroy", value: function destroy() { if (this.children) { this.children.forEach(function (child) { if (child && child.destroy) { child.destroy(); } }); this.children = []; } } }]); }(); var EntityManager = /*#__PURE__*/function () { function EntityManager() { _classCallCheck2(this, EntityManager); this.entities = []; this.pendingRemovals = []; } return _createClass2(EntityManager, [{ key: "add", value: function add(entity) { if (!entity) { return; } if (!this.entities.includes(entity)) { this.entities.push(entity); if (entity.type && game.spawnManager && game.spawnManager.objectCounts) { game.spawnManager.objectCounts[entity.type] = (game.spawnManager.objectCounts[entity.type] || 0) + 1; } } } }, { key: "remove", value: function remove(entity) { if (!entity) { return; } var index = this.entities.indexOf(entity); if (index > -1) { this.entities.splice(index, 1); // First mark as destroyed to prevent re-entry if (entity.destroy && !entity.destroyed) { entity.destroy(); } // Then update layer tracking if (game.layerManager) { game.layerManager.removeFromTracking(entity); } // Finally update spawn counts if (entity.type && game.spawnManager && game.spawnManager.objectCounts) { var currentCount = game.spawnManager.objectCounts[entity.type] || 0; game.spawnManager.objectCounts[entity.type] = Math.max(0, currentCount - 1); } } } }, { key: "update", value: function update(deltaTime) { var _this4 = this; // Clear pending removals from previous update this.pendingRemovals = []; // Update entities and mark destroyed ones for removal for (var i = this.entities.length - 1; i >= 0; i--) { var entity = this.entities[i]; if (!entity || entity.destroyed) { this.pendingRemovals.push(entity); continue; } if (entity.update) { entity.update(deltaTime); } } // Remove destroyed entities this.pendingRemovals.forEach(function (entity) { return _this4.remove(entity); }); } }, { key: "getAllOfType", value: function getAllOfType(type) { return this.entities.filter(function (entity) { return entity && !entity.destroyed && entity instanceof type; }); } }, { key: "clear", value: function clear() { // First remove all entities from layer tracking if (game.layerManager) { this.entities.forEach(function (entity) { if (entity && !entity.destroyed) { game.layerManager.removeFromTracking(entity); } }); } // Then destroy all entities this.entities.forEach(function (entity) { if (entity && !entity.destroyed && entity.destroy) { entity.destroy(); } }); this.entities = []; this.pendingRemovals = []; // Finally clear spawn timers if they exist if (game.spawnManager) { // Clear all spawn timers Object.keys(game.spawnManager.spawnTimers || {}).forEach(function (type) { if (game.spawnManager.spawnTimers[type]) { LK.clearTimeout(game.spawnManager.spawnTimers[type]); delete game.spawnManager.spawnTimers[type]; } }); game.spawnManager.spawnTimers = {}; // Reset all object counts game.spawnManager.objectCounts = { bird1: 0, bird2: 0, cloud1: 0, cloud2: 0, ufo1: 0, ufo2: 0, jet1: 0 }; } } }]); }(); var GameObject = /*#__PURE__*/function (_Container) { function GameObject(assetName) { var _this5; var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; _classCallCheck2(this, GameObject); _this5 = _callSuper(this, GameObject); _this5.graphics = _this5.attachAsset(assetName, {}); return _this5; } // Common destroy method _inherits(GameObject, _Container); return _createClass2(GameObject, [{ key: "destroy", value: function destroy() { if (game.layerManager) { game.layerManager.removeFromTracking(this); } if (this.movement && this.movement.cleanup) { this.movement.cleanup(); } _superPropGet(GameObject, "destroy", this, 3)([]); } // Common update method }, { key: "update", value: function update() { if (this.movement) { this.movement.update(); } } }]); }(Container); var Background = /*#__PURE__*/function (_GameObject) { function Background() { _classCallCheck2(this, Background); return _callSuper(this, Background, ['background']); } _inherits(Background, _GameObject); return _createClass2(Background); }(GameObject); var Bird1 = /*#__PURE__*/function (_GameObject2) { function Bird1() { var _this6; _classCallCheck2(this, Bird1); _this6 = _callSuper(this, Bird1, ['bird1']); _this6.type = 'bird1'; _this6.movement = new GameObjectMovement(_this6, _this6.graphics, MovementConfigs.bird1); return _this6; } _inherits(Bird1, _GameObject2); return _createClass2(Bird1); }(GameObject); var Bird2 = /*#__PURE__*/function (_GameObject3) { function Bird2() { var _this7; _classCallCheck2(this, Bird2); _this7 = _callSuper(this, Bird2, ['bird2']); _this7.type = 'bird2'; _this7.movement = new GameObjectMovement(_this7, _this7.graphics, MovementConfigs.bird2); return _this7; } _inherits(Bird2, _GameObject3); return _createClass2(Bird2); }(GameObject); // Define cloud types at the beginning var CLOUD_TYPES = ['cloud1', 'cloud2']; var GrassLayer = /*#__PURE__*/function (_GameObject4) { function GrassLayer(type) { var _this8; _classCallCheck2(this, GrassLayer); _this8 = _callSuper(this, GrassLayer, [type, { anchorX: 0.5, anchorY: 0.5, alpha: 1 }]); _this8.type = type; _this8.movement = new GameObjectMovement(_this8, _this8.graphics, MovementConfigs[type]); return _this8; } _inherits(GrassLayer, _GameObject4); return _createClass2(GrassLayer, [{ key: "update", value: function update(deltaTime) { _superPropGet(GrassLayer, "update", this, 3)([deltaTime]); if (this.movement) { this.movement.update(deltaTime); } } }]); }(GameObject); var GRASS_TYPES = ['grass-front', 'grass-back']; // Initialize grass layers var grassFront = new GrassLayer('grass-front'); grassFront.x = LK.width / 2; grassFront.y = LK.height - 100; var grassBack = new GrassLayer('grass-back'); grassBack.x = LK.width / 2; grassBack.y = LK.height - 150; // Add grass layers to the game game.entityManager.add(grassBack); game.entityManager.add(grassFront); var Cloud = /*#__PURE__*/function (_GameObject5) { function Cloud() { var _this9; _classCallCheck2(this, Cloud); var cloudType = CLOUD_TYPES[Math.floor(Math.random() * CLOUD_TYPES.length)]; _this9 = _callSuper(this, Cloud, [cloudType, { anchorX: 0.5, anchorY: 0.5, alpha: 0.8 }]); _this9.type = cloudType; _this9.movement = new GameObjectMovement(_this9, _this9.graphics, MovementConfigs[_this9.type]); return _this9; } _inherits(Cloud, _GameObject5); return _createClass2(Cloud, [{ key: "destroy", value: function destroy() { if (spawnManager) { spawnManager.objectCounts[this.type === 'cloud1' ? 'cloud1' : 'cloud2']--; } this.movement = null; _superPropGet(Cloud, "destroy", this, 3)([]); } }]); }(GameObject); var Jet1 = /*#__PURE__*/function (_GameObject6) { function Jet1() { var _this10; _classCallCheck2(this, Jet1); _this10 = _callSuper(this, Jet1, ['jet1']); _this10.type = 'jet1'; _this10.movement = new GameObjectMovement(_this10, _this10.graphics, MovementConfigs.jet1); _this10.soundPlayed = false; return _this10; } _inherits(Jet1, _GameObject6); return _createClass2(Jet1, [{ key: "update", value: function update() { _superPropGet(Jet1, "update", this, 3)([]); // Play jet1 sound when on screen if (!this.soundPlayed && this.x > 0 && this.x < 2048) { LK.getSound('jet1').play(); this.soundPlayed = true; } } }]); }(GameObject); 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); addEntityToLayer(jet, LAYERS.JET1); game.jet = jet; } game.jetSpawnTimer = null; } var Tree = /*#__PURE__*/function (_GameObject7) { function Tree() { var _this11; _classCallCheck2(this, Tree); _this11 = _callSuper(this, Tree, ['tree1', { anchorX: 0.5, anchorY: 1, antialias: true, stroke: 0x000000, strokeThickness: 15 }]); _this11.type = 'tree1'; _this11.movement = new GameObjectMovement(_this11, _this11.graphics, MovementConfigs.tree1); return _this11; } _inherits(Tree, _GameObject7); return _createClass2(Tree, [{ key: "update", value: function update(deltaTime) { _superPropGet(Tree, "update", this, 3)([deltaTime]); if (this.movement) { this.movement.update(deltaTime); } } }, { key: "destroy", value: function destroy() { this.movement = null; _superPropGet(Tree, "destroy", this, 3)([]); } }]); }(GameObject); var Tree2 = /*#__PURE__*/function (_GameObject8) { function Tree2() { var _this12; _classCallCheck2(this, Tree2); _this12 = _callSuper(this, Tree2, ['tree2', { anchorX: 0.5, anchorY: 1 }]); _this12.type = 'tree2'; _this12.movement = new GameObjectMovement(_this12, _this12.graphics, MovementConfigs.tree2); return _this12; } _inherits(Tree2, _GameObject8); return _createClass2(Tree2, [{ key: "update", value: function update(deltaTime) { _superPropGet(Tree2, "update", this, 3)([deltaTime]); if (this.movement) { this.movement.update(deltaTime); } } }, { key: "destroy", value: function destroy() { this.movement = null; _superPropGet(Tree2, "destroy", this, 3)([]); } }]); }(GameObject); var UFO1 = /*#__PURE__*/function (_GameObject9) { function UFO1() { var _this13; _classCallCheck2(this, UFO1); _this13 = _callSuper(this, UFO1, ['ufo1']); _this13.type = 'ufo1'; _this13.movement = new GameObjectMovement(_this13, _this13.graphics, MovementConfigs.ufo1); _this13.soundPlayed = false; return _this13; } _inherits(UFO1, _GameObject9); return _createClass2(UFO1, [{ key: "update", value: function update() { _superPropGet(UFO1, "update", this, 3)([]); if (!this.soundPlayed && this.x > 0 && this.x < 2048) { LK.getSound('ufo1').play(); this.soundPlayed = true; } } }]); }(GameObject); var UFO2 = /*#__PURE__*/function (_GameObject10) { function UFO2() { var _this14; _classCallCheck2(this, UFO2); _this14 = _callSuper(this, UFO2, ['ufo2']); _this14.type = 'ufo2'; _this14.movement = new GameObjectMovement(_this14, _this14.graphics, MovementConfigs.ufo2); _this14.soundPlayed = false; return _this14; } _inherits(UFO2, _GameObject10); return _createClass2(UFO2, [{ key: "update", value: function update() { _superPropGet(UFO2, "update", this, 3)([]); if (!this.soundPlayed && this.x > 0 && this.x < 2048) { LK.getSound('ufo1').play(); this.soundPlayed = true; } } }]); }(GameObject); 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 () { if (!this.object || this.object.destroyed) { this.cleanup(); return; } 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 (typeof spawnManager !== 'undefined' && spawnManager && typeof spawnManager.scheduleRespawn === 'function') { spawnManager.scheduleRespawn(this.object.type, this.object.constructor); } } this.object = null; }; this.playMovementSound = function () { if (this.soundTimer) { LK.clearTimeout(this.soundTimer); this.soundTimer = null; } if (!this.options.moveSound || !LK.getSound) { return; } var sound = LK.getSound(this.options.moveSound); if (!sound) { return; } sound.volume = 0.1; sound.play(); this.soundPlayed = true; this.soundTimer = LK.setTimeout(function () { if (this.soundTimer) { 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.layerManager.addToLayer(mirror, LAYERS.MIRROR); game.mirror = mirror; var scoreDisplay = mirror; var soundManager = new SoundManager(); soundManager.initialize(); // Initialize spawn manager // Ensure all entities use LayerManager consistently function addEntityToLayer(entity, layer) { if (!entity || !layer) { console.error('Invalid entity or layer provided to addEntityToLayer'); return entity; } game.layerManager.addToLayer(entity, layer); if (!game.children.includes(entity)) { game.addChild(entity); } return entity; } var _SpawnManager = function SpawnManager() { this.spawnTimers = {}; 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' } }; // Initialize sound manager with ambient sounds configuration this.soundManager = new SoundManager({ ambient: { breeze1: { volume: 0.1, interval: { min: 15000, max: 25000 } }, cricket1: { volume: 0.1, interval: { min: 10000, max: 20000 } }, frog1: { volume: 0.1, interval: { min: 20000, max: 30000 } }, songbird1: { volume: 0.1, interval: { min: 15000, max: 25000 } } } }); this.scoreManager = new ScoreManager(); this.exclusiveGroups = [['ufo1', 'ufo2']]; // Correct layer order as per requirements this.layerOrder = game.layerManager.getLayerOrder(); this.spawnObject = function (type, Constructor, options) { var _this15 = 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 _this15.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 = game.layerManager.getLayerEntityCount(LAYERS.CLOUD1) + game.layerManager.getLayerEntityCount(LAYERS.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 _this15.spawnTimers[type]; _this15.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 appropriate layer using addEntityToLayer addEntityToLayer(obj, rule.layer); // Initialize movement with appropriate options if (rule.movement) { // Define common movement parameters by object type var MovementConfigs = _defineProperty(_defineProperty({ cloud1: { speed: 1.2, speedRange: 0.5, arcAmplitude: 2.0, arcFrequency: 150, isVertical: false, moveSound: null }, cloud2: { speed: 0.8, speedRange: 0.3, arcAmplitude: 1.5, arcFrequency: 180, isVertical: false, moveSound: null }, 'grass-front': { speed: 0, speedRange: 0, arcAmplitude: 1.2, arcFrequency: 120, isVertical: false, moveSound: null, canFlip: false }, 'grass-back': { speed: 0, speedRange: 0, arcAmplitude: 0.8, arcFrequency: 150, isVertical: false, moveSound: null, canFlip: false }, // Base configuration for all entities base: { speedRange: 1.0, arcFrequency: 90, canFlip: true, validateConfig: function validateConfig(config) { var required = ['speed', 'arcAmplitude', 'isVertical', 'moveSound']; return required.every(function (prop) { return config.hasOwnProperty(prop); }); } }, bird1: { speed: 2, speedRange: 1.2, arcAmplitude: 6.5, arcFrequency: 100, isVertical: true, moveSound: 'wings1' }, bird2: { speed: 2.5, speedRange: 1.2, arcAmplitude: 6.5, arcFrequency: 100, isVertical: true, moveSound: 'wings1' }, ufo1: { speed: 3.2, speedRange: 0.8, arcAmplitude: 4.5, arcFrequency: 80, isVertical: false, moveSound: 'ufo1' }, ufo2: { speed: 3.2, speedRange: 0.8, arcAmplitude: 4.5, arcFrequency: 80, isVertical: false, 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) { if (!type || !Constructor || !this.spawnRules) { return; } var rule = this.spawnRules[type]; if (!rule) { return; } // 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 } // Clear existing timer if present if (this.spawnTimers[type]) { LK.clearTimeout(this.spawnTimers[type]); this.spawnTimers[type] = null; } // Initialize object counts if not present if (!this.objectCounts[type]) { this.objectCounts[type] = 0; } this.spawnTimers[type] = LK.setTimeout(function () { // Cleanup timer reference delete this.spawnTimers[type]; // Update object count if (this.objectCounts[type] > 0) { this.objectCounts[type]--; } var shouldSpawn = true; // Check exclusive groups (e.g., only one UFO type at a time) if (this.exclusiveGroups) { for (var i = 0; i < this.exclusiveGroups.length; i++) { var group = this.exclusiveGroups[i]; if (group && group.includes(type)) { var groupTotal = 0; for (var j = 0; j < group.length; j++) { groupTotal += this.objectCounts[group[j]] || 0; } if (groupTotal > 0) { shouldSpawn = false; break; } } } } if (shouldSpawn) { this.spawnObject(type, Constructor); } else { // Reschedule spawn attempt if blocked by exclusive group this.scheduleRespawn(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 game.layerManager.getLayerOrder().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 (game.layerManager.getLayerEntityCount(LAYERS.BIRD1) < 1) { this.spawnObject('bird1', Bird1); } while (game.layerManager.getLayerEntityCount(LAYERS.BIRD2) < 3) { this.spawnObject('bird2', Bird2); } // Maintain cloud counts - ensure 3-5 total clouds var totalClouds = game.layerManager.getLayerEntityCount(LAYERS.CLOUD1) + game.layerManager.getLayerEntityCount(LAYERS.CLOUD2); if (totalClouds < 3) { var cloudsNeeded = 3 - totalClouds; for (var i = 0; i < cloudsNeeded; i++) { if (Math.random() < 0.5 && game.layerManager.getLayerEntityCount(LAYERS.CLOUD1) < this.spawnRules.cloud1.max) { this.spawnObject('cloud1', Cloud); } else if (game.layerManager.getLayerEntityCount(LAYERS.CLOUD2) < this.spawnRules.cloud2.max) { 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 (game.layerManager.getLayerEntityCount(LAYERS.UFO1) + game.layerManager.getLayerEntityCount(LAYERS.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 (game.layerManager.getLayerEntityCount(LAYERS.JET1) === 0 && !this.spawnTimers.jet1) { this.spawnObject('jet1', Jet1); } }.bind(this), 1000); }.bind(this); }; 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 < this.spawnRules.bird2.min; i++) { this.spawnObject('bird2', Bird2); } }; // Set up cloud spawning - 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); } // Schedule initial UFO and Jet spawns if (Math.random() < 0.5) { this.spawnObject('ufo1', UFO1); } else { this.spawnObject('ufo2', UFO2); } 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 = game.layerManager.getLayerEntityCount(LAYERS.CLOUD1) + game.layerManager.getLayerEntityCount(LAYERS.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 (game.layerManager.getLayerEntityCount(LAYERS.UFO1) + game.layerManager.getLayerEntityCount(LAYERS.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 (game.layerManager.getLayerEntityCount(LAYERS.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 (game.layerManager.isInLayer(entity, LAYERS.BIRD1) || game.layerManager.isInLayer(entity, LAYERS.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 ((game.layerManager.isInLayer(entity, LAYERS.UFO1) || game.layerManager.isInLayer(entity, LAYERS.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); } }); }; // Removed redundant checkAndRespawnBirds function as it's handled by SpawnManager // Update bird positions and states function updateGameBirds() { maintainBirdCount(Bird1, 1, LAYERS.BIRD1); maintainBirdCount(Bird2, 3, LAYERS.BIRD2); } function maintainBirdCount(BirdType, targetCount, layerIndex) { var birdCount = game.layerManager.getLayerGroup('birds').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.layerManager.addToLayer(newBird, layerIndex); birds.push(newBird); } } else if (birdCount > targetCount) { var extraBirds = birds.filter(function (b) { return game.layerManager.isInLayer(b, 'birds'); }).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 ((game.layerManager.isInLayer(entity, LAYERS.UFO1) || game.layerManager.isInLayer(entity, LAYERS.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 = addEntityToLayer(new Tree(), LAYERS.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 = addEntityToLayer(new Stack1(), LAYERS.STACK); 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 } 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 addEntityToLayer(scoreDisplay, LAYERS.UI); 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.layerManager.addToLayer(mirror, LAYERS.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 = addEntityToLayer(new Cat(), LAYERS.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' }); }; // Bird2 movement is handled by MovementConfigs.bird2 var Bird2Effects = function Bird2Effects(bird) { ; this.bird = bird; this.applyEffects = function () { // Add any specific effects or animations for Bird1 here }; }; 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 }; }; // Bird2 spawning is now handled by SpawnManager // 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 = addEntityToLayer(new 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); addEntityToLayer(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 = addEntityToLayer(new Reticle(), LAYERS.RETICLE); } if (obj.event) { x = obj.event.x; 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 (game.layerManager.isInLayer(entity, 'birds') && entity.y > 2732) { entity.y = -entity.height; entity.x = Math.random() * 2048; } }); } function handleCollisions() { var projectiles = game.layerManager.getLayerEntities('projectiles'); projectiles.forEach(function (laser) { laser.update(); checkLaserCollisions(laser); }); } function checkLaserCollisions(laser) { var enemies = game.layerManager.getLayerEntities('enemies'); enemies.forEach(function (target) { if (!laser.lastIntersecting && AABBIntersect(laser, target)) { handleCollisionPoints(laser, target); } }); laser.lastIntersecting = enemies.some(function (target) { return 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 (game.layerManager.isInLayer(bird, 'birds')) { if (bird.y > 2732) { bird.y = -bird.height; bird.x = Math.random() * 2048; } } }); } // Update UFOs and play sounds game.children.forEach(function (entity) { if ((game.layerManager.isInLayer(entity, LAYERS.UFO1) || game.layerManager.isInLayer(entity, LAYERS.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 = addEntityToLayer(new Tree(), LAYERS.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 = addEntityToLayer(new Stack1(), LAYERS.STACK); 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 } 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 addEntityToLayer(scoreDisplay, LAYERS.UI); 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.layerManager.addToLayer(mirror, LAYERS.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 = addEntityToLayer(new Cat(), LAYERS.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 = addEntityToLayer(new 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); addEntityToLayer(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; // Use spawn manager to handle respawn if (game.spawnManager) { game.spawnManager.scheduleRespawn('jet1', Jet1); } } 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
@@ -185,17 +185,8 @@
* Game Code
****/
// Base GameObject class to handle common functionality
// Unified GameObjectMovement class with improved movement patterns and sound management
-Container.expand = function (constructorFunction) {
- function ExtendedContainer() {
- Container.call(this);
- constructorFunction.apply(this, arguments);
- }
- ExtendedContainer.prototype = Object.create(Container.prototype);
- ExtendedContainer.prototype.constructor = ExtendedContainer;
- return ExtendedContainer;
-};
function _defineProperty(e, r, t) {
return (r = _toPropertyKey2(r)) in e ? Object.defineProperty(e, r, {
value: t,
enumerable: !0,
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