簡體   English   中英

Python-變量設置為0,無法弄清原因

[英]Python - variable is getting set to 0 and can't figure out why

好的,所以我要用pygame做一個小游戲,並通過將圖塊生成為多維數組來構建地圖。 為了做到這一點,我使用了兩個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的值已正確傳遞到Tile初始化中。 之后雖然列[任何] .X值仍為0 y值被設置得很好,如果我用或任何其他值,而不是j的事情工作就好了。 這是我做錯的事情還是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())

我相信您遇到的問題來自在create方法中使用this.column變量。

您僅創建一個列列表(在__init__ ),然后將其重新用於地圖的所有列。 這行不通。

您的this.row列表最終具有對同一列列表的多個引用,該列表最終包含您創建的所有Tile對象。 稍后您只會看到其中的一些,因為您的迭代代碼使用預定義的維度,而不是實際遍歷整個列表。

要了解這一點,請嘗試想象2x2網格的迭代過程如何進行(忽略圖塊尺寸)。 我將每個ij值放在自己的行上以顯示其進度,並在每一步之后給出rowcolumns的值:

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)]]

row列表包含對四個圖塊的同一column列表的兩個引用。 您的代碼打算將前兩個Tile(0, 0)Tile(0,1)到第一列,然后將后兩個Tile(1, 0)Tile(1, 1)到第二列。 但是由於兩次都使用相同的列表,所以最終將所有值放在一起,然后重復整個過程。 進行迭代時,您只會在上圖的左側看到重復的值。

解決方法如下:

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的構造函數中的這一行。 它只是臨時需要的,因此不需要使用實例變量。

您最終不會創建寬度為3( numColumns )的行。 您最終會得到寬度為9(行*列)的行,因為您不會在循環中每次都創建新行。

您的循環應如下所示:

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)

然后,您可能會在調試數據時看到錯誤的數據,而沒有意識到該行的長度超出了您的預期。 (而且名稱有些混亂,因此我對其進行了一些更改。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM