0

さて、私は pygame で小さなゲームを作成し、タイルを多次元配列に生成してマップを構築しています。そのために、2 つの for ループを使用しています。

def create(this, t):

    if t == "grasslands":
        for j in range(0, this.numRows):
            for i in range(0, this.numColumns):
                this.column.append(this.Tile("grass", j * this.tileWidth, i * this.tileHeight))
            this.row.append(this.column)

j * this.tileWidthの値は、タイルの初期化に正しく渡されます。ただし、column[whatever].x値はまだ 0 です。y値は問題なく設定されます。jの代わりにiまたはその他の値を使用すると、問題なく動作します。これは私が間違っていることですか、それともPythonで何かおかしなことですか?

mapgen.py

import pygame
from sprite import *
from assets import *

class mapG:

def __init__(this, resw, resh):
    this.numRows = 3
    this.numcolumns = 3
    this.tileWidth = 128
    this.tileHeight = 128

    this.row = []
    this.column = []
    this.width = this.numRows * this.tileWidth
    this.height = this.numcolumns * this.tileHeight


def create(this, t):

    if t == "grasslands":
        for j in range(0, this.numRows):
            for i in range(0, this.numcolumns):
                this.column.append(this.Tile("grass", j * this.tileWidth, i * this.tileHeight))
            this.row.append(this.column)


def tileAt(this, x, y):
    pass

def moveRight(this):
    for j in range(0,this.numRows):
        for i in range(0, this.numcolumns):
            this.row[j][i].incX(1)

def Update(this, src):
    for j in range(0,this.numRows):
        for i in range(0, this.numcolumns):
            this.row[j][i].Update(src)
            print(this.row[j][i].y, this.row[j][i].x)

class Tile:

    def __init__(this, name, xpos, ypos):
        this.y = ypos
        this.x = xpos
        this.image = assets.tile[name + ".png"]
        this.sprite = sprite(this.image, this.x, this.y, 100, 100)

    def incX(this, amount):
        this.sprite.IncX(amount)

    def decX(this, amount):
        this.sprite.DecX(amount)

    def incY(this, amount):
        this.sprite.IncY(amount)

    def decY(this, amount):
        this.sprite.DecY(amount)

    def Update(this, src = None):
        if src != None:
            this.sprite.Update(src)

sprite.py

import pygame
import assets

class sprite:

def __init__(this, image, xpos, ypos, width = None, height = None):

    this.image = image
    this.x = xpos
    this.y = ypos
    this.width = width
    this.height = height

    if this.width != None and this.height != None:
        this.image = pygame.transform.scale(image, (this.width,this.height))

def GetPos(this):
    return (this.x, this.y)

def IncX(this, amount):
    this.x += amount

def IncY(this, amount):
    this.y += amount

def DecX(this, amount):
    this.x -= amount

def DecY(this, amount):
    this.y -= amount

def Update(this, src = None):
    if src != None:
        src.blit(this.image, this.GetPos())
4

2 に答える 2

5

あなたが抱えている問題は、メソッドでのthis.column変数の使用に起因すると思います。create

列リストを 1 つだけ ( で__init__) 作成し、それをマップのすべての列に再利用しています。これはうまくいきません。

リストには、作成したすべてのオブジェクトをthis.row含む同じ列リストへの複数の参照が含まれることになります。Tileリスト全体を実際に反復するのではなく、反復コードが事前定義されたディメンションを使用するため、後でそれらの一部のみが表示されます。

これを理解するために、2x2 グリッドの反復がどのように進行するか想像してみてください (タイルの寸法は無視します)。各ij値を独自の行に配置して、それがどのように進行するかを示し、各ステップ側の値rowと後に値を示します。columns

j=0:
   i=0:
      column.append(Tile(i, j))
      # column is [Tile(0, 0)]
      # row is []

   i=1:
      column.append(Tile(i, j))
      # column is [Tile(0, 0), Tile(0, 1)]
      # row is []

   row.append(column)
   # column is [Tile(0, 0), Tile(0, 1)]
   # row is [[Tile(0, 0), Tile(0, 1)]]

j=1: # column is not reset!
   i=0:
      column.append(Tile(i, j))
      # column is [Tile(0, 0), Tile(0, 1), Tile(1, 0)]
      # row is [[Tile(0, 0), Tile(0, 1), Tile(1, 0)]]

   i=1:
      column.append(Tile(i, j))
      # column is [Tile(0, 0), Tile(0, 1), Tile(1, 0), Tile(1, 1)]
      # row is [[Tile(0, 0), Tile(0, 1), Tile(1, 0), Tile(1, 1)]]

   row.append(column)
   # column is [Tile(0, 0), Tile(0, 1), Tile(1, 0), Tile(1, 1)]
   # row is [[Tile(0, 0), Tile(0, 1), Tile(1, 0), Tile(1, 1)],
   #          [Tile(0, 0), Tile(0, 1), Tile(1, 0), Tile(1, 1)]]

リストには、4 つのタイルrowの同じリストへの 2 つの参照が含まれています。columnあなたのコードは、最初の 2 つのタイルを最初の列に追加し、次に最後の 2 つのタイルを 2 番目の列に追加することを意図してTile(0, 0)Tile(0,1)ましTile(1, 0)Tile(1, 1)。しかし、同じリストが 2 回とも使用されたため、すべての値が一緒になってしまい、全体が繰り返されます。反復すると、上の図の左側の部分に繰り返される値のみが表示されます。

修正方法は次のとおりです。

def create(this, t):
    if t == "grasslands":
        for j in range(0, this.numRows):

            column = [] # Create a new list! This is the key!

            for i in range(0, this.numColumns):
                column.append(this.Tile("grass",
                              j * this.tileWidth,
                              i * this.tileHeight))
            this.row.append(column)

初期化するコンストラクターの行も削除self.columnできます。一時的に必要なだけなので、インスタンス変数を使用する必要はありません。

于 2013-04-29T08:41:38.250 に答える
0

幅 3 ( ) の行を作成することにはなりませんnumColumns。ループのたびに新しい行を作成しないため、幅 9 (rows*cols) の行になります。

ループは次のようになります。

for j in range(0, this.numRows):
    row=[]
    for i in range(0, this.numColumns):
        row.append(this.Tile("grass", j * this.tileWidth, i * this.tileHeight))
    this.rows.append(row)

そして、行が予想よりも長いことに気付かずに、デバッグ中に間違ったデータを見てしまった可能性があります。(また、名前が少し紛らわしいので、少し変更しました。)

于 2013-04-29T08:40:33.403 に答える