Pygame 表面无意中在对象之间共享

问题描述 投票:0回答:1

在两个单独的文件中使用此代码:

import pygame

# These are used to figure out where this top-level module is being run 
#   so that the path can be passed to submodules
from inspect import getsourcefile
from os.path import abspath

import RT_Core.rt_multimedia as mm
import Core.class_hexagon as hx
import RT_Core.rt_map as mp

# Import pygame locals into local namespace.  Do them all so we're not
#   constantly updating this list every time we find out we need a new one
from pygame.locals import *

print("Starting Pygame...")
pygame.init()

"""
    Globals/Constants
""" ###########################################################################
SCR_WIDTH = 800
SCR_HEIGHT = 600

WORLD_X = 3
WORLD_Y = 5

"""
    Classes
""" ###########################################################################

class Tile(pygame.sprite.Sprite) :
    def __init__(self, gfx) :
        super().__init__()
        self.image = gfx.copy()
        self.rect = self.image.get_rect()

# end class Tile

# Window needs to be made first or images won't load...
screen = pygame.display.set_mode((SCR_WIDTH, SCR_HEIGHT), RESIZABLE)
pygame.display.set_caption("Railroad Tycoon")

local_path = abspath(getsourcefile(lambda:0))
local_path = local_path.replace("railroad_tycoon.py" , "")
mm.multimedia_init(local_path)
tile_invalid = mm.load_tile_invalid()
tiles_sea = mm.load_tile_sea()
tiles_clear = mm.load_tile_clear()
tiles_mtn = mm.load_tile_mountain()

hex_manager = mp.Hexagon_Map(   tile_invalid.get_width(), \
                                tile_invalid.get_height())
empty_world_row = list()
world = list()
for i in range(WORLD_X) :
    empty_world_row.append(Tile(tile_invalid))
for i in range(WORLD_Y) :
    world.append(empty_world_row)

world[0][ 0] = Tile(tiles_sea[0x00])
"""
world[0][ 1] = Tile(tiles_sea[0x01])
world[0][ 2] = Tile(tiles_sea[0x02])
world[1][ 0] = Tile(tiles_clear[0x00])
world[1][ 1] = Tile(tiles_clear[0x01])
world[1][ 2] = Tile(tiles_clear[0x02])
world[2][ 0] = Tile(tiles_mtn[0x00])
world[2][ 1] = Tile(tiles_mtn[0x01])
world[2][ 2] = Tile(tiles_mtn[0x02])     
"""
    
bg_image = mm.load_background_image()
bg_cur = pygame.transform.smoothscale(bg_image, (SCR_WIDTH, SCR_HEIGHT))
screen.blit(bg_cur, (0, 0))
screen.blit(tile_invalid, (SCR_WIDTH / 2, SCR_HEIGHT / 2))
#screen.blit(world._get(0, 0).image, (0, 0))
for i in range(WORLD_X) :
    for j in range(WORLD_Y) :
        screen.blit(world[j][ i].image, hex_manager.get_xy(i, j))

running = True
clock = pygame.time.Clock()
while running :
    for event in pygame.event.get() :
        if event.type == QUIT :
            running = False
        if event.type == WINDOWRESIZED :
            SCR_WIDTH = screen.get_width()
            SCR_HEIGHT = screen.get_height()
            bg_cur = pygame.transform.smoothscale(  bg_image, \
                                                    (SCR_WIDTH, SCR_HEIGHT) )
            screen.blit(bg_cur, (0, 0))
    
    pygame.display.update()
            
# Close properly            
pygame.quit()

# end railroad_tycoon.py

class Hexagon_Map :
    def __init__(self, tile_width : int, tile_height : int) :
        self.w = tile_width
        self.h = tile_height
            
    def convert_from_axial_q(self, col : int, row : int) :
        return col + ((row - (row & 0x01)) >> 0x01)
                     
    def get_xy(self, col : int, row : int) :
        # All odd rows are x-offset by just a half tile
        x = (col * self.w) + ((self.w * (row & 0x01)) >> 0x01)
        # Each row is 75% of a height down from the previous row
        y = ((self.h * 0x03) >> 0x02) * row
        return (x, y)
         
# end class Hexagon_Map

我得到以下输出:

我期望的是,只有左上角的六边形呈现蓝色,而其他所有六边形都是黑色。因此,看起来底层表面对象正在以某种方式共享,但我没有看到它来自哪里,因为 Tile 类构造函数使用

copy()
操作。另一种选择是,我实际上只是一遍又一遍地绘制同一行,但我不确定为什么会出现这种情况。我在这里缺少什么?

请注意,

load_tile_invalid()
返回单个表面对象,而其他每个
load_tile
函数返回三个表面的列表。

pygame sprite pygame-surface
1个回答
0
投票

您在世界列表中多次附加相同的empty_world_row列表,对该列表的任何更改都将反映在引用它的所有地方。

您每次都需要创建一个新列表


world = list()
for i in range(WORLD_Y) :
    empty_world_row = list()
    for i in range(WORLD_X) :
        empty_world_row.append(Tile(tile_invalid))
    world.append(empty_world_row)
© www.soinside.com 2019 - 2024. All rights reserved.