Найти - Пользователи
Полная версия: pygame нужна помощь почему моя коллизия с масками не работает
Начало » Python для новичков » pygame нужна помощь почему моя коллизия с масками не работает
1
1004w
Привет!

в это коде

 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

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

 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(),
    } # - ЭТО ПРОСТО ЗЕЛЁНЫЙ КВАДРАТ[code][code python][/code][/code]
  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
Короче, мне подсказали:

“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.”

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

    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)
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB