Exemplo n.º 1
0
class Rect(GraphicalObject):
    """ Rectangle class representing a rectangle with a border. """
    def __init__(self, x, y):
        super().__init__('rect', x, y)
        self._width = 1
        self._height = 1
        self._group = InstructionGroup()
        self._rec_color = Color(1.0, 1.0, 1.0, 1.0)
        self._rec = Rectangle(pos=(x, y), size=(self._width, self._height))
        # self._x, self._y | self._x + self._width, self._y | self._x + self._width, self._y + self._height |
        # self._x, self._y + self._height
        self._group.add(self._rec_color)
        self._group.add(self._rec)

    """ Draws rectangle on canvas argument """

    def draw(self, canvas):
        canvas.add(self._group)

    def resize(self, x, y):
        self._rec.size = x - self._x, y - self._y

    def get_bounding_box(self):
        return self._x, self._y, self._width, self._height

    def is_within(self, x, y):
        pass
Exemplo n.º 2
0
 def group(self, color):
     rgb = InstructionGroup()
     color = Color(1, 1, 0)
     xyz = color
     rgb.add(xyz)
     rgb.add(Rectangle(pos=self.pos, size=self.size) )
     return rgb
Exemplo n.º 3
0
class BillboardDisplay(InstructionGroup):
    def __init__(self, pos, texture, size_x=1.0, size_y=1.0, intensity=1.0, Tr=1.0):
        super(BillboardDisplay, self).__init__()
        
        self.intensity = intensity
        self.Tr = Tr

        self.translate = Translate()
        self.rotate_azi = Rotate(origin=(0,0,0), axis=(0,1,0))
        self.rotate_ele = Rotate(origin=(0,0,0), axis=(1,0,0))
        self.scale = Scale()
        self.color_instruction = InstructionGroup()
        self.mesh = Mesh(
            texture=texture,
            vertices=rectangle_nurb.vertices,
            indices=rectangle_nurb.indices,
            fmt=rectangle_nurb.vertex_format,
            mode='triangles'
        )

        self.add(PushMatrix())
        self.add(self.translate)
        self.add(self.rotate_azi)
        self.add(self.rotate_ele)
        self.add(self.scale)
        self.add(self.color_instruction)
        self.add(self.mesh)
        self.add(PopMatrix())

        self.set_color(intensity=intensity, Tr=Tr)
        self.set_size(size_x, size_y)
        self.set_pos(pos)
        self.set_texture(texture)

    def set_texture(self, texture):
        self.texture = texture
        self.mesh.texture = texture

    def set_rotate(self, angles):
        self.rotate_azi.angle = angles[0] * 180/np.pi
        self.rotate_ele.angle = angles[1] * 180/np.pi

    def set_size(self, size_x, size_y):
        self.scale.xyz = (size_x, size_y, 1)

    def set_pos(self, pos):
        self.translate.xyz = pos

    def set_color(self, intensity=1.0, Tr=1.0):
        self.color_instruction.clear()
        self.color_instruction.add(
            ChangeState(
                Kd=(0.6, 0.6, 0.6),
                Ka=(0.8, 0.8, 0.8),
                Ks=(0.9, 0.9, 0.9),
                Tr=Tr,
                Ns=1.0,
                intensity=intensity
            )
        )
Exemplo n.º 4
0
 def group(self, color):
     rgb = InstructionGroup()
     color = Color(1, 1, 0)
     xyz = color
     rgb.add(xyz)
     rgb.add(Rectangle(pos=self.pos, size=self.size))
     return rgb
Exemplo n.º 5
0
class Piece(Button):
    index = ListProperty(None)
    color = StringProperty('blank')
    board_size = NumericProperty(None)
    is_dead = BooleanProperty(False)
    marker = None

    def place_piece(self, color):
        if color is None:
            self.color = 'blank'
        else:
            self.color = str(color)

    def update_marker(self, color):
        if color is None:
            if self.marker is not None:
                self.canvas.remove(self.marker)
        else:
            self.marker = InstructionGroup()
            self.marker.add(
                kColor(*((0, 0, 0) if color == Color.black else (1, 1, 1))))
            self.marker.add(
                Rectangle(pos=(self.pos[0] + (self.size[0] / 4) * 1.5,
                               self.pos[1] + (self.size[1] / 4) * 1.5),
                          size=(self.size[0] / 4, self.size[1] / 4)))
            self.canvas.add(self.marker)
Exemplo n.º 6
0
    def drawCrossLine(self, aIndex):
        """
        """
        dataNum = len(self.minTimeList)
        if dataNum == 0:
            return
        if aIndex >= dataNum:
            index = dataNum - 1
        elif aIndex < 0:
            index = 0
        else:
            index = aIndex
        self.crossLineIndex = index
        if self.infoFunc == None:
            self._showInfo(index)
        else:
            self.infoFunc(self.minTimeList[index])

        groupStr = self.instGroup + "cross_line"
        self.canvas.remove_group(groupStr)

        instg = InstructionGroup(group=groupStr)

        color = Color()
        color.rgba = self.CROSS_LINE_COLOR
        instg.add(color)
        x1 = self.start_xaxis + index * self.xscale
        y1 = self.volume_yaxis
        x2 = self.start_xaxis + index * self.xscale
        y2 = self.volume_yaxis + self.crossLine_height
        instg.add(Line(points=(x1, y1, x2, y2), width=1))
        self.canvas.add(instg)
Exemplo n.º 7
0
    def _drawLine(self, aValue, dispIdx, isLastFlag):
        """
        
        """
        groupStr = self.instGroup
        if isLastFlag == True:
            groupStr += "_lastData"
        else:
            groupStr += "_curvData"
        
        instg = InstructionGroup(group=groupStr)
        color = Color()

        if aValue > 0:
            color.rgba = self.UP_COLOR
        else:
            color.rgba = self.DOWN_COLOR
        instg.add(color)
        x1 = self.chartPos[0] + dispIdx * (self.tickWide + self.tickGap) + self.tickGap 
        y1 = self.chartPos[1] + self.baseYPos
        rectHeight = abs(aValue) * self.yscale
        if aValue < 0:
            y1 = y1 - rectHeight
        instg.add(Rectangle(pos=(x1,y1), size=(self.tickWide, rectHeight)))

        self.canvas.add(instg)
Exemplo n.º 8
0
class MyWidget(Widget):

    undolist = []
    objects = []
    drawing = False

    def on_touch_up(self, touch):
        self.drawing = False

    def on_touch_move(self, touch):
        if self.drawing:
            self.points.append(touch.pos)
            self.obj.children[-1].points = self.points
        else:
            self.drawing = True
            self.points = [touch.pos]
            self.obj = InstructionGroup()
            self.obj.add(Color(1, 1, 1))
            self.obj.add(Line())
            self.objects.append(self.obj)
            self.canvas.add(self.obj)

    def undo(self):
        item = self.objects.pop(-1)
        self.undolist.append(item)
        self.canvas.remove(item)

    def redo(self):
        item = self.undolist.pop(-1)
        self.objects.append(item)
        self.canvas.add(item)
Exemplo n.º 9
0
 def group(self, color):
     rgb = InstructionGroup()
     color = Color(1, 0, 0)
     xyz = color
     rgb.add(xyz)
     radius = sqrt(sqrt(sum([x * x for x in self.size])))
     rgb.add(Line(circle=(self.pos[0], self.pos[1], radius)))
     return rgb
Exemplo n.º 10
0
 def group(self, color):
     rgb = InstructionGroup()
     color = Color(1, 0, 0)
     xyz = color
     rgb.add(xyz)
     radius = sqrt(sqrt(sum([x*x for x in self.size])))
     rgb.add(Line(circle=(self.pos[0], self.pos[1], radius ) ) )
     return rgb
Exemplo n.º 11
0
class NurbDisplay(InstructionGroup):
    def __init__(self,
                 nurb,
                 pos,
                 size=1.0,
                 color=(0.0, 1.0, 0.0),
                 tr=1.0,
                 intensity=1.0):
        super(NurbDisplay, self).__init__()

        self.color = color
        self.tr = tr
        self.intensity = intensity

        self.translate = Translate()
        self.scale = Scale()
        self.color_instruction = InstructionGroup()

        self.add(PushMatrix())
        self.add(self.translate)
        self.add(self.scale)
        self.add(self.color_instruction)
        self.add(self.make_mesh(nurb))
        self.add(PopMatrix())

        self.set_color()
        self.set_size(size)
        self.set_pos(pos)

    def make_mesh(self, m):
        return Mesh(vertices=m.vertices,
                    indices=m.indices,
                    fmt=m.vertex_format,
                    mode='triangles')

    def set_size(self, size):
        self.scale.xyz = (size, size, size)

    def set_pos(self, pos):
        self.translate.xyz = pos

    def set_color(self, color=None, tr=None, intensity=None):
        if tr is not None:
            self.tr = tr
        if intensity is not None:
            self.intensity = intensity
        if color is not None:
            self.color = color

        self.color_instruction.clear()
        self.color_instruction.add(
            ChangeState(Kd=self.color,
                        Ka=self.color,
                        Ks=(0.3, 0.3, 0.3),
                        Tr=self.tr,
                        Ns=1.0,
                        intensity=self.intensity))
Exemplo n.º 12
0
 def __init__(self, **kwargs):
     super(SimulationWidget, self).__init__(**kwargs)
     self.nest_radius = 3
     self.old_window_size_x = 0
     self.old_window_size_y = 0
     self.cells = [[0 for y in range(HEIGHT)] for x in range(WIDTH + 1)]
     x, y = Window.size
     self.spacing_x = x / WIDTH
     self.spacing_y = y / HEIGHT
     self.meter_width = x / 2
     self.meter_bar = InstructionGroup()
     self.meter_bar.add(Color(1, 1, 1))
     self.meter_bar.add(
         RoundedRectangle(pos=[
             x / 2 - self.meter_width / 2, y - self.meter_height * 0.9
         ],
                          size=[self.meter_width, self.meter_height / 3]))
     self.meter_indicator.source = os.path.join(ROOT_PATH, "indicator.png")
     self.meter_backdrop.source = os.path.join(ROOT_PATH,
                                               "indicator_backdrop.png")
     self.meter_backdrop.pos = [
         x / 2 - self.meter_backdrop.size[0] / 2,
         y - self.meter_height * 1.2
     ]
     self.meter_indicator.pos = [
         x / 2 - self.meter_indicator.size[0] / 2,
         y - self.meter_height * 1.2
     ]
     self.meter_backdrop.size = [self.meter_height, self.meter_height]
     self.meter_indicator.size = [self.meter_height, self.meter_height]
     self.meter_backdrop.color = interpolate_color(self.p1_color,
                                                   self.p2_color, 0.5)
     self.sides = InstructionGroup()
     self.sides.add(Color(rgb=self.p1_color))
     self.sides.add(Rectangle(pos=[0, 0], size=[self.bar_width, y]))
     self.sides.add(Color(rgb=self.p2_color))
     self.sides.add(
         Rectangle(pos=[x - self.bar_width, 0], size=[self.bar_width, y]))
     x = 0
     y = -1
     count = 0
     for i in range(0, len(WORLD_DATA), INTS_PER_FIELD):
         x = (i - (count * INTS_PER_FIELD) + count) % WIDTH
         count += 1
         if x % WIDTH == 0:
             y += 1
         y_inverted = HEIGHT - y - 1
         g = InstructionGroup()
         g.add(Color(0, 0, 0, 1))  # black
         g.add(
             Rectangle(pos=(x * self.spacing_x,
                            y_inverted * self.spacing_y),
                       size=(self.spacing_x, self.spacing_y)))
         self.ids["grid_layout"].canvas.add(g)
         self.cells[x][y_inverted] = g
     self.ids["grid_layout"].canvas.add(self.sides)
     self.ids["grid_layout"].canvas.add(self.meter_bar)
