spritecollide () не работает должным образом - PullRequest
0 голосов
/ 13 января 2019

Я нахожусь в процессе создания «главного героя», который прыгает вокруг и может прыгать на боксы и т. Д., Используя pygame. Я создал класс Player, класс Level и класс Box. Функция spritecollide никогда не возвращает true, и я не уверен, где я ошибаюсь.

  • Я использовал spritecollideany и groupcollide, чтобы посмотреть, помогает ли это (не помогло)
  • Я проверил, насколько смог, и насколько я могу судить, ящики попадают в Level.box_list в качестве группы спрайтов, и оба ящика и игроки являются спрайтами.
  • Я полностью прочитал документацию и чувствую, что должна быть какая-то ключевая концепция, которую я упускаю или неправильно использую.

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

movementprototype.py

import random, pygame, sys
import math
from pygame.locals import *
from levelprototype import *

FPS = 60 # frames per second, the general speed of the program
WINDOWWIDTH = 640 # size of window's width in pixels
WINDOWHEIGHT = 480 # size of windows' height in pixels

#            R    G    B
GRAY     = (100, 100, 100)
WHITE    = (255, 255, 255)
RED      = (255,   0,   0)
GREEN    = (  0, 255,   0)
BLUE     = (  0,   0, 255)
YELLOW   = (255, 255,   0)
ORANGE   = (255, 128,   0)
BLACK    = (  0,   0,   0)

BGCOLOR = WHITE

def main():

#set up all relevant variables
global FPSCLOCK, DISPLAYSURF, player, box_list
pygame.init()
FPSCLOCK = pygame.time.Clock()

#the length, in ms, of one frame
tick = 1000/FPS

#create window
DISPLAYSURF = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
mousex = 0 # used to store x coordinate of mouse event
mousey = 0 # used to store y coordinate of mouse event
pygame.display.set_caption('Movement test environment')

#create the player object using Player() class, add to all_sprites group.
all_sprites = pygame.sprite.Group()
player = Player()
all_sprites.add(player)

#create the level object
level = Level()

while True: #main game loop

    #fill with background colour
    DISPLAYSURF.fill(BGCOLOR)

    # Update items in the level
    level.update()
    level.draw(DISPLAYSURF)

    #call the sprite update and draw methods.
    all_sprites.update()

    #check if the player has clicked the X or pressed escape.
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

    [irrelevant code]

    #update the screen
    pygame.display.update()
    FPSCLOCK.tick(FPS)

class Player(pygame.sprite.Sprite):

def __init__(self):
    pygame.sprite.Sprite.__init__(self)

    #.draw() called in main() requires that each Sprite have a Surface.image
    #and a Surface.rect.
    self.image = pygame.Surface((20,50))
    self.image.fill(GREEN)
    self.rect = self.image.get_rect()

    #attributes
    self.velX = 0
    self.velY = 0
    self.x = 0
    self.y = 0
    self.gravity = 0.6
    self.maxVelocity = 5
    self.xResistance = 0.5
    self.isJump = 0
    self.isDash = 0

def update(self):
    #check which keys are pressed and add velocity.
    keys = pygame.key.get_pressed() 
    if (keys[K_d]) and self.velX < self.maxVelocity:
        self.velX += 2.5
    if (keys[K_a]) and self.velX > -self.maxVelocity:
       self.velX -= 2.5
    if (keys[K_w]) and self.isJump == 0:
        self.velY -= 10
        self.isJump = 1
    if (keys[K_SPACE]) and self.isDash == 0:
        #at the moment, can only dash once. add timer reset.
        self.isDash = 1
        if self.velX > 0:
            self.x += 20
        else:
            self.x -= 20

    #add gravity
    self.velY += self.gravity

    #add X resistance
    if self.velX > 0.05:
        self.velX -= self.xResistance
    elif self.velX < -0.05:
        self.velX += self.xResistance
    #if velocity is really close to 0, make it 0, to stop xResistance moving it the other way.
    if self.velX < 0.15 and self.velX > -0.15:
        self.velX = 0

    self.checkCollision()

    #update position with calculated velocity
    self.x += self.velX
    self.y += self.velY

    #call the draw function, below, to blit the sprite onto screen.
    self.draw(DISPLAYSURF)

def checkCollision(self):

    level = Level().box_list
    for collide in pygame.sprite.spritecollide(self, level, False):
        print("Collision")  

    #no matter what I put here, a collision never seems to be identified!!

def draw(self, DISPLAYSURF):
    DISPLAYSURF.blit(self.image, (self.x, self.y))

if __name__ == '__main__':
    main()

levelprototype.py

import pygame, sys
from pygame.locals import*

GREEN    = (  0, 255,   0)
BLUE     = (  0,   0, 255)
BLACK    = (  0,   0,   0)

class Box(pygame.sprite.Sprite):
    """ Box the user can jump on """

    def __init__(self, width, height):
        super().__init__()

        self.image = pygame.Surface([width, height])
        self.image.fill(BLACK)

        self.rect = self.image.get_rect()

class Level():

    #create the box_list as a Class attribute that exists for all instances.
    box_list = pygame.sprite.Group()

    def __init__(self):

        # Background image
        self.background = None

        # Array with width, height, x, and y of platform
        level = [[210, 70, 500, 100],
                 [210, 70, 200, 400],
                 [210, 70, 600, 300],
                 ]

        # Go through the array above and add platforms
        if len(Level.box_list) < 3:
            for platform in level:
                block = Box(platform[0], platform[1])
                block.rect.x = platform[2]
                block.rect.y = platform[3]

                Level.box_list.add(block)

    # Update everything on this level
    def update(self):
        """ Update everything in this level."""
       # Level.box_list.update()

    def draw(self, DISPLAYSURF):
        """ Draw everything on this level. """

        # Draw all the sprite lists that we have
        Level.box_list.draw(DISPLAYSURF)

1 Ответ

0 голосов
/ 13 января 2019

При проверке столкновений pygame.sprite.spritecollide проверяет, пересекаются ли спрайты спрайта. Вы не обновляете атрибут игрока rect, поэтому его позиция будет на (0, 0). Убедитесь, что они синхронизированы:

# update position with calculated velocity
self.x += self.velX
self.y += self.velY
self.rect.x = self.x
self.rect.y = self.y
...