Python 类/实例/对象组织问题

发布于 2024-10-16 03:33:14 字数 838 浏览 1 评论 0原文

以下是我尝试在 python 中执行的操作的简化示例(使用 pygame,但这可能不相关)。

我有一个 8x8 像素 jpg 列表,每个都描绘一个英文字母:

[a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p ,q,r,s,t,u,v,w,x,y,z]

我想以我想要的任何图案排列这些 4x4 网格,作为更大的 32x32 图片:

gmmg
gppg
gppg
gmmg

但是该图案只是动画的单帧。 例如,我可能需要 4 个动画帧,其中 b 和 n 交替闪烁,而 f 向西南移动:

bbnf nnbb bbnn nnbb
bbnn nnfb bbnn nnbb
bbnn nnbb bfnn nnbb
bbnn nnbb bbnn fnbb

我希望控制每个帧中每个方块的字母值来制作任何动画,所以我猜基本上有 64 个独立的动画帧变量(对于像上面所示的 4 帧动画)。每个方块还有一个 [x,y] 列表位置变量和 rbg 颜色。

我的问题是如何通过类来组织这一切(我正在尝试学习 OOP)。从逻辑上讲,似乎每个框架都包含正方形,每个正方形都包含位置、字母和颜色等变量。但我想你甚至可以将其视为每个正方形“包含”4 个框架...... 我的猜测是创建一个框架类,并将其 4 个实例放入一个列表中(如果有 4 个框架),并以某种方式使每个框架实例包含 16 个正方形实例的列表。也许可以像frames[2].squares[5].letter = f一样使用(只是一个模糊的想法;我对OOP太陌生,不知道这是否是正确的还是一个好主意)。但看看知道自己在做什么的人如何组织这一切将会很有帮助。 谢谢!

The following is a simplified example for something I'm trying to do in python (with pygame, but that's probably irrelevant).

I have a list of 8x8 pixel jpgs, each depicting an English letter:

[a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z]

I want to arrange a 4x4 grid of these, in any pattern I want, as a larger 32x32 picture:

gmmg
gppg
gppg
gmmg

But that pattern is only a single frame of an animation.
For example, I might want 4 animation frames where b's and n's flash side to side alternately while an f moves southwest:

bbnf nnbb bbnn nnbb
bbnn nnfb bbnn nnbb
bbnn nnbb bfnn nnbb
bbnn nnbb bbnn fnbb

I want control over the letter value of each square in each frame to make any animation, so I guess essentially there are 64 separate variables (for a 4-frame animation like the one shown above). Each square also has an [x,y] list position variable and rbg color.

