Code edit (1 edits merged)
Please save this source code
User prompt
In the border class, before creating the border assets, create a borderGear at the LIGHT_LEVEL y position and radius of 20
Code edit (1 edits merged)
Please save this source code
User prompt
create a BorderGear class that inherits from the configContainer class and takes in a radius number. The class contains a borderGear asset with a width and height of 2 * config.radius and rotates at rowSpeed relative to its radius
User prompt
undo the last change; instead of checking if the self.parent exists, move the self.callDestroy to the bottom of the logic
User prompt
Please fix the bug: 'TypeError: self.parent is undefined' in or related to this line: 'var newBlock = self.parent.addChild(new newBlockClass({' Line Number: 607
User prompt
when creating the newBlock, replace the up,right,down,left block references to the new block
Code edit (9 edits merged)
Please save this source code
User prompt
when the blockblank destroys itself, create a new block in its place using the randomizeBlockClass function
Code edit (2 edits merged)
Please save this source code
User prompt
create 2 border instances before the lava instance. These should be placed on either side of the bottom of the screen
User prompt
create a Border class that inherits from the ConfigContainer class, comprised randomly of border1 and border2 assets making up the full game height
Code edit (1 edits merged)
Please save this source code
User prompt
if the crackLevel is 1, then give the crackAsset a random rotation
User prompt
in the blockBlank class, before returning self, there's a BLOCK_CRACK_CHANCE chance of calling self.rotate
Code edit (1 edits merged)
Please save this source code
Code edit (4 edits merged)
Please save this source code
User prompt
when incrementing the crackLevel in the BlockBlank class, destroy the old crackAsset if it exists, and attach a new crack asset with the number of crackLevel
Code edit (5 edits merged)
Please save this source code
User prompt
add a click animation to clicking blocks that smoothly decreases the block size by 10% then grows it back to the original all over BLOCK_ROTATE_SPEED time
User prompt
and when updating the score
User prompt
Remove the "Score: " prefix to the score text
User prompt
add a score variable, and increment it when creating a ScoreText instance, which updates the text in the scoreText element
User prompt
add a score text2 to the top center of the screen
Code edit (2 edits merged)
Please save this source code
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var BlockManager = Container.expand(function () {
var self = Container.call(this);
var blockRows = [];
var index = 0;
for (var i = 0; i < ROW_COUNT; i++) {
addRow({
x: game.width / 2,
y: LAVA_LINE - i * (BLOCK_SIZE * BLOCK_SCALE + BLOCK_MARGIN),
index: index++
});
}
blockRows[0].blocks[Math.floor(ROW_SPAN / 2)].onLit(true);
self.update = function () {
if (blockRows[0].y > game.height) {
popRow();
}
};
function addRow(settings) {
var prevRow = blockRows[blockRows.length - 1];
var newRow = self.addChild(new BlockRow(settings));
blockRows.push(newRow);
if (prevRow) {
newRow.setDown(prevRow);
prevRow.setUp(newRow);
}
}
function popRow() {
blockRows.shift().callDestroy();
blockRows[0].blocks.forEach(function (block) {
if (block) {
block.downBlock = undefined;
}
});
addRow({
x: game.width / 2,
y: blockRows[blockRows.length - 1].y - BLOCK_SIZE * BLOCK_SCALE - BLOCK_MARGIN,
index: index++,
disabled: true
});
adjustRowSpeed();
}
return self;
});
var ConfigContainer = Container.expand(function (config) {
var self = Container.call(this);
config = config || {};
self.destroyed = false;
self.tags = {};
self.x = config.x || 0;
self.y = config.y || 0;
self.rotation = config.rotation || 0;
self.alpha = config.alpha !== undefined ? config.alpha : 1.0;
if (config.scale !== undefined || config.scaleX !== undefined || config.scaleY !== undefined) {
var scaleX = config.scaleX !== undefined ? config.scaleX : config.scale !== undefined ? config.scale : 1;
var scaleY = config.scaleY !== undefined ? config.scaleY : config.scale !== undefined ? config.scale : 1;
self.scale.set(scaleX, scaleY);
}
self.callDestroy = function () {
if (!self.destroyed) {
self.destroyed = true;
self.onDestroy();
self.destroy();
}
};
self.onDestroy = function () {};
return self;
});
var ScoreText = ConfigContainer.expand(function (config) {
var self = ConfigContainer.call(this, config);
var text = self.addChild(new Text2("+1", {
fill: 0xFFFFFF,
stroke: 0x000000,
strokeThickness: 30,
size: 120
}));
text.anchor = {
x: 0.5,
y: 0.5
}; // NOTE: Cannot be set in config
tween(self, {
y: self.y - 50
}, {
duration: 2000
});
LK.setTimeout(function () {
tween(self, {
alpha: 0
}, {
duration: 1000,
onFinish: function onFinish() {
self.callDestroy();
}
});
}, 1000);
return self;
});
var Light = ConfigContainer.expand(function (config) {
var self = ConfigContainer.call(this, config);
var lightShape = self.attachAsset('shapeEllipse', {
y: -LIGHT_OFFSET,
width: BLOCK_SIZE - 2 * LIGHT_OFFSET,
height: BLOCK_SIZE - 2 * LIGHT_OFFSET,
anchorX: 0.5,
anchorY: 1,
scaleX: 0,
scaleY: 0
});
tween(lightShape, {
scaleX: 1,
scaleY: 1
}, {
duration: LIGHT_GROW_SPEED,
onFinish: function onFinish() {
if (self.parent) {
config.callback();
}
}
});
return self;
});
var LavaSlice = ConfigContainer.expand(function (config) {
var self = ConfigContainer.call(this, config);
self.attachAsset('lava' + config.index, {
anchorX: 0.5,
anchorY: 0,
width: LAVA_SLICE_WIDTH,
tint: 0xFFA500
});
self.attachAsset('shapeBox', {
width: LAVA_SLICE_WIDTH,
height: 10,
anchorX: 0.5,
anchorY: 0,
tint: 0xFF4D00
});
self.addChild(new Glow({
anchorX: 0.5,
anchorY: 0.75,
height: 20,
rangeY: 150,
width: 3 * LAVA_SLICE_WIDTH,
alpha: 0.35,
tint: 0xFF4D00
}));
self.update = function () {
self.y = Math.sin(LK.ticks * LAVA_BOB_PERIOD + config.index * LAVA_BOB_OFFSET) * LAVA_BOB_HEIGHT;
};
return self;
});
var Lava = ConfigContainer.expand(function (config) {
var self = ConfigContainer.call(this, config);
var position = Math.round((-0.5 - LAVA_SLICE_COUNT / 2) * LAVA_SLICE_WIDTH);
for (var i = 1; i <= LAVA_SLICE_COUNT; i++) {
var lavaSlice = self.addChild(new LavaSlice({
x: position += LAVA_SLICE_WIDTH,
index: i
}));
}
return self;
});
var Glow = ConfigContainer.expand(function (config) {
var self = ConfigContainer.call(this, config);
var layers = Math.max(2, config.layers || 10);
var layerAlpha = 1 / layers;
var widthStep = (config.rangeX || 0) * layerAlpha;
var heightStep = (config.rangeY || 0) * layerAlpha;
for (var i = 0; i < layers; i++) {
self.attachAsset(config.asset || 'shapeBox', {
width: config.width + widthStep * i,
height: config.height + heightStep * i,
anchorX: config.anchorX,
anchorY: config.anchorY,
tint: config.tint,
alpha: i === 0 && config.solid ? 1 : layerAlpha
});
}
return self;
});
var BlockRow = ConfigContainer.expand(function (config) {
var self = ConfigContainer.call(this, config);
var blockClasses = generateBlockClasses(config.index);
self.disabled = !!config.disabled;
self.blocks = [];
for (var i = 0; i < ROW_SPAN; i++) {
var blockClass = blockClasses[i];
self.blocks[i] = self.addChild(new blockClass({
x: (0.5 + i - ROW_SPAN / 2) * (BLOCK_SIZE * BLOCK_SCALE + BLOCK_MARGIN),
scale: BLOCK_SCALE,
disabled: self.disabled
}));
}
for (var i = 0; i < ROW_SPAN; i++) {
var block = self.blocks[i];
if (i > 0) {
block.leftBlock = self.blocks[i - 1];
}
if (i < ROW_SPAN - 1) {
block.rightBlock = self.blocks[i + 1];
}
}
self.update = function () {
self.y += rowSpeed;
if (self.disabled && self.y > BLOCK_SIZE) {
self.disabled = false;
self.blocks.forEach(function (block) {
block.disabled = false;
});
self.blocks.forEach(function (block) {
if (!block.isRotating) {
block.onSettle();
}
});
}
};
self.setUp = function (upRow) {
for (var i = 0; i < ROW_SPAN; i++) {
var selfBlock = self.blocks[i];
var upBlock = upRow.blocks[i];
upBlock.downBlock = selfBlock;
selfBlock.upBlock = upBlock;
}
};
self.setDown = function (downRow) {
for (var i = 0; i < ROW_SPAN; i++) {
var selfBlock = self.blocks[i];
var downBlock = downRow.blocks[i];
downBlock.upBlock = selfBlock;
selfBlock.downBlock = downBlock;
}
};
self.onDestroy = function () {
self.blocks.forEach(function (block) {
block.callDestroy();
});
};
return self;
});
var Block = ConfigContainer.expand(function (config) {
var self = ConfigContainer.call(this, config);
self.isRotating = false;
self.disabled = config.disabled;
self.orientation = config.orientation !== undefined ? config.orientation : Math.floor(4 * Math.random());
self.upPath = false;
self.rightPath = false;
self.downPath = false;
self.leftPath = false;
self.upBlock;
self.rightBlock;
self.downBlock;
self.leftBlock;
self.attachAsset('shapeBox', {
width: BLOCK_SIZE,
height: BLOCK_SIZE,
anchorX: 0.5,
anchorY: 0.5,
alpha: 0
});
self.lightContainer = lightManager.addChild(new ConfigContainer({
scale: BLOCK_SCALE
}));
self.blockContainer = self.addChild(new ConfigContainer({
rotation: self.orientation * Math.PI / 2
}));
self.rotate = function () {
if (!self.lit && !self.isRotating) {
self.isRotating = true;
self.lightContainer.removeChildren();
tween(self.blockContainer, {
rotation: self.blockContainer.rotation + Math.PI / 2
}, {
duration: BLOCK_ROTATE_SPEED,
onFinish: function onFinish() {
if (!self.destroyed) {
self.isRotating = false;
self.orientation = (self.orientation + 1) % 4;
self.onSettle();
}
}
});
}
};
self.update = function () {
if (self.parent && !self.destroyed) {
self.lightContainer.x = self.x + self.parent.x;
self.lightContainer.y = self.y + self.parent.y;
}
};
self.down = function () {
self.rotate();
};
self.onLit = function (pointless) {
if (!self.lit && !self.destroyed && (self.upPath || self.downPath || self.leftPath || self.rightPath)) {
self.lit = true;
self.lightContainer.removeChildren();
self.lightContainer.attachAsset('shapeEllipse', {
width: BLOCK_SIZE - 2 * LIGHT_OFFSET,
height: BLOCK_SIZE - 2 * LIGHT_OFFSET,
anchorX: 0.5,
anchorY: 0.5
});
if (self.upPath && (!self.upBlock || !self.upBlock.lit || !self.upBlock.downPath)) {
makeGlow(0, -BLOCK_SIZE / 2 - BLOCK_MARGIN / 4);
}
if (self.rightPath && (!self.rightBlock || !self.rightBlock.lit || !self.rightBlock.leftPath)) {
makeGlow(BLOCK_SIZE / 2 + BLOCK_MARGIN / 4, 0);
}
if (self.downPath && (!self.downBlock || !self.downBlock.lit || !self.downBlock.upPath)) {
makeGlow(0, BLOCK_SIZE / 2 + BLOCK_MARGIN / 4);
}
if (self.leftPath && (!self.leftBlock || !self.leftBlock.lit || !self.leftBlock.rightPath)) {
makeGlow(-BLOCK_SIZE / 2 - BLOCK_MARGIN / 4, 0);
}
if (!pointless) {
var scoreText = game.addChild(new ScoreText({
x: self.x + self.parent.x,
y: self.y + self.parent.y
}));
}
self.onSettle();
}
};
self.onSettle = function () {
self.updatePaths();
if (!self.disabled) {
var litRotationFactor = self.lit ? 0 : 1;
var litPositionFactor = self.lit ? 1 : -1;
[{
direction: 'up',
rotation: 0,
y: 1
}, {
direction: 'right',
rotation: 0.5,
x: -1
}, {
direction: 'down',
rotation: 1,
y: -1
}, {
direction: 'left',
rotation: 1.5,
x: 1
}].forEach(function (item) {
if (self[item.direction + 'Path']) {
var block = self[item.direction + 'Block'];
if (block && !block.disabled && block.lit !== self.lit && block[COMPLIMENTS[item.direction] + 'Path']) {
(self.lit ? block : self).lightContainer.addChild(new Light({
x: (item.x || 0) * litPositionFactor * BLOCK_HALFSIZE,
y: (item.y || 0) * litPositionFactor * BLOCK_HALFSIZE,
rotation: Math.PI * (item.rotation + litRotationFactor),
callback: self.lit ? block.onLit : self.onLit
}));
}
}
});
}
};
self.updatePaths = function () {};
function makeGlow(x, y) {
var glow = self.lightContainer.addChild(new Glow({
x: x,
y: y,
width: LIGHT_SPILL_SIZE,
height: LIGHT_SPILL_SIZE,
anchorX: 0.5,
anchorY: 0.5,
rangeX: 20,
rangeY: 20,
layers: 4,
solid: true,
tint: 0xFFFFFF,
alpha: 0
}));
tween(glow, {
alpha: 1
}, {
duration: 250
});
}
self.onDestroy = function () {
if (self.lightContainer) {
self.lightContainer.destroy();
}
};
return self;
});
var BlockX = Block.expand(function (config) {
var self = Block.call(this, config);
self.upPath = true;
self.rightPath = true;
self.downPath = true;
self.leftPath = true;
self.blockContainer.attachAsset('blockX1', {
x: -BLOCK_HALFSIZE,
y: -BLOCK_HALFSIZE,
anchorX: 0,
anchorY: 0
});
self.blockContainer.attachAsset('blockX2', {
x: BLOCK_HALFSIZE,
y: -BLOCK_HALFSIZE,
anchorX: 1,
anchorY: 0
});
self.blockContainer.attachAsset('blockX3', {
x: -BLOCK_HALFSIZE,
y: BLOCK_HALFSIZE,
anchorX: 0,
anchorY: 1
});
self.blockContainer.attachAsset('blockX4', {
x: BLOCK_HALFSIZE,
y: BLOCK_HALFSIZE,
anchorX: 1,
anchorY: 1
});
self.down = function () {};
return self;
});
var BlockT = Block.expand(function (config) {
var self = Block.call(this, config);
self.blockContainer.attachAsset('blockT1', {
x: -BLOCK_HALFSIZE,
y: -BLOCK_HALFSIZE,
anchorX: 0,
anchorY: 0
});
self.blockContainer.attachAsset('blockT2', {
x: BLOCK_HALFSIZE,
y: -BLOCK_HALFSIZE,
anchorX: 1,
anchorY: 0
});
self.blockContainer.attachAsset('blockT3', {
y: BLOCK_HALFSIZE,
anchorX: 0.5,
anchorY: 1
});
self.updatePaths = function () {
self.downPath = self.orientation !== 0;
self.leftPath = self.orientation !== 1;
self.upPath = self.orientation !== 2;
self.rightPath = self.orientation !== 3;
};
self.updatePaths();
return self;
});
var BlockLine = Block.expand(function (config) {
var self = Block.call(this, config);
self.blockContainer.attachAsset('blockLine1', {
x: -BLOCK_HALFSIZE,
anchorX: 0,
anchorY: 0.5,
height: BLOCK_SIZE
});
self.blockContainer.attachAsset('blockLine2', {
x: BLOCK_HALFSIZE,
anchorX: 1,
anchorY: 0.5,
height: BLOCK_SIZE
});
self.updatePaths = function () {
var vertical = !(self.orientation % 2);
self.upPath = vertical;
self.downPath = vertical;
self.leftPath = !vertical;
self.rightPath = !vertical;
};
self.updatePaths();
return self;
});
var BlockL = Block.expand(function (config) {
var self = Block.call(this, config);
self.blockContainer.attachAsset('blockL1', {
anchorX: 0.5,
anchorY: 0.5,
height: BLOCK_SIZE
});
self.blockContainer.attachAsset('blockL2', {
x: -BLOCK_HALFSIZE,
y: BLOCK_HALFSIZE,
anchorX: 0,
anchorY: 1
});
self.updatePaths = function () {
self.leftPath = self.orientation === 0 || self.orientation === 1;
self.upPath = self.orientation === 1 || self.orientation === 2;
self.rightPath = self.orientation === 2 || self.orientation === 3;
self.downPath = self.orientation === 3 || self.orientation === 0;
};
self.updatePaths();
return self;
});
var BlockBlank = Block.expand(function (config) {
var self = Block.call(this, config);
var blockBlankAssets = ['blockBlank1', 'blockBlank2', 'blockBlank3'];
var randomAsset = blockBlankAssets[Math.floor(Math.random() * blockBlankAssets.length)];
self.blockContainer.attachAsset(randomAsset, {
anchorX: 0.5,
anchorY: 0.5,
width: BLOCK_SIZE,
height: BLOCK_SIZE
});
self.down = function () {};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
var LAVA_LINE = game.height - 200;
var LAVA_SLICE_COUNT = 18;
var LAVA_SLICE_WIDTH = 128;
var LAVA_BOB_HEIGHT = 10;
var LAVA_BOB_OFFSET = Math.PI / 5;
var LAVA_BOB_PERIOD = Math.PI / 60;
var BLOCK_SCALE = 2.5;
var BLOCK_SIZE = 100;
var BLOCK_MARGIN = 20;
var BLOCK_HALFSIZE = BLOCK_SIZE * 0.5;
var BLOCK_ROTATE_SPEED = 100;
var LIGHT_GROW_SPEED = 5000;
var LIGHT_SPILL_SIZE = 35;
var LIGHT_OFFSET = 5;
var ROW_SPAN = 7;
var ROW_COUNT = 11;
var ROW_SPEED_BASE = 0.2;
var ROW_SPEED_INCREASE = 0.02;
var ROW_SPEED_INCREASE_MIN = 0.005;
var ROW_SPEED_INCREASE_FACTOR = 0.9;
var COMPLIMENTS = {
up: 'down',
right: 'left',
down: 'up',
left: 'right'
};
var rowSpeed = ROW_SPEED_BASE;
var rowSpeedIncrease = ROW_SPEED_INCREASE;
var lightManager = game.addChild(new Container());
var blockManager = game.addChild(new BlockManager());
var lava = game.addChild(new Lava({
x: game.width / 2,
y: LAVA_LINE
}));
game.addChild(new Glow({
anchorX: 0.5,
anchorY: 0,
x: game.width / 2,
y: 0,
width: game.width,
height: 200,
rangeX: 200,
tint: 0x000000
}));
function shuffle(array) {
var currentIndex = array.length;
while (currentIndex != 0) {
var randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex--;
var ref = [array[randomIndex], array[currentIndex]];
array[currentIndex] = ref[0];
array[randomIndex] = ref[1];
}
return array;
}
function generateBlockClasses(index) {
var settings = {
index: index
};
switch (index) {
case 0:
return [BlockBlank, BlockBlank, BlockBlank, BlockX, BlockBlank, BlockBlank, BlockBlank];
case 1:
settings.blanks = ROW_SPAN; // Prevent additional blanks
return [BlockBlank, BlockBlank, randomizeBlockClass(settings), BlockX, randomizeBlockClass(settings), BlockBlank, BlockBlank];
case 2:
return [BlockBlank, randomizeBlockClass(settings), randomizeBlockClass(settings), BlockX, randomizeBlockClass(settings), randomizeBlockClass(settings), BlockBlank];
default:
var blockClasses = [];
for (var i = 0; i < ROW_SPAN; i++) {
blockClasses[i] = randomizeBlockClass(settings);
}
return shuffle(blockClasses);
}
}
function adjustRowSpeed() {
rowSpeed += rowSpeedIncrease;
rowSpeedIncrease = Math.max(ROW_SPEED_INCREASE_MIN, rowSpeedIncrease * ROW_SPEED_INCREASE_FACTOR);
}
function randomizeBlockClass(settings) {
var classes = [BlockBlank, BlockT, BlockX, BlockLine, BlockL];
return classes[Math.floor(Math.random() * classes.length)];
}
background
Music
light
Sound effect
rotate
Sound effect
error
Sound effect
crack
Sound effect
break
Sound effect
flow
Sound effect
bubble1
Sound effect
bubble2
Sound effect
bubble3
Sound effect
bubble4
Sound effect
bubble5
Sound effect
gong
Sound effect