Pong Satu Pemain – PyScript
Skor: 0
Nyawa: 3
import js, asyncio, math
from pyodide.ffi import create_proxy
canvas = js.document.getElementById("arena")
ctx = canvas.getContext("2d")
# Bola
ball_r = 10
ball_x = canvas.width / 2
ball_y = canvas.height / 2
speed = 2.0
angle = math.radians(45)
ball_vx = speed * math.cos(angle)
ball_vy = speed * math.sin(angle)
# Paddle
pad_w = 80
pad_h = 10
pad_x = (canvas.width - pad_w) / 2
pad_y = canvas.height - pad_h - 10
move_step = 20
# Skor dan nyawa
score = 0
lives = 3
running = True
score_span = js.document.getElementById("score")
lives_span = js.document.getElementById("lives")
# Gambar
def draw_ball():
ctx.beginPath()
ctx.arc(ball_x, ball_y, ball_r, 0, 2*math.pi)
ctx.fillStyle = "#ff6666" # merah terang
ctx.fill()
ctx.closePath()
def draw_paddle():
ctx.fillStyle = "#00bfff" # biru terang
ctx.fillRect(pad_x, pad_y, pad_w, pad_h)
def draw_gameover():
ctx.font = "24px Arial"
ctx.fillStyle = "#ff4444"
ctx.textAlign = "center"
ctx.fillText(f"Game Over – Skor {score}", canvas.width/2, canvas.height/2)
# Keyboard
def on_key(evt):
global pad_x
evt.preventDefault()
if evt.key in ("ArrowLeft", "Left"):
pad_x -= move_step
elif evt.key in ("ArrowRight", "Right"):
pad_x += move_step
pad_x = max(0, min(pad_x, canvas.width - pad_w))
js.window.addEventListener("keydown", create_proxy(on_key))
# Loop utama
async def game_loop():
global ball_x, ball_y, ball_vx, ball_vy, score, lives, running
while running:
ctx.clearRect(0, 0, canvas.width, canvas.height)
draw_ball()
draw_paddle()
# Update posisi bola
ball_x += ball_vx
ball_y += ball_vy
# Pantulan dinding
if ball_x + ball_r > canvas.width or ball_x - ball_r < 0:
ball_vx = -ball_vx
if ball_y - ball_r < 0:
ball_vy = -ball_vy
# Pantulan paddle
if (pad_y <= ball_y + ball_r <= pad_y + pad_h) and (pad_x <= ball_x <= pad_x + pad_w):
if ball_vy > 0:
ball_vy = -ball_vy
score += 1
score_span.innerText = str(score)
# Gagal tangkap
if ball_y - ball_r > canvas.height:
lives -= 1
lives_span.innerText = str(lives)
if lives == 0:
running = False
ctx.clearRect(0, 0, canvas.width, canvas.height)
draw_gameover()
break
else:
ball_x = canvas.width / 2
ball_y = canvas.height / 2
angle = math.radians(45)
ball_vx = speed * math.cos(angle)
ball_vy = speed * math.sin(angle)
await asyncio.sleep(0.01)
await game_loop()