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が呼び出され、現在の長方形から1タイル離れた移動ターゲットを設定します。次に、characterspritesグループがグループ内のすべてのスプライトでupdateメソッド(ここでは正しい用語ですか?)を呼び出すと、そのターゲットタイルに向かって数ピクセル移動する必要があります。

更新メソッドがすべてのスプライトを1タイル飛躍​​的に移動するだけの場合、スプライトは問題なくこれを実行していました。スプライトが単にそこに跳躍するのではなく、いくつかのフレームを滑って新しいターゲットタイルに移動するように変更しようとしています。

上記のターミナルのプリントアウトを読んだように、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)

ご覧になり、手を貸してくださる方、よろしくお願いします。私は自分自身を教育するためにたくさんのチュートリアルを読んでいますが、どこが間違っているのかを見つけることができませんでした。

私のコードを改善するためのヒントは大歓迎ですが、私の動かないヒーローを修正することが私の最優先事項です。

より具体的な質問を作成するために編集します。

4

1 に答える 1

1

タイルID

(x,y)各モンスター/プレイヤーの場所にタプルを使用することをお勧めします。ピクセルではなくタイル オフセットとして保存されます。

描画するときは、タイル 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.topleftスプライトがブリットされる場所の左上です。これを設定してスプライトを動かします。(現在、targetx を設定し、self.rect.

    self.rect.topleft = (384,0)

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

削除しself.targetxます。ピクセルではなく、マップ上のタイル 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 は、多次元配列 (ローグライク 2D タイル マップ) に役立ちます。例では、マップに numpy 配列を使用しています。http://code.google.com/p/ninmonkey/source/browse/#hg%2Fexamples%2Fmaptiles_numpy%253Fstate%253D閉鎖

を実行main.pyし、 を押しsてスクロール タイルを切り替えます。

于 2012-06-29T19:02:36.717 に答える