Exemplo n.º 13
0
class NurbDisplay(InstructionGroup):
    def __init__(self, nurb, pos, size=1.0, color=(0.0,1.0,0.0), tr=1.0, intensity=1.0):
        super(NurbDisplay, self).__init__()
        
        self.color = color
        self.tr = tr
        self.intensity = intensity

        self.translate = Translate()
        self.scale = Scale()
        self.color_instruction = InstructionGroup()

        self.add(PushMatrix())
        self.add(self.translate)
        self.add(self.scale)
        self.add(self.color_instruction)
        self.add(self.make_mesh(nurb))
        self.add(PopMatrix())

        self.set_color()
        self.set_size(size)
        self.set_pos(pos)

    def make_mesh(self, m):
        return Mesh(
            vertices=m.vertices,
            indices=m.indices,
            fmt=m.vertex_format,
            mode='triangles'
        )

    def set_size(self, size):
        self.scale.xyz = (size, size, size)

    def set_pos(self, pos):
        self.translate.xyz = pos

    def set_color(self, color=None, tr=None, intensity=None):
        if tr is not None:
            self.tr = tr
        if intensity is not None:
            self.intensity = intensity
        if color is not None:
            self.color = color

        self.color_instruction.clear()
        self.color_instruction.add(
            ChangeState(
                Kd=self.color,
                Ka=self.color,
                Ks=(0.3, 0.3, 0.3),
                Tr=self.tr,
                Ns=1.0,
                intensity=self.intensity
            )
        )
Exemplo n.º 14
0
class Cell(Widget):
    def __init__(self, i, text, **kwargs):
        super(Cell, self).__init__(**kwargs)

        self.ig = InstructionGroup()
        self.rect = Rectangle()
        self.text = text
        self.color = Color(0.2, 0.2, 0.2 * i)
        self.ig.add(self.color)
        self.ig.add(self.rect)
Exemplo n.º 15
0
class MyWidget(Widget):

    undolist = []
    objects = []
    drawing = False
    eraser = False

    def on_touch_up(self, touch):
        self.drawing = False

    def on_touch_move(self, touch):
        if self.eraser == False:
            if self.drawing:
                self.points.append(touch.pos)
                self.obj.children[-1].points = self.points
            else:
                self.drawing = True
                self.points = [touch.pos]
                print(self.points)
                self.obj = InstructionGroup()
                self.obj.add(Color(0, 0, 0))
                self.obj.add(Line(width=2.5))
                self.objects.append(self.obj)
                self.canvas.add(self.obj)
        else:
            for obj in self.objects:
                for point in obj.children[-1].points:
                    #                    if point.
                    templine = Line(width=2.5, points=[touch.pos])
                    if point == (templine.points[0], templine.points[1]):
                        print(obj.children[-1].points)
                        self.canvas.remove(obj)
                        obj.children[-1].points.remove(point)
                        print(obj.children[-1].points)
                        self.canvas.add(obj)

    def toggleEraser(self):
        if self.eraser == False:
            print("Eraser on")
            self.eraser = True
        else:
            print("Eraser off")
            self.eraser = False

    def undo(self):
        item = self.objects.pop(-1)
        self.undolist.append(item)
        self.canvas.remove(item)

    def redo(self):
        item = self.undolist.pop(-1)
        self.objects.append(item)
        self.canvas.add(item)
Exemplo n.º 16
0
class BeatBar(FloatLayout):
    num_beats = NumericProperty(4)

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.beatmarkers = InstructionGroup()
        for i in range(self.num_beats):
            beatmarker = BeatMarker()
            self.beatmarkers.add(beatmarker)
        self.canvas.add(self.beatmarkers)

    def on_num_beats(self, instance, num_beats):
        while num_beats > len(self.beatmarkers.children):
            beatmarker = BeatMarker()
            self.beatmarkers.add(beatmarker)
        while num_beats < len(self.beatmarkers.children):
            self.beatmarkers.children.pop()
        self.update_beatmarkers()

    def on_size(self, *args):
        self.update_beatmarkers()

    def on_pos(self, *args):
        # Needed for slide up menu.
        self.update_beatmarkers()

    def update_beatmarkers(self):
        target_ratio = self.num_beats / 1
        aspect_ratio = self.width / self.height
        percent_radius = 0.6  # circle shouldn't take up the whole square
        if aspect_ratio > target_ratio:
            side = self.height
            r = side / 2 * percent_radius
            rdiff = side / 2 - r
            dx = (self.width - (self.num_beats * side)) / 2
            cx, cy = self.x + dx + rdiff, self.y + rdiff
            step_x = side
            for beatmarker in self.beatmarkers.children:
                beatmarker.pos = [cx, cy]
                beatmarker.size = [2*r, 2*r]
                cx += step_x
        else:
            side = self.width / self.num_beats
            r = side / 2 * percent_radius
            rdiff = side / 2 - r
            dy = (self.height - side) / 2
            cx, cy = self.x + rdiff, self.y + dy + rdiff
            step_x = side
            for beatmarker in self.beatmarkers.children:
                beatmarker.pos = [cx, cy]
                beatmarker.size = [2*r, 2*r]
                cx += step_x
Exemplo n.º 17
0
    def drawVolumeGraph(self, data, curIndex):
        instg = InstructionGroup(group="data")
        volume = data.get("vol")
        color = Color()
        color.rgba = self.VOLUME_COLOR
        instg.add(color)

        x1 = int(self.pos[0] + self.shift_left + curIndex * self.xscale)
        y1 = int(self.pos[1] + self.shift_bottom)
        x2 = int(self.pos[0] + self.shift_left + curIndex * self.xscale)
        y2 = int(self.pos[1] + self.shift_bottom + volume * self.vscale)
        instg.add(Line(points=(x1, y1, x2, y2), width=1))
        self.canvas.add(instg)
Exemplo n.º 18
0
class BackgroundLabel(Label):
    def __init__(self, **kwargs):
        super(BackgroundLabel, self).__init__(**kwargs)
        self.IG = InstructionGroup()
        self.background_color = (0, 0, 0, 1)
        self.color = (1, 1, 1, 1)

    def Set_Background_Color(self):
        self.opacity = 1
        self.IG.clear()
        self.IG.add(Color(rgba=(self.background_color)))
        self.IG.add(Rectangle(size=(self.size), pos=(self.pos)))
        self.canvas.before.add(self.IG)
Exemplo n.º 19
0
 async def draw_rect(self, touch):
     from kivy.graphics import Line, Color, Rectangle, InstructionGroup
     from kivy.utils import get_random_color
     inst_group = InstructionGroup()
     self.canvas.add(inst_group)
     inst_group.add(Color(*get_random_color()))
     line = Line(width=2)
     inst_group.add(line)
     ox, oy = self.to_local(*touch.opos)
     on_touch_move_was_fired = False
     async for __ in ak.rest_of_touch_moves(self, touch):
         # Don't await anything during this async-for-loop
         on_touch_move_was_fired = True
         x, y = self.to_local(*touch.pos)
         min_x = min(x, ox)
         min_y = min(y, oy)
         max_x = max(x, ox)
         max_y = max(y, oy)
         line.rectangle = [min_x, min_y, max_x - min_x, max_y - min_y]
     if on_touch_move_was_fired:
         inst_group.add(Color(*get_random_color(alpha=.3)))
         inst_group.add(
             Rectangle(
                 pos=(min_x, min_y),
                 size=(
                     max_x - min_x,
                     max_y - min_y,
                 ),
             ))
     else:
         self.canvas.remove(inst_group)
Exemplo n.º 20
0
    def drawCrossLine(self, index):
        if self.dataList == None or index >= len(self.dataList):
            return

        data = self.dataList[index]

        price = data.get("price")

        color = Color()
        color.rgba = self.CROSS_LINE_COLOR

        self.canvas.remove_group("cross_line")

        instg = InstructionGroup(group="cross_line")
        instg.add(color)
        x1 = int(self.pos[0] + self.shift_left + index * self.xscale)
        y1 = self.pos[1] + self.shift_bottom
        x2 = int(self.pos[0] + self.shift_left + index * self.xscale)
        y2 = self.pos[1] + self.height - self.shift_top
        instg.add(Line(points=(x1, y1, x2, y2), width=1))
        self.canvas.add(instg)

        instg = InstructionGroup(group="cross_line")
        instg.add(color)
        x1 = self.pos[0] + self.shift_left
        y1 = int(self.pos[1] + self.shift_bottom +
                 (price - self.min_price) * self.yscale)
        x2 = self.pos[0] + self.width - self.shift_right
        y2 = int(self.pos[1] + self.shift_bottom +
                 (price - self.min_price) * self.yscale)
        instg.add(Line(points=(x1, y1, x2, y2), width=1))
        self.canvas.add(instg)
Exemplo n.º 21
0
 def drawCordFrame(self):
     
     # 畫一條橫線
     instg = InstructionGroup(group="frame")
     frameColor = Color()
     frameColor.rgba = self.FRAME_COLOR
     instg.add(frameColor)
     x1 = int(self.pos[0] + self.shift_left)
     y1 = int(self.pos[1] + self.shift_bottom)
     x2 = int(self.pos[0] + self.width - self.shift_right)
     y2 = int(self.pos[1] + self.shift_bottom)
     instg.add(Line(points=(x1, y1, x2, y2), width=1))        
     self.canvas.add(instg)
     
     # 畫一條豎線
     instg = InstructionGroup(group="frame")
     instg.add(frameColor)
     center_pos = int(self.pillarPoint / 2)
     self.center_xpos = int(self.pos[0] + self.shift_left + (self.min_tickNum * -1) * self.pillarSumPoint + self.ycordWidth + center_pos)
     x1 = self.center_xpos
     y1 = int(self.pos[1] + self.shift_bottom)
     x2 = self.center_xpos
     y2 = int(self.pos[1] + self.height - self.shift_top)
     instg.add(Line(points=(x1, y1, x2, y2), width=1))
     self.canvas.add(instg)
