User prompt
just make some spacing between crocodilo and tung tung sahuur at the start menu
User prompt
just make it so that the only boss is tralalero tralalai and u can only have him as an opponent and u can only play crocodilo or tung tung tung sahur
User prompt
then do it RIGHT
User prompt
when character box "bombardiro crocodilo" is selected for each time the ball hits "bombardiro" or "bombardiropaddle" play the sound effect "hitbomba"
User prompt
NOW MAKE IT PLAY "bombardilo crocodilo" AUDIO ONLY when the character "bombardiro" IS selected and only for the hit sound effect everytime
Code edit (1 edits merged)
Please save this source code
User prompt
i dont want to hear ballerina cappucina remove it
User prompt
remove baallerina cappucina sound and assign the sounds urselves of everyone according to what they look like
User prompt
again for the green character play "hitbomba" and nothing to do with ballerina cappucina
User prompt
play "hitbomba" sound effect for green character
User prompt
you need to throughly check that each character will play its selected sound effect when it hits the ball. and i mean it take as much time as u need to do this but make sure every character plays his own unique sound effect that i already selected
User prompt
JUST MAKE EACH ONE PLAY A DIFFERENT SOUND EFFECT
User prompt
make them each seperately play their own sound that has the first 3 letters of their name after the word "hit"
User prompt
bombardiro crocodilo the crocodile one is still playing ballerina cappucinas audio and not his own which is "hitbomba" please fix
User prompt
bombardiro crocodilo should play the audio "hitbomba" when he hits the ball
User prompt
the crocodile one is supposed to play the audio "hitbomba" different than the rest
User prompt
bombardillo crocodilo is supposed to play the "hitbomba" sound
User prompt
ballerina capuccina is supposed to play the "hitball" sound
User prompt
make it so that each character plays their selected sound
User prompt
make a different hit sound asset for each character
User prompt
make the hitbox the same size as the image when it hits the ball
User prompt
delete the whole leveling system
User prompt
the level progresses after each character till its over so from 1-4
User prompt
make level go up when u beat a character and it moves on to the next until you beat all the characters and then u win
User prompt
make it so that the image paddle is way bigger but its also the same size as the paddle should be
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Ball = Container.expand(function () { var self = Container.call(this); var ballGraphics = self.attachAsset('ball', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 10; self.dx = 0; self.dy = 0; self.radius = ballGraphics.width / 2; self.active = false; self.lastX = 0; self.lastY = 0; self.lastCollidedWith = {}; // Track collisions with paddles self.reset = function () { // Clear any existing launch timer first to prevent ghost balls if (self.launchTimer) { LK.clearTimeout(self.launchTimer); self.launchTimer = null; } // Reset position to center of table self.x = tableX; self.y = tableY; // Make sure to set lastX and lastY to the same values to prevent false collisions self.lastX = self.x; self.lastY = self.y; // Reset speed and direction vectors to 0 self.dx = 0; self.dy = 0; // Explicitly deactivate ball self.active = false; // Clear collision tracking completely self.lastCollidedWith = {}; // Make sure this ball is the only active ball in the game if (game && game.children) { for (var i = 0; i < game.children.length; i++) { var child = game.children[i]; if (child !== self && child instanceof Ball) { // Remove any other balls from the game game.removeChild(child); } } } // Schedule ball to start after a delay self.launchTimer = LK.setTimeout(function () { // Only launch if this ball is still in the game if (self.parent) { self.launch(); } self.launchTimer = null; }, 1000); }; self.launch = function () { // Only launch if ball is not active and is still attached to game to prevent multiple launches if (self.active || !self.parent) return; // Launch ball at a random angle toward player or ai var angle = Math.random() * Math.PI / 4 - Math.PI / 8; // Determine direction (left or right) - use exact Math.PI value if (Math.random() < 0.5) { angle += Math.PI; } // Set reasonable initial velocity self.dx = Math.cos(angle) * self.speed; self.dy = Math.sin(angle) * self.speed; // Ensure lastX/lastY match current position before activating self.lastX = self.x; self.lastY = self.y; // Clear collision tracking completely before activating self.lastCollidedWith = {}; // Activate the ball self.active = true; // Cancel any pending launch timers to prevent duplicates if (self.launchTimer) { LK.clearTimeout(self.launchTimer); self.launchTimer = null; } }; self.update = function () { // Verify this ball is valid and active if (!self.active || !self.parent) return; // Verify this is the only active ball if (game && game.children) { var activeBalls = 0; var thisBallFound = false; for (var i = 0; i < game.children.length; i++) { var child = game.children[i]; if (child instanceof Ball) { activeBalls++; if (child === self) { thisBallFound = true; } } } // If this ball isn't found or there are multiple balls, reset if (!thisBallFound || activeBalls > 1) { // Remove extra balls and reset this one for (var i = 0; i < game.children.length; i++) { var child = game.children[i]; if (child instanceof Ball && child !== self) { game.removeChild(child); } } // If this is a ghost ball, remove it if (!thisBallFound) { return; // Exit update cycle for ghost ball } } } // Track last position for proper collision detection self.lastX = self.x; self.lastY = self.y; // Limit speed to prevent teleportation issues var maxSpeed = 25; if (Math.abs(self.dx) > maxSpeed) { self.dx = self.dx > 0 ? maxSpeed : -maxSpeed; } if (Math.abs(self.dy) > maxSpeed) { self.dy = self.dy > 0 ? maxSpeed : -maxSpeed; } // Move ball self.x += self.dx; self.y += self.dy; // Table boundaries var tableTop = tableY - tableHeight / 2 + self.radius; var tableBottom = tableY + tableHeight / 2 - self.radius; // Bounce off top and bottom if (self.y < tableTop) { self.y = tableTop; self.dy = -self.dy; LK.getSound('hit').play(); } else if (self.y > tableBottom) { self.y = tableBottom; self.dy = -self.dy; LK.getSound('hit').play(); } // Check for paddle collisions first (returns true if collision happened) var hitPlayerPaddle = checkPaddleCollision(self, playerPaddle); var hitAiPaddle = checkPaddleCollision(self, aiPaddle); // Only check for scoring if no paddle was hit this frame if (!hitPlayerPaddle && !hitAiPaddle) { // Check for scoring (left and right boundaries) var tableLeft = tableX - tableWidth / 2; var tableRight = tableX + tableWidth / 2; // Track boundary crossing for accurate scoring // Check if ball has just crossed the left boundary if (self.lastX >= tableLeft - self.radius && self.x < tableLeft - self.radius) { // AI scores - only if ball is active (wasn't already scored) if (self.active) { self.active = false; aiScore++; updateScoreDisplay(); LK.getSound('score').play(); checkGameOver(); self.reset(); } } // Check if ball has just crossed the right boundary else if (self.lastX <= tableRight + self.radius && self.x > tableRight + self.radius) { // Player scores - only if ball is active (wasn't already scored) if (self.active) { self.active = false; playerScore++; updateScoreDisplay(); LK.getSound('score').play(); checkGameOver(); self.reset(); } } } }; return self; }); var Character = Container.expand(function (name, description, imageAsset) { var self = Container.call(this); // Create the character box with image, name and description var characterBox = new CharacterBox(imageAsset, name, description); self.addChild(characterBox); // Store properties self.name = name || "Unknown Character"; self.description = description || "No description available"; self.imageAsset = imageAsset; // Add bounce animation self.startY = 0; // Initialize with 0, will be updated in first bounce LK.setInterval(function () { self.startY = self.y; // Update current position before animation tween(self, { y: self.startY - 15 }, { duration: 800, easing: tween.easeInOut, onFinish: function onFinish() { tween(self, { y: self.startY }, { duration: 800, easing: tween.easeInOut }); } }); }, 2000); // Method to set selected state self.setSelected = function (isSelected) { characterBox.setSelected(isSelected); }; // Handle click/tap self.down = function (x, y, obj) { selectCharacter(self); }; return self; }); var CharacterBox = Container.expand(function (imageAsset, name, description) { var self = Container.call(this); // Create box background var characterBox = self.attachAsset('characterBox', { anchorX: 0.5, anchorY: 0.5 }); // Assign a unique color based on the character name's length var colorOptions = [0xf4d03f, 0x3498db, 0xe74c3c, 0x2ecc71, 0x9b59b6, 0x1abc9c]; var colorIndex = name ? name.length % colorOptions.length : 0; characterBox.tint = colorOptions[colorIndex]; // Store properties self.characterName = name || "Unknown Character"; self.characterDescription = description || "No description available"; self.imageAsset = imageAsset; // Add character image if specified if (imageAsset) { var characterImage = LK.getAsset(imageAsset, { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 0.8 }); characterImage.y = -10; // Position image in the center of the box self.addChild(characterImage); } // Create empty container for description (kept to maintain layout structure) var descContainer = new Container(); descContainer.y = -characterBox.height / 2 + 80; self.addChild(descContainer); // Method to set selected state self.setSelected = function (isSelected) { if (isSelected) { characterBox.tint = 0xff0000; } else { // Get the original color from initialization var colorOptions = [0xf4d03f, 0x3498db, 0xe74c3c, 0x2ecc71, 0x9b59b6, 0x1abc9c]; var colorIndex = self.characterName ? self.characterName.length % colorOptions.length : 0; characterBox.tint = colorOptions[colorIndex]; // Restore original color } }; // Handle click/tap self.down = function (x, y, obj) { selectCharacter(self); }; return self; }); var CharacterSelectScreen = Container.expand(function () { var self = Container.call(this); var titleText = new Text2("CHOOSE YOUR WARRIOR", { size: 100, fill: 0xFFFF00 }); titleText.anchor.set(0.5, 0.5); titleText.x = 2048 / 2; titleText.y = 300; self.addChild(titleText); var characterContainers = []; var selectedCharacterIndex = -1; self.createCharacters = function () { // Calculate spacing based on number of characters var totalWidth = 2048; var spacing = 350; var startX = totalWidth / 2 - (characters.length - 1) * spacing / 2; var startY = 2732 / 2 - 200; for (var i = 0; i < characters.length; i++) { var characterContainer = new Container(); // Position characters horizontally next to each other characterContainer.x = startX + i * spacing; characterContainer.y = startY; // Create character with image, name and description var character = new Character(characters[i].name, characters[i].description, characters[i].imageAsset); character.index = i; character.difficultyLevel = characters[i].difficulty; // Store character in container for reference characterContainer.character = character; // Add the character to the container characterContainer.addChild(character); // Implement setSelected method on the container characterContainer.setSelected = function (isSelected) { this.character.setSelected(isSelected); }; characterContainer.down = function (x, y, obj) { selectCharacter(this.character); }; characterContainers.push(characterContainer); self.addChild(characterContainer); } }; self.selectCharacter = function (character) { // Deselect previous character if (selectedCharacterIndex >= 0) { characterContainers[selectedCharacterIndex].setSelected(false); } // Select new character selectedCharacterIndex = character.index; character.setSelected(true); // Animate the selected character tween(character, { scaleX: 1.2, scaleY: 1.2 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { tween(character, { scaleX: 1.0, scaleY: 1.0 }, { duration: 300, easing: tween.easeIn }); } }); // Return selected character return characters[selectedCharacterIndex]; }; return self; }); var LevelSystem = Container.expand(function () { var self = Container.call(this); // Initialize level from storage or default to 1 var currentLevel = 1; var maxLevel = 4; // Try to load level from storage when created self.loadFromStorage = function () { if (storage && storage.getItem) { var savedLevel = storage.getItem('levelSystemLevel'); if (savedLevel && !isNaN(parseInt(savedLevel))) { currentLevel = parseInt(savedLevel); // Ensure level is within valid range if (currentLevel < 1) currentLevel = 1; if (currentLevel > maxLevel) currentLevel = maxLevel; } } }; // Save level to storage self.saveToStorage = function () { if (storage && storage.setItem) { storage.setItem('levelSystemLevel', currentLevel.toString()); } }; // Load level when created self.loadFromStorage(); // Get/set current level self.getCurrentLevel = function () { return currentLevel; }; self.setLevel = function (level) { if (level >= 1 && level <= maxLevel) { currentLevel = level; // Save to storage when level changes self.saveToStorage(); // Update UI if needed if (self.levelText) { self.levelText.setText("Level: " + currentLevel); } return true; } return false; }; // Level up function self.levelUp = function () { if (currentLevel < maxLevel) { return self.setLevel(currentLevel + 1); } return false; }; // Create level display self.createLevelDisplay = function () { self.levelText = new Text2("Level: " + currentLevel, { size: 60, fill: 0xFFFFFF }); self.levelText.anchor.set(0.5, 0.5); return self.levelText; }; // Get difficulty modifier based on level self.getDifficultyModifier = function () { switch (currentLevel) { case 1: return 0.85; // Easier case 2: return 1.0; // Normal case 3: return 1.15; // Harder case 4: return 1.3; // Very hard default: return 1.0; } }; return self; }); var Paddle = Container.expand(function () { var self = Container.call(this); var paddleGraphics = self.attachAsset('paddle', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 15; self.targetY = null; self.isAI = false; self.aiDifficulty = 0.5; // Default difficulty // Give each paddle a unique ID for collision tracking self.id = "paddle_" + Date.now() + "_" + Math.random().toString(36).substr(2, 9); self.update = function () { if (self.isAI && ball) { // AI paddle movement - follows the ball with some delay based on difficulty // Higher difficulty means better tracking if (Math.random() < self.aiDifficulty) { self.targetY = ball.y; } if (self.targetY !== null) { // Move toward target position with speed adjusted by difficulty var moveSpeed = self.speed * self.aiDifficulty; if (Math.abs(self.y - self.targetY) > moveSpeed) { if (self.y < self.targetY) { self.y += moveSpeed; } else { self.y -= moveSpeed; } } else { self.y = self.targetY; } } } // Keep paddle within table bounds var halfPaddleHeight = paddleGraphics.height / 2; var tableTop = tableY - tableHeight / 2 + halfPaddleHeight; var tableBottom = tableY + tableHeight / 2 - halfPaddleHeight; if (self.y < tableTop) self.y = tableTop; if (self.y > tableBottom) self.y = tableBottom; }; return self; }); var PaddleWithImage = Paddle.expand(function (characterImageAsset) { var self = Paddle.call(this); // Add character image on top of paddle if (characterImageAsset) { // Create a container for character image var imageContainer = new Container(); self.addChild(imageContainer); // Get the paddle's dimensions var paddleWidth = 30; // Width of paddle var paddleHeight = 150; // Height of paddle // Add character image var characterImage = LK.getAsset(characterImageAsset, { anchorX: 0.5, anchorY: 0.5 }); // Now that we have the image, set its scale to cover the paddle if (characterImage && characterImage.width && characterImage.height) { // Make character image much larger but keep paddle collision size var imageWidth = paddleWidth * 8; // Make image 8x wider for better visibility var imageHeight = paddleHeight * 3; // Triple the height of the image characterImage.scale.x = imageWidth / characterImage.width; characterImage.scale.y = imageHeight / characterImage.height; } // Position the image to be visible on paddle characterImage.y = 0; imageContainer.addChild(characterImage); } return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x1a5276 }); /**** * Game Code ****/ // Game constants var tableWidth = 1600; var tableHeight = 1200; var tableX = 2048 / 2; var tableY = 2732 / 2; // Game state variables var gameState = "character_select"; // "character_select", "playing", "game_over" var playerScore = 0; var aiScore = 0; var currentOpponent = 0; var selectedCharacter = null; var lastDragY = 0; var levelSystem = null; // Character data var characters = [{ name: "Tralalero Tralala", description: "Shark in Nikes", difficulty: 0.4, imageAsset: 'tralalero' }, { name: "Bombardiro Crocodilo", description: "Bomber plane crocodile", difficulty: 0.5, imageAsset: 'bombardiro' }, { name: " Ballerina Cappuccina", description: "Elegant dancer from Italian Brainrot", difficulty: 0.6, imageAsset: 'ballerina' }, { name: "Tung Tung Sahur", description: "Wooden figure with a bat", difficulty: 0.7, imageAsset: 'tungsahur' }]; // Game elements var table; var net; var playerPaddle; var aiPaddle; var ball; var characterSelection = []; var characterSelectScreen; var playerScoreText; var aiScoreText; var statusText; // Initialize the game function initGame() { // Play background music LK.playMusic('gameMusic'); // Initialize level system if not already created if (!levelSystem) { levelSystem = new LevelSystem(); } // Always reset status text to avoid overlap if (statusText) { game.removeChild(statusText); statusText = null; } if (gameState === "character_select") { // Set a different background color for character select screen game.setBackgroundColor(0x6c3483); // Purple background for character select // Create and display character selection screen characterSelectScreen = new CharacterSelectScreen(); game.addChild(characterSelectScreen); characterSelectScreen.createCharacters(); } else { // Set game background color game.setBackgroundColor(0x1a5276); // Blue background for gameplay // Create table table = LK.getAsset('table', { anchorX: 0.5, anchorY: 0.5, x: tableX, y: tableY }); game.addChild(table); // Create net net = LK.getAsset('net', { anchorX: 0.5, anchorY: 0.5, x: tableX, y: tableY }); game.addChild(net); // Create score displays var playerScoreBoard = LK.getAsset('scoreBoard', { anchorX: 0.5, anchorY: 0.5, x: tableX - tableWidth / 4, y: tableY - tableHeight / 2 - 80 }); game.addChild(playerScoreBoard); var aiScoreBoard = LK.getAsset('scoreBoard', { anchorX: 0.5, anchorY: 0.5, x: tableX + tableWidth / 4, y: tableY - tableHeight / 2 - 80 }); game.addChild(aiScoreBoard); playerScoreText = new Text2("0", { size: 60, fill: 0xFFFFFF }); playerScoreText.anchor.set(0.5, 0.5); playerScoreText.x = tableX - tableWidth / 4; playerScoreText.y = tableY - tableHeight / 2 - 80; game.addChild(playerScoreText); aiScoreText = new Text2("0", { size: 60, fill: 0xFFFFFF }); aiScoreText.anchor.set(0.5, 0.5); aiScoreText.x = tableX + tableWidth / 4; aiScoreText.y = tableY - tableHeight / 2 - 80; game.addChild(aiScoreText); // Don't create status text at initialization since we're in character select mode } } function selectCharacter(character) { // Don't select the current opponent character if (character.index === currentOpponent) { // Flash the character to indicate it can't be selected tween(character, { alpha: 0.4 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { tween(character, { alpha: 1.0 }, { duration: 300, easing: tween.easeIn }); } }); return; // Don't proceed with selection } // If we already have a selected character, prevent selecting the same character if (selectedCharacter && character.index === selectedCharacter.index) { // Flash the character to indicate it can't be selected tween(character, { alpha: 0.4 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { tween(character, { alpha: 1.0 }, { duration: 300, easing: tween.easeIn }); } }); return; // Don't proceed with selection } // Use the CharacterSelectScreen to handle selection var selectedChar = characterSelectScreen.selectCharacter(character); selectedCharacter = character; // Make sure currentOpponent is properly set before checking it if (currentOpponent === undefined || currentOpponent === null) { currentOpponent = 0; } // Set the opponent to be a different character than the selected one var availableOpponents = []; for (var i = 0; i < characters.length; i++) { if (i !== character.index) { availableOpponents.push(i); } } // If no available opponents, return without selecting character if (availableOpponents.length === 0) { return; } // Randomly select one of the available opponents var randomIndex = Math.floor(Math.random() * availableOpponents.length); currentOpponent = availableOpponents[randomIndex]; // Start the game after a delay with animation tween(character, { alpha: 0.8 }, { duration: 500, easing: tween.easeOut, onFinish: function onFinish() { LK.setTimeout(function () { startGame(); }, 800); } }); } function startGame() { // Remove character selection screen with fade out if (characterSelectScreen) { tween(characterSelectScreen, { alpha: 0 }, { duration: 500, easing: tween.easeOut, onFinish: function onFinish() { game.removeChild(characterSelectScreen); characterSelectScreen = null; // Switch game state gameState = "playing"; // Reinitialize the game with gameplay elements game.setBackgroundColor(0x1a5276); // Blue background for gameplay initGame(); // Setup game elements playerScore = 0; aiScore = 0; currentOpponent = 0; // Remove any existing balls to prevent ghost balls if (game.children) { for (var i = game.children.length - 1; i >= 0; i--) { var child = game.children[i]; if (child instanceof Ball) { game.removeChild(child); } } } // Remove any existing paddles to prevent duplicates if (game.children) { for (var i = game.children.length - 1; i >= 0; i--) { var child = game.children[i]; if (child instanceof Paddle) { game.removeChild(child); } } } // Create paddles with character images playerPaddle = new PaddleWithImage(selectedCharacter.imageAsset); playerPaddle.x = tableX - tableWidth / 2 + 50; playerPaddle.y = tableY; game.addChild(playerPaddle); aiPaddle = new PaddleWithImage(characters[currentOpponent].imageAsset); aiPaddle.x = tableX + tableWidth / 2 - 50; aiPaddle.y = tableY; aiPaddle.isAI = true; // Apply level system difficulty modifier to the character's base difficulty var baseDifficulty = characters[currentOpponent].difficulty; var levelModifier = levelSystem.getDifficultyModifier(); aiPaddle.aiDifficulty = baseDifficulty * levelModifier; console.log("AI Difficulty: " + aiPaddle.aiDifficulty + " (Base: " + baseDifficulty + ", Level Modifier: " + levelModifier + ")"); game.addChild(aiPaddle); // Always remove existing status text to prevent duplicates if (statusText) { game.removeChild(statusText); } // Create new status text statusText = new Text2("VS " + characters[currentOpponent].name, { size: 80, fill: 0xFFFFFF }); statusText.anchor.set(0.5, 0.5); statusText.x = tableX; statusText.y = 200; game.addChild(statusText); // Add level display var levelText = levelSystem.createLevelDisplay(); levelText.x = tableX; levelText.y = 120; game.addChild(levelText); // Make sure the status text is visible statusText.alpha = 1; // Create ball ball = new Ball(); game.addChild(ball); // Reset the ball after adding to game to ensure proper initialization ball.reset(); updateScoreDisplay(); } }); } } function updateScoreDisplay() { playerScoreText.setText(playerScore.toString()); aiScoreText.setText(aiScore.toString()); } function checkGameOver() { if (playerScore >= 5) { // Player wins this round // Update opponent name only after player reaches score of 5 currentOpponent++; if (currentOpponent >= characters.length) { // Player has beaten all opponents gameState = "game_over"; // Level up if not at max level if (levelSystem.levelUp()) { // Player leveled up - restart with first opponent but at higher difficulty currentOpponent = 0; playerScore = 0; aiScore = 0; // Display level up message var levelUpMessage = "Level Up! Now Level " + levelSystem.getCurrentLevel(); // Flash the screen green to indicate level up LK.effects.flashScreen(0x00FF00, 1000); // Wait for game over screen before showing text LK.setTimeout(function () { if (statusText) { statusText.setText(levelUpMessage); } }, 100); LK.getSound('win').play(); // Restart game with new level LK.setTimeout(function () { startGame(); }, 2000); } else { // Player has reached max level - show victory // Wait for game over screen before showing text LK.setTimeout(function () { if (statusText) { statusText.setText("You are the Brainrot Pong Champion!"); } }, 100); LK.getSound('win').play(); LK.showYouWin(); } } else { // Next opponent playerScore = 0; aiScore = 0; // Apply level system difficulty modifier to the character's base difficulty var baseDifficulty = characters[currentOpponent].difficulty; var levelModifier = levelSystem.getDifficultyModifier(); aiPaddle.aiDifficulty = baseDifficulty * levelModifier; // Flash the screen gold to indicate new opponent LK.effects.flashScreen(0xFFD700, 500); // Wait for transition before updating text LK.setTimeout(function () { if (statusText) { statusText.setText("VS " + characters[currentOpponent].name); } }, 100); updateScoreDisplay(); } } else if (aiScore >= 5) { // AI wins gameState = "game_over"; // Wait for game over screen before showing text LK.setTimeout(function () { if (statusText) { statusText.setText("Game Over!"); } }, 100); LK.showGameOver(); } } function checkPaddleCollision(ball, paddle) { if (!ball.active) return false; // Return false if ball not active // Get paddle dimensions var paddleWidth = 30; // Same as in initialization var paddleHeight = 150; // Same as in initialization // Define rectangular collision box for paddle var paddleLeft = paddle.x - paddleWidth / 2; var paddleRight = paddle.x + paddleWidth / 2; var paddleTop = paddle.y - paddleHeight / 2; var paddleBottom = paddle.y + paddleHeight / 2; // Calculate ball position including radius for more accurate detection var ballLeft = ball.x - ball.radius; var ballRight = ball.x + ball.radius; var ballTop = ball.y - ball.radius; var ballBottom = ball.y + ball.radius; // Calculate last ball position for trajectory analysis var lastBallLeft = ball.lastX - ball.radius; var lastBallRight = ball.lastX + ball.radius; var lastBallTop = ball.lastY - ball.radius; var lastBallBottom = ball.lastY + ball.radius; // Check if ball is within paddle bounds var isIntersecting = ballRight > paddleLeft && ballLeft < paddleRight && ballBottom > paddleTop && ballTop < paddleBottom; // Check for fast-moving ball that might have teleported through paddle // Check both horizontal and vertical trajectories for accurate detection var crossedLeftToRight = lastBallRight <= paddleLeft && ballRight > paddleLeft && !(lastBallBottom < paddleTop || lastBallTop > paddleBottom) && !(ballBottom < paddleTop || ballTop > paddleBottom); var crossedRightToLeft = lastBallLeft >= paddleRight && ballLeft < paddleRight && !(lastBallBottom < paddleTop || lastBallTop > paddleBottom) && !(ballBottom < paddleTop || ballTop > paddleBottom); // Only process collision if ball is moving toward the paddle var movingTowardLeftPaddle = ball.dx < 0 && paddle === playerPaddle; var movingTowardRightPaddle = ball.dx > 0 && paddle === aiPaddle; // Check if this paddle was already hit in this movement var alreadyCollidedWithThisPaddle = ball.lastCollidedWith[paddle.id]; // Apply collision only on first contact, not for continuous contact var justHitPaddle = (isIntersecting || crossedLeftToRight || crossedRightToLeft) && (movingTowardLeftPaddle && paddle === playerPaddle || movingTowardRightPaddle && paddle === aiPaddle) && !alreadyCollidedWithThisPaddle; if (justHitPaddle) { // Mark this paddle as having been collided with ball.lastCollidedWith[paddle.id] = true; // For left paddle (player) if (paddle === playerPaddle) { // Ball hit paddle from right ball.x = paddleRight + ball.radius; ball.dx = Math.abs(ball.dx); // Adjust angle based on where ball hit the paddle var relativeIntersectY = paddle.y - ball.y; var normalizedRelativeIntersectionY = relativeIntersectY / (paddleHeight / 2); var bounceAngle = normalizedRelativeIntersectionY * (Math.PI / 4); // 45 degrees max angle // Adjust ball direction based on where it hit the paddle var speed = Math.sqrt(ball.dx * ball.dx + ball.dy * ball.dy); ball.dx = Math.cos(bounceAngle) * speed; ball.dy = -Math.sin(bounceAngle) * speed; // Increase speed slightly with each hit but cap it ball.dx = Math.min(Math.abs(ball.dx * 1.05), 25) * (ball.dx < 0 ? -1 : 1); ball.dy = Math.min(Math.abs(ball.dy * 1.05), 25) * (ball.dy < 0 ? -1 : 1); LK.getSound('hit').play(); // For right paddle (AI) } else if (paddle === aiPaddle) { // Ball hit paddle from left ball.x = paddleLeft - ball.radius; ball.dx = -Math.abs(ball.dx); // Adjust angle based on where ball hit the paddle var relativeIntersectY = paddle.y - ball.y; var normalizedRelativeIntersectionY = relativeIntersectY / (paddleHeight / 2); var bounceAngle = normalizedRelativeIntersectionY * (Math.PI / 4); // 45 degrees max angle // Adjust ball direction based on where it hit the paddle var speed = Math.sqrt(ball.dx * ball.dx + ball.dy * ball.dy); ball.dx = -Math.cos(bounceAngle) * speed; ball.dy = -Math.sin(bounceAngle) * speed; // Increase speed slightly with each hit but cap it ball.dx = Math.min(Math.abs(ball.dx * 1.05), 25) * (ball.dx < 0 ? -1 : 1); ball.dy = Math.min(Math.abs(ball.dy * 1.05), 25) * (ball.dy < 0 ? -1 : 1); LK.getSound('hit').play(); } // Return true to indicate collision happened return true; } else if (!justHitPaddle && !isIntersecting) { // Clear collision flag when ball is no longer intersecting with this paddle if (ball.lastCollidedWith[paddle.id]) { ball.lastCollidedWith[paddle.id] = false; } } // Return false if no collision happened return false; } // Input handling game.down = function (x, y, obj) { if (gameState === "playing") { lastDragY = y; } }; game.move = function (x, y, obj) { if (gameState === "playing" && playerPaddle) { var deltaY = y - lastDragY; playerPaddle.y += deltaY; lastDragY = y; } }; game.up = function (x, y, obj) { // Release any dragging }; // Game update function game.update = function () { if (gameState === "playing") { if (playerPaddle) playerPaddle.update(); if (aiPaddle) aiPaddle.update(); if (ball) ball.update(); } }; // Initialize the game initGame();
===================================================================
--- original.js
+++ change.js
@@ -338,18 +338,39 @@
});
var LevelSystem = Container.expand(function () {
var self = Container.call(this);
// Initialize level from storage or default to 1
- var currentLevel = storage.currentLevel || 1;
+ var currentLevel = 1;
var maxLevel = 4;
+ // Try to load level from storage when created
+ self.loadFromStorage = function () {
+ if (storage && storage.getItem) {
+ var savedLevel = storage.getItem('levelSystemLevel');
+ if (savedLevel && !isNaN(parseInt(savedLevel))) {
+ currentLevel = parseInt(savedLevel);
+ // Ensure level is within valid range
+ if (currentLevel < 1) currentLevel = 1;
+ if (currentLevel > maxLevel) currentLevel = maxLevel;
+ }
+ }
+ };
+ // Save level to storage
+ self.saveToStorage = function () {
+ if (storage && storage.setItem) {
+ storage.setItem('levelSystemLevel', currentLevel.toString());
+ }
+ };
+ // Load level when created
+ self.loadFromStorage();
// Get/set current level
self.getCurrentLevel = function () {
return currentLevel;
};
self.setLevel = function (level) {
if (level >= 1 && level <= maxLevel) {
currentLevel = level;
- storage.currentLevel = level;
+ // Save to storage when level changes
+ self.saveToStorage();
// Update UI if needed
if (self.levelText) {
self.levelText.setText("Level: " + currentLevel);
}
@@ -453,10 +474,10 @@
});
// Now that we have the image, set its scale to cover the paddle
if (characterImage && characterImage.width && characterImage.height) {
// Make character image much larger but keep paddle collision size
- var imageWidth = paddleWidth * 5; // Make image 5x wider for better visibility
- var imageHeight = paddleHeight * 2; // Double the height of the image
+ var imageWidth = paddleWidth * 8; // Make image 8x wider for better visibility
+ var imageHeight = paddleHeight * 3; // Triple the height of the image
characterImage.scale.x = imageWidth / characterImage.width;
characterImage.scale.y = imageHeight / characterImage.height;
}
// Position the image to be visible on paddle
@@ -770,8 +791,10 @@
playerScore = 0;
aiScore = 0;
// Display level up message
var levelUpMessage = "Level Up! Now Level " + levelSystem.getCurrentLevel();
+ // Flash the screen green to indicate level up
+ LK.effects.flashScreen(0x00FF00, 1000);
// Wait for game over screen before showing text
LK.setTimeout(function () {
if (statusText) {
statusText.setText(levelUpMessage);
@@ -800,8 +823,10 @@
// Apply level system difficulty modifier to the character's base difficulty
var baseDifficulty = characters[currentOpponent].difficulty;
var levelModifier = levelSystem.getDifficultyModifier();
aiPaddle.aiDifficulty = baseDifficulty * levelModifier;
+ // Flash the screen gold to indicate new opponent
+ LK.effects.flashScreen(0xFFD700, 500);
// Wait for transition before updating text
LK.setTimeout(function () {
if (statusText) {
statusText.setText("VS " + characters[currentOpponent].name);
shark with nikes on the beach. In-Game asset. 2d. High contrast. No shadows
bomber plane crocodile. In-Game asset. 2d. High contrast. No shadows
anthropomorphic wooden figure holding a baseball bat. In-Game asset. 2d. High contrast. No shadows
ping pong table only from the top with a face on it. In-Game asset. 2d. High contrast. No shadows
ball with face. In-Game asset. 2d. High contrast. No shadows