Code edit (13 edits merged)
Please save this source code
User prompt
prevent box shadow scale being less than the `SHADOW_MIN_SCALE` value
User prompt
add a global called `SHADOW_MIN_SCALE` of value 0.1
User prompt
Fix Bug: 'ReferenceError: count is not defined' in this line: 'if (countdown <= 0) {' Line Number: 329
Code edit (1 edits merged)
Please save this source code
User prompt
Rename `shiftContainer` function to `shift` for all classes
User prompt
Fix Bug: 'ReferenceError: shift is not defined' in this line: 'self.shift = shift;' Line Number: 95
User prompt
Rename `shiftContainer` to `shift` for all classes
User prompt
Rename `shiftContainer` to `shift` for all classes
User prompt
Remove the unused shift variable from the shiftableContainer class only
User prompt
Rename every single occurrence of `baseShiftContainer` to `baseShift`
User prompt
Fix Bug: 'ReferenceError: baseShiftContainer is not defined' in this line: 'baseShiftContainer(amount);' Line Number: 574
User prompt
Fix Bug: 'ReferenceError: baseShiftContainer is not defined' in this line: 'baseShiftContainer();' Line Number: 119
User prompt
Rename every single occurrence of `baseShiftContainer` to `baseShift`
Code edit (3 edits merged)
Please save this source code
User prompt
Fix Bug: 'TypeError: Box.expend is not a function' in this line: 'var InvisBox = Box.expend(function (x, y, args) {' Line Number: 556
Code edit (1 edits merged)
Please save this source code
Code edit (1 edits merged)
Please save this source code
User prompt
in the box update method, before checking the alive state, set self.alive to false if the box's y value goes above: `STAGE_HEIGHT + BOX_HEIGHT / 2`
Code edit (3 edits merged)
Please save this source code
User prompt
add an isPaused = false variable to the interface class, which when true prevents non-interface update ticks
User prompt
Add a global TERMINAL_VELOCITY = 20 and make sure boxes and the player never exceeds this value while falling
User prompt
Replace both PLAYER_GRAVITY and BOX_GRAVITY with a single GRAVITY global of 0.5. Make sure to update old references in the box and player class
Code edit (7 edits merged)
Please save this source code
User prompt
remove all console.log commands in the tnt explode function
var BorderedText = Container.expand(function (string, settings) {
var self = Container.call(this);
var textList = [];
var defaultFill = '#ffffff';
var defaultBorder = '#000000';
var defaultFont = 'Arial';
var defaultSize = 80;
var weight = 6;
var r3by2 = Math.sqrt(3) / 2;
var offsets = [[0, 1], [r3by2, 0.5], [r3by2, -0.5], [0, -1], [-r3by2, -0.5], [-r3by2, 0.5], [0, 0]];
var borderSettings = {
fill: settings.border || defaultBorder,
font: settings.font || defaultFont,
size: settings.size || defaultSize
};
var textSettings = {
fill: settings.fill || defaultFill,
font: settings.font || defaultFont,
size: settings.size || defaultSize
};
self.x = settings.x;
self.y = settings.y;
for (var i = 0; i < offsets.length; i++) {
var localSettings = i === offsets.length - 1 ? textSettings : borderSettings;
var text = self.addChild(new Text2(string, localSettings));
text.x += offsets[i][0] * weight;
text.y += offsets[i][1] * weight;
if (settings.anchor) {
text.anchor.set(settings.anchor.x || 0, settings.anchor.y || 0);
}
textList.push(text);
}
self.setText = function (string) {
for (var i = 0; i < textList.length; i++) {
textList[i].setText(string);
}
};
self.setFill = function (newFill) {
textList[textList.length - 1].fill = newFill;
};
});
var Background = Container.expand(function () {
var self = Container.call(this);
self.x = STAGE_WIDTH / 2;
self.y = STAGE_HEIGHT / 2;
;
var backgroundGraphics = self.createAsset('background', 'Background image', 0.5, 0.5);
backgroundGraphics.width = STAGE_WIDTH;
backgroundGraphics.height = STAGE_HEIGHT;
});
var Floor = Container.expand(function (x, y) {
var self = Container.call(this);
self.x = x;
self.y = y;
;
var floorGraphics = self.createAsset('floor', 'Floor image', 0.5, 0.5);
});
var Interface = Container.expand(function () {
var self = Container.call(this);
var score = 0;
var scoreTxt = self.addChild(new BorderedText(score.toString(), {
size: 150,
anchor: {
x: .5
}
}));
var moveInstructions = self.addChild(new BorderedText('Swipe left or right to move', {
y: scoreTxt.height + 20,
anchor: {
x: .5
}
}));
var jumpInstructions = self.addChild(new BorderedText('Swipe up or tap to jump', {
y: moveInstructions.y + moveInstructions.height + 10,
anchor: {
x: .5
}
}));
;
self.increment = increment;
self.gameOver = gameOver;
self.hideInstructions = hideInstructions;
;
function increment(value) {
score += value;
scoreTxt.setText(score.toString());
LK.setScore(score);
}
function gameOver() {
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
}
function hideInstructions() {
moveInstructions.destroy();
jumpInstructions.destroy();
}
});
var ExplosionEffect = Container.expand(function (x, y) {
var self = Container.call(this);
self.x = x;
self.y = y;
;
var durationMax = 10;
var duration = durationMax;
var explosionGraphics = self.createAsset('explosion', 'Explosion graphics', 0.5, 0.5);
;
self.update = update;
;
function update() {
var progress = duration / durationMax;
explosionGraphics.alpha = progress;
explosionGraphics.scale.set(2 - progress);
return !duration--;
}
});
var Box = Container.expand(function (x, y, args) {
var self = Container.call(this);
var {index, column} = args;
var speed = BOX_SPEED;
;
self.x = x;
self.y = y;
self.alive = true;
self.active = false;
self.falling = true;
self.index = index;
self.build = build;
self.update = update;
self.activation = activation;
self.collide = collide;
self.touch = touch;
;
function build(name, xAnchor, yAnchor, variations) {
var nameVariant = !variations || variations <= 1 ? '' : 1 + Math.floor(Math.random() * variations);
var boxGraphics = self.createAsset(name + nameVariant + 'Box', 'Box graphics', xAnchor, yAnchor);
var shadowGraphics = self.createAsset('shadow', 'Shadow image', 0.5, 0.5);
var hitboxGraphics = self.createAsset('hitbox', 'Hitbox graphics', .5, .25);
shadowGraphics.alpha = 0.5;
shadowGraphics.y = -BOX_HEIGHT * 0.5;
hitboxGraphics.width = BOX_WIDTH * 0.9;
hitboxGraphics.height = BOX_HEIGHT * 0.6;
hitboxGraphics.alpha = 0;
self.hitbox = hitboxGraphics;
self.shadow = shadowGraphics;
}
function update(args) {
var destroyNextTick = false;
var upperBox = column.boxes[self.index + 1];
var shadowVisible = upperBox && upperBox.falling;
self.shadow.visible = shadowVisible;
if (shadowVisible) {
var scale = 1 - (self.y - upperBox.y) / STAGE_HEIGHT;
self.shadow.scale.set(scale);
}
if (self.falling) {
var {player} = args;
speed += BOX_GRAVITY;
self.y += speed;
var targetHeight = STAGE_HEIGHT - (self.index + 0.5) * BOX_HEIGHT - FLOOR_OFFSET;
if (self.y >= targetHeight) {
self.falling = false;
self.x = 0;
self.y = targetHeight;
speed = 0;
column.count++;
column.touch(self, self.index - 1);
column.addChild(self);
} else if (player.hitbox.intersects(self.hitbox)) {
destroyNextTick = self.collide(args);
}
}
if (self.active) {
self.activation(args);
}
if (!self.alive) {
column.remove(self);
return true;
}
if (destroyNextTick) {
self.alive = false;
}
}
function activation(args) {}
function collide(args) {
var {player, interface} = args;
if (!player.invulnerability) {
interface.gameOver();
}
return false;
}
function touch(target) {}
;
return self;
});
var BasicBox = Box.expand(function (x, y, args) {
var self = Box.call(this, x, y, args);
;
self.build('basic', .5, .5, 3);
});
var StoneBox = Box.expand(function (x, y, args) {
var self = Box.call(this, x, y, args);
;
self.build('stone', .5, .5);
});
var PointsBox = Box.expand(function (x, y, args) {
var self = Box.call(this, x, y, args);
;
self.build('points', .5, .55, 2);
self.activation = activation;
self.collide = collide;
self.touch = touch;
;
function activation(args) {
var {interface} = args;
interface.increment(POINTS_GAIN_PICKUP);
}
function collide(args) {
self.active = true;
return true;
}
function touch(target) {
if (target instanceof Player) {
self.active = true;
self.alive = false;
} else if (target instanceof StoneBox) {
self.alive = false;
}
}
});
var GoldBox = Box.expand(function (x, y, args) {
var self = Box.call(this, x, y, args);
;
self.build('gold', .5, .5);
self.activation = activation;
self.collide = collide;
self.touch = touch;
;
function activation(args) {
var {player} = args;
player.invulnerability += INVULNERABILITY_TIME;
}
function collide(args) {
self.active = true;
return true;
}
function touch(target) {
if (target instanceof Player) {
self.active = true;
self.alive = false;
} else if (target instanceof StoneBox) {
self.alive = false;
}
}
});
var TntBox = Box.expand(function (x, y, args) {
var self = Box.call(this, x, y, args);
var baseCollide = self.collide;
var {column} = args;
var countdown = 0;
;
self.build('tnt', .5, .55);
self.activation = activation;
self.collide = collide;
self.touch = touch;
;
function activation(args) {
if (countdown <= 0) {
explode(args);
} else if (countdown % 15 === 0) {
LK.effects.flashObject(self, 0xff0000, 500);
}
countdown--;
}
function collide(args) {
baseCollide();
;
if (!self.active) {
self.active = true;
countdown = TNT_COUNTDOWN;
}
return false;
}
function touch(target) {
if (!self.active) {
if (target instanceof Player) {
self.active = true;
countdown = TNT_COUNTDOWN;
} else if (target instanceof StoneBox) {
self.active = true;
}
}
}
function explode(args) {
var {game, columnList, effectList} = args;
effectList.push(game.addChild(new ExplosionEffect(column.x, self.y)));
self.alive = false;
var min = self.y - BOX_HEIGHT * 1.25;
var max = self.y + BOX_HEIGHT * 1.25;
for (var i = column.index - 1; i <= column.index + 1; i++) {
var col = columnList[i];
if (col) {
for (var j = 0; j < col.boxes.length; j++) {
var box = col.boxes[j];
if (box.y < max) {
if (box.y > min) {
if (box !== self) {
if (box instanceof TntBox) {
box.active = true;
} else if (!(box instanceof StoneBox)) {
box.alive = false;
}
}
} else {
break;
}
}
}
}
}
}
});
var Column = Container.expand(function (x, y, index) {
var self = Container.call(this);
var boxes = [];
var countdown = SPAWN_INITIAL + getCountdown();
var shadowGraphics = self.createAsset('shadow', 'Shadow image', 0.5, 0.5);
shadowGraphics.alpha = 0.5;
shadowGraphics.y = STAGE_HEIGHT - FLOOR_OFFSET;
;
self.x = x;
self.y = y;
self.boxes = boxes;
self.index = index;
self.touch = touch;
self.remove = remove;
self.update = update;
self.count = 0;
;
function getCountdown() {
return SPAWN_CONST + Math.floor(Math.random() * (SPAWN_VARIANCE + SPAWN_COUNT_VARIANCE * boxes.length));
}
function touch(target, index) {
var box = self.boxes[index];
if (box) {
box.touch(target);
}
}
function remove(box) {
var index = box.index;
boxes.splice(index, 1);
if (!box.falling) {
self.count--;
}
for (var i = index; i < boxes.length; i++) {
var box = boxes[i];
box.index--;
if (!box.falling) {
self.count--;
box.falling = true;
}
}
}
function update(args) {
var upperBox = boxes[0];
var shadowVisible = upperBox && upperBox.falling;
shadowGraphics.visible = shadowVisible;
if (shadowVisible) {
var scale = 1 - (STAGE_HEIGHT - FLOOR_OFFSET - upperBox.y) / STAGE_HEIGHT;
shadowGraphics.scale.set(scale);
}
if (--countdown <= 0) {
countdown = getCountdown();
if (self.count < COLUMN_VOLUME) {
var {boxList, game} = args;
var typeValue = Math.random();
var typeInstance = BasicBox;
if ((typeValue -= SPAWN_GOLD_CHANCE) < 0) {
typeInstance = GoldBox;
} else if ((typeValue -= SPAWN_TNT_CHANCE) < 0) {
typeInstance = TntBox;
} else if ((typeValue -= SPAWN_POINTS_CHANCE) < 0) {
typeInstance = PointsBox;
} else if ((typeValue -= SPAWN_STONE_CHANCE) < 0) {
typeInstance = StoneBox;
}
var box = game.addChild(new typeInstance(self.x, SPAWN_OFFSET, {
column: self,
index: boxes.length
}));
boxList.push(box);
boxes.push(box);
}
}
}
});
var Player = Container.expand(function (x, y) {
var self = Container.call(this);
self.x = x;
self.y = y;
;
var isJumping = false;
var verticalSpeed = 0;
var floorHeight = y;
var targetColumn = Math.floor(x / BOX_WIDTH);
var playerGraphics = self.createAsset('player', 'Player character', .5, .5);
var hitboxGraphics = self.createAsset('hitbox', 'Player hitbox', .5, .5);
playerGraphics.width = PLAYER_SIZE;
playerGraphics.height = PLAYER_SIZE;
hitboxGraphics.width = PLAYER_SIZE * 0.6;
hitboxGraphics.height = PLAYER_SIZE * 0.8;
hitboxGraphics.alpha = 0;
;
self.heightClimbed = 0;
self.invulnerability = 0;
self.airborne = false;
self.hitbox = hitboxGraphics;
self.move = move;
self.jump = jump;
self.update = update;
;
function getColIndex() {
return Math.floor(self.x / BOX_WIDTH);
}
function getRowIndex() {
return Math.floor((STAGE_HEIGHT - self.y - FLOOR_OFFSET) / BOX_HEIGHT);
}
function move(direction) {
var colIndex = getColIndex();
if (targetColumn === colIndex) {
targetColumn = Math.max(0, Math.min(NUM_COLUMNS - 1, targetColumn + direction));
}
}
function jump() {
if (!self.airborne) {
self.airborne = true;
verticalSpeed = PLAYER_JUMP_SPEED;
}
}
function update(args) {
var {interface, columnList} = args;
var colIndex = getColIndex();
var rowIndex = getRowIndex();
var targetX = (targetColumn + 0.5) * BOX_WIDTH;
var targetY = floorHeight - columnList[colIndex].count * BOX_HEIGHT;
if (self.invulnerability > 0) {
self.invulnerability--;
if (self.invulnerability === 60 || self.invulnerability === 30) {
LK.effects.flashObject(playerGraphics, 0x000000, 1000);
}
playerGraphics.tint = 0xFFD700;
} else {
playerGraphics.tint = 0xFFFFFF;
}
if (self.x !== targetX) {
var moveSpeed = Math.min(Math.abs(targetX - self.x), PLAYER_MOVE_SPEED);
self.x += Math.sign(targetX - self.x) * moveSpeed;
playerGraphics.rotation = Math.PI * (self.x - STAGE_WIDTH / 2) / (BOX_WIDTH * 2);
var newColIndex = getColIndex();
}
if (self.airborne) {
verticalSpeed -= PLAYER_GRAVITY;
self.y -= verticalSpeed;
if (self.y >= targetY) {
self.y = targetY;
self.airborne = false;
verticalSpeed = 0;
}
} else {
if (self.y < targetY) {
self.airborne = true;
} else {
self.y = targetY;
}
}
var newColIndex = getColIndex();
var newRowIndex = getRowIndex();
if (newColIndex !== colIndex) {
var column = columnList[newColIndex];
var box = column.boxes[newRowIndex];
if (box && !box.falling) {
box.touch(self);
self.x = BOX_WIDTH * (0.5 + (newColIndex * 9 + colIndex * 10) / 19);
playerGraphics.rotation = Math.PI * (self.x - STAGE_WIDTH / 2) / (BOX_WIDTH * 2);
targetColumn = colIndex;
newColIndex = colIndex;
}
}
if (!self.airborne) {
columnList[newColIndex].touch(self, rowIndex - 1);
if (rowIndex > self.heightClimbed) {
interface.increment((newRowIndex - self.heightClimbed) * POINTS_GAIN_CLIMBING);
self.heightClimbed = rowIndex;
}
}
}
});
;
var STAGE_WIDTH = 2048;
var STAGE_HEIGHT = 2732;
var STAGE_TICKS = 60;
var CONTROL_SWIPE_DIST = 100;
var CONTROL_TAP_TICKS = STAGE_TICKS / 3;
var NUM_COLUMNS = 9;
var BOX_WIDTH = STAGE_WIDTH / NUM_COLUMNS;
var BOX_HEIGHT = 0.75 * BOX_WIDTH;
var PLAYER_SIZE = 0.8 * BOX_WIDTH;
var PLAYER_GRAVITY = 0.5;
var PLAYER_JUMP_SPEED = 20;
var PLAYER_MOVE_SPEED = 25;
var SPAWN_OFFSET = -100;
var SPAWN_INITIAL = 3 * STAGE_TICKS;
var SPAWN_CONST = STAGE_TICKS / 2;
var SPAWN_VARIANCE = 10 * STAGE_TICKS - SPAWN_CONST;
var SPAWN_COUNT_VARIANCE = STAGE_TICKS / 4;
var SPAWN_TNT_CHANCE = 0.03;
var SPAWN_GOLD_CHANCE = 0.01;
var SPAWN_POINTS_CHANCE = 0.05;
var SPAWN_STONE_CHANCE = 0.1;
var POINTS_GAIN_CLIMBING = 1;
var POINTS_GAIN_PICKUP = 5;
var INVULNERABILITY_TIME = 5 * STAGE_TICKS;
var INSTRUCTION_DURATION = 5 * STAGE_TICKS;
var BOX_SPEED = 5;
var BOX_GRAVITY = 0.2;
var TNT_COUNTDOWN = 2 * STAGE_TICKS;
var FLOOR_OFFSET = 100;
var COLUMN_VOLUME = Math.floor((STAGE_HEIGHT - FLOOR_OFFSET) / BOX_HEIGHT) + 1;
;
var Game = Container.expand(function () {
var self = Container.call(this);
;
var lastTouchX = null;
var lastTouchY = null;
var touchTime = null;
var boxList = [];
var effectList = [];
var columnList = [];
;
var background = self.addChild(new Background(self));
var floor = self.addChild(new Floor(STAGE_WIDTH / 2, STAGE_HEIGHT));
for (var i = 0; i < NUM_COLUMNS; i++) {
columnList.push(self.addChild(new Column((i + 0.5) * BOX_WIDTH, 0, i)));
}
var player = self.addChild(new Player(STAGE_WIDTH / 2, STAGE_HEIGHT - FLOOR_OFFSET - PLAYER_SIZE / 2));
var interface = LK.gui.topCenter.addChild(new Interface());
;
stage.on('down', function (obj) {
var event = obj.event;
lastTouchX = event.global.x;
lastTouchY = event.global.y;
touchTime = LK.ticks;
});
stage.on('up', function (obj) {
if (touchTime !== null && LK.ticks - touchTime < CONTROL_TAP_TICKS) {
player.jump();
}
lastTouchX = null;
lastTouchY = null;
touchTime = null;
});
stage.on('move', function (obj) {
if (touchTime !== null) {
var reset = false;
var event = obj.event;
var deltaX = lastTouchX - event.global.x;
var deltaY = lastTouchY - event.global.y;
if (Math.abs(deltaX) > CONTROL_SWIPE_DIST) {
var direction = deltaX > 0 ? -1 : 1;
player.move(direction);
reset = true;
} else if (deltaY > CONTROL_SWIPE_DIST) {
player.jump();
reset = true;
}
if (reset) {
touchTime = null;
lastTouchX = null;
lastTouchY = null;
}
}
});
LK.on('tick', function () {
var playerArgs = {
interface,
columnList
};
player.update(playerArgs);
;
var columnArgs = {
game: self,
boxList
};
for (var i = 0; i < columnList.length; i++) {
columnList[i].update(columnArgs);
}
;
var boxArgs = {
game: self,
columnList,
effectList,
interface,
player
};
for (var i = 0; i < boxList.length; i++) {
var box = boxList[i];
if (box.update(boxArgs)) {
box.destroy();
boxList.splice(i, 1);
i--;
}
}
;
for (var i = 0; i < effectList.length; i++) {
var effect = effectList[i];
if (effect.update()) {
effect.destroy();
effectList.splice(i, 1);
i--;
}
}
;
if (LK.ticks === INSTRUCTION_DURATION) {
interface.hideInstructions();
}
});
});
Pixel art, side view of a concrete factory floor . Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Pixel art, square with cute eyes . Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Pixel art, square with the texture of a tnt . Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
pixel art of a crate, side view . Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
pixel art of a crate, flat side view . Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
pixel art of a crate, flat side view . Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Pixel art of a golden christmas present. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Pixel art of a green christmas present with red ribbons. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Pixel art of an elaborate green christmas present with red ribbons. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
pixel art of a metal background.
pixel art of a crate made of stone with a label of coal on the side, flat side view. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
pixel art of a square tnt explosion. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.