Exemplo n.º 22
0
 async def draw_rect(self, touch):
     from kivy.graphics import Line, Color, Rectangle, InstructionGroup
     from kivy.utils import get_random_color
     inst_group = InstructionGroup()
     self.canvas.add(inst_group)
     inst_group.add(Color(*get_random_color()))
     line = Line(width=2)
     inst_group.add(line)
     ox, oy = x, y = self.to_local(*touch.opos)
     async for __ in ak.rest_of_touch_moves(self,
                                            touch,
                                            stop_dispatching=True):
         # Don't await anything during the iteration
         x, y = self.to_local(*touch.pos)
         min_x, max_x = (x, ox) if x < ox else (ox, x)
         min_y, max_y = (y, oy) if y < oy else (oy, y)
         line.rectangle = (
             min_x,
             min_y,
             max_x - min_x,
             max_y - min_y,
         )
     if x == ox and y == oy:
         self.canvas.remove(inst_group)
     else:
         inst_group.add(Color(*get_random_color(alpha=.3)))
         inst_group.add(
             Rectangle(
                 pos=(min_x, min_y),
                 size=(
                     max_x - min_x,
                     max_y - min_y,
                 ),
             ))
Exemplo n.º 23
0
    def __get_dbg_aabb_gfx(self):
        if self.__dbg_aabb is None:
            c = Color(0.8, 0.8, 0.8, 0.3)
            r = Rectangle()
            group = InstructionGroup()
            for instruction in (c, r):
                group.add(instruction)

            def update_r(_, ((left, bottom), (right, top))):
                r.pos = (left, bottom)
                r.size = (right - left, top - bottom)

            self.bind(aabb=update_r)
            update_r(None, self.aabb)
            self.__dbg_aabb = group
Exemplo n.º 24
0
    def __get_dbg_viewport_gfx(self):
        if self.__dbg_viewport is None:
            c = Color(1, 1, 1, 0.5)
            r = Rectangle()
            group = InstructionGroup()
            for instruction in (c, r):
                group.add(instruction)

            def update_r(_, __):
                r.pos = self.viewport_pos
                r.size = self.viewport_size

            self.bind(viewport_pos=update_r, viewport_size=update_r)
            update_r(None, None)
            self.__dbg_viewport = group
        return self.__dbg_viewport
Exemplo n.º 25
0
 def _drawVolumeLine(self, aDict, aIdx, isLastFlag):
     groupStr = self.instGroup
     if isLastFlag == True:
         groupStr += "volume_lastData"
     else:
         groupStr += "volume_curvData"
     instg = InstructionGroup(group=groupStr)
     color = Color()
     color.rgba = self.VOLUME_COLOR
     instg.add(color)
     x1 = self.start_xaxis + aIdx * self.xscale
     y1 = self.volume_yaxis
     x2 = x1
     y2 = self.volume_yaxis + aDict.get("Vol") * self.volume_yscale
     instg.add(Line(points=(x1, y1, x2, y2), width=1))
     self.canvas.add(instg)
Exemplo n.º 26
0
    def draw_line_preview(self, points, close):
        try:
            if len(self.lines) > 1:
                item = self.lines.pop(0)
                self.canvas.remove(item)

            line = InstructionGroup()
            line.add(
                Color(self.tool_color[0], self.tool_color[1],
                      self.tool_color[2], self.tool_color[3]))
            line.add(
                Line(points=(points), width=(self.tool_size / 2), close=close))
            self.lines.append(line)
            self.canvas.add(line)
        except:
            pass
Exemplo n.º 27
0
    def draw_fig(self):
        #traverse points to draw line of figure
        coords = []

        for p in self.points_as_added:
            coords.append(p.a_point_x)
            coords.append(p.a_point_y)

        self.canvas.remove(self.line_draw)
        new_line = InstructionGroup()
        new_line.add(
            Color(rose_50[0], rose_50[1], rose_50[2], rose_50[3], mode='rgba'))
        new_line.add(Line(points=coords, close=True, width=2))
        self.line_draw = new_line
        self.canvas.add(self.line_draw)
        return
Exemplo n.º 28
0
class NoteDisplay(InstructionGroup):
    def __init__(self, note_data, planes, ac):
        super(NoteDisplay, self).__init__()
        self.note = note_data
        self.planes = sorted(planes)
        self.ac = ac
        self.sound_count = 0
        self.past_me = False

        self.sounds = []
        self.sound_group = InstructionGroup()
        self.color = COLORS[self.note.pitch % 12]
        self.intensity = self.note.velocity

        self.texture_indices = [(self.color, i)  for i in range(100) +list(reversed(xrange(1,101)))]
        self.texture_frame = np.random.randint(len(self.texture_indices))
        self.billboard = BillboardDisplay(self.pos_from_tick(ac.tick), texture=textures[self.texture_indices[0]], size_x=2.0, size_y=2.0, intensity=self.intensity)
        self.add(self.sound_group)
        self.add(self.billboard)

    def pos_from_tick(self, tick):
        z = - (self.note.tick - tick) * config['UNITS_PER_TICK']
        x = config['LINE_SPACING'] * self.note.x
        y = config['LINE_SPACING'] * self.note.y
        return (x, y, z)

    def set_pos(self, pos):
        self.billboard.set_pos(pos)

    def sound(self, tick, pos):
        # Play Sound
        self.ac.play_note(tick, self.note, pos)

        # Render Sound
        exp_time = max(self.note.duration * 60 / (480 * self.ac.scheduler.cond.bpm), 0.2)
        sound_display = SoundDisplay(pos, exp_time, self)
        self.sounds.append(sound_display)
        self.sound_group.add(sound_display)

    def on_update(self, dt, tick, angles):
        self.texture_frame += 1
        self.billboard.set_texture(textures[self.texture_indices[int(self.texture_frame) % len(self.texture_indices)]])
        self.billboard.set_rotate(angles)
        for s in self.sounds:
            if not s.on_update(dt, tick, angles):
                self.sounds.remove(s)
                self.sound_group.remove(s)
Exemplo n.º 29
0
    def drawCrossLine(self, aIndex):
        """
        """
        dataNum = len(self.dataDict)
        if dataNum == 0:
            return
        if aIndex >= self.dispMax:
            index = self.dispMax - 1
        elif aIndex >= self.dispNum:
            index = self.dispNum - 1
        elif aIndex < 0:
            index = 0
        else:
            index = aIndex
        self.crossLineIndex = index
        if self.infoFunc == None:
            self._showInfo(index)
        else:
            aKey = self.keyList[self.scopeIdx[0] + index]
            aDict = self.dataDict.get(aKey)
            refDict = {}
            for aKey in aDict.keys():
                refDict[aKey] = aDict.get(aKey)
            refDict["TechType"] = self.techType
            self.infoFunc(refDict)

        if self.isDrawCrossLine == False:
            return
        groupStr = self.instGroup + "cross_line"
        self.canvas.remove_group(groupStr)

        color = Color()
        color.rgba = self.CROSS_LINE_COLOR

        instg = InstructionGroup(group=groupStr)
        instg.add(color)
        x1 = self.chartPos[0] + (index + 1) * (self.tickWide +
                                               self.tickGap) - self.backGap
        y1 = self.chartPos[1]
        x2 = x1
        y2 = self.chartPos[1] + self.chartSize[1]
        instg.add(Line(points=(x1, y1, x2, y2), width=1))
        self.canvas.add(instg)

        aKey = self.keyList[self.scopeIdx[0] + index]
        aDict = self.dataDict.get(aKey)

        instg = InstructionGroup(group=groupStr)
        instg.add(color)
        x1 = self.chartPos[0]
        y1 = self.chartPos[1] + (aDict.get("VOL") -
                                 self.lowestValue) * self.yscale
        x2 = self.chartPos[0] + self.chartSize[0]
        y2 = y1
        instg.add(Line(points=(x1, y1, x2, y2), width=1))
        self.canvas.add(instg)
Exemplo n.º 30
0
class MyWidget(Widget):

    def __init__(self, **kwargs):
        super(MyWidget, self).__init__(**kwargs)

        self.ig = InstructionGroup()
        self.line = Line(points=[100, 200, 300, 400])
        self.ig.add(self.line)
        self.canvas.add(self.ig)

        Thread(target=self.draw).start()


    def draw(self):
        while True:
            self.line.points = [randint(0,400) for i in range(4)]
            time.sleep(0.5)
Exemplo n.º 31
0
class ErrorPiece(Piece):
    def __init__(self, **kwargs):
        super(ErrorPiece, self).__init__(**kwargs)

        self.highlight = False

    def on_parent(self, *args):
        if self.parent:
            Clock.schedule_interval(self.update, .5)

    def on_keypress(self, keyboard, keycode, text, modifiers):
        return True

    def do_layout(self, *args):
        super(ErrorPiece, self).do_layout(*args)
        self.update()

    def update(self, *args):
        if hasattr(self, 'outline'):
            self.canvas.before.remove(self.outline)

        self.outline = InstructionGroup()
        if self.highlight:
            for child in self.children[:]:
                self.outline.add(Color(1, .2, .2, .8))
                self.outline.add(Line(
                points=[
                    child.x - 1, child.y - 1,
                    child.right + 1, child.y - 1,
                    child.right + 1, child.top + 1,
                    child.x - 1, child.top + 1
                ],
                close=True,
                width=1.5
            ))

            if self.canvas.before:
                self.canvas.before.add(self.outline)

            self.highlight = False
        else:
            self.canvas.before.remove(self.outline)

            self.highlight = True
