我开始在python中使用我自己的Super Mario Kart版本,就像我自己的一个小项目一样。到目前为止,我已经设法将图像转换为看起来像玩家正在伪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()
答案 0 :(得分:1)
如果你想获得真正的3D,你将不得不尝试像PyOpenGL或Pyglet这样的东西。 PyGame实际上只适用于传统的2D表面/透视。
那就是说,我确实写了一个运行在纯PyGame(here's a JS port)上的Mario Kart风格的3D驾驶游戏。我为道路设置坐标,将道路分解为单个三角形,并进行了大量的矩阵数学运算。这主要是一个幽默的练习,看看我能,而不是我应该做的事情。这只是几何原语。对于图像来说,它变得更加复杂。
如果你真的想要,你可能会做一些事情,比如预处理图像资源,以简化并将其分解为一堆大型方块,并采用类似的方法将这些分解成具有大量矩阵数学的三角形。它不会很快,但它在技术上可行并且只需要PyGame。
基本上我所说的是,精神上没有Pygame解决方案,如果你想要3D,你将不得不转移到支持它的框架(如Pyglet或PyOpenGL)。