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;
// Always use Tralalero sound
LK.getSound('hitTrala').play();
} else if (self.y > tableBottom) {
self.y = tableBottom;
self.dy = -self.dy;
// Always use Tralalero sound
LK.getSound('hitTrala').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 = 600; // Increased spacing from 350 to 600
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 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;
// Character data
var characters = [{
name: "Bombardiro Crocodilo",
description: "Bomber plane crocodile",
difficulty: 0.5,
imageAsset: 'bombardiro',
hitSound: 'hitBomba'
}, {
name: "Tung Tung Sahur",
description: "Wooden figure with a bat",
difficulty: 0.7,
imageAsset: 'tungsahur',
hitSound: 'hitTung'
}];
// 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');
// 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;
}
// Always set the opponent to Tralalero Tralalai (using index 0)
currentOpponent = 0;
// 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('tralalero');
aiPaddle.x = tableX + tableWidth / 2 - 50;
aiPaddle.y = tableY;
aiPaddle.isAI = true;
// Set AI difficulty based on Tralalero character
aiPaddle.aiDifficulty = 0.4;
console.log("AI Difficulty: " + aiPaddle.aiDifficulty);
game.addChild(aiPaddle);
// Always remove existing status text to prevent duplicates
if (statusText) {
game.removeChild(statusText);
}
// Create new status text
statusText = new Text2("VS Tralalero Tralalai", {
size: 80,
fill: 0xFFFFFF
});
statusText.anchor.set(0.5, 0.5);
statusText.x = tableX;
statusText.y = 200;
game.addChild(statusText);
// 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
// Player has beaten the opponent
gameState = "game_over";
// Show victory
LK.setTimeout(function () {
if (statusText) {
statusText.setText("You are the Brainrot Pong Champion!");
}
}, 100);
LK.getSound('win').play();
LK.showYouWin();
} 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 actual paddle dimensions from the image if it exists
var paddleWidth;
var paddleHeight;
// Check if this is a PaddleWithImage with a character image
if (paddle.children && paddle.children.length > 0) {
// First child is the original paddle image, second might be image container
var imageContainer = paddle.children[1];
if (imageContainer && imageContainer.children && imageContainer.children.length > 0) {
var characterImage = imageContainer.children[0];
if (characterImage) {
paddleWidth = characterImage.width * characterImage.scale.x;
paddleHeight = characterImage.height * characterImage.scale.y;
}
}
}
// Fallback to default paddle dimensions if we couldn't find the image
if (!paddleWidth || !paddleHeight) {
paddleWidth = 30; // Default paddle width
paddleHeight = 150; // Default paddle height
}
// 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);
// Use player's selected character's hit sound if available, otherwise default hit sound
if (selectedCharacter && selectedCharacter.index !== undefined && characters[selectedCharacter.index].hitSound) {
LK.getSound(characters[selectedCharacter.index].hitSound).play();
} else {
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);
// Always use Tralalero sound for AI paddle
LK.getSound('hitTrala').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
@@ -284,9 +284,9 @@
var selectedCharacterIndex = -1;
self.createCharacters = function () {
// Calculate spacing based on number of characters
var totalWidth = 2048;
- var spacing = 350;
+ var spacing = 600; // Increased spacing from 350 to 600
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();
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