Exemplo n.º 32
0
class KidDrawingScreen(Screen):
    undolist = []
    objects = []
    drawing = False

    def on_touch_up(self, touch):
        self.drawing = False

    def on_touch_down(self, touch):
        super(KidDrawingScreen, self).on_touch_down(touch)

        with self.canvas:
            Color(random(), random(), random())  #색 랜덤으로 바꾸기
            self.line = Line(points=[touch.pos[0], touch.pos[1]],
                             width=2)  #포인터 위치 지정

    def on_touch_move(self, touch):
        if self.drawing:
            self.points.append(touch.pos)
            self.obj.children[-1].points = self.points
        else:
            self.drawing = True
            self.points = [touch.pos]
            self.obj = InstructionGroup()
            self.obj.add(Color(random(), random(), random()))
            self.obj.add(Line(width=2))
            self.objects.append(self.obj)
            self.canvas.add(self.obj)

    def undo(self):
        if len(self.objects) != 0:
            item = self.objects.pop(-1)
            self.undolist.append(item)
            self.canvas.remove(item)

    def clear_canvas(
            self
    ):  # 캔퍼스를 지우는 기능. 캔퍼스는 투명도 0으로 만드어놨기때문에 보이지는 않지만, 지우는 기능은 가능하다.
        self.canvas.clear()

    def Ss(self):
        timestr = time.strftime("%Y%m%d_%H%M%S")
        self.export_to_png(f"{dirname(__file__)}\draw\IMG_" + timestr + ".png")
Exemplo n.º 33
0
    def __init__(self, **kwargs):
        super(ResizableCursor, self).__init__(**kwargs)
        self.size_hint = (None, None)
        self.pos_hint = (None, None)
        self.source = ''
        self.rect = Rectangle(pos=(-9998,-9998), size=(1, 1))
        self.size = (dp(22), dp(22))
        self.pos = [-9998, -9998]

        # Makes an instruction group with a rectangle and
        # loads an image inside it
        # Binds its properties to mouse positional changes and events triggered
        instr = InstructionGroup()
        instr.add(self.rect)
        self.canvas.after.add(instr)
        self.bind(pos=lambda obj, val: setattr(self.rect, 'pos', val))
        self.bind(source=lambda obj, val: setattr(self.rect, 'source', val))
        self.bind(hidden=lambda obj, val: self.on_mouse_move(Window.mouse_pos))
        Window.bind(mouse_pos=lambda obj, val: self.on_mouse_move(val))
    def __init__(self, **kwargs):
        super(ResizeCursor, self).__init__(**kwargs)
        self.size_hint = (None, None)
        self.pos_hint = (None, None)
        self.source = ''
        self.rect = Rectangle(pos=(-9998, -9998), size=(1, 1))
        self.size = (dp(22), dp(22))
        self.pos = [-9998, -9998]

        # Makes an instruction group with a rectangle and
        # loads an image inside it
        # Binds its properties to mouse positional changes and events triggered
        instr = InstructionGroup()
        instr.add(self.rect)
        self.canvas.after.add(instr)
        self.bind(pos=lambda obj, val: setattr(self.rect, 'pos', val))
        self.bind(source=lambda obj, val: setattr(self.rect, 'source', val))
        self.bind(hidden=lambda obj, val: self.on_mouse_move(Window.mouse_pos))
        Window.bind(mouse_pos=lambda obj, val: self.on_mouse_move(val))
Exemplo n.º 35
0
def selection(widget, select=False):
    """Emphasizes the widget adding a clear transparent background.

    Args:
        widget (Widget): the widget to apply selection to
        select (bool, optional): Apply selection. Defaults to False.
    """
    group = len(widget.canvas.get_group('sel')) > 0
    if not group:
        sel = InstructionGroup(group='sel')
        sel.add(Color(1, 1, 1, 0.3))
        sel.add(Rectangle(pos=widget.pos, size=widget.size))
    with widget.canvas:
        if select and not group:
            widget.canvas.add(sel)
        elif not select and group:
            widget.canvas.remove_group('sel')
        else:
            pass  # Nothing to do here!
Exemplo n.º 36
0
class ErrorPiece(Piece):
    def __init__(self, **kwargs):
        super(ErrorPiece, self).__init__(**kwargs)

        self.highlight = False

    def on_parent(self, *args):
        if self.parent:
            Clock.schedule_interval(self.update, .5)

    def on_keypress(self, keyboard, keycode, text, modifiers):
        return True

    def do_layout(self, *args):
        super(ErrorPiece, self).do_layout(*args)
        self.update()

    def update(self, *args):
        if hasattr(self, 'outline'):
            self.canvas.before.remove(self.outline)

        self.outline = InstructionGroup()
        if self.highlight:
            for child in self.children[:]:
                self.outline.add(Color(1, .2, .2, .8))
                self.outline.add(
                    Line(points=[
                        child.x - 1, child.y - 1, child.right + 1, child.y - 1,
                        child.right + 1, child.top + 1, child.x - 1,
                        child.top + 1
                    ],
                         close=True,
                         width=1.5))

            if self.canvas.before:
                self.canvas.before.add(self.outline)

            self.highlight = False
        else:
            self.canvas.before.remove(self.outline)

            self.highlight = True
Exemplo n.º 37
0
 def _drawLine(self, preValue, aValue, dispIdx, isLastFlag):
     """
     繪製曲線
     """
     groupStr = self.instGroup
     if isLastFlag == True:
         groupStr += "_lastData"
     else:
         groupStr += "_curvData"    
     instg = InstructionGroup(group=groupStr)
     color = Color()
     color.rgba = self.CURV_COLOR
     instg.add(color)
     #(self.tickWide + self.tickGap)代表顯示一筆資料,在x軸方向所需的總點數
     x1 = self.chartPos[0] + dispIdx * (self.tickWide + self.tickGap) - self.backGap
     y1 = self.chartPos[1] + (preValue - self.lowestValue) * self.yscale
     x2 = x1 + (self.tickWide + self.tickGap)
     y2 = self.chartPos[1] + (aValue - self.lowestValue) * self.yscale
     instg.add(Line(points=(x1, y1, x2, y2), width=1))
     self.canvas.add(instg)
Exemplo n.º 38
0
    def __get_dbg_origin_gfx(self):
        if self.__dbg_origin is None:
            c1 = Color(1, 0, 0, 0.5)
            r1 = Rectangle()
            c2 = Color(0, 1, 0, 0.5)
            r2 = Rectangle()
            c3 = Color(0, 0, 1, 0.5)
            e = Ellipse()
            group = InstructionGroup()
            for instruction in (c1, r1, c2, r2, c3, e):
                group.add(instruction)

            def update_geom(_, (w, h)):
                r1.size = (w, 0.1 * h)
                r2.size = (0.1 * w, h)
                e.size = (0.5 * w, 0.5 * h)
                e.pos = (0.25 * w, 0.25 * h)

            self.bind(viewport_size=update_geom)
            update_geom(None, self.size)
            self.__dbg_origin = group
Exemplo n.º 39
0
class PrinterAnimation(RelativeLayout):
    padding = NumericProperty(40)

    printer_actual_dimensions = ListProperty([10, 10, 80])
    printer_current_actual_height = NumericProperty(0.0)

    print_area_height = NumericProperty(1)
    print_area_width = NumericProperty(1)
    print_area_left = NumericProperty(0)
    print_area_bottom = NumericProperty(40)

    container_padding = NumericProperty(0)
    container_left = NumericProperty(0)
    container_width = NumericProperty(0)
    container_bottom = NumericProperty(0)
    container_height = NumericProperty(0)

    laser_size = ListProperty([40, 40])

    resin_height = NumericProperty(20)
    water_height = NumericProperty(20)

    scale = NumericProperty(1.0)

    resin_color = ListProperty([0.0, 0.8, 0.0, 0.6])
    water_color = ListProperty([0.2, 0.2, 1.0, 0.6])
    container_color = ListProperty([1.0, 1.0, 1.0, 1.0])
    laser_color_edge2 = ListProperty([0.0, 0.0, 0.5, 1.0])
    laser_color_edge = ListProperty([0.0, 0.0, 1.0, 1.0])
    laser_color = ListProperty([0.7, 1.0, 1.0, 1.0])

    drip_history = ListProperty()
    laser_points = ListProperty()

    middle_x = NumericProperty(52)

    laser_pos = NumericProperty(60)
    laser_speed = NumericProperty(1)
    refresh_rate = NumericProperty(1.0)

    def __init__(self, **kwargs):
        super(PrinterAnimation, self).__init__(**kwargs)
        self.drip_time_range = 5
        self.waiting_for_drips = True
        self.refresh_rate = App.get_running_app().refresh_rate
        self._gl_setup()
        self.axis_history = []
        self.drips = 0

        self.line_x = []
        self.line_y = []
        self.last_height = 0.0
        self.min_height = 0.0
        self.last_x_min = 0.0
        self.last_x_max = 1.0
        self.is_on_canvas = False

    def on_printer_actual_dimensions(self, instance, value):
        self.min_height = self.printer_actual_dimensions[2] / 400.0
        self.on_size(None)

    def _gl_setup(self):
        self.drip_texture = CoreImage("resources/images/drop.png", mipmap=True).texture
        self.drips_instruction = InstructionGroup()
        self.model_instruction = InstructionGroup()
        print(self.canvas.children)
        # self.canvas.add(self.drips_instruction)
        # self.canvas.add(self.model_instruction)

    def on_size(self, *largs):
        bounds_y = (self.height * 0.7) - self.resin_height
        bounds_x = self.width - (self.padding * 2)
        printer_x = self.printer_actual_dimensions[0]
        printer_y = self.printer_actual_dimensions[2]
        self.laser_pos = self.width / 2

        self.scale = min(bounds_y / printer_y, bounds_x / printer_x)
        Logger.info("Scale: {}".format(self.scale))
        self.print_area_width = printer_x * self.scale
        self.print_area_height = printer_y * self.scale

    def redraw(self, key):
        self._draw_drips()
        self._draw_laser()
        self._draw_model()
        if not self.is_on_canvas:
            self.canvas.insert(4, self.drips_instruction)
            self.canvas.insert(4, self.model_instruction)
            self.is_on_canvas = True

        Clock.unschedule(self.redraw)
        Clock.schedule_once(self.redraw, self.refresh_rate)

    def animation_start(self, *args):
        Clock.unschedule(self.redraw)
        self.axis_history = []
        self.line_x = []
        self.line_y = []
        self.last_height = 0
        self.min_height = 0.0
        self.laser_points = []
        self.drip_history = []
        Clock.schedule_once(self.redraw, self.refresh_rate)

    def animation_stop(self):
        Clock.unschedule(self.redraw)
        self.axis_history = []
        self.line_x = []
        self.line_y = []
        self.last_height = 0
        self.min_height = 0.0
        self.laser_points = []
        self.drip_history = []

    def _draw_drips(self):
        self.drips_instruction.clear()
        self.drips_instruction.add(Color(1, 1, 1, 1))
        top = time.time()
        bottom = top - self.drip_time_range
        drips_in_history = len(self.drip_history)
        for (index, drip_time) in zip(range(drips_in_history, 0, -1), self.drip_history):
            if drip_time > bottom:
                time_ago = top - drip_time
                y_pos_percent = (self.drip_time_range - time_ago) / self.drip_time_range
                drip_pos_y = (self.height * y_pos_percent) + self.padding
                xoff = 10 + math.sin((len(self.drip_history) - index) / (2 * math.pi)) * 20
                self.drips_instruction.add(Rectangle(size=[12, 16], pos=[self.print_area_left + xoff, drip_pos_y], texture=self.drip_texture))

    def _draw_laser(self):
        if self.waiting_for_drips:
            self.laser_points = []
        else:
            x_min = self.print_area_left + (self.last_x_min * self.print_area_width)
            x_max = self.print_area_left + (self.last_x_max * self.print_area_width)
            if (self.laser_pos >= x_max):
                self.laser_pos = x_max
                self.laser_speed = abs(self.laser_speed) * -1
            if (self.laser_pos <= x_min):
                self.laser_pos = x_min
                self.laser_speed = abs(self.laser_speed)

            self.laser_pos += self.laser_speed
            laser_x = self.laser_pos
            self.laser_points = [self.middle_x, self.height - self.padding,
                                 laser_x,          self.water_height + self.print_area_bottom + self.resin_height]

    def _draw_model(self):
            if self.axis_history:
                model_height = self.axis_history[-1][2]
                if model_height > (self.last_height + self.min_height) or not self.line_x:
                    x1, y1, x2, y2 = self._get_pixels(self.axis_history[-1])
                    self.last_x_min = x1
                    self.last_x_max = x2

                    self.line_x.insert(0, x1)
                    self.line_x.append(x2)
                    self.line_y.insert(0, y1)
                    self.line_y.append(y2)
                    self.last_height = model_height

                    points = []
                    for idx in range(0, len(self.line_x)):
                        x = int(self.print_area_left + (self.line_x[idx] * self.print_area_width))
                        y = int(self.print_area_bottom + self.resin_height + (self.line_y[idx] * self.print_area_height)) - 2
                        points.append(x)
                        points.append(y)
                    self.model_instruction.clear()
                    self.model_instruction.add(Color(rgba=(1.0, 0.0, 0.0, 1.0)))
                    self.model_instruction.add(Line(points=points, width=2, close=True))

    def _get_pixels(self, data):
        pixel_height = data[2] / self.printer_actual_dimensions[2]
        pixel_pos_min = (data[0][0] + (self.printer_actual_dimensions[1] / 2.0)) / self.printer_actual_dimensions[1]
        pixel_pos_max = (data[0][1] + (self.printer_actual_dimensions[1] / 2.0)) / self.printer_actual_dimensions[1]
        return [pixel_pos_min, pixel_height, pixel_pos_max, pixel_height]
