mirror of
https://github.com/quantum5/punyverse.git
synced 2025-04-24 13:11:57 -04:00
Move non-UI logic from game to world.
This commit is contained in:
parent
3e50d66e91
commit
924c59f7b1
|
@ -10,6 +10,10 @@ class Camera(object):
|
||||||
self.yaw = yaw
|
self.yaw = yaw
|
||||||
self.roll = roll
|
self.roll = roll
|
||||||
|
|
||||||
|
self.speed = 0
|
||||||
|
self.roll_left = False
|
||||||
|
self.roll_right = False
|
||||||
|
|
||||||
def move(self, speed):
|
def move(self, speed):
|
||||||
dx, dy, dz = self.direction()
|
dx, dy, dz = self.direction()
|
||||||
self.x += dx * speed
|
self.x += dx * speed
|
||||||
|
@ -40,5 +44,16 @@ class Camera(object):
|
||||||
dz = sin(radians(self.yaw - 90)) * m
|
dz = sin(radians(self.yaw - 90)) * m
|
||||||
return dx, dy, dz
|
return dx, dy, dz
|
||||||
|
|
||||||
|
def update(self, dt, move):
|
||||||
|
if self.roll_left:
|
||||||
|
self.roll += 4 * dt * 10
|
||||||
|
if self.roll:
|
||||||
|
self.roll -= 4 * dt * 10
|
||||||
|
if move:
|
||||||
|
self.move(self.speed * 10 * dt)
|
||||||
|
|
||||||
|
def reset_roll(self):
|
||||||
|
self.roll = 0
|
||||||
|
|
||||||
def distance(self, x, y, z):
|
def distance(self, x, y, z):
|
||||||
return hypot(hypot(x - self.x, y - self.y), z - self.z)
|
return hypot(hypot(x - self.x, y - self.y), z - self.z)
|
||||||
|
|
|
@ -34,20 +34,14 @@ class Entity(object):
|
||||||
def collides(self, x, y, z):
|
def collides(self, x, y, z):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def draw(self, cam, options):
|
def draw(self, options):
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
|
||||||
class Asteroid(Entity):
|
class Asteroid(Entity):
|
||||||
asteroid_ids = []
|
def __init__(self, asteroid_id, location, direction):
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def load_asteroid(cls, file):
|
|
||||||
cls.asteroid_ids.append(model_list(load_model(file), 5, 5, 5, (0, 0, 0)))
|
|
||||||
|
|
||||||
def __init__(self, location, direction):
|
|
||||||
super(Asteroid, self).__init__('Asteroid', location, direction=direction)
|
super(Asteroid, self).__init__('Asteroid', location, direction=direction)
|
||||||
self.asteroid_id = random.choice(self.asteroid_ids)
|
self.asteroid_id = asteroid_id
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
super(Asteroid, self).update()
|
super(Asteroid, self).update()
|
||||||
|
@ -56,11 +50,26 @@ class Asteroid(Entity):
|
||||||
# Increment all axis to 'spin'
|
# Increment all axis to 'spin'
|
||||||
self.rotation = rx + 1, ry + 1, rz + 1
|
self.rotation = rx + 1, ry + 1, rz + 1
|
||||||
|
|
||||||
def draw(self, cam, options):
|
def draw(self, options):
|
||||||
with glMatrix(self.location, self.rotation), glRestore(GL_CURRENT_BIT):
|
with glMatrix(self.location, self.rotation), glRestore(GL_CURRENT_BIT):
|
||||||
glCallList(self.asteroid_id)
|
glCallList(self.asteroid_id)
|
||||||
|
|
||||||
|
|
||||||
|
class AsteroidManager(object):
|
||||||
|
def __init__(self):
|
||||||
|
self.asteroids = []
|
||||||
|
|
||||||
|
def __bool__(self):
|
||||||
|
return bool(self.asteroids)
|
||||||
|
__nonzero__ = __bool__
|
||||||
|
|
||||||
|
def load(self, file):
|
||||||
|
self.asteroids.append(model_list(load_model(file), 5, 5, 5, (0, 0, 0)))
|
||||||
|
|
||||||
|
def new(self, location, direction):
|
||||||
|
return Asteroid(random.choice(self.asteroids), location, direction)
|
||||||
|
|
||||||
|
|
||||||
class Belt(Entity):
|
class Belt(Entity):
|
||||||
def __init__(self, name, world, info):
|
def __init__(self, name, world, info):
|
||||||
self.world = world
|
self.world = world
|
||||||
|
@ -93,7 +102,7 @@ class Belt(Entity):
|
||||||
pitch, yaw, roll = self.rotation
|
pitch, yaw, roll = self.rotation
|
||||||
self.rotation = pitch, self.world.tick * self.rotation_angle % 360, roll
|
self.rotation = pitch, self.world.tick * self.rotation_angle % 360, roll
|
||||||
|
|
||||||
def draw(self, cam, options):
|
def draw(self, options):
|
||||||
with glMatrix(self.location, self.rotation), glRestore(GL_CURRENT_BIT):
|
with glMatrix(self.location, self.rotation), glRestore(GL_CURRENT_BIT):
|
||||||
glCallList(self.belt_id)
|
glCallList(self.belt_id)
|
||||||
|
|
||||||
|
@ -114,7 +123,8 @@ class Sky(Entity):
|
||||||
self.sky_id = compile(sphere, info.get('radius', 1000000), division, division, texture,
|
self.sky_id = compile(sphere, info.get('radius', 1000000), division, division, texture,
|
||||||
inside=True, lighting=False)
|
inside=True, lighting=False)
|
||||||
|
|
||||||
def draw(self, cam, options):
|
def draw(self, options):
|
||||||
|
cam = self.world.cam
|
||||||
with glMatrix((-cam.x, -cam.y, -cam.z), self.rotation), glRestore(GL_CURRENT_BIT):
|
with glMatrix((-cam.x, -cam.y, -cam.z), self.rotation), glRestore(GL_CURRENT_BIT):
|
||||||
glCallList(self.sky_id)
|
glCallList(self.sky_id)
|
||||||
|
|
||||||
|
@ -219,18 +229,18 @@ class Body(Entity):
|
||||||
glLineWidth(1)
|
glLineWidth(1)
|
||||||
glCallList(self.get_orbit())
|
glCallList(self.get_orbit())
|
||||||
|
|
||||||
def draw(self, cam, options):
|
def draw(self, options):
|
||||||
self._draw(cam, options)
|
self._draw(options)
|
||||||
|
|
||||||
if options.orbit and self.orbit:
|
if options.orbit and self.orbit:
|
||||||
dist = cam.distance(*self.parent.location)
|
dist = self.world.cam.distance(*self.parent.location)
|
||||||
if dist < self.parent.orbit_show:
|
if dist < self.parent.orbit_show:
|
||||||
self._draw_orbits(dist)
|
self._draw_orbits(dist)
|
||||||
|
|
||||||
for satellite in self.satellites:
|
for satellite in self.satellites:
|
||||||
satellite.draw(cam, options)
|
satellite.draw(options)
|
||||||
|
|
||||||
def _draw(self, cam, options):
|
def _draw(self, options):
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
def collides(self, x, y, z):
|
def collides(self, x, y, z):
|
||||||
|
@ -297,7 +307,7 @@ class SphericalBody(Body):
|
||||||
glDisable(GL_LIGHTING)
|
glDisable(GL_LIGHTING)
|
||||||
glCallList(self.sphere_id)
|
glCallList(self.sphere_id)
|
||||||
|
|
||||||
def _draw_atmosphere(self, cam, glMatrixBuffer=GLfloat * 16):
|
def _draw_atmosphere(self, glMatrixBuffer=GLfloat * 16):
|
||||||
with glMatrix(self.location), glRestore(GL_ENABLE_BIT | GL_CURRENT_BIT):
|
with glMatrix(self.location), glRestore(GL_ENABLE_BIT | GL_CURRENT_BIT):
|
||||||
matrix = glMatrixBuffer()
|
matrix = glMatrixBuffer()
|
||||||
glGetFloatv(GL_MODELVIEW_MATRIX, matrix)
|
glGetFloatv(GL_MODELVIEW_MATRIX, matrix)
|
||||||
|
@ -310,7 +320,7 @@ class SphericalBody(Body):
|
||||||
glCallList(self.atmosphere_id)
|
glCallList(self.atmosphere_id)
|
||||||
|
|
||||||
if self.corona_id:
|
if self.corona_id:
|
||||||
x, y, z = cam.direction()
|
x, y, z = self.world.cam.direction()
|
||||||
glTranslatef(-x, -y, -z)
|
glTranslatef(-x, -y, -z)
|
||||||
glEnable(GL_BLEND)
|
glEnable(GL_BLEND)
|
||||||
glCallList(self.corona_id)
|
glCallList(self.corona_id)
|
||||||
|
@ -325,11 +335,11 @@ class SphericalBody(Body):
|
||||||
with glMatrix(self.location, self.ring_rotation), glRestore(GL_CURRENT_BIT):
|
with glMatrix(self.location, self.ring_rotation), glRestore(GL_CURRENT_BIT):
|
||||||
glCallList(self.ring_id)
|
glCallList(self.ring_id)
|
||||||
|
|
||||||
def _draw(self, cam, options):
|
def _draw(self, options):
|
||||||
self._draw_sphere()
|
self._draw_sphere()
|
||||||
|
|
||||||
if options.atmosphere and (self.atmosphere_id or self.corona_id):
|
if options.atmosphere and (self.atmosphere_id or self.corona_id):
|
||||||
self._draw_atmosphere(cam)
|
self._draw_atmosphere()
|
||||||
|
|
||||||
if options.cloud and self.cloudmap_id:
|
if options.cloud and self.cloudmap_id:
|
||||||
self._draw_clouds()
|
self._draw_clouds()
|
||||||
|
@ -352,6 +362,6 @@ class ModelBody(Body):
|
||||||
self.object_id = model_list(load_model(info['model']), info.get('sx', scale), info.get('sy', scale),
|
self.object_id = model_list(load_model(info['model']), info.get('sx', scale), info.get('sy', scale),
|
||||||
info.get('sz', scale), (0, 0, 0))
|
info.get('sz', scale), (0, 0, 0))
|
||||||
|
|
||||||
def _draw(self, cam, options):
|
def _draw(self, options):
|
||||||
with glMatrix(self.location, self.rotation), glRestore(GL_CURRENT_BIT):
|
with glMatrix(self.location, self.rotation), glRestore(GL_CURRENT_BIT):
|
||||||
glCallList(self.object_id)
|
glCallList(self.object_id)
|
||||||
|
|
|
@ -8,8 +8,6 @@ from time import clock
|
||||||
import six
|
import six
|
||||||
|
|
||||||
from punyverse import texture
|
from punyverse import texture
|
||||||
from punyverse.camera import Camera
|
|
||||||
from punyverse.entity import Asteroid
|
|
||||||
from punyverse.glgeom import *
|
from punyverse.glgeom import *
|
||||||
from punyverse.world import World
|
from punyverse.world import World
|
||||||
|
|
||||||
|
@ -28,7 +26,6 @@ from pyglet.window import key, mouse
|
||||||
|
|
||||||
import pyglet
|
import pyglet
|
||||||
|
|
||||||
INITIAL_SPEED = 0 # The initial speed of the player
|
|
||||||
MOUSE_SENSITIVITY = 0.3 # Mouse sensitivity, 0..1, none...hyperspeed
|
MOUSE_SENSITIVITY = 0.3 # Mouse sensitivity, 0..1, none...hyperspeed
|
||||||
|
|
||||||
MAX_DELTA = 5
|
MAX_DELTA = 5
|
||||||
|
@ -44,8 +41,6 @@ def entity_distance(x0, y0, z0):
|
||||||
|
|
||||||
|
|
||||||
class Applet(pyglet.window.Window):
|
class Applet(pyglet.window.Window):
|
||||||
asteroids = ['asteroids/01.obj', 'asteroids/02.obj', 'asteroids/03.obj']
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(Applet, self).__init__(*args, **kwargs)
|
super(Applet, self).__init__(*args, **kwargs)
|
||||||
texture.init()
|
texture.init()
|
||||||
|
@ -94,8 +89,6 @@ class Applet(pyglet.window.Window):
|
||||||
self.fps = 0
|
self.fps = 0
|
||||||
self.world = World('world.json', self._load_callback)
|
self.world = World('world.json', self._load_callback)
|
||||||
self._load_callback('Initializing game...', '', 0)
|
self._load_callback('Initializing game...', '', 0)
|
||||||
self.speed = INITIAL_SPEED
|
|
||||||
self.keys = set()
|
|
||||||
self.info = True
|
self.info = True
|
||||||
self.debug = False
|
self.debug = False
|
||||||
self.orbit = True
|
self.orbit = True
|
||||||
|
@ -105,7 +98,6 @@ class Applet(pyglet.window.Window):
|
||||||
self.atmosphere = True
|
self.atmosphere = True
|
||||||
self.cloud = True
|
self.cloud = True
|
||||||
|
|
||||||
self.tick = self.world.tick_length
|
|
||||||
self.ticks = [
|
self.ticks = [
|
||||||
1, 2, 5, 10, 20, 40, 60, # Second range
|
1, 2, 5, 10, 20, 40, 60, # Second range
|
||||||
120, 300, 600, 1200, 1800, 2700, 3600, # Minute range
|
120, 300, 600, 1200, 1800, 2700, 3600, # Minute range
|
||||||
|
@ -116,9 +108,6 @@ class Applet(pyglet.window.Window):
|
||||||
63072000, 157680000, 315360000, # 2, 5, 10 years
|
63072000, 157680000, 315360000, # 2, 5, 10 years
|
||||||
630720000, 1576800000, 3153600000, # 20, 50, 100 years
|
630720000, 1576800000, 3153600000, # 20, 50, 100 years
|
||||||
]
|
]
|
||||||
self.__time_per_second_cache = None
|
|
||||||
self.__time_per_second_value = None
|
|
||||||
self.__time_accumulate = 0
|
|
||||||
|
|
||||||
def speed_incrementer(object, increment):
|
def speed_incrementer(object, increment):
|
||||||
def incrementer():
|
def incrementer():
|
||||||
|
@ -137,24 +126,24 @@ class Applet(pyglet.window.Window):
|
||||||
def increment_tick():
|
def increment_tick():
|
||||||
index = self.ticks.index(self.tick) + 1
|
index = self.ticks.index(self.tick) + 1
|
||||||
if index < len(self.ticks):
|
if index < len(self.ticks):
|
||||||
self.tick = self.ticks[index]
|
self.world.tick_length = self.ticks[index]
|
||||||
|
|
||||||
def decrement_tick():
|
def decrement_tick():
|
||||||
index = self.ticks.index(self.tick) - 1
|
index = self.ticks.index(self.tick) - 1
|
||||||
if index >= 0:
|
if index >= 0:
|
||||||
self.tick = self.ticks[index]
|
self.world.tick_length = self.ticks[index]
|
||||||
|
|
||||||
self.key_handler = {
|
self.key_handler = {
|
||||||
key.ESCAPE: pyglet.app.exit,
|
key.ESCAPE: pyglet.app.exit,
|
||||||
key.NUM_ADD: speed_incrementer(self, 1),
|
key.NUM_ADD: speed_incrementer(self.world.cam, 1),
|
||||||
key.NUM_SUBTRACT: speed_incrementer(self, -1),
|
key.NUM_SUBTRACT: speed_incrementer(self.world.cam, -1),
|
||||||
key.NUM_MULTIPLY: speed_incrementer(self, 10),
|
key.NUM_MULTIPLY: speed_incrementer(self.world.cam, 10),
|
||||||
key.NUM_DIVIDE: speed_incrementer(self, -10),
|
key.NUM_DIVIDE: speed_incrementer(self.world.cam, -10),
|
||||||
key.PAGEUP: speed_incrementer(self, 100),
|
key.PAGEUP: speed_incrementer(self.world.cam, 100),
|
||||||
key.PAGEDOWN: speed_incrementer(self, -100),
|
key.PAGEDOWN: speed_incrementer(self.world.cam, -100),
|
||||||
key.HOME: speed_incrementer(self, 1000),
|
key.HOME: speed_incrementer(self.world.cam, 1000),
|
||||||
key.END: speed_incrementer(self, -1000),
|
key.END: speed_incrementer(self.world.cam, -1000),
|
||||||
key.R: lambda: setattr(self.cam, 'roll', 0),
|
key.R: self.world.cam.reset_roll,
|
||||||
key.I: attribute_toggler(self, 'info'),
|
key.I: attribute_toggler(self, 'info'),
|
||||||
key.D: attribute_toggler(self, 'debug'),
|
key.D: attribute_toggler(self, 'debug'),
|
||||||
key.O: attribute_toggler(self, 'orbit'),
|
key.O: attribute_toggler(self, 'orbit'),
|
||||||
|
@ -164,19 +153,18 @@ class Applet(pyglet.window.Window):
|
||||||
key.ENTER: attribute_toggler(self, 'running'),
|
key.ENTER: attribute_toggler(self, 'running'),
|
||||||
key.INSERT: increment_tick,
|
key.INSERT: increment_tick,
|
||||||
key.DELETE: decrement_tick,
|
key.DELETE: decrement_tick,
|
||||||
key.SPACE: self.launch_meteor,
|
key.SPACE: self.world.spawn_asteroid,
|
||||||
key.E: lambda: self.set_exclusive_mouse(False),
|
key.E: lambda: self.set_exclusive_mouse(False),
|
||||||
key.F: lambda: self.set_fullscreen(not self.fullscreen),
|
key.F: lambda: self.set_fullscreen(not self.fullscreen),
|
||||||
}
|
}
|
||||||
|
|
||||||
self.mouse_press_handler = {
|
self.mouse_press_handler = {
|
||||||
mouse.LEFT: self.launch_meteor,
|
mouse.LEFT: self.world.spawn_asteroid,
|
||||||
mouse.RIGHT: attribute_toggler(self, 'moving'),
|
mouse.RIGHT: attribute_toggler(self, 'moving'),
|
||||||
}
|
}
|
||||||
|
|
||||||
self.label = pyglet.text.Label('', font_name='Consolas', font_size=12, x=10, y=self.height - 20,
|
self.label = pyglet.text.Label('', font_name='Consolas', font_size=12, x=10, y=self.height - 20,
|
||||||
color=(255,) * 4, multiline=True, width=600)
|
color=(255,) * 4, multiline=True, width=600)
|
||||||
self.cam = Camera()
|
|
||||||
|
|
||||||
self.exclusive = False
|
self.exclusive = False
|
||||||
|
|
||||||
|
@ -205,18 +193,6 @@ class Applet(pyglet.window.Window):
|
||||||
glLightfv(GL_LIGHT1, GL_DIFFUSE, fv4(.5, .5, .5, 1))
|
glLightfv(GL_LIGHT1, GL_DIFFUSE, fv4(.5, .5, .5, 1))
|
||||||
glLightfv(GL_LIGHT1, GL_SPECULAR, fv4(1, 1, 1, 1))
|
glLightfv(GL_LIGHT1, GL_SPECULAR, fv4(1, 1, 1, 1))
|
||||||
|
|
||||||
for id, file in enumerate(self.asteroids):
|
|
||||||
self._load_callback('Loading asteroids...', 'Loading %s...' % file, float(id) / len(self.asteroids))
|
|
||||||
Asteroid.load_asteroid(file)
|
|
||||||
|
|
||||||
c = self.cam
|
|
||||||
c.x, c.y, c.z = self.world.start
|
|
||||||
c.pitch, c.yaw, c.roll = self.world.direction
|
|
||||||
|
|
||||||
self._load_callback('Updating entities...', '', 0)
|
|
||||||
for entity in self.world.tracker:
|
|
||||||
entity.update()
|
|
||||||
|
|
||||||
print('Loaded in %s seconds.' % (clock() - start))
|
print('Loaded in %s seconds.' % (clock() - start))
|
||||||
self.loaded = True
|
self.loaded = True
|
||||||
pyglet.clock.schedule(self.update)
|
pyglet.clock.schedule(self.update)
|
||||||
|
@ -252,15 +228,6 @@ class Applet(pyglet.window.Window):
|
||||||
super(Applet, self).set_exclusive_mouse(exclusive)
|
super(Applet, self).set_exclusive_mouse(exclusive)
|
||||||
self.exclusive = exclusive
|
self.exclusive = exclusive
|
||||||
|
|
||||||
def launch_meteor(self):
|
|
||||||
c = self.cam
|
|
||||||
dx, dy, dz = c.direction()
|
|
||||||
speed = abs(self.speed) * 1.1 + 5
|
|
||||||
dx *= speed
|
|
||||||
dy *= speed
|
|
||||||
dz *= speed
|
|
||||||
self.world.tracker.append(Asteroid((c.x, c.y - 3, c.z + 5), (dx, dy, dz)))
|
|
||||||
|
|
||||||
def on_mouse_press(self, x, y, button, modifiers):
|
def on_mouse_press(self, x, y, button, modifiers):
|
||||||
self.modifiers = modifiers
|
self.modifiers = modifiers
|
||||||
if not self.loaded:
|
if not self.loaded:
|
||||||
|
@ -277,7 +244,7 @@ class Applet(pyglet.window.Window):
|
||||||
return
|
return
|
||||||
|
|
||||||
if self.exclusive: # Only handle camera movement if mouse is grabbed
|
if self.exclusive: # Only handle camera movement if mouse is grabbed
|
||||||
self.cam.mouse_move(dx * MOUSE_SENSITIVITY, dy * MOUSE_SENSITIVITY)
|
self.world.cam.mouse_move(dx * MOUSE_SENSITIVITY, dy * MOUSE_SENSITIVITY)
|
||||||
|
|
||||||
def on_key_press(self, symbol, modifiers):
|
def on_key_press(self, symbol, modifiers):
|
||||||
self.modifiers = modifiers
|
self.modifiers = modifiers
|
||||||
|
@ -288,15 +255,19 @@ class Applet(pyglet.window.Window):
|
||||||
if self.exclusive: # Only handle keyboard input if mouse is grabbed
|
if self.exclusive: # Only handle keyboard input if mouse is grabbed
|
||||||
if symbol in self.key_handler:
|
if symbol in self.key_handler:
|
||||||
self.key_handler[symbol]()
|
self.key_handler[symbol]()
|
||||||
else:
|
elif symbol == key.A:
|
||||||
self.keys.add(symbol)
|
self.world.cam.roll_left = True
|
||||||
|
elif symbol == key.S:
|
||||||
|
self.world.cam.roll_right = True
|
||||||
|
|
||||||
def on_key_release(self, symbol, modifiers):
|
def on_key_release(self, symbol, modifiers):
|
||||||
if not self.loaded:
|
if not self.loaded:
|
||||||
return
|
return
|
||||||
|
|
||||||
if symbol in self.keys:
|
if symbol == key.A:
|
||||||
self.keys.remove(symbol)
|
self.world.cam.roll_left = False
|
||||||
|
elif symbol == key.S:
|
||||||
|
self.world.cam.roll_right = False
|
||||||
|
|
||||||
def on_resize(self, width, height):
|
def on_resize(self, width, height):
|
||||||
if not self.loaded:
|
if not self.loaded:
|
||||||
|
@ -315,12 +286,10 @@ class Applet(pyglet.window.Window):
|
||||||
if not self.loaded:
|
if not self.loaded:
|
||||||
return
|
return
|
||||||
|
|
||||||
self.speed += scroll_y * 50 + scroll_x * 500
|
self.world.cam.speed += scroll_y * 50 + scroll_x * 500
|
||||||
|
|
||||||
def get_time_per_second(self):
|
def get_time_per_second(self):
|
||||||
if self.__time_per_second_cache == self.tick:
|
time = self.world.tick_length
|
||||||
return self.__time_per_second_value
|
|
||||||
time = self.tick + .0
|
|
||||||
unit = 'seconds'
|
unit = 'seconds'
|
||||||
for size, name in ((60, 'minutes'), (60, 'hours'), (24, 'days'), (365, 'years')):
|
for size, name in ((60, 'minutes'), (60, 'hours'), (24, 'days'), (365, 'years')):
|
||||||
if time < size:
|
if time < size:
|
||||||
|
@ -328,35 +297,10 @@ class Applet(pyglet.window.Window):
|
||||||
time /= size
|
time /= size
|
||||||
unit = name
|
unit = name
|
||||||
result = '%s %s' % (round(time, 1), unit)
|
result = '%s %s' % (round(time, 1), unit)
|
||||||
self.__time_per_second_cache = self.tick
|
|
||||||
self.__time_per_second_value = result
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def update(self, dt):
|
def update(self, dt):
|
||||||
c = self.cam
|
self.world.update(dt, move=self.exclusive and self.moving, tick=self.running)
|
||||||
|
|
||||||
if self.exclusive:
|
|
||||||
if key.A in self.keys:
|
|
||||||
c.roll += 4 * dt * 10
|
|
||||||
if key.S in self.keys:
|
|
||||||
c.roll -= 4 * dt * 10
|
|
||||||
if self.moving:
|
|
||||||
c.move(self.speed * 10 * dt)
|
|
||||||
|
|
||||||
if self.running:
|
|
||||||
delta = self.tick * dt
|
|
||||||
update = int(delta + self.__time_accumulate + 0.5)
|
|
||||||
if update:
|
|
||||||
self.__time_accumulate = 0
|
|
||||||
self.world.tick += update
|
|
||||||
for entity in self.world.tracker:
|
|
||||||
entity.update()
|
|
||||||
collision = entity.collides(c.x, c.y, c.z)
|
|
||||||
if collision:
|
|
||||||
self.speed *= -1
|
|
||||||
c.move(self.speed * 12 * dt)
|
|
||||||
else:
|
|
||||||
self.__time_accumulate += delta
|
|
||||||
|
|
||||||
def draw_loading(self, phase=None, message=None, progress=None):
|
def draw_loading(self, phase=None, message=None, progress=None):
|
||||||
glClear(GL_COLOR_BUFFER_BIT)
|
glClear(GL_COLOR_BUFFER_BIT)
|
||||||
|
@ -378,8 +322,7 @@ class Applet(pyglet.window.Window):
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
|
||||||
glLoadIdentity()
|
glLoadIdentity()
|
||||||
|
|
||||||
c = self.cam
|
c = self.world.cam
|
||||||
|
|
||||||
x, y, z = c.x, c.y, c.z
|
x, y, z = c.x, c.y, c.z
|
||||||
glRotatef(c.pitch, 1, 0, 0)
|
glRotatef(c.pitch, 1, 0, 0)
|
||||||
glRotatef(c.yaw, 0, 1, 0)
|
glRotatef(c.yaw, 0, 1, 0)
|
||||||
|
@ -395,7 +338,7 @@ class Applet(pyglet.window.Window):
|
||||||
world.x, world.y, world.z = x, y, z
|
world.x, world.y, world.z = x, y, z
|
||||||
|
|
||||||
for entity in world.tracker:
|
for entity in world.tracker:
|
||||||
entity.draw(c, self)
|
entity.draw(self)
|
||||||
|
|
||||||
glColor4f(1, 1, 1, 1)
|
glColor4f(1, 1, 1, 1)
|
||||||
glDisable(GL_TEXTURE_2D)
|
glDisable(GL_TEXTURE_2D)
|
||||||
|
@ -407,11 +350,11 @@ class Applet(pyglet.window.Window):
|
||||||
if self.info_precise:
|
if self.info_precise:
|
||||||
info = ('%d FPS @ (x=%.2f, y=%.2f, z=%.2f) @ %s, %s/s\n'
|
info = ('%d FPS @ (x=%.2f, y=%.2f, z=%.2f) @ %s, %s/s\n'
|
||||||
'Direction(pitch=%.2f, yaw=%.2f, roll=%.2f)\nTick: %d' %
|
'Direction(pitch=%.2f, yaw=%.2f, roll=%.2f)\nTick: %d' %
|
||||||
(pyglet.clock.get_fps(), c.x, c.y, c.z, self.speed, self.get_time_per_second(),
|
(pyglet.clock.get_fps(), c.x, c.y, c.z, self.world.cam.speed, self.get_time_per_second(),
|
||||||
c.pitch, c.yaw, c.roll, self.world.tick))
|
c.pitch, c.yaw, c.roll, self.world.tick))
|
||||||
else:
|
else:
|
||||||
info = ('%d FPS @ (x=%.2f, y=%.2f, z=%.2f) @ %s, %s/s\n' %
|
info = ('%d FPS @ (x=%.2f, y=%.2f, z=%.2f) @ %s, %s/s\n' %
|
||||||
(pyglet.clock.get_fps(), c.x, c.y, c.z, self.speed, self.get_time_per_second()))
|
(pyglet.clock.get_fps(), c.x, c.y, c.z, self.world.cam.speed, self.get_time_per_second()))
|
||||||
self.label.text = info
|
self.label.text = info
|
||||||
self.label.draw()
|
self.label.draw()
|
||||||
with glRestore(GL_CURRENT_BIT | GL_LINE_BIT):
|
with glRestore(GL_CURRENT_BIT | GL_LINE_BIT):
|
||||||
|
|
|
@ -308,6 +308,7 @@
|
||||||
"yaw": 30,
|
"yaw": 30,
|
||||||
"roll": 180
|
"roll": 180
|
||||||
},
|
},
|
||||||
|
"asteroids": ["asteroids/01.obj", "asteroids/02.obj", "asteroids/03.obj"],
|
||||||
"start": {
|
"start": {
|
||||||
"z": "AU - 400",
|
"z": "AU - 400",
|
||||||
"yaw": 180
|
"yaw": 180
|
||||||
|
|
|
@ -6,14 +6,15 @@ from collections import OrderedDict
|
||||||
|
|
||||||
import six
|
import six
|
||||||
|
|
||||||
|
from punyverse import texture
|
||||||
|
from punyverse.camera import Camera
|
||||||
|
from punyverse.entity import *
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from punyverse._model import model_list, load_model
|
from punyverse._model import model_list, load_model
|
||||||
except ImportError:
|
except ImportError:
|
||||||
from punyverse.model import model_list, load_model
|
from punyverse.model import model_list, load_model
|
||||||
|
|
||||||
from punyverse.entity import *
|
|
||||||
from punyverse import texture
|
|
||||||
|
|
||||||
|
|
||||||
def load_world(file, callback=lambda message, completion: None):
|
def load_world(file, callback=lambda message, completion: None):
|
||||||
return World(file, callback)
|
return World(file, callback)
|
||||||
|
@ -22,18 +23,23 @@ def load_world(file, callback=lambda message, completion: None):
|
||||||
class World(object):
|
class World(object):
|
||||||
def __init__(self, file, callback):
|
def __init__(self, file, callback):
|
||||||
self.tracker = []
|
self.tracker = []
|
||||||
self.start = (0, 0, 0)
|
|
||||||
self.direction = (0, 0, 0)
|
|
||||||
self.x = None
|
self.x = None
|
||||||
self.y = None
|
self.y = None
|
||||||
self.z = None
|
self.z = None
|
||||||
self.tick_length = 1
|
self.tick_length = 0
|
||||||
self.tick = 0
|
self.tick = 0
|
||||||
|
self.asteroids = AsteroidManager()
|
||||||
|
self.cam = Camera()
|
||||||
|
|
||||||
self.callback = callback
|
self.callback = callback
|
||||||
self._parse(file)
|
self._parse(file)
|
||||||
del self.callback # So it can't be used after loading finishes
|
del self.callback # So it can't be used after loading finishes
|
||||||
|
|
||||||
|
self._time_accumulate = 0
|
||||||
|
|
||||||
|
for entity in self.tracker:
|
||||||
|
entity.update()
|
||||||
|
|
||||||
def evaluate(self, value):
|
def evaluate(self, value):
|
||||||
return eval(str(value), {'__builtins__': None}, self._context)
|
return eval(str(value), {'__builtins__': None}, self._context)
|
||||||
|
|
||||||
|
@ -53,8 +59,7 @@ class World(object):
|
||||||
self._length = root.get('length', 4320)
|
self._length = root.get('length', 4320)
|
||||||
self._context = {'AU': self._au, 'TEXTURE': texture.max_texture, 'KM': 1.0 / self._length}
|
self._context = {'AU': self._au, 'TEXTURE': texture.max_texture, 'KM': 1.0 / self._length}
|
||||||
|
|
||||||
tick = root.get('tick', 4320) # How many second is a tick?
|
self.tick_length = root.get('tick', 4320) # How many second is a tick?
|
||||||
self.tick_length = tick
|
|
||||||
|
|
||||||
# Need to know how many objects are being loaded
|
# Need to know how many objects are being loaded
|
||||||
self._objects = 0
|
self._objects = 0
|
||||||
|
@ -68,14 +73,12 @@ class World(object):
|
||||||
|
|
||||||
if 'start' in root:
|
if 'start' in root:
|
||||||
info = root['start']
|
info = root['start']
|
||||||
x = self.evaluate(info.get('x', 0))
|
self.cam.x = self.evaluate(info.get('x', 0))
|
||||||
y = self.evaluate(info.get('y', 0))
|
self.cam.y = self.evaluate(info.get('y', 0))
|
||||||
z = self.evaluate(info.get('z', 0))
|
self.cam.z = self.evaluate(info.get('z', 0))
|
||||||
pitch = self.evaluate(info.get('pitch', 0))
|
self.cam.pitch = self.evaluate(info.get('pitch', 0))
|
||||||
yaw = self.evaluate(info.get('yaw', 0))
|
self.cam.yaw = self.evaluate(info.get('yaw', 0))
|
||||||
roll = self.evaluate(info.get('roll', 0))
|
self.cam.roll = self.evaluate(info.get('roll', 0))
|
||||||
self.start = (x, y, z)
|
|
||||||
self.direction = (pitch, yaw, roll)
|
|
||||||
|
|
||||||
for planet, info in six.iteritems(root['bodies']):
|
for planet, info in six.iteritems(root['bodies']):
|
||||||
self.callback('Loading objects (%d of %d)...' % (self._current_object, self._objects),
|
self.callback('Loading objects (%d of %d)...' % (self._current_object, self._objects),
|
||||||
|
@ -94,6 +97,12 @@ class World(object):
|
||||||
self.callback('Loading sky...', 'Loading sky.', 0)
|
self.callback('Loading sky...', 'Loading sky.', 0)
|
||||||
self.tracker.append(Sky(self, root['sky']))
|
self.tracker.append(Sky(self, root['sky']))
|
||||||
|
|
||||||
|
if 'asteroids' in root:
|
||||||
|
asteroids = root['asteroids']
|
||||||
|
for i, file in enumerate(asteroids):
|
||||||
|
self.callback('Loading asteroids...', 'Loading %s...' % file, i / len(asteroids))
|
||||||
|
self.asteroids.load(file)
|
||||||
|
|
||||||
def _body(self, name, info, parent=None):
|
def _body(self, name, info, parent=None):
|
||||||
if 'texture' in info:
|
if 'texture' in info:
|
||||||
body = SphericalBody(name, self, info, parent)
|
body = SphericalBody(name, self, info, parent)
|
||||||
|
@ -112,3 +121,30 @@ class World(object):
|
||||||
'Loading %s, satellite of %s.' % (satellite, name), self._current_object / self._objects)
|
'Loading %s, satellite of %s.' % (satellite, name), self._current_object / self._objects)
|
||||||
self._body(satellite, info, body)
|
self._body(satellite, info, body)
|
||||||
self._current_object += 1
|
self._current_object += 1
|
||||||
|
|
||||||
|
def spawn_asteroid(self):
|
||||||
|
if self.asteroids:
|
||||||
|
c = self.cam
|
||||||
|
dx, dy, dz = c.direction()
|
||||||
|
speed = abs(self.cam.speed) * 1.1 + 5
|
||||||
|
self.tracker.append(self.asteroids.new((c.x, c.y - 3, c.z + 5), (dx * speed, dy * speed, dz * speed)))
|
||||||
|
|
||||||
|
def update(self, dt, move, tick):
|
||||||
|
c = self.cam
|
||||||
|
c.update(dt, move)
|
||||||
|
|
||||||
|
if tick:
|
||||||
|
delta = self.tick_length * dt
|
||||||
|
update = int(delta + self._time_accumulate + 0.5)
|
||||||
|
if update:
|
||||||
|
self._time_accumulate = 0
|
||||||
|
self.tick += update
|
||||||
|
|
||||||
|
for entity in self.tracker:
|
||||||
|
entity.update()
|
||||||
|
collision = entity.collides(c.x, c.y, c.z)
|
||||||
|
if collision:
|
||||||
|
c.speed *= -1
|
||||||
|
c.move(c.speed * 12 * dt)
|
||||||
|
else:
|
||||||
|
self._time_accumulate += delta
|
||||||
|
|
Loading…
Reference in a new issue