qflow3r/__init__.py

153 lines
4.1 KiB
Python

from st3m.application import Application, ApplicationContext
from st3m.run import run_view
import os.path
UP = 0
LEFT = 1
DOWN = 2
RIGHT = 3
class Random:
def __init__(self):
self._state = 0x9ec5_9ec5 # (two gecs)
# idk its fine its just for choosing delay and direction
def next(self):
self._state *= 37
self._state &= 0xffff_ffff
return self._state >> 24
def direction(self):
return self.next() & 3
def delay(self):
return Quox.TURN_DELAY_BASE + self.next()
# screen coords range ±120 each side
class Quox(Application):
STEP_DELAY = 250
TURN_DELAY_BASE = 1400
MOVE_DELAY = 100
TOP = -90
BOTTOM = 70 # so its always a bit visible
LEFT = -90
RIGHT = 70
@staticmethod
def image_path(direction, step):
dir = os.path.dirname(__file__)
bases = {UP: 'back', LEFT: 'left', DOWN: 'front', RIGHT: 'right'}
base = bases[direction]
return f"{dir}/sprites/{base}{step}.png"
def __init__(self, app_ctx):
super().__init__(app_ctx)
self.random = Random()
self.choose_direction()
self.choose_turn_delay()
self.step = 0
self.step_delay = Quox.STEP_DELAY
self.move_delay = Quox.MOVE_DELAY
self.x = -10
self.y = -10
def draw(self, ctx):
self.clear(ctx)
# self.text(ctx)
self.image(ctx)
def clear(self, ctx):
ctx.rgb(0, 0, 0) \
.rectangle(-120, -120, 240, 240) \
.fill()
def image(self, ctx):
path = Quox.image_path(self.direction, self.step)
ctx.image(path, self.x, self.y, -1, -1)
@staticmethod
def coord(d):
if d == UP:
return (-20, -100)
elif d == LEFT:
return (-100, -20)
elif d == RIGHT:
return (100, 20)
elif d == DOWN:
return (20, 100)
def rect(self, ctx):
if self.step:
ctx = ctx.rgb(.1, .6, .3)
else:
ctx = ctx.rgb(.1, .3, .6)
ctx.rectangle(0, 0, *Quox.coord(self.direction)).fill()
def text(self, ctx):
msg = f"{self.x}, {self.y}"
ctx.font_size = 16.0
ctx.text_align = ctx.CENTER
ctx.rgb(1, 1, 1).move_to(0, -100).text(msg)
def think(self, state, Δ):
super().think(state, Δ)
self.update_delay(Δ)
def update_delay(self, Δ):
self.turn_delay -= Δ
self.step_delay -= Δ
self.move_delay -= Δ
if self.turn_delay <= 0:
old_delay = self.turn_delay
self.choose_direction()
self.choose_turn_delay(old_delay)
if self.step_delay <= 0:
self.step_delay = Quox.STEP_DELAY
self.step = (self.step + 1) & 3
if self.move_delay <= 0:
self.move_delay += Quox.MOVE_DELAY
self.move()
def choose_direction(self):
self.direction = self.random.direction()
def choose_turn_delay(self, subtract=0):
self.turn_delay = self.random.delay() + subtract
def at_edge(self):
return ((self.direction == UP and self.y <= Quox.TOP) or
(self.direction == DOWN and self.y >= Quox.BOTTOM) or
(self.direction == LEFT and self.x <= Quox.LEFT) or
(self.direction == RIGHT and self.x >= Quox.RIGHT))
def flip_direction(self):
if self.direction == UP:
self.direction = DOWN
elif self.direction == LEFT:
self.direction = RIGHT
elif self.direction == DOWN:
self.direction = UP
elif self.direction == RIGHT:
self.direction = LEFT
def move(self):
if self.at_edge():
self.flip_direction()
if self.direction == UP:
self.y -= 5
elif self.direction == LEFT:
self.x -= 5
elif self.direction == DOWN:
self.y += 5
elif self.direction == RIGHT:
self.x += 5
if __name__ == '__main__':
run_view(Quox(ApplicationContext()))