Pygame Sprite运动,无法更新

时间:2012-06-29 00:28:19

标签: python-3.x pygame sprite

我会尝试将我的问题重新定义为一个更简洁和具体的问题。下面是Hero类,其中有一些打印命令到终端,我正在尝试用它来解决出错的问题:

代码:

class Hero(pygame.sprite.Sprite):
    """Moves the hero around the screen, following the mouse"""
    #male = load_image("malehero-64.png", -1)
    #female = load_image("girlhero-64.png", -1)
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image, self.rect = load_image("girlhero-64.png", -1)
        self.rect = self.image.get_rect()
        self.rect.topleft = (384,0)
        self.target = self.movetarget()

    #def setgender(self, gender):
        #if gender == "male":
            #self.image, self.rect = self.male
        #if gender == "female":
            #self.image, self.rect = self.female
        #self.startingpos = (480, 640)
        #self.rect.topleft = (480,640)
        #self.target = self.rect.topleft

    def movetarget(self):
        self.pos = pygame.mouse.get_pos()
        self.rect = self.image.get_rect()
        self.target = self.rect.topleft
        self.targetx,self.targety = self.target
        self.oldx, self.oldy = self.rect.topleft
        if self.oldx + tilesize < self.pos[0]:
            self.targetx = self.oldx + tilesize
        if self.oldx > self.pos[0]:
            self.targetx = self.oldx - tilesize
        if self.oldx + tilesize >= self.pos[0] and self.oldx < self.pos[0]:
            self.targetx = self.oldx
        if self.oldy + tilesize < self.pos[1]:
            self.targety = self.oldy + tilesize
        if self.oldy > self.pos[1]:
            self.targety = self.oldy - tilesize
        if self.oldy + tilesize >= self.pos[1] and self.oldy < self.pos[1]:
            self.targety = self.oldy
        self.target = (self.targetx,self.targety)
        print("NOW THE TARGET IS SET!!!!!!!!")
        print(self.targetx,self.targety)
        return self.target

    def update(self):
        "Move the hero closer to the last mouse position clicked self.target"
        self.rect = self.image.get_rect()
        print("topleft before")
        print(self.rect.topleft)
        self.xmove = 0
        self.ymove = 0
        print("update target is")
        print(self.target)
        if self.rect.topleft[0] > 960:
            self.rect.topleft = (960, self.rect.topleft[1])
        if self.rect.topleft[0] < 0:
            self.rect.topleft = (0, self.rect.topleft[1])
        if self.rect.topleft[0] >= 0 and self.rect.topleft[0] <= 960:
            if self.rect.topleft[0] < self.target[0]:
                self.xmove = 4
            if self.rect.topleft[1] < self.target[1]:
                self.ymove = 4
            if self.rect.topleft[0] > self.target[0]:
                self.xmove = -4
            if self.rect.topleft[1] > self.target[1]:
                self.ymove = -4
        self.newx=self.rect.topleft[0]+self.xmove
        self.newy=self.rect.topleft[1]+self.ymove
        print("newx and newy")
        print (self.newx,self.newy)
        self.rect.topleft = (self.newx,self.newy)
        print("topleft after")
        print(self.rect.topleft)

运行时,终端的片段如下:

代码:

NOW THE TARGET IS SET!!!!!!!!
64 64
NOW THE TARGET IS SET!!!!!!!!
64 64
NOW THE TARGET IS SET!!!!!!!!
64 64
NOW THE TARGET IS SET!!!!!!!!
64 64
topleft before
(0, 0)
update target is
(0, 0)
newx and newy
0 0
topleft after
(0, 0)
topleft before
(0, 0)
update target is
(0, 0)
newx and newy
0 0
topleft after
(0, 0)
topleft before
(0, 0)
update target is
(0, 0)
newx and newy
0 0
topleft after
(0, 0)

我想要完成的事情: 在游戏地图上单击鼠标时,将调用Hero.movetarget,并将移动目标设置为距离当前矩形一个瓦片。然后,当charactersprites组在组中的所有精灵上调用更新方法(这里是正确的术语吗?)时,它们应该向目标图块移动几个像素。

当更新方法只是在一个跳跃中移动所有精灵时,我有精灵这样做没有问题。我试图改变它,以便精灵在几个帧上滑动到新的目标区块,而不是简单地跳到那里。

当我阅读上面的终端打印输出时,Hero.movetarget中设置的self.target变量与Hero.update开头打印到终端的self.target不同。

我不明白为什么在Hero.movetarget中更改self.target并没有改变Hero.update中的self.target。

