User prompt
Add the slime, night, sky, cheese, popcorn, mismi, and volcano assets as the footballs in the game
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'inventoryContainer.destroy();' Line Number: 268
Code edit (1 edits merged)
Please save this source code
User prompt
Football Pack Collect
User prompt
Create a fun football collecting game where people open a pack of ootballs and they get 4 collectible footballs with an inevntory tab where they can see sll of the footballs they have and the footballs they are missing to collect
User prompt
And add an inventory where players can see their ootballs
User prompt
Create a fun football collecting game where you open a pack and you get 4 random collectible ootballs
User prompt
Please continue polishing my design document.
User prompt
Please continue polishing my design document.
Initial prompt
Create a fun collecting game where you can buy a pack of footballs and youget a
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { collectedFootballs: [] }); /**** * Classes ****/ //Library for using the camera (the background becomes the user's camera video feed) and the microphone. It can access face coordinates for interactive play, as well detect microphone volume / voice interactions // var facekit = LK.import('@upit/facekit.v1'); //Classes can only be defined here. You cannot create inline classes in the games code. var Football = Container.expand(function (id) { var self = Container.call(this); self.id = id; // Unique ID for the football // Use the correct asset for each football type var assetId = id; // Defensive: fallback to generic if asset not found var validAssets = { 'Tropical': true, 'Cave': true, 'Crystal': true, 'Fire': true, 'Galaxy': true, 'Magic': true, 'Snow': true, 'Gold': true, 'Honey': true, 'Ocean': true, 'Plant': true, 'Rainbow': true, 'Regular': true, 'Slime': true, 'Night': true, 'Sky': true, 'Cheese': true, 'Popcorn': true, 'Mismi': true, 'Volcano': true, 'Soapy': true, 'Ice': true, 'Neon': true, 'Nuclear': true, 'Coral': true, 'Astronaut': true, 'Icecream': true, 'Medival': true, 'Star': true, 'Coconut': true, 'Clock': true, 'Jellyfish': true, 'Airplane': true, 'Bacon': true, 'Potato': true, 'Money': true, 'Pickle': true, 'Pumpkin': true, 'Rock': true, 'Gummy': true, 'Wizard': true, 'Polka': true }; if (!validAssets[assetId]) assetId = 'football'; self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5 }); return self; }); var InventorySlot = Container.expand(function (footballId) { var self = Container.call(this); self.footballId = footballId; self.attachAsset('inventorySlot', { anchorX: 0.5, anchorY: 0.5 }); // Display the football if it has been collected if (isFootballCollected(footballId)) { var football = new Football(footballId); football.scale.set(1.75); // Scale up to fit in slot football.x = self.width / 2; football.y = self.height / 2; self.addChild(football); } else { // Display a placeholder or question mark for uncollected footballs var placeholder = new Text2('?', { size: 150, fill: 0xFFFFFF }); placeholder.anchor.set(0.5); placeholder.x = self.width / 2; placeholder.y = self.height / 2; self.addChild(placeholder); } return self; }); var Pack = Container.expand(function () { var self = Container.call(this); self.attachAsset('pack', { anchorX: 0.5, anchorY: 0.5 }); self.down = function (x, y, obj) { // Open the pack when pressed openPack(); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x1a1a1a // Dark background }); /**** * Game Code ****/ //Storage library which should be used for persistent game data //Minimalistic tween library which should be used for animations over time, including tinting / colouring an object, scaling, rotating, or changing any game object property. //Only include the plugins you need to create the game. //We have access to the following plugins. (Note that the variable names used are mandetory for each plugin) // Initialize music // Placeholder football graphic // Initialize assets used in this game. Scale them according to what is needed for the game. // or via static code analysis based on their usage in the code. // Assets are automatically created and loaded either dynamically during gameplay /* Supported Types: 1. Shape: - Simple geometric figures with these properties: * width: (required) pixel width of the shape. * height: (required) pixel height of the shape. * color: (required) color of the shape. * shape: (required) type of shape. Valid options: 'box', 'ellipse'. 2. Image: - Imported images with these properties: * width: (required) pixel resolution width. * height: (required) pixel resolution height. * id: (required) identifier for the image. * flipX: (optional) horizontal flip. Valid values: 0 (no flip), 1 (flip). * flipY: (optional) vertical flip. Valid values: 0 (no flip), 1 (flip). * orientation: (optional) rotation in multiples of 90 degrees, clockwise. Valid values: - 0: No rotation. - 1: Rotate 90 degrees. - 2: Rotate 180 degrees. - 3: Rotate 270 degrees. Note: Width and height remain unchanged upon flipping. 3. Sound: - Sound effects with these properties: * id: (required) identifier for the sound. * volume: (optional) custom volume. Valid values are a float from 0 to 1. 4. Music: - In contract to sound effects, only one music can be played at a time - Music is using the same API to initilize just like sound. - Music loops by default - Music with these config options: * id: (required) identifier for the sound. * volume: (optional) custom volume. Valid values are a float from 0 to 1. * start: (optional) a float from 0 to 1 used for cropping and indicates the start of the cropping * end: (optional) a float from 0 to 1 used for cropping and indicates the end of the cropping */ var allFootballs = []; // Array of all possible football IDs var packNode = null; // The visual representation of the pack var inventoryContainer = null; // Container for inventory slots var scoreTxt = null; // Text display for collection progress // Define all possible football IDs (actual asset names) allFootballs = ['Tropical', 'Cave', 'Crystal', 'Fire', 'Galaxy', 'Magic', 'Snow', 'Gold', 'Honey', 'Ocean', 'Plant', 'Rainbow', 'Regular', 'Slime', 'Night', 'Sky', 'Cheese', 'Popcorn', 'Mismi', 'Volcano', 'Soapy', 'Ice', 'Neon', 'Nuclear', 'Coral', 'Astronaut', 'Icecream', 'Medival', 'Star', 'Coconut', 'Clock', 'Jellyfish', 'Airplane', 'Bacon', 'Potato', 'Money', 'Pickle', 'Pumpkin', 'Rock', 'Gummy', 'Wizard', 'Polka']; // Function to check if a football ID is in the player's collection function isFootballCollected(footballId) { return storage.collectedFootballs.indexOf(footballId) !== -1; } // Function to get a random uncollected football ID function getRandomUncollectedFootballId() { var uncollected = allFootballs.filter(function (id) { return !isFootballCollected(id); }); if (uncollected.length === 0) { return null; // All footballs collected } var randomIndex = Math.floor(Math.random() * uncollected.length); return uncollected[randomIndex]; } // Function to get a random football ID (collected or uncollected) function getRandomFootballId() { var randomIndex = Math.floor(Math.random() * allFootballs.length); return allFootballs[randomIndex]; } // Function to open a pack function openPack() { // Remove the pack node if (packNode) { packNode.destroy(); packNode = null; } LK.getSound('openPack').play(); var revealedFootballs = []; // Generate 4 footballs. Allow duplicates, but if not all collected, bias toward uncollected for at least one slot var guaranteedUncollected = !allFootballs.every(isFootballCollected); var uncollectedGiven = false; for (var i = 0; i < 4; i++) { var footballId; // Guarantee at least one uncollected if possible if (guaranteedUncollected && !uncollectedGiven) { footballId = getRandomUncollectedFootballId(); if (footballId !== null) { uncollectedGiven = true; } else { footballId = getRandomFootballId(); } } else { footballId = getRandomFootballId(); } revealedFootballs.push(footballId); // Add to collection if not already collected if (!isFootballCollected(footballId)) { storage.collectedFootballs.push(footballId); LK.getSound('collectFootball').play(); } } // Update storage immediately (ensure persistence) storage.collectedFootballs = storage.collectedFootballs; // Display the revealed footballs var startX = (game.width - (revealedFootballs.length * 300 + (revealedFootballs.length - 1) * 50)) / 2 + 150; var startY = game.height / 2; for (var j = 0; j < revealedFootballs.length; j++) { var football = new Football(revealedFootballs[j]); football.scale.set(1.75); // Increase scale for visibility football.x = startX + j * 350; football.y = startY; game.addChild(football); // Simple animation tween(football, { y: football.y - 200 }, { duration: 500, easing: tween.easeOut }); tween(football, { rotation: Math.PI * 2 }, { duration: 1000, easing: tween.linear }); // Delete football after animation is done (after 1000ms) // Delete football after animation is done (after 1000ms) (function (footballRef) { var thisJ = j; // capture the current value of j for this closure LK.setTimeout(function () { // Always destroy the football after animation, do not leave it visible if (footballRef && footballRef.parent) { // Optionally, you could play a quick scale-down animation before destroy tween(footballRef, { scaleX: 0.5, scaleY: 0.5 }, { duration: 200, easing: tween.easeOut, complete: function complete() { if (footballRef && footballRef.parent) { footballRef.destroy(); } } }); } }, 1000); })(football); } // Update collection progress display updateCollectionProgress(); // After a delay, show the inventory again LK.setTimeout(showInventory, 3000); // Show inventory after 3 seconds } // Function to update the collection progress display function updateCollectionProgress() { var collectedCount = storage.collectedFootballs.length; var totalCount = allFootballs.length; scoreTxt.setText('Collected: ' + collectedCount + '/' + totalCount); // Check for win condition if (collectedCount === totalCount) { LK.showYouWin(); } } // Function to show the inventory function showInventory() { // Remove any revealed footballs from pack opening game.children.forEach(function (child) { if (child instanceof Football) { child.destroy(); } }); // Create or show the inventory container if (!inventoryContainer) { inventoryContainer = new Container(); // Configure for horizontal scrolling inventoryContainer.interactive = true; inventoryContainer.overflow = 'scroll'; inventoryContainer.scrollDirection = 'horizontal'; // Add drag functionality for manual horizontal scrolling var dragging = false; var lastMouseX = 0; var scrollOffset = 0; var minScroll = 0; var slotWidth = 300; var slotHeight = 300; var padding = 50; var totalContentWidth = allFootballs.length * (slotWidth + padding) - padding; var maxScroll = Math.max(0, totalContentWidth - game.width); inventoryContainer.down = function (x, y, obj) { dragging = true; lastMouseX = x; }; inventoryContainer.move = function (x, y, obj) { if (dragging) { var deltaX = x - lastMouseX; scrollOffset += deltaX; // Clamp scrollOffset to bounds if (scrollOffset > minScroll) scrollOffset = minScroll; if (scrollOffset < -maxScroll) scrollOffset = -maxScroll; // Move all slots accordingly for (var i = 0; i < inventoryContainer.children.length; i++) { var child = inventoryContainer.children[i]; // Only move InventorySlot, not buttons if (child instanceof InventorySlot) { child.x = i * (slotWidth + padding) + slotWidth / 2 + scrollOffset; } } lastMouseX = x; } }; inventoryContainer.up = function (x, y, obj) { dragging = false; }; inventoryContainer.upoutside = function (x, y, obj) { dragging = false; }; inventoryContainer.width = game.width; // Set the visible width inventoryContainer.height = game.height - 400; // Set the visible height, leaving space for buttons // Position the inventory container (example positioning) inventoryContainer.x = 0; // Align to the left edge inventoryContainer.y = 300; // Offset from top, moved down by 100 pixels game.addChild(inventoryContainer); // Arrange inventory slots in a single row var slotWidth = 300; var slotHeight = 300; var padding = 50; // Calculate the total width needed for the single row var totalContentWidth = allFootballs.length * (slotWidth + padding) - padding; inventoryContainer.contentWidth = totalContentWidth; // Set the scrollable width for (var i = 0; i < allFootballs.length; i++) { var footballId = allFootballs[i]; var slot = new InventorySlot(footballId); slot.x = i * (slotWidth + padding) + slotWidth / 2; slot.y = slotHeight / 2; // Position vertically relative to the slot's height, keeping it in a straight line at the top of the container. inventoryContainer.addChild(slot); } // Add a button to open a pack var openPackButton = new Container(); var buttonGraphic = openPackButton.attachAsset('pack', { anchorX: 0.5, anchorY: 0.5 }); // Use pack graphic for button buttonGraphic.width = 300; buttonGraphic.height = 400; var buttonText = new Text2('Open Pack', { size: 60, fill: 0xFFFFFF }); buttonText.anchor.set(0.5); buttonText.x = buttonGraphic.width / 2; buttonText.y = buttonGraphic.height / 2; openPackButton.addChild(buttonText); openPackButton.x = game.width / 2; openPackButton.y = game.height - 150; // Position at the bottom, adjusted for larger inventory area openPackButton.down = function () { // Remove the inventory and show the pack if (inventoryContainer) { // Destroy children first inventoryContainer.children.forEach(function (child) { child.destroy(); }); inventoryContainer.destroy(); inventoryContainer = null; } showPack(); }; game.addChild(openPackButton); // Add a reset progress button at the bottom left (avoid top left 100x100 for menu) var resetButton = new Container(); var resetButtonGraphic = resetButton.attachAsset('inventorySlot', { anchorX: 0.5, anchorY: 0.5 }); resetButtonGraphic.width = 220; resetButtonGraphic.height = 120; var resetText = new Text2('Reset', { size: 60, fill: 0xFFFFFF }); resetText.anchor.set(0.5); resetText.x = resetButtonGraphic.width / 2; resetText.y = resetButtonGraphic.height / 2; resetButton.addChild(resetText); // Place at bottom left, but not in the top left 100x100 resetButton.x = 120; resetButton.y = game.height - 120; // Keep at the bottom left resetButton.down = function () { // Clear collection and restart storage.collectedFootballs = []; // Remove inventory and pack if present if (inventoryContainer) { inventoryContainer.children.forEach(function (child) { child.destroy(); }); inventoryContainer.destroy(); inventoryContainer = null; } if (packNode) { packNode.destroy(); packNode = null; } // Reset progress display updateCollectionProgress(); // Show inventory again showInventory(); }; game.addChild(resetButton); } else { inventoryContainer.visible = true; } // Update the content of the inventory slots based on collected footballs inventoryContainer.children.forEach(function (child) { if (child instanceof InventorySlot) { // Clear existing content in the slot child.children.forEach(function (slotChild) { slotChild.destroy(); }); child.children = []; // Clear children array // Add appropriate graphic based on collection status if (isFootballCollected(child.footballId)) { var football = new Football(child.footballId); football.scale.set(1.75); // Ensure scale is correct on update football.x = child.width / 2; football.y = child.height / 2; child.addChild(football); } else { var placeholder = new Text2('?', { size: 150, fill: 0xFFFFFF }); placeholder.anchor.set(0.5); placeholder.x = child.width / 2; placeholder.y = child.height / 2; child.addChild(placeholder); } } }); } // Function to show the pack function showPack() { // Remove inventory if visible if (inventoryContainer) { inventoryContainer.visible = false; } if (!packNode) { packNode = new Pack(); packNode.x = game.width / 2; packNode.y = game.height / 2; game.addChild(packNode); } else { packNode.visible = true; } } // Initial setup scoreTxt = new Text2('Collected: 0/0', { size: 80, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); scoreTxt.x = LK.gui.top.width / 2; scoreTxt.y = 100; // Offset from the very top to avoid the menu icon LK.gui.top.addChild(scoreTxt); updateCollectionProgress(); // Initialize the score display showInventory(); // Start by showing the inventory // Play background music LK.playMusic('backgroundMusic'); // Main game loop (not needed for this simple UI game) // game.update = function () { // };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
collectedFootballs: []
});
/****
* Classes
****/
//Library for using the camera (the background becomes the user's camera video feed) and the microphone. It can access face coordinates for interactive play, as well detect microphone volume / voice interactions
// var facekit = LK.import('@upit/facekit.v1');
//Classes can only be defined here. You cannot create inline classes in the games code.
var Football = Container.expand(function (id) {
var self = Container.call(this);
self.id = id; // Unique ID for the football
// Use the correct asset for each football type
var assetId = id;
// Defensive: fallback to generic if asset not found
var validAssets = {
'Tropical': true,
'Cave': true,
'Crystal': true,
'Fire': true,
'Galaxy': true,
'Magic': true,
'Snow': true,
'Gold': true,
'Honey': true,
'Ocean': true,
'Plant': true,
'Rainbow': true,
'Regular': true,
'Slime': true,
'Night': true,
'Sky': true,
'Cheese': true,
'Popcorn': true,
'Mismi': true,
'Volcano': true,
'Soapy': true,
'Ice': true,
'Neon': true,
'Nuclear': true,
'Coral': true,
'Astronaut': true,
'Icecream': true,
'Medival': true,
'Star': true,
'Coconut': true,
'Clock': true,
'Jellyfish': true,
'Airplane': true,
'Bacon': true,
'Potato': true,
'Money': true,
'Pickle': true,
'Pumpkin': true,
'Rock': true,
'Gummy': true,
'Wizard': true,
'Polka': true
};
if (!validAssets[assetId]) assetId = 'football';
self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var InventorySlot = Container.expand(function (footballId) {
var self = Container.call(this);
self.footballId = footballId;
self.attachAsset('inventorySlot', {
anchorX: 0.5,
anchorY: 0.5
});
// Display the football if it has been collected
if (isFootballCollected(footballId)) {
var football = new Football(footballId);
football.scale.set(1.75); // Scale up to fit in slot
football.x = self.width / 2;
football.y = self.height / 2;
self.addChild(football);
} else {
// Display a placeholder or question mark for uncollected footballs
var placeholder = new Text2('?', {
size: 150,
fill: 0xFFFFFF
});
placeholder.anchor.set(0.5);
placeholder.x = self.width / 2;
placeholder.y = self.height / 2;
self.addChild(placeholder);
}
return self;
});
var Pack = Container.expand(function () {
var self = Container.call(this);
self.attachAsset('pack', {
anchorX: 0.5,
anchorY: 0.5
});
self.down = function (x, y, obj) {
// Open the pack when pressed
openPack();
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a1a // Dark background
});
/****
* Game Code
****/
//Storage library which should be used for persistent game data
//Minimalistic tween library which should be used for animations over time, including tinting / colouring an object, scaling, rotating, or changing any game object property.
//Only include the plugins you need to create the game.
//We have access to the following plugins. (Note that the variable names used are mandetory for each plugin)
// Initialize music
// Placeholder football graphic
// Initialize assets used in this game. Scale them according to what is needed for the game.
// or via static code analysis based on their usage in the code.
// Assets are automatically created and loaded either dynamically during gameplay
/*
Supported Types:
1. Shape:
- Simple geometric figures with these properties:
* width: (required) pixel width of the shape.
* height: (required) pixel height of the shape.
* color: (required) color of the shape.
* shape: (required) type of shape. Valid options: 'box', 'ellipse'.
2. Image:
- Imported images with these properties:
* width: (required) pixel resolution width.
* height: (required) pixel resolution height.
* id: (required) identifier for the image.
* flipX: (optional) horizontal flip. Valid values: 0 (no flip), 1 (flip).
* flipY: (optional) vertical flip. Valid values: 0 (no flip), 1 (flip).
* orientation: (optional) rotation in multiples of 90 degrees, clockwise. Valid values:
- 0: No rotation.
- 1: Rotate 90 degrees.
- 2: Rotate 180 degrees.
- 3: Rotate 270 degrees.
Note: Width and height remain unchanged upon flipping.
3. Sound:
- Sound effects with these properties:
* id: (required) identifier for the sound.
* volume: (optional) custom volume. Valid values are a float from 0 to 1.
4. Music:
- In contract to sound effects, only one music can be played at a time
- Music is using the same API to initilize just like sound.
- Music loops by default
- Music with these config options:
* id: (required) identifier for the sound.
* volume: (optional) custom volume. Valid values are a float from 0 to 1.
* start: (optional) a float from 0 to 1 used for cropping and indicates the start of the cropping
* end: (optional) a float from 0 to 1 used for cropping and indicates the end of the cropping
*/
var allFootballs = []; // Array of all possible football IDs
var packNode = null; // The visual representation of the pack
var inventoryContainer = null; // Container for inventory slots
var scoreTxt = null; // Text display for collection progress
// Define all possible football IDs (actual asset names)
allFootballs = ['Tropical', 'Cave', 'Crystal', 'Fire', 'Galaxy', 'Magic', 'Snow', 'Gold', 'Honey', 'Ocean', 'Plant', 'Rainbow', 'Regular', 'Slime', 'Night', 'Sky', 'Cheese', 'Popcorn', 'Mismi', 'Volcano', 'Soapy', 'Ice', 'Neon', 'Nuclear', 'Coral', 'Astronaut', 'Icecream', 'Medival', 'Star', 'Coconut', 'Clock', 'Jellyfish', 'Airplane', 'Bacon', 'Potato', 'Money', 'Pickle', 'Pumpkin', 'Rock', 'Gummy', 'Wizard', 'Polka'];
// Function to check if a football ID is in the player's collection
function isFootballCollected(footballId) {
return storage.collectedFootballs.indexOf(footballId) !== -1;
}
// Function to get a random uncollected football ID
function getRandomUncollectedFootballId() {
var uncollected = allFootballs.filter(function (id) {
return !isFootballCollected(id);
});
if (uncollected.length === 0) {
return null; // All footballs collected
}
var randomIndex = Math.floor(Math.random() * uncollected.length);
return uncollected[randomIndex];
}
// Function to get a random football ID (collected or uncollected)
function getRandomFootballId() {
var randomIndex = Math.floor(Math.random() * allFootballs.length);
return allFootballs[randomIndex];
}
// Function to open a pack
function openPack() {
// Remove the pack node
if (packNode) {
packNode.destroy();
packNode = null;
}
LK.getSound('openPack').play();
var revealedFootballs = [];
// Generate 4 footballs. Allow duplicates, but if not all collected, bias toward uncollected for at least one slot
var guaranteedUncollected = !allFootballs.every(isFootballCollected);
var uncollectedGiven = false;
for (var i = 0; i < 4; i++) {
var footballId;
// Guarantee at least one uncollected if possible
if (guaranteedUncollected && !uncollectedGiven) {
footballId = getRandomUncollectedFootballId();
if (footballId !== null) {
uncollectedGiven = true;
} else {
footballId = getRandomFootballId();
}
} else {
footballId = getRandomFootballId();
}
revealedFootballs.push(footballId);
// Add to collection if not already collected
if (!isFootballCollected(footballId)) {
storage.collectedFootballs.push(footballId);
LK.getSound('collectFootball').play();
}
}
// Update storage immediately (ensure persistence)
storage.collectedFootballs = storage.collectedFootballs;
// Display the revealed footballs
var startX = (game.width - (revealedFootballs.length * 300 + (revealedFootballs.length - 1) * 50)) / 2 + 150;
var startY = game.height / 2;
for (var j = 0; j < revealedFootballs.length; j++) {
var football = new Football(revealedFootballs[j]);
football.scale.set(1.75); // Increase scale for visibility
football.x = startX + j * 350;
football.y = startY;
game.addChild(football);
// Simple animation
tween(football, {
y: football.y - 200
}, {
duration: 500,
easing: tween.easeOut
});
tween(football, {
rotation: Math.PI * 2
}, {
duration: 1000,
easing: tween.linear
});
// Delete football after animation is done (after 1000ms)
// Delete football after animation is done (after 1000ms)
(function (footballRef) {
var thisJ = j; // capture the current value of j for this closure
LK.setTimeout(function () {
// Always destroy the football after animation, do not leave it visible
if (footballRef && footballRef.parent) {
// Optionally, you could play a quick scale-down animation before destroy
tween(footballRef, {
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 200,
easing: tween.easeOut,
complete: function complete() {
if (footballRef && footballRef.parent) {
footballRef.destroy();
}
}
});
}
}, 1000);
})(football);
}
// Update collection progress display
updateCollectionProgress();
// After a delay, show the inventory again
LK.setTimeout(showInventory, 3000); // Show inventory after 3 seconds
}
// Function to update the collection progress display
function updateCollectionProgress() {
var collectedCount = storage.collectedFootballs.length;
var totalCount = allFootballs.length;
scoreTxt.setText('Collected: ' + collectedCount + '/' + totalCount);
// Check for win condition
if (collectedCount === totalCount) {
LK.showYouWin();
}
}
// Function to show the inventory
function showInventory() {
// Remove any revealed footballs from pack opening
game.children.forEach(function (child) {
if (child instanceof Football) {
child.destroy();
}
});
// Create or show the inventory container
if (!inventoryContainer) {
inventoryContainer = new Container();
// Configure for horizontal scrolling
inventoryContainer.interactive = true;
inventoryContainer.overflow = 'scroll';
inventoryContainer.scrollDirection = 'horizontal';
// Add drag functionality for manual horizontal scrolling
var dragging = false;
var lastMouseX = 0;
var scrollOffset = 0;
var minScroll = 0;
var slotWidth = 300;
var slotHeight = 300;
var padding = 50;
var totalContentWidth = allFootballs.length * (slotWidth + padding) - padding;
var maxScroll = Math.max(0, totalContentWidth - game.width);
inventoryContainer.down = function (x, y, obj) {
dragging = true;
lastMouseX = x;
};
inventoryContainer.move = function (x, y, obj) {
if (dragging) {
var deltaX = x - lastMouseX;
scrollOffset += deltaX;
// Clamp scrollOffset to bounds
if (scrollOffset > minScroll) scrollOffset = minScroll;
if (scrollOffset < -maxScroll) scrollOffset = -maxScroll;
// Move all slots accordingly
for (var i = 0; i < inventoryContainer.children.length; i++) {
var child = inventoryContainer.children[i];
// Only move InventorySlot, not buttons
if (child instanceof InventorySlot) {
child.x = i * (slotWidth + padding) + slotWidth / 2 + scrollOffset;
}
}
lastMouseX = x;
}
};
inventoryContainer.up = function (x, y, obj) {
dragging = false;
};
inventoryContainer.upoutside = function (x, y, obj) {
dragging = false;
};
inventoryContainer.width = game.width; // Set the visible width
inventoryContainer.height = game.height - 400; // Set the visible height, leaving space for buttons
// Position the inventory container (example positioning)
inventoryContainer.x = 0; // Align to the left edge
inventoryContainer.y = 300; // Offset from top, moved down by 100 pixels
game.addChild(inventoryContainer);
// Arrange inventory slots in a single row
var slotWidth = 300;
var slotHeight = 300;
var padding = 50;
// Calculate the total width needed for the single row
var totalContentWidth = allFootballs.length * (slotWidth + padding) - padding;
inventoryContainer.contentWidth = totalContentWidth; // Set the scrollable width
for (var i = 0; i < allFootballs.length; i++) {
var footballId = allFootballs[i];
var slot = new InventorySlot(footballId);
slot.x = i * (slotWidth + padding) + slotWidth / 2;
slot.y = slotHeight / 2; // Position vertically relative to the slot's height, keeping it in a straight line at the top of the container.
inventoryContainer.addChild(slot);
}
// Add a button to open a pack
var openPackButton = new Container();
var buttonGraphic = openPackButton.attachAsset('pack', {
anchorX: 0.5,
anchorY: 0.5
}); // Use pack graphic for button
buttonGraphic.width = 300;
buttonGraphic.height = 400;
var buttonText = new Text2('Open Pack', {
size: 60,
fill: 0xFFFFFF
});
buttonText.anchor.set(0.5);
buttonText.x = buttonGraphic.width / 2;
buttonText.y = buttonGraphic.height / 2;
openPackButton.addChild(buttonText);
openPackButton.x = game.width / 2;
openPackButton.y = game.height - 150; // Position at the bottom, adjusted for larger inventory area
openPackButton.down = function () {
// Remove the inventory and show the pack
if (inventoryContainer) {
// Destroy children first
inventoryContainer.children.forEach(function (child) {
child.destroy();
});
inventoryContainer.destroy();
inventoryContainer = null;
}
showPack();
};
game.addChild(openPackButton);
// Add a reset progress button at the bottom left (avoid top left 100x100 for menu)
var resetButton = new Container();
var resetButtonGraphic = resetButton.attachAsset('inventorySlot', {
anchorX: 0.5,
anchorY: 0.5
});
resetButtonGraphic.width = 220;
resetButtonGraphic.height = 120;
var resetText = new Text2('Reset', {
size: 60,
fill: 0xFFFFFF
});
resetText.anchor.set(0.5);
resetText.x = resetButtonGraphic.width / 2;
resetText.y = resetButtonGraphic.height / 2;
resetButton.addChild(resetText);
// Place at bottom left, but not in the top left 100x100
resetButton.x = 120;
resetButton.y = game.height - 120; // Keep at the bottom left
resetButton.down = function () {
// Clear collection and restart
storage.collectedFootballs = [];
// Remove inventory and pack if present
if (inventoryContainer) {
inventoryContainer.children.forEach(function (child) {
child.destroy();
});
inventoryContainer.destroy();
inventoryContainer = null;
}
if (packNode) {
packNode.destroy();
packNode = null;
}
// Reset progress display
updateCollectionProgress();
// Show inventory again
showInventory();
};
game.addChild(resetButton);
} else {
inventoryContainer.visible = true;
}
// Update the content of the inventory slots based on collected footballs
inventoryContainer.children.forEach(function (child) {
if (child instanceof InventorySlot) {
// Clear existing content in the slot
child.children.forEach(function (slotChild) {
slotChild.destroy();
});
child.children = []; // Clear children array
// Add appropriate graphic based on collection status
if (isFootballCollected(child.footballId)) {
var football = new Football(child.footballId);
football.scale.set(1.75); // Ensure scale is correct on update
football.x = child.width / 2;
football.y = child.height / 2;
child.addChild(football);
} else {
var placeholder = new Text2('?', {
size: 150,
fill: 0xFFFFFF
});
placeholder.anchor.set(0.5);
placeholder.x = child.width / 2;
placeholder.y = child.height / 2;
child.addChild(placeholder);
}
}
});
}
// Function to show the pack
function showPack() {
// Remove inventory if visible
if (inventoryContainer) {
inventoryContainer.visible = false;
}
if (!packNode) {
packNode = new Pack();
packNode.x = game.width / 2;
packNode.y = game.height / 2;
game.addChild(packNode);
} else {
packNode.visible = true;
}
}
// Initial setup
scoreTxt = new Text2('Collected: 0/0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
scoreTxt.x = LK.gui.top.width / 2;
scoreTxt.y = 100; // Offset from the very top to avoid the menu icon
LK.gui.top.addChild(scoreTxt);
updateCollectionProgress(); // Initialize the score display
showInventory(); // Start by showing the inventory
// Play background music
LK.playMusic('backgroundMusic');
// Main game loop (not needed for this simple UI game)
// game.update = function () {
// };