Monday, September 6, 2021

kivy 51 add ship

 
#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, Triangle
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 = 5
        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.05
        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.n_keydown = 0
        self.tiles = []
        for i in range(12):
            self.tiles.append({"x": 2, "y": i})

        with self.canvas:
            self.vlines = []
            self.hlines = []
            for i in range(self.n_vlines+1):
                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))
            Color(0,0,1)
            self.ship = Triangle()

        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(self.n_keydown)
        self.click_press = False
        if self.n_keydown>0: return False

        #print("keyboard down")
        if keycode[1] == 'left':
            self.click_press = True
            self.n_keydown += 1
            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.direction_vl = self.space_vlines/self.speed_hl

        elif keycode[1] == 'right':
            self.n_keydown += 1
            self.click_press = True
            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.direction_vl = -self.space_vlines/self.speed_hl

        return True

    def _on_keyboard_up(self, *args):
        #print(*args)
        #print("keyboard up")
        self.n_keydown=0
        self.update(0.2)
        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)+0.5) * 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 and self.n_keydown==0:
            self.step_vl += self.direction_vl

        for i in range(self.n_vlines+1):
            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})

        x0 = self.center_x - self.space_vlines/2
        y0 = self.space_hlines
        x1 = self.center_x
        y1 = self.space_hlines * 2
        x2 = self.center_x + self.space_vlines/2
        y2 = self.space_hlines

        _, 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)

        self.ship.points = [x0, y0, x1, y1, x2, y2]

        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