Pong Level 3 — Fizika odbijanja i 2 igrača


Lekcija 8 od 14

U prethodnoj lekciji Pong Level 2 dodali smo score i game over logiku.

Sada unapređujemo igru i pravimo ozbiljniju verziju:

  • dva igrača
  • realističnije odbijanje lopte
  • postepeno povećavanje brzine
  • bolji osećaj kontrole

1. Nove promenljive


# Lopta
ball_x = 350
ball_y = 200
dx = 5
dy = 4
ball_size = 20
max_speed = 10

# Palice
paddle_width = 15
paddle_height = 80

left_y = 160
right_y = 160

left_speed = 0
right_speed = 0

# Score
score_left = 0
score_right = 0
Novina:

Dodali smo max_speed da ograničimo brzinu lopte i sprečimo da igra postane neigriva.

2. Setup


def setup():
    size(700, 400)
    textSize(24)

3. Glavna logika igre


def draw():
    global ball_x, ball_y, dx, dy
    global left_y, right_y
    global score_left, score_right

    background(20)

    # Srednja linija (vizuelni detalj)
    for y in range(0, height, 20):
        rect(width/2 - 2, y, 4, 10)

    # Lopta
    ellipse(ball_x, ball_y, ball_size, ball_size)

    # Palice
    rect(30, left_y, paddle_width, paddle_height)
    rect(width-45, right_y, paddle_width, paddle_height)

    # Kretanje lopte
    ball_x += dx
    ball_y += dy

    # Odbijanje od gore/dole
    if ball_y < ball_size/2 or ball_y > height-ball_size/2:
        dy = -dy

    # Sudar sa levom palicom
    if (ball_x < 45 and
        left_y < ball_y < left_y + paddle_height):

        dx = abs(dx)

        # Efekat ugla (zavisno gde udara palicu)
        offset = (ball_y - (left_y + paddle_height/2)) / (paddle_height/2)
        dy += offset * 2

    # Sudar sa desnom palicom
    if (ball_x > width-45 and
        right_y < ball_y < right_y + paddle_height):

        dx = -abs(dx)

        offset = (ball_y - (right_y + paddle_height/2)) / (paddle_height/2)
        dy += offset * 2

    # Postepeno ubrzanje (ali ograničeno)
    dx *= 1.001
    dy *= 1.001

    dx = constrain(dx, -max_speed, max_speed)
    dy = constrain(dy, -max_speed, max_speed)

    # Poeni
    if ball_x < 0:
        score_right += 1
        resetBall()

    if ball_x > width:
        score_left += 1
        resetBall()

    # Pomeranje palica
    left_y += left_speed
    right_y += right_speed

    left_y = constrain(left_y, 0, height-paddle_height)
    right_y = constrain(right_y, 0, height-paddle_height)

    # Score
    text(score_left, width/4, 40)
    text(score_right, width*3/4, 40)

Ključna novina — fizika odbijanja

Lopta se više ne odbija uvek istim uglom.

  • udar u centar → pravolinijsko odbijanje
  • udar na ivicu → veći ugao

To pravimo pomoću offset vrednosti.


4. Reset lopte


def resetBall():
    global ball_x, ball_y, dx, dy

    ball_x = width/2
    ball_y = height/2

    dx = random([-5, 5])
    dy = random(-3, 3)
Savet: Manji početni dy daje bolju kontrolu igre na početku.

5. Kontrole tastature

  • Igrač 1: W / S
  • Igrač 2: ↑ / ↓

def keyPressed():
    global left_speed, right_speed
    
    if key == 'w':
        left_speed = -6
    if key == 's':
        left_speed = 6
        
    if keyCode == UP:
        right_speed = -6
    if keyCode == DOWN:
        right_speed = 6


def keyReleased():
    global left_speed, right_speed
    
    if key in ['w','s']:
        left_speed = 0
        
    if keyCode in [UP, DOWN]:
        right_speed = 0
Zašto je ovo važno?

Omogućava glatko kretanje — palica se kreće samo dok držiš taster.

Šta smo unapredili?

  • realističnije odbijanje lopte
  • kontrolu ugla kretanja
  • postepeno ubrzanje igre
  • igranje za dva igrača
  • vizuelna poboljšanja (linija terena)

Izazovi (napredno)

  • Dodaj maksimalan score (npr. 10) i pobednika
  • Dodaj AI protivnika
  • Dodaj zvuk pri sudaru
  • Dodaj meni (start / restart)

Sledeća lekcija

U sledećoj lekciji prelazimo na organizaciju koda pomoću objekata (OOP).

Pong OOP — objekti i klase →


Povezane lekcije