/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
highScore: 0,
currentLevel: 1
});
/****
* Classes
****/
var AdElement = Container.expand(function (type, row, col) {
var self = Container.call(this);
self.type = type;
self.row = row;
self.col = col;
self.isPowerup = false;
var assetId;
switch (type) {
case 'social':
assetId = 'adSocial';
break;
case 'print':
assetId = 'adPrint';
break;
case 'tv':
assetId = 'adTV';
break;
case 'billboard':
assetId = 'adBillboard';
break;
case 'viral':
assetId = 'powerupViral';
self.isPowerup = true;
break;
case 'targeted':
assetId = 'powerupTargeted';
self.isPowerup = true;
break;
default:
assetId = 'adSocial';
}
var graphic = self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.9,
scaleY: 0.9
});
self.setGridPosition = function (newRow, newCol) {
self.row = newRow;
self.col = newCol;
self.x = GRID_OFFSET_X + newCol * CELL_SIZE + CELL_SIZE / 2;
self.y = GRID_OFFSET_Y + newRow * CELL_SIZE + CELL_SIZE / 2;
};
self.highlight = function () {
tween(graphic, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 200
});
};
self.unhighlight = function () {
tween(graphic, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 200
});
};
self.explode = function () {
tween(graphic, {
alpha: 0,
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 300,
onFinish: function onFinish() {
self.destroy();
}
});
};
self.down = function (x, y, obj) {
selectAdElement(self);
};
return self;
});
var ClientBrief = Container.expand(function (targetType, count) {
var self = Container.call(this);
self.targetType = targetType;
self.requiredCount = count;
self.currentCount = 0;
var assetId;
switch (targetType) {
case 'social':
assetId = 'adSocial';
break;
case 'print':
assetId = 'adPrint';
break;
case 'tv':
assetId = 'adTV';
break;
case 'billboard':
assetId = 'adBillboard';
break;
default:
assetId = 'adSocial';
}
var icon = self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 0,
scaleX: 0.6,
scaleY: 0.6
});
var progressText = new Text2('0/' + count, {
size: 40,
fill: 0x333333
});
progressText.anchor.set(0, 0.5);
progressText.x = 50;
progressText.y = 0;
self.addChild(progressText);
self.updateProgress = function (matched) {
if (matched && self.targetType === matched) {
self.currentCount++;
if (self.currentCount > self.requiredCount) {
self.currentCount = self.requiredCount;
}
progressText.setText(self.currentCount + '/' + self.requiredCount);
if (self.isComplete()) {
tween(icon, {
scaleX: 0.8,
scaleY: 0.8
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(icon, {
scaleX: 0.6,
scaleY: 0.6
}, {
duration: 200,
easing: tween.easeIn
});
}
});
}
}
};
self.isComplete = function () {
return self.currentCount >= self.requiredCount;
};
return self;
});
var GridCell = Container.expand(function (row, col) {
var self = Container.call(this);
self.row = row;
self.col = col;
self.isHighlighted = false;
var background = self.attachAsset('cellBackground', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.3
});
self.setPosition = function () {
self.x = GRID_OFFSET_X + col * CELL_SIZE + CELL_SIZE / 2;
self.y = GRID_OFFSET_Y + row * CELL_SIZE + CELL_SIZE / 2;
};
self.highlight = function () {
if (!self.isHighlighted) {
self.isHighlighted = true;
tween(background, {
alpha: 0.6
}, {
duration: 200
});
}
};
self.unhighlight = function () {
if (self.isHighlighted) {
self.isHighlighted = false;
tween(background, {
alpha: 0.3
}, {
duration: 200
});
}
};
self.setPosition();
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xf5f5f5
});
/****
* Game Code
****/
// Constants
var GRID_SIZE = 6;
var CELL_SIZE = 180;
var GRID_OFFSET_X = (2048 - GRID_SIZE * CELL_SIZE) / 2;
var GRID_OFFSET_Y = 500;
var MATCH_MIN = 3;
var AD_TYPES = ['social', 'print', 'tv', 'billboard'];
// Game variables
var grid = [];
var gridCells = [];
var adElements = [];
var selectedElement = null;
var moveCount = 30;
var score = 0;
var level = storage.currentLevel || 1;
var clientBriefs = [];
var gameActive = true;
// UI Elements
var gridBackground = LK.getAsset('gridBackground', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: GRID_SIZE * CELL_SIZE / 1100,
scaleY: GRID_SIZE * CELL_SIZE / 1100,
alpha: 0.5
});
gridBackground.x = GRID_OFFSET_X + GRID_SIZE * CELL_SIZE / 2;
gridBackground.y = GRID_OFFSET_Y + GRID_SIZE * CELL_SIZE / 2;
game.addChild(gridBackground);
var titleText = new Text2("Ad Story Blast", {
size: 130,
fill: 0x333333
});
titleText.anchor.set(0.5, 0);
titleText.x = 2048 / 2;
titleText.y = 80;
game.addChild(titleText);
var levelText = new Text2("Level: " + level, {
size: 60,
fill: 0x333333
});
levelText.anchor.set(0, 0);
levelText.x = 150;
levelText.y = 250;
game.addChild(levelText);
var scoreText = new Text2("Score: 0", {
size: 60,
fill: 0x333333
});
scoreText.anchor.set(0, 0);
scoreText.x = 150;
scoreText.y = 320;
game.addChild(scoreText);
var moveText = new Text2("Moves: " + moveCount, {
size: 60,
fill: 0x333333
});
moveText.anchor.set(1, 0);
moveText.x = 2048 - 150;
moveText.y = 250;
game.addChild(moveText);
var briefsTitle = new Text2("Client Briefs:", {
size: 60,
fill: 0x333333
});
briefsTitle.anchor.set(0, 0);
briefsTitle.x = 150;
briefsTitle.y = GRID_OFFSET_Y + GRID_SIZE * CELL_SIZE + 80;
game.addChild(briefsTitle);
var selectedOutline = LK.getAsset('selectedOutline', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.8
});
selectedOutline.visible = false;
game.addChild(selectedOutline);
// Functions
function initializeGrid() {
// Create grid cells
for (var row = 0; row < GRID_SIZE; row++) {
gridCells[row] = [];
for (var col = 0; col < GRID_SIZE; col++) {
var cell = new GridCell(row, col);
gridCells[row][col] = cell;
game.addChild(cell);
}
}
// Create empty grid
for (var row = 0; row < GRID_SIZE; row++) {
grid[row] = [];
for (var col = 0; col < GRID_SIZE; col++) {
grid[row][col] = null;
}
}
// Fill grid with ad elements
fillGrid();
}
function fillGrid() {
for (var row = 0; row < GRID_SIZE; row++) {
for (var col = 0; col < GRID_SIZE; col++) {
if (grid[row][col] === null) {
createAdElement(row, col);
}
}
}
// Check for initial matches and refill if needed
var initialMatches = findAllMatches();
if (initialMatches.length > 0) {
for (var i = 0; i < initialMatches.length; i++) {
for (var j = 0; j < initialMatches[i].length; j++) {
var element = initialMatches[i][j];
grid[element.row][element.col] = null;
element.destroy();
}
}
fillGrid();
}
}
function createAdElement(row, col) {
// Get random ad type
var typeIndex = Math.floor(Math.random() * AD_TYPES.length);
var type = AD_TYPES[typeIndex];
// Avoid creating three in a row initially
if (row >= 2) {
var prevType1 = grid[row - 1][col] ? grid[row - 1][col].type : null;
var prevType2 = grid[row - 2][col] ? grid[row - 2][col].type : null;
if (prevType1 === type && prevType2 === type) {
// Choose a different type
do {
typeIndex = Math.floor(Math.random() * AD_TYPES.length);
type = AD_TYPES[typeIndex];
} while (type === prevType1);
}
}
if (col >= 2) {
var prevType1 = grid[row][col - 1] ? grid[row][col - 1].type : null;
var prevType2 = grid[row][col - 2] ? grid[row][col - 2].type : null;
if (prevType1 === type && prevType2 === type) {
// Choose a different type
do {
typeIndex = Math.floor(Math.random() * AD_TYPES.length);
type = AD_TYPES[typeIndex];
} while (type === prevType1);
}
}
var adElement = new AdElement(type, row, col);
adElement.setGridPosition(row, col);
grid[row][col] = adElement;
adElements.push(adElement);
game.addChild(adElement);
return adElement;
}
function selectAdElement(element) {
if (!gameActive) {
return;
}
if (selectedElement === null) {
// First selection
selectedElement = element;
selectedElement.highlight();
selectedOutline.x = selectedElement.x;
selectedOutline.y = selectedElement.y;
selectedOutline.visible = true;
} else if (selectedElement === element) {
// Deselect
selectedElement.unhighlight();
selectedElement = null;
selectedOutline.visible = false;
} else {
// Check if adjacent
if (areAdjacent(selectedElement, element)) {
// Swap elements
swapElements(selectedElement, element);
} else {
// Not adjacent, change selection
selectedElement.unhighlight();
selectedElement = element;
selectedElement.highlight();
selectedOutline.x = selectedElement.x;
selectedOutline.y = selectedElement.y;
}
}
}
function areAdjacent(elem1, elem2) {
// Check if two elements are adjacent in the grid
var rowDiff = Math.abs(elem1.row - elem2.row);
var colDiff = Math.abs(elem1.col - elem2.col);
return rowDiff === 1 && colDiff === 0 || rowDiff === 0 && colDiff === 1;
}
function swapElements(elem1, elem2) {
// Store original positions
var row1 = elem1.row;
var col1 = elem1.col;
var row2 = elem2.row;
var col2 = elem2.col;
// Update grid references
grid[row1][col1] = elem2;
grid[row2][col2] = elem1;
// Update element positions
elem1.setGridPosition(row2, col2);
elem2.setGridPosition(row1, col1);
// Animate the swap
tween(elem1, {
x: GRID_OFFSET_X + col2 * CELL_SIZE + CELL_SIZE / 2,
y: GRID_OFFSET_Y + row2 * CELL_SIZE + CELL_SIZE / 2
}, {
duration: 200
});
tween(elem2, {
x: GRID_OFFSET_X + col1 * CELL_SIZE + CELL_SIZE / 2,
y: GRID_OFFSET_Y + row1 * CELL_SIZE + CELL_SIZE / 2
}, {
duration: 200,
onFinish: function onFinish() {
// Reset selection
elem1.unhighlight();
selectedElement = null;
selectedOutline.visible = false;
// Check for matches
var matches = findAllMatches();
if (matches.length > 0) {
// Valid move
decrementMoves();
processMatches(matches);
} else {
// Invalid move, swap back
grid[row1][col1] = elem1;
grid[row2][col2] = elem2;
elem1.setGridPosition(row1, col1);
elem2.setGridPosition(row2, col2);
tween(elem1, {
x: GRID_OFFSET_X + col1 * CELL_SIZE + CELL_SIZE / 2,
y: GRID_OFFSET_Y + row1 * CELL_SIZE + CELL_SIZE / 2
}, {
duration: 200
});
tween(elem2, {
x: GRID_OFFSET_X + col2 * CELL_SIZE + CELL_SIZE / 2,
y: GRID_OFFSET_Y + row2 * CELL_SIZE + CELL_SIZE / 2
}, {
duration: 200
});
}
}
});
}
function findAllMatches() {
var allMatches = [];
// Check horizontal matches
for (var row = 0; row < GRID_SIZE; row++) {
var col = 0;
while (col < GRID_SIZE - 2) {
var matchLength = 1;
var currentType = grid[row][col] ? grid[row][col].type : null;
if (currentType) {
// Count matching adjacent elements
while (col + matchLength < GRID_SIZE && grid[row][col + matchLength] && grid[row][col + matchLength].type === currentType) {
matchLength++;
}
// If we have a match of at least 3
if (matchLength >= MATCH_MIN) {
var match = [];
for (var i = 0; i < matchLength; i++) {
match.push(grid[row][col + i]);
}
allMatches.push(match);
col += matchLength;
} else {
col++;
}
} else {
col++;
}
}
}
// Check vertical matches
for (var col = 0; col < GRID_SIZE; col++) {
var row = 0;
while (row < GRID_SIZE - 2) {
var matchLength = 1;
var currentType = grid[row][col] ? grid[row][col].type : null;
if (currentType) {
// Count matching adjacent elements
while (row + matchLength < GRID_SIZE && grid[row + matchLength][col] && grid[row + matchLength][col].type === currentType) {
matchLength++;
}
// If we have a match of at least 3
if (matchLength >= MATCH_MIN) {
var match = [];
for (var i = 0; i < matchLength; i++) {
match.push(grid[row + i][col]);
}
allMatches.push(match);
row += matchLength;
} else {
row++;
}
} else {
row++;
}
}
}
return allMatches;
}
function processMatches(matches) {
// Play sound
LK.getSound('match').play();
// Calculate points and remove matched elements
var pointsEarned = 0;
var matchedTypes = {};
for (var i = 0; i < matches.length; i++) {
var match = matches[i];
var matchType = match[0].type;
var matchSize = match.length;
// Keep track of matched types for client briefs
if (!matchedTypes[matchType]) {
matchedTypes[matchType] = 0;
}
matchedTypes[matchType] += matchSize;
// Calculate points (more points for larger matches)
var matchPoints = 10 * matchSize;
pointsEarned += matchPoints;
// Create powerup for matches of 4 or more
var createPowerup = false;
var powerupType = null;
var powerupRow = null;
var powerupCol = null;
if (matchSize >= 4) {
createPowerup = true;
powerupType = matchSize >= 5 ? 'viral' : 'targeted';
// Use middle element position for powerup
var middleIndex = Math.floor(matchSize / 2);
powerupRow = match[middleIndex].row;
powerupCol = match[middleIndex].col;
}
// Remove matched elements
for (var j = 0; j < matchSize; j++) {
var element = match[j];
var elementIndex = adElements.indexOf(element);
if (elementIndex !== -1) {
adElements.splice(elementIndex, 1);
}
grid[element.row][element.col] = null;
element.explode();
}
// Create powerup if needed
if (createPowerup) {
// Wait for animations to complete
LK.setTimeout(function (row, col, type) {
return function () {
var powerup = new AdElement(type, row, col);
powerup.setGridPosition(row, col);
grid[row][col] = powerup;
adElements.push(powerup);
game.addChild(powerup);
LK.getSound('powerup').play();
};
}(powerupRow, powerupCol, powerupType), 300);
}
}
// Update score
updateScore(pointsEarned);
// Update client briefs
for (var type in matchedTypes) {
if (matchedTypes.hasOwnProperty(type) && AD_TYPES.indexOf(type) !== -1) {
updateClientBriefs(type);
}
}
// Check if all briefs are completed
checkBriefsCompleted();
// After a delay, collapse the grid and refill
LK.setTimeout(function () {
collapseGrid();
}, 400);
}
function processPowerup(powerup, targetElement) {
var elementsToRemove = [];
if (powerup.type === 'viral') {
// Viral powerup: clear entire row and column
for (var col = 0; col < GRID_SIZE; col++) {
if (grid[powerup.row][col] && grid[powerup.row][col] !== powerup) {
elementsToRemove.push(grid[powerup.row][col]);
}
}
for (var row = 0; row < GRID_SIZE; row++) {
if (grid[row][powerup.col] && grid[row][powerup.col] !== powerup && elementsToRemove.indexOf(grid[row][powerup.col]) === -1) {
elementsToRemove.push(grid[row][powerup.col]);
}
}
} else if (powerup.type === 'targeted') {
// Targeted powerup: remove all elements of the same type as the target
var targetType = targetElement.type;
for (var row = 0; row < GRID_SIZE; row++) {
for (var col = 0; col < GRID_SIZE; col++) {
if (grid[row][col] && grid[row][col].type === targetType && !grid[row][col].isPowerup) {
elementsToRemove.push(grid[row][col]);
}
}
}
}
// Remove powerup
var powerupIndex = adElements.indexOf(powerup);
if (powerupIndex !== -1) {
adElements.splice(powerupIndex, 1);
}
grid[powerup.row][powerup.col] = null;
powerup.explode();
// Remove affected elements
for (var i = 0; i < elementsToRemove.length; i++) {
var element = elementsToRemove[i];
var elementIndex = adElements.indexOf(element);
if (elementIndex !== -1) {
adElements.splice(elementIndex, 1);
}
// Track matched types for client briefs
if (AD_TYPES.indexOf(element.type) !== -1) {
updateClientBriefs(element.type);
}
grid[element.row][element.col] = null;
element.explode();
}
// Update score
updateScore(elementsToRemove.length * 15);
// Play powerup sound
LK.getSound('powerup').play();
// Check if all briefs are completed
checkBriefsCompleted();
// After a delay, collapse the grid and refill
LK.setTimeout(function () {
collapseGrid();
}, 400);
}
function collapseGrid() {
var elementsMoved = false;
// Move elements down to fill empty spaces
for (var col = 0; col < GRID_SIZE; col++) {
var emptySpaces = 0;
for (var row = GRID_SIZE - 1; row >= 0; row--) {
if (grid[row][col] === null) {
emptySpaces++;
} else if (emptySpaces > 0) {
// Move element down
var element = grid[row][col];
var newRow = row + emptySpaces;
grid[newRow][col] = element;
grid[row][col] = null;
// Animate the movement
element.setGridPosition(newRow, col);
tween(element, {
y: GRID_OFFSET_Y + newRow * CELL_SIZE + CELL_SIZE / 2
}, {
duration: 300
});
elementsMoved = true;
}
}
}
// Refill the grid from the top
LK.setTimeout(function () {
// Create new elements for empty spaces at the top
for (var col = 0; col < GRID_SIZE; col++) {
for (var row = 0; row < GRID_SIZE; row++) {
if (grid[row][col] === null) {
var newElement = createAdElement(row, col);
// Start from above the grid
newElement.y = GRID_OFFSET_Y + (row - GRID_SIZE) * CELL_SIZE + CELL_SIZE / 2;
// Animate falling in
tween(newElement, {
y: GRID_OFFSET_Y + row * CELL_SIZE + CELL_SIZE / 2
}, {
duration: 300
});
}
}
}
// Check for new matches after the grid is refilled
LK.setTimeout(function () {
var newMatches = findAllMatches();
if (newMatches.length > 0) {
processMatches(newMatches);
} else {
// Check if there are possible moves
if (!hasPossibleMoves()) {
// No moves left, shuffle the grid
shuffleGrid();
}
}
}, 400);
}, elementsMoved ? 300 : 0);
}
function shuffleGrid() {
// Collect all current elements
var allElements = [];
for (var row = 0; row < GRID_SIZE; row++) {
for (var col = 0; col < GRID_SIZE; col++) {
if (grid[row][col]) {
allElements.push({
type: grid[row][col].type,
isPowerup: grid[row][col].isPowerup
});
// Remove from grid
grid[row][col].destroy();
grid[row][col] = null;
}
}
}
// Clear adElements array
adElements = [];
// Shuffle the elements
for (var i = allElements.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = allElements[i];
allElements[i] = allElements[j];
allElements[j] = temp;
}
// Refill the grid with shuffled elements
var elementIndex = 0;
for (var row = 0; row < GRID_SIZE; row++) {
for (var col = 0; col < GRID_SIZE; col++) {
if (elementIndex < allElements.length) {
var element = new AdElement(allElements[elementIndex].type, row, col);
element.setGridPosition(row, col);
grid[row][col] = element;
adElements.push(element);
game.addChild(element);
elementIndex++;
} else {
// In case we need more elements
createAdElement(row, col);
}
}
}
// Check for matches after shuffling
var newMatches = findAllMatches();
if (newMatches.length > 0) {
// If we have matches, process them
LK.setTimeout(function () {
processMatches(newMatches);
}, 500);
}
}
function hasPossibleMoves() {
// Check for possible moves horizontally
for (var row = 0; row < GRID_SIZE; row++) {
for (var col = 0; col < GRID_SIZE - 1; col++) {
// Swap adjacent elements
var temp = grid[row][col];
grid[row][col] = grid[row][col + 1];
grid[row][col + 1] = temp;
// Check for matches
var matches = findAllMatches();
// Swap back
temp = grid[row][col];
grid[row][col] = grid[row][col + 1];
grid[row][col + 1] = temp;
if (matches.length > 0) {
return true;
}
}
}
// Check for possible moves vertically
for (var row = 0; row < GRID_SIZE - 1; row++) {
for (var col = 0; col < GRID_SIZE; col++) {
// Swap adjacent elements
var temp = grid[row][col];
grid[row][col] = grid[row + 1][col];
grid[row + 1][col] = temp;
// Check for matches
var matches = findAllMatches();
// Swap back
temp = grid[row][col];
grid[row][col] = grid[row + 1][col];
grid[row + 1][col] = temp;
if (matches.length > 0) {
return true;
}
}
}
return false;
}
function updateScore(points) {
score += points;
scoreText.setText("Score: " + score);
}
function decrementMoves() {
moveCount--;
moveText.setText("Moves: " + moveCount);
if (moveCount <= 0) {
// Game over if no more moves
gameActive = false;
// Wait a bit before showing game over
LK.setTimeout(function () {
if (score > storage.highScore) {
storage.highScore = score;
}
LK.setScore(score);
LK.showGameOver();
}, 1000);
}
}
function initializeClientBriefs() {
// Clear existing briefs
for (var i = 0; i < clientBriefs.length; i++) {
clientBriefs[i].destroy();
}
clientBriefs = [];
// Create new client briefs based on level
var briefsCount = Math.min(3, level + 1);
var briefsComplexity = Math.floor(level * 1.5) + 5;
var targetTypes = [];
// Select random unique ad types for briefs
var availableTypes = [].concat(AD_TYPES);
for (var i = 0; i < briefsCount; i++) {
if (availableTypes.length === 0) {
break;
}
var index = Math.floor(Math.random() * availableTypes.length);
targetTypes.push(availableTypes[index]);
availableTypes.splice(index, 1);
}
// Create brief objects
for (var i = 0; i < targetTypes.length; i++) {
var count = briefsComplexity + Math.floor(Math.random() * 5);
var brief = new ClientBrief(targetTypes[i], count);
brief.x = 400 + i * 400;
brief.y = GRID_OFFSET_Y + GRID_SIZE * CELL_SIZE + 160;
clientBriefs.push(brief);
game.addChild(brief);
}
}
function updateClientBriefs(matchedType) {
for (var i = 0; i < clientBriefs.length; i++) {
clientBriefs[i].updateProgress(matchedType);
}
}
function checkBriefsCompleted() {
var allCompleted = true;
for (var i = 0; i < clientBriefs.length; i++) {
if (!clientBriefs[i].isComplete()) {
allCompleted = false;
break;
}
}
if (allCompleted && clientBriefs.length > 0 && gameActive) {
// Level completed
gameActive = false;
// Play celebration sound
LK.getSound('briefComplete').play();
// Update level
level++;
storage.currentLevel = level;
// Add bonus points
var levelBonus = level * 100;
updateScore(levelBonus);
// Add move bonus
var moveBonus = moveCount * 20;
updateScore(moveBonus);
// Show level complete and continue
LK.setTimeout(function () {
LK.setScore(score);
LK.showYouWin();
}, 1200);
}
}
// Initialize game
initializeGrid();
initializeClientBriefs();
// Play background music
LK.playMusic('bgmusic', {
fade: {
start: 0,
end: 0.4,
duration: 1000
}
}); ===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,880 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+var storage = LK.import("@upit/storage.v1", {
+ highScore: 0,
+ currentLevel: 1
+});
+
+/****
+* Classes
+****/
+var AdElement = Container.expand(function (type, row, col) {
+ var self = Container.call(this);
+ self.type = type;
+ self.row = row;
+ self.col = col;
+ self.isPowerup = false;
+ var assetId;
+ switch (type) {
+ case 'social':
+ assetId = 'adSocial';
+ break;
+ case 'print':
+ assetId = 'adPrint';
+ break;
+ case 'tv':
+ assetId = 'adTV';
+ break;
+ case 'billboard':
+ assetId = 'adBillboard';
+ break;
+ case 'viral':
+ assetId = 'powerupViral';
+ self.isPowerup = true;
+ break;
+ case 'targeted':
+ assetId = 'powerupTargeted';
+ self.isPowerup = true;
+ break;
+ default:
+ assetId = 'adSocial';
+ }
+ var graphic = self.attachAsset(assetId, {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 0.9,
+ scaleY: 0.9
+ });
+ self.setGridPosition = function (newRow, newCol) {
+ self.row = newRow;
+ self.col = newCol;
+ self.x = GRID_OFFSET_X + newCol * CELL_SIZE + CELL_SIZE / 2;
+ self.y = GRID_OFFSET_Y + newRow * CELL_SIZE + CELL_SIZE / 2;
+ };
+ self.highlight = function () {
+ tween(graphic, {
+ scaleX: 1.1,
+ scaleY: 1.1
+ }, {
+ duration: 200
+ });
+ };
+ self.unhighlight = function () {
+ tween(graphic, {
+ scaleX: 0.9,
+ scaleY: 0.9
+ }, {
+ duration: 200
+ });
+ };
+ self.explode = function () {
+ tween(graphic, {
+ alpha: 0,
+ scaleX: 1.5,
+ scaleY: 1.5
+ }, {
+ duration: 300,
+ onFinish: function onFinish() {
+ self.destroy();
+ }
+ });
+ };
+ self.down = function (x, y, obj) {
+ selectAdElement(self);
+ };
+ return self;
+});
+var ClientBrief = Container.expand(function (targetType, count) {
+ var self = Container.call(this);
+ self.targetType = targetType;
+ self.requiredCount = count;
+ self.currentCount = 0;
+ var assetId;
+ switch (targetType) {
+ case 'social':
+ assetId = 'adSocial';
+ break;
+ case 'print':
+ assetId = 'adPrint';
+ break;
+ case 'tv':
+ assetId = 'adTV';
+ break;
+ case 'billboard':
+ assetId = 'adBillboard';
+ break;
+ default:
+ assetId = 'adSocial';
+ }
+ var icon = self.attachAsset(assetId, {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: 0,
+ y: 0,
+ scaleX: 0.6,
+ scaleY: 0.6
+ });
+ var progressText = new Text2('0/' + count, {
+ size: 40,
+ fill: 0x333333
+ });
+ progressText.anchor.set(0, 0.5);
+ progressText.x = 50;
+ progressText.y = 0;
+ self.addChild(progressText);
+ self.updateProgress = function (matched) {
+ if (matched && self.targetType === matched) {
+ self.currentCount++;
+ if (self.currentCount > self.requiredCount) {
+ self.currentCount = self.requiredCount;
+ }
+ progressText.setText(self.currentCount + '/' + self.requiredCount);
+ if (self.isComplete()) {
+ tween(icon, {
+ scaleX: 0.8,
+ scaleY: 0.8
+ }, {
+ duration: 200,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ tween(icon, {
+ scaleX: 0.6,
+ scaleY: 0.6
+ }, {
+ duration: 200,
+ easing: tween.easeIn
+ });
+ }
+ });
+ }
+ }
+ };
+ self.isComplete = function () {
+ return self.currentCount >= self.requiredCount;
+ };
+ return self;
+});
+var GridCell = Container.expand(function (row, col) {
+ var self = Container.call(this);
+ self.row = row;
+ self.col = col;
+ self.isHighlighted = false;
+ var background = self.attachAsset('cellBackground', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ alpha: 0.3
+ });
+ self.setPosition = function () {
+ self.x = GRID_OFFSET_X + col * CELL_SIZE + CELL_SIZE / 2;
+ self.y = GRID_OFFSET_Y + row * CELL_SIZE + CELL_SIZE / 2;
+ };
+ self.highlight = function () {
+ if (!self.isHighlighted) {
+ self.isHighlighted = true;
+ tween(background, {
+ alpha: 0.6
+ }, {
+ duration: 200
+ });
+ }
+ };
+ self.unhighlight = function () {
+ if (self.isHighlighted) {
+ self.isHighlighted = false;
+ tween(background, {
+ alpha: 0.3
+ }, {
+ duration: 200
+ });
+ }
+ };
+ self.setPosition();
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
+ backgroundColor: 0xf5f5f5
+});
+
+/****
+* Game Code
+****/
+// Constants
+var GRID_SIZE = 6;
+var CELL_SIZE = 180;
+var GRID_OFFSET_X = (2048 - GRID_SIZE * CELL_SIZE) / 2;
+var GRID_OFFSET_Y = 500;
+var MATCH_MIN = 3;
+var AD_TYPES = ['social', 'print', 'tv', 'billboard'];
+// Game variables
+var grid = [];
+var gridCells = [];
+var adElements = [];
+var selectedElement = null;
+var moveCount = 30;
+var score = 0;
+var level = storage.currentLevel || 1;
+var clientBriefs = [];
+var gameActive = true;
+// UI Elements
+var gridBackground = LK.getAsset('gridBackground', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: GRID_SIZE * CELL_SIZE / 1100,
+ scaleY: GRID_SIZE * CELL_SIZE / 1100,
+ alpha: 0.5
+});
+gridBackground.x = GRID_OFFSET_X + GRID_SIZE * CELL_SIZE / 2;
+gridBackground.y = GRID_OFFSET_Y + GRID_SIZE * CELL_SIZE / 2;
+game.addChild(gridBackground);
+var titleText = new Text2("Ad Story Blast", {
+ size: 130,
+ fill: 0x333333
+});
+titleText.anchor.set(0.5, 0);
+titleText.x = 2048 / 2;
+titleText.y = 80;
+game.addChild(titleText);
+var levelText = new Text2("Level: " + level, {
+ size: 60,
+ fill: 0x333333
+});
+levelText.anchor.set(0, 0);
+levelText.x = 150;
+levelText.y = 250;
+game.addChild(levelText);
+var scoreText = new Text2("Score: 0", {
+ size: 60,
+ fill: 0x333333
+});
+scoreText.anchor.set(0, 0);
+scoreText.x = 150;
+scoreText.y = 320;
+game.addChild(scoreText);
+var moveText = new Text2("Moves: " + moveCount, {
+ size: 60,
+ fill: 0x333333
+});
+moveText.anchor.set(1, 0);
+moveText.x = 2048 - 150;
+moveText.y = 250;
+game.addChild(moveText);
+var briefsTitle = new Text2("Client Briefs:", {
+ size: 60,
+ fill: 0x333333
+});
+briefsTitle.anchor.set(0, 0);
+briefsTitle.x = 150;
+briefsTitle.y = GRID_OFFSET_Y + GRID_SIZE * CELL_SIZE + 80;
+game.addChild(briefsTitle);
+var selectedOutline = LK.getAsset('selectedOutline', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ alpha: 0.8
+});
+selectedOutline.visible = false;
+game.addChild(selectedOutline);
+// Functions
+function initializeGrid() {
+ // Create grid cells
+ for (var row = 0; row < GRID_SIZE; row++) {
+ gridCells[row] = [];
+ for (var col = 0; col < GRID_SIZE; col++) {
+ var cell = new GridCell(row, col);
+ gridCells[row][col] = cell;
+ game.addChild(cell);
+ }
+ }
+ // Create empty grid
+ for (var row = 0; row < GRID_SIZE; row++) {
+ grid[row] = [];
+ for (var col = 0; col < GRID_SIZE; col++) {
+ grid[row][col] = null;
+ }
+ }
+ // Fill grid with ad elements
+ fillGrid();
+}
+function fillGrid() {
+ for (var row = 0; row < GRID_SIZE; row++) {
+ for (var col = 0; col < GRID_SIZE; col++) {
+ if (grid[row][col] === null) {
+ createAdElement(row, col);
+ }
+ }
+ }
+ // Check for initial matches and refill if needed
+ var initialMatches = findAllMatches();
+ if (initialMatches.length > 0) {
+ for (var i = 0; i < initialMatches.length; i++) {
+ for (var j = 0; j < initialMatches[i].length; j++) {
+ var element = initialMatches[i][j];
+ grid[element.row][element.col] = null;
+ element.destroy();
+ }
+ }
+ fillGrid();
+ }
+}
+function createAdElement(row, col) {
+ // Get random ad type
+ var typeIndex = Math.floor(Math.random() * AD_TYPES.length);
+ var type = AD_TYPES[typeIndex];
+ // Avoid creating three in a row initially
+ if (row >= 2) {
+ var prevType1 = grid[row - 1][col] ? grid[row - 1][col].type : null;
+ var prevType2 = grid[row - 2][col] ? grid[row - 2][col].type : null;
+ if (prevType1 === type && prevType2 === type) {
+ // Choose a different type
+ do {
+ typeIndex = Math.floor(Math.random() * AD_TYPES.length);
+ type = AD_TYPES[typeIndex];
+ } while (type === prevType1);
+ }
+ }
+ if (col >= 2) {
+ var prevType1 = grid[row][col - 1] ? grid[row][col - 1].type : null;
+ var prevType2 = grid[row][col - 2] ? grid[row][col - 2].type : null;
+ if (prevType1 === type && prevType2 === type) {
+ // Choose a different type
+ do {
+ typeIndex = Math.floor(Math.random() * AD_TYPES.length);
+ type = AD_TYPES[typeIndex];
+ } while (type === prevType1);
+ }
+ }
+ var adElement = new AdElement(type, row, col);
+ adElement.setGridPosition(row, col);
+ grid[row][col] = adElement;
+ adElements.push(adElement);
+ game.addChild(adElement);
+ return adElement;
+}
+function selectAdElement(element) {
+ if (!gameActive) {
+ return;
+ }
+ if (selectedElement === null) {
+ // First selection
+ selectedElement = element;
+ selectedElement.highlight();
+ selectedOutline.x = selectedElement.x;
+ selectedOutline.y = selectedElement.y;
+ selectedOutline.visible = true;
+ } else if (selectedElement === element) {
+ // Deselect
+ selectedElement.unhighlight();
+ selectedElement = null;
+ selectedOutline.visible = false;
+ } else {
+ // Check if adjacent
+ if (areAdjacent(selectedElement, element)) {
+ // Swap elements
+ swapElements(selectedElement, element);
+ } else {
+ // Not adjacent, change selection
+ selectedElement.unhighlight();
+ selectedElement = element;
+ selectedElement.highlight();
+ selectedOutline.x = selectedElement.x;
+ selectedOutline.y = selectedElement.y;
+ }
+ }
+}
+function areAdjacent(elem1, elem2) {
+ // Check if two elements are adjacent in the grid
+ var rowDiff = Math.abs(elem1.row - elem2.row);
+ var colDiff = Math.abs(elem1.col - elem2.col);
+ return rowDiff === 1 && colDiff === 0 || rowDiff === 0 && colDiff === 1;
+}
+function swapElements(elem1, elem2) {
+ // Store original positions
+ var row1 = elem1.row;
+ var col1 = elem1.col;
+ var row2 = elem2.row;
+ var col2 = elem2.col;
+ // Update grid references
+ grid[row1][col1] = elem2;
+ grid[row2][col2] = elem1;
+ // Update element positions
+ elem1.setGridPosition(row2, col2);
+ elem2.setGridPosition(row1, col1);
+ // Animate the swap
+ tween(elem1, {
+ x: GRID_OFFSET_X + col2 * CELL_SIZE + CELL_SIZE / 2,
+ y: GRID_OFFSET_Y + row2 * CELL_SIZE + CELL_SIZE / 2
+ }, {
+ duration: 200
+ });
+ tween(elem2, {
+ x: GRID_OFFSET_X + col1 * CELL_SIZE + CELL_SIZE / 2,
+ y: GRID_OFFSET_Y + row1 * CELL_SIZE + CELL_SIZE / 2
+ }, {
+ duration: 200,
+ onFinish: function onFinish() {
+ // Reset selection
+ elem1.unhighlight();
+ selectedElement = null;
+ selectedOutline.visible = false;
+ // Check for matches
+ var matches = findAllMatches();
+ if (matches.length > 0) {
+ // Valid move
+ decrementMoves();
+ processMatches(matches);
+ } else {
+ // Invalid move, swap back
+ grid[row1][col1] = elem1;
+ grid[row2][col2] = elem2;
+ elem1.setGridPosition(row1, col1);
+ elem2.setGridPosition(row2, col2);
+ tween(elem1, {
+ x: GRID_OFFSET_X + col1 * CELL_SIZE + CELL_SIZE / 2,
+ y: GRID_OFFSET_Y + row1 * CELL_SIZE + CELL_SIZE / 2
+ }, {
+ duration: 200
+ });
+ tween(elem2, {
+ x: GRID_OFFSET_X + col2 * CELL_SIZE + CELL_SIZE / 2,
+ y: GRID_OFFSET_Y + row2 * CELL_SIZE + CELL_SIZE / 2
+ }, {
+ duration: 200
+ });
+ }
+ }
+ });
+}
+function findAllMatches() {
+ var allMatches = [];
+ // Check horizontal matches
+ for (var row = 0; row < GRID_SIZE; row++) {
+ var col = 0;
+ while (col < GRID_SIZE - 2) {
+ var matchLength = 1;
+ var currentType = grid[row][col] ? grid[row][col].type : null;
+ if (currentType) {
+ // Count matching adjacent elements
+ while (col + matchLength < GRID_SIZE && grid[row][col + matchLength] && grid[row][col + matchLength].type === currentType) {
+ matchLength++;
+ }
+ // If we have a match of at least 3
+ if (matchLength >= MATCH_MIN) {
+ var match = [];
+ for (var i = 0; i < matchLength; i++) {
+ match.push(grid[row][col + i]);
+ }
+ allMatches.push(match);
+ col += matchLength;
+ } else {
+ col++;
+ }
+ } else {
+ col++;
+ }
+ }
+ }
+ // Check vertical matches
+ for (var col = 0; col < GRID_SIZE; col++) {
+ var row = 0;
+ while (row < GRID_SIZE - 2) {
+ var matchLength = 1;
+ var currentType = grid[row][col] ? grid[row][col].type : null;
+ if (currentType) {
+ // Count matching adjacent elements
+ while (row + matchLength < GRID_SIZE && grid[row + matchLength][col] && grid[row + matchLength][col].type === currentType) {
+ matchLength++;
+ }
+ // If we have a match of at least 3
+ if (matchLength >= MATCH_MIN) {
+ var match = [];
+ for (var i = 0; i < matchLength; i++) {
+ match.push(grid[row + i][col]);
+ }
+ allMatches.push(match);
+ row += matchLength;
+ } else {
+ row++;
+ }
+ } else {
+ row++;
+ }
+ }
+ }
+ return allMatches;
+}
+function processMatches(matches) {
+ // Play sound
+ LK.getSound('match').play();
+ // Calculate points and remove matched elements
+ var pointsEarned = 0;
+ var matchedTypes = {};
+ for (var i = 0; i < matches.length; i++) {
+ var match = matches[i];
+ var matchType = match[0].type;
+ var matchSize = match.length;
+ // Keep track of matched types for client briefs
+ if (!matchedTypes[matchType]) {
+ matchedTypes[matchType] = 0;
+ }
+ matchedTypes[matchType] += matchSize;
+ // Calculate points (more points for larger matches)
+ var matchPoints = 10 * matchSize;
+ pointsEarned += matchPoints;
+ // Create powerup for matches of 4 or more
+ var createPowerup = false;
+ var powerupType = null;
+ var powerupRow = null;
+ var powerupCol = null;
+ if (matchSize >= 4) {
+ createPowerup = true;
+ powerupType = matchSize >= 5 ? 'viral' : 'targeted';
+ // Use middle element position for powerup
+ var middleIndex = Math.floor(matchSize / 2);
+ powerupRow = match[middleIndex].row;
+ powerupCol = match[middleIndex].col;
+ }
+ // Remove matched elements
+ for (var j = 0; j < matchSize; j++) {
+ var element = match[j];
+ var elementIndex = adElements.indexOf(element);
+ if (elementIndex !== -1) {
+ adElements.splice(elementIndex, 1);
+ }
+ grid[element.row][element.col] = null;
+ element.explode();
+ }
+ // Create powerup if needed
+ if (createPowerup) {
+ // Wait for animations to complete
+ LK.setTimeout(function (row, col, type) {
+ return function () {
+ var powerup = new AdElement(type, row, col);
+ powerup.setGridPosition(row, col);
+ grid[row][col] = powerup;
+ adElements.push(powerup);
+ game.addChild(powerup);
+ LK.getSound('powerup').play();
+ };
+ }(powerupRow, powerupCol, powerupType), 300);
+ }
+ }
+ // Update score
+ updateScore(pointsEarned);
+ // Update client briefs
+ for (var type in matchedTypes) {
+ if (matchedTypes.hasOwnProperty(type) && AD_TYPES.indexOf(type) !== -1) {
+ updateClientBriefs(type);
+ }
+ }
+ // Check if all briefs are completed
+ checkBriefsCompleted();
+ // After a delay, collapse the grid and refill
+ LK.setTimeout(function () {
+ collapseGrid();
+ }, 400);
+}
+function processPowerup(powerup, targetElement) {
+ var elementsToRemove = [];
+ if (powerup.type === 'viral') {
+ // Viral powerup: clear entire row and column
+ for (var col = 0; col < GRID_SIZE; col++) {
+ if (grid[powerup.row][col] && grid[powerup.row][col] !== powerup) {
+ elementsToRemove.push(grid[powerup.row][col]);
+ }
+ }
+ for (var row = 0; row < GRID_SIZE; row++) {
+ if (grid[row][powerup.col] && grid[row][powerup.col] !== powerup && elementsToRemove.indexOf(grid[row][powerup.col]) === -1) {
+ elementsToRemove.push(grid[row][powerup.col]);
+ }
+ }
+ } else if (powerup.type === 'targeted') {
+ // Targeted powerup: remove all elements of the same type as the target
+ var targetType = targetElement.type;
+ for (var row = 0; row < GRID_SIZE; row++) {
+ for (var col = 0; col < GRID_SIZE; col++) {
+ if (grid[row][col] && grid[row][col].type === targetType && !grid[row][col].isPowerup) {
+ elementsToRemove.push(grid[row][col]);
+ }
+ }
+ }
+ }
+ // Remove powerup
+ var powerupIndex = adElements.indexOf(powerup);
+ if (powerupIndex !== -1) {
+ adElements.splice(powerupIndex, 1);
+ }
+ grid[powerup.row][powerup.col] = null;
+ powerup.explode();
+ // Remove affected elements
+ for (var i = 0; i < elementsToRemove.length; i++) {
+ var element = elementsToRemove[i];
+ var elementIndex = adElements.indexOf(element);
+ if (elementIndex !== -1) {
+ adElements.splice(elementIndex, 1);
+ }
+ // Track matched types for client briefs
+ if (AD_TYPES.indexOf(element.type) !== -1) {
+ updateClientBriefs(element.type);
+ }
+ grid[element.row][element.col] = null;
+ element.explode();
+ }
+ // Update score
+ updateScore(elementsToRemove.length * 15);
+ // Play powerup sound
+ LK.getSound('powerup').play();
+ // Check if all briefs are completed
+ checkBriefsCompleted();
+ // After a delay, collapse the grid and refill
+ LK.setTimeout(function () {
+ collapseGrid();
+ }, 400);
+}
+function collapseGrid() {
+ var elementsMoved = false;
+ // Move elements down to fill empty spaces
+ for (var col = 0; col < GRID_SIZE; col++) {
+ var emptySpaces = 0;
+ for (var row = GRID_SIZE - 1; row >= 0; row--) {
+ if (grid[row][col] === null) {
+ emptySpaces++;
+ } else if (emptySpaces > 0) {
+ // Move element down
+ var element = grid[row][col];
+ var newRow = row + emptySpaces;
+ grid[newRow][col] = element;
+ grid[row][col] = null;
+ // Animate the movement
+ element.setGridPosition(newRow, col);
+ tween(element, {
+ y: GRID_OFFSET_Y + newRow * CELL_SIZE + CELL_SIZE / 2
+ }, {
+ duration: 300
+ });
+ elementsMoved = true;
+ }
+ }
+ }
+ // Refill the grid from the top
+ LK.setTimeout(function () {
+ // Create new elements for empty spaces at the top
+ for (var col = 0; col < GRID_SIZE; col++) {
+ for (var row = 0; row < GRID_SIZE; row++) {
+ if (grid[row][col] === null) {
+ var newElement = createAdElement(row, col);
+ // Start from above the grid
+ newElement.y = GRID_OFFSET_Y + (row - GRID_SIZE) * CELL_SIZE + CELL_SIZE / 2;
+ // Animate falling in
+ tween(newElement, {
+ y: GRID_OFFSET_Y + row * CELL_SIZE + CELL_SIZE / 2
+ }, {
+ duration: 300
+ });
+ }
+ }
+ }
+ // Check for new matches after the grid is refilled
+ LK.setTimeout(function () {
+ var newMatches = findAllMatches();
+ if (newMatches.length > 0) {
+ processMatches(newMatches);
+ } else {
+ // Check if there are possible moves
+ if (!hasPossibleMoves()) {
+ // No moves left, shuffle the grid
+ shuffleGrid();
+ }
+ }
+ }, 400);
+ }, elementsMoved ? 300 : 0);
+}
+function shuffleGrid() {
+ // Collect all current elements
+ var allElements = [];
+ for (var row = 0; row < GRID_SIZE; row++) {
+ for (var col = 0; col < GRID_SIZE; col++) {
+ if (grid[row][col]) {
+ allElements.push({
+ type: grid[row][col].type,
+ isPowerup: grid[row][col].isPowerup
+ });
+ // Remove from grid
+ grid[row][col].destroy();
+ grid[row][col] = null;
+ }
+ }
+ }
+ // Clear adElements array
+ adElements = [];
+ // Shuffle the elements
+ for (var i = allElements.length - 1; i > 0; i--) {
+ var j = Math.floor(Math.random() * (i + 1));
+ var temp = allElements[i];
+ allElements[i] = allElements[j];
+ allElements[j] = temp;
+ }
+ // Refill the grid with shuffled elements
+ var elementIndex = 0;
+ for (var row = 0; row < GRID_SIZE; row++) {
+ for (var col = 0; col < GRID_SIZE; col++) {
+ if (elementIndex < allElements.length) {
+ var element = new AdElement(allElements[elementIndex].type, row, col);
+ element.setGridPosition(row, col);
+ grid[row][col] = element;
+ adElements.push(element);
+ game.addChild(element);
+ elementIndex++;
+ } else {
+ // In case we need more elements
+ createAdElement(row, col);
+ }
+ }
+ }
+ // Check for matches after shuffling
+ var newMatches = findAllMatches();
+ if (newMatches.length > 0) {
+ // If we have matches, process them
+ LK.setTimeout(function () {
+ processMatches(newMatches);
+ }, 500);
+ }
+}
+function hasPossibleMoves() {
+ // Check for possible moves horizontally
+ for (var row = 0; row < GRID_SIZE; row++) {
+ for (var col = 0; col < GRID_SIZE - 1; col++) {
+ // Swap adjacent elements
+ var temp = grid[row][col];
+ grid[row][col] = grid[row][col + 1];
+ grid[row][col + 1] = temp;
+ // Check for matches
+ var matches = findAllMatches();
+ // Swap back
+ temp = grid[row][col];
+ grid[row][col] = grid[row][col + 1];
+ grid[row][col + 1] = temp;
+ if (matches.length > 0) {
+ return true;
+ }
+ }
+ }
+ // Check for possible moves vertically
+ for (var row = 0; row < GRID_SIZE - 1; row++) {
+ for (var col = 0; col < GRID_SIZE; col++) {
+ // Swap adjacent elements
+ var temp = grid[row][col];
+ grid[row][col] = grid[row + 1][col];
+ grid[row + 1][col] = temp;
+ // Check for matches
+ var matches = findAllMatches();
+ // Swap back
+ temp = grid[row][col];
+ grid[row][col] = grid[row + 1][col];
+ grid[row + 1][col] = temp;
+ if (matches.length > 0) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+function updateScore(points) {
+ score += points;
+ scoreText.setText("Score: " + score);
+}
+function decrementMoves() {
+ moveCount--;
+ moveText.setText("Moves: " + moveCount);
+ if (moveCount <= 0) {
+ // Game over if no more moves
+ gameActive = false;
+ // Wait a bit before showing game over
+ LK.setTimeout(function () {
+ if (score > storage.highScore) {
+ storage.highScore = score;
+ }
+ LK.setScore(score);
+ LK.showGameOver();
+ }, 1000);
+ }
+}
+function initializeClientBriefs() {
+ // Clear existing briefs
+ for (var i = 0; i < clientBriefs.length; i++) {
+ clientBriefs[i].destroy();
+ }
+ clientBriefs = [];
+ // Create new client briefs based on level
+ var briefsCount = Math.min(3, level + 1);
+ var briefsComplexity = Math.floor(level * 1.5) + 5;
+ var targetTypes = [];
+ // Select random unique ad types for briefs
+ var availableTypes = [].concat(AD_TYPES);
+ for (var i = 0; i < briefsCount; i++) {
+ if (availableTypes.length === 0) {
+ break;
+ }
+ var index = Math.floor(Math.random() * availableTypes.length);
+ targetTypes.push(availableTypes[index]);
+ availableTypes.splice(index, 1);
+ }
+ // Create brief objects
+ for (var i = 0; i < targetTypes.length; i++) {
+ var count = briefsComplexity + Math.floor(Math.random() * 5);
+ var brief = new ClientBrief(targetTypes[i], count);
+ brief.x = 400 + i * 400;
+ brief.y = GRID_OFFSET_Y + GRID_SIZE * CELL_SIZE + 160;
+ clientBriefs.push(brief);
+ game.addChild(brief);
+ }
+}
+function updateClientBriefs(matchedType) {
+ for (var i = 0; i < clientBriefs.length; i++) {
+ clientBriefs[i].updateProgress(matchedType);
+ }
+}
+function checkBriefsCompleted() {
+ var allCompleted = true;
+ for (var i = 0; i < clientBriefs.length; i++) {
+ if (!clientBriefs[i].isComplete()) {
+ allCompleted = false;
+ break;
+ }
+ }
+ if (allCompleted && clientBriefs.length > 0 && gameActive) {
+ // Level completed
+ gameActive = false;
+ // Play celebration sound
+ LK.getSound('briefComplete').play();
+ // Update level
+ level++;
+ storage.currentLevel = level;
+ // Add bonus points
+ var levelBonus = level * 100;
+ updateScore(levelBonus);
+ // Add move bonus
+ var moveBonus = moveCount * 20;
+ updateScore(moveBonus);
+ // Show level complete and continue
+ LK.setTimeout(function () {
+ LK.setScore(score);
+ LK.showYouWin();
+ }, 1200);
+ }
+}
+// Initialize game
+initializeGrid();
+initializeClientBriefs();
+// Play background music
+LK.playMusic('bgmusic', {
+ fade: {
+ start: 0,
+ end: 0.4,
+ duration: 1000
+ }
});
\ No newline at end of file
Ad billboard. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A ad Print. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A social ad. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
TV ad. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows