diff --git a/punyverse/entity.py b/punyverse/entity.py index e40f64b..70f56b0 100644 --- a/punyverse/entity.py +++ b/punyverse/entity.py @@ -29,17 +29,17 @@ class Asteroid(Entity): self.rotation = rx + 1, ry + 1, rz + 1 -class Planet(Entity): +class Body(Entity): def __init__(self, *args, **kwargs): self.delta = kwargs.pop('delta', 5) self.atmosphere = kwargs.pop('atmosphere', 0) self.cloudmap = kwargs.pop('cloudmap', 0) self.last_tick = 0 self.mass = kwargs.pop('mass', None) - super(Planet, self).__init__(*args, **kwargs) + super(Body, self).__init__(*args, **kwargs) def update(self): - super(Planet, self).update() + super(Body, self).update() if self.last_tick != framedata.tick: self.last_tick = framedata.tick @@ -48,7 +48,7 @@ class Planet(Entity): self.rotation = pitch, yaw, roll -class Satellite(Planet): +class Satellite(Body): def __init__(self, *args, **kwargs): self.parent = kwargs.pop('parent') self.orbit_speed = kwargs.pop('orbit_speed', 1) @@ -85,8 +85,8 @@ class Satellite(Planet): glDisable(GL_LIGHTING) glDisable(GL_TEXTURE_2D) glPushAttrib(GL_LINE_BIT | GL_CURRENT_BIT) - glColor3f(0, 1, 0) - glLineWidth(3) + glColor3f(1, 1, 1) + glLineWidth(1) glBegin(GL_LINE_LOOP) for theta in xrange(360): x, z, y = self.orbit.orbit(theta) @@ -102,7 +102,7 @@ class Satellite(Planet): return id def update(self): - super(Planet, self).update() + super(Body, self).update() if self.last_tick != framedata.tick: self.last_tick = framedata.tick @@ -112,7 +112,7 @@ class Satellite(Planet): self.parent.update() px, py, pz = self.parent.location - self.theta += self.orbit_speed + self.theta = framedata.tick * self.orbit_speed % 360 x, z, y = self.orbit.orbit(self.theta) self.location = (x + px, y + py, z + pz) diff --git a/punyverse/game.py b/punyverse/game.py index 15d89cd..a55a6e1 100644 --- a/punyverse/game.py +++ b/punyverse/game.py @@ -55,7 +55,7 @@ class Applet(pyglet.window.Window): cam.roll -= 4 cam.move(0, 0, -self.speed * 128 * 0.003) - framedata.tick += 1 + framedata.tick += self.tick for entity in self.world.tracker: entity.update() @@ -68,6 +68,15 @@ class Applet(pyglet.window.Window): self.keys = set() self.info = True self.debug = False + self.orbit = True + + self.tick = 1 + # On standard world: 10x is one day per second, 100x is 10 days, 300x is a month + # 900x is a quarter, 1825 is a half year, 3650 is a year, 36500 is a decade, 365000 is a century + self.ticks = [1, 2, 4, 8, 10, 15, 25, 36, 50, 100, 300, 900, 1825, 3650, + 7300, 18250, 36500, 73000, 182500, 365000] + self.__time_per_second_cache = None + self.__time_per_second_value = None self.label = pyglet.text.Label('', font_name='Consolas', font_size=12, x=10, y=self.height - 20, color=(255,) * 4, multiline=True, width=600) @@ -162,10 +171,24 @@ class Applet(pyglet.window.Window): self.speed += 100 elif symbol == key.PAGEDOWN: self.speed -= 100 + elif symbol == key.HOME: + self.speed += 1000 + elif symbol == key.END: + self.speed -= 1000 elif symbol == key.I: self.info = not self.info elif symbol == key.D: self.debug = not self.debug + elif symbol == key.O: + self.orbit = not self.orbit + elif symbol == key.INSERT: + index = self.ticks.index(self.tick) + 1 + if index < len(self.ticks): + self.tick = self.ticks[index] + elif symbol == key.DELETE: + index = self.ticks.index(self.tick) - 1 + if index >= 0: + self.tick = self.ticks[index] elif symbol == key.Q: c = self.cam dx, dy, dz = c.direction() @@ -192,6 +215,21 @@ class Applet(pyglet.window.Window): gluPerspective(45.0, width / float(height), 0.1, 50000000.0) glMatrixMode(GL_MODELVIEW) + def get_time_per_second(self): + if self.__time_per_second_cache == self.tick: + return self.__time_per_second_value + time = self.world.tick * self.tick * TICKS_PER_SECOND + .0 + unit = 'seconds' + for size, name in ((60, 'minutes'), (60, 'hours'), (24, 'days'), (365, 'years')): + if time < size: + break + time /= size + unit = name + result = '%s %s' % (time, unit) + self.__time_per_second_cache = self.tick + self.__time_per_second_value = result + return result + def on_draw(self): glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) glLoadIdentity() @@ -265,7 +303,7 @@ class Applet(pyglet.window.Window): glDisable(GL_ALPHA_TEST) glPopMatrix() - if self.debug and hasattr(entity, 'get_orbit') and hasattr(entity, 'parent'): + if self.orbit and hasattr(entity, 'get_orbit') and hasattr(entity, 'parent'): glPushMatrix() glTranslatef(*entity.parent.location) glCallList(entity.get_orbit()) @@ -279,9 +317,10 @@ class Applet(pyglet.window.Window): if self.info: ortho(width, height) - self.label.text = ('%d FPS @ (x=%.2f, y=%.2f, z=%.2f) @ %s\n' - 'Direction(pitch=%.2f, yaw=%.2f, roll=%.2f)') % ( - self.fps, c.x, c.y, c.z, self.speed, c.pitch, c.yaw, c.roll) + self.label.text = ('%d FPS @ (x=%.2f, y=%.2f, z=%.2f) @ %s, %s/second\n' + 'Direction(pitch=%.2f, yaw=%.2f, roll=%.2f)' % + (self.fps, c.x, c.y, c.z, self.speed, self.get_time_per_second(), + c.pitch, c.yaw, c.roll)) self.label.draw() glPushAttrib(GL_CURRENT_BIT | GL_LINE_BIT) diff --git a/punyverse/world.json b/punyverse/world.json index db036f8..4abca48 100644 --- a/punyverse/world.json +++ b/punyverse/world.json @@ -13,7 +13,7 @@ "au": 10000, "tick": 432, "length": 63.7, - "planets": { + "bodies": { "earth": { "texture": ["earth.jpg", "earth_medium.jpg", "earth_small.jpg", [0, 0.28, 1, 1]], "radius": 6378.1, diff --git a/punyverse/world.py b/punyverse/world.py index dcca6cf..b4d3105 100644 --- a/punyverse/world.py +++ b/punyverse/world.py @@ -62,6 +62,7 @@ def load_world(file): e = lambda x: eval(str(x), {'__builtins__': None}, {'AU': root.get('au', 2000)}) tick = root.get('tick', 4320) # How many second is a tick? length = root.get('length', 4320) # Satellite distance is in km, divide by this gets in world units + world.tick = tick if 'start' in root: info = root['start'] @@ -103,11 +104,11 @@ def load_world(file): params = {} if parent is None: - type = Planet + type = Body else: x, y, z = parent.location - distance = info.get('distance', 100) # Semi-major axis when actually displayed in virtual space - sma = info.get('sma', distance) # Semi-major axis used to calculate orbital speed + distance = e(info.get('distance', 100)) # Semi-major axis when actually displayed in virtual space + sma = e(info.get('sma', distance)) # Semi-major axis used to calculate orbital speed if hasattr(parent, 'mass') and parent.mass is not None: speed = 360 / (2 * pi * sqrt((sma * 1000) ** 3 / (G * parent.mass)) / tick) else: @@ -159,7 +160,7 @@ def load_world(file): print "Loading %s, satellite of %s." % (satellite, name) body(satellite, info, object) - for planet, info in root['planets'].iteritems(): + for planet, info in root['bodies'].iteritems(): print "Loading %s." % planet body(planet, info) @@ -174,3 +175,4 @@ class World(object): self.x = None self.y = None self.z = None + self.tick = 1