我正在为我的CS课程开展一个项目,我在附近的地方,我很乐意把它称为完整,但我收到了这个错误:
exceptions.AttributeError: type object 'protaganist' has no attribute 'hearts'
我也试图让我的示威课程向上移动......我已经尝试了
if keys[pygame.K_SPACE]:
self.y += self.dy # (where dy was defined as 10 in init)
我不知道还有什么可以尝试
最后我如何设置一个带有y位置的随机位置x的东西
它在这里强调:(它调用另一个classe的属性,但我不知道它导致错误的原因:
class coinandheartscore(gameEngine.SuperSprite):
def __init__(self, scene):
gameEngine.SuperSprite.__init__(self, scene)
self.font = pygame.font.SysFont("None", 50)
def update(self):
self.text = "hearts X: %d, Coins X: %d" % (protaganist.hearts, protaganist.coins)
self.image = self.font.render(self.text, 1, (255, 255, 0))
self.rect = self.image.get_rect()
这是我的整体代码:
import gameEngine
import pygame
import math
pygame.init()
screen = pygame.display.set_mode((640, 480))
pygame.mixer.init()
sndAtk = pygame.mixer.Sound("OOT_AdultLink_Attack1.wav")
sndWalk = pygame.mixer.Sound("OOT_Steps_Dirt1.wav")
sndPoof = pygame.mixer.Sound("OOT_Enemy_Poof1.wav")
sndWalk.set_volume(.1)
sndAtk.set_volume(.5)
sndPoof.set_volume(.9)
#sndRun = pygame.mixer.Sound("")
#goal is to create a game
#must have menu to start game
#menu should have a start and quit button.. start runs gaming operations and quit exits program
#sprites for character and enemies and bullets maybe, use one large image and simply move visibiliy
#this saves memory as 1 image is loaded instead of many
"""
protaganist is our hero sprite
should run left and right, jump left and right
and attack left and right...
I might add in the bow and jump attack
"""
class scrollinggrass(gameEngine.SuperSprite):
def __init__(self, scene):
gameEngine.SuperSprite.__init__(self, scene)
self.setImage("gamebackground.jpg")
self.rect = self.imageMaster.get_rect()
self.setPosition((400,247))
self.checkKeys()
self.dy = 3
def checkKeys(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_d]:
self.forward(-6)
sndWalk.play()
if keys[pygame.K_a]:
self.forward(6)
sndWalk.play()
class coins(gameEngine.SuperSprite):
def __init__(self, scene):
gameEngine.SuperSprite.__init__(self, scene)
self.loadImages()
self.image = self.imageMaster
self.frame = -1
self.pause = 0
self.delay = 3
def loadImages(self):
self.coinImgList = []
for i in range(3):
nameImage = "linkimages/coins/greenrupee%d.png" % i
self.setImage(nameImage)
tempImage = self.imageMaster
transparentColor = tempImage.get_at((1,1))
tempImage.set_colorkey(transparentColor)
self.coinImgList.append(tempImage)
def update(self):
self.pause += .25
if self.pause >= self.delay:
self.pause = 0
self.frame += 1
if self.frame >= len(self.coinImgList):
self.frame = 0
self.image = self.coinImgList[self.frame]
class hearts(gameEngine.SuperSprite):
def __init__(self, scene):
gameEngine.SuperSprite.__init__(self, scene)
self.setImage("heart.png")
self.setTransparentColor = self.imageMaster.get_at((1,1))
self.imageMaster.set_colorkey(self.setTransparentColor)
self.setPosition((550 , 30))
class badguy(gameEngine.SuperSprite):
def __init__(self, scene):
gameEngine.SuperSprite.__init__(self, scene)
self.setImage("badguy1.png")
self.setTransparentColor = self.imageMaster.get_at((1,1))
self.imageMaster.set_colorkey(self.setTransparentColor)
self.rect = self.imageMaster.get_rect()
# self.CONTINUE = 4
self.boundAction = self.CONTINUE
self.health = 2
self.DEAD = 1
self.state = 0
self.setPosition((200,375))
self.checkKeys()
def checkKeys(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_d]:
self.forward(-3)
if keys[pygame.K_a]:
self.forward(3)
def reset(self):
self.setPosition((1000, 375))
self.health = 2
# def update(self):
class protaganist(gameEngine.SuperSprite):
def __init__(self, scene):
gameEngine.SuperSprite.__init__(self, scene)
self.imageList = []
self.pause = 0
self.delay = 3
self.rect = self.imageMaster.get_rect()
self.STANDING = 0
self.RIGHT = 0
self.LEFT = 1
self.direction = self.RIGHT
self.RUNNING = 1
self.ATTACKING = 2
self.JUMPING = 3
self.DEAD = 10
self.frame = -1
self.state = self.STANDING
self.coins = 0
self.hearts = 1
self.heartPts = self.hearts * 3
self.stats()
self.dy = 20
self.loadImages()
self.image = self.imageMaster
self.checkKeys()
def stats(self):
#sets it up so each heart is essentially 3 hit points
if self.heartPts >= 3:
self.hearts = 1
elif self.heartPts >= 6:
self.hearts = 2
elif self.heartPts == 9:
self.hearts = 3
elif self.heartPts > 9:
self.heartPts = 9
# changes state to dead if hp == 0
if self.heartPts == 0:
self.state = DEAD
def loadImages(self):
self.setImage("heroSTANDINGLeft.gif")
self.setTransparentColor = self.imageMaster.get_at((1,1))
self.imageMaster.set_colorkey(self.setTransparentColor)
self.imageSTANDINGLeft = self.imageMaster
self.setImage("heroSTANDING.gif")
self.setTransparentColor = self.imageMaster.get_at((1,1))
self.imageMaster.set_colorkey(self.setTransparentColor)
self.imageSTANDING = self.imageMaster
self.heroATKList = []
self.heroATKleft = []
self.heroDEAD = []
self.heroRUNList = []
self.heroRUNLeftList = []
for i in range(4):
nameImage = "linkimages/DEAD/heroDEAD%d.gif" % i
self.setImage(nameImage)
tempImage = self.imageMaster
transparentColor = tempImage.get_at((1,1))
tempImage.set_colorkey(transparentColor)
self.heroDEAD.append(tempImage)
for i in range(5):
nameImage = "linkimages/runningRIGHT/heroRUN%d.gif" % i
self.setImage(nameImage)
tempImage = self.imageMaster
transparentColor = tempImage.get_at((1,1))
tempImage.set_colorkey(transparentColor)
self.heroRUNList.append(tempImage)
for i in range(5):
nameImage = "linkimages/runningLEFT/heroRUN%d.gif" % i
self.setImage(nameImage)
tempImage = self.imageMaster
transparentColor = tempImage.get_at((1,1))
tempImage.set_colorkey(transparentColor)
self.heroRUNLeftList.append(tempImage)
for i in range(4):
nameImage = "linkimages/ATTACKING/heroATTACKING%d.gif" % i
self.setImage(nameImage)
tempImage = self.imageMaster
transparentColor = tempImage.get_at((1,1))
tempImage.set_colorkey(transparentColor)
self.heroATKList.append(tempImage)
for i in range(4):
nameImage = "linkimages/ATTACKING/heroATTACKINGLeft%d.gif" % i
self.setImage(nameImage)
tempImage = self.imageMaster
transparentColor = tempImage.get_at((1,1))
tempImage.set_colorkey(transparentColor)
self.heroATKleft.append(tempImage)
def update(self):
self.rect = self.imageMaster.get_rect()
self.rect.x = 275
self.rect.y = 350
if self.state == self.STANDING:
if self.direction == self.RIGHT:
self.image = self.imageSTANDING
self.setPosition((200,200))
elif self.direction == self.LEFT:
self.image = self.imageSTANDINGLeft
if self.state == self.RUNNING:
if self.direction == self.RIGHT:
self.frame += 1
if self.frame >= len(self.heroRUNList):
self.frame = 0
self.image = self.heroRUNList[self.frame]
elif self.direction == self.LEFT:
self.frame += 1
if self.frame >= len(self.heroRUNLeftList):
self.frame = 0
self.image = self.heroRUNLeftList[self.frame]
if self.state == self.DEAD:
self.frame += 1
if self.frame >= len(self.heroDEAD):
self.frame = 0
self.image = self.heroDEAD[self.frame]
self.pause += .5
if self.pause >= self.delay:
self.pause = 0
if self.state == self.ATTACKING:
if self.direction == self.RIGHT:
self.frame += 1
sndAtk.play()
if self.frame >= len(self.heroATKList):
self.frame = 0
self.image = self.heroATKList[self.frame]
elif self.direction == self.LEFT:
self.frame += 1
sndAtk.play()
if self.frame >= len(self.heroATKleft):
self.frame = 0
self.image = self.heroATKleft[self.frame]
def checkKeys(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_d]:
self.direction = self.RIGHT
self.state = self.RUNNING
self.x += self.dx
else:
self.state = self.STANDING
if keys[pygame.K_a]:
self.state = self.RUNNING
self.direction = self.LEFT
if keys[pygame.K_g]:
self.state = self.ATTACKING
#sndAtk.play()
if keys[pygame.K_SPACE]:
self.addDY(3)
if self.state == self.DEAD:
self.image = self.deadImgList[0]
self.frame += 1
self.image = self.deadImgList[self.frame]
#self.image = self.image.get_rect()
#self.rect.center = (320, 240)
class coinandheartscore(gameEngine.SuperSprite):
def __init__(self, scene):
gameEngine.SuperSprite.__init__(self, scene)
self.font = pygame.font.SysFont("None", 50)
def update(self):
self.text = "hearts X: %d, Coins X: %d" % (protaganist.hearts, protaganist.coins)
self.image = self.font.render(self.text, 1, (255, 255, 0))
self.rect = self.image.get_rect()
class game(gameEngine.Scene):
def __init__ (self):
gameEngine.Scene.__init__(self)
pygame.display.set_caption("Link's Mediocre Adventure")
background = pygame.Surface(screen.get_size())
background.fill((0, 0, 0))
screen.blit(background, (0, 0))
coin = coins(self)
pro = protaganist(self)
baddy = badguy(self)
baddy1 = badguy(self)
heart = hearts(self)
grass = scrollinggrass(self)
score = coinandheartscore(self)
goodlySprites = self.makeSpriteGroup((grass, coin, pro, heart))
baddySprites = self.makeSpriteGroup((baddy, baddy1))
cnhrtSprites = self.makeSpriteGroup((score))
self.addGroup((cnhrtSprites))
self.addGroup((goodlySprites))
self.addGroup((baddySprites))
clock = pygame.time.Clock()
keepGoing = True
while keepGoing:
clock.tick(30)
for event in pygame.event.get():
if event.type == pygame.QUIT:
keepGoing = False
if pro.state == pro.ATTACKING:
if pro.collidesGroup(baddySprites):
baddy.health -= 1
baddy1.health -= 1
if baddy.health == 0:
sndPoof.play()
baddy.reset()
elif baddy1.health == 0:
sndPoof.play()
baddy1.reset()
elif pro.state != pro.ATTACKING:
if pro.collidesGroup(baddySprites):
pro.heartPts -= 1
baddy.checkKeys()
grass.checkKeys()
pro.checkKeys()
pro.loadImages()
goodlySprites.clear(screen, background)
baddySprites.clear(screen, background)
cnhrtSprites.clear(screen, background)
goodlySprites.update()
baddySprites.update()
cnhrtSprites.update()
goodlySprites.draw(screen)
baddySprites.draw(screen)
cnhrtSprites.draw(screen)
pygame.display.flip()
def main():
game.start()
if __name__ == "__main__":
game()
答案 0 :(得分:1)
至少有一个问题出在你的类命名中:PEP8约定要求大写的类名(Protagonist
)和它们的小写实例(pro
)。您已将您的班级protagonist
称为pro
并将其实例化为protagonist.hearts
。当你的意思是pro.hearts
(protagonist
类的实例的属性时,看起来你指的是{{1}}(没有这样的类属性)。
答案 1 :(得分:0)
作为一般规则,如果您有两个问题(甚至是同一段代码),您应该在Stack Overflow上发布两个单独的问题。那说......
1:向上移动
您在问题中引用的代码看起来不错。不幸的是,它与您在protaganist.checkKeys
中实际运行的代码完全不同:
if keys[pygame.K_SPACE]:
self.addDY(3)
是没有protaganist.addDY
方法,因此尝试调用它应该引发异常。不存在的方法的硬连接参数是3,而不是10.最后(为了更正您的评论),protaganist.__init__
将protaganist.dy
设置为20,而不是10。
2:AttributeError
您的protaganist
类没有hearts
属性,这几乎就是错误消息所说的内容。 (请注意,它通常拼写为“o”:protag o nist。)
protaganist
类做的 实例具有hearts
属性,但您无法通过查看类名来访问该属性。 (Python解释器如何知道您可能使用的protaganist
个实例中的哪一个?)
要获取特定protaganist
对象的hearts
值,您需要引用该特定实例:
class coinandheartscore(gameEngine.SuperSprite):
# New protagonist parameter is required.
def __init__(self, scene, protagonist):
gameEngine.SuperSprite.__init__(self, scene)
self.font = pygame.font.SysFont("None", 50)
# Save it for later use.
self.protagonist = protagonist
def update(self):
# self.protagonist refers to _one_ specific
# protaganist instance, which _does_ have
# hearts and coins attributes.
self.text = "hearts X: %d, Coins X: %d" % (
self.protagonist.hearts,
self.protagonist.coins,
)
# Remainder unchanged...
稍后,在game.__init__
方法中,您必须在实例化coinandheartscore
时提供新参数:
# New self.pro argument.
score = coinandheartscore(self, self.pro)
3:PEP-8
最后,我再次提到了xnx关于命名约定的评论......这些奇怪的名字让这个很多比以前更难以阅读。
虽然xnx在他的回答中没有链接到PEP-8,但字面上是第一个Google结果。他或她专门讨论了关于Naming Conventions的部分。
4:免费赠品
protaganist.checkKeys
:d
和a
不是您期望的反转。 d
将self.dx
(不存在)添加到self.x
,而a
则不添加任何内容。
protaganist.stats
将self.state
设置为DEAD
,但不存在。你可能意味着self.DEAD
。
通常,测试更多,代码更少。您在测试之间写的越多,您需要追踪的错误就越多,它们可以隐藏的地方就越多。