Python 如何扭曲图像

Python 如何扭曲图像,python,python-3.x,pygame,pygame-surface,Python,Python 3.x,Pygame,Pygame Surface,我开始用python开发自己版本的超级马里奥卡丁车,这只是我自己的一个小项目。到目前为止,我已经成功地将一个图像转换成玩家在伪3D轨迹上移动的样子。然而,根本没有透视图,这在某种程度上破坏了3D的幻觉。我知道,如果我有一种方法使图像倾斜,使表面底部比顶部宽,我几乎可以解决这个问题,因为这将有助于模拟透视 我已经在网上找了很长一段时间,想看看是否有办法做到这一点,因为我真的不知道从哪里开始。尽管我的搜索没有结果,我也没有发现任何有用的东西 那么,我该如何做才能扭曲轨迹的图像呢 以下是我目前的代码:

我开始用python开发自己版本的超级马里奥卡丁车,这只是我自己的一个小项目。到目前为止,我已经成功地将一个图像转换成玩家在伪3D轨迹上移动的样子。然而,根本没有透视图,这在某种程度上破坏了3D的幻觉。我知道,如果我有一种方法使图像倾斜,使表面底部比顶部宽,我几乎可以解决这个问题,因为这将有助于模拟透视

我已经在网上找了很长一段时间,想看看是否有办法做到这一点,因为我真的不知道从哪里开始。尽管我的搜索没有结果,我也没有发现任何有用的东西

那么,我该如何做才能扭曲轨迹的图像呢

以下是我目前的代码:

import os, sys, pygame
from pygame.locals import *
from math import *

pygame.init()

path, file_name = os.path.split(__file__)
path            = os.path.join(path, 'data')

WIDTH  = 800
HEIGHT = 600
SCREEN = pygame.display.set_mode((WIDTH,HEIGHT))
CLOCK  = pygame.time.Clock()
FPS    = 30

pygame.mouse.set_visible(False)
pygame.display.set_caption('Mario Kart')

class Driver(object):
    def __init__(self, image, start_pos):
        self.surface = pygame.image.load(os.path.join(path, image)).convert()
        self.surface.set_colorkey(MAGENTA)
        self.surface = pygame.transform.scale(self.surface, (64, 64))

        self.pos = list(start_pos)
        self.angle = 0
        self.velocity = 0

    def move(self):
        keys = pygame.key.get_pressed()

        if keys[K_a] or keys[K_LEFT]:
            self.angle -= 14 / (1 + e ** (-0.3 * self.velocity)) - 7
            #Sigmoid function to contain the angular velocity between 7 and -7

        if keys[K_d] or keys[K_RIGHT]:
            self.angle += 14 / (1 + e ** (-0.3 * self.velocity)) - 7

        if keys[K_w] or keys[K_UP]:
            self.velocity += 3

        elif keys[K_s] or keys[K_DOWN]:
            self.velocity -= 1

        self.velocity *= 0.85

        self.pos[0] += self.velocity * sin(radians(self.angle))
        self.pos[1] -= self.velocity * cos(radians(self.angle))

    def render(self):
        SCREEN.blit(self.surface, (WIDTH / 2 - 32, HEIGHT / 2 - 32))

class Track(object):
    def __init__(self, image, tilt = 1, zoom = 1):
        self.surface = pygame.image.load(os.path.join(path, image)).convert_alpha()
        self.angle = 0
        self.tilt = tilt
        self.zoom = zoom
        self.rect = self.surface.get_rect()
        self.rect.center = (WIDTH / 2, HEIGHT / 2)

        self.image = self.surface
        self.image_rect = self.image.get_rect()

    def render(self, angle, center = (0, 0)):
        self.angle = angle

        self.image = self.surface 
        self.image = pygame.transform.rotate(self.image, self.angle)
        self.image_rect = self.image.get_rect()

        self.image = pygame.transform.scale(self.image, (int(self.image_rect.width * self.zoom), int((self.image_rect.height * self.zoom) / self.tilt)))

        self.image_rect = self.image.get_rect(center = (self.rect.centerx - ((center[0] * self.zoom) * cos(radians(-self.angle)) - (center[1] * self.zoom) * sin(radians(-self.angle))),
                                                        self.rect.centery - ((center[0] * self.zoom) * sin(radians(-self.angle)) + (center[1] * self.zoom) * cos(radians(-self.angle))) / self.tilt))

        SCREEN.blit(self.image, self.image_rect)


def main():
    track = Track('MushroomCup1.png', tilt = 4, zoom = 7)
    toad = Driver('Toad Sprite.png', (408, 90))

    while True:
        SCREEN.fill((255, 255, 255))

        toad.move() 

        track.render(toad.angle, toad.pos)
        toad.render()

        events = pygame.event.get()
        for event in events:
            if event.type == QUIT or event.type == KEYDOWN and event.key == K_ESCAPE:
                pygame.quit()
                sys.exit()

        pygame.display.update()
        CLOCK.tick(FPS)

if __name__ == '__main__':
    main()
  • MushroomCup1.png

  • 蟾蜍雪碧.png

如果你想获得真正的3D效果,你必须尝试类似于PyOpenGL或Pyglet的东西。PyGame实际上只用于在传统的2D表面/透视图上进行操作

也就是说,我确实在纯PyGame()上编写了一款马里奥卡丁车风格的3D驾驶游戏。我设置了道路的坐标,将道路分解成单独的三角形,并进行了大量的矩阵运算。这主要是一个幽默的练习,看看我是否可以,而不是我应该做的事情。这只是几何原语。对于图像来说,它变得更加复杂

如果你真的想,你可以做一些像预处理图像资源这样的事情来简化它并将其分解成一堆大的正方形块,然后用类似的方法用大量的矩阵数学将它们分解成三角形。它不会很快,但从技术上讲它可以工作,并且只需要PyGame


基本上,我想说的是,在spirit中没有Pygame解决方案,如果你想要3D,你必须转移到一个支持它的框架(比如Pyglet或PyOpenGL)

如果你想获得真正的3D效果,你必须尝试类似于PyOpenGL或Pyglet的东西。PyGame实际上只用于在传统的2D表面/透视图上进行操作

也就是说,我确实在纯PyGame()上编写了一款马里奥卡丁车风格的3D驾驶游戏。我设置了道路的坐标,将道路分解成单独的三角形,并进行了大量的矩阵运算。这主要是一个幽默的练习,看看我是否可以,而不是我应该做的事情。这只是几何原语。对于图像来说,它变得更加复杂

如果你真的想,你可以做一些像预处理图像资源这样的事情来简化它并将其分解成一堆大的正方形块,然后用类似的方法用大量的矩阵数学将它们分解成三角形。它不会很快,但从技术上讲它可以工作,并且只需要PyGame


基本上,我想说的是,在spirit中没有Pygame解决方案,如果你想要3D,你必须转移到一个支持它的框架(比如Pyglet或PyOpenGL)

据我所知,pygame中没有允许你扭曲图像的功能。您可以使用另一个库(如pillow)来扭曲图像,然后使用
image.tobytes
和将其转换为pygame曲面。我不知道这对一场比赛来说是否足够有效。据我所知,pygame中没有允许你扭曲图像的功能。您可以使用另一个库(如pillow)来扭曲图像,然后使用
image.tobytes
和将其转换为pygame曲面。我不知道这对一场比赛来说是否足够有效。