class LoadIcon: """ A spinning icon. """ def __init__(self, mainScreen, x=0.0, y=0.0): self.main_screen = mainScreen self._image = OnscreenImage( image=self.main_screen.image_path + "load_icon.png", pos=(x, 0, y), parent=self.main_screen.gameEngine.render2d, scale=(0.07, 1, 0.07)) self._image.setTransparency(TransparencyAttrib.MAlpha) self.spin_task = None self._image.hide() def set_pos(self, x, y): """ Sets the position of the icon @param x: the relative x in the screen @param y: the relative y in the screen """ self._image.set_r(0) self._image.set_pos(x, 0, y) def start(self): """ Starts the spinning animation and shows it. """ self._image.set_r(0) self._image.show() self.spin_task = self._image.hprInterval(duration=2, hpr=(0, 0, 360)) self.spin_task.loop() def stop(self): """ Stops the spinning animation and hides it. @return: """ self.spin_task.finish() self._image.hide()
class Sprite(RPObject): """ Simple wrapper arround OnscreenImage, providing a simpler interface """ def __init__(self, image=None, parent=None, x=0, y=0, w=None, h=None, transparent=True, near_filter=True, any_filter=True): """ Creates a new image, taking (x,y) as topleft coordinates. When near_filter is set to true, a near filter will be set to the texture passed. This provides sharper images. When any_filter is set to false, the passed image won't be modified at all. This enables you to display existing textures, otherwise the texture would get a near filter in the 3D View, too. """ RPObject.__init__(self) if not isinstance(image, Texture): if not isinstance(image, str): self.warn("Invalid argument to image parameter:", image) return image = RPLoader.load_texture(image) if w is None or h is None: w, h = image.get_x_size(), image.get_y_size() else: if w is None or h is None: w = 10 h = 10 self._width, self._height = w, h self._initial_pos = self._translate_pos(x, y) self.node = OnscreenImage( image=image, parent=parent, pos=self._initial_pos, scale=(self._width / 2.0, 1, self._height / 2.0)) if transparent: self.node.set_transparency(TransparencyAttrib.M_alpha) tex = self.node.get_texture() # Apply a near filter, but only if the parent has no scale, otherwise # it will look weird if near_filter and any_filter and parent.get_sx() == 1.0: tex.set_minfilter(SamplerState.FT_nearest) tex.set_magfilter(SamplerState.FT_nearest) if any_filter: tex.set_anisotropic_degree(8) tex.set_wrap_u(SamplerState.WM_clamp) tex.set_wrap_v(SamplerState.WM_clamp) def get_initial_pos(self): """ Returns the initial position of the image. This can be used for animations """ return self._initial_pos def pos_interval(self, *args, **kwargs): """ Returns a pos interval, this is a wrapper around NodePath.posInterval """ return self.node.posInterval(*args, **kwargs) def hpr_interval(self, *args, **kwargs): """ Returns a hpr interval, this is a wrapper around NodePath.hprInterval """ return self.node.hprInterval(*args, **kwargs) def color_scale_interval(self, *args, **kwargs): """ Returns a color scale interval, this is a wrapper around NodePath.colorScaleInterval """ return self.node.colorScaleInterval(*args, **kwargs) def set_image(self, img): """ Sets the current image """ self.node.set_image(img) def get_width(self): """ Returns the width of the image in pixels """ return self._width def get_height(self): """ Returns the height of the image in pixels """ return self._height def set_pos(self, x, y): """ Sets the position """ self.node.set_pos(self._translate_pos(x, y)) def _translate_pos(self, x, y): """ Converts 2d coordinates to pandas coordinate system """ return Vec3(x + self._width / 2.0, 1, -y - self._height / 2.0) def set_shader(self, shader): """ Sets a shader to be used for rendering the image """ self.node.set_shader(shader) def set_shader_input(self, *args): """ Sets a shader input on the image """ self.node.set_shader_input(*args) def remove(self): """ Removes the image """ self.node.remove() def hide(self): """ Hides the image """ self.node.hide() def show(self): """ Shows the image if it was previously hidden """ self.node.show()
class Gauge: """ Represents a dynamic gauge linked to a global variable of the shuttle. """ def __init__(self, screen, name, x=0, low_value=-1, high_value=101, min=0, max=100): """ Creates a new gauge @param screen: the controlScreen instance @param name: the name of the corresponding global variable (soft_state). @param x: @param low_value: below this limit, @param high_value: @param min: minimum value @param max: maximum value """ self.taskMgr = screen.gameEngine.taskMgr self.update_func = screen.update self.screen = screen self.name = name self.low_value = low_value self.high_value = high_value self._hardware = screen.gameEngine.hardware self._sound = screen.gameEngine.sound_manager self.texture = OnscreenImage(image=screen.image_path + "indicateur.png", parent=screen.gui_render_node) self.texture.setTransparency(True) iH = PNMImageHeader() iH.readHeader(Filename(screen.image_path + "indicateur.png")) self.time_for_goto = None self.half_sec_step_for_goto = 1.0 self.w = iH.get_x_size() self.h = iH.get_y_size() self._limits = [min, max] iH.readHeader(Filename(screen.image_path + "screen.png")) self._x0 = x self._x = [-1 + self.w / iH.get_x_size(), 2 / iH.get_x_size()] self._y = [1 - self.h / iH.get_y_size(), -2 / iH.get_y_size()] self._gauge_min_y = 44 - 0.5 * self.h self._gauge_max_y = 466 - 0.5 * self.h self.texture.set_scale( LVector3f(self.w / iH.get_x_size(), 1, self.h / iH.get_y_size())) self._task_to_come = [] self.value = self.screen.gameEngine.get_soft_state(self.name) self._is_destroyed = False self.set_value() self.hide() def set_time_for_goto(self, time): self.time_for_goto = time self.half_sec_step_for_goto = None def set_half_sec_step_for_goto(self, step): self.half_sec_step_for_goto = step self.time_for_goto = None def _set_gimp_pos(self, x, y): self.texture.set_pos( (self._x[0] + x * self._x[1], 0.0, self._y[0] + y * self._y[1])) def set_color(self, color): self.texture.set_color(color) def destroy(self): self.texture.destroy() self._is_destroyed = True for i in range(len(self._task_to_come)): self.taskMgr.remove(self._task_to_come.pop()) def hide(self): self.texture.hide() def show(self): self.texture.show() def goto_value(self, new_value): # stop the previous tasks for i in range(len(self._task_to_come)): self.taskMgr.remove(self._task_to_come.pop()) def func(v): self.set_value(v) self.update_func.__call__() def stop(t=None): self._hardware.set_led_off("l_" + self.name + "_down") self._hardware.set_led_off("l_" + self.name + "_up") if self.low_value >= self.value: self._sound.play(self.name + "_low") elif self.high_value <= self.value: self._sound.play(self.name + "_high") self._hardware.set_led_off("l_" + self.name + "_down") self._hardware.set_led_off("l_" + self.name + "_up") step_by_half_sec = self.half_sec_step_for_goto if self.half_sec_step_for_goto is None: dx = abs(self.value - new_value) step_by_half_sec = 0.5 * dx / self.time_for_goto if self.value >= new_value: self._hardware.set_led_on("l_" + self.name + "_down") step_by_half_sec = -step_by_half_sec else: self._hardware.set_led_on("l_" + self.name + "_up") n_steps = -int((self.value - new_value) / step_by_half_sec) old_value = self.value for i in range(n_steps): self._task_to_come.append( self.taskMgr.doMethodLater( 0.5 * i, func, name="gauge_move", extraArgs=[old_value + (i + 1) * step_by_half_sec])) self._task_to_come.append( self.taskMgr.doMethodLater(0.5 * n_steps, stop, name="gauge_move_stop")) def set_value(self, value=None): if not self._is_destroyed: if self.value >= self._limits[1]: self.value = self._limits[1] elif self.value < self._limits[0]: self.value = self._limits[0] old_value = self.value if value is not None: if value >= self._limits[1]: value = self._limits[1] elif value < self._limits[0]: value = self._limits[0] self.value = value if old_value > self.low_value >= self.value: self._sound.play(self.name + "_low") self._hardware.set_led_on("l_" + self.name + "_low") elif old_value <= self.low_value < self.value: self._hardware.set_led_off("l_" + self.name + "_low") elif old_value < self.high_value <= self.value: self._sound.play(self.name + "_high") self._hardware.set_led_on("l_" + self.name + "_high") elif self.value < self.high_value <= old_value: self._hardware.set_led_off("l_" + self.name + "_high") self._set_gimp_pos( self._x0, self._gauge_max_y + (self.value - self._limits[0]) / (self._limits[1] - self._limits[0]) * (self._gauge_min_y - self._gauge_max_y))
class Sprite(RPObject): """ Simple wrapper arround OnscreenImage, providing a simpler interface """ def __init__(self, image=None, parent=None, x=0, y=0, w=None, h=None, transparent=True, near_filter=True, any_filter=True): """ Creates a new image, taking (x,y) as topleft coordinates. When near_filter is set to true, a near filter will be set to the texture passed. This provides sharper images. When any_filter is set to false, the passed image won't be modified at all. This enables you to display existing textures, otherwise the texture would get a near filter in the 3D View, too. """ RPObject.__init__(self) if not isinstance(image, Texture): if not isinstance(image, str): self.warn("Invalid argument to image parameter:", image) return image = RPLoader.load_texture(image) if w is None or h is None: w, h = image.get_x_size(), image.get_y_size() else: if w is None or h is None: w = 10 h = 10 self._width, self._height = w, h self._initial_pos = self._translate_pos(x, y) self.node = OnscreenImage(image=image, parent=parent, pos=self._initial_pos, scale=(self._width / 2.0, 1, self._height / 2.0)) if transparent: self.node.set_transparency(TransparencyAttrib.M_alpha) tex = self.node.get_texture() # Apply a near filter, but only if the parent has no scale, otherwise # it will look weird if near_filter and any_filter and parent.get_sx() == 1.0: tex.set_minfilter(SamplerState.FT_nearest) tex.set_magfilter(SamplerState.FT_nearest) if any_filter: tex.set_anisotropic_degree(8) tex.set_wrap_u(SamplerState.WM_clamp) tex.set_wrap_v(SamplerState.WM_clamp) def get_initial_pos(self): """ Returns the initial position of the image. This can be used for animations """ return self._initial_pos def pos_interval(self, *args, **kwargs): """ Returns a pos interval, this is a wrapper around NodePath.posInterval """ return self.node.posInterval(*args, **kwargs) def hpr_interval(self, *args, **kwargs): """ Returns a hpr interval, this is a wrapper around NodePath.hprInterval """ return self.node.hprInterval(*args, **kwargs) def color_scale_interval(self, *args, **kwargs): """ Returns a color scale interval, this is a wrapper around NodePath.colorScaleInterval """ return self.node.colorScaleInterval(*args, **kwargs) def set_image(self, img): """ Sets the current image """ self.node.set_image(img) def get_width(self): """ Returns the width of the image in pixels """ return self._width def get_height(self): """ Returns the height of the image in pixels """ return self._height def set_pos(self, x, y): """ Sets the position """ self.node.set_pos(self._translate_pos(x, y)) def _translate_pos(self, x, y): """ Converts 2d coordinates to pandas coordinate system """ return Vec3(x + self._width / 2.0, 1, -y - self._height / 2.0) def set_shader(self, shader): """ Sets a shader to be used for rendering the image """ self.node.set_shader(shader) def set_shader_input(self, *args): """ Sets a shader input on the image """ self.node.set_shader_input(*args) def remove(self): """ Removes the image """ self.node.remove() def hide(self): """ Hides the image """ self.node.hide() def show(self): """ Shows the image if it was previously hidden """ self.node.show()