blog.furas.pl
# prywatne notatki - Python, Linux, Machine Learning, etc.

Przykład rysowania linii za poruszającym się graczem w Pygame

To jest "przedruk" mojej wypowiedzi na polskim forum Pythona.

http://pl.python.org/forum/index.php?topic=4433.msg18982#msg18982


Prosty przykład rysowania kreski. Bez stale przemieszczającego się gracza. Czyli bez kropki oznaczającej gracza.

Kreska rysuje się tylko gdy wciska się klawisze strzałek. Rysowanie odbywa się tylko w kierunku wskazanym przez klawisz (lub kombinację klawiszy). Tak więc gracz przesuwa się w prawo-lewo, góra-dół i po przekątnych.

Taka może trochę dziwna obsługa klawiszy sprawia, że jak wciśnie się jednocześnie klawisz góra i dół to gracz nie przesuwa się ani w górę ani w dół a jak puści się górę lub dół (a drugi klawisz wciąż jest wciśnięty) to znowu przesuwa się w odpowiednim kierunku. Ale obsługa klawiszy akurat nie była najistotniejsza w tym przykładzie.

#!/usr/bin/env python

import pygame

#=== constants === (UPPER_CASE names)

RED = (255, 0 , 0)

SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600

#=== main === (lower_case names)

# --- init ---

pygame.init()

screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
screen_rect = screen.get_rect()

# --- objects ---

pos_new = list(screen_rect.center)
pos_old = list(screen_rect.center)

move_x = move_y = 0

# --- mainloop ---

clock = pygame.time.Clock()

running = True

while running:

    # --- events ---

    for event in pygame.event.get():

        if event.type == pygame.QUIT:
            running = False

        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                running = False

            elif event.key == pygame.K_RIGHT:
                move_x += 5

            elif event.key == pygame.K_LEFT:
                move_x -= 5

            elif event.key == pygame.K_UP:
                move_y -= 5

            elif event.key == pygame.K_DOWN:
                move_y += 5

        if event.type == pygame.KEYUP:
            if event.key == pygame.K_RIGHT:
                move_x -= 5

            elif event.key == pygame.K_LEFT:
                move_x += 5

            elif event.key == pygame.K_UP:
                move_y += 5

            elif event.key == pygame.K_DOWN:
                move_y -= 5

    # --- updates ---

    pos_new[0] += move_x
    pos_new[1] += move_y

    #print pos_old, pos_new

    # --- draws ---

    if pos_new != pos_old:
        pygame.draw.line(screen, RED, pos_new, pos_old)
        pos_old = pos_new[:]

    pygame.display.update()

    # --- FPS ---

    clock.tick(30)

# --- the end ---

pygame.quit()

Przerobiłem kod tak aby gracz poruszał się cały czas się i strzałkami prawo, lewo zmienia się kierunek ruchu. Zastosonanie trygonometri pozwoliło na poruszanie się w (prawie) dowolną stronę (co 10 stopni) i teraz widać, że z prostych kresek da się zrobić zaokrąglenia.

Próby z innymi wartościami prędkości i zmiany kąta raczej dawały gorsze zaokrąglenia.

Gdyby rysować prostą kreskę mniej regularnie to efekt mógłby być jak w grze.

#!/usr/bin/env python

import pygame
import math

# === constants === (UPPER_CASE names)

RED = (255, 0 , 0)

SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600

# === main === (lower_case names)

# --- init ---

pygame.init()
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
screen_rect = screen.get_rect()

# --- objects ---

# convert tuple to list 
pos_new = list(screen_rect.center)
pos_old = list(screen_rect.center)

speed = 5.0
angle = 0.0

# --- mainloop ---

clock = pygame.time.Clock()

running = True

while running:

    # --- events ---

    for event in pygame.event.get():

        if event.type == pygame.QUIT:
            running = False

        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                running = False

    keys = pygame.key.get_pressed()

    if keys[pygame.K_LEFT]:
        angle -= 10
    if keys[pygame.K_RIGHT]:
        angle += 10

    # --- updates ---

    if angle >= 360:
        angle -= 360
    elif angle < 0:
        angle += 360

    pos_new[0] += int(speed * math.cos(math.radians(angle)))
    pos_new[1] += int(speed * math.sin(math.radians(angle)))

    # --- draws ---

    if pos_new != pos_old:
        pygame.draw.line(screen, RED, pos_new, pos_old)
        pos_old = pos_new[:]

    pygame.display.flip()

    # --- FPS ---

    clock.tick(25)

# --- the end ---

pygame.quit()

rysowanie_kreski

rysowanie_trygonometria_1

rysowanie_trygonometria_2

Książki: python-dla-kazdego-podstawy-programowania python-wprowadzenie python-leksykon-kieszonkowy python-receptury python-programuj-szybko-i-wydajnie python-projekty-do-wykorzystania black-hat-python-jezyk-python-dla-hackerow-i-pentesterow efektywny-python-59-sposobow-na-lepszy-kod tdd-w-praktyce-niezawodny-kod-w-jezyku-python aplikacje-internetowe-z-django-najlepsze-receptury