/****
* Classes
****/
// Asteroid class
var Asteroid = Container.expand(function () {
var self = Container.call(this);
var asteroidGraphics = self.attachAsset('asteroid', {
anchorX: 0.5,
anchorY: 0.5
});
self.speedX = Math.random() * 2 - 1; // Random horizontal speed
self.speedY = Math.random() * 3 + 1; // Random vertical speed
self._update_migrated = function () {
self.x += self.speedX;
self.y += self.speedY;
// Destroy asteroid if it goes off-screen
if (self.y > 2732 || self.x < 0 || self.x > 2048) {
self.destroy();
}
};
});
var CrashedLander = Container.expand(function () {
var self = Container.call(this);
var crashedLanderGraphics = self.attachAsset('crashedlander', {
anchorX: 0.5,
anchorY: 0.5
});
self.destroyAfterOneSecond = function () {
LK.setTimeout(function () {
self.destroy();
}, 1000);
};
});
var DottedLine = Container.expand(function () {
var self = Container.call(this);
self.createDottedLine = function (startX, startY, endX, endY, color, dotSize, gapSize) {
var distance = Math.sqrt(Math.pow(endX - startX, 2) + Math.pow(endY - startY, 2));
var dotCount = Math.floor(distance / (dotSize + gapSize * 2));
for (var i = 0; i < dotCount; i++) {
var dot = self.addChild(LK.getAsset('dot', {
anchorX: 0.5,
anchorY: 0.5
}));
dot.alpha = 0.5;
dot.x = startX + (endX - startX) * (i / dotCount);
dot.y = startY + (endY - startY) * (i / dotCount);
dot.width = dotSize;
dot.height = dotSize;
dot.tint = color;
}
};
});
// Down Thruster class
var DownThruster = Container.expand(function () {
var self = Container.call(this);
var downThrusterGraphics = self.attachAsset('thruster', {
anchorX: 0.5,
anchorY: 0.5
});
});
var LandedLander = Container.expand(function () {
var self = Container.call(this);
var landedLanderGraphics = self.attachAsset('landedlander', {
anchorX: 0.5,
anchorY: 0.5
});
self.destroyAfterOneSecond = function () {
LK.setTimeout(function () {
self.destroy();
}, 1000);
};
});
// Lander class
var Lander = Container.expand(function () {
var self = Container.call(this);
var landerGraphics = self.attachAsset('lander', {
anchorX: 0.5,
anchorY: 0.5
});
self.speedX = 0;
self.speedY = 0;
self.fuel = 500;
self.isThrusting = false;
self.isLanding = false;
self._update_migrated = function () {
if (!self.isLanding) {
self.x += self.speedX;
self.y += self.speedY;
if (self.isThrusting && self.fuel > 0) {
if (self.thrustDirection === 'left') {
self.speedX += 0.1; // Right thruster effect
} else if (self.thrustDirection === 'right') {
self.speedX -= 0.1; // Left thruster effect
} else {
self.speedY -= 0.2; // Down thruster effect
}
self.fuel -= 1;
fuelTxt.setText(Math.round(self.fuel / 500 * 100) + '% Fuel'); // Show fuel as a percentage
} else {
self.speedY += 0.05; // Gravity effect
}
ySpeedTxt.setText('Y Speed: ' + self.speedY.toFixed(2)); // Update Y Speed display
}
// Update thruster position and visibility
if (self.thrustDirection === 'left') {
leftThruster.x = self.x - self.width / 2;
leftThruster.y = self.y;
leftThruster.visible = self.isThrusting;
} else {
leftThruster.visible = false;
}
if (self.thrustDirection === 'right') {
rightThruster.x = self.x + self.width / 2;
rightThruster.y = self.y;
rightThruster.visible = self.isThrusting;
} else {
rightThruster.visible = false;
}
if (self.thrustDirection === 'down') {
downThruster.x = self.x;
downThruster.y = self.y + self.height / 2 + 10;
downThruster.visible = self.isThrusting;
} else {
downThruster.visible = false;
}
downThruster.x = self.x;
downThruster.y = self.y + self.height / 2 + 40;
};
self.land = function () {
self.isLanding = true;
var landedLander = game.addChild(new LandedLander());
landedLander.x = self.x;
landedLander.y = self.y;
landedLander.destroyAfterOneSecond();
levelManager.incrementLevel();
LK.getSound('hooray').play();
};
self.refuel = function () {
self.fuel = 500;
fuelTxt.setText('100% Fuel'); // Show fuel as a percentage when refueled
};
});
// Left Thruster class
var LeftThruster = Container.expand(function () {
var self = Container.call(this);
var leftThrusterGraphics = self.attachAsset('leftThruster', {
anchorX: 0.5,
anchorY: 0.5
});
});
// Level class
var Level = Container.expand(function () {
var self = Container.call(this);
self.currentLevel = 1;
var levelTxt = new Text2('Level: ' + self.currentLevel, {
size: 100,
// Double the size
fill: "#ffffff"
});
levelTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(levelTxt);
self.incrementLevel = function () {
self.currentLevel += 1;
levelTxt.setText('Level: ' + self.currentLevel);
platform.startMoving(self.currentLevel);
leftDottedLine.visible = false;
rightDottedLine.visible = false;
leftMessage.visible = false;
centerMessage.visible = false;
rightMessage.visible = false;
var successMessages = ['Smooth landing Captain!', 'Perfect touchdown!', 'Another successful landing!', 'You nailed it!', 'Flawless descent!'];
var randomIndex = Math.floor(Math.random() * successMessages.length);
var successMessage = new Text2(successMessages[randomIndex], {
size: 100,
fill: '#ffffff',
align: 'center'
});
successMessage.anchor.set(0.5, 0.5);
successMessage.x = 1024;
successMessage.y = 1066;
game.addChild(successMessage);
LK.setTimeout(function () {
successMessage.destroy();
}, 1000);
isPaused = true;
pauseTimer = 60;
};
});
// Platform class
var MovingPlatform = Container.expand(function () {
var self = Container.call(this);
var platformGraphics = self.attachAsset('platform', {
anchorX: 0.5,
anchorY: 0.5
});
self.speedX = 0;
self.startMoving = function (level) {
LK.setTimeout(function () {
if (level >= 2) {
self.x = Math.random() * (2048 - self.width) + self.width / 2; // Random horizontal start position ensuring platform is fully visible
}
if (level >= 5) {
self.speedX = 2.8 + (level - 5) * 0.2; // Increase sideways speed by 0.2 for each level above 5
}
}, 1000); // Add a 1 second pause before repositioning the platform
};
self._update_migrated = function () {
self.x += self.speedX;
if (self.x > 1524 || self.x < 524) {
self.speedX *= -1; // Change direction when hitting screen bounds
}
};
self.checkLanding = function (lander) {
if (lander.intersects(self)) {
if (lander.speedY < 2 && lander.speedX >= -1 && lander.speedX <= 1 && lander.x > self.x - self.width / 2 && lander.x < self.x + self.width / 2) {
return true;
} else {
isGameOver = true;
var crashedLander = game.addChild(new CrashedLander());
crashedLander.x = lander.x;
crashedLander.y = lander.y;
crashedLander.destroyAfterOneSecond();
leftMessage.visible = false;
centerMessage.visible = false;
rightMessage.visible = false;
leftDottedLine.visible = false;
rightDottedLine.visible = false;
LK.getSound('crash').play(); // Play crash sound
if (levelManager.currentLevel <= 2) {
var crashMessageLine1 = new Text2('Slow down Captain!', {
size: 100,
fill: '#ffffff',
align: 'center'
});
crashMessageLine1.anchor.set(0.5, 0.5);
crashMessageLine1.x = 1024;
crashMessageLine1.y = 1150;
game.addChild(crashMessageLine1);
var crashMessageLine2 = new Text2('-Keep Y speed below 2\n-And X between -1 and 1', {
size: 70,
fill: '#ffffff',
align: 'center'
});
crashMessageLine2.anchor.set(0.5, 0.5);
crashMessageLine2.x = 1024;
crashMessageLine2.y = 1316;
game.addChild(crashMessageLine2);
LK.setTimeout(function () {
crashMessageLine1.destroy();
crashMessageLine2.destroy();
}, 3000);
}
if (levelManager.currentLevel <= 2) {
LK.setTimeout(function () {
LK.showGameOver();
}, 3000);
} else {
LK.showGameOver();
}
return false;
}
}
return false;
};
});
// Right Thruster class
var RightThruster = Container.expand(function () {
var self = Container.call(this);
var rightThrusterGraphics = self.attachAsset('rightThruster', {
anchorX: 0.5,
anchorY: 0.5
});
});
/****
* Initialize Game
****/
// Stars class
// Center vertically
// Initialize lander
var game = new LK.Game({
backgroundColor: 0x000000 // Init game with black background
});
/****
* Game Code
****/
// Stars class
// Initialize lander
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(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
function _defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) {
descriptor.writable = true;
}
Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor);
}
}
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) {
_defineProperties(Constructor.prototype, protoProps);
}
if (staticProps) {
_defineProperties(Constructor, staticProps);
}
Object.defineProperty(Constructor, "prototype", {
writable: false
});
return Constructor;
}
function _toPropertyKey(t) {
var i = _toPrimitive(t, "string");
return "symbol" == _typeof(i) ? i : String(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);
}
function _inherits(subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function");
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
writable: true,
configurable: true
}
});
Object.defineProperty(subClass, "prototype", {
writable: false
});
if (superClass) {
_setPrototypeOf(subClass, superClass);
}
}
function _setPrototypeOf(o, p) {
_setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) {
o.__proto__ = p;
return o;
};
return _setPrototypeOf(o, p);
}
function _createSuper(Derived) {
var hasNativeReflectConstruct = _isNativeReflectConstruct();
return function _createSuperInternal() {
var Super = _getPrototypeOf(Derived),
result;
if (hasNativeReflectConstruct) {
var NewTarget = _getPrototypeOf(this).constructor;
result = Reflect.construct(Super, arguments, NewTarget);
} else {
result = Super.apply(this, arguments);
}
return _possibleConstructorReturn(this, result);
};
}
function _possibleConstructorReturn(self, call) {
if (call && (_typeof(call) === "object" || typeof call === "function")) {
return call;
} else if (call !== void 0) {
throw new TypeError("Derived constructors may only return object or undefined");
}
return _assertThisInitialized(self);
}
function _assertThisInitialized(self) {
if (self === void 0) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return self;
}
function _isNativeReflectConstruct() {
if (typeof Reflect === "undefined" || !Reflect.construct) {
return false;
}
if (Reflect.construct.sham) {
return false;
}
if (typeof Proxy === "function") {
return true;
}
try {
Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
return true;
} catch (e) {
return false;
}
}
function _getPrototypeOf(o) {
_getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) {
return o.__proto__ || Object.getPrototypeOf(o);
};
return _getPrototypeOf(o);
}
var Stars = /*#__PURE__*/function (_Container) {
_inherits(Stars, _Container);
var _super = _createSuper(Stars);
function Stars() {
var _thi;
_classCallCheck(this, Stars);
_this = _super.call(this);
_this.createStars();
return _this;
}
_createClass(Stars, [{
key: "createStars",
value: function createStars() {
for (var i = 0; i < 100; i++) {
var star = this.addChild(LK.getAsset('star', {
anchorX: 0.5,
anchorY: 0.5
}));
star.x = Math.random() * 2048;
star.y = Math.random() * 2732;
star.alpha = Math.random() * 0.5 + 0.5; // Random transparency for twinkling effect
var randomScale = Math.random() * 0.3 + 0.2; // Random scale for different sizes
star.scale.x = randomScale;
star.scale.y = randomScale;
}
}
}]);
return Stars;
}(Container);
var background = game.addChild(LK.getAsset('background', {}));
background.x = 1024; // Center horizontally
background.y = 1366;
// Add stars behind the main background
var stars = game.addChild(new Stars());
// Add second background
var secondBackground = game.addChildAt(LK.getAsset('secondBackground', {
anchorX: 0.5,
anchorY: 0.5
}), 0);
secondBackground.width = 2048;
secondBackground.height = 2732;
secondBackground.x = 2048 / 2; // Center horizontally
secondBackground.y = 2732 / 2; // Center vertically
var scoreTxt = new Text2('0', {
size: 50,
fill: "#ffffff"
});
scoreTxt.anchor.set(0.5, 0);
//LK.gui.top.addChild(scoreTxt);
// Initialize thrusters
var downThruster = game.addChild(new DownThruster()); // Position down thruster at the bottom center of the lander
var leftThruster = game.addChild(new LeftThruster());
leftThruster.visible = false;
var rightThruster = game.addChild(new RightThruster());
rightThruster.visible = false;
// Initialize level manager
var levelManager = game.addChild(new Level());
var leftMessage = new Text2('Tap here for\nLeft Thruster', {
size: 70,
fill: '#cccccc',
alpha: 0.5,
align: 'center'
});
leftMessage.anchor.set(0.5, 0.5);
leftMessage.x = 2048 / 6;
leftMessage.y = 1066;
game.addChild(leftMessage);
var centerMessage = new Text2('Tap here for\nCenter Thruster', {
size: 70,
fill: '#cccccc',
alpha: 0.5,
align: 'center'
});
centerMessage.anchor.set(0.5, 0.5);
centerMessage.x = 2048 / 2;
centerMessage.y = 1066;
game.addChild(centerMessage);
var rightMessage = new Text2('Tap here for\nRight Thruster', {
size: 70,
alpha: 0.5,
fill: '#cccccc',
align: 'center'
});
rightMessage.anchor.set(0.5, 0.5);
rightMessage.x = 2048 * 5 / 6;
rightMessage.y = 1066;
game.addChild(rightMessage);
// Create and add two vertical dotted lines
var leftDottedLine = game.addChild(new DottedLine());
leftDottedLine.createDottedLine(2048 / 3, 0, 2048 / 3, 2732, 0xffffff, 5, 10);
var rightDottedLine = game.addChild(new DottedLine());
rightDottedLine.createDottedLine(2048 * 2 / 3, 0, 2048 * 2 / 3, 2732, 0xffffff, 5, 10);
// Initialize moving platform
var platform = game.addChild(new MovingPlatform());
// Add the lander after the messages to ensure it appears in front of them
var lander = game.addChild(new Lander());
lander.x = 1024; // Start in the middle of the screen horizontally
lander.y = 250; // Start 250 pixels down from the top
platform.x = 1024; // Center horizontally
platform.y = 2632; // Place at the bottom
// Game variables
var isGameOver = false;
var isPaused = false;
var pauseTimer = 0;
var score = 0;
var asteroids = [];
// Fuel display text
var fuelTxt = new Text2('100% Fuel', {
size: 50,
fill: "#ffffff"
});
fuelTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(fuelTxt);
// Y Speed display text
var ySpeedTxt = new Text2('Y Speed: ' + lander.speedY.toFixed(2), {
size: 50,
fill: "#ffffff"
});
ySpeedTxt.anchor.set(1, 0);
ySpeedTxt.y = 50;
LK.gui.topRight.addChild(ySpeedTxt);
// X Speed display text
var xSpeedTxt = new Text2('X Speed: ' + lander.speedX.toFixed(2), {
size: 50,
fill: "#ffffff"
});
xSpeedTxt.anchor.set(1, 0);
xSpeedTxt.y = 100;
LK.gui.topRight.addChild(xSpeedTxt);
// Gravity display text
var gravityTxt = new Text2('Gravity: 1.62', {
size: 50,
fill: "#ffffff"
});
gravityTxt.anchor.set(1, 0);
gravityTxt.y = 150;
LK.gui.topRight.addChild(gravityTxt);
// Event listeners
game.on('down', function (x, y, obj) {
var touchPos = game.toLocal(obj.global);
if (touchPos.x < 2048 / 3) {
lander.thrustDirection = 'left';
} else if (touchPos.x > 2048 * 2 / 3) {
lander.thrustDirection = 'right';
} else {
lander.thrustDirection = 'down';
}
lander.isThrusting = true;
LK.getSound('thruster').play();
});
game.on('up', function (x, y, obj) {
lander.isThrusting = false;
lander.thrustDirection = null;
});
// Game tick update
LK.on('tick', function () {
if (isPaused) {
lander.visible = false;
pauseTimer--;
if (pauseTimer <= 0) {
isPaused = false;
lander.visible = true;
}
return;
}
if (!isGameOver) {
// Update all asteroids
asteroids = game.children.filter(function (child) {
return child instanceof Asteroid;
});
lander._update_migrated();
platform._update_migrated(); // Update platform position
// Update X Speed display
xSpeedTxt.setText('X Speed: ' + lander.speedX.toFixed(2));
// Check for landing
if (platform.checkLanding(lander)) {
lander.land();
score += 1;
scoreTxt.setText(score.toString());
lander.refuel();
lander.isLanding = true;
LK.setTimeout(function () {
lander.x = 1024;
lander.y = 250;
lander.speedX = 0;
lander.speedY = 0;
lander.isLanding = false;
}, 2 * 1000 / 60); // Wait for 2 ticks (1000ms/60fps * 2)
}
// Check for collision with asteroids and game over conditions
for (var i = 0; i < asteroids.length; i++) {
if (lander.intersects(asteroids[i])) {
isGameOver = true;
LK.showGameOver();
break;
}
}
// Check if lander is off-screen for game over
if (lander.y > 2732) {
isGameOver = true;
LK.showGameOver();
}
// Asteroid spawning
if (levelManager.currentLevel >= 3 && LK.ticks % (240 - Math.floor((levelManager.currentLevel - 1) / 2) * 20) == 0) {
// Spawn an asteroid less frequently as levels progress
// Adjusted the rate of increase for asteroid spawn frequency
var newAsteroid = new Asteroid();
var safeZoneRadius = 400;
var landerSpawnX = 1024;
var minDistanceFromLander;
do {
newAsteroid.x = Math.random() * 2048; // Random horizontal start position
minDistanceFromLander = Math.abs(newAsteroid.x - landerSpawnX);
} while (minDistanceFromLander <= safeZoneRadius);
newAsteroid.y = -50; // Start just above the screen
game.addChild(newAsteroid);
}
// Update all asteroids
asteroids = game.children.filter(function (child) {
return child instanceof Asteroid;
});
for (var i = 0; i < asteroids.length; i++) {
asteroids[i]._update_migrated();
}
// Check for game over conditions
if (lander.y > 3000 || lander.x < -300 || lander.x > 2348 || lander.y < -300) {
isGameOver = true;
leftDottedLine.visible = false;
rightDottedLine.visible = false;
leftMessage.visible = false;
centerMessage.visible = false;
rightMessage.visible = false;
var lostMessage = new Text2('You got Lost in Space! Try again!', {
size: 100,
fill: '#ffffff',
align: 'center'
});
lostMessage.anchor.set(0.5, 0.5);
lostMessage.x = 1024;
lostMessage.y = 1366;
game.addChild(lostMessage);
LK.setTimeout(function () {
lostMessage.destroy();
LK.showGameOver();
}, 2000);
}
}
});