Exemplo n.º 40
0
Arquivo: app.py Projeto: chip2n/sprite
class CanvasWidget(FloatLayout):
    canvas_size = ObjectProperty((512, 512))
    scale = NumericProperty(1)
    texture = ObjectProperty()
    touch_type = 'move'
    current_color = [0,0,0,1]

    @property
    def scaled_size(self):
        w, h = self.canvas_size
        return (w * self.scale, h * self.scale)

    def __init__(self, **kwargs):
        super(CanvasWidget, self).__init__(**kwargs)
        self.size = (512, 512)
        self._keyboard = Window.request_keyboard(self._keyboard_closed, self)
        self._keyboard.bind(on_key_down=self._on_keyboard_down)


        self.img = Image.open('test.png')
        self.img = self.img =  self.img.transpose(Image.FLIP_TOP_BOTTOM)
        self.texture = Texture.create(size=(512,512))
        self.texture.mag_filter = 'nearest'
        size = 512*512*3
        buf = []
        for r,g,b,a in self.img.getdata():
            buf.extend([r,g,b,a])
        #buf = [int(x*255/size) for x in range(size)]
        #buf = self._flatten_list(self.pixels)
        self.arr = array('B', buf)
        self.texture.blit_buffer(self.arr, colorfmt='rgba', bufferfmt='ubyte')

        with self.canvas:
            self.test = InstructionGroup()
            #self.test.add(Color(1, 1, 0, mode='rgb'))
            self.test.add(Rectangle(texture=self.texture, pos=self.pos, size=self.size, group='heh'))

        #self.bind(texture=self.on_texture_update)
        self.bind(pos=self.on_texture_update)
        self.bind(size=self.on_texture_update)

    def on_texture_update(self, instance=None, value=None):
        print('on_texture_update')
        for inst in self.test.get_group('heh'):
            if hasattr(inst, 'pos'):
                inst.pos = self.pos
            if hasattr(inst, 'size'):
                inst.size = self.size

        #self.canvas.clear()
        #with self.canvas:
        #    Color(1, 1, 0, mode='rgb')
        #    #Rectangle(texture=self.texture, pos=self.pos, size=self.size)
        #    Rectangle(pos=self.pos, size=self.size)


    def _keyboard_closed(self):
        self._keyboard.unbind(on_key_down=self._on_keyboard_down)
        self._keyboard = None

    def _on_keyboard_down(self, keyboard, keycode, text, modifiers):
        if keycode[1] == 'q':
            self.touch_type = 'move'
        elif keycode[1] == 'w':
            self.touch_type = 'draw'
        elif keycode[1] == 'e':
            r = random.random()
            g = random.random()
            b = random.random()
            print(self.parent.parent.ids.palette.add_color([r,g,b,1]))

    def on_touch_down(self, touch):
        if touch.button == 'scrolldown':
            print('Zoomin\' in')
            self.set_scale(self.scale * 1.2, touch.pos)
        elif touch.button == 'scrollup':
            print('Zoomin\' out')
            self.set_scale(self.scale / 1.2, touch.pos)
        else:
            if self.touch_type == 'draw':
                x,y = self.project(touch.pos)
                r,g,b,a = self.current_color
                self.update_pixel(int(x), int(y), r, g, b, a)
                self.refresh()
            touch.grab(self)
        return True

    def on_touch_move(self, touch):
        if touch.grab_current == self:
            if self.touch_type == 'move':
                x, y = self.pos
                dx, dy = touch.dpos
                self.pos = (x+dx, y+dy)
            elif self.touch_type == 'draw':
                x,y = self.project(touch.pos)
                px, py = self.project(touch.ppos)
                #self.update_pixel(int(x), int(y), 255, 0, 100, 100)
                r,g,b,a = self.current_color
                self.draw_line(px, py, x, y, r,g,b,a)
                
        return True

    def set_color(self, color):
        self.current_color = color

    def on_touch_up(self, touch):
        if touch.grab_current == self:
            touch.ungrab(self)
        return True

    def update_pixel(self, x, y, r, g, b, a):
        w,h = self.canvas_size
        index = int((y * w * 4) + 4 * x)
        self.arr[index] = int(r*255)
        self.arr[index+1] = int(g*255)
        self.arr[index+2] = int(b*255)
        self.arr[index+3] = int(a*255)
        self.texture.blit_buffer(self.arr, colorfmt='rgba', bufferfmt='ubyte')
        print('PIXEL: %s,%s' % (int(x), int(y)))

    def refresh(self):
        self.canvas.ask_update()

    def draw_line(self, x0, y0, x1, y1, r,g,b,a):
        self.update_pixel(int(x0),int(y0),r,g,b,a)
        self.update_pixel(int(x1),int(y1),r,g,b,a)
        print('LINE: %s, %s -> %s, %s' % (x0,y0,x1,y1))
        x0, y0, x1, y1 = int(x0), int(y0), int(x1), int(y1)
        steep = abs(y1-y0) > abs(x1-x0)
        if steep:
            x0, y0 = y0, x0
            x1, y1 = y1, x1
        if x0 > x1:
            x0, x1 = x1, x0
            y0, y1 = y1, y0
        deltax = x1-x0
        deltay = abs(y1-y0)
        error = int(deltax / 2)
        ystep = 0
        y = y0
        if y0 < y1:
            ystep = 1
        else:
            ystep = -1

        for x in range(x0,x1):
            if steep:
                self.update_pixel(y, x, r,g,b,a)
            else:
                self.update_pixel(x, y, r,g,b,a)
            error -= deltay
            if error < 0:
                y = y + ystep
                error = error + deltax
        self.refresh()

    def redraw_canvas(self):
        arr = array('B', self.buf)
        self.texture.blit_buffer(arr, colorfmt='rgba', bufferfmt='ubyte')

    def is_moveable(self):
        w, h = self.size
        return w > Window.size[0] and h > Window.size[1]

    def set_scale(self, scale, pivot):
        delta_scale = self.scale - scale
        prev_w, prev_h = self.size
        c_w, c_h = self.canvas_size
        self.scale = scale
        w, h = (c_w * self.scale, c_h * self.scale)
        self.size = (w, h)
        dw = w - prev_w
        dh = h - prev_h
        px, py = pivot
        x, y = self.pos
        ratio_x =  abs(px - x) / w
        ratio_y =  abs(py - y) / h
        after_x = dw * ratio_x
        after_y = dh * ratio_y
        print('current', ratio_x, ratio_y)
        #self.center = (x - (ax-px)*scale, y - (ay-py)*scale)
        #if not self.is_moveable():
        #    self.center = Window.center
        #else:
        x,y = self.pos
        self.pos = (x - after_x, y - after_y)

    def project(self, point):
        px,py = point
        x, y = self.pos
        ratio = self.canvas_size[0]/self.size[0]
        return (ratio*(px-x), ratio*(py-y))

    def _flatten_list(self, lst):
        return list(itertools.chain.from_iterable(lst))


    def resize(self):
        print('Resize %s' % self.size)

    def redraw_region(region=None):
        # This will redraw a region of the canvas by iterating over
        # a box of pixels in the pixel map and then drawing a
        # rectangle for each of them. Every time something is drawn
        # the rectangle dimensions containing the shape will be sent
        # through a callback to this function
        pass
