Code edit (1 edits merged)
Please save this source code
Code edit (1 edits merged)
Please save this source code
User prompt
Fix Bug: 'ReferenceError: enter is not defined' in this line: 'self.enter = enter;' Line Number: 434
Code edit (5 edits merged)
Please save this source code
User prompt
Fix Bug: 'ReferenceError: columnIndex is not defined' in this line: 'if (!player.invulnerability && player.y > min && player.y < max && playerColumn >= column.index - 1 && playerColumn <= columnIndex + 1) {' Line Number: 387
Code edit (9 edits merged)
Please save this source code
User prompt
Fix Bug: 'TypeError: newColumn is undefined' in this line: 'var sideBox = newColumn.boxes[rowIndex];' Line Number: 580
Code edit (1 edits merged)
Please save this source code
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
	};
	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.x = settings.x;
	self.y = settings.y;
	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 Interface = Container.expand(function () {
	var self = Container.call(this);
	var score = 0;
	var shown = true;
	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.isPaused = false;
	self.isGameOver = false;
	self.deathReason = '';
	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);
		var deathReasonTxt = self.addChild(new BorderedText(self.deathReason, {
			y: scoreTxt.y + scoreTxt.height + 20,
			anchor: {
				x: .5
			}
		}));
		hideInstructions();
		LK.showGameOver();
	}
	function hideInstructions() {
		if (shown) {
			shown = false;
			moveInstructions.destroy();
			jumpInstructions.destroy();
		}
	}
});
var ShiftableContainer = Container.expand(function () {
	var self = Container.call(this);
	;
	self.shift = shift;
	;
	function shift(amount) {
		self.y += amount;
	}
	;
	return self;
});
var Background = ShiftableContainer.expand(function () {
	var self = ShiftableContainer.call(this);
	var baseShift = self.shift;
	var backgroundBotLGraphics = self.createAsset('backgroundLeft', 'Background bottom left image', 0, 0);
	var backgroundBotRGraphics = self.createAsset('backgroundRight', 'Background bottom right image', 1, 0);
	var backgroundTopLGraphics = self.createAsset('backgroundLeft', 'Background top left image', 0, 0);
	var backgroundTopRGraphics = self.createAsset('backgroundRight', 'Background top right image', 1, 0);
	backgroundBotLGraphics.width = STAGE_WIDTH / 2;
	backgroundBotRGraphics.width = STAGE_WIDTH / 2;
	backgroundBotLGraphics.height = STAGE_HEIGHT;
	backgroundBotRGraphics.height = STAGE_HEIGHT;
	backgroundBotRGraphics.x = STAGE_WIDTH;
	backgroundTopLGraphics.width = STAGE_WIDTH / 2;
	backgroundTopRGraphics.width = STAGE_WIDTH / 2;
	backgroundTopLGraphics.height = STAGE_HEIGHT;
	backgroundTopRGraphics.height = STAGE_HEIGHT;
	backgroundTopRGraphics.x = STAGE_WIDTH;
	backgroundTopLGraphics.scale.y = -1;
	backgroundTopRGraphics.scale.y = -1;
	;
	self.shift = shift;
	;
	function shift(amount) {
		baseShift(amount);
		;
		if (self.y > STAGE_HEIGHT) {
			self.y -= STAGE_HEIGHT;
		}
		return false;
	}
});
var Floor = ShiftableContainer.expand(function (x, y) {
	var self = ShiftableContainer.call(this);
	var shiftCount = 0;
	var floorGraphics = self.createAsset('floor', 'Floor image', 0.5, 0.5);
	;
	self.x = x;
	self.y = y;
	self.shift = shift;
	;
	function shift(amount) {
		shiftCount += amount;
		floorGraphics.y += amount;
		return shiftCount > floorGraphics.height / 2;
	}
});
var ExplosionEffect = ShiftableContainer.expand(function (x, y) {
	var self = ShiftableContainer.call(this);
	var alphaMax = 0.8;
	var durationMax = 10;
	var duration = durationMax;
	var explosionGraphics = self.createAsset('explosion', 'Explosion graphics', 0.5, 0.5);
	;
	self.x = x;
	self.y = y;
	self.update = update;
	;
	function update() {
		var progress = duration / durationMax;
		explosionGraphics.alpha = alphaMax * progress;
		explosionGraphics.scale.set(2 - progress);
		return !duration--;
	}
});
var Box = ShiftableContainer.expand(function (x, y, args) {
	var self = ShiftableContainer.call(this);
	var baseShift = self.shift;
	var {index, column} = args;
	var speed = BOX_SPEED;
	;
	self.x = x;
	self.y = y;
	self.alive = true;
	self.active = false;
	self.falling = true;
	self.gravity = BOX_GRAVITY;
	self.index = index;
	self.build = build;
	self.update = update;
	self.activation = activation;
	self.collide = collide;
	self.touch = touch;
	self.shift = shift;
	self.deathReason = DEATH_CRUSH_BOX;
	;
	function build(name, xAnchor, yAnchor, variations) {
		var boxGraphics;
		if (name) {
			var nameVariant = !variations || variations <= 1 ? '' : 1 + Math.floor(Math.random() * variations);
			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.graphic = boxGraphics;
		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 scaleFraction = 1 - (self.y - upperBox.y) / STAGE_HEIGHT;
			var scale = SHADOW_MIN_SCALE + (1 - SHADOW_MIN_SCALE) * scaleFraction;
			self.shadow.scale.set(scale);
		}
		if (self.alive && self.falling) {
			var {player} = args;
			speed += self.gravity;
			self.y += speed;
			var targetHeight = BOX_LINE - self.index * BOX_HEIGHT;
			if (self.y >= targetHeight) {
				speed = 0;
				self.x = 0;
				self.y = targetHeight;
				self.falling = false;
				column.count++;
				column.touch(self, self.index - 1);
			} else if (player.hitbox.intersects(self.hitbox)) {
				destroyNextTick = self.collide(args);
			}
		}
		if (!destroyNextTick && 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.isGameOver = true;
			interface.deathReason = self.deathReason;
		}
		return false;
	}
	function touch(target) {}
	function shift(amount) {
		baseShift(amount);
		;
		if (self.y > BOX_LINE) {
			column.remove(self);
			return true;
		}
		return false;
	}
	;
	return self;
});
var InvisBox = Box.expand(function (x, y, args) {
	var self = Box.call(this, x, y, args);
	;
	self.build();
});
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);
	self.deathReason = DEATH_CRUSH_STONE;
});
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;
	self.deathReason = DEATH_CRUSH_TNT;
	;
	function activation(args) {
		if (countdown <= 0) {
			explode(args);
		} else if (countdown % (countdown >= STAGE_TICKS ? 30 : 15) === 0) {
			LK.effects.flashObject(self.graphic, 0xff0000, 500);
		}
		countdown--;
	}
	function collide(args) {
		baseCollide(args);
		;
		if (!self.active) {
			self.active = true;
			countdown = TNT_COUNTDOWN;
		}
		return false;
	}
	function touch(target) {
		if (target instanceof Player) {
			if (!self.active) {
				self.active = true;
				self.deathReason = DEATH_TNT_BASIC;
				countdown = TNT_COUNTDOWN;
			}
		} else if (target instanceof StoneBox) {
			self.active = true;
			self.deathReason = DEATH_TNT_INSTA;
			countdown = 0;
		}
	}
	function explode(args) {
		var {game, player, interface, 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;
		if (!player.invulnerability && player.y > min && player.y < max && player.x > column.x - BOX_WIDTH * 1.5 && player.x < column.x + BOX_WIDTH * 1.5) {
			interface.isGameOver = true;
			interface.deathReason = self.deathReason;
		}
		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;
									box.deathReason = DEATH_TNT_CHAIN;
								} else if (!(box instanceof StoneBox || box instanceof InvisBox)) {
									box.alive = false;
								}
							}
						} else {
							break;
						}
					}
				}
			}
		}
	}
});
var Column = Container.expand(function (x, y, args) {
	var self = Container.call(this);
	var {index, boxList} = args;
	var boxes = [];
	var countdown = SPAWN_INITIAL + getCountdown();
	var defaultBox = self.addChild(new InvisBox(0, BOX_LINE, {
		column: self,
		index: 0
	}));
	boxList.push(defaultBox);
	boxes.push(defaultBox);
	;
	self.x = x;
	self.y = y;
	self.boxes = boxes;
	self.index = index;
	self.touch = touch;
	self.remove = remove;
	self.update = update;
	self.enter = enter;
	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;
				box.gravity = PLAYER_GRAVITY;
			}
		}
	}
	function update(args) {
		if (--countdown <= 0) {
			countdown = getCountdown();
			if (self.count < COLUMN_VOLUME) {
				var {boxList} = 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 = self.addChild(new typeInstance(0, SPAWN_OFFSET, {
					column: self,
					index: boxes.length
				}));
				boxList.push(box);
				boxes.push(box);
			}
		}
	}
	function enter(player) {
		self.addChild(player);
		self.children.sort(function (a, b) {
			return b.y - a.y;
		});
	}
});
var Player = ShiftableContainer.expand(function (x, y) {
	var self = ShiftableContainer.call(this);
	var baseShift = self.shift;
	var isJumping = false;
	var verticalSpeed = 0;
	var targetDirection = 0;
	var targetX = 0;
	var playerGraphics = self.createAsset('player', 'Player character', .5, .5);
	var hitboxGraphics = self.createAsset('hitbox', 'Player hitbox', .5, .5);
	var invR = 0xFF;
	var invG = 0xD7;
	var invB = 0x00;
	playerGraphics.width = PLAYER_SIZE;
	playerGraphics.height = PLAYER_SIZE;
	hitboxGraphics.width = PLAYER_SIZE * 0.6;
	hitboxGraphics.height = PLAYER_SIZE * 0.8;
	hitboxGraphics.alpha = 0;
	;
	self.x = x;
	self.y = y;
	self.heightClimbed = BOX_HEIGHT;
	self.invulnerability = 0;
	self.airborne = false;
	self.hitbox = hitboxGraphics;
	self.move = move;
	self.jump = jump;
	self.update = update;
	self.shift = shift;
	;
	function getRowIndex() {
		return Math.floor((BOX_LINE - self.y) / BOX_HEIGHT + 0.5);
	}
	function move(direction) {
		if (!targetDirection) {
			targetDirection = direction;
			targetX += direction * BOX_WIDTH;
		}
	}
	function jump() {
		if (!self.airborne) {
			self.airborne = true;
			verticalSpeed = PLAYER_JUMP_SPEED;
		}
	}
	function update(args) {
		var {interface, columnList} = args;
		var column = self.parent;
		var targetY = BOX_LINE - column.count * BOX_HEIGHT;
		if (self.invulnerability > 0) {
			self.invulnerability--;
			var factor = 1 - Math.min(self.invulnerability, INVULNERABILITY_WARNING) / INVULNERABILITY_WARNING;
			var newR = (invR + Math.floor((0xFF - invR) * factor)) * Math.pow(16, 4);
			var newG = (invG + Math.floor((0xFF - invG) * factor)) * Math.pow(16, 2);
			var newB = (invB + Math.floor((0xFF - invB) * factor)) * Math.pow(16, 0);
			playerGraphics.tint = newR + newG + newB;
		}
		if (targetDirection) {
			var moveSpeed = Math.min((targetX - self.x) * targetDirection, PLAYER_MOVE_SPEED);
			self.x += moveSpeed * targetDirection;
			playerGraphics.rotation = Math.PI * (column.index + self.x / BOX_WIDTH);
			if (moveSpeed < PLAYER_MOVE_SPEED) {
				targetDirection = 0;
			}
		}
		if (self.airborne) {
			verticalSpeed -= PLAYER_GRAVITY;
			self.y -= verticalSpeed;
			if (self.y >= targetY) {
				self.y = targetY;
				self.airborne = false;
				verticalSpeed = 0;
				if (self.y >= BOX_LINE) {
					interface.isGameOver = true;
					interface.deathReason = DEATH_FALLDOWN;
				}
			}
		} else {
			if (self.y < targetY) {
				self.airborne = true;
			} else {
				self.y = targetY;
			}
		}
		var rowIndex = getRowIndex();
		var overhang = Math.max(0, Math.abs(self.x) - BOX_WIDTH / 2);
		if (overhang > 0) {
			var newColumn = columnList[column.index + targetDirection];
			var sideBox = newColumn ? newColumn.boxes[rowIndex] : null;
			var moveDist = BOX_WIDTH * targetDirection;
			if (sideBox && !sideBox.falling) {
				sideBox.touch(self);
				self.x -= overhang * 2 * targetDirection;
				targetX += moveDist;
				targetDirection = -targetDirection;
				playerGraphics.rotation = Math.PI * (column.index + self.x / BOX_WIDTH);
			} else {
				column = newColumn;
				column.enter(self);
				targetX -= moveDist;
				self.x -= moveDist;
				var underBox = column.boxes[rowIndex - 1];
				if (!underBox || underBox.falling) {
					self.airborne = true;
				}
			}
		}
		;
		;
		;
	}
	function shift(amount) {
		baseShift(amount);
		;
		self.heightClimbed -= amount;
	}
});
;
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_LINE = STAGE_HEIGHT;
var BOX_WIDTH = STAGE_WIDTH / NUM_COLUMNS;
var BOX_HEIGHT = 0.75 * BOX_WIDTH;
var BOX_SPEED = 5;
var BOX_GRAVITY = 0.2;
var TNT_COUNTDOWN = 2 * STAGE_TICKS;
var INVULNERABILITY_TIME = 5 * STAGE_TICKS;
var INVULNERABILITY_WARNING = STAGE_TICKS;
var COLUMN_VOLUME = Math.ceil(BOX_LINE / BOX_HEIGHT);
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 SHADOW_MIN_SCALE = 0.4;
var SPAWN_TNT_CHANCE = 0.05;
var SPAWN_GOLD_CHANCE = 0.02;
var SPAWN_POINTS_CHANCE = 0.08;
var SPAWN_STONE_CHANCE = 0.1;
var POINTS_GAIN_CLIMBING = 1;
var POINTS_GAIN_PICKUP = 5;
var SHIFT_THRESHOLD = 6;
var SHIFT_COUNT = 3;
var SHIFT_DURATION = STAGE_TICKS / 3;
var SHIFT_AMOUNT = SHIFT_COUNT * BOX_HEIGHT / SHIFT_DURATION;
var INSTRUCTION_DURATION = 5 * STAGE_TICKS;
var DEATH_FALLDOWN = 'Fell into the factory!';
var DEATH_CRUSH_BOX = 'Crushed by a packing crate!';
var DEATH_CRUSH_TNT = 'Crushed by a freshly armed TNT!';
var DEATH_CRUSH_STONE = 'Crushed by the naughty list!';
var DEATH_TNT_BASIC = 'Blew up after arming a TNT!';
var DEATH_TNT_INSTA = 'Coal detonated a TNT... And you!';
var DEATH_TNT_CHAIN = 'Blew up in a chain reaction!';
;
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 shiftTicks = 0;
	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, {
			index: i,
			boxList
		})));
	}
	var midColumn = columnList[Math.floor(NUM_COLUMNS / 2)];
	var player = midColumn.addChild(new Player(0, BOX_LINE - PLAYER_SIZE / 2));
	var interface = LK.gui.topCenter.addChild(new Interface());
	var shiftContainers = [[player, background, floor], boxList, effectList];
	;
	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 () {
		if (interface.isGameOver) {
			interface.gameOver();
		} else if (interface.isPaused = shiftTicks > 0) {
			shiftTicks--;
			shiftContainers.forEach(function (containers) {
				for (var i = containers.length - 1; i >= 0; i--) {
					var container = containers[i];
					if (container.shift(SHIFT_AMOUNT)) {
						container.destroy();
						containers.splice(i, 1);
					}
				}
			});
		} else {
			var playerArgs = {
				interface,
				columnList
			};
			if (player.update(playerArgs)) {
				shiftTicks += SHIFT_DURATION;
			}
			;
			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();
		}
	});
});
 ===================================================================
