Skip to content

Commit 8a6b471

Browse files
committed
init commit
1 parent ef3d378 commit 8a6b471

File tree

18 files changed

+2130
-2
lines changed

18 files changed

+2130
-2
lines changed
-1.96 KB
Binary file not shown.

Chapter 8/8-1.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import pygame
2+
from pygame.locals import *
3+
from random import randint
4+
5+
class Star(object):
6+
7+
def __init__(self, x, y, speed):
8+
9+
self.x = x
10+
self.y = y
11+
self.speed = speed
12+
13+
def run():
14+
15+
pygame.init()
16+
screen = pygame.display.set_mode((640, 480), FULLSCREEN)
17+
18+
stars = []
19+
20+
# Add a few stars for the first frame
21+
for n in range(200):
22+
23+
x = float(randint(0, 639))
24+
y = float(randint(0, 479))
25+
speed = float(randint(10, 300))
26+
stars.append( Star(x, y, speed) )
27+
28+
clock = pygame.time.Clock()
29+
30+
white = (255, 255, 255)
31+
32+
while True:
33+
34+
for event in pygame.event.get():
35+
if event.type == QUIT:
36+
pygame.quit()
37+
quit()
38+
if event.type == KEYDOWN:
39+
pygame.quit()
40+
quit()
41+
42+
# Add a new star
43+
y = float(randint(0, 479))
44+
speed = float(randint(10, 300))
45+
star = Star(640, y, speed)
46+
47+
stars.append(star)
48+
time_passed = clock.tick()
49+
time_passed_seconds = time_passed / 1000.
50+
51+
screen.fill((0, 0, 0))
52+
53+
# Draw the stars
54+
for star in stars:
55+
56+
new_x = star.x - time_passed_seconds * star.speed
57+
pygame.draw.aaline(screen, white, (new_x, star.y), (star.x+1., star.y))
58+
star.x = new_x
59+
60+
def on_screen(star):
61+
return star.x > 0
62+
63+
# Remove stars that are no longer visible
64+
stars = list(filter(on_screen, stars))
65+
66+
pygame.display.update()
67+
68+
69+
if __name__ == "__main__":
70+
run()

Chapter 8/8-2.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
from math import sqrt
2+
3+
class Vector3(object):
4+
5+
def init (self, x, y, z):
6+
7+
self.x = x
8+
self.y = y
9+
self.z = z
10+
11+
def add (self, x, y, z):
12+
13+
return Vector3(self.x + x, self.y + y, self.z + z)
14+
15+
def get_magnitude(self):
16+
17+
return sqrt(self.x ** 2 + self.y ** 2 + self.z ** 2)

Chapter 8/8-3.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from gameobjects.vector3 import *
2+
3+
A = Vector3(6, 8, 12)
4+
B = Vector3(10, 16, 12)
5+
6+
print("A is", A)
7+
print("B is", B)
8+
print("Magnitude of A is", A.get_magnitude())
9+
print("A+B is", A+B)
10+
print("A-B is", A-B)
11+
12+
13+
print("A normalized is", A.get_normalized())
14+
print("A*2 is", A * 2)

Chapter 8/8-4.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from gameobjects.vector3 import *
2+
3+
A = (-6, 2, 2)
4+
B = (7, 5, 10)
5+
plasma_speed = 100 # meters per second
6+
7+
AB = Vector3.from_points(A, B)
8+
print("Vector to droid is", AB)
9+
10+
distance_to_target = AB.get_magnitude()
11+
print("Distance to droid is", distance_to_target, "meters")
12+
13+
plasma_heading = AB.get_normalized()
14+
print("Heading is", plasma_heading)

Chapter 8/8-5.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
def parallel_project(vector3):
2+
return (vector3.x, vector3.y)

Chapter 8/8-6.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
def perspective_project(vector3, d):
2+
x, y, z = vector3
3+
return (x * d/z, -y * d/z)

Chapter 8/8-7.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from math import tan
2+
3+
def calculate_viewing_distance(fov, screen_width):
4+
5+
d = (screen_width/2.0) / tan(fov/2.0)
6+
return d

