Code edit (1 edits merged)
Please save this source code
User prompt
tween the column with ease in ↪💡 Consider importing and using the following plugins: @upit/tween.v1, @upit/tween.v1
User prompt
in the block Class's update function, instead of setting the y value using a sin function, instead get the relevant column's y value (using self.index)
User prompt
Replace the "// TODO: Timer and animations" by setting the column's timer to true, and adding a timeout between COL_TIMEOUT_MIN and COL_TIMEOUT_MAX. When the timeout completes, tween the column's y value to between COL_SLIP_MIN and COL_SLIP_MAX, over COL_SLIP_TIME time accounting for the slip (y) value. When the tween is complete, set the column's timer to false ↪💡 Consider importing and using the following plugins: @upit/tween.v1, @upit/tween.v1
User prompt
Please fix the bug: 'TypeError: columns is undefined' in or related to this line: 'for (var i = 1; i < columns.length - 1; i++) {' Line Number: 1135
Code edit (1 edits merged)
Please save this source code
User prompt
Please fix the bug: 'TypeError: columns is undefined' in or related to this line: 'for (var i = 1; i < columns.length - 1; i++) {' Line Number: 1135
Code edit (1 edits merged)
Please save this source code
User prompt
add a game update method that iterates through the columns array excluding the first and last element
Code edit (3 edits merged)
Please save this source code
User prompt
create a global array called columns and populate the array with objects containing y=0 and timer=false. There should be ROW_SPAN number of elements
User prompt
increase the size of the game over message by 50%
Code edit (1 edits merged)
Please save this source code
User prompt
set the rangeX to 20 as well
User prompt
additionally, use a shapeEllipse as the asset and solid set to true
User prompt
The Light class's lightshape should rather be a glow class instance with 5 layers, 10 rangeY and tinted white
Code edit (1 edits merged)
Please save this source code
User prompt
instead of showing the message as part of the widget, display it as a bordered text in the middle of the screen, 1/3 of the way from the top
User prompt
delay the game over widget by 1 second
User prompt
play the gong sound when game over
User prompt
when creating a lavaparticle, add a 25% chance to randomly play one of the bubble asset sounds
User prompt
in the Lava class, play the 'flow' sound every 5s to 10s, starting immediately
Code edit (3 edits merged)
Please save this source code
User prompt
play the light sound when onLit is called, after the paths have been checked
User prompt
instead of using self.errorSoundPlaying, use a global variable
/**** * 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 PointText = ConfigContainer.expand(function (config) { var self = ConfigContainer.call(this, config); var text = self.addChild(new BorderedText('+1', { anchorX: 0.5, anchorY: 0.5, size: 100 })); 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.addChild(new Glow({ y: -LIGHT_OFFSET, width: BLOCK_SIZE - 2 * LIGHT_OFFSET - 10, height: BLOCK_SIZE - 2 * LIGHT_OFFSET - 10, anchorX: 0.5, anchorY: 1, layers: 5, rangeX: 20, rangeY: 10, tint: 0xFFFFFF, scaleX: 0, scaleY: 0, asset: 'shapeEllipse', solid: true })); tween(lightShape, { scaleX: 1, scaleY: 1 }, { duration: LIGHT_GROW_SPEED + Math.random() * LIGHT_GROW_VARIANCE, 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; if (Math.random() < 0.0025) { self.parent.particleContainer.addChild(new LavaParticle({ x: self.x + Math.random() * LAVA_SLICE_WIDTH - LAVA_SLICE_WIDTH / 2, y: self.y, scale: 1 + Math.random() * 0.5 // Random scale between 1 and 1.5 })); } }; return self; }); var LavaParticle = ConfigContainer.expand(function (config) { var self = ConfigContainer.call(this, config); // Attach a glow asset with specified properties self.rotation = Math.random() * Math.PI; // Random rotation between 0 and pi self.attachAsset('shapeBox', { anchorX: 0.5, anchorY: 0.5, width: 20, height: 20, tint: 0xFF4D00, alpha: 0.5 }); // Attach a smaller shapeBox with black tint and 0.5 alpha self.attachAsset('shapeBox', { anchorX: 0.5, anchorY: 0.5, width: 10, height: 10, tint: 0x000000, alpha: 0.25 }); // Set initial random velocities increased by a factor of 10 self.vx = (1 - 2 * Math.random()) * 10; // Random x velocity between 10 and -10 self.vy = (1 - 0.5 * Math.random()) * -8; // Random y velocity between -8 and -4 // Update function to apply gravity and movement self.update = function () { self.vy += 0.1; // Gravity effect self.vx *= 0.975; self.x += self.vx; self.y += self.vy; // Destroy the particle if it goes below the game height if (self.y > LAVA_BOB_HEIGHT) { self.callDestroy(); } }; if (Math.random() < 0.25) { var bubbleSounds = ['bubble1', 'bubble2', 'bubble3', 'bubble4', 'bubble5']; var randomBubbleSound = bubbleSounds[Math.floor(Math.random() * bubbleSounds.length)]; LK.getSound(randomBubbleSound).play(); } return self; }); var Lava = ConfigContainer.expand(function (config) { var self = ConfigContainer.call(this, config); self.particleContainer = self.addChild(new Container()); 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 })); } // Function to play the 'flow' sound at random intervals between 5s to 10s function playFlowSound() { LK.getSound('flow').play(); var nextInterval = 5000 + Math.random() * 5000; // Random interval between 5000ms (5s) and 10000ms (10s) LK.setTimeout(playFlowSound, nextInterval); } // Start playing the 'flow' sound immediately playFlowSound(); 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 config = { * x : Number || 0, // See: ConfigContainer * y : Number || 0, // See: ConfigContainer * rotation : Number || 0, // See: ConfigContainer * anchorX : Number || 0, * anchorY : Number || 1, * size : Number || TEXT_DEFAULT_SIZE, * font : String || TEXT_DEFAULT_FONT, * fill : String || TEXT_DEFAULT_FILL, * border : String || TEXT_DEFAULT_BORDER, * } **/ var BorderedText = ConfigContainer.expand(function (text, config) { var self = ConfigContainer.call(this, config); config = config || {}; var anchorX = config.anchorX !== undefined ? config.anchorX : 0; var anchorY = config.anchorY !== undefined ? config.anchorY : 1; var size = config.size !== undefined ? config.size : TEXT_DEFAULT_SIZE; var font = config.font !== undefined ? config.font : TEXT_DEFAULT_FONT; var textFill = config.fill !== undefined ? config.fill : TEXT_DEFAULT_FILL; var borderFill = config.border !== undefined ? config.border : TEXT_DEFAULT_BORDER; var mainAsset; var textAssets = []; ; self.setText = setText; self.setFill = setFill; ; function setText(newText) { for (var i = 0; i < textAssets.length; i++) { textAssets[i].setText(newText); } } function setFill(newFill) { textFill = newFill; mainAsset.fill = newFill; } function buildTextAssets(newText) { for (var i = 0; i < TEXT_OFFSETS.length; i++) { var main = i === TEXT_OFFSETS.length - 1; var textAsset = textAssets[i]; if (textAsset) { textAsset.destroy(); } textAsset = self.addChild(new Text2(newText, { fill: main ? textFill : borderFill, font: font, size: size })); textAsset.anchor = { x: anchorX, y: anchorY }; // NOTE: Cannot be set in config textAsset.x = TEXT_OFFSETS[i][0] * TEXT_BORDER_WEIGHT; // NOTE: Cannot be set in config textAsset.y = TEXT_OFFSETS[i][1] * TEXT_BORDER_WEIGHT; // NOTE: Cannot be set in config textAssets[i] = textAsset; } mainAsset = textAssets[TEXT_OFFSETS.length - 1]; } ; buildTextAssets(text); return self; }); /** * var config = { * x : Number || 0, // See: ConfigContainer * y : Number || 0, // See: ConfigContainer * rotation : Number || 0, // See: ConfigContainer * anchorX : Number || .5, * anchorY : Number || .5, * scale : Number || undefined, * scaleX : Number || scale, * scaleY : Number || scale, * width : Number || undefined, // Auto-calculated if left undefined and height is set * height : Number || undefined, // Auto-calculated if left undefined and width is set * tint : String || 0xFFFFFF, // Not tinted by default * border : String || TEXT_DEFAULT_BORDER, * } **/ var BorderedSymbol = ConfigContainer.expand(function (symbol, config) { var self = ConfigContainer.call(this, config); config = config || {}; var width = config.width !== undefined ? config.width : undefined; var height = config.height !== undefined ? config.height : undefined; var scale = config.scale !== undefined ? config.scale : undefined; var scaleX = config.scaleX !== undefined ? config.scaleX : scale; var scaleY = config.scaleY !== undefined ? config.scaleX : scale; var anchorX = config.anchorX !== undefined ? config.anchorX : .5; var anchorY = config.anchorY !== undefined ? config.anchorY : .5; var symbolTint = config.tint !== undefined ? config.tint : 0xFFFFFF; var borderTint = config.border !== undefined ? config.border : TEXT_DEFAULT_BORDER; var mainSymbol; var symbolAssets = []; ; self.setSymbol = buildSymbolAssets; self.setTint = setTint; ; function setTint(newTint) { // NOTE: Tinting is currently broken (cannot use string) // mainSymbol.tint = newTint; // symbolConfig.tint = newTint; } function buildSymbolAssets(newSymbol) { for (var i = 0; i < TEXT_OFFSETS.length; i++) { var main = i === TEXT_OFFSETS.length - 1; var symbolAsset = symbolAssets[i]; if (symbolAsset) { symbolAsset.destroy(); } symbolAsset = self.attachAsset(newSymbol, { // tint: main ? symbolTint : borderTint, tint: main ? 0xFFFFFF : 0x000000, // NOTE: Tinting is currently broken (cannot use string) x: TEXT_OFFSETS[i][0] * TEXT_BORDER_WEIGHT, y: TEXT_OFFSETS[i][1] * TEXT_BORDER_WEIGHT, anchorX: anchorX, anchorY: anchorY }); if (width !== undefined && height === undefined) { height = symbolAsset.height * (width / symbolAsset.width); } else if (height !== undefined && width === undefined) { width = symbolAsset.width * (height / symbolAsset.height); } symbolAsset.width = width; symbolAsset.height = height; if (scaleX !== undefined && scaleY !== undefined) { symbolAsset.scale.set(scaleX, scaleY); } symbolAssets[i] = symbolAsset; } mainSymbol = symbolAssets[TEXT_OFFSETS.length - 1]; } ; buildSymbolAssets(symbol); return self; }); var Border = ConfigContainer.expand(function (config) { var self = ConfigContainer.call(this, config); var radius = 70; var totalHeight = 0; var borderAssets = ['border1', 'border2']; while (totalHeight < game.height) { var randomAsset = borderAssets[Math.floor(Math.random() * borderAssets.length)]; var borderSegment = self.attachAsset(randomAsset, { anchorX: 0.5, anchorY: 0, y: totalHeight }); totalHeight += borderSegment.height; } var borderGear = self.attachAsset('borderGear', { width: 2 * radius, height: 2 * radius, anchorX: 0.5, anchorY: 0.5, y: LIGHT_LEVEL, rotation: Math.random() * Math.PI * 2 // Initialize with random rotation }); var borderLevel = self.attachAsset('borderLevel', { anchorX: 0.15, anchorY: 0.85, y: LIGHT_LEVEL, rotation: Math.PI / 4 // 45 degree rotation }); self.update = function () { borderGear.rotation += rowSpeed / radius; }; return self; }); var BlockSparkParticle = ConfigContainer.expand(function (config) { var self = ConfigContainer.call(this, config); var shapeBox = self.attachAsset('shapeBox', { width: 10, height: 10, anchorX: 0.5, anchorY: 0.5, rotation: Math.random() * Math.PI // Random rotation between 0 and pi }); // Set initial random direction and speed var angle = Math.random() * 2 * Math.PI; var offset = Math.random() * 50; // Random offset between 0 and 50 self.x += Math.cos(angle) * offset; self.y += Math.sin(angle) * offset; self.vx = Math.cos(angle) * 10; self.vy = Math.sin(angle) * 10; // Update function to move the particle self.update = function () { self.vy += 0.5; // Apply gravity effect self.x += self.vx; self.y += self.vy; }; // Tween to fade out the particle tween(self, { alpha: 0 }, { duration: 350, onFinish: function onFinish() { self.callDestroy(); } }); return self; }); var BlockRow = ConfigContainer.expand(function (config) { var self = ConfigContainer.call(this, config); var blockClasses = generateBlockClasses(config.index); self.index = 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, index: i, row: self })); } 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 > LIGHT_LEVEL - BLOCK_SIZE * BLOCK_SCALE / 2) { 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 BlockLitParticle = ConfigContainer.expand(function (config) { var self = ConfigContainer.call(this, config); var shapeBox = self.attachAsset('particleBlockLit', { scaleX: 1.0, scaleY: 1.0, anchorX: 0.5, anchorY: 0.5, alpha: 0.1 }); tween(shapeBox, { scaleX: 2.0, scaleY: 2.0, alpha: 0.0 }, { duration: 350, easing: tween.linear, onFinish: function onFinish() { self.callDestroy(); } }); return self; }); var BlockBreakParticle = ConfigContainer.expand(function (config) { var self = ConfigContainer.call(this, config); var blockAssets = ['blockX1', 'blockX2', 'blockX3', 'blockX4']; var randomAsset = blockAssets[Math.floor(Math.random() * blockAssets.length)]; var shapeBox = self.attachAsset(randomAsset, { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 1.5, rotation: Math.random() * Math.PI * 2 }); // Set initial random direction and speed var angle = Math.random() * 2 * Math.PI; var offset = 50 + Math.random() * 50; // Random offset between 0 and 50 self.x += Math.cos(angle) * offset; self.y += Math.sin(angle) * offset; self.vx = Math.cos(angle) * 10; self.vy = Math.sin(angle) * 10; // Update function to move the particle self.update = function () { self.vy += 0.5; // Apply gravity effect self.x += self.vx; self.y += self.vy; }; // Tween to fade out the particle tween(self, { alpha: 0 }, { duration: 350, onFinish: function onFinish() { self.callDestroy(); } }); return self; }); var Block = ConfigContainer.expand(function (config) { var self = ConfigContainer.call(this, config); self.isRotating = false; self.disabled = config.disabled; self.row = config.row; self.index = config.index; self.orientation = config.orientation !== undefined ? config.orientation : Math.floor(4 * Math.random()); self.toLight = false; 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.showLock(); } else if (!self.isRotating) { self.toLight = false; self.isRotating = true; LK.getSound('rotate').play(); 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.y = Math.max(0, Math.sin(LK.ticks / 60 + self.index) * 10); self.lightContainer.x = self.x + self.parent.x; self.lightContainer.y = self.y + self.parent.y; } if (self.toLight && self.row.y >= LIGHT_LEVEL + BLOCK_SCALE * BLOCK_HALFSIZE) { self.toLight = false; self.onLit(); } }; self.down = function () { self.rotate(); tween(self.scale, { x: 0.9 * BLOCK_SCALE, y: 0.9 * BLOCK_SCALE }, { duration: BLOCK_ROTATE_SPEED / 2, onFinish: function onFinish() { tween(self.scale, { x: BLOCK_SCALE, y: BLOCK_SCALE }, { duration: BLOCK_ROTATE_SPEED / 2 }); } }); }; self.onLit = function (pointless) { if (self.row.y < LIGHT_LEVEL + BLOCK_SCALE * BLOCK_HALFSIZE) { self.toLight = true; } else 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) { LK.setScore(LK.getScore() + 1); scoreText.setText(LK.getScore()); game.addChild(new BlockLitParticle({ // Create a BlockLitParticle x: self.x + self.parent.x, y: self.y + self.parent.y, scale: BLOCK_SCALE })); game.addChild(new PointText({ x: self.x + self.parent.x, y: self.y + self.parent.y })); } lightSources += 1; LK.getSound('light').play(); 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.showLock = function () { // Check and destroy existing lockSymbol before creating a new one if (self.lockSymbol) { self.lockSymbol.destroy(); } var lockSymbol = self.addChild(LK.getAsset('iconLock', { anchorX: 0.5, anchorY: 0.5, scaleX: 1 / self.scale.x, scaleY: 1 / self.scale.y })); // Play error sound if not already playing if (!errorSoundPlaying) { errorSoundPlaying = true; LK.getSound('error').play(); LK.setTimeout(function () { errorSoundPlaying = false; }, 500); } self.lockSymbol = lockSymbol; // Set a timeout to fade out the lockSymbol after 500ms LK.setTimeout(function () { tween(lockSymbol, { alpha: 0 }, { duration: 500, onFinish: function onFinish() { lockSymbol.destroy(); self.lockSymbol = null; } }); }, 500); }; 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.lit) { lightSources -= 1; if (lightSources === 0) { LK.getSound('gong').play(); // Play the gong sound var gameOverText = game.addChild(new BorderedText("- Your Light is Dead -", { size: 150, anchorX: 0.5, anchorY: 0.5, x: game.width / 2, y: game.height / 4 })); LK.setTimeout(function () { // Delay the game over widget by 1 second LK.showGameOver(); }, 1000); } } if (self.lightContainer) { self.lightContainer.destroy(); } }; return self; }); var BlockX = Block.expand(function (config) { var self = Block.call(this, config); var shiftY = 2; self.upPath = true; self.rightPath = true; self.downPath = true; self.leftPath = true; self.blockContainer.attachAsset('blockX1', { x: -BLOCK_HALFSIZE, y: -BLOCK_HALFSIZE + shiftY, anchorX: 0, anchorY: 0 }); self.blockContainer.attachAsset('blockX2', { x: BLOCK_HALFSIZE, y: -BLOCK_HALFSIZE + shiftY, anchorX: 1, anchorY: 0 }); self.blockContainer.attachAsset('blockX3', { x: -BLOCK_HALFSIZE, y: BLOCK_HALFSIZE + shiftY, anchorX: 0, anchorY: 1 }); self.blockContainer.attachAsset('blockX4', { x: BLOCK_HALFSIZE, y: BLOCK_HALFSIZE + shiftY, anchorX: 1, anchorY: 1 }); 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 crackAsset; var crackLevel = 0; 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.rotate = function (force) { if (force || crackLevel > 0) { if (++crackLevel <= 4) { if (crackAsset) { crackAsset.destroy(); } if (!force) { LK.getSound('crack').play(); } crackAsset = self.blockContainer.attachAsset('crack' + crackLevel, { anchorX: 0.5, anchorY: 0.5, rotation: crackLevel === 1 ? Math.random() * Math.PI * 2 : 0 // Random rotation if crackLevel is 1 }); // Create BlockSparkParticles if (self.parent) { for (var i = 0; i < 2 * crackLevel; i++) { game.addChild(new BlockSparkParticle({ x: self.x + self.parent.x, y: self.y + self.parent.y })); } } } else { LK.getSound('break').play(); var blockClass = randomizeBlockClass({ index: self.row.index, blanks: ROW_SPAN // Prevent spawning blocks }); var newBlock = self.parent.addChild(new blockClass({ x: self.x, y: self.y, scale: BLOCK_SCALE, index: self.index, row: self.row })); self.row.blocks[self.index] = newBlock; // Update block references if (self.upBlock) { self.upBlock.downBlock = newBlock; newBlock.upBlock = self.upBlock; } if (self.downBlock) { self.downBlock.upBlock = newBlock; newBlock.downBlock = self.downBlock; } if (self.leftBlock) { self.leftBlock.rightBlock = newBlock; newBlock.leftBlock = self.leftBlock; } if (self.rightBlock) { self.rightBlock.leftBlock = newBlock; newBlock.rightBlock = self.rightBlock; } if (!self.disabled) { newBlock.onSettle(); } // Create BlockBreakParticles for (var i = 0; i < 6; i++) { game.addChild(new BlockBreakParticle({ x: self.x + self.parent.x, y: self.y + self.parent.y })); } self.callDestroy(); } } else { self.showLock(); } }; if (Math.random() < BLOCK_CRACK_CHANCE) { self.rotate(true); } return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ // Math constants / pre-calculations var MATH_HALF_ROOT_3 = Math.sqrt(3) / 2; // Required by: TEXT_OFFSETS, BorderedText, BorderedSymbol, SymbolText ; // Text settings 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]]; // Required by: BorderedText, BorderedSymbol, SymbolText var TEXT_BORDER_WEIGHT = 5; // Required by: BorderedText, BorderedSymbol, SymbolText var TEXT_DEFAULT_BORDER = '#000000'; // Required by: BorderedText, BorderedSymbol, SymbolText var TEXT_DEFAULT_FILL = '#FFFFFF'; // Required by: BorderedText, SymbolText var TEXT_DEFAULT_FONT = 'Arial'; // Required by: BorderedText, SymbolText var TEXT_DEFAULT_SIZE = 50; // Required by: BorderedText, SymbolText ; // Other settings 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_CRACK_CHANCE = 0.3; var BLOCK_ROTATE_SPEED = 100; var LIGHT_LEVEL = 800; var LIGHT_GROW_SPEED = 4500; var LIGHT_GROW_VARIANCE = 1000; 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.04; var ROW_SPEED_INCREASE_MIN = 0.01; var ROW_SPEED_INCREASE_FACTOR = 0.9; var COL_SLIP_MIN = 10; var COL_SLIP_MAX = 25; var COL_SLIP_TIME = 350; var COL_TIMEOUT_MIN = 1000; var COL_TIMEOUT_MAX = 10000; var COMPLIMENTS = { up: 'down', right: 'left', down: 'up', left: 'right' }; var lightSources = 0; var rowSpeed = ROW_SPEED_BASE; var rowSpeedIncrease = ROW_SPEED_INCREASE; var errorSoundPlaying = false; var columns = []; for (var i = 0; i < ROW_SPAN; i++) { columns.push({ y: 0, timer: false }); } // Play background music on repeat when the game starts LK.playMusic('background', { loop: true }); game.update = function () { for (var i = 1; i < columns.length - 1; i++) { var columns = columns[i]; if (!column.timer) { if (column.y > 0) { column.y = Math.max(0, columns.y - rowSpeed); } else { // TODO: Timer and animations } } } }; var scoreText = new BorderedText('0', { size: 100, anchorX: 0.5, anchorY: 0 }); LK.gui.top.addChild(scoreText); var rowSpeedText = LK.gui.topRight.addChild(new Text2((rowSpeed * 60).toFixed(1), { size: 50, fill: 0xFFFFFF, stroke: 0x000000, strokeThickness: 5 })); rowSpeedText.anchor.set(1.0, -0.5); var speedIcon = LK.gui.topRight.addChild(LK.getAsset('iconGear', { anchorX: 0.5, anchorY: 0.5, x: rowSpeedText.x - rowSpeedText.width - 40, y: rowSpeedText.height })); var iconRotate = LK.gui.topRight.addChild(new BorderedSymbol('iconRotate', { anchorX: 0.2, anchorY: 1.0, x: speedIcon.x, y: speedIcon.y })); var lightManager = game.addChild(new Container()); game.addChild(new Glow({ width: game.width, height: LIGHT_LEVEL, rangeY: 20, layers: 5, solid: true })); var blockManager = game.addChild(new BlockManager()); var leftBorder = game.addChild(new Border({ x: 30 })); var rightBorder = game.addChild(new Border({ x: game.width - 30, scaleX: -1 })); var lava = game.addChild(new Lava({ x: game.width / 2, y: LAVA_LINE })); game.addChild(new Glow({ x: game.width / 2, width: game.width, height: 200, anchorX: 0.5, anchorY: 0, rangeY: 200, tint: 0x000000, alpha: 2.0 })); var iconLight = game.addChild(LK.getAsset('iconLight', { x: game.width / 2, y: 100, anchorX: 0.5, anchorY: 0.5, tint: 0xFF4D00 })); 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, blanks: 0, xs: 0 }; switch (index) { case 0: return [BlockBlank, BlockBlank, BlockBlank, BlockX, BlockBlank, BlockBlank, BlockBlank]; case 1: settings.blanks = ROW_SPAN; settings.xs = 1; return [BlockBlank, BlockBlank, randomizeBlockClass(settings), BlockX, randomizeBlockClass(settings), BlockBlank, BlockBlank]; case 2: settings.blanks = ROW_SPAN; settings.xs = 1; 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; rowSpeedText.setText((rowSpeed * 60).toFixed(1)); rowSpeedIncrease = Math.max(ROW_SPEED_INCREASE_MIN, rowSpeedIncrease * ROW_SPEED_INCREASE_FACTOR); } function randomizeBlockClass(settings) { var classes = [{ blockClass: BlockBlank, chance: Math.max(0, 1.5 - 0.5 * (settings.blanks || 0)) }, { blockClass: BlockT, chance: 1 }, { blockClass: BlockX, chance: Math.max(0, 1 - 1 * (settings.xs || 0)) }, { blockClass: BlockLine, chance: 1 }, { blockClass: BlockL, chance: 1 }]; var totalChance = classes.reduce(function (sum, item) { return sum + item.chance; }, 0); var randomValue = Math.random() * totalChance; var accumulatedChance = 0; var blockClass = BlockBlank; for (var i = 0; i < classes.length; i++) { accumulatedChance += classes[i].chance; if (randomValue < accumulatedChance) { blockClass = classes[i].blockClass; break; } } switch (blockClass) { case BlockBlank: settings.blanks = (settings.blanks || 0) + 1; break; case BlockX: settings.xs = (settings.xs || 0) + 1; break; } return blockClass; }
===================================================================
--- original.js
+++ change.js