Exemplo n.º 41
0
class DisplayController(object):
    def __init__(self, width, height, canvas, ac, eye_pos, eye_angle):
        super(DisplayController, self).__init__()
        self.width = width
        self.height = height
        self.canvas = canvas
        self.eye_pos = eye_pos
        self.eye_angle = eye_angle
        self.ac = ac

        self.canvas.shader.source = resource_find('data/simple.glsl')

        self.all_notes = []
        self.future_notes = {}
        self.past_notes = {}
        self.ticks = []

        # self.planes = range(0, 10 * config['PLANE_SPACING'], config['PLANE_SPACING'])
        self.planes = []
        self.lines = []

        self.past_displays = InstructionGroup()
        self.future_displays = InstructionGroup()
        self.plane_displays = InstructionGroup()
        self.line_displays = InstructionGroup()

        self.fixed_x = Translate(0, 0, 0)
        self.fixed_y = Translate(0, 0, 0)
        self.fixed_z = Translate(0, 0, 0)
        self.fixed_azi = Rotate(origin=(0, 0, 0), axis=(0, 1, 0))
        self.fixed_ele = Rotate(origin=(0, 0, 0), axis=(1, 0, 0))

        self.alpha_callback = Callback(self.alpha_sample_callback)
        self.disable_alpha_callback = Callback(self.disable_alpha_sample_callback)
        self.alpha_instruction = InstructionGroup()
        self.alpha_disable_instruction = InstructionGroup()
        self.alpha_sample_enable = False

        self.canvas.add(Callback(self.setup_gl_context))
        self.canvas.add(self.alpha_instruction)
        self.canvas.add(PushMatrix())
        self.canvas.add(UpdateNormalMatrix())

        
        
        self.canvas.add(PushMatrix())
        self.canvas.add(self.fixed_z)
        self.canvas.add(self.line_displays)
        self.canvas.add(PopMatrix())

        self.canvas.add(PushMatrix())
        self.canvas.add(self.past_displays)
        self.canvas.add(self.future_displays)
        self.canvas.add(PopMatrix())

        self.canvas.add(PushMatrix())
        # self.canvas.add(self.fixed_x)
        # self.canvas.add(self.fixed_y)
        self.canvas.add(self.plane_displays)
        self.canvas.add(PopMatrix())

        # self.canvas.add(PushMatrix())
        # self.canvas.add(self.fixed_x)
        # self.canvas.add(self.fixed_y)
        # self.canvas.add(self.fixed_z)
        # self.canvas.add(Plane(-config['SELF_PLANE_DISTANCE'], size=0.1, color=(0x20/255., 0xD8/255., 0xE9/255.), tr=0.2))
        # self.canvas.add(PopMatrix())

        self.canvas.add(PopMatrix())
        self.canvas.add(self.alpha_disable_instruction)
        self.canvas.add(Callback(self.reset_gl_context))

        self.draw_planes()

    def add_notes(self, note_data):
        s = config['LINE_SPACING']
        for nd in note_data:
            if (nd.x, nd.y) not in self.lines and float(nd.x).is_integer() and float(nd.y).is_integer():
                self.line_displays.add(Line(nd.x * s, nd.y * s, color=(0.7, 0.5, 0.0)))
                self.lines.append((nd.x, nd.y))

        self.all_notes.extend(note_data)
        self.all_notes.sort(key=lambda n:n.tick)
        self.ticks = map(lambda n:n.tick, self.all_notes)

    def draw_planes(self):
        for p in self.planes:
            self.plane_displays.add(Plane(p, color=(0xE9/255., 0xD8/255., 0x3C/255.)))

    def setup_gl_context(self, *args):
        gl.glEnable(gl.GL_DEPTH_TEST)

    def toggle_alpha_sample(self):
        if self.alpha_sample_enable:
            self.alpha_instruction.remove(self.alpha_callback)
            self.alpha_disable_instruction.remove(self.disable_alpha_callback)
            self.alpha_sample_enable = False
        else:
            self.alpha_instruction.add(self.alpha_callback)
            self.alpha_disable_instruction.add(self.disable_alpha_callback)
            self.alpha_sample_enable = True

    def alpha_sample_callback(self, *args):
        gl.glEnable(gl.GL_SAMPLE_ALPHA_TO_COVERAGE)

    def reset_gl_context(self, *args):
        gl.glDisable(gl.GL_DEPTH_TEST)

    def disable_alpha_sample_callback(self, *args):
        gl.glDisable(gl.GL_SAMPLE_ALPHA_TO_COVERAGE)

    def get_look_at(self, x, y, z, azi, ele):
        dx = - np.sin(azi) * np.cos(ele)
        dy = np.sin(ele)
        dz = - np.cos(azi) * np.cos(ele)

        # Not sure why up has to just be up...
        upx, upy, upz = (0, 1, 0)

        mat = Matrix()
        mat = mat.look_at(x, y, z,
                          x + dx, y + dy, z + dz,
                          upx, upy, upz)
        return mat

    def update_camera(self, pos, angle):
        self.eye_pos = pos
        self.eye_angle = angle
        x, y, z = pos
        azi, ele = angle
        asp = self.width / float(self.height)
        mat = self.get_look_at(x, y, z, azi, ele)

        proj = Matrix()
        proj.perspective(30, asp, 1, 100)

        self.canvas['projection_mat'] = proj
        self.canvas['modelview_mat'] = mat

        self.fixed_x.x = x
        self.fixed_y.y = y
        self.fixed_z.z = z
        self.fixed_azi.angle = azi * 180/np.pi
        self.fixed_ele.angle = ele * 180/np.pi

    def get_notes_in_range(self, start_tick, end_tick):
      l = bisect.bisect_left(self.ticks, start_tick)
      r = bisect.bisect_left(self.ticks, end_tick)
      if r <= 0:
         return []
      return self.all_notes[l:r]

    def on_update(self, tick):
        self_plane_z = self.eye_pos[2] - config['SELF_PLANE_DISTANCE']

        eye_tick = tick + ( - self.eye_pos[2] / config['UNITS_PER_TICK'])
        dt = kivyClock.frametime

        future_range = self.get_notes_in_range(eye_tick, eye_tick + config['VISIBLE_TICK_RANGE'])
        past_range = self.get_notes_in_range(eye_tick - config['VISIBLE_TICK_RANGE'], eye_tick)

        # COMPLEX LOGIC TO MAINTAIN LISTS OF VISIBLE NOTES ORDERED BY DISTANCE FROM CAMERA
        # far future <-> future
        # future <-> past
        # past <-> far past

        # far future -> future
        fftof = list(x for x in future_range if x not in self.past_notes and x not in self.future_notes)
        # future -> far future
        ftoff = list(x for x in self.future_notes if x not in future_range and x not in past_range)
        # future -> past
        ftop = list(x for x in past_range if x in self.future_notes)
        # past -> future
        ptof = list(x for x in future_range if x in self.past_notes)
        # past -> far past
        ptofp = list(x for x in self.past_notes if x not in future_range and x not in past_range)
        # far past -> past
        fptop = list(x for x in past_range if x not in self.past_notes and x not in self.future_notes)

        # handle ff -> f
        for nd in sorted(fftof, key=lambda n: n.tick):
            ndisp = NoteDisplay(nd, self.planes, self.ac)
            self.future_displays.insert(0, ndisp)
            self.future_notes[nd] = ndisp

        # handle f -> ff
        for nd in ftoff:
            ndisp = self.future_notes[nd]
            self.future_displays.remove(ndisp)
            del self.future_notes[nd]

        # handle f -> p
        for nd in sorted(ftop, key=lambda n: n.tick):
            ndisp = self.future_notes[nd]
            self.future_displays.remove(ndisp)
            self.past_displays.add(ndisp)
            self.past_notes[nd] = ndisp
            del self.future_notes[nd]

        # handle p -> f
        for nd in sorted(ptof, key=lambda n: -n.tick):
            ndisp = self.past_notes[nd]
            self.past_displays.remove(ndisp)
            self.future_displays.add(ndisp)
            self.future_notes[nd] = ndisp
            del self.past_notes[nd]

        # handle p -> fp
        for nd in ptofp:
            ndisp = self.past_notes[nd]
            self.past_displays.remove(ndisp)
            del self.past_notes[nd]

        # handle fp -> p
        for nd in sorted(fptop, key=lambda n: -n.tick):
            ndisp = NoteDisplay(nd, self.planes, self.ac)
            self.past_displays.insert(0, ndisp)
            self.past_notes[nd] = ndisp


        for s in self.future_notes.values() + self.past_notes.values():
            pos = s.pos_from_tick(tick)
            s.set_pos(pos)
            s.on_update(dt, eye_tick, self.eye_angle)

            if s.past_me and pos[2] < self_plane_z - 0.5 * config['SELF_PLANE_DISTANCE']:
                s.past_me = False
            if pos[2] > self_plane_z and not s.past_me:
                s.sound(tick, pos)
                s.past_me = True


        Logger.debug('Number of notes: %s' % (len(self.future_notes) + len(self.past_notes)))
Exemplo n.º 42
0
 def move(self,*dt):
     self.canvas.clear()
     self.canvas.add(self.foodblue)
     x,y = self.snake[-1]
     if abs(self.snake[-1][0] -self.food.pos[0])<10 and abs(self.snake[-1][1] -self.food.pos[1])<10:#吃到食物
         x,y = self.snake[-1]
         if self.keyboard.direction == "left":
             for i in range(1,11):
                 x1,y1 = x-i,y
                 self.snake.append((x1,y1))
         elif self.keyboard.direction == "right":
              for i in range(1,11):
                 x1,y1 = x+i,y
                 self.snake.append((x1,y1))
         elif self.keyboard.direction == "up":
             for i in range(1,11):
                 x1,y1 = x,y+i
                 self.snake.append((x1,y1))
         elif self.keyboard.direction == "down":
             for i in range(1,11):
                 x1,y1 = x,y-i
                 self.snake.append((x1,y1))
         self.foods()
     else:
         if self.keyboard.direction == "left":
             x,y = x-1,y
             if x < self.rangeSnake[0] :
                 self.gameover()
             for a,b in self.snake:
                 if x >a and x-a<10 and abs(b-y)<10:
                     self.gameover()
                     break
         elif self.keyboard.direction == "right":
             x,y = x+1,y
             if x+10 > self.rangeSnake[2]:
                 self.gameover()
             for a,b in self.snake:
                 if a>x and a-x < 10 and abs(b-y)< 10:
                     self.gameover()
                     break
         elif self.keyboard.direction == "up":
             x,y = x,y+1
             if y+10 >self.rangeSnake[3]:
                 self.gameover()
             for a,b in self.snake:
                 if b>y and b-y < 10 and abs(x-a)<10:
                     self.gameover()
                     break
         elif self.keyboard.direction == "down":
             x,y = x,y-1
             if y < self.rangeSnake[1]:
                 self.gameover()
             for a,b in self.snake:
                 if y >b and y-b>10 and abs(x-a)<10:
                     self.gameover()
                     break
         self.snake.append((x,y))
         del self.snake[0]
     for i in self.snake:
         snake = InstructionGroup()
         snake.add(Color(0, 0, 1, 1))
         snake.add(Rectangle(pos=i, size=(10,10)))
         self.canvas.add(snake)
