成为一个等轴测瓷砖的纹理

成为一个等轴测瓷砖的纹理

本文介绍了Python,Pygame,图像处理:Restretch一个加载的PNG,成为一个等轴测瓷砖的纹理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是一名17岁的程序员,试图用pygame编写python中的等距游戏。在完成一个平铺引擎后,使用不好看的gimp-drawn PNG工作,我想知道,是否可以通过纹理渲染一些Tiles。我希望我提供了所有需要了解的信息,我的问题是什么,请原谅我的不完美的英语。



简单地说,我想要做的就是生成128个128像素宽度等轴测图的图像,使用以下图片作为块的所有三面的纹理:



(链接在这里,因为我因为这是我的第一篇文章,所以还没有被允许放入图片)

为了更好地解释,我正在尝试做的事情,我画了这张小图片:



我已经搜索过互联网约2小时,并没有得到解决方案,除了瓷砖的顶部,这里是我已经在代码中:

这是图像操作模块,transformToRightPart()是我需要帮助的方法:

pre $ import $ py $
$ b $ class Image(object):
'''
使用此模块按纹理创建Tiles,稍后在Tileengine中使用它们。
在创建这个类的对象之前运行pygame.init()是非常重要的!
包含未完成的元素!
'''
def __init __(self,path):
self.loadFromPath(path)
$ b $ get getIMG(self):
assert self。 originalIMG不是无,没有图片要返回
如果不是self.IMG ==无:
返回self.IMG
其他:
返回self.originalIMG

def loadFromPath(self,path):
'''
这里不要做convert()或convert_alpha(),因为这个类的对象是在加载过程中创建的过程中,
没有创建pygame.display()。
'''
self.originalIMG = pygame.image.load(路径)
self.IMG =无

def transformToTopPart(self):
'''
将加载的图像转换为等轴测图的顶部,尺寸为2:1,
用像素表示:128像素宽度乘以64像素高度。
'''
self.IMG = pygame.transform.rotate(self.originalIMG,45)
self.IMG = pygame.transform.scale(self.IMG,(128,64) )

def transformToRightPart(self):
'''
TODO !!不要问(X.X)
如何将加载的图像转换为等轴测图块的右侧部分。
'''
assert False,这个方法没有完成,尝试不同的东西;)

def transformToLeftPart(self):
'''
将加载的图像转换为等轴测图块的左侧部分。
由于好的几何事实,左边部分的形状
只是右边部分的翻转形状,我们不会因为翻转而损失质量,
我们做这个小动作,来代码。
'''
self.originalIMG = pygame.transform.flip(self.originalIMG,True,False)
self.transformToRightPart()
self.IMG = pygame.transform。 flip(self.IMG,True,False)
self.originalIMG = pygame.transform.flip(self.originalIMG,True,False)

这是模块,它创建一个窗口并显示tile:

 从ImageManipulation导入pygame,sys 

从pygame.locals导入图像
import *
$ b $如果__name__ =='__main__':
pygame.init ()
FPS = 20
fpsClock = pygame.time.Clock()
picture = Image(Stone_Floor_texture.png)
picture.transformToTopPart()
DISPLAY = pygame.display.set_mode((400,400),0,32)
,而True:
用于pygame.event.get()中的事件:
if event.type == QUIT:
pygame.quit()
sys.exit()
DISPLAY。 blit(picture.getIMG(),(0,0))
pygame.display.update()
fpsClock.tick(FPS)

代码的输出如下所示:



我试图实现的是,看起来像这样:





我做了什么? - 我写了两个函数,第一个函数获取一个只包含另一个曲面的单个列的曲面,并带有一个索引,指向列的x位置。
其次,计算一个系数,每行应移动多少,如果最后一行应该向下移动一定数量的像素,然后返回带有移动图片的曲面。



这是魔法代码:

  import pygame 

from pygame.locals import pygame import *
Surface
$ b def getColumn(surface,index):
断言索引< = surface.get_width(),index不能是比表面宽度更大
height = surface.get_height()
subsurf = Surface((1,height))#通过图片高度高创建Surface 1 px,以将输出存储在$ b $中b subsurf.blit(surface.subsurface(pygame.Rect((index,0),(1,height))),(0,0))#将位于图像索引处的x位置的一个像素宽度子表面划分为subsurf
return subsurf
$ b $ def shiftRightDown(surface,pixels):
size = surface.get_size()
newSize =(size [0],size [1] +像素)
coeff =像素/大小[0]
returnSurface = Surface(newSize)
在范围内(size [1]):#这里发生了神奇的
returnSurface.blit(getColumn(surface,i),(i ,0 + int(i * coeff)))
return returnSurface

毕竟,尊重Spektres编码技巧,尽管我很笨,无法理解c plus plus示例中的任何内容,因为我是一名初学者。


