User prompt
the ball still goes trough the players
User prompt
stop the ball from going trough players
User prompt
Player to the right is controlled by human and the player to the left is cpu
Code edit (1 edits merged)
Please save this source code
User prompt
Tennis Championship
User prompt
Not 6 games. Player that wins the first set wins the game
User prompt
Sorry, first to 6 game/1 set wins the match
Initial prompt
A classic pong game but with two actual tennis players on an actual tennis court. A referee, audience and a ball. Points sytem like in a real tennis game. First to 6 sets wins.
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var AIPaddle = Container.expand(function () {
var self = Container.call(this);
var paddleGraphics = self.attachAsset('aiPaddle', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8;
self.difficulty = 0.7;
self.update = function () {
if (ball && ball.velocityX > 0) {
var targetY = ball.y + (Math.random() - 0.5) * 100 * (1 - self.difficulty);
var diff = targetY - self.y;
var moveSpeed = self.speed * self.difficulty;
if (Math.abs(diff) > 10) {
if (diff > 0) {
self.y += moveSpeed;
} else {
self.y -= moveSpeed;
}
}
}
// Keep AI paddle within court bounds
if (self.y < courtTop + 60) self.y = courtTop + 60;
if (self.y > courtBottom - 60) self.y = courtBottom - 60;
};
return self;
});
var PlayerPaddle = Container.expand(function () {
var self = Container.call(this);
var paddleGraphics = self.attachAsset('playerPaddle', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 15;
self.targetY = 0;
self.update = function () {
var diff = self.targetY - self.y;
if (Math.abs(diff) > 5) {
self.y += diff * 0.15;
}
};
return self;
});
var TennisBall = Container.expand(function () {
var self = Container.call(this);
var ballGraphics = self.attachAsset('ball', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityX = 0;
self.velocityY = 0;
self.speed = 12;
self.lastPlayerHit = null;
self.reset = function () {
self.x = 1024;
self.y = 1366;
self.velocityX = (Math.random() > 0.5 ? 1 : -1) * self.speed;
self.velocityY = (Math.random() - 0.5) * 8;
self.lastPlayerHit = null;
};
self.update = function () {
self.x += self.velocityX;
self.y += self.velocityY;
// Ball collision with top and bottom court boundaries
if (self.y <= courtTop || self.y >= courtBottom) {
self.velocityY = -self.velocityY;
self.y = self.y <= courtTop ? courtTop : courtBottom;
}
// Ball collision with player paddle
if (self.x <= playerPaddle.x + 20 && self.x >= playerPaddle.x - 20 && self.y >= playerPaddle.y - 60 && self.y <= playerPaddle.y + 60 && self.velocityX < 0) {
self.velocityX = -self.velocityX * 1.05;
self.velocityY += (self.y - playerPaddle.y) * 0.1;
self.lastPlayerHit = 'player';
LK.getSound('hitBall').play();
rallyCount++;
}
// Ball collision with AI paddle
if (self.x >= aiPaddle.x - 20 && self.x <= aiPaddle.x + 20 && self.y >= aiPaddle.y - 60 && self.y <= aiPaddle.y + 60 && self.velocityX > 0) {
self.velocityX = -self.velocityX * 1.05;
self.velocityY += (self.y - aiPaddle.y) * 0.1;
self.lastPlayerHit = 'ai';
LK.getSound('hitBall').play();
rallyCount++;
}
// Ball out of bounds - score point
if (self.x < courtLeft - 50) {
scorePoint('ai');
} else if (self.x > courtRight + 50) {
scorePoint('player');
}
// Limit ball speed
var maxSpeed = 20;
if (Math.abs(self.velocityX) > maxSpeed) {
self.velocityX = self.velocityX > 0 ? maxSpeed : -maxSpeed;
}
if (Math.abs(self.velocityY) > maxSpeed) {
self.velocityY = self.velocityY > 0 ? maxSpeed : -maxSpeed;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x228B22
});
/****
* Game Code
****/
// Game variables
var playerScore = 0;
var aiScore = 0;
var playerGames = 0;
var aiGames = 0;
var rallyCount = 0;
var gameInProgress = true;
// Court dimensions
var courtLeft = 124;
var courtRight = 1924;
var courtTop = 766;
var courtBottom = 1966;
// Create court
var court = game.addChild(LK.getAsset('court', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366
}));
// Create net
var net = game.addChild(LK.getAsset('net', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366
}));
// Create court lines
var topLine = game.addChild(LK.getAsset('courtLine', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: courtTop
}));
var bottomLine = game.addChild(LK.getAsset('courtLine', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: courtBottom
}));
var leftLine = game.addChild(LK.getAsset('sideLine', {
anchorX: 0.5,
anchorY: 0.5,
x: courtLeft,
y: 1366
}));
var rightLine = game.addChild(LK.getAsset('sideLine', {
anchorX: 0.5,
anchorY: 0.5,
x: courtRight,
y: 1366
}));
// Service lines
var leftServiceLine = game.addChild(LK.getAsset('serviceLine', {
anchorX: 0.5,
anchorY: 0.5,
x: 574,
y: 1366
}));
var rightServiceLine = game.addChild(LK.getAsset('serviceLine', {
anchorX: 0.5,
anchorY: 0.5,
x: 1474,
y: 1366
}));
// Center service line
var centerServiceLine = game.addChild(LK.getAsset('centerLine', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1216
}));
// Create paddles
var playerPaddle = game.addChild(new PlayerPaddle());
playerPaddle.x = 200;
playerPaddle.y = 1366;
var aiPaddle = game.addChild(new AIPaddle());
aiPaddle.x = 1848;
aiPaddle.y = 1366;
// Create ball
var ball = game.addChild(new TennisBall());
ball.reset();
// Score display
var scoreText = new Text2('0 - 0', {
size: 80,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
var gameScoreText = new Text2('Games: 0 - 0', {
size: 60,
fill: 0xFFFFFF
});
gameScoreText.anchor.set(0.5, 0);
gameScoreText.y = 100;
LK.gui.top.addChild(gameScoreText);
// Touch controls
var dragActive = false;
game.down = function (x, y, obj) {
if (gameInProgress) {
dragActive = true;
playerPaddle.targetY = y;
}
};
game.move = function (x, y, obj) {
if (dragActive && gameInProgress) {
playerPaddle.targetY = y;
// Keep paddle within court bounds
if (playerPaddle.targetY < courtTop + 60) playerPaddle.targetY = courtTop + 60;
if (playerPaddle.targetY > courtBottom - 60) playerPaddle.targetY = courtBottom - 60;
}
};
game.up = function (x, y, obj) {
dragActive = false;
};
// Tennis scoring system
var scoreNames = ['0', '15', '30', '40'];
function getScoreText() {
var playerScoreStr, aiScoreStr;
if (playerScore >= 3 && aiScore >= 3) {
// Deuce situation
if (playerScore === aiScore) {
return 'Deuce';
} else if (playerScore > aiScore) {
return 'Player Advantage';
} else {
return 'AI Advantage';
}
} else {
playerScoreStr = playerScore >= 4 ? '40' : scoreNames[playerScore];
aiScoreStr = aiScore >= 4 ? '40' : scoreNames[aiScore];
return playerScoreStr + ' - ' + aiScoreStr;
}
}
function scorePoint(winner) {
if (!gameInProgress) return;
LK.getSound('scorePoint').play();
if (winner === 'player') {
playerScore++;
} else {
aiScore++;
}
// Check if game is won
var gameWon = false;
if ((playerScore >= 4 || aiScore >= 4) && Math.abs(playerScore - aiScore) >= 2) {
gameWon = true;
if (playerScore > aiScore) {
playerGames++;
} else {
aiGames++;
}
// Reset point scores
playerScore = 0;
aiScore = 0;
}
// Check if set is won
if (gameWon) {
if ((playerGames >= 6 || aiGames >= 6) && Math.abs(playerGames - aiGames) >= 2) {
// Set won
gameInProgress = false;
if (playerGames > aiGames) {
LK.showYouWin();
} else {
LK.showGameOver();
}
} else if (playerGames === 6 && aiGames === 6) {
// Tiebreaker (simplified - first to 7 points wins)
// For simplicity, we'll just continue normal game scoring
}
}
// Update score displays
scoreText.setText(getScoreText());
gameScoreText.setText('Games: ' + playerGames + ' - ' + aiGames);
// Reset ball and adjust AI difficulty
rallyCount = 0;
aiPaddle.difficulty = Math.min(0.9, 0.5 + (playerGames + aiGames) * 0.05);
ball.reset();
}
game.update = function () {
if (!gameInProgress) return;
// Update score display
scoreText.setText(getScoreText());
gameScoreText.setText('Games: ' + playerGames + ' - ' + aiGames);
}; ===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,303 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+
+/****
+* Classes
+****/
+var AIPaddle = Container.expand(function () {
+ var self = Container.call(this);
+ var paddleGraphics = self.attachAsset('aiPaddle', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = 8;
+ self.difficulty = 0.7;
+ self.update = function () {
+ if (ball && ball.velocityX > 0) {
+ var targetY = ball.y + (Math.random() - 0.5) * 100 * (1 - self.difficulty);
+ var diff = targetY - self.y;
+ var moveSpeed = self.speed * self.difficulty;
+ if (Math.abs(diff) > 10) {
+ if (diff > 0) {
+ self.y += moveSpeed;
+ } else {
+ self.y -= moveSpeed;
+ }
+ }
+ }
+ // Keep AI paddle within court bounds
+ if (self.y < courtTop + 60) self.y = courtTop + 60;
+ if (self.y > courtBottom - 60) self.y = courtBottom - 60;
+ };
+ return self;
+});
+var PlayerPaddle = Container.expand(function () {
+ var self = Container.call(this);
+ var paddleGraphics = self.attachAsset('playerPaddle', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = 15;
+ self.targetY = 0;
+ self.update = function () {
+ var diff = self.targetY - self.y;
+ if (Math.abs(diff) > 5) {
+ self.y += diff * 0.15;
+ }
+ };
+ return self;
+});
+var TennisBall = Container.expand(function () {
+ var self = Container.call(this);
+ var ballGraphics = self.attachAsset('ball', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.velocityX = 0;
+ self.velocityY = 0;
+ self.speed = 12;
+ self.lastPlayerHit = null;
+ self.reset = function () {
+ self.x = 1024;
+ self.y = 1366;
+ self.velocityX = (Math.random() > 0.5 ? 1 : -1) * self.speed;
+ self.velocityY = (Math.random() - 0.5) * 8;
+ self.lastPlayerHit = null;
+ };
+ self.update = function () {
+ self.x += self.velocityX;
+ self.y += self.velocityY;
+ // Ball collision with top and bottom court boundaries
+ if (self.y <= courtTop || self.y >= courtBottom) {
+ self.velocityY = -self.velocityY;
+ self.y = self.y <= courtTop ? courtTop : courtBottom;
+ }
+ // Ball collision with player paddle
+ if (self.x <= playerPaddle.x + 20 && self.x >= playerPaddle.x - 20 && self.y >= playerPaddle.y - 60 && self.y <= playerPaddle.y + 60 && self.velocityX < 0) {
+ self.velocityX = -self.velocityX * 1.05;
+ self.velocityY += (self.y - playerPaddle.y) * 0.1;
+ self.lastPlayerHit = 'player';
+ LK.getSound('hitBall').play();
+ rallyCount++;
+ }
+ // Ball collision with AI paddle
+ if (self.x >= aiPaddle.x - 20 && self.x <= aiPaddle.x + 20 && self.y >= aiPaddle.y - 60 && self.y <= aiPaddle.y + 60 && self.velocityX > 0) {
+ self.velocityX = -self.velocityX * 1.05;
+ self.velocityY += (self.y - aiPaddle.y) * 0.1;
+ self.lastPlayerHit = 'ai';
+ LK.getSound('hitBall').play();
+ rallyCount++;
+ }
+ // Ball out of bounds - score point
+ if (self.x < courtLeft - 50) {
+ scorePoint('ai');
+ } else if (self.x > courtRight + 50) {
+ scorePoint('player');
+ }
+ // Limit ball speed
+ var maxSpeed = 20;
+ if (Math.abs(self.velocityX) > maxSpeed) {
+ self.velocityX = self.velocityX > 0 ? maxSpeed : -maxSpeed;
+ }
+ if (Math.abs(self.velocityY) > maxSpeed) {
+ self.velocityY = self.velocityY > 0 ? maxSpeed : -maxSpeed;
+ }
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x228B22
+});
+
+/****
+* Game Code
+****/
+// Game variables
+var playerScore = 0;
+var aiScore = 0;
+var playerGames = 0;
+var aiGames = 0;
+var rallyCount = 0;
+var gameInProgress = true;
+// Court dimensions
+var courtLeft = 124;
+var courtRight = 1924;
+var courtTop = 766;
+var courtBottom = 1966;
+// Create court
+var court = game.addChild(LK.getAsset('court', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: 1024,
+ y: 1366
+}));
+// Create net
+var net = game.addChild(LK.getAsset('net', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: 1024,
+ y: 1366
+}));
+// Create court lines
+var topLine = game.addChild(LK.getAsset('courtLine', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: 1024,
+ y: courtTop
+}));
+var bottomLine = game.addChild(LK.getAsset('courtLine', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: 1024,
+ y: courtBottom
+}));
+var leftLine = game.addChild(LK.getAsset('sideLine', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: courtLeft,
+ y: 1366
+}));
+var rightLine = game.addChild(LK.getAsset('sideLine', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: courtRight,
+ y: 1366
+}));
+// Service lines
+var leftServiceLine = game.addChild(LK.getAsset('serviceLine', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: 574,
+ y: 1366
+}));
+var rightServiceLine = game.addChild(LK.getAsset('serviceLine', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: 1474,
+ y: 1366
+}));
+// Center service line
+var centerServiceLine = game.addChild(LK.getAsset('centerLine', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: 1024,
+ y: 1216
+}));
+// Create paddles
+var playerPaddle = game.addChild(new PlayerPaddle());
+playerPaddle.x = 200;
+playerPaddle.y = 1366;
+var aiPaddle = game.addChild(new AIPaddle());
+aiPaddle.x = 1848;
+aiPaddle.y = 1366;
+// Create ball
+var ball = game.addChild(new TennisBall());
+ball.reset();
+// Score display
+var scoreText = new Text2('0 - 0', {
+ size: 80,
+ fill: 0xFFFFFF
+});
+scoreText.anchor.set(0.5, 0);
+LK.gui.top.addChild(scoreText);
+var gameScoreText = new Text2('Games: 0 - 0', {
+ size: 60,
+ fill: 0xFFFFFF
+});
+gameScoreText.anchor.set(0.5, 0);
+gameScoreText.y = 100;
+LK.gui.top.addChild(gameScoreText);
+// Touch controls
+var dragActive = false;
+game.down = function (x, y, obj) {
+ if (gameInProgress) {
+ dragActive = true;
+ playerPaddle.targetY = y;
+ }
+};
+game.move = function (x, y, obj) {
+ if (dragActive && gameInProgress) {
+ playerPaddle.targetY = y;
+ // Keep paddle within court bounds
+ if (playerPaddle.targetY < courtTop + 60) playerPaddle.targetY = courtTop + 60;
+ if (playerPaddle.targetY > courtBottom - 60) playerPaddle.targetY = courtBottom - 60;
+ }
+};
+game.up = function (x, y, obj) {
+ dragActive = false;
+};
+// Tennis scoring system
+var scoreNames = ['0', '15', '30', '40'];
+function getScoreText() {
+ var playerScoreStr, aiScoreStr;
+ if (playerScore >= 3 && aiScore >= 3) {
+ // Deuce situation
+ if (playerScore === aiScore) {
+ return 'Deuce';
+ } else if (playerScore > aiScore) {
+ return 'Player Advantage';
+ } else {
+ return 'AI Advantage';
+ }
+ } else {
+ playerScoreStr = playerScore >= 4 ? '40' : scoreNames[playerScore];
+ aiScoreStr = aiScore >= 4 ? '40' : scoreNames[aiScore];
+ return playerScoreStr + ' - ' + aiScoreStr;
+ }
+}
+function scorePoint(winner) {
+ if (!gameInProgress) return;
+ LK.getSound('scorePoint').play();
+ if (winner === 'player') {
+ playerScore++;
+ } else {
+ aiScore++;
+ }
+ // Check if game is won
+ var gameWon = false;
+ if ((playerScore >= 4 || aiScore >= 4) && Math.abs(playerScore - aiScore) >= 2) {
+ gameWon = true;
+ if (playerScore > aiScore) {
+ playerGames++;
+ } else {
+ aiGames++;
+ }
+ // Reset point scores
+ playerScore = 0;
+ aiScore = 0;
+ }
+ // Check if set is won
+ if (gameWon) {
+ if ((playerGames >= 6 || aiGames >= 6) && Math.abs(playerGames - aiGames) >= 2) {
+ // Set won
+ gameInProgress = false;
+ if (playerGames > aiGames) {
+ LK.showYouWin();
+ } else {
+ LK.showGameOver();
+ }
+ } else if (playerGames === 6 && aiGames === 6) {
+ // Tiebreaker (simplified - first to 7 points wins)
+ // For simplicity, we'll just continue normal game scoring
+ }
+ }
+ // Update score displays
+ scoreText.setText(getScoreText());
+ gameScoreText.setText('Games: ' + playerGames + ' - ' + aiGames);
+ // Reset ball and adjust AI difficulty
+ rallyCount = 0;
+ aiPaddle.difficulty = Math.min(0.9, 0.5 + (playerGames + aiGames) * 0.05);
+ ball.reset();
+}
+game.update = function () {
+ if (!gameInProgress) return;
+ // Update score display
+ scoreText.setText(getScoreText());
+ gameScoreText.setText('Games: ' + playerGames + ' - ' + aiGames);
+};
\ No newline at end of file
pixel art tennis ball. In-Game asset. 2d. High contrast. No shadows
tennis referee, Top-down perspective, pixelart. In-Game asset. 2d. High contrast. No shadows
pixelart tennis player looking to the right. In-Game asset. 2d. High contrast. No shadows
pixelart tennis player looking to the left. In-Game asset. 2d. High contrast. No shadows
pixelart tennis audience, looking down. In-Game asset. 2d. High contrast. No shadows
playerHit
Sound effect
aiHit
Sound effect
audienceCheer
Sound effect
audienceCheerExtra
Sound effect
scoreDeuce
Sound effect
scorePlayerAdvantage
Sound effect
scoreAIAdvantage
Sound effect
scorePoint
Sound effect
audienceCheerMatch
Sound effect
refMatchWin
Sound effect
victoryMusic
Music