我如何使对象居中以使矩形围绕我的角色?

How do I center objects so the rectangle is around my character?

我正在尝试使用 pygame 制作一个小游戏(只是为了好玩),但我无法正确处理对象之间的碰撞。所以我决定绘制碰撞并注意到碰撞不在我的角色周围。这就是我的意思: The rectangles are the collisions

这是我的代码:

import pygame

pygame.init()
winWidth = 400
winHeigth = 400
win = pygame.display.set_mode((winWidth, winHeigth))
pygame.display.set_caption("Pokemon copy")

Items = []

walkUp = [pygame.image.load('Up1.png'), pygame.image.load('Up2.png'), pygame.image.load('Up3.png'), pygame.image.load('Up4.png'), pygame.image.load('Up5.png'), pygame.image.load('idleUp.png'), pygame.image.load('Up6.png'), pygame.image.load('Up5.png'), pygame.image.load('Up6.png')]
walkDown = [pygame.image.load('D1.png'), pygame.image.load('D2.png'), pygame.image.load('D3.png'), pygame.image.load('D4.png'), pygame.image.load('D5.png'), pygame.image.load('idle.png'), pygame.image.load('D3.png'), pygame.image.load('D4.png'), pygame.image.load('D2.png')]
walkRight = [pygame.image.load('R1.png'), pygame.image.load('R2.png'), pygame.image.load('R3.png'), pygame.image.load('R4.png'), pygame.image.load('R1.png'), pygame.image.load('R2.png'), pygame.image.load('R3.png'), pygame.image.load('R4.png'), pygame.image.load('idleRight.png')]
walkLeft = [pygame.image.load('L1.png'), pygame.image.load('L2.png'), pygame.image.load('L3.png'), pygame.image.load('L4.png'), pygame.image.load('L3.png'), pygame.image.load('L2.png'), pygame.image.load('L1.png'), pygame.image.load('L2.png'), pygame.image.load('idleLeft.png')]
bg = pygame.image.load('Test.png')
idle = [pygame.image.load('idle.png'), pygame.image.load("idleUp.png"), pygame.image.load("idleLeft.png"), pygame.image.load("idleRight.png")]

myfont = pygame.font.SysFont("monospace", 15)

clock = pygame.time.Clock()


class trainer():
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.width = 32
        self.heigth = 32
        self.enemy = pygame.image.load('idleE.png')
        self.rect = self.enemy.get_rect()

    def draw(self, win):
        win.blit(self.enemy, (self.x, self.y))