My question is how to organize this all with classes (I'm trying to learn OOP). Logically, it seems that each frame contains squares, and each square contains variables like position, letter and color. But I suppose you could even think of it as each square 'contains' 4 frames...
My guess is make a frame class, and put 4 instances of it in a list (if there's 4 frames) and somehow make each frame instance contain a list of 16 square instances. Maybe usable like frames[2].squares[5].letter = f (Just a fuzzy idea; I'm too new at OOP to know if that's remotely correct or a good idea). But it would be helpful to see how someone who knows what they're doing would organize all this.
Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

爱要勇敢去追 2024-10-23 03:33:15

由于框架的大小是固定的,而框架的数量不是固定的,因此制作一个类Frame似乎是一个不错的首选。每个Frame将包含一个成员grid,它可以是四个字母的四个列表的列表。四个字符串的列表效果不佳,因为字符串是不可变的,尽管将其设置为单个 16 个字符的字符串可能会表现更好。您必须进行配置才能确定。对于这个答案,我假设您要使用字符列表列表。

然后创建一个具有 frames 成员的 Animation 类,它是一个帧列表。然后您将编写如下所示的代码:

myAnimation.frames[10].grid[2][3] = 'f'

如果需要,我可以提供更多详细信息。

示例:(尚未对此进行测试,但应该很接近。文档注释有望与 doctest 配合使用。)

import string

class Frame(object):
    """This is a single frame in an animation."""
    def __init__(self, fill=None, color=None):
        """Initializes the frame.

        >>> f = Frame()
        >>> f.print()
        aaaa
        aaaa
        aaaa
        aaaa
        >>> g = Frame(fill='c', color=(0, 255, 0))
        >>> g.print()
        cccc
        cccc
        cccc
        cccc
        """
        if fill is None:
            fill = 'a' # Or whatever default you want
        self.letterGrid = []
        for row in range(4):
            self.letterGrid.append([fill for col in range(4)])

        if color is None:
            color = (0, 0, 0)
        self.colorGrid = []
        for row in range(4):
            self.letterGrid.append([fill for col in range(4)])

    def set_grid(self, row, col, letter=None, color=None):
        """Sets the letter and/or color at the given grid.

        >>> f.set_grid(1, 1, 'b', (255, 0, 0))
        >>> f.print()
        aaaa
        abaa
        aaaa
        aaaa
        >>> f.set_grid(1, 3, letter='x')
        >>> f.print()
        aaaa
        abax
        aaaa
        aaaa
        >>> f.set_grid(3, 3, color=(255, 0, 0))
        """
        if letter is not None:
            self.letterGrid[row][col] = letter
        if color is not None:
            self.colorGrid[row][col] = color

    def position(row, col):
        return (row * 16, col * 16)

    def print(self):
        """Simple routine to print a frame as text."""
        for row in self.letterGrid:
            print(''.join(row))

class Animation(object):
    def __init__(self, frames=None):
        """Initializes an animation."""
        self.frames = frames or []

希望这可以帮助您入门。

Since the size of a frame is fixed, and the number of frames is not, then making a class Frame seems like a good first choice. Each Frame would contain a member grid which could be a list of four lists of four letters. A list of four strings wouldn't work as well since strings are immutable, though having it be a single 16-character string might perform better. You'd have to profile to be sure. For this answer, I'll assume you're going with a list of lists of characters.

Then make a class Animation that has a frames member, which is a list of frames. Then you'll write code that looks like:

myAnimation.frames[10].grid[2][3] = 'f'

I can provide more detail if desired.

EXAMPLE: (Haven't tested this yet, but it should be close. The doc comments should hopefully work with doctest.)

import string

class Frame(object):
    """This is a single frame in an animation."""
    def __init__(self, fill=None, color=None):
        """Initializes the frame.

        >>> f = Frame()
        >>> f.print()
        aaaa
        aaaa
        aaaa
        aaaa
        >>> g = Frame(fill='c', color=(0, 255, 0))
        >>> g.print()
        cccc
        cccc
        cccc
        cccc
        """
        if fill is None:
            fill = 'a' # Or whatever default you want
        self.letterGrid = []
        for row in range(4):
            self.letterGrid.append([fill for col in range(4)])

        if color is None:
            color = (0, 0, 0)
        self.colorGrid = []
        for row in range(4):
            self.letterGrid.append([fill for col in range(4)])

    def set_grid(self, row, col, letter=None, color=None):
        """Sets the letter and/or color at the given grid.

        >>> f.set_grid(1, 1, 'b', (255, 0, 0))
        >>> f.print()
        aaaa
        abaa
        aaaa
        aaaa
        >>> f.set_grid(1, 3, letter='x')
        >>> f.print()
        aaaa
        abax
        aaaa
        aaaa
        >>> f.set_grid(3, 3, color=(255, 0, 0))
        """
        if letter is not None:
            self.letterGrid[row][col] = letter
        if color is not None:
            self.colorGrid[row][col] = color

    def position(row, col):
        return (row * 16, col * 16)

    def print(self):
        """Simple routine to print a frame as text."""
        for row in self.letterGrid:
            print(''.join(row))

class Animation(object):
    def __init__(self, frames=None):
        """Initializes an animation."""
        self.frames = frames or []

Hope this gets you started.

維他命╮ 2024-10-23 03:33:15

另一种方法是提出一个仅由字典、列表、集合等组成的合适的通用数据结构,然后编写库方法来操作该数据。这听起来不是非常经典的 OOP,事实上也不是,但我发现这种方式更容易处理,也更容易“正确”。您可以清楚地区分一方面构建数据容器和另一方面定义合适的数据操作代码的两个问题。

正如早期海报所建议的,动画可以建模为帧列表;然后,每个帧要么包含 32 个列表,每个列表包含 32 个元素,要么包含 8 个列表,每个列表包含 8 个元素,其中每个元素再次模拟上面所示的 4x4 网格。当然,您是否实际上预先计算(或简单地定义)每个帧,或者是否在动画过程中“实时”操作单帧的数据取决于进一步的考虑。

the alternative approach would be to come up with a suitable generic datastructure solely made up from dictionaries, lists, sets and so on, and then write library methods to manipulate that data. that doesn't sound very classical OOP, and it isn't, but i've found that way easier to handle and easier to 'get right'. you can clearly seperate the two concerns of building data containers on the one hand and defining suitable data manipulation code on the other.

as earlier posters suggested, the animation could be modeled as a list of frames; each frame then either contains 32 lists with 32 elements each, or 8 lists with 8 elements each where each element models again the 4x4 grid shown above. of course, whether you actually precompute (or simply define) each frame beforehand, or whether you manipulate the data of a single frame 'live' during the animation depends on further considerations.

蓝天 2024-10-23 03:33:15

@麦克风
(上面的回复限制在600个字符内,所以我想我会在这里显示我的回复)
这是我迄今为止在 Frame 类中的尝试。我不知道是否应该在另一个类中定义一个类,或者是否或如何将实例列表发送到动画类或其他类。每个方块可以有一个唯一的字母、位置和颜色(位置是因为我打算让列或行位置可移动)。这就是为什么我在那里放置了 3 种类型的网格(不确定这是否是一个好主意,或者单个方块是否也应该有自己的类或其他东西)。

class Frame(object):
    def __init__(self, letterGrid, positionGrid, colorGrid):
        self.letterGrid = letterGrid
        self.positionGrid = positionGrid
        self.colorGrid = colorGrid

class Animation(object):
    def __init__(self, frames):
        self.frames = frames

frames = []
frames.append(Frame( [
                    ['b','b','n','f'],
                    ['b','b','n','n'],
                    ['b','b','n','n'],
                    ['b','b','n','n'] ],

                    [
                    [[0,0],[16,0],[32,0],[48,0]],
                    [[0,16],[16,16],[32,16],[48,16]],
                    [[0,32],[16,32],[32,32],[48,32]],
                    [[0,48],[16,48],[32,48],[48,48]] ],

                    [
                    [[0,0,255],[0,0,0],[0,0,0],[0,0,0]],
                    [[0,0,255],[0,0,0],[0,0,0],[0,0,0]],
                    [[0,0,255],[0,0,0],[0,0,0],[0,0,0]],
                    [[0,0,255],[0,0,0],[0,0,0],[0,0,0]] ]
                    ))

frames.append(Frame( [
                    ['n','n','b','b'],
                    ['n','n','f','b'],
                    ['n','n','b','b'],
                    ['n','n','b','b'] ],

                    [
                    [[0,0],[16,0],[32,0],[48,0]],
                    [[0,16],[16,16],[32,16],[48,16]],
                    [[0,32],[16,32],[32,32],[48,32]],
                    [[0,48],[16,48],[32,48],[48,48]] ],

                    [
                    [[0,0,0],[0,0,255],[0,0,0],[0,0,0]],
                    [[0,0,0],[0,0,255],[0,0,0],[0,0,0]],
                    [[0,0,0],[0,0,255],[0,0,0],[0,0,0]],
                    [[0,0,0],[0,0,255],[0,0,0],[0,0,0]] ]
                    ))

frames.append(Frame( [
                    ['b','b','n','n'],
                    ['b','b','n','n'],
                    ['b','f','n','n'],
                    ['b','b','n','n'] ],

                    [
                    [[0,0],[16,0],[32,0],[48,0]],
                    [[0,16],[16,16],[32,16],[48,16]],
                    [[0,32],[16,32],[32,32],[48,32]],
                    [[0,48],[16,48],[32,48],[48,48]] ],

                    [
                    [[0,0,0],[0,0,0],[0,0,255],[0,0,0]],
                    [[0,0,0],[0,0,0],[0,0,255],[0,0,0]],
                    [[0,0,0],[0,0,0],[0,0,255],[0,0,0]],
                    [[0,0,0],[0,0,0],[0,0,255],[0,0,0]] ]
                    ))

frames.append(Frame( [
                    ['n','n','b','b'],
                    ['n','n','b','b'],
                    ['n','n','b','b'],
                    ['n','n','b','b'] ],

                    [
                    [[0,0],[16,0],[32,0],[48,0]],
                    [[0,16],[16,16],[32,16],[48,16]],
                    [[0,32],[16,32],[32,32],[48,32]],
                    [[0,48],[16,48],[32,48],[48,48]] ],

                    [
                    [[0,0,0],[0,0,0],[0,0,0],[0,0,255]],
                    [[0,0,0],[0,0,0],[0,0,0],[0,0,255]],
                    [[0,0,0],[0,0,0],[0,0,0],[0,0,255]],
                    [[0,0,0],[0,0,0],[0,0,0],[0,0,255]] ]
                    ))

print "3rd frame's colorGrid:\n", frames[2].colorGrid

@Mike
(replying to you above was limited to 600 characters so I guess I'll show my reply here)
This is my attempt at the Frame class so far. I don't know if I should define one class inside another or whether or how to send a list of instances to the Animation class or something. Each square can have a unique letter, position, and color (position because I intend for the columns or rows to be positionally shiftable). So that's why I put 3 types of grids in there (not sure if that's a good idea, or whether an individual square should have its own class too or something).

class Frame(object):
    def __init__(self, letterGrid, positionGrid, colorGrid):
        self.letterGrid = letterGrid
        self.positionGrid = positionGrid
        self.colorGrid = colorGrid

class Animation(object):
    def __init__(self, frames):
        self.frames = frames

frames = []
frames.append(Frame( [
                    ['b','b','n','f'],
                    ['b','b','n','n'],
                    ['b','b','n','n'],
                    ['b','b','n','n'] ],

                    [
                    [[0,0],[16,0],[32,0],[48,0]],
                    [[0,16],[16,16],[32,16],[48,16]],
                    [[0,32],[16,32],[32,32],[48,32]],
                    [[0,48],[16,48],[32,48],[48,48]] ],

                    [
                    [[0,0,255],[0,0,0],[0,0,0],[0,0,0]],
                    [[0,0,255],[0,0,0],[0,0,0],[0,0,0]],
                    [[0,0,255],[0,0,0],[0,0,0],[0,0,0]],
                    [[0,0,255],[0,0,0],[0,0,0],[0,0,0]] ]
                    ))

frames.append(Frame( [
                    ['n','n','b','b'],
                    ['n','n','f','b'],
                    ['n','n','b','b'],
                    ['n','n','b','b'] ],

                    [
                    [[0,0],[16,0],[32,0],[48,0]],
                    [[0,16],[16,16],[32,16],[48,16]],
                    [[0,32],[16,32],[32,32],[48,32]],
                    [[0,48],[16,48],[32,48],[48,48]] ],

                    [
                    [[0,0,0],[0,0,255],[0,0,0],[0,0,0]],
                    [[0,0,0],[0,0,255],[0,0,0],[0,0,0]],
                    [[0,0,0],[0,0,255],[0,0,0],[0,0,0]],
                    [[0,0,0],[0,0,255],[0,0,0],[0,0,0]] ]
                    ))

frames.append(Frame( [
                    ['b','b','n','n'],
                    ['b','b','n','n'],
                    ['b','f','n','n'],
                    ['b','b','n','n'] ],

                    [
                    [[0,0],[16,0],[32,0],[48,0]],
                    [[0,16],[16,16],[32,16],[48,16]],
                    [[0,32],[16,32],[32,32],[48,32]],
                    [[0,48],[16,48],[32,48],[48,48]] ],

                    [
                    [[0,0,0],[0,0,0],[0,0,255],[0,0,0]],
                    [[0,0,0],[0,0,0],[0,0,255],[0,0,0]],
                    [[0,0,0],[0,0,0],[0,0,255],[0,0,0]],
                    [[0,0,0],[0,0,0],[0,0,255],[0,0,0]] ]
                    ))

frames.append(Frame( [
                    ['n','n','b','b'],
                    ['n','n','b','b'],
                    ['n','n','b','b'],
                    ['n','n','b','b'] ],

                    [
                    [[0,0],[16,0],[32,0],[48,0]],
                    [[0,16],[16,16],[32,16],[48,16]],
                    [[0,32],[16,32],[32,32],[48,32]],
                    [[0,48],[16,48],[32,48],[48,48]] ],

                    [
                    [[0,0,0],[0,0,0],[0,0,0],[0,0,255]],
                    [[0,0,0],[0,0,0],[0,0,0],[0,0,255]],
                    [[0,0,0],[0,0,0],[0,0,0],[0,0,255]],
                    [[0,0,0],[0,0,0],[0,0,0],[0,0,255]] ]
                    ))

print "3rd frame's colorGrid:\n", frames[2].colorGrid
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文