pygame почему моя коллизия с масками не работает

1004w

Новичок
Пользователь
Июл 23, 2024
2
0
1
Привет! Я уже задавал этот вопрос на другом форуме, но мне никто не ответил, помогите хоть вы пожалуйста :)

в это коде

Python:
self.square_rect = pygame.Rect(200, 200, 100, 100)
square_mask = pygame.mask.from_surface(pygame.Surface((100,100),pygame.SRCALPHA))
pygame.draw.rect(square_mask.to_surface(), (255,255,255), square_mask.get_rect())
player_mask = pygame.mask.from_surface(self.player.image)
offset_x = self.square_rect.x - self.player.x
offset_y = self.square_rect.y - self.player.y
overlap_mask = player_mask.overlap(square_mask, (offset_x, offset_y))
print(overlap_mask)
print (offset_x)
print (offset_y)
if overlap_mask:
print("10")
Хочу сделать так, что если player (квадрат) находится под квадратом self.square_rect, то код print ("10) выполняется. Но почему-то, даже если я стою на квадрате, этот код не выполняется и столкновение не определяется.

принты дают мне такую инфу:

None

0

-4

то есть я точно под квадратом но коллизия не детектится, почему я не могу понять. Если что вот полный код:

Python:
import pygame
import math
import random
import numpy
pygame.init()
class GameData:
def __init__(self):

self.screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
self.screen_x, self.screen_y = self.screen.get_size()
self.left_wall_rect = pygame.Rect(0, 0, round(self.screen_x * 0.01), self.screen_y)
self.right_wall_rect = pygame.Rect(round(self.screen_x * 0.99), 0, round(self.screen_x * 0.01), self.screen_y)
self.top_wall_rect = pygame.Rect(0, 0, self.screen_x, round(self.screen_y * 0.01))
self.bottom_wall_rect = pygame.Rect(0, round(self.screen_y * 0.99), self.screen_x, round(self.screen_y * 0.01))
self.walls_rects = [self.left_wall_rect,self.right_wall_rect, self.top_wall_rect, self.bottom_wall_rect]

self.player_speed = round ((self.screen_x + self.screen_y) * 0.0025)
self.clock = pygame.time.Clock()
self.изображения = {
"spike": pygame.image.load("images/spike.png").convert_alpha(),
"player": pygame.image.load("images/player.png").convert_alpha(),
} # - ЭТО ПРОСТО ЗЕЛЁНЫЙ КВАДРАТ
def calculate_velocity(self, angle, speed):
velocityX = speed * numpy.cos(numpy.deg2rad(angle))
velocityY = speed * numpy.sin(numpy.deg2rad(angle))
return velocityX, velocityY

class Player ():
def __init__(self, gamedata):
self.gamedata = gamedata
self.image = self.gamedata.изображения["player"]
self.x = self.gamedata.screen_x // 2
self.y = self.gamedata.screen_y // 2
self.rect = self.image.get_rect(center=(self.x, self.y))
self.alive = True
def draw (self):
self.gamedata.screen.blit (self.image, (self.x, self.y))
class Game:
def __init__(self, gamedata, player):
self.gamedata = gamedata
self.spikes = []
self.player = player
self.running = True
self.square_rect = pygame.Rect(200, 200, 100, 100)
def update_events(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
self.running = False
keys = pygame.key.get_pressed()
dx = 0
dy = 0
if keys[pygame.K_LEFT]:
dx -= 1
if keys[pygame.K_RIGHT]:
dx += 1
if keys[pygame.K_UP]:
dy -= 1
if keys[pygame.K_DOWN]:
dy += 1
self.dx = dx
self.dy = dy
def update_collisions(self):
dx = self.dx
dy = self.dy
self.player.x += dx * self.gamedata.player_speed
self.player.y += dy * self.gamedata.player_speed
player_left = self.player.x
player_right = self.player.x + self.player.image.get_width()
player_top = self.player.y
player_bottom = self.player.y + self.player.image.get_height()
if dx > 0:
if player_right > self.gamedata.right_wall_rect.left:
self.player.x = self.gamedata.right_wall_rect.left - self.player.image.get_width()
elif dx < 0:
if player_left < self.gamedata.left_wall_rect.right:
self.player.x = self.gamedata.left_wall_rect.right
player_left = self.player.x
player_right = self.player.x + self.player.image.get_width()
player_top = self.player.y
player_bottom = self.player.y + self.player.image.get_height()

if dy > 0:
if player_bottom > self.gamedata.bottom_wall_rect.top:
self.player.y = self.gamedata.bottom_wall_rect.top - self.player.image.get_height()
elif dy < 0:
if player_top < self.gamedata.top_wall_rect.bottom:
self.player.y = self.gamedata.top_wall_rect.bottom
self.square_rect = pygame.Rect(200, 200, 100, 100)
square_mask = pygame.mask.from_surface(pygame.Surface((100,100),pygame.SRCALPHA))
pygame.draw.rect(square_mask.to_surface(), (255,255,255), square_mask.get_rect())
player_mask = pygame.mask.from_surface(self.player.image)
offset_x = self.square_rect.x - self.player.x
offset_y = self.square_rect.y - self.player.y
overlap_mask = player_mask.overlap(square_mask, (offset_x, offset_y))
print(overlap_mask)
print (offset_x)
print (offset_y)
if overlap_mask:
print(10)

def draw(self):
self.gamedata.screen.fill ((0, 0, 0))
self.player.draw()
for spike in self.spikes:
spike.draw()
pygame.draw.rect(self.gamedata.screen, (255, 255, 255), self.square_rect)
pygame.display.flip()

def run(self):
while self.running:
self.update_events()
self.update_collisions()
self.draw()
self.gamedata.clock.tick(60)


gamedata = GameData()
player = Player (gamedata)
game = Game(gamedata, player)
game.run()
pygame.quit()
 
Последнее редактирование:

1004w

Новичок
Пользователь
Июл 23, 2024
2
0
1
Короче, мне подсказали:

“in the first code block you've posted you have

square_mask = pygame.mask.from_surface(pygame.Surface((100,100),pygame.SRCALPHA))

you've created your 100x100 surface inline but you never use Surface.fill() to actually put something on your surface. This means your surface is empty and your mask is empty and has nothing to collide with. You need to fill your surface before you make the mask from it.”

это было решением. ПРоблема решена.


Python:
self.square_rect = pygame.Rect(200, 200, 100, 100)
square_surface = pygame.Surface((100, 100), pygame.SRCALPHA)
square_surface.fill((255, 255, 255))
square_mask = pygame.mask.from_surface(square_surface)
player_mask = pygame.mask.from_surface(self.player.image)
offset_x = self.square_rect.x - self.player.x
offset_y = self.square_rect.y - self.player.y
overlap_mask = player_mask.overlap(square_mask, (offset_x, offset_y))
print(overlap_mask)
print(offset_x)
print(offset_y)
if overlap_mask:
print(10)
 

Форум IT Специалистов