Цялата ни игра е един безкраен цикъл, в който обработваме event-и
import pygame
pygame.init()
screen = pygame.display.set_mode((640, 480))
while True:
pass
import pygame
class Game:
running = True
def __init__(self, size):
pygame.init()
self.screen = pygame.display.set_mode(size)
def main(self):
while self.running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
return
if __name__ == '__main__':
Game((800, 600)).main()
Различни машини - различни възможности.
pygame.time.Clock
while self.running:
clock.tick(30)
for event in pygame.event.get():
if event.type == pygame.QUIT:
return
screen.fill((200, 200, 200))
screen.blit(image, (320, 240))
pygame.display.flip()
Със всяка итерация променяме координатите на нещото, което се "движи"
и всеки път подаваме новите на screen.blit:
screen.blit(image, (x, y))
key = pygame.key.get_pressed()
if key[pygame.K_LEFT]:
image_x -= 10
if key[pygame.K_RIGHT]:
image_x += 10
if key[pygame.K_UP]:
image_y -= 10
if key[pygame.K_DOWN]:
image_y += 10
Двуизмерна картинка или анимация, интегрирана в някакво пространство
class Player(pygame.sprite.Sprite):
def __init__(self, *groups):
super(Player, self).__init__(*groups)
self.image = pygame.image.load('player.png')
self.rect = pygame.rect.Rect((320, 240), self.image.get_size())
def update(self):
key = pygame.key.get_pressed()
if key[pygame.K_LEFT]:
self.rect.x -= 10
if key[pygame.K_RIGHT]:
self.rect.x += 10
if key[pygame.K_UP]:
self.rect.y -= 10
if key[pygame.K_DOWN]:
self.rect.y += 10
В общия случай го раздаваме с десетки/стотици спрайтове.
Не искаме да се молим на всеки един по отделно да се пречертае
class Game(object):
def main(self, screen):
clock = pygame.time.Clock()
sprites = pygame.sprite.Group()
self.player = Player(sprites)
while 1:
clock.tick(30)
for event in pygame.event.get():
if event.type == pygame.QUIT:
return
sprites.update()
screen.fill((200, 200, 200))
sprites.draw(screen)
pygame.display.flip()
screen.fill е полезно, но изключително куцо
Би било далеч по-приятно да имаме някакъв красив фон...като небе примерно:
def main(self, screen):
clock = pygame.time.Clock()
background = pygame.image.load('background.png')
sprites = pygame.sprite.Group()
self.player = Player(sprites)
while 1:
dt = clock.tick(30)
for event in pygame.event.get():
[....]
sprites.update(dt / 1000.)
screen.blit(background, (0, 0))
sprites.draw(screen)
pygame.display.flip()
Каквото и да правим с това човече, ще стигнем до момента, в който искаме да стреля като обезумяло.
Тук нещата загрубяват и имаме нужда от адекватна структура
game/
assets/...
main.py
player.py
projectile.py
settings.py
vec2d.py
4 основни подхода:
Ще добавим стени, че да не ни бяга човечето, също биха били полезни:
self.walls = pygame.sprite.Group()
block = pygame.image.load('block.png')
for x in range(0, 640, 32):
for y in range(0, 480, 32):
if x in (0, 640-32) or y in (0, 480-32):
wall = pygame.sprite.Sprite(self.walls)
wall.image = block
wall.rect = pygame.rect.Rect((x, y), block.get_size())
sprites.add(self.walls)
last = self.rect.copy()
for cell in pygame.sprite.spritecollide(self, game.walls, dokill=False):
self.rect = last
new = self.rect
for cell in pygame.sprite.spritecollide(self, game.walls, False):
cell = cell.rect
if last.right <= cell.left and new.right > cell.left:
new.right = cell.left
if last.left >= cell.right and new.left < cell.right:
new.left = cell.right
if last.bottom <= cell.top and new.bottom > cell.top:
new.bottom = cell.top
if last.top >= cell.bottom and new.top < cell.bottom:
new.top = cell.bottom
Навсякъде хвърчат препиятствия, патрони, зомбита, нашия играч
Вече можем да постигнем и далеч по-адекватен collision detection
За него ще си говорим точно след седмица.