Exemplo n.º 1
0
class GearLocation(InstructionGroup):
    def __init__(self, position, size, x, y, gear_type):
        super(GearLocation, self).__init__()

        self.x = x
        self.y = y
        self.type = gear_type

        self.add(self.get_color())
        self.location_holder = CEllipse(cpos=position, csize=(size, size))
        self.add(self.location_holder)

    def on_layout(self, pos, size):
        self.location_holder.set_cpos(pos)
        self.location_holder.set_csize((size, size))

    def get_color(self):
        if self.type == 'volume':
            return colors["light_red"]
        elif self.type == 'pitch':
            return colors["light_orange"]
        elif self.type == 'tempo':
            return colors["light_purple"]
        elif self.type == 'instrument':
            return colors["light_yellow"]
        else:
            return Color(255, 255, 255)
Exemplo n.º 2
0
class TimedCEllipse(InstructionGroup):
    def __init__(self, cpos, radius, texture=None):
        super(TimedCEllipse, self).__init__()
        # save position
        self.cpos = cpos
        self.r = radius
        self.width = radius * .2

        # code for creating the Line
        self.rcolor = Color(*kGemRingColor, mode="rgba")
        self.rrgb = kGemRingColor
        PushMatrix()
        self.add(self.rcolor)
        self.angle = 0
        self.ring = Line(circle=(*self.cpos, self.r, self.angle, 360),
                         width=self.width,
                         cap='none')
        self.add(self.ring)

        # code for creating the circle
        self.ccolor = Color(*kGemCircleColor)
        self.add(self.ccolor)
        csize = (2 * radius - self.width, ) * 2
        self.circ = CEllipse(cpos=cpos, csize=csize)
        self.add(self.circ)
        PopMatrix()

    def set_cpos(self, cpos):
        '''Set the centered position of the shape'''
        self.cpos = cpos
        self.circ.set_cpos(cpos)
        self.ring.circle = (*cpos, self.r, self.angle, 360)

    def get_cpos(self):
        '''Returned centered position of the shape'''
        return self.cpos

    def set_radius(self, r):
        '''Set radius of the shape'''
        self.r = r
        self.ring.circle = (*self.cpos, self.r, self.angle, 360)
        self.width = self.r * .2
        self.ring.width = self.width

        csize = (2 * r - self.width, ) * 2
        self.circ.csize = csize

    def set_ring_color(self, color):
        '''Set the ring color to indicate correct/incorrect input'''
        self.rrgb = color
        self.rcolor.rgba = color

    def set_alpha(self, a):
        '''Set the alpha for the sake of animating off the screen'''
        self.rcolor.a = a
        self.ccolor.a = a

    def set_angle(self, angle):
        '''Set the new angle of the ring'''
        self.angle = angle
        self.rcolor.rgba = self.rrgb
        self.ring.circle = (*self.cpos, self.r, self.angle, 360)

    def get_angle(self):
        '''Get the current angle of the ring'''
        return self.angle
Exemplo n.º 3
0
class NowBar(InstructionGroup):
    def __init__(self, bpm):
        super(NowBar, self).__init__()

        self.bpm = bpm

        # color the cursor grey
        self.color = Color(*kCursorDefaultColor)
        self.add(self.color)

        # save position and size
        self.xpos = PlaceOnBeat(.75)  #kTrackLowerLimit
        self.xstart = self.xpos
        self.ypos = kGemBarYPos
        self.csize = kCursorSize

        # draw the cursor as a circle
        cpos = (self.xpos, self.ypos)
        self.cursor = CEllipse(cpos=cpos,
                               csize=self.csize,
                               texture=Image(kNowBarPng).texture)
        self.add(self.cursor)

        # limits that NowBar will be moving within, correlates with length of gem bar
        self.lim_lo = kTrackLowerLimit
        self.lim_hi = Window.width - self.lim_lo

        # save time for animation, by starting large, the cursor will maintain its size
        self.t = kCursorMaxTime

        # save speed of the cursor
        self.v = BpmToPixels(bpm)

        # initialize position of the NowBar
        self.active = True

        # hold callback that will be used to indicate reaching the end of the line
        self.end_cb = None

    def install_cb(self, cb):
        self.end_cb = cb

    def change_bpm(self, bpm):
        self.bpm = bpm
        self.v = BpmToPixels(self.bpm)

    def get_xpos(self):
        return self.xpos

    def update_pos(self, dt):
        # y should remain constant
        curr_xpos = self.cursor.get_cpos()[0]
        new_xpos = curr_xpos + self.v * dt
        self.cursor.set_cpos((new_xpos, self.ypos))
        if not self.in_bounds():
            if self.end_cb:
                self.end_cb()
            self.reset()
        self.xpos = self.cursor.get_cpos()[0]

    # move cursor back to beginning of the screen
    def reset(self):
        self.cursor.set_cpos((self.lim_lo, self.ypos))

    def restart(self):
        self.cursor.set_cpos((self.xstart, self.ypos))
        self.activate(True)

    # animate
    def animate(self, dt):
        new_size = kCursorSize[0] * exp(-kCursorDecayRate * self.t) * cos(
            kCursorOscRate * self.t) + kCursorSize[0]
        self.csize = (new_size, new_size)
        self.cursor.csize = self.csize
        self.t = kCursorMaxTime if (
            self.t + dt >= kCursorMaxTime) else self.t + dt

    # reset time for animating key presses, can call this function when input is recorded
    def time_reset(self):
        self.t = 0

    # find out if the barline is on screen, if so we will draw it
    def in_bounds(self):
        xpos = self.cursor.get_cpos()[0]
        return True if self.lim_lo <= xpos <= self.lim_hi else False

    def activate(self, active):
        self.active = active

    # update position and update animation
    def on_update(self, dt):
        # return whether the bar is active or inactive
        self.update_pos(dt)
        self.animate(dt)
        return self.active