Chapter 8/8-8.py

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
import pygame
2+
from pygame.locals import *
3+
from gameobjects.vector3 import Vector3
4+
from math import *
5+
from random import randint
6+
7+
SCREEN_SIZE = (640, 480)
8+
CUBE_SIZE = 300
9+
10+
def calculate_viewing_distance(fov, screen_width):
11+
12+
d = (screen_width/2.0) / tan(fov/2.0)
13+
return d
14+
15+
16+
def run():
17+
18+
pygame.init()
19+
screen = pygame.display.set_mode(SCREEN_SIZE, 0)
20+
21+
default_font = pygame.font.get_default_font()
22+
font = pygame.font.SysFont(default_font, 24)
23+
24+
ball = pygame.image.load("ball.png").convert_alpha()
25+
26+
# The 3D points
27+
points = []
28+
29+
fov = 90. # Field of view
30+
viewing_distance = calculate_viewing_distance(radians(fov), SCREEN_SIZE[0])
31+
32+
# Create a list of points along the edge of a cube
33+
for x in range(0, CUBE_SIZE+1, 20):
34+
edge_x = x == 0 or x == CUBE_SIZE
35+
36+
for y in range(0, CUBE_SIZE+1, 20):
37+
edge_y = y == 0 or y == CUBE_SIZE
38+
39+
for z in range(0, CUBE_SIZE+1, 20):
40+
edge_z = z == 0 or z == CUBE_SIZE
41+
42+
if sum((edge_x, edge_y, edge_z)) >= 2:
43+
44+
point_x = float(x) - CUBE_SIZE/2
45+
point_y = float(y) - CUBE_SIZE/2
46+
point_z = float(z) - CUBE_SIZE/2
47+
48+
points.append(Vector3(point_x, point_y, point_z))
49+
50+
# Sort points in z order
51+
def point_z(point):
52+
return point.z
53+
points.sort(key=point_z, reverse=True)
54+
55+
center_x, center_y = SCREEN_SIZE
56+
center_x /= 2
57+
center_y /= 2
58+
59+
ball_w, ball_h = ball.get_size()
60+
ball_center_x = ball_w / 2
61+
ball_center_y = ball_h / 2
62+
63+
camera_position = Vector3(0.0, 0.0, -700.)
64+
camera_speed = Vector3(300.0, 300.0, 300.0)
65+
66+
clock = pygame.time.Clock()
67+
68+
while True:
69+
70+
for event in pygame.event.get():
71+
if event.type == QUIT:
72+
pygame.quit()
73+
quit()
74+
75+
screen.fill((0, 0, 0))
76+
77+
pressed_keys = pygame.key.get_pressed()
78+
79+
time_passed = clock.tick()
80+
time_passed_seconds = time_passed / 1000.
81+
82+
direction = Vector3()
83+
if pressed_keys[K_LEFT]:
84+
direction.x = -1.0
85+
elif pressed_keys[K_RIGHT]:
86+
direction.x = +1.0
87+
88+
if pressed_keys[K_UP]:
89+
direction.y = +1.0
90+
elif pressed_keys[K_DOWN]:
91+
direction.y = -1.0
92+
93+
if pressed_keys[K_q]:
94+
direction.z = +1.0
95+
elif pressed_keys[K_a]:
96+
direction.z = -1.0
97+
98+
if pressed_keys[K_w]:
99+
fov = min(179., fov+1.)
100+
w = SCREEN_SIZE[0]
101+
viewing_distance = calculate_viewing_distance(radians(fov), w)
102+
elif pressed_keys[K_s]:
103+
fov = max(1., fov-1.)
104+
w = SCREEN_SIZE[0]
105+
viewing_distance = calculate_viewing_distance(radians(fov), w)
106+
107+
camera_position += direction * camera_speed * time_passed_seconds
108+
109+
# Draw the 3D points
110+
for point in points:
111+
112+
x, y, z = point - camera_position
113+
114+
if z > 0:
115+
x = x * viewing_distance / z
116+
y = -y * viewing_distance / z
117+
x += center_x
118+
y += center_y
119+
screen.blit(ball, (x-ball_center_x, y-ball_center_y))
120+
121+
# Draw the field of view diagram
122+
diagram_width = SCREEN_SIZE[0] / 4
123+
col = (50, 255, 50)
124+
diagram_points = []
125+
diagram_points.append( (diagram_width/2, 100+viewing_distance/4) )
126+
diagram_points.append( (0, 100) )
127+
diagram_points.append( (diagram_width, 100) )
128+
diagram_points.append( (diagram_width/2, 100+viewing_distance/4) )
129+
diagram_points.append( (diagram_width/2, 100) )
130+
pygame.draw.lines(screen, col, False, diagram_points, 2)
131+
132+
# Draw the text
133+
white = (255, 255, 255)
134+
cam_text = font.render("camera = "+str(camera_position), True, white)
135+
screen.blit(cam_text, (5, 5))
136+
fov_text = font.render("field of view = %i"%int(fov), True, white)
137+
screen.blit(fov_text, (5, 35))
138+
txt = "viewing distance = %.3f"%viewing_distance
139+
d_text = font.render(txt, True, white)
140+
screen.blit(d_text, (5, 65))
141+
142+
pygame.display.update()
143+
144+
145+
if __name__ == "__main__":
146+
run()
147+
148+
149+

Chapter 8/ball.png

857 Bytes
Loading

0 commit comments

Comments
 (0)