import
pygame
from
pygame.locals
import
*
from
gameobjects.vector3
import
Vector3
from
math
import
*
from
random
import
randint
SCREEN_SIZE
= (640,
480)
CUBE_SIZE
=
300
def
calculate_viewing_distance(fov,
screen_width):
d
=
(screen_width/2.0)
/
tan(fov/2.0)
return
d
def
run():
pygame.init()
screen
=
pygame.display.set_mode(SCREEN_SIZE,
0)
default_font
=
pygame.font.get_default_font()
font
=
pygame.font.SysFont(default_font,
24)
ball
=
pygame.image.load("ball.png").convert_alpha()
#
3D points
points
=
[]
fov
=
90.
#
Field of view
viewing_distance
=
calculate_viewing_distance(radians(fov),
SCREEN_SIZE[0])
#
邊沿的一系列點
for
x
in
xrange(0,
CUBE_SIZE+1,
20):
edge_x
=
x
==
0
or
x
==
CUBE_SIZE
for
y
in
xrange(0,
CUBE_SIZE+1,
20):
edge_y
=
y
==
0
or
y
==
CUBE_SIZE
for
z
in
xrange(0,
CUBE_SIZE+1,
20):
edge_z
=
z
==
0
or
z
==
CUBE_SIZE
if
sum((edge_x,
edge_y,
edge_z))
>=
2:
point_x
=
float(x)
-
CUBE_SIZE/2
point_y
=
float(y)
-
CUBE_SIZE/2
point_z
=
float(z)
-
CUBE_SIZE/2
points.append(Vector3(point_x,
point_y,
point_z))
#
以z序存儲,類似於css中的z-index
def
point_z(point):
return
point.z
points.sort(key=point_z,
reverse=True)
center_x,
center_y
=
SCREEN_SIZE
center_x
/=
2
center_y
/=
2
ball_w,
ball_h
=
ball.get_size()
ball_center_x
=
ball_w
/
2
ball_center_y
=
ball_h
/
2
camera_position
=
Vector3(0.0,
0.0,
-700.)
camera_speed
=
Vector3(300.0,
300.0,
300.0)
clock
=
pygame.time.Clock()
while
True:
for
event
in
pygame.event.get():
if
event.type
==
QUIT:
return
screen.fill((0,
0,
0))
pressed_keys
=
pygame.key.get_pressed()
time_passed
=
clock.tick()
time_passed_seconds
=
time_passed
/
1000.
direction
=
Vector3()
if
pressed_keys[K_LEFT]:
direction.x
=
-1.0
elif
pressed_keys[K_RIGHT]:
direction.x
=
+1.0
if
pressed_keys[K_UP]:
direction.y
=
+1.0
elif
pressed_keys[K_DOWN]:
direction.y
=
-1.0
if
pressed_keys[K_q]:
direction.z
=
+1.0
elif
pressed_keys[K_a]:
direction.z
=
-1.0
if
pressed_keys[K_w]:
fov
=
min(179.,
fov+1.)
w
=
SCREEN_SIZE[0]
viewing_distance
=
calculate_viewing_distance(radians(fov),
w)
elif
pressed_keys[K_s]:
fov
=
max(1.,
fov-1.)
w
=
SCREEN_SIZE[0]
viewing_distance
=
calculate_viewing_distance(radians(fov),
w)
camera_position
+=
direction
*
camera_speed
*
time_passed_seconds
#
繪製點
for
point
in
points:
x,
y,
z
=
point
-
camera_position
if
z
>
0:
x
= x
*
viewing_distance
/
z
y
=
-y
*
viewing_distance
/
z
x
+=
center_x
y
+=
center_y
screen.blit(ball,
(x-ball_center_x,
y-ball_center_y))
#
繪製表
diagram_width
=
SCREEN_SIZE[0]
/
4
col
=
(50,
255,
50)
diagram_points
=
[]
diagram_points.append(
(diagram_width/2,
100+viewing_distance/4)
)
diagram_points.append(
(0,
100)
)
diagram_points.append(
(diagram_width,
100)
)
diagram_points.append(
(diagram_width/2,
100+viewing_distance/4)
)
diagram_points.append(
(diagram_width/2,
100)
)
pygame.draw.lines(screen,
col,
False,
diagram_points,
2)
#
繪製文字
white
=
(255,
255,
255)
cam_text
=
font.render("camera
= "+str(camera_position),
True,
white)
screen.blit(cam_text,
(5,
5))
fov_text
=
font.render("field
of view = %i"%int(fov),
True,
white)
screen.blit(fov_text,
(5,
35))
txt
=
"viewing
distance = %.3f"%viewing_distance
d_text
=
font.render(txt,
True,
white)
screen.blit(d_text,
(5,
65))
pygame.display.update()
if
__name__
==
"__main__":
run()