class player():
    def __init__(self, x, y, width, heigth):
        self.x = x
        self.y = y
        self.width = width
        self.heigth = heigth
        self.vel = 5
        self.left = False
        self.right = False
        self.up = False
        self.down = False
        self.walkCount = 0
        self.stamina = 100
        self.Event = pygame.USEREVENT+1
        self.previous = "right"
        self.player = pygame.image.load("idle.png")
        self.rect = self.player.get_rect(center=(self.x, self.y))
        self.pos = self.x, self.y

    def draw(self, win):
        if self.walkCount + 1 >= 27:
            self.walkCount = 0
        if self.up:
            self.rect.center = self.x, self.y
            win.blit(walkUp[self.walkCount//3], (self.x, self.y))
            self.walkCount += 1
        elif self.down:
            self.rect.center = self.x, self.y
            win.blit(walkDown[self.walkCount//3], (self.x, self.y))
            self.walkCount += 1
        elif self.right:
            self.rect.center = self.x, self.y
            win.blit(walkRight[self.walkCount//3], (self.x, self.y))
            self.walkCount += 1
        elif self.left:
            self.rect.center = self.x, self.y
            win.blit(walkLeft[self.walkCount//3], (self.x, self.y))
            self.walkCount += 1
        else:
            if self.previous == "up":
                win.blit(idle[1], (self.x, self.y))
            elif self.previous == "down":
                win.blit(idle[0], (self.x, self.y))
            elif self.previous == "left":
                win.blit(idle[2], (self.x, self.y))
            elif self.previous == "right":
                win.blit(idle[3], (self.x, self.y))

    def Collision(self, Potion):
        if self.rect.colliderect(Potion.rect):
            return True
        else:
            return False

    def getPos(self):
        return self.x, self.y


class usableItems():
    def __init__(self, x, y):
        self.usable = True
        self.x = x
        self.y = y


class potion(usableItems):
    def __init__(self, usable, x, y):
        super().__init__(x, y)
        self.heal = 20
        self.potion = pygame.image.load("Potion.png")
        self.rect = self.potion.get_rect(center=(self.x, self.y))

    def draw(self, win):
        self.rect.center = self.x, self.y
        win.blit(self.potion, (self.x, self.y))


def write(text, x, y, color):
    text = myfont.render(text, 4, pygame.Color(color))
    text_rect = text.get_rect(center=(winWidth//2, y))
    return text, text_rect


def inventory():
    Inventory = True
    while Inventory:
        clock.tick(27)

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                Inventory = False

        keys = pygame.key.get_pressed()

        if keys[pygame.K_ESCAPE]:
            Inventory = False

        redrawInventoryWindow(Items)


def redrawInventoryWindow(items):
    win.fill((0, 0, 0))
    if len(items) == 0:
        message = "You currently have no items!"
        text, text_rect = write(message, 10, 70, (255, 255, 255))
        win.blit(text, text_rect)
    else:
        distance = 10
        for item in items:
            text2, text_rect2 = write(item, 0, distance, (255, 255, 255))
            distance += 25
            win.blit(text2, text_rect2)
    pygame.display.update()


def redrawGameWindow(character, trainer1, Potion):
    win.fill((255, 255, 255))
    text = "Stamina: " + str(int(character.stamina)) + "/100"
    label = myfont.render(text, 1, (0, 0, 0))
    win.blit(label, (0, winHeigth - 50))
    character.draw(win)
    pygame.draw.rect(win, (0, 255, 0), character, 3, 1)
    trainer1.draw(win)
    Potion.draw(win)
    pygame.draw.rect(win, (200, 55, 0), Potion, 3, 2)
    pygame.display.update()


def game():
    character = player(50, 50, 32, 32)
    trainer1 = trainer(300, 360)
    Potion = potion(True, 150, 150)
    run = True
    while run:
        clock.tick(27)

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False

        keys = pygame.key.get_pressed()

        if keys[pygame.K_i]:
            inventory()

        elif keys[pygame.K_LCTRL] and character.stamina > 0:
            vel = 7.5
            pygame.time.set_timer(character.Event, 1000)
            character.stamina -= 1

        elif not keys[pygame.K_LCTRL] and character.stamina < 100:
            vel = 5
            pygame.time.set_timer(character.Event, 1000)
            character.stamina += 0.5
        else:
            vel = 5

        if keys[pygame.K_LEFT] and character.x > 0:
            character.previous = "left"
            character.x -= vel
            character.left = True
            character.right = False
            character.up = False
            character.down = False

        elif keys[pygame.K_RIGHT] and character.x < winWidth - character.width:
            character.previous = "right"
            character.x += vel
            character.right = True
            character.left = False
            character.up = False
            character.down = False

        elif keys[pygame.K_UP] and character.y > 0:
            character.previous = "up"
            character.y -= vel
            character.up = True
            character.down = False
            character.left = False
            character.right = False

        elif keys[pygame.K_DOWN] and character.y < winHeigth - character.heigth:
            character.previous = "down"
            character.y += vel
            character.down = True
            character.up = False
            character.left = False
            character.right = False

        else:
            character.right = False
            character.left = False
            character.up = False
            character.down = False
            character.walkCount = 0

        if character.Collision(Potion):
            if keys[pygame.K_DOWN]:
                character.y -= vel
            elif keys[pygame.K_UP]:
                character.y += vel
            elif keys[pygame.K_LEFT]:
                character.x += vel
            elif keys[pygame.K_RIGHT]:
                character.x -= vel
            vel = 0

        redrawGameWindow(character, trainer1, Potion)

    pygame.quit()


game()

请注意,我是编程新手,所以我知道我的代码还有很多需要改进的地方。

您的矩形是正确的,但是 Sprites 绘制在错误的位置。 Sprites 的位置由 rect 属性定义。属性 xy 定义 Sprite 的中心。但是,方法 blit specifies the upper left corner where the source pygame.Surface. is drawn. See blit:

的参数 dest

Draws a source Surface onto this Surface. The draw can be positioned with the dest argument. The dest argument can either be a pair of coordinates representing the position of the upper left corner of the blit or a Rect, where the upper left corner of the rectangle will be used as the position for the blit.

您必须更改所有 draw 方法:

class trainer():
    # [...]

        def draw(self, win):
        self.rect.center = self.x, self.y
        win.blit(self.enemy, self.rect)
class player():
    # [...]

    def draw(self, win):
        self.rect.center = self.x, self.y
        if self.walkCount + 1 >= 27:
            self.walkCount = 0
        if self.up:
            win.blit(walkUp[self.walkCount//3], self.rect)
            self.walkCount += 1
        elif self.down:
            win.blit(walkDown[self.walkCount//3], self.rect)
            self.walkCount += 1

        # continue for all "win.blit()"
class potion(usableItems):
    # [...]

    def draw(self, win):
        self.rect.center = self.x, self.y
        win.blit(self.potion, self.rect)