@@ -23,20 +23,16 @@ let ballSpeedY = 3;
2323let leftScore = 0 ;
2424let rightScore = 0 ;
2525let upPressed = false , downPressed = false , wPressed = false , sPressed = false ;
26- let running = true ;
2726
28- // Touch/mouse for right paddle
29- let dragging = false ;
27+ // Simple AI difficulty (pixels per frame)
28+ const AI_SPEED = 5 ;
3029
3130function draw ( ) {
32- // Clear
3331 ctx . clearRect ( 0 , 0 , canvas . width , canvas . height ) ;
3432
35- // Field
3633 ctx . fillStyle = "#222" ;
3734 ctx . fillRect ( 0 , 0 , canvas . width , canvas . height ) ;
3835
39- // Middle line
4036 ctx . setLineDash ( [ 8 , 8 ] ) ;
4137 ctx . strokeStyle = "#00e676" ;
4238 ctx . beginPath ( ) ;
@@ -45,19 +41,16 @@ function draw() {
4541 ctx . stroke ( ) ;
4642 ctx . setLineDash ( [ ] ) ;
4743
48- // Scores
4944 ctx . font = "bold 28px 'Segoe UI', Arial" ;
5045 ctx . fillStyle = "#00e676" ;
5146 ctx . textAlign = "center" ;
5247 ctx . fillText ( leftScore , canvas . width / 4 , 40 ) ;
5348 ctx . fillText ( rightScore , canvas . width * 3 / 4 , 40 ) ;
5449
55- // Paddles
5650 ctx . fillStyle = "#fff" ;
5751 ctx . fillRect ( 18 , leftY , PADDLE_WIDTH , PADDLE_HEIGHT ) ;
5852 ctx . fillRect ( canvas . width - 18 - PADDLE_WIDTH , rightY , PADDLE_WIDTH , PADDLE_HEIGHT ) ;
5953
60- // Ball
6154 ctx . beginPath ( ) ;
6255 ctx . arc ( ballX , ballY , BALL_RADIUS , 0 , Math . PI * 2 ) ;
6356 ctx . fillStyle = "#fff" ;
@@ -68,12 +61,19 @@ function draw() {
6861}
6962
7063function update ( ) {
71- if ( ! running ) return ;
72- // Left paddle movement
64+ // Player paddle movement (left)
7365 if ( wPressed || upPressed ) leftY -= 6 ;
7466 if ( sPressed || downPressed ) leftY += 6 ;
7567 leftY = Math . max ( 0 , Math . min ( canvas . height - PADDLE_HEIGHT , leftY ) ) ;
7668
69+ // AI paddle movement (right)
70+ if ( rightY + PADDLE_HEIGHT / 2 < ballY - 10 ) {
71+ rightY += AI_SPEED ;
72+ } else if ( rightY + PADDLE_HEIGHT / 2 > ballY + 10 ) {
73+ rightY -= AI_SPEED ;
74+ }
75+ rightY = Math . max ( 0 , Math . min ( canvas . height - PADDLE_HEIGHT , rightY ) ) ;
76+
7777 // Ball movement
7878 ballX += ballSpeedX ;
7979 ballY += ballSpeedY ;
@@ -137,43 +137,12 @@ document.addEventListener('keyup', (e) => {
137137 if ( e . key . toLowerCase ( ) === 's' ) sPressed = false ;
138138} ) ;
139139
140- // Touch for right paddle (mobile)
141- canvas . addEventListener ( 'touchstart' , function ( e ) {
142- dragging = true ;
143- } ) ;
144- canvas . addEventListener ( 'touchend' , function ( e ) {
145- dragging = false ;
146- } ) ;
147- canvas . addEventListener ( 'touchmove' , function ( e ) {
148- if ( dragging && e . touches . length === 1 ) {
149- const touchY = e . touches [ 0 ] . clientY - canvas . getBoundingClientRect ( ) . top ;
150- rightY = touchY - PADDLE_HEIGHT / 2 ;
151- rightY = Math . max ( 0 , Math . min ( canvas . height - PADDLE_HEIGHT , rightY ) ) ;
152- }
153- } , { passive : false } ) ;
154- // Mouse drag for right paddle (desktop)
155- canvas . addEventListener ( 'mousedown' , function ( e ) {
156- dragging = true ;
157- } ) ;
158- canvas . addEventListener ( 'mouseup' , function ( e ) {
159- dragging = false ;
160- } ) ;
161- canvas . addEventListener ( 'mousemove' , function ( e ) {
162- if ( dragging ) {
163- const mouseY = e . clientY - canvas . getBoundingClientRect ( ) . top ;
164- rightY = mouseY - PADDLE_HEIGHT / 2 ;
165- rightY = Math . max ( 0 , Math . min ( canvas . height - PADDLE_HEIGHT , rightY ) ) ;
166- }
167- } ) ;
168-
169140document . getElementById ( 'restartBtn' ) . onclick = function ( ) {
170141 leftScore = rightScore = 0 ;
171142 resetBall ( ) ;
172143 leftY = rightY = canvas . height / 2 - PADDLE_HEIGHT / 2 ;
173- running = true ;
174- update ( ) ;
175144} ;
176145
177146canvas . focus ( ) ;
178147draw ( ) ;
179- update ( ) ;
148+ update ( ) ; // Game starts immediately!
0 commit comments