/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); var facekit = LK.import("@upit/facekit.v1"); /**** * Classes ****/ //Classes can only be defined here. You cannot create inline classes in the games code. var Block = Container.expand(function (type, gridX, gridY) { var self = Container.call(this); self.gridX = gridX; self.gridY = gridY; self.type = type; var assetId = type + 'Block'; var blockGraphics = self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5 }); // Adjust position based on grid coordinates self.x = self.gridX * BLOCK_SIZE + BLOCK_SIZE / 2; self.y = self.gridY * BLOCK_SIZE + BLOCK_SIZE / 2; return self; }); var InventorySlot = Container.expand(function (itemType) { var self = Container.call(this); self.itemType = itemType; self.attachAsset('inventorySlot', { anchorX: 0.5, anchorY: 0.5 }); self.itemIcon = self.attachAsset(itemType + 'Block', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.6, scaleY: 0.6 }); self.countText = new Text2('0', { size: 50, fill: 0xFFFFFF }); self.countText.anchor.set(0.5, 0.5); self.countText.y = 30; self.addChild(self.countText); self.updateCount = function (count) { self.countText.setText(count); }; return self; }); var Player = Container.expand(function () { var self = Container.call(this); self.gridX = 0; self.gridY = 0; var playerGraphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); self.inventory = { dirt: 0, grass: 0, stone: 0, wood: 0 }; self.heldItem = null; // What block type is currently selected to be placed // Position player based on grid coordinates self.updatePosition = function () { self.x = self.gridX * BLOCK_SIZE + BLOCK_SIZE / 2; self.y = self.gridY * BLOCK_SIZE + BLOCK_SIZE / 2; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 //Init game with black background }); /**** * Game Code ****/ //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 //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 // 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 var world = []; // 2D array to hold the blocks var player; var inventorySlots = []; var BLOCK_SIZE = 100; var GRID_WIDTH = Math.floor(2048 / BLOCK_SIZE); var GRID_HEIGHT = Math.floor(2732 / BLOCK_SIZE); game.setBackgroundColor(0x87CEEB); // Sky blue background // Generate a simple world function generateWorld() { world = []; for (var y = 0; y < GRID_HEIGHT; y++) { world[y] = []; for (var x = 0; x < GRID_WIDTH; x++) { var block = null; if (y > GRID_HEIGHT / 2) { block = new Block('dirt', x, y); } else if (y === GRID_HEIGHT / 2) { block = new Block('grass', x, y); } world[y][x] = block; if (block) { game.addChild(block); } } } } // Initialize player player = new Player(); player.gridX = Math.floor(GRID_WIDTH / 2); player.gridY = Math.floor(GRID_HEIGHT / 2) - 1; // Place above ground player.updatePosition(); game.addChild(player); // Initialize inventory UI function setupInventoryUI() { var items = ['dirt', 'grass', 'stone', 'wood']; var startX = 150; // Offset from left edge, outside the menu area var startY = 2600; // Near the bottom for (var i = 0; i < items.length; i++) { var slot = new InventorySlot(items[i]); slot.x = startX + i * 140; slot.y = startY; inventorySlots.push(slot); LK.gui.addChild(slot); } } // Update inventory display function updateInventoryUI() { for (var i = 0; i < inventorySlots.length; i++) { var slot = inventorySlots[i]; slot.updateCount(player.inventory[slot.itemType]); } } // Handle tapping the screen game.down = function (x, y, obj) { // Convert screen coordinates to game coordinates var gameCoords = game.toLocal({ x: x, y: y }); // Convert game coordinates to grid coordinates var gridX = Math.floor(gameCoords.x / BLOCK_SIZE); var gridY = Math.floor(gameCoords.y / BLOCK_SIZE); // Check if tap is within the game grid and outside the top-left menu area if (gridX >= 0 && gridX < GRID_WIDTH && gridY >= 0 && gridY < GRID_HEIGHT && gameCoords.x > 100 && gameCoords.y > 100) { var block = world[gridY] && world[gridY][gridX]; if (player.heldItem) { // Place block if (!block) { // Check if player is adjacent to the placement location (simplified) var dx = Math.abs(player.gridX - gridX); var dy = Math.abs(player.gridY - gridY); if (dx <= 1 && dy === 0 || dx === 0 && dy <= 1 || dx <= 1 && dy <= 1) { // Allow diagonal placement for simplicity if (player.inventory[player.heldItem] > 0) { var newBlock = new Block(player.heldItem, gridX, gridY); world[gridY][gridX] = newBlock; game.addChild(newBlock); player.inventory[player.heldItem]--; updateInventoryUI(); LK.getSound('place').play(); } } } } else if (block) { // Mine block // Check if player is adjacent to the block (simplified) var dx = Math.abs(player.gridX - gridX); var dy = Math.abs(player.gridY - gridY); if (dx <= 1 && dy === 0 || dx === 0 && dy <= 1 || dx <= 1 && dy <= 1) { // Allow diagonal mining for simplicity player.inventory[block.type]++; updateInventoryUI(); block.destroy(); world[gridY][gridX] = null; LK.getSound('mine').play(); } } } // Check if a tap is on an inventory slot for (var i = 0; i < inventorySlots.length; i++) { var slot = inventorySlots[i]; var slotBounds = slot.getBounds(); // Get global bounds of the slot if (x >= slotBounds.x && x <= slotBounds.x + slotBounds.width && y >= slotBounds.y && y <= slotBounds.y + slotBounds.height) { if (player.heldItem === slot.itemType) { player.heldItem = null; // Deselect slot.alpha = 1; // Reset alpha } else { // Deselect previously held item if any if (player.heldItem) { for (var j = 0; j < inventorySlots.length; j++) { if (inventorySlots[j].itemType === player.heldItem) { inventorySlots[j].alpha = 1; break; } } } player.heldItem = slot.itemType; // Select slot.alpha = 0.7; // Indicate selected } break; // Only interact with one slot at a time } } }; // Game update loop game.update = function () { // Basic player movement (example, can be expanded with controls) // Player follows horizontal movement of a facial feature (e.g., noseTip) if (facekit && facekit.noseTip && facekit.noseTip.x > 0) { var targetGridX = Math.floor(facekit.noseTip.x / BLOCK_SIZE); if (targetGridX < 0) { targetGridX = 0; } if (targetGridX >= GRID_WIDTH) { targetGridX = GRID_WIDTH - 1; } // Simple movement to the target grid cell if (player.gridX < targetGridX) { player.gridX++; } else if (player.gridX > targetGridX) { player.gridX--; } // Prevent player from moving into occupied blocks (basic collision) var blockBelow = world[player.gridY + 1] && world[player.gridY + 1][player.gridX]; if (!blockBelow && player.gridY < GRID_HEIGHT - 1) { player.gridY++; // Gravity } else if (blockBelow && player.gridY > 0) { // Stay on top of the block } player.updatePosition(); } }; // Initial world generation and UI setup generateWorld(); setupInventoryUI(); updateInventoryUI(); // Play background music LK.playMusic('backgroundMusic');
===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,250 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+var storage = LK.import("@upit/storage.v1");
+var facekit = LK.import("@upit/facekit.v1");
+
+/****
+* Classes
+****/
+//Classes can only be defined here. You cannot create inline classes in the games code.
+var Block = Container.expand(function (type, gridX, gridY) {
+ var self = Container.call(this);
+ self.gridX = gridX;
+ self.gridY = gridY;
+ self.type = type;
+ var assetId = type + 'Block';
+ var blockGraphics = self.attachAsset(assetId, {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ // Adjust position based on grid coordinates
+ self.x = self.gridX * BLOCK_SIZE + BLOCK_SIZE / 2;
+ self.y = self.gridY * BLOCK_SIZE + BLOCK_SIZE / 2;
+ return self;
+});
+var InventorySlot = Container.expand(function (itemType) {
+ var self = Container.call(this);
+ self.itemType = itemType;
+ self.attachAsset('inventorySlot', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.itemIcon = self.attachAsset(itemType + 'Block', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 0.6,
+ scaleY: 0.6
+ });
+ self.countText = new Text2('0', {
+ size: 50,
+ fill: 0xFFFFFF
+ });
+ self.countText.anchor.set(0.5, 0.5);
+ self.countText.y = 30;
+ self.addChild(self.countText);
+ self.updateCount = function (count) {
+ self.countText.setText(count);
+ };
+ return self;
+});
+var Player = Container.expand(function () {
+ var self = Container.call(this);
+ self.gridX = 0;
+ self.gridY = 0;
+ var playerGraphics = self.attachAsset('player', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.inventory = {
+ dirt: 0,
+ grass: 0,
+ stone: 0,
+ wood: 0
+ };
+ self.heldItem = null; // What block type is currently selected to be placed
+ // Position player based on grid coordinates
+ self.updatePosition = function () {
+ self.x = self.gridX * BLOCK_SIZE + BLOCK_SIZE / 2;
+ self.y = self.gridY * BLOCK_SIZE + BLOCK_SIZE / 2;
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x000000 //Init game with black background
+});
+
+/****
+* Game Code
+****/
+//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
+//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
+// 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
+var world = []; // 2D array to hold the blocks
+var player;
+var inventorySlots = [];
+var BLOCK_SIZE = 100;
+var GRID_WIDTH = Math.floor(2048 / BLOCK_SIZE);
+var GRID_HEIGHT = Math.floor(2732 / BLOCK_SIZE);
+game.setBackgroundColor(0x87CEEB); // Sky blue background
+// Generate a simple world
+function generateWorld() {
+ world = [];
+ for (var y = 0; y < GRID_HEIGHT; y++) {
+ world[y] = [];
+ for (var x = 0; x < GRID_WIDTH; x++) {
+ var block = null;
+ if (y > GRID_HEIGHT / 2) {
+ block = new Block('dirt', x, y);
+ } else if (y === GRID_HEIGHT / 2) {
+ block = new Block('grass', x, y);
+ }
+ world[y][x] = block;
+ if (block) {
+ game.addChild(block);
+ }
+ }
+ }
+}
+// Initialize player
+player = new Player();
+player.gridX = Math.floor(GRID_WIDTH / 2);
+player.gridY = Math.floor(GRID_HEIGHT / 2) - 1; // Place above ground
+player.updatePosition();
+game.addChild(player);
+// Initialize inventory UI
+function setupInventoryUI() {
+ var items = ['dirt', 'grass', 'stone', 'wood'];
+ var startX = 150; // Offset from left edge, outside the menu area
+ var startY = 2600; // Near the bottom
+ for (var i = 0; i < items.length; i++) {
+ var slot = new InventorySlot(items[i]);
+ slot.x = startX + i * 140;
+ slot.y = startY;
+ inventorySlots.push(slot);
+ LK.gui.addChild(slot);
+ }
+}
+// Update inventory display
+function updateInventoryUI() {
+ for (var i = 0; i < inventorySlots.length; i++) {
+ var slot = inventorySlots[i];
+ slot.updateCount(player.inventory[slot.itemType]);
+ }
+}
+// Handle tapping the screen
+game.down = function (x, y, obj) {
+ // Convert screen coordinates to game coordinates
+ var gameCoords = game.toLocal({
+ x: x,
+ y: y
+ });
+ // Convert game coordinates to grid coordinates
+ var gridX = Math.floor(gameCoords.x / BLOCK_SIZE);
+ var gridY = Math.floor(gameCoords.y / BLOCK_SIZE);
+ // Check if tap is within the game grid and outside the top-left menu area
+ if (gridX >= 0 && gridX < GRID_WIDTH && gridY >= 0 && gridY < GRID_HEIGHT && gameCoords.x > 100 && gameCoords.y > 100) {
+ var block = world[gridY] && world[gridY][gridX];
+ if (player.heldItem) {
+ // Place block
+ if (!block) {
+ // Check if player is adjacent to the placement location (simplified)
+ var dx = Math.abs(player.gridX - gridX);
+ var dy = Math.abs(player.gridY - gridY);
+ if (dx <= 1 && dy === 0 || dx === 0 && dy <= 1 || dx <= 1 && dy <= 1) {
+ // Allow diagonal placement for simplicity
+ if (player.inventory[player.heldItem] > 0) {
+ var newBlock = new Block(player.heldItem, gridX, gridY);
+ world[gridY][gridX] = newBlock;
+ game.addChild(newBlock);
+ player.inventory[player.heldItem]--;
+ updateInventoryUI();
+ LK.getSound('place').play();
+ }
+ }
+ }
+ } else if (block) {
+ // Mine block
+ // Check if player is adjacent to the block (simplified)
+ var dx = Math.abs(player.gridX - gridX);
+ var dy = Math.abs(player.gridY - gridY);
+ if (dx <= 1 && dy === 0 || dx === 0 && dy <= 1 || dx <= 1 && dy <= 1) {
+ // Allow diagonal mining for simplicity
+ player.inventory[block.type]++;
+ updateInventoryUI();
+ block.destroy();
+ world[gridY][gridX] = null;
+ LK.getSound('mine').play();
+ }
+ }
+ }
+ // Check if a tap is on an inventory slot
+ for (var i = 0; i < inventorySlots.length; i++) {
+ var slot = inventorySlots[i];
+ var slotBounds = slot.getBounds(); // Get global bounds of the slot
+ if (x >= slotBounds.x && x <= slotBounds.x + slotBounds.width && y >= slotBounds.y && y <= slotBounds.y + slotBounds.height) {
+ if (player.heldItem === slot.itemType) {
+ player.heldItem = null; // Deselect
+ slot.alpha = 1; // Reset alpha
+ } else {
+ // Deselect previously held item if any
+ if (player.heldItem) {
+ for (var j = 0; j < inventorySlots.length; j++) {
+ if (inventorySlots[j].itemType === player.heldItem) {
+ inventorySlots[j].alpha = 1;
+ break;
+ }
+ }
+ }
+ player.heldItem = slot.itemType; // Select
+ slot.alpha = 0.7; // Indicate selected
+ }
+ break; // Only interact with one slot at a time
+ }
+ }
+};
+// Game update loop
+game.update = function () {
+ // Basic player movement (example, can be expanded with controls)
+ // Player follows horizontal movement of a facial feature (e.g., noseTip)
+ if (facekit && facekit.noseTip && facekit.noseTip.x > 0) {
+ var targetGridX = Math.floor(facekit.noseTip.x / BLOCK_SIZE);
+ if (targetGridX < 0) {
+ targetGridX = 0;
+ }
+ if (targetGridX >= GRID_WIDTH) {
+ targetGridX = GRID_WIDTH - 1;
+ }
+ // Simple movement to the target grid cell
+ if (player.gridX < targetGridX) {
+ player.gridX++;
+ } else if (player.gridX > targetGridX) {
+ player.gridX--;
+ }
+ // Prevent player from moving into occupied blocks (basic collision)
+ var blockBelow = world[player.gridY + 1] && world[player.gridY + 1][player.gridX];
+ if (!blockBelow && player.gridY < GRID_HEIGHT - 1) {
+ player.gridY++; // Gravity
+ } else if (blockBelow && player.gridY > 0) {
+ // Stay on top of the block
+ }
+ player.updatePosition();
+ }
+};
+// Initial world generation and UI setup
+generateWorld();
+setupInventoryUI();
+updateInventoryUI();
+// Play background music
+LK.playMusic('backgroundMusic');
\ No newline at end of file