I'm a 17 year old programmer, trying to program an isometric game in python, with pygame. After finishing a tile engine, working with not good looking, gimp-drawn PNG's, I wondered, if it would be possible to render some Tiles by texture. I hope I provided all what's needed to understand, what's my issue and please excuse my not perfect English.

Simply what I want to do, is to generate a 128 by 128 Pixel width Image of an Isometric Tile, using the following picture as texture for all three sides of the Block:

(Links here because I'm not yet allowed to put pictures in, due to it's my first post)

To explain better, what I'm trying to do, I have drawn this little picture:

I have already searched the Internet for about 2 hours and didn't come to a solution, except for the top part of the Tile, here is what I already got in Code:

This is the Image Manipulation Module, the transformToRightPart() is the method where I need help:

import pygame

class Image(object):
    '''
    Use this Module to create Tiles by Texture to use them later in the Tileengine.
    It is important to run pygame.init() before creating objects of this class!
    Contains unfinished Elements!
    '''
    def __init__(self, path):
        self.loadFromPath(path)

    def getIMG(self):
        assert self.originalIMG is not None, "No picture to return"
        if not self.IMG == None:
            return self.IMG
        else:
            return self.originalIMG

    def loadFromPath(self, path):
        '''
        Don't do convert() or convert_alpha() here,
        as Objects of this class are created during the loading process,
        with no pygame.display() created.
        '''
        self.originalIMG = pygame.image.load(path)
        self.IMG = None

    def transformToTopPart(self):
        '''
        Transforms the loaded Image to the Top Part of an Isometric Tile, with the Dimensions 2:1,
        said in Pixels: 128 px Width by 64 px Height.
        '''
        self.IMG = pygame.transform.rotate(self.originalIMG, 45)
        self.IMG = pygame.transform.scale(self.IMG, (128, 64))

    def transformToRightPart(self):
        '''
        TODO!! Don't ask how (X.X)
        Transforms the loaded Image to the right Part of an Isometric Tile.
        '''
        assert False, "This method isn't finished, try something different ;)"

    def transformToLeftPart(self):
        '''
        Transforms the loaded Image to the left Part of an Isometric Tile.
        Due to the nice geometric fact, that the shape of the left part,
        is just the flipped right part shape and we don't lose quality by flipping,
        we do this little trick, to enshorten the code.
        '''
        self.originalIMG = pygame.transform.flip(self.originalIMG, True, False)
        self.transformToRightPart()
        self.IMG = pygame.transform.flip(self.IMG, True, False)
        self.originalIMG = pygame.transform.flip(self.originalIMG, True, False)

And this is the Module, which creates a window with the tile to render:

import pygame, sys

from ImageManipulation import Image
from pygame.locals import *

if __name__ == '__main__':
    pygame.init()
    FPS=20
    fpsClock = pygame.time.Clock()
    picture = Image("Stone_Floor_texture.png")
    picture.transformToTopPart()
    DISPLAY = pygame.display.set_mode((400,400),0,32)
    while True:
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
        DISPLAY.blit(picture.getIMG(),(0,0))
        pygame.display.update()
        fpsClock.tick(FPS)

The output of the code looks like this:

What I'm trying to achieve is, that it looks, something like this:

解决方案

Big thanks to Spektre for all the effort he made, trying to help me, but all in all, after two days of over-thinking the problem and bug-fixing, I came up with a solution myself. It might not be as fast or efficient as targeting the pixels directly in an array, like Spektre did in his c++ example, but it is a way, you're only dependencies are pygame, and it is easy to understand.

What did I do? - I wrote two functions, the first getting a surface containing only a single column of another surface, with an index, referring to the x position of the column.And the second, calculating a coefficient, how far down each row should get moved, if the last row should get shifted down a certain amount of pixels and then returning a surface with the shifted picture.

Here is the magic Code:

import pygame

from pygame.locals import *
from pygame import Surface

def getColumn(surface, index):
    assert index <= surface.get_width(), "index can't be bigger, than surface width"
    height = surface.get_height()
    subsurf = Surface((1,height)) # Create Surface 1 px by picture-height high, to store the output in
    subsurf.blit(surface.subsurface(pygame.Rect( (index,0),(1,height) )),(0,0)) # Blit a one pixel width subsurface with x Position at index of the image to subsurf
    return subsurf

def shiftRightDown(surface, pixels):
    size = surface.get_size()
    newSize = (size[0], size[1]+pixels)
    coeff = pixels / size[0]
    returnSurface = Surface(newSize)
    for i in range(size[1]): # here happens the magic
        returnSurface.blit(getColumn(surface, i), (i,0+int(i*coeff)))
    return returnSurface

After all, big respect to Spektres coding skills, even though I'm to dumb to understand anything from the c plus plus example, as I'm a total beginner.

这篇关于Python,Pygame,图像处理:Restretch一个加载的PNG,成为一个等轴测瓷砖的纹理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-31 09:48