Итак, ты уже был в классе. Класс - это инкапсуляция данных и функций, которые являются общими для этого "объекта". Все для этого объекта или около него должно входить в этот класс. Но когда код для обработки клавиатуры был помещен в класс Dot
, все пошло не в ту сторону. Dot
- это вещь, которая рисуется на экране, имеет размер, цвет и положение. Он не должен отвечать за обработку пользовательского ввода. Это выходит за рамки того, что Dot
.
При обновлении класса я решил основывать его на классе спрайтов PyGame . Сначала это немного больше работы, и ее нужно написать особым образом - иметь image
, rect
и (надеюсь) функцию update()
. Но будучи спрайтом, он получает множество уже написанных функциональных возможностей, в том числе PyGame подпрограммы коллизий .
Рядом с основным циклом есть пара дополнений. Первый - создание спрайта dotty
и спрайт-группы sprites
для его удержания. Немного странно создавать группу спрайтов для одного спрайта, но я предположил, что в будущем их будет больше одного.
Затем в фактическом цикле код вызывает sprites.update()
. Это удобная процедура, которая вызывает функцию update()
для каждого спрайта в группе. Затем позже вызывается sprites.draw( win )
, который рисует каждый спрайт в группе на экране. При этом используются спрайты image
и rect
, чтобы знать, где и что рисовать.
import pygame
import random
pygame.init()
WIN_H = 500
WIN_L = 500
win = pygame.display.set_mode((WIN_H, WIN_L))
width = 20
vel = 5
y = 250
x = 250
score = 0
direction = "up"
class Dot( pygame.sprite.Sprite ):
def __init__( self, x,y, size=20, direction='right', colour=(0,255,0) ):
pygame.sprite.Sprite.__init__( self )
self.size = size
self.colour = colour
self.direction = direction
self.image = pygame.Surface( ( size, size ), pygame.SRCALPHA )
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
self.image.fill( colour )
def move( self, x_dir, y_dir ):
global WIN_H, WIN_L
# Adjust our co-oridinates
self.rect.x += x_dir
self.rect.y += y_dir
# Stay on the screen, and wrap around
if (self.rect.left >= WIN_L ):
self.rect.right = 0
elif (self.rect.right <= 0 ):
self.rect.left = WIN_L
if (self.rect.top >= WIN_H ):
self.rect.bottom = 0
elif (self.rect.bottom <= 0):
self.rect.top = WIN_H
def update( self ):
# TODO - handle animation, collisions, whatever
pass
# make some sprites
dotty = Dot( x,y )
sprites = pygame.sprite.Group() # a group, for a single sprite (or more)
sprites.add( dotty )
p = True
run = True
while run:
pygame.time.delay(100)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_w]:
direction = "up"
if keys[pygame.K_a]:
direction = "left"
if keys[pygame.K_s]:
direction = "down"
if keys[pygame.K_d]:
direction = "right"
if direction == "up":
dotty.move( 0, -width )
if direction == "down":
dotty.move( 0, width )
if direction == "left":
dotty.move( -width, 0 )
if direction == "right":
dotty.move( width, 0 )
# update all the sprites
sprites.update()
# repaint the screen
win.fill((0,0,0))
sprites.draw( win )
#dot = pygame.draw.rect(win, (0, 255, 0), (x, y, width, width))
pygame.display.update()
pygame.quit()
Код движения был перемещен в класс Dot
. Это позволяет Dot
регулировать свою позицию, но также заботится о проблемах с переносом экрана. Если бы этот спрайт был, скажем, своего рода снарядом, возможно, когда он пересек границу экрана, он вызвал бы функцию sprite.kill()
, чтобы удалить себя из группы спрайтов. Но поскольку Dot
является явно не снарядом, он может переместиться на другую сторону.