Exemplo n.º 43
0
class TextureStack(Widget):
    """Several textures superimposed on one another, and possibly offset
    by some amount.

    In 2D games where characters can wear different clothes or hold
    different equipment, their graphics are often composed of several
    graphics layered on one another. This widget simplifies the
    management of such compositions.

    """
    texs = ListProperty()
    """Texture objects"""
    offxs = ListProperty()
    """x-offsets. The texture at the same index will be moved to the right
    by the number of pixels in this list.

    """
    offys = ListProperty()
    """y-offsets. The texture at the same index will be moved upward by
    the number of pixels in this list.

    """
    group = ObjectProperty()
    """My ``InstructionGroup``, suitable for addition to whatever ``canvas``."""

    def _get_offsets(self):
        return zip(self.offxs, self.offys)

    def _set_offsets(self, offs):
        offxs = []
        offys = []
        for x, y in offs:
            offxs.append(x)
            offys.append(y)
        self.offxs, self.offys = offxs, offys

    offsets = AliasProperty(
        _get_offsets,
        _set_offsets,
        bind=('offxs', 'offys')
    )
    """List of (x, y) tuples by which to offset the corresponding texture."""
    _texture_rectangles = DictProperty({})
    """Private.

    Rectangle instructions for each of the textures, keyed by the
    texture.

    """

    def __init__(self, **kwargs):
        """Make triggers and bind."""
        kwargs['size_hint'] = (None, None)
        self.translate = Translate(0, 0)
        self.group = InstructionGroup()
        super().__init__(**kwargs)
        self.bind(offxs=self.on_pos, offys=self.on_pos)

    def on_texs(self, *args):
        """Make rectangles for each of the textures and add them to the canvas."""
        if not self.canvas or not self.texs:
            Clock.schedule_once(self.on_texs, 0)
            return
        texlen = len(self.texs)
        # Ensure each property is the same length as my texs, padding
        # with 0 as needed
        for prop in ('offxs', 'offys'):
            proplen = len(getattr(self, prop))
            if proplen > texlen:
                setattr(self, prop, getattr(self, prop)[:proplen-texlen])
            if texlen > proplen:
                propval = list(getattr(self, prop))
                propval += [0] * (texlen - proplen)
                setattr(self, prop, propval)
        self.group.clear()
        self._texture_rectangles = {}
        w = h = 0
        (x, y) = self.pos
        self.translate.x = x
        self.translate.y = y
        self.group.add(PushMatrix())
        self.group.add(self.translate)
        for tex, offx, offy in zip(self.texs, self.offxs, self.offys):
            rect = Rectangle(
                pos=(offx, offy),
                size=tex.size,
                texture=tex
            )
            self._texture_rectangles[tex] = rect
            self.group.add(rect)
            tw = tex.width + offx
            th = tex.height + offy
            if tw > w:
                w = tw
            if th > h:
                h = th
        self.size = (w, h)
        self.group.add(PopMatrix())
        self.canvas.add(self.group)

    def on_pos(self, *args):
        """Translate all the rectangles within this widget to reflect the widget's position.

        """
        (x, y) = self.pos
        self.translate.x = x
        self.translate.y = y

    def clear(self):
        """Clear my rectangles and ``texs``."""
        self.group.clear()
        self._texture_rectangles = {}
        self.texs = []
        self.size = [1, 1]

    def insert(self, i, tex):
        """Insert the texture into my ``texs``, waiting for the creation of
        the canvas if necessary.

        """
        if not self.canvas:
            Clock.schedule_once(
                lambda dt: self.insert(i, tex), 0)
            return
        self.texs.insert(i, tex)

    def append(self, tex):
        """``self.insert(len(self.texs), tex)``"""
        self.insert(len(self.texs), tex)

    def __delitem__(self, i):
        """Remove a texture and its rectangle"""
        tex = self.texs[i]
        try:
            rect = self._texture_rectangles[tex]
            self.canvas.remove(rect)
            del self._texture_rectangles[tex]
        except KeyError:
            pass
        del self.texs[i]

    def __setitem__(self, i, v):
        """First delete at ``i``, then insert there"""
        if len(self.texs) > 0:
            self._no_upd_texs = True
            self.__delitem__(i)
            self._no_upd_texs = False
        self.insert(i, v)

    def pop(self, i=-1):
        """Delete the texture at ``i``, and return it."""
        return self.texs.pop(i)
Exemplo n.º 44
0
class Main(FloatLayout):
    snake = ListProperty([(0,0)])
    rangeSnake = ListProperty([0,0,Window.width,Window.height])
    startSpeed = NumericProperty(30)

    def __init__(self, **kwargs):
        super(Main, self).__init__(**kwargs)
        self.keyboard = Controls()
        self.count = 0
        self.bind(size=self.up,pos=self.up)

    def up(self,*args):
        self.rangeSnake[0] = self.pos[0]
        self.rangeSnake[1] = self.pos[1]
        self.rangeSnake[2] = self.pos[0] + self.size[0]
        self.rangeSnake[3] = self.pos[1] + self.size[1]
        self.snake[0] = self.pos

    def start(self,*dt):
        self.canvas.clear()
        Clock.unschedule(self.move)
        self.food()
        Clock.schedule_interval(self.move,1./(self.startSpeed+self.count))

    def restart(self, *dt):
        self.canvas.clear()
        self.clear_widgets()
        Clock.unschedule(self.move)

        self.foods()
        self.snake = [ self.pos]
        self.keyboard.direction = "right"
        Clock.schedule_interval(self.move,1./(self.startSpeed+self.count))

    def stop(self,*dt):
        Clock.unschedule(self.move)

    def continue_move(self):
        Clock.unschedule(self.move)
        Clock.schedule_interval(self.move,1./(self.startSpeed+self.count))

    def food(self,*args):
        self.foodblue = InstructionGroup()
        self.foodblue.add(Color(1, 0, 0, 1))
        x = random.randint(int(self.rangeSnake[0]), int(self.rangeSnake[2]-10))
        y = random.randint(int(self.rangeSnake[1]), int(self.rangeSnake[3]-10))
        self.food = Rectangle(pos=(x,y), size=(10,10))
        self.foodblue.add(self.food)

    def foods(self):
        self.count += 1
        x = random.randint(int(self.rangeSnake[0]), int(self.rangeSnake[2]-10))
        y = random.randint(int(self.rangeSnake[1]), int(self.rangeSnake[3]-10))
        for a,b in self.snake:
            if x > a+10 or y >b+10 or x < a- 10 or y<b-10:
                pass
            else:
                self.foods()
                return
        self.food.pos = (x,y)

    def move(self,*dt):
        self.canvas.clear()
        self.canvas.add(self.foodblue)
        x,y = self.snake[-1]
        if abs(self.snake[-1][0] -self.food.pos[0])<10 and abs(self.snake[-1][1] -self.food.pos[1])<10:#吃到食物
            x,y = self.snake[-1]
            if self.keyboard.direction == "left":
                for i in range(1,11):
                    x1,y1 = x-i,y
                    self.snake.append((x1,y1))
            elif self.keyboard.direction == "right":
                 for i in range(1,11):
                    x1,y1 = x+i,y
                    self.snake.append((x1,y1))
            elif self.keyboard.direction == "up":
                for i in range(1,11):
                    x1,y1 = x,y+i
                    self.snake.append((x1,y1))
            elif self.keyboard.direction == "down":
                for i in range(1,11):
                    x1,y1 = x,y-i
                    self.snake.append((x1,y1))
            self.foods()
        else:
            if self.keyboard.direction == "left":
                x,y = x-1,y
                if x < self.rangeSnake[0] :
                    self.gameover()
                for a,b in self.snake:
                    if x >a and x-a<10 and abs(b-y)<10:
                        self.gameover()
                        break
            elif self.keyboard.direction == "right":
                x,y = x+1,y
                if x+10 > self.rangeSnake[2]:
                    self.gameover()
                for a,b in self.snake:
                    if a>x and a-x < 10 and abs(b-y)< 10:
                        self.gameover()
                        break
            elif self.keyboard.direction == "up":
                x,y = x,y+1
                if y+10 >self.rangeSnake[3]:
                    self.gameover()
                for a,b in self.snake:
                    if b>y and b-y < 10 and abs(x-a)<10:
                        self.gameover()
                        break
            elif self.keyboard.direction == "down":
                x,y = x,y-1
                if y < self.rangeSnake[1]:
                    self.gameover()
                for a,b in self.snake:
                    if y >b and y-b>10 and abs(x-a)<10:
                        self.gameover()
                        break
            self.snake.append((x,y))
            del self.snake[0]
        for i in self.snake:
            snake = InstructionGroup()
            snake.add(Color(0, 0, 1, 1))
            snake.add(Rectangle(pos=i, size=(10,10)))
            self.canvas.add(snake)
    def gameover(self):
        Clock.unschedule(self.move)
        btn = Button(text="Game is over",size_hint=(1,1),pos_hint={"center_x":.5,"center_y":.5})
        self.add_widget(btn)
        btn.bind(on_release=self.restart )
Exemplo n.º 45
0
class LinePlot(Widget):

    viewport = ListProperty(None)
    line_width = NumericProperty(5.)
    line_color = ListProperty([0,.8,1])
    border_width = NumericProperty(5)
    border_color = ListProperty([.3,.3,.3])
    flattened_points = ListProperty(None)
    tick_distance_x = NumericProperty(None)
    tick_distance_y = NumericProperty(None)
    tick_color = ListProperty([.3,.3,.3])
    select_circle = ListProperty([0,0,0])

    def __init__(self, points, **kwargs):
        # calculate some basic information about the data
        self.points = points
        self.points_x = zip(*points)[0]
        self.points_y = zip(*points)[1]

        # if we could figure out how to draw an arbitrary number of ticks in kv, this would be cleaner
        self.ticks = InstructionGroup()
        self.tick_translate = Translate()
        

        super(LinePlot, self).__init__(**kwargs)
        self.canvas.insert(0, self.ticks)
        self.viewport = (min(self.points_x), min(self.points_y), max(self.points_x), max(self.points_y))
    
    # recalculate viewport when size changes
    def on_size(self, instance, value):
        self.on_viewport(None, self.viewport)

    def on_pos(self, instance, value):
        self.tick_translate.xy = self.x, self.y
        
    def on_viewport(self, instance, value):
        if value is None or len(value) != 4: return
        print value
        self.vp_width_convert = float(self.width)/(value[2] - value[0])
        self.vp_height_convert = float(self.height)/(value[3] - value[1])

        # calculate the actual display points based on the viewport and self.size
        self.display_points = [self.to_display_point(*p) for p in self.points if value[0] <= p[0] <= value[2] and value[1] <= p[1] <= value[3]]
        self.flattened_points = [item for sublist in self.display_points for item in sublist]
        self.draw_ticks()

    # it would be real nice if we could figure out how to do this in kv
    def draw_ticks(self):
        self.ticks.clear()
        self.ticks.add(Color(*self.tick_color, mode='rgb'))
        self.ticks.add(PushMatrix())
        self.ticks.add(self.tick_translate)
        if self.tick_distance_x is not None:
            first_x_tick = self.tick_distance_x*(int(self.viewport[0]/self.tick_distance_x) + 1)
            for x in drange(first_x_tick, self.viewport[2], self.tick_distance_x):
                start = self.to_display_point(x, self.viewport[1])
                stop = self.to_display_point(x, self.viewport[3])
                self.ticks.add(Line(points=[start[0], start[1], stop[0], stop[1]]))

        if self.tick_distance_y is not None:
            first_y_tick = self.tick_distance_y*(int(self.viewport[1]/self.tick_distance_y) + 1)
            for y in drange(first_y_tick, self.viewport[3], self.tick_distance_y):
                start = self.to_display_point(self.viewport[0], y)
                stop = self.to_display_point(self.viewport[2], y)
                self.ticks.add(Line(points=[start[0], start[1], stop[0], stop[1]]))
        
        self.ticks.add(PopMatrix())

    def to_display_point(self, x, y):
        return (self.vp_width_convert*(x-self.viewport[0]), self.vp_height_convert*(y-self.viewport[1]))

    def select_point(self, x, y):
        # get point from self.displaypoints that is closest to x
        
        distances = [abs((x - self.x) - d[0]) for d in self.display_points]
        idx = min(xrange(len(distances)),key=distances.__getitem__)
        self.select_circle = [self.display_points[idx][0], self.display_points[idx][1], 20]
        return self.points[idx]




    def to_xy(self, x, y):
        xt = (x - self.x)/self.vp_width_convert+self.viewport[0]
        yt = (y - self.y)/self.vp_height_convert+self.viewport[1]
        return (xt, yt)
