sketch.py
# -*- coding: utf-8 -*-
import pyxel
import math
from dataclasses import dataclass
N_POINTS = 100
@dataclass
class Vector:
x: float
y: float
def square_mag(self):
return self.x**2 + self.y**2
def mag(self):
return math.sqrt(self.mag())
def __add__(self, v):
return Vector(self.x + v.x, self.y + v.y)
def __sub__(self, v):
return Vector(self.x - v.x, self.y - v.y)
def __neg__(self):
return Vector(-self.x, -self.y)
neighbors_list = [
Vector(1, 0),
Vector(0, 1),
Vector(-1, 0),
Vector(0, -1),
]
def fill(v, c):
que = []
que.append(v)
def is_valid_pos(p):
return 0 <= p.x < pyxel.width and 0 <= p.y < pyxel.height
while len(que) > 0:
p = que.pop(0)
for q in neighbors_list:
r = p + q
if is_valid_pos(r) and pyxel.pget(r.x, r.y) == pyxel.COLOR_WHITE:
que.append(r)
pyxel.pset(r.x, r.y, c)
class App:
def __init__(self):
pyxel.init(128, 128, title='app')
self.scale = Vector(2.0, 2.0)
self.clicked_frame = 0
self.points = []
for k in range(N_POINTS):
t = 2.0 * math.pi * k / N_POINTS
x = 16.0 * math.sin(t) ** 3
y = -(13.0 * math.cos(t) - 5.0 * math.cos(2.0 * t)
- 2.0*math.cos(3.0 * t) - math.cos(4.0 * t))
self.points.append(Vector(x, y))
def run(self):
pyxel.run(self.update, self.draw)
def update(self):
if pyxel.btnp(pyxel.MOUSE_BUTTON_LEFT):
self.clicked_frame = pyxel.frame_count
t = (pyxel.frame_count - self.clicked_frame) / 30.0
self.scale.x = 2.0 + 0.5 * math.exp(-t) * math.cos(t * 10.0)
self.scale.y = 2.0 + 0.5 * math.exp(-t) * math.sin(t * 10.0)
def draw(self):
pyxel.cls(pyxel.COLOR_WHITE)
for k in range(N_POINTS - 1):
pyxel.line(
pyxel.width / 2 + self.points[k].x * self.scale.x,
pyxel.height / 2 + self.points[k].y * self.scale.y,
pyxel.width / 2 + self.points[k+1].x * self.scale.x,
pyxel.height / 2 + self.points[k+1].y * self.scale.y,
pyxel.COLOR_RED
)
# pyxel.fill is officially implemented in v1.6.8
# fill(Vector(pyxel.width / 2.0, pyxel.height / 2.0), pyxel.COLOR_RED)
pyxel.fill(pyxel.width / 2.0, pyxel.height / 2.0, pyxel.COLOR_RED)
if __name__ == '__main__':
app = App()
app.run()