Created
April 5, 2019 07:38
-
-
Save loganzartman/039a902fe61594d6ca29e70fac587415 to your computer and use it in GitHub Desktop.
termpixels demo
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
star-run.py | |
dependencies: termpixels 0.0.6 (via pip) | |
""" | |
import operator | |
import math | |
from random import uniform | |
from termpixels import App, Color | |
class Vec: | |
def __init__(self, x, y): | |
self.x = x | |
self.y = y | |
def _component_op(self, op, other): | |
if isinstance(other, Vec): | |
return Vec(op(self.x, other.x), op(self.y, other.y)) | |
return Vec(op(self.x, other), op(self.y, other)) | |
def __add__(self, other): | |
return self._component_op(operator.add, other) | |
def __sub__(self, other): | |
return self._component_op(operator.sub, other) | |
def __mul__(self, other): | |
return self._component_op(operator.mul, other) | |
def __truediv__(self, other): | |
return self._component_op(operator.truediv, other) | |
def __mod__(self, other): | |
return self._component_op(operator.mod, other) | |
def __str__(self): | |
return "({}, {})".format(self.x, self.y) | |
def print_block_ysub(screen, x, y, **kwargs): | |
frac = y % 1 | |
if frac > 0.5: | |
screen.print("▄\n▀", int(x), int(y), **kwargs) | |
else: | |
screen.print("█", int(x), int(y), **kwargs) | |
VIEW_BAND = Vec(20, 5) | |
class Player: | |
def __init__(self): | |
self.p = Vec(0,30) | |
self.v = Vec(0,0) | |
def update(self, screen, world): | |
#if world.height_at(self.p.x) + 2 > self.p.y: | |
# raise Exception("Game over") | |
self.p = self.p + self.v | |
self.v.y -= 0.05 | |
self.v *= 0.98 | |
h = world.height_at(round(self.p.x)) | |
if h > self.p.y: | |
self.v.y = h - self.p.y | |
self.p.y = h | |
p = self.p - world.scroll | |
print_block_ysub(screen, p.x, screen.h - p.y, fg=Color.rgb(1,0.1,0.3)) | |
self.update_view(screen, world) | |
def update_view(self, screen, world): | |
view_left = world.scroll.x + VIEW_BAND.x | |
view_right = world.scroll.x + screen.w - VIEW_BAND.x | |
view_top = world.scroll.y + VIEW_BAND.y | |
view_bottom = world.scroll.y + screen.h - VIEW_BAND.y | |
if self.p.x > view_right: | |
world.scroll.x = self.p.x - screen.w + VIEW_BAND.x | |
if self.p.x < view_left: | |
world.scroll.x = self.p.x - VIEW_BAND.x | |
if self.p.y > view_bottom: | |
world.scroll.y = self.p.y - screen.h + VIEW_BAND.y | |
if self.p.y < view_top: | |
world.scroll.y = self.p.y - VIEW_BAND.y | |
def jump(self): | |
self.v.y += 1 | |
def left(self): | |
self.v.x -= 1 | |
def right(self): | |
self.v.x += 1 | |
class World: | |
def __init__(self): | |
self.scroll = Vec(0,0) | |
def height_at(self, x): | |
def octave(n, x): | |
n += 1 | |
return math.sin(x * n * 0.03317) ** 3 * 4 / n | |
acc = 10 | |
for i in range(5): | |
acc += octave(i, x) | |
return acc | |
def update(self, screen): | |
for x in range(screen.w): | |
h = self.height_at(x + self.scroll.x) | |
y = screen.h + self.scroll.y | |
i = 0 | |
while h - i >= 0: | |
f = i / h | |
col = Color.rgb(f, f, f) | |
screen.print(":" if h - i > 0.5 else ".", x, int(y - i), fg=col) | |
i += 1 | |
class Starfield: | |
def __init__(self): | |
self.stars = None | |
def rebuild(self, screen, n=100): | |
self.stars = [(Vec(uniform(0, screen.w), uniform(0, screen.h)), uniform(0, 1)) for i in range(n)] | |
def update(self, screen, world): | |
if self.stars is None: | |
return | |
for p, depth in self.stars: | |
p = (p - world.scroll / (depth * 2 + 1)) % Vec(screen.w, screen.h) | |
col = Color.hsl(0.8, 0.7, 1-depth) | |
screen.print("*", round(p.x), round(screen.h-p.y), fg=col) | |
class RunApp(App): | |
def __init__(self): | |
super().__init__(framerate=60) | |
def on_start(self): | |
self.world = World() | |
self.player = Player() | |
self.starfield = Starfield() | |
self._dirty = True | |
def on_resize(self): | |
self._dirty = True | |
def on_frame(self): | |
if self._dirty: | |
self.starfield.rebuild(self.screen) | |
self._dirty = False | |
self.screen.clear() | |
self.starfield.update(self.screen, self.world) | |
self.world.update(self.screen) | |
self.player.update(self.screen, self.world) | |
self.screen.update() | |
def on_key(self, k): | |
if k == "z" or k == " ": | |
self.player.jump() | |
if k == "a" or k == "left": | |
self.player.left() | |
if k == "d" or k == "right": | |
self.player.right() | |
if __name__ == "__main__": | |
RunApp().start() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment