Pygame Movement of Flag and Character With Walls

六眼飞鱼酱① 提交于 2020-05-31 04:03:43

问题


I am making a capture the flag type game. From the code below, I have the fundamentals set up. However, I don't know how I stop the flag from moving when the character hits a wall. Can anyone help me with this? As you can see if you run the code, the flag is effectively picked up by the character and carried but the flag will not stop if the character hits a wall. I want the flag to stay on the right side of the character as well. Thanks for any help. (CODE HAS BEEN UPDATED SINCE ORIGINAL POST)

import pygame
def start():
    pygame.init()
    BLUE = (0, 0, 128)
    RED = (204, 0, 0)
    WHITE = (255, 255, 255)
    BLACK = (0, 0, 0)
    screen = pygame.display.set_mode((1920,1080), flags=pygame.FULLSCREEN)
    pygame.display.set_caption("Recovery")
    clock = pygame.time.Clock()
    bigJoe = pygame.image.load("bigJoe.png")
    characterSelected = bigJoe
    game(BLACK, WHITE, BLUE, RED, screen, clock, characterSelected, bigJoe)
def game(BLACK, WHITE, BLUE, RED, screen, clock, characterSelected, bigJoe):
    if characterSelected == bigJoe:
        gameCharacter = "gameJoe.png"
    all_sprite_list = pygame.sprite.Group()
    playerList = pygame.sprite.Group()
    wall_list = pygame.sprite.Group()
    flagList = pygame.sprite.Group()
    playerFlag = pygame.sprite.Group()
    flag = Flag(1810,540)
    flagList.add(flag)
'''Design of Map Below'''
    topWall = Wall(0, 0, 1920, 5, BLUE)
    bottomWall = Wall(0, 1075, 1920, 5, BLUE)
    leftWall = Wall(0, 0, 5, 1080, BLUE)
    rightWall = Wall(1915, 0, 5, 1080, BLUE)
    baseWall1 = Wall(5, 300, 150, 75, WHITE)
    baseWall2 = Wall(5, 375, 100, 330, WHITE)
    baseWall3 = Wall(5, 705, 150, 75, WHITE)
    baseSquare = Wall(30, 530, 40, 40, RED)
    wall1 = Wall(400, 400, 200, 300, RED)
    wall_list.add(topWall, bottomWall, leftWall, rightWall, baseWall1, wall1, baseWall2, baseWall3)
    all_sprite_list.add(topWall, bottomWall, leftWall, rightWall, baseWall1, wall1, baseWall2, baseWall3, baseSquare, flag)
'''Adding Character to Game'''
    player = Player(110, 550, gameCharacter)
    flag.player = playerFlag
    player.wall = wall_list
    all_sprite_list.add(player)
    playerFlag.add(player, flag)
    playerList.add(player)
    flag.player = player
    flag.carried = playerFlag
    flag.walls = wall_list
    run = True
    while run:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False
            keys = pygame.key.get_pressed()
            if keys[pygame.K_ESCAPE]:
                run = False
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:
                    player.changespeed(-3, 0)
                    flag.moveFlag(-3, 0)
                elif event.key == pygame.K_RIGHT:
                    player.changespeed(3, 0)
                    flag.moveFlag(3, 0)
                elif event.key == pygame.K_UP:
                    player.changespeed(0, -3)
                    flag.moveFlag(0, -3,)
                elif event.key == pygame.K_DOWN:
                    player.changespeed(0, 3)
                    flag.moveFlag(0, 3)
            elif event.type == pygame.KEYUP:
                if event.key == pygame.K_LEFT:
                    player.changespeed(3, 0)
                    flag.moveFlag(3, 0)
                elif event.key == pygame.K_RIGHT:
                    player.changespeed(-3, 0)
                    flag.moveFlag(-3, 0)
                elif event.key == pygame.K_UP:
                    player.changespeed(0, 3)
                    flag.moveFlag(0, 3)
                elif event.key == pygame.K_DOWN:
                    player.changespeed(0, -3)
                    flag.moveFlag(0, -3)
        all_sprite_list.update()
        screen.fill(BLACK)
        all_sprite_list.draw(screen)
        pygame.display.flip()
        clock.tick(75)

start()

On a separate file

import pygame
class Player(pygame.sprite.Sprite):
    def __init__(self, x, y, gameCharacter):
        super().__init__()
        self.image = pygame.image.load(gameCharacter)
        self.rect = self.image.get_rect()
        self.rect.y = y
        self.rect.x = x
        self.change_x = 0
        self.change_y = 0
        self.wall = None

    def changespeed(self, x, y):
        self.change_x += x
        self.change_y += y

    def update(self):
        self.rect.x += self.change_x
        wallHitList = pygame.sprite.spritecollide(self, self.wall, False)
        for wall in wallHitList:
            if self.change_x > 0:
                self.rect.right = wall.rect.left
            else:
                self.rect.left = wall.rect.right
        self.rect.y += self.change_y
        wallHitList = pygame.sprite.spritecollide(self, self.wall, False)
        for wall in wallHitList:
            if self.change_y > 0:
                self.rect.bottom = wall.rect.top
            else:
                self.rect.top = wall.rect.bottom


class Wall(pygame.sprite.Sprite):
    def __init__(self, x, y, width, height,color):
        super().__init__()
        self.image = pygame.Surface([width, height])
        self.image.fill(color)
        self.rect = self.image.get_rect()
        self.rect.y = y
        self.rect.x = x


class Flag(pygame.sprite.Sprite):
    def __init__(self, x, y,):
        super().__init__()
        self.image = pygame.image.load("flag.png")
        self.rect = self.image.get_rect()
        self.rect.y = y
        self.rect.x = x
        self.change_x = 0
        self.change_y = 0


    def moveFlag(self, x, y):
        self.change_x += x
        self.change_y += y

    def update(self):
        hit = False
        allowMove = True
        flagCharacterList = pygame.sprite.spritecollide(self, self.carried, False)
        for i in flagCharacterList:
            if len(flagCharacterList) == 2:
                hit = True
            else:
                hit = False
        block_hit_list = pygame.sprite.groupcollide(self.walls, self.carried, False, False)
        for block in block_hit_list:
            if len(block_hit_list) == 1:
                allowMove = False
            else:
                allowMove = True
        if hit and allowMove:
            self.rect.x += self.change_x
            self.rect.y += self.change_y

回答1:


The flag doesn't move bit itself. bit the player carries the flag. Possibly the player can carry more than 1 flag.

Remove the collision detection from the method Flag.update:

class Flag(pygame.sprite.Sprite):
    def __init__(self, x, y,):
        super().__init__()
        #self.image = pygame.image.load("flag.png")
        self.rect = self.image.get_rect()
        self.rect.y = y
        self.rect.x = x
        self.change_x = 0
        self.change_y = 0

    def moveFlag(self, x, y):
        self.change_x += x
        self.change_y += y

    def update(self):
        self.rect.x += self.change_x
        self.rect.y += self.change_y

Add an attribute self.flags to the player and move all the flags contained in the list by the same amount as the player:

class Player(pygame.sprite.Sprite):
    def __init__(self, x, y, gameCharacter):
        # [...]

        self.flags = []

    # [...]

    def update(self):

        current_pos = (self.rect.x, self.rect.y) 

        self.rect.x += self.change_x
        wallHitList = pygame.sprite.spritecollide(self, self.wall, False)
        for wall in wallHitList:
            if self.change_x > 0:
                self.rect.right = wall.rect.left
            else:
                self.rect.left = wall.rect.right
        self.rect.y += self.change_y
        wallHitList = pygame.sprite.spritecollide(self, self.wall, False)
        for wall in wallHitList:
            if self.change_y > 0:
                self.rect.bottom = wall.rect.top
            else:
                self.rect.top = wall.rect.bottom

        for flag in self.flags:
            flag.rect.x += self.rect.x - current_pos[0]
            flag.rect.y += self.rect.y - current_pos[1]

flag.move() is not needed any more. But if the player hits the flag, then the flag is add player.flags. That caused, that the plyer carries the flag:

def game(BLACK, WHITE, BLUE, RED, screen, clock, characterSelected, bigJoe):
    # [...]

    while run:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False
            keys = pygame.key.get_pressed()
            if keys[pygame.K_ESCAPE]:
                run = False
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT: player.changespeed(-3, 0)
                elif event.key == pygame.K_RIGHT: player.changespeed(3, 0)
                elif event.key == pygame.K_UP: player.changespeed(0, -3)
                elif event.key == pygame.K_DOWN: player.changespeed(0, 3)
            elif event.type == pygame.KEYUP:
                if event.key == pygame.K_LEFT: player.changespeed(3, 0)
                elif event.key == pygame.K_RIGHT: player.changespeed(-3, 0)
                elif event.key == pygame.K_UP: player.changespeed(0, 3)
                elif event.key == pygame.K_DOWN: player.changespeed(0, -3)

        if flag not in player.flags:
            if pygame.sprite.collide_rect(flag, player):
                player.flags.append(flag)
                flag.rect.left = player.rect.right

        # [...]


来源:https://stackoverflow.com/questions/62073323/pygame-movement-of-flag-and-character-with-walls

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!