Как я могу обнаружить столкновение между игроком и блоком? Pygame - PullRequest
1 голос
/ 05 апреля 2020

Я борюсь со столкновениями в Pygame. Я хочу, чтобы , когда игрок (Том) касается FireBlock, на консоли печатается сообщение.

В классе Level я создаю свою карту и добавляю соответствующие блоки. Том - главный игрок.

У меня также есть другой файл, где отображается и создается мой уровень: [введите описание изображения здесь] [1]

Не могли бы вы мне помочь, пожалуйста? Я не могу заставить столкновения работать должным образом. Спасибо за помощь! Я действительно ценю это!

from pygame.locals import *
import sys

SCREEN_SIZE = (960, 720) #resolution of the game
global HORIZ_MOV_INCR
HORIZ_MOV_INCR = 10 #speed of movement
global FPS
global clock
global time_spent

def RelRect(actor, camera):
    return pygame.Rect(actor.rect.x-camera.rect.x, actor.rect.y-camera.rect.y, actor.rect.w, actor.rect.h)

# Clase para tener la pantalla en el centro del jugador
class Camera(object):
    def __init__(self, screen, player, level_width, level_height):
        self.player = player
        self.rect = screen.get_rect()
        self.rect.center = self.player.center
        self.world_rect = Rect(0, 0, level_width, level_height)

    def update(self):
      if self.player.centerx > self.rect.centerx + 100:
          self.rect.centerx = self.player.centerx - 100
      if self.player.centerx < self.rect.centerx - 100:
          self.rect.centerx = self.player.centerx + 100
      if self.player.centery > self.rect.centery + 100:
          self.rect.centery = self.player.centery - 100
      if self.player.centery < self.rect.centery - 100:
          self.rect.centery = self.player.centery + 100
      self.rect.clamp_ip(self.world_rect)

    def draw_sprites(self, surf, sprites):
        for s in sprites:
            if s.rect.colliderect(self.rect):
                surf.blit(s.image, RelRect(s, self))

# Clase para crear los obstáculos
class BlockMedieval(pygame.sprite.Sprite):
    def __init__(self, x, y):
        self.x = x
        self.y = y
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load("images/BlockMedieval.png").convert()
        self.rect = self.image.get_rect()
        self.rect.topleft = [self.x, self.y]

class FireBlock(pygame.sprite.Sprite):
    def __init__(self, x, y):
        self.x = x
        self.y = y
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load("images/Fire.png").convert()
        self.rect = self.image.get_rect()
        self.rect.topleft = [self.x, self.y]

# Clase para el jugador y sus colisiones
class Tom(pygame.sprite.Sprite):    
    def __init__(self, x, y):
        pygame.sprite.Sprite.__init__(self)
        self.movy = 0
        self.movx = 0
        self.x = x
        self.y = y
        self.contact = False
        self.jump = False
        self.image = pygame.image.load('images/Right00.png').convert()
        self.rect = self.image.get_rect()
        self.run_left = ["images/Left00.png","images/Left01.png",
                         "images/Left02.png", "images/Left03.png",
                         "images/Left00.png", "images/Left01.png",
                         "images/Left02.png", "images/Left03.png"]
        self.run_right = ["images/Right00.png","images/Right01.png",
                         "images/Right02.png", "images/Right03.png",
                         "images/Right00.png","images/Right01.png",
                         "images/Right02.png", "images/Right03.png"]
        self.direction = "right"
        self.rect.topleft = [x, y]
        self.frame = 0
        self.score = 0

    def update(self, up, down, left, right):
        if up:
            if self.contact:
                if self.direction == "right":
                    self.image = pygame.image.load("images/Right03.png")
                self.jump = True
                self.movy -= 20
        if down:
            if self.contact and self.direction == "right":
                self.image = pygame.image.load('images/Right00.png').convert_alpha()
            if self.contact and self.direction == "left":
                self.image = pygame.image.load('images/Left00.png').convert_alpha()

        if not down and self.direction == "right":
                self.image = pygame.image.load('images/Right00.png').convert_alpha()

        if not down and self.direction == "left":
            self.image = pygame.image.load('images/Left00.png').convert_alpha()

        if left:
            self.direction = "left"
            self.movx = -HORIZ_MOV_INCR
            if self.contact:
                self.frame += 1
                self.image = pygame.image.load(self.run_left[self.frame]).convert_alpha()
                if self.frame == 6: self.frame = 0
            else:
                self.image = self.image = pygame.image.load("images/Left03.png").convert_alpha()

        if right:
            self.direction = "right"
            self.movx = +HORIZ_MOV_INCR
            if self.contact:
                self.frame += 1
                self.image = pygame.image.load(self.run_right[self.frame]).convert_alpha()
                if self.frame == 6: self.frame = 0
            else:
                self.image = self.image = pygame.image.load("images/Right03.png").convert_alpha()

        if not (left or right):
            self.movx = 0
        self.rect.right += self.movx

        self.collide(self.movx, 0, world)


        if not self.contact:
            self.movy += 0.3
            if self.movy > 10:
                self.movy = 10
            self.rect.top += self.movy

        if self.jump:
            self.movy += 2
            self.rect.top += self.movy
            if self.contact == True:
                self.jump = False

        self.contact = False
        self.collide(0, self.movy, world)


    # Colisiones
    def collide(self, movx, movy, world):
        self.contact = False        
        for o in world:
            if self.rect.colliderect(o):
                self.score += 1
                print("Score: " + str(self.score))
                if movx > 0:
                    self.rect.right = o.rect.left
                if movx < 0:
                    self.rect.left = o.rect.right
                if movy > 0:
                    self.rect.bottom = o.rect.top
                    self.movy = 0
                    self.contact = True
                if movy < 0:
                    self.rect.top = o.rect.bottom
                    self.movy = 0

