Следующая программа представляет собой простую игру, в которой вы можете ударить по мячу. Теперь я собирался реализовать класс («Gameobject») для мяча, чтобы сделать вещи объектно-ориентированными.
Пока все хорошо. Но как только я добавлю mask.from_surface () в качестве атрибута к классу, шар больше не будет двигаться. Что я делаю не так?
Рабочий код (маска расположена в строке 61):
import pygame
from pygame.math import Vector2
import math
width = 1150
height = 800
# Colors
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
GREY = (210, 210, 210)
RED = (255, 0, 0)
GREEN = (20, 255, 140)
BLUE = (0, 0, 255)
GOLD = (255, 215, 0)
SILVER = (192, 192, 192)
drag = 0.399 # Between 0 and 1
elasticity = 0.75 # Between 0 and 1
gravity = (math.pi, 0.000)
pygame.init()
screen = pygame.display.set_mode((width, height))
clock = pygame.time.Clock()
# Define game object class
class Gameobject:
"""
Interactive objects with the game
"""
def __init__(self, coordinates, velocity, angle, radius, objectColor):
self.x = coordinates[0]
self.y = coordinates[1]
self.velocity = velocity
self.angle = angle
self.radius = radius
self.objectColor = objectColor
self.surface = pygame.Surface((self.radius*2, self.radius*2), pygame.SRCALPHA)
self.rectangle = self.surface.get_rect(center=[self.x, self.y])
def draw(self):
"""
Rendering game object
:param screen: pygame screen
"""
pygame.draw.circle(self.surface, self.objectColor, [self.radius, self.radius], self.radius)
# Images.
BG_IMG = pygame.Surface((1150, 800))
BG_IMG.fill((30, 120, 30))
REDCAR_ORIGINAL = pygame.Surface((50, 30), pygame.SRCALPHA)
pygame.draw.polygon(
REDCAR_ORIGINAL, (255, 0, 0), [(0, 0), (50, 10), (50, 20), (0, 30)])
redcar = REDCAR_ORIGINAL
myBall = Gameobject(Vector2(575, 400), Vector2(0, 0), 0, 60, GOLD)
myBall.draw()
mask_ball = pygame.mask.from_surface(myBall.surface)
# Car variables.
pos_red = Vector2(470, 370)
vel_red = Vector2(3, 0)
redrect = redcar.get_rect(center=pos_red)
redangle = 0
# Masks.
mask_red = pygame.mask.from_surface(redcar)
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
redangle += 5
vel_red.rotate_ip(-5)
redcar = pygame.transform.rotate(REDCAR_ORIGINAL, redangle)
redrect = redcar.get_rect(center=redrect.center)
# We need a new mask after the rotation.
mask_red = pygame.mask.from_surface(redcar)
elif keys[pygame.K_RIGHT]:
redangle -= 5
vel_red.rotate_ip(5)
redcar = pygame.transform.rotate(REDCAR_ORIGINAL, redangle)
redrect = redcar.get_rect(center=redrect.center)
mask_red = pygame.mask.from_surface(redcar)
# Move the cars.
pos_red += vel_red
redrect.center = pos_red
# Move the ball.
myBall.velocity *= .99 # Friction.
myBall.x += myBall.velocity[0]
myBall.y += myBall.velocity[1]
myBall.rectangle.center = [myBall.x, myBall.y]
# Red car collision.
# We need the offset between the redrect and the ballrect.
offset_red = redrect[0] - myBall.rectangle[0], redrect[1] - myBall.rectangle[1]
# Pass the offset to the `overlap` method. If the masks collide,
# overlap will return a single point, otherwise `None`.
overlap_red = mask_ball.overlap(mask_red, offset_red)
# Blue car collision.
if overlap_red: # Red collides with the ball.
myBall.velocity = Vector2(vel_red) * 1.4
# Drawing.
screen.blit(BG_IMG, (0, 0))
screen.blit(myBall.surface, myBall.rectangle)
screen.blit(redcar, redrect)
pygame.display.flip()
clock.tick(60)
pygame.quit()
Моя попытка реализовать маску внутри класса Gameobject:
import pygame
from pygame.math import Vector2
import math
width = 1150
height = 800
# Colors
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
GREY = (210, 210, 210)
RED = (255, 0, 0)
GREEN = (20, 255, 140)
BLUE = (0, 0, 255)
GOLD = (255, 215, 0)
SILVER = (192, 192, 192)
drag = 0.399 # Between 0 and 1
elasticity = 0.75 # Between 0 and 1
gravity = (math.pi, 0.000)
pygame.init()
screen = pygame.display.set_mode((width, height))
clock = pygame.time.Clock()
# Define game object class
class Gameobject:
"""
Interactive objects with the game
"""
def __init__(self, coordinates, velocity, angle, radius, objectColor):
self.x = coordinates[0]
self.y = coordinates[1]
self.velocity = velocity
self.angle = angle
self.radius = radius
self.objectColor = objectColor
self.surface = pygame.Surface((self.radius*2, self.radius*2), pygame.SRCALPHA)
self.rectangle = self.surface.get_rect(center=[self.x, self.y])
self.mask = pygame.mask.from_surface(self.surface)
def draw(self):
"""
Rendering game object
:param screen: pygame screen
"""
pygame.draw.circle(self.surface, self.objectColor, [self.radius, self.radius], self.radius)
# Images.
BG_IMG = pygame.Surface((1150, 800))
BG_IMG.fill((30, 120, 30))
REDCAR_ORIGINAL = pygame.Surface((50, 30), pygame.SRCALPHA)
pygame.draw.polygon(
REDCAR_ORIGINAL, (255, 0, 0), [(0, 0), (50, 10), (50, 20), (0, 30)])
redcar = REDCAR_ORIGINAL
myBall = Gameobject(Vector2(575, 400), Vector2(0, 0), 0, 60, GOLD)
myBall.draw()
# Car variables.
pos_red = Vector2(470, 370)
vel_red = Vector2(3, 0)
redrect = redcar.get_rect(center=pos_red)
redangle = 0
# Masks.
mask_red = pygame.mask.from_surface(redcar)
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
redangle += 5
vel_red.rotate_ip(-5)
redcar = pygame.transform.rotate(REDCAR_ORIGINAL, redangle)
redrect = redcar.get_rect(center=redrect.center)
# We need a new mask after the rotation.
mask_red = pygame.mask.from_surface(redcar)
elif keys[pygame.K_RIGHT]:
redangle -= 5
vel_red.rotate_ip(5)
redcar = pygame.transform.rotate(REDCAR_ORIGINAL, redangle)
redrect = redcar.get_rect(center=redrect.center)
mask_red = pygame.mask.from_surface(redcar)
# Move the cars.
pos_red += vel_red
redrect.center = pos_red
# Move the ball.
myBall.velocity *= .99 # Friction.
myBall.x += myBall.velocity[0]
myBall.y += myBall.velocity[1]
myBall.rectangle.center = [myBall.x, myBall.y]
# Red car collision.
# We need the offset between the redrect and the ballrect.
offset_red = redrect[0] - myBall.rectangle[0], redrect[1] - myBall.rectangle[1]
# Pass the offset to the `overlap` method. If the masks collide,
# overlap will return a single point, otherwise `None`.
overlap_red = myBall.mask.overlap(mask_red, offset_red)
# Blue car collision.
if overlap_red: # Red collides with the ball.
myBall.velocity = Vector2(vel_red) * 1.4
# Drawing.
screen.blit(BG_IMG, (0, 0))
screen.blit(myBall.surface, myBall.rectangle)
screen.blit(redcar, redrect)
pygame.display.flip()
clock.tick(60)
pygame.quit()