Exemplo n.º 46
0
class Piece(SparseGridLayout, TetrisAware):
    map = ListProperty([])

    def __init__(self, color=(1, 1, 1, 1), **kwargs):
        self.color = color

        self.size_hint = (None, None)
        super(SparseGridLayout, self).__init__(**kwargs)

        self.bind(map=self.on_map)

        self.keyboard = App.get_running_app().keyboard
        self.keyboard.bind(
            on_key_down=self.on_keypress,
            on_key_up=self.on_keyrelease
        )

        self.base_delay = self.keyboard.repeat_delay
        self.base_speed = self.keyboard.repeat_speed

        self.vertical = False

        """
        One may wonder, when entering the realms of Piece.update(), "what exactly is delay_lambda?".

        It is what makes a piece remain controllable after having touched the ground, for a static duration (.5).

        It is checked in move() and rotate() - if check_lock notices the Piece isn't right above the ground anymore, it
        triggers "normal" gravity back by calling on_parent. Finally, the lock timeout is necessarily called after the
        static duration (.5), to lock the piece if its height hasn't changed (we discard the false-positive if it has).
        """
        self.delay_lambda = None

    def on_parent(self, *args):
        if self.parent:
            level = self.parent.parent.level
            Clock.schedule_interval(
                self.update,
                .5 * (.75 + (.05 * (4 - (level % 4)))) ** level
            )

    def on_map(self, instance, value):
        current_child = 0
        for y in range(len(self.map)):
            for x in range(len(self.map[y])):
                if self.map[y][x] == 'x':
                    if len(self.children) < sum(line.count('x') for line in self.map):
                        self.add_widget(Block(coords=(x, y), color=self.color))
                    else:
                        self.children[current_child].coords = (x, y)
                        current_child += 1
        self.do_layout()

    def update(self, *args):
        if not self.parent:
            Clock.unschedule(self.update)
            self.keyboard_closed()
            return

        if self.tetris_coords[1] == 0 or self.collide_piece('down'):
            self.do_layout()
            self.remove_children()
            self.keyboard_closed()

            self.parent.check_line()
            self.parent.parent.spawn.new_piece()

            if self.parent:
                self.parent.remove_widget(self)
        else:
            self.tetris_coords[1] -= 1

            self.check_lock(retrigger=True)

    def check_lock(self, retrigger=False):
        if not self.delay_lambda and (self.tetris_coords[1] == 0 or self.collide_piece('down')):
            self.trigger_lock()
        elif self.delay_lambda and (self.tetris_coords[1] > 0 and not self.collide_piece('down')):
            self.reset_lock()
        elif retrigger and self.delay_lambda:
            Clock.unschedule(self.delay_lambda)
            self.trigger_lock()


    def trigger_lock(self):
        Clock.unschedule(self.update)
        y = self.tetris_coords[1]

        self.delay_lambda = lambda *args: self.lock_timeout(y)
        Clock.schedule_once(self.delay_lambda, .5)

    def reset_lock(self):
        self.on_parent()

        Clock.unschedule(self.delay_lambda)
        self.delay_lambda = None

    def lock_timeout(self, y):
        if self.tetris_coords[1] == y:
            self.update()
            self.on_parent()

        self.delay_lambda = None

    def remove_children(self):
        for child in self.children[:]:
            child.pos_hint = {}
            self.remove_widget(child)
            self.parent.add_widget(child)

    def collide_piece(self, direction='down', map=[], coords=[]):
        if self.parent:
            for child in self.parent.children:
                if hasattr(child, 'tetris_coords') and child != self:
                    if direction == 'cw' or direction == 'ccw':
                        for y in range(len(map)):
                            for x in range(len(map[y])):
                                if map[y][x] == 'x':
                                    if coords[0] + x == child.tetris_coords[0]\
                                       and coords[1] + y == child.tetris_coords[1]:
                                            return True
                    else:
                        for own_child in self.children:
                            if direction == 'down':
                                if own_child.tetris_coords[1] - 1 == child.tetris_coords[1]\
                                   and own_child.tetris_coords[0] == child.tetris_coords[0]:
                                    return True
                            if direction == 'left':
                                if own_child.tetris_coords[0] - 1 == child.tetris_coords[0]\
                                   and own_child.tetris_coords[1] == child.tetris_coords[1]:
                                    return True
                            if direction == 'right':
                                if own_child.tetris_coords[0] + 1 == child.tetris_coords[0]\
                                   and own_child.tetris_coords[1] == child.tetris_coords[1]:
                                    return True
                            if direction == 'current':
                                if own_child.tetris_coords[0] == child.tetris_coords[0]\
                                   and own_child.tetris_coords[1] == child.tetris_coords[1]:
                                    return True

        return False

    def on_tetris_coords(self, *args):
        if hasattr(self, 'map') and self.parent:
            if self.tetris_coords[0] < 0:
                self.tetris_coords[0] = 0
            if self.tetris_coords[0] + len(self.map[0]) > self.parent.cols:
                self.tetris_coords[0] = self.parent.cols - len(self.map[0])
            if self.tetris_coords[1] < 0:
                self.tetris_coords[1] = 0
            if self.tetris_coords[1] + len(self.map) > self.parent.rows:
                self.tetris_coords[1] = self.parent.rows - len(self.map)

        if hasattr(self.parent, 'coord_to_pos'):
            self.pos = self.parent.coord_to_pos(*self.tetris_coords)

        for child in self.children:
            child.tetris_coords = [self.tetris_coords[0] + child.col, self.tetris_coords[1] + child.row]

    def do_layout(self, *args):
        super(Piece, self).do_layout(*args)

        if hasattr(self, 'outline'):
            self.canvas.before.remove(self.outline)

        self.outline = InstructionGroup()
        for child in self.children:
            self.outline.add(Color(.5, .8, 1, .8))
            self.outline.add(Line(
                points=[
                    child.x - 1, child.y - 1,
                    child.right + 1, child.y - 1,
                    child.right + 1, child.top + 1,
                    child.x - 1, child.top + 1
                ],
                close=True,
                width=1.5
            ))

        if self.canvas.before:
            self.canvas.before.add(self.outline)

            if len(self.children) == 0:
                if hasattr(self, 'outline'):
                    self.canvas.before.remove(self.outline)

    def move(self, direction):
        if direction == 'left' and not self.collide_piece('left'):
            self.tetris_coords[0] -= 1
        if direction == 'right' and not self.collide_piece('right'):
            self.tetris_coords[0] += 1
        if direction == 'down':
            self.keyboard.repeat_delay = 0
            self.keyboard.repeat_speed /= 4

            self.update()

        self.check_lock()

    def rotate(self, **kwargs):
        direction = 'ccw'
        if 'direction' in kwargs:
            direction = kwargs['direction']

        new_map = self.rotate_map(direction)
        new_coords = self.rotate_coords(new_map)

        if self.collide_piece(direction, new_map, new_coords):
            return

        self.vertical = not self.vertical

        self.map = new_map

        self.tetris_coords = new_coords

        self.check_lock()

    def rotate_map(self, direction):
        new_map = zip(*self.map[::-1])
        if direction == 'cw':
            for i in range(2):
                new_map = zip(*new_map[::-1])

        return new_map

    def rotate_coords(self, new_map):
        map_diff = [
            len(self.map[0]) - len(new_map[0]),
            len(self.map) - len(new_map)
        ]

        for i in range(len(map_diff)):
            if self.vertical:
                map_diff[i] = floor(map_diff[i] / 2.)
            else:
                map_diff[i] = ceil(map_diff[i] / 2.)

        return self.tetris_coords[0] + map_diff[0], self.tetris_coords[1] + map_diff[1]

    def on_keypress(self, keyboard, key, keycode, modifiers):
        self.reset_keyboard_repeat()
        if key == 113: # 'q' on qwerty
            self.rotate(direction='ccw')
        elif key == 101: # 'e'
            self.rotate(direction='cw')
        elif key == 97: # 'a' on qwerty
            self.move('left')
        elif key == 100: # 'd'
            self.move('right')
        elif key == 115: # 's'
            self.move('down')
        elif key == 122: # 'z' on qwerty
            self.rotate(direction='ccw')
        elif key == 120: # 'x'
            self.rotate(direction='cw')
        elif key == 276: # left arrow
            self.move('left')
        elif key == 275: # right arrow
            self.move('right')
        elif key == 273: # up arrow
            self.rotate(direction='ccw')
        elif key == 274: # down arrow
            self.move('down')
        else:
            return True

        return False

    def on_keyrelease(self, keyboard, keycode):
        self.reset_keyboard_repeat()

    def reset_keyboard_repeat(self):
        self.keyboard.repeat_delay = self.base_delay
        self.keyboard.repeat_speed = self.base_speed

    def keyboard_closed(self):
        self.reset_keyboard_repeat()
        self.keyboard.unbind(
            on_key_down=self.on_keypress,
            on_key_up=self.on_keyrelease
        )