Code edit (21 edits merged)
Please save this source code
User prompt
where it says 'make the t objects flash red' in the code, please make it do so
Code edit (1 edits merged)
Please save this source code
User prompt
please place a score label above the boad on the right side, and under it, a highest score label,somewhat smaller
Code edit (4 edits merged)
Please save this source code
User prompt
Please fix the bug: 'Error: Invalid end type for property x: undefined' in or related to this line: 'tween(self, {' Line Number: 173
Code edit (7 edits merged)
Please save this source code
User prompt
on gameover, please compare the playerscore to any previously stored highscore, using the storage plugin, and store the new highscore if it is indeed higher than the previous score. ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'setItem')' in or related to this line: 'localStorage.setItem('highscore', playerScore);' Line Number: 679
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'setItem')' in or related to this line: 'localStorage.setItem('highscore', playerScore);' Line Number: 675
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'setItem')' in or related to this line: 'localStorage.setItem('highscore', playerScore);' Line Number: 671
Code edit (1 edits merged)
Please save this source code
Code edit (1 edits merged)
Please save this source code
User prompt
Please fix the bug: 'TypeError: Cannot set properties of undefined (setting '3')' in or related to this line: 'currentLevel[self.gridY][self.gridX] = self.colorIndex;' Line Number: 189
Code edit (1 edits merged)
Please save this source code
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'length')' in or related to this line: 'for (var i = 0; i < a.length; i++) {' Line Number: 357
Code edit (1 edits merged)
Please save this source code
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'length')' in or related to this line: 'for (var i = 0; i < a.length; i++) {' Line Number: 357
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'length')' in or related to this line: 'for (var i = 0; i < a.length; i++) {' Line Number: 357
Code edit (1 edits merged)
Please save this source code
Code edit (4 edits merged)
Please save this source code
User prompt
Please fix the bug: 'TypeError: Cannot set properties of undefined (setting '5')' in or related to this line: 'currentLevel[self.gridY][self.gridX] = self.colorIndex;' Line Number: 189
Code edit (13 edits merged)
Please save this source code
User prompt
Please fix the bug: 'newPosition is not defined' in or related to this line: 'if (newPosition != 999) {' Line Number: 638
Code edit (1 edits merged)
Please save this source code
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Arrow = Container.expand(function () {
var self = Container.call(this);
var arrowGraphics = self.attachAsset('arrow', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.1
});
});
//<Assets used in the game will automatically appear here>
//<Write imports for supported plugins here>
var Board = Container.expand(function () {
var self = Container.call(this);
self.boxGraphics = self.attachAsset('board', {
anchorX: 0.5,
anchorY: 0.5
});
self.paint = function () {
self.boxGraphics.width = boardSize;
self.boxGraphics.height = boardSize;
var startX = -self.width / 2;
var startY = -self.height / 2;
var boxSize = calculateTileSize();
var boxSpacing = boxSize * spacingRatio;
var offset = boxSize / 2 + boxSpacing;
for (var i = 0; i < gridSize; i++) {
for (var j = 0; j < gridSize; j++) {
var box = self.addChild(new Box());
box.width = box.height = boxSize;
box.x = offset + startX + i * (boxSize + boxSpacing);
box.y = offset + startY + j * (boxSize + boxSpacing);
box.setAlpha(0.075);
}
}
// Paint arrows at edges of board.
for (var i = 0; i < gridSize; i++) {
for (var j = 0; j < gridSize; j++) {
if (i == 0) {
var arrow = new Arrow();
arrow.rotation = Math.PI / 2;
arrow.scale.x = arrow.scale.y = boxSize / 100;
arrow.x = offset + startX + j * (boxSize + boxSpacing);
arrow.y = startY - 2 * boxSpacing;
self.addChild(arrow);
} else if (i == gridSize - 1) {
var arrow = new Arrow();
arrow.rotation = -Math.PI / 2;
arrow.scale.x = arrow.scale.y = boxSize / 100;
arrow.x = offset + startX + j * (boxSize + boxSpacing);
arrow.y = -startY + 2 * boxSpacing;
self.addChild(arrow);
}
if (j == 0) {
var arrow = new Arrow();
arrow.scale.x = arrow.scale.y = boxSize / 100;
arrow.x = startX - 2 * boxSpacing;
arrow.y = offset + startY + i * (boxSize + boxSpacing);
self.addChild(arrow);
} else if (j == gridSize - 1) {
var arrow = new Arrow();
arrow.rotation = Math.PI;
arrow.scale.x = arrow.scale.y = boxSize / 100;
arrow.x = -startX + 2 * boxSpacing;
arrow.y = offset + startY + i * (boxSize + boxSpacing);
self.addChild(arrow);
}
}
}
};
self.paint();
self.paintArrows = function () {};
self.paintArrows();
});
var Box = Container.expand(function () {
var self = Container.call(this);
var boxGraphics = self.attachAsset('box', {
anchorX: 0.5,
anchorY: 0.5
});
self.setAlpha = function (i) {
self.alpha = i;
};
});
var ColorBox = Container.expand(function (colorIndex) {
var self = Container.call(this);
self.colorIndex = colorIndex;
var boxGraphics = self.attachAsset('box', {
anchorX: 0.5,
anchorY: 0.5,
tint: colors[colorIndex]
});
self.gridX = 0;
self.gridY = 0;
self.speed = 10;
self.outlier = false;
self.down = function (x, y, obj) {
if (GAME_IS_CLICKABLE) {
if (!self.outlier) {
GAME_IS_CLICKABLE = false;
colorBoxClicked(self);
}
}
};
self.remove = function (delay) {
numRunningTweens++;
currentLevel[self.gridY][self.gridX] = 0;
tween(self, {
scaleX: 0.5,
scaleY: 0.5,
rotation: Math.PI,
alpha: 0
}, {
duration: 300,
delay: delay,
easing: tween.easeInOut,
onFinish: function onFinish() {
//console.log("Animation complete!");
//console.log('currentLevel:', currentLevel);
console.log('levelContainer:', levelContainer);
playerScore++;
numRunningTweens--;
self.destroy();
}
});
//self.destroy();
};
self.fadeIn = function () {
numRunningTweens++;
self.alpha = 0;
tween(self, {
alpha: 1
}, {
duration: 300,
delay: 0,
easing: tween.easeInOut,
onFinish: function onFinish() {
numRunningTweens--;
console.log('faded in:', self);
}
});
};
self.moveInPosition = function () {
var startX = -boardSize / 2;
var startY = -boardSize / 2;
var boxSize = tileSize; //calculateTileSize();
var boxSpacing = boxSize * spacingRatio;
var offset = boxSize / 2 + boxSpacing;
var destX = offset + startX + self.gridX * (boxSize + boxSpacing);
var destY = offset + startY + self.gridY * (boxSize + boxSpacing);
numRunningTweens++;
tween(self, {
x: destX,
y: destY
}, {
duration: 300,
delay: 0,
easing: tween.easeInOut,
onFinish: function onFinish() {
numRunningTweens--;
currentLevel[self.gridY][self.gridX] = self.colorIndex;
console.log('done moving into position');
}
});
};
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000 //Init game with black background
});
/****
* Game Code
****/
function _slicedToArray(r, e) {
return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();
}
function _nonIterableRest() {
throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _iterableToArrayLimit(r, l) {
var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
if (null != t) {
var e,
n,
i,
u,
a = [],
f = !0,
o = !1;
try {
if (i = (t = t.call(r)).next, 0 === l) {
if (Object(t) !== t) {
return;
}
f = !1;
} else {
for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0) {
;
}
}
} catch (r) {
o = !0, n = r;
} finally {
try {
if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) {
return;
}
} finally {
if (o) {
throw n;
}
}
}
return a;
}
}
function _arrayWithHoles(r) {
if (Array.isArray(r)) {
return r;
}
}
function _createForOfIteratorHelper(r, e) {
var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
if (!t) {
if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) {
t && (r = t);
var _n = 0,
F = function F() {};
return {
s: F,
n: function n() {
return _n >= r.length ? {
done: !0
} : {
done: !1,
value: r[_n++]
};
},
e: function e(r) {
throw r;
},
f: F
};
}
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
var o,
a = !0,
u = !1;
return {
s: function s() {
t = t.call(r);
},
n: function n() {
var r = t.next();
return a = r.done, r;
},
e: function e(r) {
u = !0, o = r;
},
f: function f() {
try {
a || null == t["return"] || t["return"]();
} finally {
if (u) {
throw o;
}
}
}
};
}
function _unsupportedIterableToArray(r, a) {
if (r) {
if ("string" == typeof r) {
return _arrayLikeToArray(r, a);
}
var t = {}.toString.call(r).slice(8, -1);
return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
}
}
function _arrayLikeToArray(r, a) {
(null == a || a > r.length) && (a = r.length);
for (var e = 0, n = Array(a); e < a; e++) {
n[e] = r[e];
}
return n;
}
var GAME_IS_CLICKABLE = true; // flag for when board is clickable and when not.
var numRunningTweens = 0; // input is blocked while tweens running, so increment this when a tween starts, nd decrement when tween ends.
var outlierDirectionCounter = 0; // increment to allow outliers spawning on different side each turn.
var playerScore = 0;
var colors = ['0x000000', '0xffffff', '0xffff00'];
var gridSize = 7;
var spacingRatio = 0.2;
var boardSize = 1300;
function calculateTileSize() {
// Example of getting desired tileSize depending on gridSize (for different size grids)
// maintaining 1300px board size and 0.2 gutter between tiles.
var tileSize = boardSize / ((gridSize + 1) * spacingRatio + gridSize);
return tileSize;
console.log(tileSize);
}
var tileSize = calculateTileSize();
var board = new Board();
board.x = 1024;
board.y = 2732 / 2;
game.addChild(board);
var l1 = [[0, 0, 0, 0, 0], [0, 1, 1, 1, 0], [0, 1, 2, 1, 0], [0, 0, 1, 0, 0], [0, 0, 0, 0, 0]];
var l2 = [[0, 0, 0, 0, 0, 0], [0, 0, 1, 1, 0, 0], [0, 0, 2, 2, 0, 0], [0, 0, 1, 1, 0, 0], [0, 0, 2, 2, 0, 0], [0, 0, 0, 0, 0, 0]];
var l3 = [[0, 0, 0, 0, 0, 0, 0], [0, 0, 1, 1, 1, 0, 0], [0, 0, 2, 2, 0, 0, 0], [0, 0, 1, 1, 0, 0, 0], [0, 0, 2, 2, 0, 0, 0], [0, 2, 2, 1, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0]];
var levels = [l1, l2, l3];
var currentLevel = levels[2].slice(0); //copy without reference, so we have original for retry/level reset.
var levelContainer = new Container();
levelContainer.x = 1024;
levelContainer.y = 2732 / 2;
game.addChild(levelContainer);
function paintLevel(a) {
var startX = -boardSize / 2;
var startY = -boardSize / 2;
var boxSize = tileSize;
var boxSpacing = boxSize * spacingRatio;
var offset = boxSize / 2 + boxSpacing;
for (var i = 0; i < a.length; i++) {
for (var j = 0; j < a[0].length; j++) {
if (a[j][i] != 0) {
var cBox = levelContainer.addChild(new ColorBox(a[j][i]));
cBox.width = cBox.height = boxSize;
cBox.x = offset + startX + i * (boxSize + boxSpacing);
cBox.y = offset + startY + j * (boxSize + boxSpacing);
cBox.gridX = i;
cBox.gridY = j;
}
}
}
}
paintLevel(currentLevel);
// Click handler
game.down = function (x, y, obj) {
//board.scale.x *= 1.2;
//board.scale.y *= 1.2;
//console.log(x, y, obj);
};
function findConnectedSameColorTiles(startBox) {
var connectedTiles = [];
var visited = [];
var queue = [startBox];
var targetColor = startBox.colorIndex;
while (queue.length > 0) {
var currentBox = queue.shift(); // Use pop() for DFS
var _currentBox = currentBox,
x = _currentBox.gridX; //x,
y = _currentBox.gridY; //y; // Assuming each box has x, y properties
if (visited.indexOf(currentBox) === -1) {
visited.push(currentBox);
connectedTiles.push(currentBox);
// Check all adjacent tiles
var neighbors = getAdjacentTiles(x, y);
console.log("neighbors:", neighbors);
var _iterator = _createForOfIteratorHelper(neighbors),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var neighbor = _step.value;
//if (neighbor.colorIndex === targetColor && !visited.has(neighbor)) {
if (neighbor.colorIndex === targetColor && !visited.includes(neighbor)) {
queue.push(neighbor);
}
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
}
}
return connectedTiles;
}
function getAdjacentTiles(x, y) {
var adjacentTiles = [];
var directions = [[-1, 0], [1, 0], [0, -1], [0, 1]]; // left, right, up, down
for (var _i = 0, _directions = directions; _i < _directions.length; _i++) {
var _directions$_i = _slicedToArray(_directions[_i], 2),
dx = _directions$_i[0],
dy = _directions$_i[1];
var newX = x + dx;
var newY = y + dy;
// Check if the new position is within the grid boundaries
if (newX >= 0 && newX < currentLevel.length && newY >= 0 && newY < currentLevel[0].length) {
var colorBox = levelContainer.children.find(function (child) {
//return child.gridX === newX && child.gridY === newY;
return !child.outlier && child.gridX === newX && child.gridY === newY;
});
if (colorBox) {
adjacentTiles.push(colorBox);
}
}
}
return adjacentTiles;
}
function colorBoxClicked(b) {
console.log('colorbox clicked:', b);
// Find connected tiles with same color
var t = findConnectedSameColorTiles(b);
//console.log(t);
for (var i = 0; i < t.length; i++) {
//t[i].destroy();
t[i].remove(i * 30);
}
}
function placeOutliers() {
// Determine colors left on the board to choose from.
var colorsPresent = [];
var gridSize = currentLevel.length;
for (var i = 0; i < gridSize; i++) {
for (var j = 0; j < gridSize; j++) {
var t = currentLevel[i][j];
if (t != 0 && !colorsPresent.includes(t)) {
colorsPresent.push(t);
}
}
}
console.log('Game still includes these colors:', colorsPresent);
// Determine what rows and cols contain colorboxes.
// Horizontal rows
var availableRows = [];
for (var i = 0; i < gridSize; i++) {
if (currentLevel[i].some(checkNonZero)) {
console.log('there are non-zero values in row:', i);
availableRows.push(i);
}
}
// Vertical columns
var availableCols = [];
var cols = rotateMatrix90C(currentLevel);
for (var i = 0; i < gridSize; i++) {
if (cols[i].some(checkNonZero)) {
console.log('there are non-zero values in col:', i);
availableCols.push(i);
}
}
// If no available rows or cols left, level cleared!
var n = availableRows.length + availableCols.length;
console.log(n);
if (n === 0) {
console.log('level cleared. TODO: write level cleared function.');
} else {
var startX = -boardSize / 2;
var startY = -boardSize / 2;
var boxSize = tileSize;
var boxSpacing = boxSize * spacingRatio;
var offset = boxSize / 2 + boxSpacing;
// Place an outlier tile at 50% (and minimum one) of the available positions.
var placedAtLeastOne = false;
//console.log('ac:', availableCols);
availableCols = shuffleArray(availableCols);
availableRows = shuffleArray(availableRows);
//console.log('ac:', availableCols);
var currentDirection = outlierDirectionCounter % 4;
outlierDirectionCounter++; // increment, so we get a new direction next turn.
if (currentDirection == 1 || currentDirection == 3) {
for (var i = 0; i < availableRows.length; i++) {
//if (Math.random() < 0.5 || !placedAtLeastOne) {
if (true || !placedAtLeastOne) {
// place it, either side will do.
var cIndex = colorsPresent[Math.floor(Math.random() * colorsPresent.length)];
var b = new ColorBox(cIndex);
b.outlier = true;
b.width = b.height = tileSize;
if (currentDirection == 3) {
b.x = -900;
b.y = offset + startY + availableRows[i] * (boxSize + boxSpacing);
b.gridX = -1;
b.gridY = availableRows[i];
} else {
b.x = 900;
b.y = offset + startY + availableRows[i] * (boxSize + boxSpacing);
b.gridX = 99;
b.gridY = availableRows[i];
}
b.fadeIn();
//console.log('b is:', b);
levelContainer.addChild(b);
//console.log('levelContainer is now:', levelContainer);
placedAtLeastOne = true;
}
}
} else {
for (var i = 0; i < availableCols.length; i++) {
//if (Math.random() < 0.5 || !placedAtLeastOne) {
if (true || !placedAtLeastOne) {
// place it, either side will do
var cIndex = colorsPresent[Math.floor(Math.random() * colorsPresent.length)];
var b = new ColorBox(cIndex);
b.outlier = true;
b.width = b.height = tileSize;
if (currentDirection == 0) {
b.x = offset + startX + availableCols[i] * (boxSize + boxSpacing);
b.y = -900;
b.gridX = availableCols[i];
//console.log(availableCols[i]);
b.gridY = -1;
} else {
b.x = offset + startX + availableCols[i] * (boxSize + boxSpacing);
b.y = 900;
b.gridX = availableCols[i];
b.gridY = 99;
}
b.fadeIn();
//console.log('b is:', b);
levelContainer.addChild(b);
//console.log('levelContainer is now:', levelContainer);
placedAtLeastOne = true;
}
}
}
}
// And place them. (Animate them in from sides.)
console.log(tween);
}
function shuffleArray(arr) {
var j, x, index;
for (index = arr.length - 1; index > 0; index--) {
j = Math.floor(Math.random() * (index + 1));
x = arr[index];
arr[index] = arr[j];
arr[j] = x;
}
return arr;
}
function checkNonZero(i) {
return i != 0;
}
function rotateMatrix90C(source) {
// get the dimensions of the source matrix
var m = source.length;
var n = source[0].length;
// create a new NxM destination array
var destination = new Array(n);
for (var i = 0; i < n; i++) {
destination[i] = new Array(m);
}
// start copying from source into destination
for (var i = 0; i < n; i++) {
for (var j = 0; j < m; j++) {
destination[i][j] = source[m - j - 1][i];
}
}
// return the destination matrix
return destination;
}
placeOutliers();
function moveIn() {
// Move all outliers onto stage
var outliers = levelContainer.children.filter(function (child) {
return child.outlier;
});
console.log('there are ', outliers.length, 'outliers');
for (var i = 0; i < outliers.length; i++) {
var t = outliers[i];
//console.log(t);
var newPos;
// Determine direction the outlier is moving in, in order to determine position to tween to.
if (t.gridX == -1) {
// do something
} else if (t.gridX == 99) {
// do something
} else if (t.gridY == -1) {
newPos = gridSize;
for (var j = gridSize - 1; j >= 0; j--) {
console.log('j entry is', currentLevel[j][t.gridX]);
if (currentLevel[j][t.gridX] != 0) {
newPos = j - 1;
}
}
console.log(t, 'would move to position', newPos);
t.gridY = newPos;
t.moveInPosition();
} else if (t.gridY == 99) {
// do something
}
}
// Once in place, add them to currentLevel object. (or delete if flown ofscreen)
}
moveIn();
game.update = function () {
if (LK.ticks % 12 == 0) {
//console.log(numRunningTweens);
if (numRunningTweens > 0) {
GAME_IS_CLICKABLE = false;
} else {
GAME_IS_CLICKABLE = true;
}
}
};
A large calm background drawing for a puzzle game, in dark calm blueish colors and non-confusing content. High definition. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
A quadratic polished dark blue marble slate. Front perspective with right angles. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
A white question mark in a circle, like for a help button in a game.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
A white X in a circle, like for a close window button in a game. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
A white questionmark on a black background. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
A green check mark on a dark background. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.