碰撞检测“跳跃/不平滑”运动

时间:2014-05-10 04:49:51

标签: python pygame collision-detection collision

我的代码问题是我创建了一个精灵,每次按下箭头键时都可以移动一个拼贴,问题是当精灵移动到一个有墙上的拼贴时,它仍然会去在瓷砖上而不是停留在瓷砖上。我似乎无法获得正确的碰撞检测代码。

import pygame
import random

# Define some colors
black    = (   0,   0,   0)
white    = ( 255, 255, 255)
red      = ( 255,   0,   0)
GREEN    = (   0, 255,   0)
wall     = (  66,  66,  66)

# This class represents the ball        
# It derives from the "Sprite" class in Pygame
class Main(pygame.sprite.Sprite):


    walls = None
    def __init__(self, filename):

        # Calls the parent class (Sprite) constructor
        pygame.sprite.Sprite.__init__(self)

        # Creates the 'block' that will contain the image
        self.image = pygame.image.load(filename).convert()

        # Set background colour so its transparent
        self.image.set_colorkey(black)

        # Sets parameters so you can adjust the x and y values
    self.rect = self.image.get_rect()


    def update (self,):
        # Moving left or right
        self.rect.x += self.change_y

        # Did something collide into wall ?
        wall_hit_list = pygame.sprite.spritecollide(self, self.walls, False)

        for wall in wall_hit_list:

            # If we are moving right, set our right side to the left side of the item we hit
            if self.change_y > 0:
                self.rect.right = wall.rect.left
            else:
                # Otherwise if we are moving left, do the opposite
                self.rect.left = wall.rect.right

        # Move up/down
        self.rect.y += self.change_x

        # Check and see if we hit anything
        wall_hit_list = pygame.sprite.spritecollide(self, self.walls, False)

        for wall in wall_hit_list:

            # Reset our position based on the top/bottom of the object.
            if self.change_x > 0:
                self.rect.bottom = wall.rect.top
            else:
                self.rect.top = wall.rect.bottom


class Wall(pygame.sprite.Sprite):
    # Wall that the player can run into.

    def __init__(self, filename):
        # Constructor
        pygame.sprite.Sprite.__init__(self)

        # Make a wall
        self.image = pygame.image.load(filename).convert()

        # Sets parameters so you adjust the x and y values
        self.rect = self.image.get_rect()


# Initialize Pygame
pygame.init()

# Set the height and width of the screen
screen_width = 700
screen_height = 400
screen = pygame.display.set_mode([screen_width, screen_height])

# List of all the sprites
all_sprites_list = pygame.sprite.Group ()

# List of the main sprite ( squirtle )
main_sprite = pygame.sprite.Group ()

# List of Walls
wall_list = pygame.sprite.Group ()

wall = Wall("wall2.png",)
wall.rect.x = 100
wall.rect.y = 150
wall_list.add(wall)
all_sprites_list.add(wall)

# Sets player to the class 'Main' which thanks to the parameter, is squirtle
Hero = Main ("Character.png")
player = Main ("Character.png")

# Spawns squirtle in a random position
Hero.rect.x = 4
Hero.rect.y = 1

# Adds squirtle to the lists that we made
main_sprite.add(Hero)
all_sprites_list.add(Hero)



#Loop until the user clicks the close button.
done = False

# Used to manage how fast the screen updates
clock = pygame.time.Clock()

# -------- Main Program Loop -----------
while done == False:

    for event in pygame.event.get(): # User did something
        if event.type == pygame.QUIT: # If user clicked close
            done = True # Flag that we are done so we exit this loop

        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                Hero.rect.x -= 50
            elif event.key == pygame.K_RIGHT:
                Hero.rect.x += 50
            elif event.key == pygame.K_UP:
                Hero.rect.y -= 50
            elif event.key == pygame.K_DOWN:
                Hero.rect.y += 50


    # Clear the screen
    screen.fill(white)

    # Drawing Code
    y_offset = 0
    x_offset = 0
    while x_offset < 750:
        pygame.draw.line(screen,GREEN, [0+x_offset,0], [0+x_offset,500],1)
        x_offset = x_offset + 50

    while y_offset < 550:
        pygame.draw.line(screen, GREEN, [0,0+y_offset], [700,0+y_offset],1)
        y_offset = y_offset + 50

    # Draw all the sprites
    all_sprites_list.draw(screen)

    pygame.display.flip ()

    clock.tick (60)

pygame.quit ()`

1 个答案:

答案 0 :(得分:0)

首先,你永远不会调用精灵的update方法,因此你的碰撞检查永远不会被执行。

如果你打电话给它,它就会失败,因为你试着阅读self.change_y,这是你从未设定的。

如果你愿意,它仍然会失败,因为你试图检查self.walls中精灵的碰撞,但你从未设置它,因此self.walls总是None