我如何使对象居中以使矩形围绕我的角色?
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
属性定义。属性 x
和 y
定义 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)
我正在尝试使用 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
属性定义。属性 x
和 y
定义 Sprite 的中心。但是,方法 blit
specifies the upper left corner where the source pygame.Surface
. is drawn. See blit
:
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)