# Lee el mapa del nivel y crea el nivel
class Level(object):
    def __init__(self, open_level):
        self.level1 = []
        self.world = []
        self.all_sprite = pygame.sprite.Group()
        self.level = open(open_level, "r")

    def create_level(self, x, y):
        for l in self.level:
            self.level1.append(l)

        for row in self.level1:
            for col in row:
                # Donde Tom aparece por primera vez
                if col == "P":
                    self.tom = Tom(x,y)
                    self.all_sprite.add(self.tom)     
                # Medieval Block Obstacle
                if col == "X":
                    blockMedieval = BlockMedieval(x, y)
                    self.world.append(blockMedieval)
                    self.all_sprite.add(self.world)                                                  
                # Fire Block Obstacle
                if col == "F":
                    fireBlock = FireBlock(x, y)
                    self.world.append(fireBlock)
                    self.all_sprite.add(self.world) 

                x += 25   
            y += 25
            x = 0        

    def get_size(self):
        lines = self.level1
        #line = lines[0]
        line = max(lines, key=len)
        self.width = (len(line))*25
        self.height = (len(lines))*25
        return (self.width, self.height)

def tps(reloj, fps):
    temp = reloj.tick(fps)
    tps = temp / 1000.
    return tps


pygame.init()
screen = pygame.display.set_mode(SCREEN_SIZE, 32)
screen_rect = screen.get_rect()
background = pygame.image.load("world/background2.jpg").convert_alpha()
background_rect = background.get_rect()
level = Level("level/level1")
level.create_level(0, 0)
world = level.world
tom = level.tom
pygame.mouse.set_visible(0)

camera = Camera(screen, tom.rect, level.get_size()[0], level.get_size()[1])
all_sprite = level.all_sprite

FPS = 30
clock = pygame.time.Clock()


def startLevel1():
    up = down = left = right = False
    x, y = 0, 0
    while True:

        # if tom.rect.colliderect(blockMedieval.rect):
        #     print("YAY")

        for event in pygame.event.get():
            if event.type == QUIT or event.type == KEYDOWN and event.key == K_ESCAPE:
                pygame.quit()
                sys.exit()

            if event.type == KEYDOWN and event.key == K_SPACE:
                up = True
            if event.type == KEYDOWN and event.key == K_DOWN:
                down = True
            if event.type == KEYDOWN and event.key == K_LEFT:
                left = True
            if event.type == KEYDOWN and event.key == K_RIGHT:
                right = True

            if event.type == KEYUP and event.key == K_SPACE:
                up = False
            if event.type == KEYUP and event.key == K_DOWN:
                down = False
            if event.type == KEYUP and event.key == K_LEFT:
                left = False
            if event.type == KEYUP and event.key == K_RIGHT:
                right = False

        asize = ((screen_rect.w // background_rect.w + 1) * background_rect.w, (screen_rect.h // background_rect.h + 1) * background_rect.h)
        bg = pygame.Surface(asize)

        for x in range(0, asize[0], background_rect.w):
            for y in range(0, asize[1], background_rect.h):
                screen.blit(background, (x, y))

        time_spent = tps(clock, FPS)
        camera.draw_sprites(screen, all_sprite)

        tom.update(up, down, left, right)
        camera.update()
        pygame.display.flip()


  [1]: https://i.stack.imgur.com/FZGKk.png

1 Ответ

0 голосов
/ 06 апреля 2020

вы можете посмотреть на .spritecollideany() метод. Этот метод принимает в качестве параметров спрайт и группу спрайтов. Он просматривает .rect одного спрайта и проверяет его на соответствие всем .rect группы спрайтов и возвращает True, если есть какое-либо перекрытие / столкновение. В этом руководстве есть раздел по обнаружению столкновений, который может помочь: https://realpython.com/pygame-a-primer/#collision -обнаружение

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...