1

我将尝试将我的问题重新定义为一个更简洁和具体的问题。下面是 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 会被调用,并设置一个距离当前矩形一格的移动目标。然后,当字符精灵组对组中的所有精灵调用更新方法(这是正确的术语吗?)时,它们应该向目标图块移动几个像素。

当更新方法只是将所有精灵快速移动一个图块时,我让精灵毫无问题地执行此操作。我正在尝试更改它,以便精灵滑过几帧到新的目标图块,而不是简单地跳到那里。

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

我不明白为什么更改 Hero.movetarget 中的 self.target 不会更改 Hero.update 中的 self.target。

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

load_image 类取自 Pygame chimp 教程: 代码:

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)

预先感谢任何愿意看一看并愿意伸出援手的人。我一直在阅读很多教程来尝试自我教育,但我一直无法找到我哪里出错了。

欢迎任何改进我的代码的提示,尽管修复我一动不动的英雄是我的首要任务。

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

4

1 回答 1

1

tile id's

I suggest you use a tuple (x,y) for each monster/player's location. Saved as tile-offset rather than pixels.

When you draw, convert tile-id to pixels. It'll be ok if its offscreen.

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)    

You need the reverse too, which converts mouse location to tile-ids.

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 is the topleft of where the sprite is blit to. Set this to move the sprite. (Right now you are setting targetx, and reading from self.rect.

    self.rect.topleft = (384,0)

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

Remove self.targetx . Unless you are using it as tile-id locations on the map, instead of pixels. (If you draw a sprite, when it's Rect is offscreen, that's fine.)

Some tips:

    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 virtual attributes are useful. See : http://www.pygame.org/docs/ref/rect.html#pygame.Rect . They simplify logic / remove some math.

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

numpy + example project

Numpy is useful for multi-dimensional arrays (roguelike 2d tile maps). example uses a numpy array for the map. http://code.google.com/p/ninmonkey/source/browse/#hg%2Fexamples%2Fmaptiles_numpy%253Fstate%253Dclosed

Run main.py , press s to toggle scrolling tiles.

于 2012-06-29T19:02:36.717 回答