User prompt
Remove the console.log
Code edit (4 edits merged)
Please save this source code
User prompt
plant class refreshGraphics should also randomly flip the x scale
Code edit (5 edits merged)
Please save this source code
User prompt
When the farmGraphics are clicked, call the tryPlantFruit function
Code edit (3 edits merged)
Please save this source code
User prompt
explosions should have their initial rotation set to face the planet
User prompt
explosions should start with 0.5 alpha and fade it out over its lifetime and also double its scale over its lifetime
User prompt
Create a global effectsList array and call updateList(effectsList) in the on tick callback. Explosion effects should be added to this list in their constructor
User prompt
When asteroids impact, they should create an explosion effect where they landed
User prompt
Move the angle, and fruitX,Y calculations into the if statement for fruitDiamondDust creation
User prompt
Instead of asteroids always creating a diamondDustFruit on impact, add a ASTEROID_DROP_CHANCE global of 0.1 (10% chance)
Code edit (1 edits merged)
Please save this source code
Code edit (1 edits merged)
Please save this source code
Code edit (4 edits merged)
Please save this source code
User prompt
in the planet update method, update all nodes as well
Code edit (2 edits merged)
Please save this source code
User prompt
move the fruitList array onto the planet. Instead of updating all fruits on tick callback, update the list in the planet update method
Code edit (2 edits merged)
Please save this source code
User prompt
Fix Bug: 'ReferenceError: angle is not defined' in or related to this line: 'var baseIndex = mod(Math.round(angle / MATH_2_PI * count), count);' Line Number: 161
Code edit (2 edits merged)
Please save this source code
User prompt
add a new action function to plantNodes that checks if its plant exists, and is harvestable and calls the harvest function on it. Returning whether the harvest was callable
User prompt
Replace `// TODO: Create fruit at node's position` with: spawn a new fruit with the self.fruit variable as the name, at the parent node's position and attach it to the planet
Code edit (4 edits merged)
Please save this source code
User prompt
add a harvest function and a harvestable variable to the Plant class
/****
* Classes
****/
var BorderedText = Container.expand(function (string, config) {
var self = Container.call(this);
config = config || {};
var textList = [];
var anchorX = config.anchorX !== undefined ? config.anchorX : 0;
var anchorY = config.anchorY !== undefined ? config.anchorY : 0;
var borderConfig = {
fill: config.border || TEXT_DEFAULT_BORDER,
font: config.font || TEXT_DEFAULT_FONT,
size: config.size || TEXT_DEFAULT_SIZE
};
var textConfig = {
fill: config.fill || TEXT_DEFAULT_FILL,
font: config.font || TEXT_DEFAULT_FONT,
size: config.size || TEXT_DEFAULT_SIZE
};
for (var i = 0; i < TEXT_OFFSETS.length; i++) {
var localSettings = i === TEXT_OFFSETS.length - 1 ? textConfig : borderConfig;
var text = self.addChild(new Text2(string, localSettings));
text.x += TEXT_OFFSETS[i][0] * TEXT_BORDER_WEIGHT;
text.y += TEXT_OFFSETS[i][1] * TEXT_BORDER_WEIGHT;
text.anchor.set(anchorX, anchorY);
textList.push(text);
}
;
self.x = config.x || 0;
self.y = config.y || 0;
self.setText = setText;
self.setFill = setFill;
;
function setText(string) {
for (var i = 0; i < textList.length; i++) {
textList[i].setText(string);
}
}
function setFill(newFill) {
textList[textList.length - 1].fill = newFill;
}
});
var CurrencySymbol = Container.expand(function (config) {
var self = Container.call(this);
config = config || {};
var mainSymbol;
var anchorX = config.anchorX !== undefined ? config.anchorX : .5;
var anchorY = config.anchorY !== undefined ? config.anchorY : .5;
var borderSettings = {
fill: 0x000000,
// fill: config.border || TEXT_DEFAULT_BORDER,
size: config.size || TEXT_DEFAULT_SIZE
};
var symbolSettings = {
fill: 0xFFFFFF,
// fill: config.fill || TEXT_DEFAULT_FILL,
size: config.size || TEXT_DEFAULT_SIZE
};
for (var i = 0; i < TEXT_OFFSETS.length; i++) {
var localConfig = i === TEXT_OFFSETS.length - 1 ? symbolSettings : borderSettings;
var symbol = self.attachAsset('currencySymbol', {});
symbol.tint = localConfig.fill;
symbol.anchor.set(anchorX, anchorY);
symbol.scale.set(localConfig.size / 100);
symbol.x += TEXT_OFFSETS[i][0] * TEXT_BORDER_WEIGHT;
symbol.y += TEXT_OFFSETS[i][1] * TEXT_BORDER_WEIGHT;
if (i === TEXT_OFFSETS.length - 1) {
mainSymbol = symbol;
}
}
;
self.x = config.x || 0;
self.y = config.y || 0;
self.setFill = setFill;
;
function setFill(newFill) {
mainSymbol.tint = newFill;
}
});
var CurrencyText = Container.expand(function (amount, config) {
var self = Container.call(this);
config = config || {};
var anchorX = config.anchorX !== undefined ? config.anchorX : .5;
var anchorY = config.anchorY !== undefined ? config.anchorY : .5;
var margin = config.margin || CURRENCY_DEFAULT_MARGIN;
var currencySymbol = self.addChild(new CurrencySymbol({
anchorX: 0,
anchorY: anchorY
}));
var textAmount = self.addChild(new BorderedText(amount, {
anchorX: 0,
anchorY: anchorY
}));
;
self.x = config.x || 0;
self.y = config.y || 0;
self.setAmount = setAmount;
;
function alignText() {
var totalWidth = currencySymbol.width + margin + textAmount.width;
currencySymbol.x = -totalWidth * anchorX;
textAmount.x = currencySymbol.x + currencySymbol.width + margin;
}
function setAmount(newAmount) {
textAmount.setText(newAmount);
alignText();
}
;
alignText();
});
var ConfigContainer = Container.expand(function (config) {
var self = Container.call(this);
;
config = config || {};
self.x = config.x || 0;
self.y = config.y || 0;
self.rotation = config.rotation || 0;
if (config.width !== undefined) {
self.width = config.width;
}
if (config.height !== undefined) {
self.height = config.height;
}
if (self.anchor) {
self.anchor.set(config.anchorX || 0, config.anchorY || 0);
}
;
return self;
});
var Player = ConfigContainer.expand(function (config) {
var self = ConfigContainer.call(this, config);
var actionCountdown = PLAYER_ACTION_INTERVAL;
var playerGraphics = self.attachAsset('player', {
rotation: MATH_HALF_PI,
anchorX: 0.5,
anchorY: 0.5
});
;
self.update = update;
;
function update() {
var currentAngle = Math.atan2(self.y, self.x);
var angleDifference = targetAngle - currentAngle;
angleDifference = mod(angleDifference + Math.PI, MATH_2_PI) - Math.PI;
if (angleDifference < -MATH_APPROX_ZERO || angleDifference > MATH_APPROX_ZERO) {
var direction = angleDifference / Math.abs(angleDifference);
var angleStep = PLAYER_SPEED / planet.radius;
var newAngle = currentAngle + direction * Math.min(Math.abs(angleDifference), angleStep);
self.x = Math.cos(newAngle) * planet.radius;
self.y = Math.sin(newAngle) * planet.radius;
playerGraphics.scale.x = direction < 0 ? -1 : 1;
playerGraphics.rotation = newAngle + MATH_HALF_PI;
actionCountdown = PLAYER_ACTION_INTERVAL;
} else if (--actionCountdown <= 0) {
actionCountdown = PLAYER_ACTION_INTERVAL;
var actionNode = checkForActionNode(currentAngle);
if (actionNode) {
performAction(actionNode);
}
}
}
function performAction(actionNode) {}
function checkForActionNode(angle) {
var count = planet.nodes.length;
var baseIndex = mod(Math.round(angle / MATH_2_PI * count), count);
}
});
var Ship = Container.expand(function (x, y) {
var self = Container.call(this);
var shipGraphics = self.attachAsset('ship', {
anchorX: 0.35,
anchorY: 0.5
});
var counter = 0;
;
self.update = update;
self.launch = launch;
self.x = x;
self.y = y;
self.direction = -1;
;
function update() {
if (self.direction < 0) {
self.x -= ROCKET_SPEED_REVERSE;
if (self.x <= self.parent.radius) {
self.x = self.parent.radius;
self.direction = 0;
player = planet.addChild(new Player({
rotation: ship.rotation,
x: ship.x,
y: ship.y
}));
}
} else if (self.direction > 0) {
counter++;
var speed = Math.pow(ROCKET_SPEED_BASE, counter / ROCKET_SPEED_DIV - ROCKET_SPEED_DELAY);
self.x += speed;
if (self.x > ROCKET_DIST_LEAVE) {
counter = 0;
self.direction = -1;
transitionPlanets();
}
}
}
function launch(direction) {
if (!self.direction) {
self.direction = direction;
if (direction > 0) {
player.destroy();
player = undefined;
}
}
}
});
var Plant = ConfigContainer.expand(function (type, stage, config) {
var self = ConfigContainer.call(this, config);
var details = PLANT_DETAILS[type];
;
self.update = update;
self.newStage = newStage;
self.refreshGraphics = refreshGraphics;
self.refreshCountdown = refreshCountdown;
self.type = type;
self.fruit = details.fruit;
self.stage = stage;
self.stages = details.stages;
self.growthTime = details.growthTime;
self.growthVariance = details.growthVariance;
self.stageCountdown = 0;
self.harvestable = false;
;
function update() {
if (self.stageCountdown > 0) {
self.stageCountdown--;
} else if (self.stage < self.stages - 1) {
self.newStage(self.stage + 1);
}
}
function newStage(stage) {
self.stage = stage;
self.refreshGraphics();
self.refreshCountdown();
if (self.stage === self.stages - 1) {
self.harvestable = true;
}
}
function refreshGraphics() {
if (self.graphics) {
self.graphics.destroy();
}
self.graphics = self.createAsset(self.type + self.stage, {
anchorX: 0.5,
anchorY: 1
});
}
function refreshCountdown() {
self.stageCountdown = Math.floor(self.growthTime + Math.random() * self.growthVariance);
}
;
self.refreshCountdown();
self.refreshGraphics();
self.harvest = function () {
if (self.harvestable) {
// Harvest logic will be implemented here
}
};
return self;
});
var PlantWeeds = Plant.expand(function (stage, config) {
var self = Plant.call(this, 'plantWeeds', stage, config);
});
var PlantBush = Plant.expand(function (stage, config) {
var self = Plant.call(this, 'plantBush', stage, config);
});
var PlantStalk = Plant.expand(function (stage, config) {
var self = Plant.call(this, 'plantStalk', stage, config);
});
var PlantEyeball = Plant.expand(function (stage, config) {
var self = Plant.call(this, 'plantEyeball', stage, config);
});
var PlantNode = ConfigContainer.expand(function (config) {
var self = ConfigContainer.call(this, config);
;
self.update = update;
self.addPlant = addPlant;
self.offset = 20;
self.plant;
self.farm;
self.prev;
self.next;
;
function update() {}
function addPlant(plantName, stage) {
var plantBlueprint = PLANT_DETAILS[plantName].blueprint;
self.plant = self.addChild(new plantBlueprint(stage, {
y: self.offset
}));
}
;
return self;
});
var FarmNode = PlantNode.expand(function (config) {
var self = PlantNode.call(this, config);
var baseOffset = self.offset;
var baseUpdate = self.update;
var baseAddPlant = self.addPlant;
var targetAlpha = 0;
var currentAlpha = targetAlpha;
var farmGraphics = self.attachAsset('farm', {
anchorX: 0.5,
anchorY: 0.6,
alpha: currentAlpha
});
farmGraphics.scale.set(PLOT_SIZE / 100);
;
self.update = update;
self.addPlant = addPlant;
self.tryPlantFruit = tryPlantFruit;
self.offset = -20;
;
function update() {
baseUpdate();
if (currentAlpha !== targetAlpha) {
if (currentAlpha < targetAlpha) {
currentAlpha = Math.min(1, currentAlpha + PLOT_ALPHA_STEP);
} else {
currentAlpha = Math.max(0, currentAlpha - PLOT_ALPHA_STEP);
}
}
}
function addPlant(plantName, stage) {
baseAddPlant(plantName, stage);
if (plantName === 'plantWeeds') {
self.plant.y = baseOffset;
targetAlpha = 0;
} else {
targetAlpha = 1;
}
}
function tryPlantFruit(fruitName) {}
});
var Planet = Container.expand(function (x, y, radius, assetName, barren) {
var self = Container.call(this);
var perimeter = MATH_2_PI * radius;
var numPlots = Math.floor(perimeter / (PLOT_SIZE + PLOT_GAP));
var numNodes = numPlots / 4;
var nodes = [];
var planetGraphics = self.createAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5
});
planetGraphics.scale.set(2 * radius / 1000);
;
self.update = update;
self.x = x;
self.y = y;
self.nodes = nodes;
self.radius = radius;
self.rotation = Math.random() * MATH_2_PI;
self.spin = 0;
;
function update(ticks) {
self.rotation += self.spin;
}
function createNodes() {
if (!barren) {
var defaultPlant = 'plantWeeds';
var maxPlantStage = PLANT_DETAILS[defaultPlant].stages;
for (var i = 0; i < numPlots * 4; i++) {
var angle = i / (numPlots * 4) * MATH_2_PI;
var nodeX = radius * Math.cos(angle);
var nodeY = radius * Math.sin(angle);
var rotation = angle + MATH_HALF_PI;
var farmNode = i !== 0 && i % 4 === 0;
var nodeType = farmNode ? FarmNode : PlantNode;
var node = self.addChild(new nodeType({
x: nodeX,
y: nodeY,
rotation: rotation
}));
if (farmNode) {
node.addPlant(defaultPlant, maxPlantStage - 1);
} else if (Math.random() < 0.2) {
node.addPlant(defaultPlant, Math.floor(Math.random() * maxPlantStage));
}
nodes.push(node);
}
}
}
;
createNodes();
return self;
});
var PlanetGrey = Planet.expand(function (x, y) {
var self = Planet.call(this, x, y, PLANET_RADIUS_GREY, 'planetGrey');
;
self.spin = PLANET_SPIN_GREY;
});
var PlanetRed = Planet.expand(function (x, y) {
var self = Planet.call(this, x, y, PLANET_RADIUS_RED, 'planetRed');
;
self.spin = PLANET_SPIN_RED;
});
var PlanetBlue = Planet.expand(function (x, y) {
var self = Planet.call(this, x, y, PLANET_RADIUS_BLUE, 'planetBlue');
;
self.spin = PLANET_SPIN_BLUE;
});
var PlanetOmni = Planet.expand(function (x, y) {
var self = Planet.call(this, x, y, PLANET_RADIUS_OMNI, 'planetOmni');
;
self.spin = PLANET_SPIN_OMNI;
});
var PlanetGold = Planet.expand(function (x, y) {
var self = Planet.call(this, x, y, PLANET_RADIUS_GOLD, 'planetGold', true);
;
self.spin = PLANET_SPIN_GOLD;
});
var Crosshair = Container.expand(function () {
var self = Container.call(this);
var counter = 0;
var arrows = [];
var arrowOffsets = [{
x: 0,
y: -1
}, {
x: 1,
y: 0
}, {
x: 0,
y: 1
}, {
x: -1,
y: 0
}];
for (var i = 0; i < arrowOffsets.length; i++) {
var arrow = self.attachAsset('arrow', {
anchorX: 0.5,
anchorY: 1
});
arrow.rotation = MATH_HALF_PI * i;
arrows.push(arrow);
self.addChild(arrow);
}
;
self.rotation = MATH_QUARTER_PI;
self.update = update;
;
function update() {
if (currentPlanet !== destinationPlanet) {
counter++;
var distance = CROSSHAIR_DIST + CROSSHAIR_VARIANCE * Math.sin(counter / CROSSHAIR_PERIOD);
setDistance(distance);
} else if (counter > 0) {
counter = 0;
setDistance(CROSSHAIR_DIST);
}
}
function setDistance(distance) {
for (var i = 0; i < arrows.length; i++) {
arrows[i].x = arrowOffsets[i].x * distance;
arrows[i].y = arrowOffsets[i].y * distance;
}
}
;
setDistance(CROSSHAIR_DIST);
});
var NavigationButton = Container.expand(function (x, y, index, callback) {
var self = Container.call(this);
var details = NAVIGATION[index];
var buttonGraphics = self.attachAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0xFFAAAA
});
var planetGraphics = self.createAsset(details.planet, {
anchorX: 0.5,
anchorY: 0.5,
width: buttonGraphics.width * 0.4,
height: buttonGraphics.width * 0.4
});
var currencyText = self.addChild(new CurrencyText(details.cost));
;
self.unlock = unlock;
self.x = x;
self.y = y;
self.cost = details.cost;
self.planet = details.planet;
self.unlocked = false;
self.on('down', function () {
callback(index);
});
;
function unlock() {
self.unlocked = true;
buttonGraphics.tint = 0xFFFFFF;
currencyText.destroy();
}
});
var NavigationInterface = Container.expand(function (x, y) {
var self = Container.call(this);
var buttons = [];
for (var i = 0; i < NAVIGATION.length; i++) {
var buttonX = (-NAVIGATION.length / 2 + 0.5 + i) * 200;
buttons.push(self.addChild(new NavigationButton(buttonX, 0, i, buttonCallback)));
}
buttons[0].addChild(crosshair);
self.x = x;
self.y = y;
;
function buttonCallback(index) {
var button = buttons[index];
if (button.unlocked) {
setDestination(index);
} else if (money >= button.cost) {
moneyDisplay.setAmount(money -= button.cost);
button.unlock();
}
}
self.setDestination = setDestination;
;
function setDestination(index) {
if (destinationPlanet !== index && ship.direction === 0) {
destinationPlanet = index;
buttons[index].addChild(crosshair);
ship.launch(1);
}
}
buttonCallback(0);
});
var WinningMessage = Container.expand(function (x, y, completionTicks) {
var self = Container.call(this);
var seconds = Math.floor(completionTicks / 60);
var minutes = Math.floor(seconds / 60);
var hours = Math.floor(minutes / 60);
seconds = seconds % 60;
minutes = minutes % 60;
var winningTime = (hours > 0 ? hours + 'h ' : '') + (minutes > 0 ? minutes + 'm ' : '') + seconds + 's';
var messageStatTitles = ['Credits', 'Harvests', 'Weeds', 'Trades'];
var messageStatKeys = ['creditsEarned', 'cropsHarvested', 'weedsPulled', 'salesDone'];
var timeText = self.addChild(new BorderedText('You reached the Gold Planet in: ' + winningTime, {
anchorX: .5,
anchorY: 1,
y: -TEXT_WINNING_OFFSET
}));
self.addChild(new BorderedText('Congratulations, you win!', {
anchorX: .5,
anchorY: 1,
size: 80,
y: timeText.y - timeText.height - 10
}));
self.addChild(new BorderedText(messageStatTitles.map(mapTitle).join('\n'), {
anchorX: 1,
anchorY: 0,
y: TEXT_WINNING_OFFSET
}));
self.addChild(new BorderedText(messageStatKeys.map(mapKey).join('\n'), {
anchorX: 0,
anchorY: 0,
y: TEXT_WINNING_OFFSET
}));
;
self.x = x;
self.y = y;
;
function mapTitle(title) {
return '• ' + title + ' ';
}
function mapKey(key) {
var stat = winningStats[key];
var extra = stat - stats[key];
return ': ' + stat + (extra ? ' (+ ' + extra + ')' : '');
}
});
var Background = Container.expand(function () {
var self = Container.call(this);
var backgroundGraphics = self.attachAsset('background', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.5
});
backgroundGraphics.width = GAME_WIDTH * 1.05;
backgroundGraphics.height = GAME_WIDTH * 1.05;
;
self.x = GAME_WIDTH / 2;
self.y = GAME_HEIGHT / 2;
self.refresh = refresh;
;
function refresh() {
backgroundGraphics.rotation += Math.PI / 2;
}
});
var InventorySlot = ConfigContainer.expand(function (index, config) {
var self = ConfigContainer.call(this, config);
var itemDisplay;
var frame = self.attachAsset('inventoryFrame', {
anchorX: .5,
anchorY: .5
});
var selectionContainer = self.addChild(new Container());
var quantityText = self.addChild(new BorderedText('', {
size: 30,
anchorX: .5,
anchorY: .5,
y: INVENTORY_SLOT_SIZE / 2.2
}));
frame.width = INVENTORY_SLOT_SIZE;
frame.height = INVENTORY_SLOT_SIZE;
;
self.setItem = setItem;
self.adjustQuantity = adjustQuantity;
self.selectionContainer = selectionContainer;
self.index = index;
self.item = null;
self.quantity = 0;
;
function adjustQuantity(amount) {
self.quantity += amount;
quantityText.setText(self.quantity);
}
function setItem(itemName) {
self.item = itemName;
if (itemDisplay) {
itemDisplay.destroy();
}
itemDisplay = self.attachAsset(itemName, {
anchorX: 0.5,
anchorY: 0.5
});
itemDisplay.scale.set(INVENTORY_SLOT_SIZE / 100 * INVENTORY_ICON_SCALE);
}
;
self.on('down', function () {
self.parent.selectSlot(self.index);
});
});
var Inventory = ConfigContainer.expand(function (config) {
var self = ConfigContainer.call(this, config);
var slots = [];
var itemIndices = {};
var widthOffset = INVENTORY_SLOT_SIZE * INVENTORY_COLS * (config.anchorX || 0);
var heightOffset = INVENTORY_SLOT_SIZE * INVENTORY_ROWS * (config.anchorY || 0);
for (var row = 0; row < INVENTORY_ROWS; row++) {
for (var col = 0; col < INVENTORY_COLS; col++) {
var index = row * INVENTORY_COLS + col;
slots.push(self.addChild(new InventorySlot(index, {
x: (col + .5) * INVENTORY_SLOT_SIZE - widthOffset,
y: (row + .5) * INVENTORY_SLOT_SIZE - heightOffset
})));
}
}
;
self.adjustItem = adjustItem;
self.selectSlot = selectSlot;
self.selector = LK.getAsset('inventorySelector', {
anchorX: .5,
anchorY: .5,
tint: 0xFF3333
});
;
function selectSlot(index) {
slots[index].selectionContainer.addChild(self.selector);
}
function adjustItem(item, quantity) {
var slotIndex = itemIndices[item];
if (slotIndex === undefined) {
for (slotIndex = 0; slotIndex < slots.length; slotIndex++) {
if (!slots[slotIndex].item) {
break;
}
}
slots[slotIndex].setItem(item);
}
itemIndices[item] = slotIndex;
slots[slotIndex].adjustQuantity(quantity);
}
;
selectSlot(0);
adjustItem('fruitWeeds', 0);
});
var Asteroid = ConfigContainer.expand(function (config) {
var self = ConfigContainer.call(this, config);
var asteroidGraphics = self.attachAsset('asteroid', {
anchorX: 0.5,
anchorY: 0.5,
rotation: Math.random() * MATH_2_PI
});
var randomScale = ASTEROID_SCALE_MIN + Math.random() * ASTEROID_SCALE_VAR;
asteroidGraphics.scale.set(randomScale);
var side = self.x < 0;
var targetY = ASTEROID_TARGET_OFFSET + Math.random() * (GAME_HEIGHT - 2 * ASTEROID_TARGET_OFFSET);
var targetX = side ? GAME_WIDTH + ASTEROID_MARGIN : -ASTEROID_MARGIN;
var rotationSpeed = (Math.random() - 0.5) * 2 * ASTEROID_ROTATION_MAX;
var angle = Math.atan2(targetY - self.y, targetX - self.x);
var velocityX = ASTEROID_SPEED * Math.cos(angle);
var velocityY = ASTEROID_SPEED * Math.sin(angle);
;
self.update = update;
;
function update() {
self.rotation += rotationSpeed;
self.x += velocityX;
self.y += velocityY;
var dx = self.x - planet.x;
var dy = self.y - planet.y;
var distanceSquared = dx * dx + dy * dy;
if (distanceSquared <= planet.radius * planet.radius) {
var angle = Math.atan2(self.y - planet.y, self.x - planet.x) - planet.rotation;
var fruitX = Math.cos(angle) * planet.radius;
var fruitY = Math.sin(angle) * planet.radius;
var fruit = planet.addChild(new Fruit('fruitDiamondDust', {
rotation: angle,
x: fruitX,
y: fruitY
}));
return true;
}
return side ? self.x > targetX : self.x < targetX;
}
});
var Fruit = ConfigContainer.expand(function (fruitName, config) {
var self = ConfigContainer.call(this, config);
var fruitGraphics = self.attachAsset(fruitName, {
anchorX: 0.5,
anchorY: 0.5,
rotation: MATH_HALF_PI
});
fruitGraphics.scale.set(INVENTORY_SLOT_SIZE / 100 * INVENTORY_ICON_SCALE);
;
self.fruitName = fruitName;
self.update = update;
;
function update() {
if (player) {
var dx = self.x - player.x;
var dy = self.y - player.y;
var sqrDistance = dx * dx + dy * dy;
if (sqrDistance < PLAYER_ACTION_SQRDIST) {
inventory.adjustItem(fruitName, 1);
return true;
}
}
}
;
fruitList.push(self);
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000 // Init game with black background
});
/****
* Game Code
****/
// Math constants / pre-calculations
var MATH_2_PI = Math.PI * 2;
var MATH_HALF_PI = Math.PI / 2;
var MATH_QUARTER_PI = Math.PI / 4;
var MATH_HALF_ROOT_3 = Math.sqrt(3) / 2;
var MATH_APPROX_ZERO = 0.0000001;
// Game constants
var GAME_TICKS = 60;
var GAME_WIDTH = 2048;
var GAME_HEIGHT = 2732;
// Planet constants (TODO: Move to PLANET_DETAILS map)
var PLANET_RADIUS_GREY = 200;
var PLANET_RADIUS_RED = 400;
var PLANET_RADIUS_BLUE = 350;
var PLANET_RADIUS_OMNI = 500;
var PLANET_RADIUS_GOLD = 250;
var PLANET_SPIN_GREY = 0.001;
var PLANET_SPIN_RED = -0.0002;
var PLANET_SPIN_BLUE = 0.001;
var PLANET_SPIN_OMNI = 0.005;
var PLANET_SPIN_GOLD = -0.001;
// Rocket constants
var ROCKET_DIST_REVERSE = 300;
var ROCKET_DIST_LEAVE = 2500;
var ROCKET_SPEED_BASE = 1.2;
var ROCKET_SPEED_DIV = 5;
var ROCKET_SPEED_DELAY = 10;
var ROCKET_SPEED_REVERSE = 2;
var PLOT_SIZE = 65;
var PLOT_GAP = 90;
var PLOT_ALPHA_STEP = 1 / GAME_TICKS;
var TEXT_OFFSETS = [[0, 1], [MATH_HALF_ROOT_3, 0.5], [MATH_HALF_ROOT_3, -0.5], [0, -1], [-MATH_HALF_ROOT_3, -0.5], [-MATH_HALF_ROOT_3, 0.5], [0, 0]];
var TEXT_BORDER_WEIGHT = 4;
var TEXT_DEFAULT_SIZE = 50;
var TEXT_DEFAULT_FONT = 'Arial';
var TEXT_DEFAULT_FILL = '#FFFFFF';
var TEXT_DEFAULT_BORDER = '#000000';
var TEXT_WINNING_OFFSET = 300;
var CURRENCY_DEFAULT_MARGIN = 0;
var CROSSHAIR_DIST = 40;
var CROSSHAIR_VARIANCE = 10;
var CROSSHAIR_PERIOD = 1.25 * GAME_TICKS / MATH_2_PI;
var INVENTORY_ROWS = 1;
var INVENTORY_COLS = 8;
var INVENTORY_ICON_SCALE = 0.5;
var INVENTORY_SLOT_SIZE = 100;
var ASTEROID_SPAWN_CHANCE = 0.001;
var ASTEROID_ROTATION_MAX = 0.02;
var ASTEROID_SPEED = 5;
var ASTEROID_MARGIN = 100;
var ASTEROID_SCALE_MIN = 0.75;
var ASTEROID_SCALE_VAR = 0.5;
var ASTEROID_TARGET_OFFSET = 500;
var PLAYER_SPEED = 5;
var PLAYER_ACTION_INTERVAL = GAME_TICKS / 2;
var PLAYER_ACTION_DIST = 100;
var PLAYER_ACTION_SQRDIST = PLAYER_ACTION_DIST * PLAYER_ACTION_DIST;
var PLAYER_BUFFER_DIST = 200;
var PLAYER_BUFFER_SQRDIST = PLAYER_BUFFER_DIST * PLAYER_BUFFER_DIST;
var PLANT_DETAILS = {
plantWeeds: {
blueprint: PlantWeeds,
stages: 4,
fruit: 'fruitWeeds',
growthTime: 60 * GAME_TICKS,
growthVariance: 10 * GAME_TICKS
},
plantBush: {
blueprint: PlantBush,
stages: 5,
fruit: 'fruitBush',
growthTime: 120 * GAME_TICKS,
growthVariance: 30 * GAME_TICKS
},
plantStalk: {
blueprint: PlantStalk,
stages: 7,
fruit: 'fruitStalk',
growthTime: 60 * GAME_TICKS,
growthVariance: 20 * GAME_TICKS
},
plantEyeball: {
blueprint: PlantEyeball,
stages: 5,
fruit: 'fruitEyeball',
growthTime: 40 * GAME_TICKS,
growthVariance: 10 * GAME_TICKS
}
};
var NAVIGATION = [{
cost: 0,
"class": PlanetGrey,
planet: 'planetGrey',
description: 'Small moon, with no special bonuses.'
}, {
cost: 100,
"class": PlanetRed,
planet: 'planetRed',
description: ''
}, {
cost: 250,
"class": PlanetBlue,
planet: 'planetBlue',
description: ''
}, {
cost: 800,
"class": PlanetOmni,
planet: 'planetOmni',
description: ''
}, {
cost: 3000,
"class": PlanetGold,
planet: 'planetGold',
description: 'A wealthy planet with vast resources.'
}];
;
var money = 10000;
var asteroidList = [];
var fruitList = [];
var stats = {
creditsEarned: 0,
cropsHarvested: 0,
cropsOverrun: 0,
weedsPulled: 0,
salesDone: 0,
salesRejected: 0
};
var winningStats = {};
var winningTick = -1;
var winningTime = '';
var winningMessage;
var player;
var targetAngle = Math.PI / 16;
var currentPlanet = 0;
var destinationPlanet = 0;
var background = game.addChild(new Background());
var planet = game.addChild(new PlanetGrey(GAME_WIDTH / 2, GAME_HEIGHT / 2));
var ship = planet.addChild(new Ship(planet.radius + ROCKET_DIST_REVERSE, 0));
var planets = [planet];
var inventory = LK.gui.top.addChild(new Inventory({
y: INVENTORY_SLOT_SIZE / 2 + 10,
anchorX: .5,
anchorY: .5
}));
var moneyDisplay = LK.gui.top.addChild(new CurrencyText(money, {
x: inventory.width / 2 + 25,
y: inventory.y,
size: 70,
anchorX: 0
}));
var crosshair = new Crosshair();
var navigation = LK.gui.bottom.addChild(new NavigationInterface(0, -100));
;
LK.on('tick', function () {
if (player) {
player.update();
}
ship.update();
planet.update();
crosshair.update();
updateList(asteroidList);
updateList(fruitList);
trySpawnAsteroid();
});
game.on('down', function (obj) {
if (player) {
var clickPosition = obj.event.getLocalPosition(game);
var dx = clickPosition.x - planet.x;
var dy = clickPosition.y - planet.y;
var sqrDistance = dx * dx + dy * dy;
var range = planet.radius + PLAYER_BUFFER_DIST;
if (sqrDistance <= range * range) {
targetAngle = Math.atan2(dy, dx) - planet.rotation;
}
}
});
;
function updateList(list) {
for (var i = list.length - 1; i >= 0; i--) {
var item = list[i];
if (item.update && typeof item.update === 'function' && item.update()) {
item.destroy();
list.splice(i, 1);
}
}
}
function trySpawnAsteroid() {
if (Math.random() < ASTEROID_SPAWN_CHANCE) {
var side = Math.random() < 0.5;
asteroidList.push(game.addChild(new Asteroid({
x: side ? -ASTEROID_MARGIN : GAME_WIDTH + ASTEROID_MARGIN,
y: Math.random() * GAME_HEIGHT,
vx: side ? ASTEROID_SPEED : -ASTEROID_SPEED
})));
}
}
function transitionPlanets() {
LK.effects.flashScreen(0x000000, 500);
currentPlanet = destinationPlanet;
planet.parent.removeChild(planet);
planet = planets[currentPlanet];
background.refresh();
for (var i = 0; i < asteroidList.length; i++) {
asteroidList[i].destroy();
}
asteroidList = [];
if (!planet) {
var planetClass = NAVIGATION[currentPlanet]["class"];
planet = planets[currentPlanet] = new planetClass(GAME_WIDTH / 2, GAME_HEIGHT / 2);
}
if (currentPlanet === NAVIGATION.length - 1) {
if (winningTick < 0) {
saveStats();
winningTick = LK.ticks;
}
winningMessage = LK.gui.center.addChild(new WinningMessage(0, -100, winningTick));
} else if (winningMessage) {
winningMessage.destroy();
winningMessage = undefined;
}
game.addChild(planet);
planet.addChild(ship);
ship.x = planet.radius + ROCKET_DIST_REVERSE;
}
function mod(x, base) {
return (x % base + base) % base;
}
function saveStats() {
for (var key in stats) {
winningStats[key] = stats[key];
}
}
pixel art of a tiny planet. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
pixel art of a planet. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
pixel art of an alien currency symbol. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
pixel art of a planet made of gold ore. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
plain black background with stars. 2d repeating Texture.
pixel art of a asteroid. Game asset. 2d. Blank background. High contrast. No shadows.
pixel art of a cute alien farmer, side view. Game asset. 2d. Blank background. High contrast. No shadows.
pixel art of a rocky explosion.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
pixel art flame particle. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
pixel art of a large white, empty, rectangular, speech bubble. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
pixel art of a red chevron. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Pixel art of yellow grapes. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.