#galaxy.py
import random
from kivy import platform
from kivy.app import App
from kivy.core.window import Window
from kivy.graphics import Line, Rectangle, Color, Quad
from kivy.metrics import dp
from kivy.properties import NumericProperty, Clock
from kivy.uix.widget import Widget
class Galaxy(Widget):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.n_vlines = 7
self.n_hlines = 15
self.space_vlines = dp(150)
self.space_hlines = dp(100)
self.speed_hl = 10
self.step_hl = 0
self.clock = 0.2
self.speed_vl = 10
self.step_vl = 0
self.direction_vl = 1
self.click_press = False
self.start_x = 0
self.shift_x = 0
self.shift_y = 0
self.tiles = []
for i in range(12):
self.tiles.append({"x": 1, "y": i})
with self.canvas:
self.vlines = []
self.hlines = []
for i in range(self.n_vlines):
vline = Line(points=(0,0,0,100))
self.vlines.append(vline)
for j in range(self.n_hlines):
hline = Line(points=(0,0,100,0))
self.hlines.append(hline)
self.rect_l = Rectangle(pos =(0,0), size=(0,0))
self.rect_r = Rectangle(pos=(0, 0), size=(0, 0))
self.quads = []
Color(0,1,0)
for n in range(30):
quad = Quad()
quad.points = [0, 0, 0, 0, 0, 0, 0, 0]
self.quads.append((quad))
Clock.schedule_interval(self.update, self.clock)
if platform in ('linux', 'win', 'macosx'):
self._keyboard = Window.request_keyboard(self._keyboard_closed, self)
self._keyboard.bind(on_key_down=self._on_keyboard_down)
self._keyboard.bind(on_key_up=self._on_keyboard_up)
def on_size(self, *args):
self.update(0.2)
def on_touch_down(self, touch):
self.click_press = True
if touch.x < self.width/2:
self.rect_l.pos = (0, self.center_y-dp(50))
self.rect_l.size = (dp(100), dp(100))
self.direction_vl = abs(self.direction_vl)
self.update(0.2)
else:
self.rect_r.pos = (self.width-dp(100), self.center_y - dp(50))
self.rect_r.size = (dp(100), dp(100))
self.direction_vl = -abs(self.direction_vl)
self.update(0.2)
def on_touch_up(self, touch):
self.click_press = False
self.rect_l.size=(0,0)
self.rect_r.size = (0, 0)
def _keyboard_closed(self):
self._keyboard.unbind(on_key_down=self._on_keyboard_down)
self._keyboard.unbind(on_key_down=self._on_keyboard_up)
self._keyboard = None
def _on_keyboard_down(self, keyboard, keycode, text, modifiers):
#print("keyboard down")
self.click_press = True
if keycode[1] == 'left':
self.rect_l.pos = (0, self.center_y - dp(50))
self.rect_l.size = (dp(100), dp(100))
self.direction_vl = abs(self.direction_vl)
self.update(0.2)
elif keycode[1] == 'right':
self.rect_r.pos = (self.width - dp(100), self.center_y - dp(50))
self.rect_r.size = (dp(100), dp(100))
self.direction_vl = -abs(self.direction_vl)
self.update(0.2)
return True
def _on_keyboard_up(self, *args):
#print(*args)
#print("keyboard up")
self.rect_l.size = (0, 0)
self.rect_r.size = (0, 0)
self.click_press = False
return True
def perspective_transform(self, x, y):
#return x, y
ratio = (self.height-y)/self.height
tx = ratio*(self.center_x-x)
ty = ratio**2
return self.center_x-tx, 0.8*self.height*(1-ty)
def tile(self, a, b, n):
x0 = self.start_x + a * self.space_vlines + self.shift_x
y0 = b * self.space_hlines - self.shift_y
x1 = x0
y1 = y0 + self.space_hlines
x2 = x0 + self.space_vlines
y2 = y1
x3 = x2
y3 = y0
_, y0 = self.perspective_transform(x0, y0)
x0, _ = self.perspective_transform(x0, y0 / 0.8)
_, y1 = self.perspective_transform(x1, y1)
x1, _ = self.perspective_transform(x1, y1 / 0.8)
_, y2 = self.perspective_transform(x2, y2)
x2, _ = self.perspective_transform(x2, y2 / 0.8)
_, y3 = self.perspective_transform(x3, y3)
x3, _ = self.perspective_transform(x3, y3 / 0.8)
self.quads[n].points = [x0, y0, x1, y1, x2, y2, x3, y3]
def update(self, dt):
self.start_x = self.center_x - int(self.n_vlines / 2) * self.space_vlines
self.shift_x = self.speed_vl * self.step_vl
"""
if shift_x > self.width or shift_x < -self.width:
self.direction_vl = -self.direction_vl
"""
if self.click_press:
self.step_vl += self.direction_vl
for i in range(self.n_vlines):
x = self.start_x + self.space_vlines * i + self.shift_x
x1, y1, x2, y2 = x, 0, x, self.height
x1, y1 = self.perspective_transform(x1, y1)
x2, y2 = self.perspective_transform(x2, y2)
self.vlines[i].points = (x1, y1, x2, y2)
self.space_hlines = self.height / self.n_hlines
self.shift_y = self.speed_hl * self.step_hl
if self.shift_y > self.space_hlines:
self.step_hl = 0
if not self.click_press:
self.step_hl += 1
for j in range(self.n_hlines):
y = j * self.space_hlines - self.shift_y
x1, y1, x2, y2 = self.start_x + self.shift_x, y, self.width - self.start_x + self.shift_x, y
_, y1 = self.perspective_transform(x1, y1)
x1, _ = self.perspective_transform(x1, y1 / 0.8)
_, y2 = self.perspective_transform(x2, y2)
x2, _ = self.perspective_transform(x2, y2 / 0.8)
self.hlines[j].points = (x1, y1, x2, y2)
for i, tile in enumerate(self.tiles):
self.tile(tile["x"], tile["y"], i)
n_tiles = len(self.tiles)
if self.shift_y > self.space_hlines:
tile["y"] -= 1
if tile["y"] < 0:
del self.tiles[i]
self.quads[n_tiles-1].points = [0, 0, 0, 0, 0, 0, 0, 0]
if self.tiles[i+1]["y"] == 0:
del self.tiles[i+1]
self.quads[n_tiles-2].points = [0, 0, 0, 0, 0, 0, 0, 0]
tile_y = self.tiles[-1]["y"]
tile_x = self.tiles[-1]["x"] + random.randrange(-1, 2)
if tile_x < 0 or tile_x > self.n_vlines-2:
tile_x = self.tiles[-1]["x"]
if tile_x == self.tiles[-1]["x"]:
self.tiles.append({"x": tile_x, "y": tile_y + 1})
else:
self.tiles.append({"x": tile_x, "y": tile_y})
self.tiles.append({"x": tile_x, "y": tile_y + 1})
if self.shift_y > self.space_hlines:
self.shift_y = 0
print(self.tiles)
class GalaxyApp(App):
pass
GalaxyApp().run()
reference:
No comments:
Post a Comment