我有一个关于colliderect函数和嵌入在类和函数中的变量的问题。
我在我的重要元素(玩家,终点线,怪物)周围创建了“hitboxes”,我希望当这些hitbox“遇见”时触发动作。
我知道pygame中的 colliderect 函数是为了做到这一点,但不知怎的,我无法实现它。
有人可以向我解释一下,我将如何使用以下代码中的功能,特别是当我必须调用的变量嵌入到单独的类和函数中时?
非常感谢,到目前为止,这是我的代码:
#!/usr/bin/python
import sys, pygame, glob, math
from pygame import *
from random import randint
import time
pygame.init()
h = 600
w = 800
screen = pygame.display.set_mode((w, h))
clock = pygame.time.Clock()
jump_height = 0
class finish_line:
def __init__(self):
self.n = 600
self.b = 200
self.img_finish = pygame.image.load("finish.png")
self.update_finish(0)
def update_finish(self, pos_finish):
screen.blit(self.img_finish, (self.n, self.b))
class player:
def __init__(self):
self.x = 11
self.y = 200
self.speed = 5
self.ani_speed_init = 5
self.ani_speed = self.ani_speed_init
self.ani = glob.glob("animation/run*.png")
self.ani.sort()
self.ani_pos = 0
self.ani_max = len(self.ani)-1
self.img = pygame.image.load(self.ani[0])
self.update(0)
def update(self, pos):
if pos > 0:
if self.x >= (w - 100):
self.x = self.x
else:
self.x += self.speed
self.ani_speed -= 1
if self.ani_speed == 0:
self.img = pygame.image.load(self.ani[self.ani_pos])
self.ani_speed = self.ani_speed_init
if self.ani_pos == self.ani_max:
self.ani_pos = 0
else:
self.ani_pos += 1
elif pos < 0:
if self.x <= 9:
self.x = self.x
else:
self.x -= self.speed
self.ani_speed -= 1
if self.ani_speed == 0:
self.img = pygame.image.load(self.ani[self.ani_pos])
self.ani_speed = self.ani_speed_init
if self.ani_pos == self.ani_max:
self.ani_pos = 0
else:
self.ani_pos += 1
if jump_height == 1:
if self.y <= 10:
self.y = self.y
else:
self.y -= self.speed
elif jump_height == -1:
if self.y >= 500:
self.y = self.y
else:
self.y += self.speed
rectplayer = pygame.draw.rect(screen, (0, 0, 0), ((self.x + 10), (self.y + 15), 65, 70), 1)
screen.blit(self.img, (self.x, self.y))
return self.x, self.y
class monster:
rectmonster = 0
def __init__(self):
self.v = 650
self.c = 200
self.speed_monster = 0.3
self.img_monster = pygame.image.load("orange.png")
self.update_monster(0)
def update_monster(self, pos_monster):
if pos_monster == 1:
self.v = self.v + ((randint(-5, 1)) * self.speed_monster)
self.c = self.c + ((randint(-1, 3)) * self.speed_monster)
if self.v >= 660:
self.v = self.v + ((randint(-2, 0)) * self.speed_monster)
elif self.v <= 140:
self.v = self.v + ((randint(0, 2)) * self.speed_monster)
if self.c <= 140:
self.c = self.c + ((randint(0, 2)) * self.speed_monster)
elif self.c >= 460:
self.c = self.c + ((randint(-2, 0)) * self.speed_monster)
rectmonster = pygame.draw.rect(screen, (0, 0, 0), ((self.v + 12), (self.c + 5), 76, 90), 1)
screen.blit(self.img_monster, (self.v, self.c))
finish1 = finish_line()
player1 = player()
monster1 = monster()
monster2 = monster()
pos = 0
pos_monster = 1
pos_finish = 0
while 1:
screen.fill((255, 204, 229))
pygame.draw.rect(screen, (0,0,0,), (610, 210, 200, 180), 1)
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == KEYDOWN and event.key == K_RIGHT:
pos = 1
elif event.type == KEYUP and event.key == K_RIGHT:
pos = 0
elif event.type == KEYDOWN and event.key == K_LEFT:
pos = -1
elif event.type == KEYUP and event.key == K_LEFT:
pos = 0
elif event.type == KEYDOWN and event.key == K_UP:
jump_height = 1
elif event.type == KEYUP and event.key == K_UP:
jump_height = 0
elif event.type == KEYDOWN and event.key == K_DOWN:
jump_height = -1
elif event.type == KEYUP and event.key == K_DOWN:
jump_height = 0
finish1.update_finish(pos_finish)
monster1.update_monster(pos_monster)
monster2.update_monster(pos_monster)
player1.update(pos)
pygame.display.flip()
答案 0 :(得分:0)
根据上述两条评论,这是我对问题的两分钱。
您假设pygame.draw.rect
会自动为您的班级提供尺码属性,但事实并非如此
您将rect()
的返回值存储在rectplayer
中,如下所示:
rectplayer = pygame.draw.rect(...)
我打赌rect()
首先返回None
。除此之外,变量不会存储为self.rectplayer
,因此它是一个本地函数变量而不是类拥有的变量 - 所以Pygame无法检查它。
这是一个容易犯的错误,如果这是问题的唯一根源,那将是一个简单的修复。
不幸的是,这里有更多的假设,例如colliderrect
是Pygame
的全局函数。
Pygame
的内部函数有一个关键说明:
所有精灵必须有一个“rect”值,这是一个矩形 精灵区域,用于计算碰撞。
这是pygame.sprite.spritecollide()调用的内部函数,它提到了你应该使用 Sprites 的事实。
这是一个精灵对象的最小例子:
class Player(pygame.sprite.Sprite):
def __init__(self, color, width, height):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface([width, height])
self.image.fill(color)
self.rect = self.image.get_rect()
在这个精灵的初始化过程的底部,我们定义了包含self.rect
数据的矩形(start_x, start_y), (width, height)
。这些是您在上面的示例中未定义的大小属性。
最有可能的是,您可以按照以下方式定义:
class player:
def __init__(self):
self.rect = ...
但请记住,您的<class player>
没有名为spritecollide()
或collide_rect()
的功能,这些功能是来自pygame.sprite.Sprite
或pygame.Surface
的继承,所以你'最好坚持将这些作为自定义类的继承对象。
请参阅我上面的class Player(...)
如何执行此操作的示例。
我知道这并不能解决您的整个代码库,但希望它能让您对完成代码所需的内容有所了解。
友情提醒,如果您认为某些事情已经为您完成了 - 请仔细检查一下。假设一个类因为你绘制了一个矩形而获得了大小属性,请检查你的类是否真的这样做了。
player1 = player()
print(dir(player1))
那里有什么东西与width
,height
,size
或rectangle
类似吗?如果没有,这应该表明某些东西很时髦。