Exemplo n.º 4
0
class GearCenter(InstructionGroup):
    def __init__(self, x, y, storage_pos, box_pos, type, size,
                 background_color):
        super(GearCenter, self).__init__()

        self.color = background_color
        self.size = size
        self.storage_pos = storage_pos
        self.box_pos = box_pos
        self.type = type
        self.x = x
        self.y = y

        self.add(self.color)
        if self.type == 'center':
            self.middle_black = CEllipse(
                texture=CoreImage('images/play.png').texture)
        else:
            self.middle_black = CEllipse(cpos=self.storage_pos,
                                         csize=(self.size, self.size))

        self.add(self.middle_black)

        self.is_draggable = False
        self.in_music_box = False

    def update_music_pos(self, pos):
        self.box_pos = pos

    def update_storage_pos(self, pos):
        self.storage_pos = pos

    def reset(self):
        self.middle_black.set_cpos(self.storage_pos)
        self.in_music_box = False

    def on_layout(self, pos, size):
        if self.in_music_box:
            self.middle_black.set_cpos(self.box_pos)

        else:
            self.middle_black.set_cpos(pos)

        self.middle_black.set_csize((size, size))

    def get_distance_from_center(self, touch):
        return sqrt((touch[0] - self.middle_black.get_cpos()[0])**2 +
                    (touch[1] - self.middle_black.get_cpos()[1])**2)

    def on_touch_down(self, touch):

        distance = self.get_distance_from_center(touch)

        if distance <= self.size and distance >= self.size / 2:
            self.is_draggable = True
            self.touch_x_diff = touch[0] - self.middle_black.get_cpos()[0]
            self.touch_y_diff = touch[1] - self.middle_black.get_cpos()[1]

            return True

        return False

    def on_touch_up(self, touch, gear_box_x, can_add_gear):
        # if it was previously dragged, update it to the correct location
        if self.is_draggable:
            if touch[0] <= gear_box_x or not can_add_gear(self):
                self.middle_black.set_cpos(self.storage_pos)
                self.in_music_box = False
            else:
                self.middle_black.set_cpos(self.box_pos)
                self.in_music_box = True

        self.is_draggable = False
        return self.in_music_box

    def on_touch_move(self, touch):
        if self.is_draggable:
            self.middle_black.set_cpos(
                (touch[0] - self.touch_x_diff, touch[1] - self.touch_y_diff))
            return True
        return False