请原谅我对这个问题的措辞无知,并提前感谢您提供的任何见解。

load_image类取自Pygame黑猩猩教程: 代码:

def load_image(name, colorkey=None):
    fullname = os.path.join('data', name)
    try:
        image = pygame.image.load(fullname)
    except pygame.error as message:
        print ('Cannot load image:', name)
        raise SystemExit(message)
    image = image.convert()
    if colorkey is not None:
        if colorkey is -1:
            colorkey = image.get_at((0,0))
        image.set_colorkey(colorkey, RLEACCEL)
    return image, image.get_rect()

调用Hero类的程序主体,编辑到我认为的相关部分: 代码:

hero = Hero()

charactersprites = pygame.sprite.Group((hero))

mathsterGroup = pygame.sprite.Group()
mathster = Mathster((0, 0))
mathsterGroup.add((mathster))
charactersprites.add((mathster))
mathster = Mathster((128, 256))
mathsterGroup.add((mathster))
charactersprites.add((mathster))
mathster = Mathster((512, 320))
mathsterGroup.add((mathster))
charactersprites.add((mathster))

inventory = TextObject("Hit a mathster!", Font, (0,0,0), (1024,50))
charactersprites.add((inventory))
nextproblem = Input(x=825, color=(255,25,25), 

heroGroup = pygame.sprite.Group()
heroGroup.add(hero)

clock = pygame.time.Clock() 

while 1:
    events1 = pygame.event.get()

    for event in events1:
        if event.type == pygame.QUIT: sys.exit()

    if not menu:
        for events in events1:
            if event.type == MOUSEBUTTONDOWN:
                mouseclick = 1

        if not collisiontest and mouseclick:
            for heros in charactersprites:
                hero.movetarget()
            for mathsters in mathsterGroup:
                mathster.movetarget()
            mouseclick = 0
        screen.fill((50,100,200))
        gamebackground = GameMap()
        if not mapdrawn:
            levelmap = gamebackground.drawmap()
            mapdrawn = 1
        screen.blit(levelmap, (0,0))
        wallGroup.draw(screen)
        nextproblem.update()
        nextproblem.draw(screen)
        charactersprites.update()
        charactersprites.draw(screen)
        screen.fill((50,100,200))
        screen.blit(menubackground, (0,0))
        menusprites.update()
        menusprites.draw(screen)


    pygame.display.flip()
    clock.tick(120)

提前感谢任何看过并愿意伸出援助之手的人。我一直在阅读很多教程,试图教育自己,但我一直无法找到我出错的地方。

欢迎任何改进我的代码的提示,尽管修复我不动的英雄是我的最高优先级。

编辑以制定更具体的问题。

1 个答案:

答案 0 :(得分:1)

tile id's

我建议你为每个怪物/玩家的位置使用元组(x,y)。保存为平铺偏移而不是像素。

绘制时,将tile-id转换为像素。如果它在屏幕外就好了。

def id_to_screen( tile_id width=32, height=32):
    """convert tile-coordinate to screen-coordinate (Pixels)"""
    x,y = tile_id
    x *= width
    y *= height
    return (x, y)         # unless you need: return pygame.Rect(x, y, width, height)    

你也需要反向,它将鼠标位置转换为tile-id。

def screen_to_id( pos, width=32, height=32):
    # converts screen pixel coordinate to world map tile offsets.
    x = pos[0] / width
    y = pos[1] / height
    return (x, y)

RECT

rect.topleft是sprite为blit的地方。设置此项以移动精灵。 (现在您正在设置targetx,并从self.rect读取。

    self.rect.topleft = (384,0)

    # or
    self.rect.move_ip(384,0)

删除self.targetx。除非您在地图上将其用作tile-id位置,否则不是像素。 (如果你绘制一个精灵,当它的Rect在屏幕外时,那很好。)

一些提示:

    self.targetx = self.rect.topleft[0]
    self.targety = self.rect.topleft[1]

    # becomes
    self.target = self.rect.topleft
    # or
    x,y = self.rect.topleft
    # or
    self.tilex, self.tiley = self.rect.topleft

rect虚拟属性很有用。见:http://www.pygame.org/docs/ref/rect.html#pygame.Rect。它们简化了逻辑/删除了一些数学。

    r.bottomleft = (20,30)
    r.left = 500

numpy +示例项目

Numpy对于多维数组(roguelike 2d tile maps)非常有用。 示例使用numpy数组作为地图。 http://code.google.com/p/ninmonkey/source/browse/#hg%2Fexamples%2Fmaptiles_numpy%253Fstate%253Dclosed

运行main.py,按s切换滚动图块。