用python写游戏 - 从入门到精通16

kkkkk 2018年12月17日 23:09 PythonGUI

所谓3D,说到底就是利用透视原理,在2D的画面上创造出有纵深错觉(说白了也就是近大远小)的画面而已,毕竟,屏幕是平的,怎么可能真的画出距离呢?换句话说,计算机3D的本质还是2D,只不过额外多了很多东西。


在纯pygame中,我们画3D画面就是通过计算在2D图像上画一些大小不一的东西:)

距离的魔法

我们看现实中的东西,和我们看画面上的东西,最大差别在于能感受现实物体的距离。而距离的产生,则是因为我们双眼看到的东西是不同的,两眼交替闭合,你会发现眼前的东西左右移动。一只眼睛则很难正确的判断距离,虽然比上眼睛还是能感觉到远近,但更精细一点,比如很难把线穿过针眼。


我们在3D画面上绘图的时候,就要遵循这个规律,看看下面的代码。

import pygame
from pygame.locals import *
from random import randint
   
class Star(object):
   
    def __init__(self, x, y, speed):
   
        self.x = x
        self.y = y
        self.speed = speed
   
def run():
   
    pygame.init()
    screen = pygame.display.set_mode((640, 480)) #, FULLSCREEN)
   
    stars = []
   
    # 在第一帧,画上一些星星
    for n in xrange(200):
   
        x = float(randint(0, 639))
        y = float(randint(0, 479))
        speed = float(randint(10, 300))
        stars.append( Star(x, y, speed) )
   
    clock = pygame.time.Clock()
   
    white = (255, 255, 255)
   
    while True:
   
        for event in pygame.event.get():
            if event.type == QUIT:
                return
            if event.type == KEYDOWN:
                return
   
        # 增加一颗新的星星
        y = float(randint(0, 479))
        speed = float(randint(10, 300))
        star = Star(640., y, speed)
        stars.append(star)
   
        time_passed = clock.tick()
        time_passed_seconds = time_passed / 1000.
   
        screen.fill((0, 0, 0))
   
        # 绘制所有的星
        for star in stars:
   
            new_x = star.x - time_passed_seconds * star.speed
            pygame.draw.aaline(screen, white, (new_x, star.y), (star.x+1., star.y))
            star.x = new_x
   
        def on_screen(star):
            return star.x > 0
   
        # 星星跑出了画面,就删了它
        stars = filter(on_screen, stars)
   
        pygame.display.update()
   
if __name__ == "__main__":
    run()


这里你还可以把FULLSCREEN加上,更有感觉。

这个程序给我的画面,发挥一下你的想象,不是一片宇宙么,无数的星云穿梭,近的速度更快,远的则很慢。而实际上看代码,我们只是画了一些长短不同的线而已!虽然很简单,还是用了不少不少python的技术,特别是函数式编程的(小)技巧。不过强大的你一定没问题:)但是pygame的代码,没有任何没讲过的,为什么这样就能有3D的效果了?感谢你的大脑,因为它知道远的看起来更慢,所以这样的错觉就产生了。

理解3D空间

3D空间的事情,基本就是立体几何的问题,高中学一半应该就差不多理解了,这里不多讲了。你能明白下图的小球在(7, 5, 10)的位置,换句话说,如果你站在原点,面朝Z轴方向。那么小球就在你左边7,上面5,前面10的位置。这就够了~


使用3D向量

我们已经学习了二维向量来表达运动,在三维空间内,当然要使用三维的向量。其实和二维的概念都一样,加减缩放啥的,这里就不用三个元素的元组列表先演练一番了,直接祭出我们的gameobjects神器吧!

from gameobjects.vector3 import *
A = Vector3(6, 8, 12)
B = Vector3(10, 16, 12)
print "A is", A
print "B is", B
print "Magnitude of A is", A.get_magnitude()
print "A+B is", A+B
print "A-B is", A–B
print "A normalized is", A.get_normalized()
print "A*2 is", A * 2


运行一下看看结果吧,有些无趣?确实,光数字没法展现3D的美啊,下一次,让我们把物体在立体空间内运动起来。


文章评论(0)
  • avatar kkkkkk 2018年12月21日 11:31
    差劲
    kkkkk
    2018年12月21日 11:16
    立意较高,内蕴丰富,文风帅气。
    回复
  • avatar kkkkkk 2018年12月21日 11:31
    Youkou老师真帅
    kkkkklxinde
    2018年12月21日 11:17
    本文提出中心,论述过程紧紧围绕中心论题,摆事实讲道理,批驳辛辣,论述颇显力道。文章立意高蹈,剖析深刻,较好地体现了辩证思维,材料丰富。
    回复
  • avatar kkkkklxinde 2018年12月21日 11:17
    本文提出中心,论述过程紧紧围绕中心论题,摆事实讲道理,批驳辛辣,论述颇显力道。文章立意高蹈,剖析深刻,较好地体现了辩证思维,材料丰富。
    回复
  • avatar kkkkk 2018年12月21日 11:16
    立意较高,内蕴丰富,文风帅气。
    回复