--- original.js
+++ change.js
@@ -485,9 +485,9 @@
 	}
 	function enter(player) {
 		self.addChild(player);
 		self.children.sort(function (a, b) {
-			return a.y - b.y;
+			return b.y - a.y;
 		});
 	}
 });
 var Player = ShiftableContainer.expand(function (x, y) {
:quality(85)/https://cdn.frvr.ai/657f407e193547097ce2b752.png%3F3) 
 Pixel art, side view of a concrete factory floor . Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
:quality(85)/https://cdn.frvr.ai/657f42e3193547097ce2b77c.png%3F3) 
 Pixel art, square with cute eyes . Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
:quality(85)/https://cdn.frvr.ai/657f47e7193547097ce2b79f.png%3F3) 
 Pixel art, square with the texture of a tnt . Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
:quality(85)/https://cdn.frvr.ai/658aeb22f093e2712f8c3e00.png%3F3) 
 pixel art of a crate, side view . Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
:quality(85)/https://cdn.frvr.ai/658aeb93f093e2712f8c3e10.png%3F3) 
 pixel art of a crate, flat side view . Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
:quality(85)/https://cdn.frvr.ai/658af121f093e2712f8c3e42.png%3F3) 
 pixel art of a crate, flat side view . Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
:quality(85)/https://cdn.frvr.ai/658afd2ef093e2712f8c3ece.png%3F3) 
 Pixel art of a golden christmas present. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
:quality(85)/https://cdn.frvr.ai/658afebbf093e2712f8c3ef0.png%3F3) 
 Pixel art of a green christmas present with red ribbons. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
:quality(85)/https://cdn.frvr.ai/658b0051f093e2712f8c3f0f.png%3F3) 
 Pixel art of an elaborate green christmas present with red ribbons. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
:quality(85)/https://cdn.frvr.ai/658c17488af59fdd6a28a354.png%3F3) 
 pixel art of a metal background.
:quality(85)/https://cdn.frvr.ai/658c1e768af59fdd6a28a38f.png%3F3) 
 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.
:quality(85)/https://cdn.frvr.ai/658d76019cf53b39605f6ddb.png%3F3) 
 pixel art of a square tnt explosion. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
:quality(85)/https://cdn.frvr.ai/65915ee08a1dde74f17e80e8.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/65915ef88a1dde74f17e80ec.png%3F3)