Exemplo n.º 5
0
class Gear(InstructionGroup):
    def __init__(self,
                 x,
                 y,
                 size,
                 num_teeth,
                 gear_type,
                 gear_value,
                 storage_pos,
                 box_pos,
                 gear_id,
                 background_color=Color(0, 0, 0),
                 part=0):
        super(Gear, self).__init__()

        # part is 0 for melody and 1 for bassline
        self.part = part

        self.type = gear_type  # 'volume', 'pitch', 'speed', 'instrument', 'center'
        self.color = self._get_color()

        self.value = gear_value
        self.x = x
        self.y = y

        self.storage_pos = storage_pos
        self.box_pos = box_pos
        self.gear_id = gear_id
        self.size = size

        self.add(self.color)
        self.main_circle = CEllipse(cpos=self.storage_pos,
                                    csize=(self.size, self.size))
        self.add(self.main_circle)

        self.middle_size = self.size / 2

        self.teeth = []
        self.num_teeth = num_teeth
        self.add_teeth(self.storage_pos, self.num_teeth)

        self.is_draggable = False
        self.in_music_box = False

        self.touch_x_diff = None
        self.touch_y_diff = None

        self.time = 0
        self.rpm = 0.1
        self.is_rotating = False

    def update_music_pos(self, pos):
        self.box_pos = pos

    def update_storage_pos(self, pos):
        self.storage_pos = pos

    def _get_color(self):
        if self.type == 'volume':
            return colors["red"]
        elif self.type == 'pitch':
            return colors["orange"]
        elif self.type == 'tempo':
            return colors["purple"]
        elif self.type == 'center':
            return Color(rgb=hex_to_rgb('#5e6f81'))
        elif self.type == 'center1':
            return colors["trout"]
        else:
            return colors["yellow"]

    def add_teeth(self, center, num_teeth):
        for tooth in self.teeth:
            self.remove(tooth)

        self.teeth = []
        self.add(self.color)
        self.add(PushMatrix())
        self.add(Translate(center))

        # use this Rotate to animate rotation for the whole flower
        self.rot = Rotate(angle=0, origin=self.storage_pos)
        self.add(self.rot)

        # make petals ellipses with these width and height:
        self.middle_size = self.size / 2
        w = self.size / 5
        h = self.size / 5

        # how much to rotate each petal.
        d_theta = 360. / num_teeth

        for n in range(num_teeth):
            self.add(Rotate(angle=d_theta, origin=center))
            self.add(Translate(self.middle_size, 0))
            rect = CRectangle(cpos=center, csize=(h, w))
            self.teeth.append(rect)
            self.add(rect)
            self.add(Translate(-self.middle_size, 0))

        self.add(PopMatrix())

    def on_layout(self, pos, size):
        self.size = size
        if self.in_music_box:
            self._update_graphics(self.box_pos)
            self.rot.origin = self.box_pos
        else:
            self._update_graphics(pos)
            self.rot.origin = pos

        self.main_circle.set_csize((size, size))

    def stop(self):
        self.is_rotating = False

    def toggle_rotate(self):
        self.is_rotating = not self.is_rotating
        return self.is_rotating

    def _update_graphics(self, position):
        self.main_circle.set_cpos(position)
        self.add_teeth(position, self.num_teeth)

    def reset(self):
        self._update_graphics(self.storage_pos)
        self.rot.origin = self.storage_pos
        self.in_music_box = False

    def get_distance_from_center(self, touch):
        return sqrt((touch[0] - self.main_circle.get_cpos()[0])**2 +
                    (touch[1] - self.main_circle.get_cpos()[1])**2)

    def on_touch_down(self, touch):
        distance = self.get_distance_from_center(touch)

        if distance <= self.size / 2 and distance >= self.middle_size / 2:
            self.is_draggable = True
            self.touch_x_diff = touch[0] - self.main_circle.get_cpos()[0]
            self.touch_y_diff = touch[1] - self.main_circle.get_cpos()[1]

            return True

        if self.type == 'center' and distance <= self.size:
            self.is_draggable = True
            self.touch_x_diff = touch[0] - self.main_circle.get_cpos()[0]
            self.touch_y_diff = touch[1] - self.main_circle.get_cpos()[1]
            return True

        return False

    def on_touch_up(self, touch, gear_box_x, can_add_gear):
        # if it was previously dragged, update it to the correct location
        if self.is_draggable:
            if touch[0] <= gear_box_x or not can_add_gear(self):
                self._update_graphics(self.storage_pos)
                self.rot.origin = self.storage_pos
                self.in_music_box = False
            else:
                self._update_graphics(self.box_pos)
                self.rot.origin = self.box_pos
                self.in_music_box = True

        self.is_draggable = False
        return self.in_music_box

    def on_touch_move(self, touch):
        if self.is_draggable:
            self._update_graphics(
                (touch[0] - self.touch_x_diff, touch[1] - self.touch_y_diff))
            self.rot.origin = (touch[0] - self.touch_x_diff,
                               touch[1] - self.touch_y_diff)
            return True
        return False

    def on_update(self, dt, multiple=False):
        if not multiple:
            if self.type == 'center':
                direction = -1
            else:
                direction = 1
        else:
            if self.type == 'center':
                direction = -1
            elif self.type == 'center1':
                direction = 1
            else:
                direction = -1

        if self.is_rotating:
            degrees_per_sec = self.rpm * 360 / 60
            self.rot.angle = degrees_per_sec * self.time
            self.time += direction * dt