class LoopBars(object): def __init__(self, width, height, canvas): self.width = width self.height = height self.start = 0 self.canvas = canvas self.loop = False self.loops = InstructionGroup() def loop_func(self, loop): if loop: loopL = Line(points=[30+20,self.height,30+20,0]) loopR = Line(points=[30+70,self.height,30+70,0]) handle_size=(20,20) top_padding = 20 loopHandleL = Rectangle(pos=(loopL.points[0]-(handle_size[0]/2),self.height-top_padding), size=handle_size) loopHandleR = Rectangle(pos=(loopR.points[0]-(handle_size[0]/2),self.height-top_padding), size=handle_size) self.loops.add(Color(0,1,1)) self.loops.add(loopL) self.loops.add(Color(1,0,1)) self.loops.add(loopR) self.loops.add(loopHandleL) self.loops.add(loopHandleR) self.canvas.add(self.loops) else: self.canvas.remove(self.loops) self.loops.clear() def drag_loop_bar(self, loop): # only move loop line if dragged by handle pass
class Renderer(Widget): def __init__(self, **kw): self.shader_file = kw.pop("shader_file", None) self.canvas = Canvas() super(Renderer, self).__init__(**kw) with self.canvas: self._viewport = Rectangle(size=self.size, pos=self.pos) self.fbo = Fbo(size=self.size, with_depthbuffer=True, compute_normal_mat=True) self._config_fbo() self.texture = self.fbo.texture self.camera = None self.scene = None def _config_fbo(self): # set shader file here self.fbo.shader.source = self.shader_file or \ os.path.join(kivy3_path, "default.glsl") with self.fbo: Callback(self._setup_gl_context) PushMatrix() # instructions set for all instructions self._instructions = InstructionGroup() PopMatrix() Callback(self._reset_gl_context) def _setup_gl_context(self, *args): glEnable(GL_DEPTH_TEST) self.fbo.clear_buffer() def _reset_gl_context(self, *args): glDisable(GL_DEPTH_TEST) def render(self, scene, camera): self.scene = scene self.camera = camera self.camera.bind_to(self) self._instructions.add(scene.as_instructions()) Clock.schedule_once(self._update_matrices, -1) def on_size(self, instance, value): self.fbo.size = value self._viewport.texture = self.fbo.texture self._viewport.size = value self._update_matrices() def on_texture(self, instance, value): self._viewport.texture = value def _update_matrices(self, dt=None): if self.camera: self.fbo['projection_mat'] = self.camera.projection_matrix self.fbo['modelview_mat'] = self.camera.modelview_matrix else: raise RendererError("Camera is not defined for renderer") def set_clear_color(self, color): self.fbo.clear_color = color
class AltLabel(BoxLayout): """ """ active = BooleanProperty(False) def __init__(self, **kwargs): super(AltLabel, self).__init__(**kwargs) self.onColor = (1, 0, 0, 1) self.offColor = (0, 1, 0, 1) self.bold = False self.font_size = 14 self.instr = InstructionGroup() self.canvas.before.add(self.instr) def on_active(self, *args): self.evaluateColor() def evaluateColor(self): print("Evaluating") if self.active: self.colorTuple = self.onColor else: self.colorTuple = self.offColor self.instr.clear() self.instr.add(Color(*self.colorTuple)) self.instr.add(Rectangle(pos=self.pos, size=self.size)) def on_size(self, *args): self.evaluateColor()
def create_shadowed_background(self, *args): focus_window_pos, focus_window_size = self.calculate_focus_window_pos_n_size( ) focus_window_width, focus_window_height = focus_window_size[ 0], focus_window_size[1] focus_window_x, focus_window_y = focus_window_pos[0], focus_window_pos[ 1] window_width, window_height = self.screen_utils.window.size[ 0], self.screen_utils.window.size[1] background = InstructionGroup() background.add(Color(0, 0, 0, 0.5)) background.add( Rectangle(pos=(0, 0), size=(focus_window_x, window_height))) background.add( Rectangle(pos=(focus_window_x, 0), size=(window_width - focus_window_x, focus_window_y))) background.add( Rectangle(pos=(focus_window_x, focus_window_y + focus_window_height), size=(window_width - focus_window_x, window_height - focus_window_y - focus_window_height))) background.add( Rectangle(pos=(focus_window_x + focus_window_width, focus_window_y), size=(window_width - focus_window_width - focus_window_x, focus_window_height))) self.background = background self.canvas.before.add(background)
def make_demo_line(self, x, y): c1 = self.bright_color() l1 = Line(points=(x, y), width=10) line = InstructionGroup(group='demo') line.add(c1) line.add(l1) return line
class String(Widget): string_tuning = ObjectProperty(None) def __init__(self, active_fret=None, *args, **kwargs): super().__init__(**kwargs) self.active_fret = active_fret self.active_rect = InstructionGroup() self.bind(size=self._update_canvas, pos=self._update_canvas) def _update_canvas(self, instance, value): self._update_note(instance, value) def _update_note(self, instance, value): self.active_rect.clear() if self.active_fret is None: return left, right = self.parent.fret_ranges[self.active_fret] width = right - left x_pos = left self.active_rect.add(Color(1, 1, 1, 0.2)) self.active_rect.add( Rectangle(size=[width, self.height], pos=[x_pos, self.y])) self.canvas.add(self.active_rect) def _clear_note(self): self.active_rect.clear() def _play_note(self, fret_num): self.active_fret = fret_num self._update_note(None, None)
def add_explosion(self, line): line += self.currently_exploding self.currently_exploding += 1 explosion = InstructionGroup() color = Color(1, 1, .5, .8) explosion.add(color) explosion.add(Rectangle( pos=self.coord_to_pos(0, line), size=( self.tile_size()[0] * self.cols, self.tile_size()[1] ) )) self.canvas.add(explosion) def remove(self): self.canvas.remove(explosion) self.currently_exploding -= 1 anim = Animation( a=0, duration=.125 ) anim.bind(on_complete=lambda *args: remove(self)) anim.start(color)
def __init__(self, *args, **kwargs): super(LevelProgressBar, self).__init__(*args, **kwargs) texture = Texture.create(size=(1, 16)) size = 1 * 16 * 3 buf = [ int( Color(.66 - (float(data) / size) * .66, .75, .75, mode='hsv').rgb[data % 3] * 255) for data in range(size) ] buf = b''.join(map(chr, buf)) texture.blit_buffer(buf, colorfmt='rgb', bufferfmt='ubyte') self.progress_bar = Rectangle(texture=texture) self.progress_mask = Rectangle() group = InstructionGroup() group.add(Color(0, 0, 0)) group.add(self.progress_mask) self.canvas.add(Color(1, 1, 1)) self.canvas.add(self.progress_bar) self.canvas.add(group) self.bind(pos=self.redraw, size=self.redraw)
def __init__(self, grid_path: Path, grid_properties: GridProperties): self._grid_properties = grid_properties self._grid_path = grid_path container_instruction_group = InstructionGroup() container_instruction_group.add(Color(1, 0, 0)) points = [grid_properties.to_pixels(*point) for point in grid_path] container_instruction_group.add(Line(points=points)) d = 15 x, y = self._agent_position container_instruction_group.add( Ellipse(pos=(x - d / 2, y - d / 2), size=(d, d)) ) self.instruction_groups = [container_instruction_group] rectangle_diameter = 10 for resource in grid_path.resources: resource_instruction_group = InstructionGroup() resource_instruction_group.add(COLOR_FROM_RESOURCE[resource]) resource_instruction_group.add( Rectangle( pos=(x - rectangle_diameter / 2, y - rectangle_diameter / 2), size=(rectangle_diameter, rectangle_diameter), ) ) self.instruction_groups.append(resource_instruction_group)
class FloatButtonWidget(ButtonBehavior, AnchorLayout): __shape_up__ = None __shape_down__ = None def collide_point(self, x, y): return (x > self.x and x < self.x + self.width) and (y > self.y and y < self.y + self.height) def on_press(self): if self.__shape_down__ == None: self.__shape_down__ = InstructionGroup(grup="__shape_down__") else: self.canvas.remove(self.__shape_down__) self.__shape_down__.clear() color = Color(0, 0, 0, .4) self.__shape_down__.add(color) self.__shape_down__.add(Ellipse(pos=self.pos, size=self.size)) self.canvas.add(self.__shape_down__) super(FloatButtonWidget, self).on_press() def on_release(self): self.canvas.remove(self.__shape_down__) self.__shape_down__.clear() super(FloatButtonWidget, self).on_release()
class MenuIcon(Widget): #spawns moving icon on touch def __init__(self, **kwargs): super(MenuIcon,self).__init__(**kwargs) self.local_c=[0,0] self.r=30 if kwargs is not None: for key, value in kwargs.items(): if(key=='pos'): self.local_c=value self.icon=InstructionGroup() self.icon.add(Color(1,1,1)) self.icon.add(Ellipse(size=(2*self.r,2*self.r),pos=(self.local_c[0]-self.r,self.local_c[1]-self.r))) self.icon.add(SmoothLine(circle=(self.local_c[0],self.local_c[1],self.r+4),width=3)) self.icon.add(Color(.3,.3,.3)) self.icon.add(SmoothLine(circle=(self.local_c[0],self.local_c[1],self.r),width=3)) for group in [self.icon]: self.canvas.add(group) def options(self): pass def on_touch_down(self,touch): if get_dis(self.local_c,touch.pos) < 40: a=MovingIcon(pos=touch.pos) a.init(self.r*.8) self.parent.add_widget(a)#adds moving icon to screen
def capture(self): ''' Function to capture the images and give them the names according to their captured time and date. ''' camera = self.ids['camera'] #timestr = time.strftime("%Y%m%d_%H%M%S") #camera.export_to_png("IMG_{}.png".format(timestr)) #print(requests.get('http://127.0.0.1:5000')) print(camera.texture.height) print(camera.texture.width) print(len(camera.texture.pixels)) data = requests.post('http://127.0.0.1:5000/image', data={"height":str(camera.texture.height), "width": str(camera.texture.width)}, files={'media': camera.texture.pixels}).text #Fix Later people = eval(data) people = [list(map(lambda: (x[0], x[1], 1-x[2]), person)) for person in people] while len(self.dots) > 0: camera.canvas.remove(self.dots.pop()) for person in people: for keypoint in person: dot = InstructionGroup() dot.add(Color(1., 0, 0)) (x, y), size = relative_coord_to_pixel((keypoint[1], keypoint[2]), dot_size, camera.pos, camera.size) dot.add(Ellipse(pos=(x, y), size=size)) camera.canvas.add(dot) self.dots.append(dot)
def __init__(self, *args, **kwargs): super(LevelProgressBar, self).__init__(*args, **kwargs) texture = Texture.create(size=(1, 16)) size = 1 * 16 * 3 buf = [ int(Color( .66 - (float(data) / size) * .66, .75, .75, mode='hsv' ).rgb[data % 3] * 255) for data in range(size) ] buf = b''.join(map(chr, buf)) texture.blit_buffer(buf, colorfmt='rgb', bufferfmt='ubyte') self.progress_bar = Rectangle(texture=texture) self.progress_mask = Rectangle() group = InstructionGroup() group.add(Color(0, 0, 0)) group.add(self.progress_mask) self.canvas.add(Color(1, 1, 1)) self.canvas.add(self.progress_bar) self.canvas.add(group) self.bind(pos=self.redraw, size=self.redraw)
class LabelClicableBase(ButtonBehavior, LabelBase): tag = ObjectProperty(None, allowNone=True) def __init__(self, **kargs): super(LabelClicableBase, self).__init__(**kargs) self.shape_down = None def collide_point(self, x, y): return (x > self.x and x < self.x + self.width) and (y > self.y and y < self.y + self.height) def on_touch_down(self, touch, *args): if self.collide_point(touch.x, touch.y): size = ceil(self.height * 0.7), ceil(self.height * 0.7) w, h = size pos = touch.x - w / 2, touch.y - h / 2 if self.shape_down == None: self.shape_down = InstructionGroup(group="shape_down") else: self.container.canvas.before.remove(self.shape_down) self.shape_down.clear() color = Color(0, 0, 0, .4) self.shape_down.add(color) self.shape_down.add(Ellipse(pos=pos, size=size)) self.container.canvas.before.add(self.shape_down) Clock.schedule_once(self.remove_shape_down, .05) super(LabelClicableBase, self).on_touch_down(touch) return True def remove_shape_down(self, dt): self.container.canvas.before.remove(self.shape_down) self.shape_down.clear()
class HeaderLabel(Label): def __init__(self, **kwargs): self.instr = InstructionGroup() self.bgColor_255 = (60,60,60,255) #BG color in the 0 to 255 scale #Using map to produce a tuple scale 0 to 1 from a tuple scaled 0 to 255 self.bgColor_1 = tuple(list(map(lambda x: round(x/255, 3), self.bgColor_255))) super(HeaderLabel, self).__init__(**kwargs) # Customizing the visuals self.canvas.before.add(self.instr) self.color = (1, 1, 1, 1) #Font color in the 0 to 1 scale self.bold = True self.font_size = 20 def on_pos(self, *args): self.evaluateColor() def on_size(self, *args): self.evaluateColor() def evaluateColor(self): self.instr.clear() self.instr.add(Color(*self.bgColor_1)) #BG self.instr.add(Rectangle(pos=self.pos, size=self.size))
def make_line(self, touch): c1 = self.bright_color() l1 = Line(points=(touch.x, touch.y), width=10) line = InstructionGroup(group='line') line.add(c1) line.add(l1) return line
def clear_canvas(self, obj): with self.paint_widget.canvas: self.paint_widget.canvas.clear() #self.paint_widget.canvas.ClearColor(1,1,1,0) clear = InstructionGroup() clear.add(Color(1, 1, 1, 0)) clear.add(Rectangle(pos=self.pos, size=self.size)) self.paint_widget.canvas.add(clear)
def draw_line(self, line, line_width=1, color=(0, 0, 0)): instructions = InstructionGroup() self.set_color(instructions, color) instructions.add( Line(points=[(line.start.x, line.start.y), (line.end.x, line.end.y)], width=line_width)) self.canvas.add(instructions)
def draw_line(self, next_hold_coordinates): group_of_lines = InstructionGroup() group_of_lines.add( Line(width=2., points=(self.last_hold_coordinates[0], self.last_hold_coordinates[1], next_hold_coordinates[0], next_hold_coordinates[1]))) self.line_objects.append(group_of_lines) self.canvas.add(group_of_lines)
def select(self): if self.border is not None: return border = InstructionGroup() border.add(Color(232 / 256, 58 / 256, 88 / 256, 1)) border.add( Line(width=2, rectangle=(self.x, self.y, self.width, self.height))) self.border = border self.parent.canvas.add(self.border)
def change_foreground_color(self, s, state): """修改前景色""" front_color = Color(0, 1, 0, .8) # 修改此处可更改前景色 front = InstructionGroup() front.add(front_color) front.add(Rectangle(pos=self.pos, size=self.size)) if state == 'normal': self.canvas.after.clear() else: self.canvas.after.add(front)
def put_pixel(x, y, color, canvas, token, alpha=None, thickness=2): r, g, b = color.r, color.g, color.b c = Color(r, g, b) if alpha: c.a = alpha group = InstructionGroup(group=token) group.add(c) group.add(Rectangle(pos=(x, y), size=(thickness, thickness))) canvas.add(group)
def __init__(self, body, size, texture=None, halfShift=True): ig = InstructionGroup() ig.add(Color(1,1,1, 1.0)) ig.add(Rectangle(pos=(0,0), size=size, texture=texture)) offset = None if halfShift: offset = [-1.0*s/2.0 for s in size] super(TextrueRect, self).__init__(body, instruction=ig, offset=offset)
def _paint_digit(self): label = CoreLabel(text=str(self._resource_count), font_size=20) label.refresh() text = label.texture instruction_group = InstructionGroup() instruction_group.add(Color(1, 1, 1)) instruction_group.add( Rectangle(size=text.size, pos=(self._x, self._y), texture=text)) self.instruction_groups.append(instruction_group)
class PaintAreaBackgroundWidget(RelativeLayout): selectedColor = ListProperty([1,0,0,1]) def __init__(self, *args, **kwargs): super(PaintAreaBackgroundWidget, self).__init__(*args, **kwargs) self.lineGroup = None self.line = None self.isDrawing = False def on_touch_down(self, touch): # only draw if no widget is selected if self.paintWidget.selectedItem is None: if self.collide_point(*touch.pos): self.isDrawing = True width = self.lineWidth self.lineGroup = InstructionGroup() #print self.lineGroup self.line = Line(points=(touch.x, touch.y),width=width,dash_offset=2) self.lineGroup.add(Color(*self.selectedColor)) self.lineGroup.add(self.line) self.canvas.add(self.lineGroup) def on_touch_move(self, touch): if self.paintWidget.selectedItem is None: if self.collide_point(*touch.pos): self.line.points += [touch.x, touch.y] def on_touch_up(self, touch): if self.paintWidget.selectedItem is None: if self.collide_point(*touch.pos) and len(self.line.points)>1: self.canvas.remove(self.lineGroup) lp = numpy.array(self.line.points) scatterPolyLine = ScatterPolyLineWidget(paintWidget=self.paintWidget, linePoints=lp, lineWidth=self.lineWidth, lineColor=self.selectedColor) self.line.points = [] scatterPolyLine.pos = [scatterPolyLine.minX, scatterPolyLine.minY] #.size = polyLineWidget.size self.addPaintedThingsWidget.add_widget(scatterPolyLine) #self.addedOne = True self.isDrawing = False
def __init__(self, **kwargs): Widget.__init__(self, **kwargs) # create keyboard self.keyboard = Window.request_keyboard(self.keyboard_closed, self) self.keyboard.bind(on_key_down=self.on_keyboard_down) # custom events self.register_event_type('on_land') self.bind(on_land=self.check_landing) # canvas core labels self.lose_label = CoreLabel(text='', font_size=40) self.lose_label.refresh() self.lose_instruction = Rectangle(texture=self.lose_label.texture, pos=(85, 430), size=self.lose_label.texture.size) self.aim_label = CoreLabel(text='', font_size=20) self.aim_label.refresh() self.aim_instruction = Rectangle(texture=self.aim_label.texture, pos=(415, 300), size=self.aim_label.texture.size) self.score_label = CoreLabel(text='Score: 0', font_size=20) self.score_label.refresh() self.score_instruction = Rectangle(texture=self.score_label.texture, pos=(400, 530), size=self.score_label.texture.size) self.speed_label = CoreLabel(text='Speed: 1.0', font_size=20) self.speed_label.refresh() self.speed_instruction = Rectangle(texture=self.speed_label.texture, pos=(400, 485), size=self.speed_label.texture.size) self.canvas.add(self.lose_instruction) self.canvas.add(self.score_instruction) self.canvas.add(self.aim_instruction) self.canvas.add(self.speed_instruction) # graphics line_instruction = InstructionGroup() line_instruction.add(Color(1, 1, 1, 1)) line_instruction.add(Line(points=[0, 518, 500, 518], width=2)) self.canvas.add(line_instruction) self.canvas.add(self.next_block.instruction) # run these functions continuously Clock.schedule_interval(self.move_tower, 0.02) Clock.schedule_interval(self.move_block, 0.04) Clock.schedule_interval(self.drop_block, 0) Clock.schedule_interval(self.check_tower, 0)
def dessinerFond(case): dessin_fond = InstructionGroup() dessin_fond.add(blanc) dessin_fond.add(Rectangle(pos=case.pos, size=case.size)) label = Label(text=str(case.X) + ',' + str(case.Y), font_size=int(case.largeur / 5), color=gris_clair.rgba) label.texture_update() texture = label.texture dessin_fond.add( Rectangle(texture=texture, pos=[case.x, case.y], size=label.texture.size))
def on_enter(self, *args): if not hasattr(self.app.root, "error_message"): return None self.clear_widgets() menu_background = InstructionGroup() menu_background.add(Color(*GlobalStyle.error_screen_background_color)) menu_background.add(Rectangle(pos=self.pos, size=self.size)) self.canvas.add(menu_background) v_layout = BoxLayout(orientation="vertical") label = Label(text="Error", font_name=GlobalStyle.extrabold_caption_font, font_size=GlobalStyle.huge_caption_font_size, text_size=self.size, halign="center", valign="middle", size_hint_y=40) v_layout.add_widget(label) label = Label(text=self.app.root.error_message, font_name=GlobalStyle.semibold_caption_font, font_size=GlobalStyle.big_caption_font_size, text_size=self.size, halign="center", valign="middle", size_hint_y=40) v_layout.add_widget(label) h_layout = BoxLayout(orientation="horizontal", size_hint_y=20, padding=[0, 0, 0, 20], spacing=40) dummy = Label(size_hint_x=1) h_layout.add_widget(dummy) menu_button = Button(size_hint=(None, None), size=GlobalStyle.standard_button_size, border=(0, 0, 0, 0), background_normal=image('menu'), background_down=image('menu_pressed')) menu_button.bind(on_release=self.menu_button_callback) h_layout.add_widget(menu_button) dummy = Label(size_hint_x=1) h_layout.add_widget(dummy) v_layout.add_widget(h_layout) self.add_widget(v_layout)
def get_graphics(self, gc, polygons, points_line, rgbFace, closed=False): '''Return an instruction group which contains the necessary graphics instructions to draw the respective graphics. ''' instruction_group = InstructionGroup() if isinstance(gc.line['dash_list'], tuple): gc.line['dash_list'] = list(gc.line['dash_list']) if rgbFace is not None: if len(polygons.meshes) != 0: instruction_group.add(Color(*rgbFace)) for vertices, indices in polygons.meshes: instruction_group.add( Mesh(vertices=vertices, indices=indices, mode=str("triangle_fan"))) instruction_group.add(Color(*gc.get_rgb())) if _mpl_1_5 and closed: points_poly_line = points_line[:-2] else: points_poly_line = points_line if gc.line['width'] > 0: instruction_group.add( Line(points=points_poly_line, width=int(gc.line['width'] / 2), dash_length=gc.line['dash_length'], dash_offset=gc.line['dash_offset'], dash_joint=gc.line['joint_style'], dash_list=gc.line['dash_list'])) return instruction_group
def get_graphics(self, gc, polygons, points_line, rgbFace, closed=False): '''Return an instruction group which contains the necessary graphics instructions to draw the respective graphics. ''' instruction_group = InstructionGroup() if isinstance(gc.line['dash_list'], tuple): gc.line['dash_list'] = list(gc.line['dash_list']) if rgbFace is not None: if len(polygons.meshes) != 0: instruction_group.add(Color(*rgbFace)) for vertices, indices in polygons.meshes: instruction_group.add(Mesh( vertices=vertices, indices=indices, mode=str("triangle_fan") )) instruction_group.add(Color(*gc.get_rgb())) if _mpl_1_5 and closed: points_poly_line = points_line[:-2] else: points_poly_line = points_line if gc.line['width'] > 0: instruction_group.add(Line(points=points_poly_line, width=int(gc.line['width'] / 2), dash_length=gc.line['dash_length'], dash_offset=gc.line['dash_offset'], dash_joint=gc.line['joint_style'], dash_list=gc.line['dash_list'])) return instruction_group
def clone(self): new_left_line = Line() new_left_line.points = [ self.left_line.points[0], self.left_line.points[1], self.left_line.points[2], self.left_line.points[3] ] new_right_line = Line() new_right_line.points = [ self.right_line.points[0], self.right_line.points[1], self.right_line.points[2], self.right_line.points[3] ] new_top_line = Line() new_top_line.points = [ self.top_line.points[0], self.top_line.points[1], self.top_line.points[2], self.top_line.points[3] ] new_bottom_line = Line() new_bottom_line.points = [ self.bottom_line.points[0], self.bottom_line.points[1], self.bottom_line.points[2], self.bottom_line.points[3] ] rect_lines = InstructionGroup() rect_lines.add(new_left_line) rect_lines.add(new_right_line) rect_lines.add(new_top_line) rect_lines.add(new_bottom_line) new_rect = Rectangle(new_left_line, new_bottom_line, new_right_line, new_top_line, rect_lines) new_rect.set_string(self.get_text()) return new_rect
class Mute(InstructionGroup): def __init__(self, size=20, pos=(100, 100), color=Color(50 / 255, 1, 0)): super(Mute, self).__init__() x1 = pos[0] - size / 2 x2 = pos[0] + size / 2 y1 = pos[1] - size / 2 y2 = pos[1] + size / 2 self.x = InstructionGroup() self.x.add(color) line1 = Line(points=[x1, y2, x2, y1], width=size * .15, cap='square') line2 = Line(points=[x1, y1, x2, y2], width=size * .15, cap='square') self.x.add(line1) self.x.add(line2) self.add(self.x)
class ColorBoxLayout(BoxLayout): def __init__(self, color=Color(142/255, 206/255, 229/255, 1),**kwargs): self.bg = InstructionGroup() self.color_widget = color self._rectangle = Rectangle() self.bg.add(self.color_widget) self.bg.add(self._rectangle) super(ColorBoxLayout, self).__init__(**kwargs) self.canvas.add(self.bg) def on_size(self, *args): if self._rectangle != None: self._rectangle.size = self.size self._rectangle.pos = self.pos
class PrTracks: """ PrTracks ======== provides object which manage track instruction groups 1. Container instruction group for canvas 2. List of PrTracks 3. show/hide tracks 4. z-order handling """ def __init__(self): self.container = InstructionGroup() self.tracks = {} def get(self, idx): if idx in self.tracks: return self.tracks[idx] def add(self, idx, track): self.tracks[idx] = track self.container.add(track.canvas) def remove(self, idx): self.container.remove(self.tracks[idx].canvas) self.tracks[idx] = None def show(self, idx): track = self.tracks[idx] if track: if self.tracks[idx].visible == False: # self.container.add(track.canvas) # track.visible = True track.show() def hide(self, idx): track = self.tracks[idx] if track: if self.tracks[idx].visible: # self.container.remove(track.canvas) # track.visible = False track.hide() def draw(self): self.container.clear() for key in self.tracks: self.container.add(self.tracks[key].canvas) return self.container
def on_data(self, *args): self.clear_widgets() instance, data = args # TODO: move to draw_static menu_background = InstructionGroup() menu_background.add(Color(*GlobalStyle.menu_background_color)) menu_background.add(Rectangle(pos=self.pos, size=self.size)) self.canvas.add(menu_background) v_layout = BoxLayout(orientation="vertical") label = Label(text=data['text'], halign='center', font_name=GlobalStyle.standard_caption_font, font_size=GlobalStyle.big_caption_font_size, size_hint_y=80) v_layout.add_widget(label) h_layout = BoxLayout(orientation="horizontal", size_hint_y=20, padding=[0, 0, 0, 20], spacing=40) dummy = Label(size_hint_x=1) h_layout.add_widget(dummy) ok_button = Button(size_hint=(None, None), size=GlobalStyle.standard_button_size, border=(0, 0, 0, 0), background_normal=image('ok'), background_down=image('ok_pressed')) ok_button.bind(on_release=data['ok_callback']) h_layout.add_widget(ok_button) cancel_button = Button(size_hint=(None, None), size=GlobalStyle.standard_button_size, border=(0, 0, 0, 0), background_normal=image('x'), background_down=image('x_pressed')) cancel_button.bind(on_release=data['cancel_callback']) h_layout.add_widget(cancel_button) dummy = Label(size_hint_x=1) h_layout.add_widget(dummy) v_layout.add_widget(h_layout) self.add_widget(v_layout)
def selection(widget, select=False): """ Emphasizes the widget adding a clear transparent background. """ 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!
class Sprite(): def __init__(self, **kwargs): self.canvas = InstructionGroup() self.sizeScalar = 50 self.color = Color(0.0, 0.5, 0.2) self.centerPos = (MIDDLE_X, MIDDLE_Y) self.rect = Rectangle(pos=(330, 220), size=(50, 45)) self.setCenterPos((330, 220)) self.repos() self.canvas.add(self.color) self.canvas.add(self.rect) def repos(self): size = (self.sizeScalar, self.sizeScalar * ASPECT) self.rect.pos = (self.centerPos[0] - (size[0] / 2), self.centerPos[1] - (size[1] / 2)) self.rect.size = size def setSizeScalar(self, sizeScalar): self.sizeScalar = sizeScalar self.repos() def setCenterPos(self, centerPos): self.centerPos = centerPos self.repos() def collidesWithLine(self, lineCoords): halfWidth = self.rect.size[0] / 2 halfHeight = self.rect.size[1] / 2 topLeft = (self.centerPos[0] - halfWidth, self.centerPos[1] + halfHeight) topRight = (self.centerPos[0] + halfWidth, self.centerPos[1] + halfHeight) bottomLeft = (self.centerPos[0] - halfWidth, self.centerPos[1] - halfHeight) bottomRight = (self.centerPos[0] + halfWidth, self.centerPos[1] - halfHeight) intersection1 = Vector.segment_intersection(topLeft, bottomRight, (lineCoords[0], lineCoords[1]), (lineCoords[2], lineCoords[3])) intersection2 = Vector.segment_intersection(bottomLeft, topRight, (lineCoords[0], lineCoords[1]), (lineCoords[2], lineCoords[3])) return True if intersection1 or intersection2 else False
def calc_hillbodies(self, force, planet): # typecasting problem while crosscompiling foo = App.get_running_app().config.get('planetapp','showforcemode') if foo == u'0': return if ((force / self.mass) > (self.showforcelimit * 0.0002)): if not planet.fixed: if not planet in self.hillbodies: self.hillbodies.append(planet) else: if planet in self.hillbodies: self.hillbodies.remove(planet) for dude in self.canvas.children: if 'InstructionGroup' in type(dude).__name__: self.canvas.remove(dude) shit = InstructionGroup() for body in self.hillbodies: shit.add(Line(points=(self.center_x,self.center_y, body.center_x,body.center_y), width=1, group=str(self.uid))) if len(self.hillbodies) > 0: self.canvas.add(shit) if self.drawtrajectory and not self.fixed: shit2 = InstructionGroup() sunpos = (self.parent.width/2,self.parent.height/2) trajectory = self.parent.calc_trajectory((self.center_x,self.center_y), self.velocity, self.mass, sunpos, self.parent.sunmass, 1, 1000) shit2.add(Line(points=trajectory, width=1, group=str(self.uid))) self.canvas.add(shit2) else: pass
def calc_hillbodies(self, force, planet): # typecasting problem while crosscompiling foo = Utilitys.get_app_config('planetapp','showforcemode') if foo == u'0': return if ((force / self.mass) > (self.showforcelimit * 0.0002)): if not planet.fixed: if not planet in self.hillbodies: self.hillbodies.append(planet) else: if planet in self.hillbodies: self.hillbodies.remove(planet) for dude in self.canvas.children: if 'InstructionGroup' in type(dude).__name__: self.canvas.remove(dude) shit = InstructionGroup() for body in self.hillbodies: shit.add(Line(points=(self.center_x,self.center_y, body.center_x,body.center_y), width=1, group=str(self.uid))) if len(self.hillbodies) > 0: self.canvas.add(shit)
def __setitem__(self, key, cell): ret = super().__setitem__(key, cell) group = InstructionGroup() if cell.food == 0: group.add(self.color) group.add(Mesh(vertices=self._mesh_vertices(cell), indices=list(range(6)), mode=self.mesh_mode)) else: group.add(Color(0, 1, 0, 1)) group.add(Mesh(vertices=self._mesh_vertices(cell), indices=list(range(6)), mode='triangle_fan')) self.canvas_groups[key] = group self.canvas.add(group) return ret
def draw_point(point): token = str(hash(point)) group = InstructionGroup(group=token) point.obj.widget.canvas.remove_group(token) x, y = point.x, point.y if point.texture is not None: group.add( Ellipse( pos=(x - point.size/2, y - point.size/2), size=(point.size, point.size), texture=point.texture ) ) else: group.add(POINT_COLOR) group.add( Ellipse( pos=(x - point.size/2, y - point.size/2), size=(point.size, point.size) ) ) point.obj.widget.canvas.add(group)
class Player(): def __init__(self, playerCode, **kwargs): self.canvas = InstructionGroup() self.sprite = Sprite() self.playerCode = playerCode self.frameNum = 0 self.bottomLeft = (0, 0) self.topRight = (700, 500) self.pos = (0, 0) self.direction = (0, 0) self.speed = 0 self.targetDirection = (0, 0) self.targetSpeed = 0 self.isTweeningDirection = False self.isTweeningSpeed = False self.newDirectionSince = 0 self.newSpeedSince = 0 self.directionChange = (0, 0) if playerCode == 'p2': self.sprite.color.r = 1 if playerCode == 'enemy1': self.sprite.color.b = 1 self.canvas.add(self.sprite.canvas) def reset(self): self.frameNum = 0 def setBounds(self, bottomLeft, topRight): self.bottomLeft = bottomLeft self.topRight = topRight def setCenterPos(self, centerPos): self.pos = centerPos self.sprite.setCenterPos(self.pos) def setPlayerKeyReport(self, playerKeyReport): self.playerKeyReport = playerKeyReport def update(self, dt): self.frameNum += 1 self.updateDynamics() self.updateTweening() self.updatePosition() def updateDynamics(self): dX = 0 dY = 0 scale = 1 speed = 0 if self.playerKeyReport.up: dY = 1 elif self.playerKeyReport.down: dY = -1 if self.playerKeyReport.left: dX = -1 elif self.playerKeyReport.right: dX = 1 if not dY == 0 and not dX == 0: scale = SQRT_2_DIV_2 if not dY == 0 or not dX == 0: speed = TOP_SPEED targetDirection = (dX * scale, dY * scale) wasNullDirection = (self.targetDirection[0] == 0 and self.targetDirection[1] == 0) isNullDirection = (targetDirection[0] == 0 and targetDirection[1] == 0) isNewTargetDirection = (not self.targetDirection[0] == targetDirection[0] or not self.targetDirection[1] == targetDirection[1]) if not isNullDirection and isNewTargetDirection: if wasNullDirection: self.targetDirection = targetDirection self.direction = targetDirection else: self.isTweeningDirection = True self.newDirectionSince = self.frameNum self.targetDirection = targetDirection self.calculateDirectionVector() isNewTargetSpeed = not self.targetSpeed == speed if isNewTargetSpeed: self.isTweeningSpeed = True self.newSpeedSince = self.frameNum self.targetSpeed = speed def updateTweening(self): self.updateSpeedTweening() self.accountForZeroSpeed() self.updateDirectionTweening() def updateSpeedTweening(self): if not self.isTweeningSpeed: return speedDelta = 1 speedDirection = 1 speedTweeningContinues = True if self.targetSpeed < self.speed: speedDirection = -1 nextSpeed = self.speed + speedDirection * speedDelta if speedDirection == -1 and nextSpeed < self.targetSpeed: nextSpeed = self.targetSpeed speedTweeningContinues = False elif speedDirection == 1 and nextSpeed > self.targetSpeed: nextSpeed = self.targetSpeed speedTweeningContinues = False self.speed = nextSpeed self.isTweeningSpeed = speedTweeningContinues def accountForZeroSpeed(self): if self.speed == 0: self.isTweeningDirection = False self.targetDirection = (0, 0) self.direction = (0, 0) def calculateDirectionVector(self): subdivs = 5 vector = (self.targetDirection[0] - self.direction[0], self.targetDirection[1] - self.direction[1]) vectorLength = math.sqrt(math.pow(vector[0], 2) + math.pow(vector[1], 2)) self.directionChange = (vector[0] / (vectorLength * subdivs), vector[1] / (vectorLength * subdivs)) def updateDirectionTweening(self): if not self.isTweeningDirection: return nextDirection = self.direction directionTweeningContinues = True nextDirection = (self.direction[0] + self.directionChange[0], self.direction[1] + self.directionChange[1]) remainder = (nextDirection[0] - self.targetDirection[0], nextDirection[1] - self.targetDirection[1]) targetDirectionLen = math.sqrt(math.pow(self.targetDirection[0], 2) + math.pow(self.targetDirection[1], 2)) # "unrotate" the remainder by the target direction so we # can compare distance along that line. if False: dotA = self.targetDirection[0] * remainder[0] / targetDirectionLen dotB = self.targetDirection[1] * remainder[1] / targetDirectionLen dot = dotA + dotB didOvershoot = (dot < 0) ## Check if we went out of the unit circle len = math.pow(nextDirection[0], 2) + math.pow(nextDirection[1], 2) didOvershoot = len > 1 if didOvershoot: nextDirection = self.targetDirection directionTweeningContinues = False self.direction = nextDirection self.isTweeningDirection = directionTweeningContinues def updatePosition(self): if self.speed <= 0.001: return len = math.sqrt(math.pow(self.direction[0], 2) + math.pow(self.direction[1], 2)) if len == 0: return newCoords = (self.pos[0] + self.direction[0] * self.speed / len, self.pos[1] + self.direction[1] * self.speed / len) self.setCenterPos(newCoords)
class Enemy(): def __init__(self, enemyType, **kwargs): self.canvas = InstructionGroup() self.enemyType = enemyType self.sprite = Sprite() if self.enemyType == 'normal': self.setOffsetTheta(0) self.sprite.color.r = 0.0 self.sprite.color.g = 0.2 self.sprite.color.b = 0.5 else: self.setOffsetTheta(math.pi / 2) self.sprite.color.r = 0.5 self.sprite.color.g = 0.1 self.sprite.color.b = 0.1 self.health = 100 self.pos = (0, 0) self.velocity = [0, 0] self.updateAppearance() self.canvas.add(self.sprite.canvas) self.shouldRemove = False def setOffsetTheta(self, offsetTheta): self.offsetTheta = offsetTheta self.otcos = math.cos(self.offsetTheta) self.otsin = math.sin(self.offsetTheta) def reset(self, isRespawned): sample = random.random() theta = math.pi * 2 * sample speed = 0.1 self.isRespawned = isRespawned self.velocity = [math.cos(theta) * speed, math.sin(theta) * speed] def setWorld(self, world): self.world = world def setCenterPos(self, centerPos): self.pos = centerPos self.sprite.setCenterPos(centerPos) def decrement(self, beamState): delta = 0 if beamState == 1: self.health -= 10 if self.enemyType == 'normal': delta = 100 else: delta = -500 if self.health <= 0: self.shouldRemove = True else: self.updateAppearance() return delta def updateAppearance(self): baseSize = 30 if not self.enemyType == 'normal': baseSize = 15 factor = math.log(100 - self.health + 1) self.sprite.setSizeScalar(baseSize + factor * 10) def update(self, dt): worldVector = (self.world.direction[0] * self.world.speed, self.world.direction[1] * self.world.speed) worldOffset = (worldVector[0] * self.otcos - worldVector[1] * self.otsin, worldVector[0] * self.otsin - worldVector[1] * self.otcos) centerPos = (self.pos[0] + self.velocity[0] + worldOffset[0], self.pos[1] + self.velocity[1] + worldOffset[1]) if self.isRespawned: self.isRespawned = False if centerPos[0] < self.world.left: self.shouldRemove = True if centerPos[0] > self.world.right: self.shouldRemove = True if centerPos[1] < self.world.left: self.shouldRemove = True if centerPos[1] > self.world.right: self.shouldRemove = True self.setCenterPos(centerPos)
class EntityFollow(State): def __init__(self, target, following): super(EntityFollow, self).__init__(target) self.following = following self.cells = [] self.moving = False self.instructions = InstructionGroup() targeted = self.target.map.layers.by_name['below'].get_at(*self.following.pos) # targeted = self.target.map.layers.by_name['below'].get_neighbor_cells(following_cell)[0] origin_cell = self.target.map.layers.by_name['below'].get_at(*self.target.pos) if targeted is not None and targeted.tile.is_passable(): cells = targeted.layer.a_star_search(origin_cell, targeted) # if there's only two cells selected, and goal is not origin neighbor... then run away, RUN AWAY! if len(cells) == 2 and targeted not in self.target.map.layers.by_name['below'].get_neighbor_cells(origin_cell): return if len(cells) > 1: cells.reverse() # self.instructions.clear() self.instructions = InstructionGroup() # self.highlight_tiles(cells) self.cells = cells self.moving = False if not self.cells: print('no cells here dawg') self.target.state = EntityIdle(self.target) self.end() return # self.highlight_tiles(self.cells) self.foreshadowed = None self.velocity = [0, 0] self.target.anim_delay = .2 self.task = Clock.schedule_interval(self.slow_update, .6) def slow_update(self, *args): print([self.following.pos]) distance = Vector(*self.target.pos).distance(self.following.pos) if distance < 100: pass else: self.moving = False # self.instructions.clear() self.target.set_position(self.foreshadowed.px, self.foreshadowed.py) if distance > 500: self.target.state = EntityIdle(self.target) self.end() else: self.target.state = EntityFollow(self.target, self.following) self.end() def update(self, dt): if not self.moving: if self.cells: self.foreshadowed = self.cells.pop() print('moving to', self.foreshadowed) # if self.foreshadowed.occupied: # self.end() if self.foreshadowed.px != self.target.x: if self.foreshadowed.px < self.target.x: self.target.set_face('left') self.velocity = [self.target.map.tile_width * -1, 0] else: self.target.set_face('right') self.velocity = [self.target.map.tile_width, 0] elif self.foreshadowed.py != self.target.y: if self.foreshadowed.py < self.target.y: self.target.set_face('down') self.velocity = [0, self.target.map.tile_width * -1] else: self.target.set_face('up') self.velocity = [0, self.target.map.tile_width] self.start_moving() else: self.end() self.target.get_current_cell() self.target.state = EntityIdle(self.target) else: self.move(dt) def move(self, dt): done = move(dt, self.target, self.foreshadowed.px, self.foreshadowed.py) if done: self.done_moving() def done_moving(self, *args): self.target.set_position(self.foreshadowed.px, self.foreshadowed.py) self.moving = False def highlight_tiles(self, tiles): self.instructions.clear() for tile in tiles: self.instructions.add(Color(rgba=[.3, 1, .3, .3])) self.instructions.add(Rectangle(pos=(tile.px, tile.py), size=(tile.px_width, tile.px_height))) self.target.game.layer_widgets['below'].canvas.add(self.instructions) def start_moving(self, *args): print('start moving') self.moving = True def end(self): super(EntityFollow, self).end() self.task.cancel()
class RealtimeTouchMove(State): def __init__(self, target, cells, **kwargs): super(RealtimeTouchMove, self).__init__(target, **kwargs) self.cells = cells self.moving = False self.instructions = InstructionGroup() self.highlight_tiles(cells) self.foreshadowed = self.target._current_cell self.velocity = [0, 0] self.target.anim_delay = .2 self.movement_axis = 0 def touch(self, touch, *args): pos = self.target.map.pixel_from_screen(*touch.pos) cell = self.target.map.layers.by_name['below'].get_at(*pos) origin_cell = self.target.map.layers.by_name['below'].get_at(*self.target.pos) if cell is not None and cell.tile.is_passable(): cells = cell.layer.a_star_search(origin_cell, cell) # if there's only two cells selected, and goal is not origin neighbor... then run away, RUN AWAY! if len(cells) == 2 and cell not in self.target.map.layers.by_name['below'].get_neighbor_cells(origin_cell): return if len(cells) > 1: cells.reverse() self.instructions.clear() self.instructions = InstructionGroup() self.highlight_tiles(cells) self.cells = cells self.moving = False def update(self, dt): if not self.moving: self.check_moving() else: self.move(dt) def move(self, dt): delta_x = self.target.x - self.foreshadowed.px delta_y = self.target.y - self.foreshadowed.py distance = Vector(*self.target.pos).distance((self.foreshadowed.px, self.foreshadowed.py)) if distance >= 1.0: delta_x = (delta_x / distance) * (dt * 50) delta_y = (delta_y / distance) * (dt * 50) x, y = self.target.pos x += -delta_x y += -delta_y self.target.set_position(x, y) distance = Vector(*self.target.pos).distance((self.foreshadowed.px, self.foreshadowed.py)) if distance <= 1.0: self.check_moving() def done_moving(self, *args): self.target.set_position(self.foreshadowed.px, self.foreshadowed.py) self.moving = False def highlight_tiles(self, tiles): self.instructions.clear() for tile in tiles: self.instructions.add(Color(rgba=[.3, 1, .3, .3])) self.instructions.add(Rectangle(pos=(tile.px, tile.py), size=(tile.px_width, tile.px_height))) self.target.game.layer_widgets['below'].canvas.add(self.instructions) def check_moving(self, *args): last_axis = self.movement_axis last_cell = self.foreshadowed if self.cells: self.moving = True self.foreshadowed = self.cells.pop() print('moving to', self.foreshadowed.bottomleft) if self.foreshadowed.px != last_cell.px: self.movement_axis = 0 if self.foreshadowed.px < last_cell.px: self.target.set_face('left') self.velocity = [self.target.map.tile_width * -1, 0] else: self.target.set_face('right') self.velocity = [self.target.map.tile_width, 0] elif self.foreshadowed.py != last_cell.py: self.movement_axis = 1 if self.foreshadowed.py < last_cell.py: self.target.set_face('down') self.velocity = [0, self.target.map.tile_width * -1] else: self.target.set_face('up') self.velocity = [0, self.target.map.tile_width] if last_axis != self.movement_axis: print('axis changed!') print(self.target.pos) self.target.set_position(last_cell.px, last_cell.py) print(self.target.pos) print(last_cell.bottomleft, self.foreshadowed.bottomleft) else: self.done_moving() self.end() print('no cells') return self.target.activate_object(target='floor', button_press=False) def end(self): self.target.state = IdleReadyState(self.target) self.instructions.clear()
class SelectMoveState(State): def __init__(self, target, **kwargs): super(SelectMoveState, self).__init__(target, **kwargs) self.amount = self.target.map.tile_width self.moving = False self.velocity = [0, 0] self.layer = self.target.map.layers.by_name['below'] self.foreshadowed = self.layer.get_at(*target.center) self.current_tile = self.target.get_current_cell() self.move_keys = [Keyboard.keycodes['left'], Keyboard.keycodes['right'], Keyboard.keycodes['up'], Keyboard.keycodes['down'], Keyboard.keycodes['enter']] self.travelled = set() self.checked = set() self.index = {} self.instructions = InstructionGroup() self.layer = self.target.map.layers.by_name['below'] tile = self.layer.get_at(*self.target.pos) self.get_tiles_in_range(tile, 0) self.last_touched = None self.selected = [] self.highlight_tiles() def touch(self, touch, *args): print('touch!', touch) pos = self.target.map.pixel_from_screen(*touch.pos) cell = self.target.map.layers.by_name['below'].get_at(*pos) print('at {}. Found? {}'.format(pos, cell)) if cell is not None and cell in self.travelled: print('cell not none, found in travels') if cell is self.last_touched: self.target.set_position(cell.px, cell.py) self.end() else: self.last_touched = cell self.highlight_selected(cell) def highlight_selected(self, tile): if self.selected: for s in self.selected: self.instructions.remove(s) self.selected = [Color(rgba=[6, .3, .2, .6]), Rectangle(pos=(tile.px, tile.py), size=(tile.px_width, tile.px_height))] for a in self.selected: self.instructions.add(a) def highlight_tiles(self): for tile in self.travelled: self.instructions.add(Color(rgba=[.3, .5, .8, .5])) self.instructions.add(Rectangle(pos=(tile.px, tile.py), size=(tile.px_width, tile.px_height))) self.target.game.layer_widgets['below'].canvas.add(self.instructions) @memoized def get_tiles_in_range(self, tile, moved): self.travelled.add(tile) # did this to keep smallest range possible to reach selected tile, for calculating cost at end of move state self.index[tile] = min(self.index.get(tile, 1000), moved) if moved < self.target.move_range(): for neighbor in self.layer.get_neighbor_cells(tile): self.get_tiles_in_range(neighbor, moved + 1) def update(self, dt): if not self.moving: pressed = [key for key in self.move_keys if keys.get(key)] if pressed: self.velocity = [0, 0] if Keyboard.keycodes['left'] in pressed: self.target.set_face('left') self.velocity = self.velocity_dict['left'] elif Keyboard.keycodes['right'] in pressed: self.target.set_face('right') self.velocity = self.velocity_dict['right'] elif Keyboard.keycodes['up'] in pressed: self.target.set_face('up') self.velocity = self.velocity_dict['up'] elif Keyboard.keycodes['down'] in pressed: self.target.set_face('down') self.velocity = self.velocity_dict['down'] elif keys.get(Keyboard.keycodes['enter']): self.end() return self.current_tile = self.target.get_current_cell() new_x = self.current_tile.x + self.velocity[0] new_y = self.current_tile.y + self.velocity[1] # print('new not none') new_target = self.layer.get_tile(new_x, new_y) if new_target and new_target.tile.is_passable() and not new_target.occupied: # print('starting to move!') self.foreshadowed = new_target if self.foreshadowed in self.travelled: self.start_moving() else: if self.target.anim_delay > 0: self.target.reload() # reset animation self.target.anim_delay = -1 else: self.move(dt) def move(self, dt): done = move(dt, self.target, self.foreshadowed.px, self.foreshadowed.py) if done: self.done_moving() def done_moving(self, *args): self.target.set_position(self.foreshadowed.px, self.foreshadowed.py) self.moving = False def start_moving(self, *args): self.moving = True def end(self): current = self.layer.get_at(*self.target.center) self.target.spend_moves(self.index[self.layer.get_at(*self.target.center)]) self.target.game.layer_widgets['below'].canvas.remove(self.instructions) self.target.anim_delay = -1 self.target.reload() # reset animation self.target.set_position(current.px, current.py) self.target.state = BattleMenuState(self.target)
class Object3D(EventDispatcher): """Base class for all 3D objects in rendered 3D world. """ def __init__(self, **kw): super(Object3D, self).__init__(**kw) self.name = kw.pop('name', '') self.children = list() self.parent = None self.scale = Scale(1., 1., 1.) self._position = Vector3(0, 0, 0) self._rotation = Vector3(0, 0, 0) self._position.set_change_cb(self.on_pos_changed) self._rotation.set_change_cb(self.on_angle_change) # general instructions self._pop_matrix = PopMatrix() self._push_matrix = PushMatrix() self._translate = Translate(*self._position) self._rotors = { "x": Rotate(self._rotation.x, 1, 0, 0), "y": Rotate(self._rotation.y, 0, 1, 0), "z": Rotate(self._rotation.z, 0, 0, 1), } self._instructions = InstructionGroup() def add(self, *objs): for obj in objs: self._add_child(obj) def _add_child(self, obj): self.children.append(obj) obj.parent = self def _set_position(self, val): if isinstance(val, Vector3): self._position = val else: self._position = Vector3(val) self._position.set_change_cb(self.on_pos_changed) def _get_position(self): return self._position position = AliasProperty(_get_position, _set_position) pos = position # just shortcut def _set_rotation(self, val): if isinstance(val, Vector3): self._rotation = val else: self._rotation = Vector3(val) self._rotation.set_change_cb(self.on_angle_change) self._rotors["x"].angle = self._rotation.x self._rotors["y"].angle = self._rotation.y self._rotors["z"].angle = self._rotation.z def _get_rotation(self): return self._rotation rotation = AliasProperty(_get_rotation, _set_rotation) rot = rotation def on_pos_changed(self, coord, v): """ Some coordinate was changed """ self._translate.xyz = self._position def on_angle_change(self, axis, angle): self._rotors[axis].angle = angle def as_instructions(self): """ Get instructions set for renderer """ if not self._instructions.children: self._instructions.add(self._push_matrix) self._instructions.add(self._translate) self._instructions.add(self.scale) for rot in self._rotors.itervalues(): self._instructions.add(rot) self._instructions.add(UpdateNormalMatrix()) for instr in self.custom_instructions(): self._instructions.add(instr) for child in self.get_children_instructions(): self._instructions.add(child) self._instructions.add(self._pop_matrix) return self._instructions def custom_instructions(self): """ Should be overriden in subclasses to provide some extra instructions """ return [] def get_children_instructions(self): for child in self.children: yield child.as_instructions()
class SelectAttackState(TurnAction): def __init__(self, target, **kwargs): super(SelectAttackState, self).__init__(target, **kwargs) self.amount = self.target.map.tile_width self.moving = False self.velocity = [0, 0] self.layer = self.target.map.layers.by_name['below'] self.foreshadowed = self.layer.get_at(*target.center) self.move_keys = [Keyboard.keycodes['left'], Keyboard.keycodes['right'], Keyboard.keycodes['up'], Keyboard.keycodes['down'], Keyboard.keycodes['enter']] self.travelled = set() self.checked = set() self.index = {} self.instructions = InstructionGroup() self.layer = self.target.map.layers.by_name['below'] self.confirmed = False self.effect = MeleeDamage tile = self.layer.get_at(*self.target.pos) self.cursor = Sprite(pos=[tile.px, tile.py], size=self.target.size, texture=images['cursor'], opacity=0.5) self.current_tile = self.target.get_current_cell() self.target.game.layer_widgets['sprite_layer'].add_widget(self.cursor) self.get_tiles_in_range(tile, 0) self.selected = None self.last_touched = None self.highlight_tiles() def highlight_tiles(self): for tile in self.travelled: self.instructions.add(Color(rgba=[1, .4, .3, .3])) self.instructions.add(Rectangle(pos=(tile.px, tile.py), size=(tile.px_width, tile.px_height))) self.target.game.layer_widgets['below'].canvas.add(self.instructions) # print(self.travelled, self.foreshadowed) @memoized def get_tiles_in_range(self, tile, moved): self.travelled.add(tile) if moved < 2: for neighbor in self.layer.get_neighbor_cells(tile): # if not self.target.map.layers['objects'].collide(Rect(*neighbor.center + (8, 8)), 'wall'): self.get_tiles_in_range(neighbor, moved + 1) def touch(self, touch, *args): print('touch!', touch) pos = self.target.map.pixel_from_screen(*touch.pos) cell = self.target.map.layers.by_name['below'].get_at(*pos) print('at {}. Found? {}'.format(pos, cell)) if cell is not None and cell in self.travelled: print('cell not none, found in travels') self.cursor.pos = (cell.px, cell.py) if cell is self.last_touched: if self.get_selected(): self.confirm() else: self.last_touched = cell self.highlight_selected(cell) def highlight_selected(self, tile): if self.selected: for s in self.selected: self.instructions.remove(s) self.selected = [Color(rgba=[6, .3, .2, .6]), Rectangle(pos=(tile.px, tile.py), size=(tile.px_width, tile.px_height))] for a in self.selected: self.instructions.add(a) def get_selected(self): self.selected_targets = [] for battler in self.target.game.entities: # TODO - figure out why this code is selecting both characters... print('checks say:', battler is not self.target, not battler.incapacitated, self.cursor.collide_point(*battler.center)) if battler is not self.target and not battler.incapacitated and self.cursor.collide_point(*battler.center): self.selected_targets.append(battler) print('selected targets:', self.selected_targets) return self.selected_targets def update(self, dt): if not self.confirmed: if not self.moving: self.velocity = [0, 0] if keys.get(Keyboard.keycodes['left']): self.velocity = self.velocity_dict['left'] elif keys.get(Keyboard.keycodes['right']): self.velocity = self.velocity_dict['right'] elif keys.get(Keyboard.keycodes['up']): self.velocity = self.velocity_dict['up'] elif keys.get(Keyboard.keycodes['down']): self.velocity = self.velocity_dict['down'] elif keys.get(Keyboard.keycodes['enter']): print('battle_entities currently:', self.target.game.entities) if self.get_selected(): self.confirm() else: pass elif keys.get(Keyboard.keycodes['backspace']): print('pressed backspace') self.end() else: return new_x = self.current_tile.x + self.velocity[0] new_y = self.current_tile.y + self.velocity[1] # print('new not none') new_target = self.layer.get_tile(new_x, new_y) if new_target and new_target.tile.is_passable() and not new_target.occupied: # print('starting to move!') self.foreshadowed = new_target if self.foreshadowed in self.travelled: self.start_moving() else: self.move(dt) else: if not self.current_effect.finished: self.current_effect.update(dt) else: self.ready_next_effect() def move(self, dt): # because we are moving a cursor Sprite and there's a dependency mess, we are pasting here for now x, y = self.foreshadowed.px, self.foreshadowed.py delta_x = self.cursor.x - x delta_y = self.cursor.y - y distance = Vector(*self.cursor.pos).distance((x, y)) if distance >= 0.5: delta_x = (delta_x / distance) * (dt * 50) delta_y = (delta_y / distance) * (dt * 50) new_x, new_y = self.cursor.pos new_x += -delta_x new_y += -delta_y self.cursor.pos = [new_x, new_y] distance = Vector(*self.cursor.pos).distance((x, y)) if distance <= 0.5: self.done_moving() else: return False def done_moving(self, *args): self.cursor.pos = [self.foreshadowed.px, self.foreshadowed.py] self.current_tile = self.foreshadowed self.moving = False def start_moving(self, *args): self.moving = True def end(self): super(SelectAttackState, self).end() self.target.state = BattleMenuState(self.target) self.target.game.layer_widgets['below'].canvas.remove(self.instructions) self.target.anim_delay = -1 self.target.reload() # reset animation self.cursor.parent.remove_widget(self.cursor)
class NavigationToolbar2Kivy(NavigationToolbar2): '''This class extends from matplotlib class NavigationToolbar2 and creates an action bar which is added to the main app to allow the following operations to the figures. Home: Resets the plot axes to the initial state. Left: Undo an operation performed. Right: Redo an operation performed. Pan: Allows to drag the plot. Zoom: Allows to define a rectangular area to zoom in. Configure: Loads a pop up for repositioning elements. Save: Loads a Save Dialog to generate an image. ''' def __init__(self, canvas, **kwargs): self.actionbar = ActionBar(pos_hint={'top': 1.0}) super(NavigationToolbar2Kivy, self).__init__(canvas) self.rubberband_color = (1.0, 0.0, 0.0, 1.0) self.lastrect = None self.save_dialog = Builder.load_string(textwrap.dedent('''\ <SaveDialog>: text_input: text_input BoxLayout: size: root.size pos: root.pos orientation: "vertical" FileChooserListView: id: filechooser on_selection: text_input.text = self.selection and\ self.selection[0] or '' TextInput: id: text_input size_hint_y: None height: 30 multiline: False BoxLayout: size_hint_y: None height: 30 Button: text: "Cancel" on_release: root.cancel() Button: text: "Save" on_release: root.save(filechooser.path,\ text_input.text) ''')) def _init_toolbar(self): '''A Toolbar is created with an ActionBar widget in which buttons are added with a specific behavior given by a callback. The buttons properties are given by matplotlib. ''' basedir = os.path.join(rcParams['datapath'], 'images') actionview = ActionView() actionprevious = ActionPrevious(title="Navigation", with_previous=False) actionoverflow = ActionOverflow() actionview.add_widget(actionprevious) actionview.add_widget(actionoverflow) actionview.use_separator = True self.actionbar.add_widget(actionview) id_group = uuid.uuid4() for text, tooltip_text, image_file, callback in self.toolitems: if text is None: actionview.add_widget(ActionSeparator()) continue fname = os.path.join(basedir, image_file + '.png') if text in ['Pan', 'Zoom']: action_button = ActionToggleButton(text=text, icon=fname, group=id_group) else: action_button = ActionButton(text=text, icon=fname) action_button.bind(on_press=getattr(self, callback)) actionview.add_widget(action_button) def configure_subplots(self, *largs): '''It will be implemented later.''' pass def dismiss_popup(self): self._popup.dismiss() def show_save(self): '''Displays a popup widget to perform a save operation.''' content = SaveDialog(save=self.save, cancel=self.dismiss_popup) self._popup = Popup(title="Save file", content=content, size_hint=(0.9, 0.9)) self._popup.open() def save(self, path, filename): self.canvas.export_to_png(os.path.join(path, filename)) self.dismiss_popup() def save_figure(self, *args): self.show_save() def draw_rubberband(self, event, x0, y0, x1, y1): w = abs(x1 - x0) h = abs(y1 - y0) rect = [int(val)for val in (min(x0, x1) + self.canvas.x, min(y0, y1) + self.canvas.y, w, h)] if self.lastrect is None: self.canvas.canvas.add(Color(*self.rubberband_color)) else: self.canvas.canvas.remove(self.lastrect) self.lastrect = InstructionGroup() self.lastrect.add(Line(rectangle=rect, width=1.0, dash_length=5.0, dash_offset=5.0)) self.lastrect.add(Color(1.0, 0.0, 0.0, 0.2)) self.lastrect.add(Rectangle(pos=(rect[0], rect[1]), size=(rect[2], rect[3]))) self.canvas.canvas.add(self.lastrect) def release_zoom(self, event): self.lastrect = None return super(NavigationToolbar2Kivy, self).release_zoom(event)
class TouchConfigurationWidget(Widget): def __init__(self, calibrationSize): super(TouchConfigurationWidget, self).__init__() self.calibrationSize = calibrationSize self.currentPosition = [0, 0] self.offsetData = [[None for y in range(self.calibrationSize[1])] for x in range(self.calibrationSize[0])] self.calibrating = True self.calibrationTouch = None self.savePointInstructionGroup = None self.timerDisplay = Label(text="", font_size=256) self.add_widget(self.timerDisplay) self._updateView() def _touchTimer(self, dt): self.touchTimer -= 1 if self.calibrationTouch == None: self.touchTimer = 0 self.timerDisplay.text = "" return False if self.touchTimer <= 0: self.touchTimer = 0 self.timerDisplay.text = "" self._saveTouch() return False else: self.timerDisplay.text = "%d" % self.touchTimer return True def on_touch_down(self, touch): if not self.calibrating: with self.canvas: Color(0, 0.75, 0.75, 0.5) self._drawCircle([touch.x, touch.y], 25) elif self.calibrationTouch == None: self.calibrationTouch = touch self.touchTimer = 3 self.timerDisplay.text = "%d" % self.touchTimer self.timerDisplay.pos = [0,0] self.timerDisplay.size = [self.width, self.height] Clock.schedule_interval(self._touchTimer, 0.5) def on_touch_up(self, touch): if self.calibrationTouch == touch: self.calibrationTouch = None self.timerDisplay.text = "" Clock.unschedule(self._touchTimer) def _saveTouch(self): if not self.calibrating: return if self.calibrationTouch == None: return expectedLocation = self._getExpectedPosition() self.canvas.remove(self.savePointInstructionGroup) self.savePointInstructionGroup = None self.canvas.add(Color(0, 1, 0)) self._drawCircle(expectedLocation, 25) self.offsetData[self.currentPosition[0]][self.currentPosition[1]] = [self.calibrationTouch.x, self.calibrationTouch.y] # update data self.currentPosition[0] += 1 if self.currentPosition[0] >= self.calibrationSize[0]: self.currentPosition[0] = 0 self.currentPosition[1] += 1 if self.currentPosition[1] >= self.calibrationSize[1]: self.calibrating = False self.touchAccepted = False self.calibrationTouch = None self._updateView() def _updateView(self): if not self.calibrating: pass else: location = self._getExpectedPosition() if self.savePointInstructionGroup == None: self.savePointInstructionGroup = InstructionGroup() self.savePointInstructionGroup.add(Color(1, 0, 0)) self._drawCircle(location, 100, self.savePointInstructionGroup) self.savePointInstructionGroup.add(Color(0, 0, 0)) self._drawCircle(location, 66, self.savePointInstructionGroup) self.savePointInstructionGroup.add(Color(1, 1, 1)) self._drawCircle(location, 33, self.savePointInstructionGroup) self.canvas.add(self.savePointInstructionGroup) def _getExpectedPosition(self, point=None, calibrationSize=None): if point == None: point = self.currentPosition if calibrationSize == None: calibrationSize = self.calibrationSize return [ self.width * (float(point[0]) / (calibrationSize[0] - 1)), self.height * (float(point[1]) / (calibrationSize[1] - 1)) ] def _drawCircle(self, location, size, instructionGroup=None): [x,y] = location pos = (x - size/2, y - size/2) size = (size, size) if instructionGroup != None: instructionGroup.add(Ellipse(pos=pos, size=size)) else: self.canvas.add(Ellipse(pos=pos, size=size))
class KnittingPatternWidget(RelativeLayout): """The widget to display a knitting pattern.""" def __init__(self, **kw): super().__init__(**kw) self._pattern = new_knitting_pattern("") self._mark = None self.zoom = 1 def show_pattern(self, pattern): """Show a knitting pattern. :param knittingpattern.KnittingPattern.KnittingPattern pattern: the pattern to display """ self._pattern = pattern self._layout = GridLayout(self._pattern) self._bbox = self._layout.bounding_box self._cache = default_cache() self._instructions = list(self._layout.walk_instructions()) self._instructions.sort(key=lambda i: i.instruction.render_z) self.update_widget() def update_widget(self): """Call after a resize to rerender the elements to fit.""" if not self._pattern: return self.clear_widgets() add_width = 1 add_height = 1 bbox = self._bbox bbox_width = bbox[2] - bbox[0] + add_width bbox_height = bbox[3] - bbox[1] + add_height print(bbox, self.height, self.width) zoom = min(self.height / bbox_height, self.width / bbox_width) self.zoom = zoom min_y = bbox[1] - add_width / 2 # - 0.618 flip_x = bbox[0] + bbox[2] + add_height / 2 # + 1.618 create_svg_widget = self._cache.create_svg_widget for instruction in self._instructions: svg = create_svg_widget(instruction.instruction, size_hint=(None, None)) self.add_widget(svg) svg.scale = zoom / svg.height svg.x = (flip_x - instruction.x - instruction.width) * zoom svg.y = (instruction.y - min_y) * zoom self._zoom = zoom self._min_y = min_y self._flip_x = flip_x def mark_row(self, row, border_width=1): """Mark a row. The old mark is removed.""" assert self._pattern, "I can only mark a row if I show a pattern." row = self._layout.row_in_grid(row) if self._mark: self.canvas.remove(self._mark) border_width *= self.zoom width = row.width * self._zoom + border_width + border_width height = row.height * self._zoom + border_width + border_width x = (self._flip_x - row.x - row.width) * self._zoom - border_width y = (row.y - self._min_y) * self._zoom - border_width self._mark = InstructionGroup() self._mark.add(Color(0, 0, 1, 1)) self._mark.add(Rectangle(pos=(x, y), size=(width, border_width))) self._mark.add(Rectangle(pos=(x, y + height), size=(width, border_width))) self._mark.add(Rectangle(pos=(x, y), size=(border_width, height))) self._mark.add(Rectangle(pos=(x + width, y), size=(border_width, height))) self.canvas.add(self._mark) @property def pattern(self): """The knitting pattern.""" return self._pattern pattern.setter(show_pattern)
class LetterGrid(Widget): """An instance is a grid of letter boxes. While letter boxes are arranged in a grid, not all grids must have a letter box. This allows us to represent a seven-cross. Instance Attributes: cols: number of columns in the grid [int > 0] rows: number of rows in the grid [int > 0] foreground: the foreground color [4 element list of floats] background: the background color [4 element list of floats] textcolor: the text color [4 element list of floats] font_size: the size of the font [int > 0] bold: whether the font is bolded [boolean] italic: whether the font is in italics [boolean] border: the border size in pixels [odd, positive integer] _labels: the collection of all letter boxes [map of tuples to LetterBox] _back: drawing layer for unpressed boxes _front: drawing layer for pressed boxes """ # Computed propery @property def cellsize(self): """A 2-element tuple with the cellsize in pixels.""" if self._resized: width = self.size[0]/float(self.cols) height = self.size[1]/float(self.rows) self._cellsize = (width, height) self._resized = False return self._cellsize # Kivy style properties for KV sheets cols = NumericProperty(1) rows = NumericProperty(1) border = NumericProperty(3) font_size = NumericProperty(36) bold = BooleanProperty(True) italic = BooleanProperty(False) foreground = ListProperty([0,0,0,1]) background = ListProperty([1,1,1,1]) textcolor = ListProperty([1,0,0,1]) def __init__(self, **kw): """**Constructor**: Create a new letter box :param keywords: dictionary of keyword arguments **Precondition**: See below. To use the constructor for this class, you should provide it with a list of keyword arguments that initialize various attributes. For example, to initialize a 2x3 grid, use the constructor call GObject(rows=2,cols=3) You do not need to provide the keywords as a dictionary. The ** in the parameter `keywords` does that automatically. Any attribute of this class may be used as a keyword. The argument must satisfy the invariants of that attribute. See the list of attributes of this class for more information.""" Widget.__init__(self,**kw) self._resized = True self._labels = dict() self._set_properties(kw) self.bind(pos=self._reposition) # Create a layer for proper state control. self._back = InstructionGroup() self._front = InstructionGroup() self.canvas.add(self._back) self.canvas.add(self._front) # Bind kivy attributes to methods self.bind(size=self._resize) self.bind(cols=self._resize) self.bind(rows=self._resize) self.bind(border=self._set_border) self.bind(font_size=self._set_font_size) self.bind(bold=self._set_bold) self.bind(italic=self._set_italic) self.bind(foreground=self._set_foreground) self.bind(background=self._set_background) self.bind(textcolor=self._set_textcolor) def clear(self): """Reset the entire letter grid, eliminating all letter boxes.""" self._labels = dict() self.canvas.clear() self.canvas.add(Color(0,0,0,1)) self.canvas.add(Rectangle(pos=self.pos,size=self.size)) self._back = InstructionGroup() self._front = InstructionGroup() self.canvas.add(self._back) self.canvas.add(self._front) def _set_properties(self,kw): """Sets the letter box attributes according to kw If an attribute is not in kw, the attribute is set to a default. :param keywords: dictionary of keyword arguments **Precondition**: Same as __init__""" if 'cols' in kw: self.cols = kw['cols'] if 'rows' in kw: self.rows = kw['rows'] if 'background' in kw: self.background = kw['background'] if 'foreground' in kw: self.foreground = kw['foreground'] if 'textcolor' in kw: self.textcolor = kw['textcolor'] if 'border' in kw: self.border =kw['border'] if 'font_size' in kw: self.fontsize =kw['font_size'] if 'bold' in kw: self.bold =kw['bold'] if 'italic' in kw: self.italic =kw['italic'] # Methods to update the letter grid def add_cell(self, s, col, row): """Adds a new cell to the letter grid. The letter grid has s as its initial text. If the cell already exists, it replaces the text with s. Precondition: row and col are valid indices in the grid. s is a string.""" assert row >= 0 and row < self.rows, 'Row '+`row`+' is out of range [0,'+`self.rows`+']' assert col >= 0 and col < self.cols, 'Row '+`col`+' is out of range [0,'+`self.cols`+']' if (col,row) in self._labels: self._labels[(col,row)].text = s return label = LetterBox(text=s, fontsize=self.font_size, color=self.textcolor) label.bold = self.bold label.italic = self.italic label.size = self.cellsize x = self.pos[0] + col*self.cellsize[0] y = self.pos[1] + row*self.cellsize[1] label.pos = [x,y] self._labels[(col,row)] = label self._back.add(label.canvas) def delete_cell(self, col, row): """Deletes the LetterBox at col and row. If there is no LetterBox at that position, this method does nothing. Precondition: row and col are valid indices in the grid.""" if not (col, row) in self._labels: return label = self._labels[(col,row)] self._back.remove(label.canvas) del self._labels[(col,row)] def get_cell(self, col, row): """Returns the LetterBox at col and row. If there is no LetterBox at that position, it returns None. Precondition: row and col are valid indices in the grid.""" assert row >= 0 and row < self.rows, 'Row '+`row`+' is out of range [0,'+`self.rows`+']' assert col >= 0 and col < self.cols, 'Row '+`col`+' is out of range [0,'+`self.cols`+']' if not (col, row) in self._labels: return None return self._labels[(col,row)] def toggle_cell(self, col, row): """Toggles the state of the LetterBox at col and row. If there is no LetterBox at that position, it does nothing. Precondition: row and col are valid indices in the grid.""" if not (col, row) in self._labels: return label = self._labels[(col,row)] label.state = not label.state tmp = label.foreground label.foreground = label.background label.background = tmp tmp = label.textcolor tmp = map(lambda x: 1-x, tmp[:-1])+tmp[-1:] label.textcolor = tmp if label.state: self._front.add(label.canvas) return True self._front.remove(label.canvas) return False # Call Back Methods def _reposition(self,obj,value): """Repositions the graphics object. This function is called by Kivy services, so it passes the object and new position as an argument.""" for pos in self._labels: self._labels[pos].pos[0] = self.pos[0]+self.cellsize[0]*pos[0] self._labels[pos].pos[1] = self.pos[1]+self.cellsize[1]*pos[1] def _resize(self,obj,value): """Resizes the graphics object. This function is called by Kivy services, so it passes the object and new size as an argument.""" self._resized = True for pos in self._labels: self._labels[pos].size = self.cellsize self._labels[pos].pos[0] = self.pos[0]+self.cellsize[0]*pos[0] self._labels[pos].pos[1] = self.pos[1]+self.cellsize[1]*pos[1] def _set_border(self,obj,value): """Updates the border attribute. This method propagates its value across all LetterBoxes in the grid. This function is called by Kivy services, so it passes the object and new attribute value as an argument.""" for pos in self._labels: self._labels[pos].border = value def _set_font_size(self,obj,value): """Updates the font size attribute. This method propagates its value across all LetterBoxes in the grid. This function is called by Kivy services, so it passes the object and new attribute value as an argument.""" for pos in self._labels: self._labels[pos].fontsize = value def _set_bold(self,obj,value): """Updates the bold attribute. This method propagates its value across all LetterBoxes in the grid. This function is called by Kivy services, so it passes the object and new attribute value as an argument.""" for pos in self._labels: self._labels[pos].bold = value def _set_italic(self,obj,value): """Updates the italic attribute. This method propagates its value across all LetterBoxes in the grid. This function is called by Kivy services, so it passes the object and new attribute value as an argument.""" for pos in self._labels: self._labels[pos].italic = value def _set_foreground(self,obj,value): """Updates the foreground attribute. This method propagates its value across all LetterBoxes in the grid. This function is called by Kivy services, so it passes the object and new attribute value as an argument.""" for pos in self._labels: self._labels[pos].foreground = list(value) def _set_background(self,obj,value): """Updates the background attribute. This method propagates its value across all LetterBoxes in the grid. This function is called by Kivy services, so it passes the object and new attribute value as an argument.""" for pos in self._labels: self._labels[pos].background = list(value) def _set_textcolor(self,obj,value): """Updates the text color attribute. This method propagates its value across all LetterBoxes in the grid. This function is called by Kivy services, so it passes the object and new attribute value as an argument.""" for pos in self._labels: self._labels[pos].textcolor = list(value)
class Beam(): enemies = [] player1 = None player2 = None def __init__(self, player1, player2, **kwargs): self.canvas = InstructionGroup() self.beamColor = Color(0.0, 0.0, 0.0, 1.0) self.beamGroup = InstructionGroup() self.beamThickness = 40 self.canvas.add(self.beamGroup) self.player1 = player1 self.player2 = player2 self.beamState = 0 self.isColliding = False def setKeyReport(self, keyReport): self.keyReport = keyReport self.player1.setPlayerKeyReport(keyReport.player1) self.player2.setPlayerKeyReport(keyReport.player2) def setIsColliding(self, isColliding): self.isColliding = isColliding def reset(self): self.beamState = 0 self.isColliding = False def updateBeamState(self): bothButton1 = self.keyReport.player1.button1 and self.keyReport.player2.button1 bothButton2 = self.keyReport.player1.button2 and self.keyReport.player2.button2 beamState = self.beamState if not bothButton1 and not bothButton2: beamState = 0 else: beamState = 1 isChanged = False if not beamState == self.beamState: isChanged = True self.beamState = beamState return isChanged def updateBeam(self, p1Pos, p2Pos): xDelta = p2Pos[0] - p1Pos[0] yDelta = p2Pos[1] - p1Pos[1] distanceSquared = math.pow(xDelta, 2) + math.pow(yDelta, 2) theta = math.atan2(yDelta, xDelta) distance = math.sqrt(distanceSquared) self.beamGroup.clear() self.beamGroup.add(PushMatrix()) self.beamGroup.add(self.beamColor) self.beamGroup.add(Translate(p1Pos[0], p1Pos[1], 0)) self.beamGroup.add(Rotate(theta * 180 / math.pi, 0, 0, 1)) self.beamGroup.add(Scale(distance, self.beamThickness, 1)) self.beamGroup.add(Rectangle(pos=(0, -0.5), size=(1, 1))) self.beamGroup.add(PopMatrix()) def update(self, dt): beamLineCoords = (self.player2.pos[0], self.player2.pos[1], self.player1.pos[0], self.player1.pos[1]) if self.isColliding: self.beamColor.r = 0.8 self.beamColor.g = 0.5 self.beamColor.b = 0.3 self.beamColor.a = 1 else: self.beamColor.r = 0.3 self.beamColor.g = 0.3 self.beamColor.b = 0.3 self.beamColor.a = 1 self.updateBeamState() if self.beamState == 0: self.beamThickness = 1 elif self.beamState == 1: self.beamThickness = 40 self.updateBeam(self.player1.pos, self.player2.pos)
class BodyRenderInstructionBase(object): def __init__(self, body, instruction, offset=None): #self.size = size self.body = body self.instructionGroup = InstructionGroup() self.instructionGroup.add(PushMatrix()) self.s = Scale(50.0) self.t = Translate(0,0) self.r = Rotate(0.0) #self.rect = Rectangle(pos=(0,0), size=(1, 1)) self.instructionGroup.add(self.s) self.instructionGroup.add(self.t) self.instructionGroup.add(self.r) if offset is not None: self.instructionGroup.add(Translate(offset[0], offset[1])) #g = InstructionGroup() #g.add(Color(1,1,1,1)) #g.add(self.rect) self.instructionGroup.add(instruction) #self.instructionGroup.add(Color(1,1,1,1)) #self.instructionGroup.add(self.rect) self.instructionGroup.add(PopMatrix()) def update(self): self.t.xy = self.body.position self.r.angle = math.degrees(self.body.angle)