def read_texture(self, filename): """ Reads a texture from the Pandora resources repository. Returns a PNMImage object representing the image data. Throws a PalettizerException if file could not be found. :filename: Relative filename pointing to a texture file in the Pandora repository. """ full_filename = self.find_texture(filename) if self.debug: print(f'Reading {full_filename}...') # We've found the source file! Let's load it using Panda3D. img = PNMImage() img.read(Filename.from_os_specific(full_filename)) needs_alpha_fill = img.num_channels not in (2, 4) img.set_color_type(4) if needs_alpha_fill: # We need an alpha channel no matter what, so if the image does not have one, # it needs to be filled immediately with opaque pixels as it starts out with transparent pixels img.alpha_fill(1) return img
def generate_atlas(files, dest_dat, dest_png): entries = [] virtual_atlas_size = 32 all_entries_matched = False print "Loading", len(files), "entries .." for verbose_name, source in files: entries.append(AtlasEntry(verbose_name, source)) entries = sorted(entries, key=lambda a: -a.area) while not all_entries_matched: print "Trying to pack into a", virtual_atlas_size, "x", virtual_atlas_size, "atlas .." packer = LUIAtlasPacker(virtual_atlas_size) all_entries_matched = True for entry in entries: uv = packer.find_position(entry.w, entry.h) if uv.get_x() < 0: # print " Not all images matched, trying next power of 2" all_entries_matched = False virtual_atlas_size *= 2 break entry.assigned_pos = uv print "Matched entries, writing atlas .." atlas_description_content = "" dest = PNMImage(virtual_atlas_size, virtual_atlas_size, 4) for entry in entries: src = PNMImage(entry.w, entry.h, 4) entry.tex.store(src) if not src.has_alpha(): src.add_alpha() src.alpha_fill(1.0) dest.copy_sub_image( src, int(entry.assigned_pos.get_x()), int(entry.assigned_pos.get_y())) atlas_description_content += "{0} {1} {2} {3} {4}\n".format( entry.name.replace(" ", "_"), int(entry.assigned_pos.get_x()), int(entry.assigned_pos.get_y()), entry.w, entry.h) dest.write(dest_png) with open(dest_dat, "w") as handle: handle.write(atlas_description_content)
def read_texture(self, filename, alpha=False): """ Reads a texture from the model path. Throws a PalettizerException if file could not be found. :filename: Relative filename pointing to a texture file in the model path. :alpha: Do we need an alpha channel? """ img = PNMImage() img.read(Filename.from_os_specific(filename)) if alpha: needs_alpha_fill = img.num_channels not in (2, 4) img.set_color_type(4) if needs_alpha_fill: # We need an alpha channel no matter what, so if the image does not have one, # it needs to be filled immediately with opaque pixels as it starts out with transparent pixels img.alpha_fill(1) else: img.set_color_type(3) return img
def convert_texture(self, texture, model_path=None): if not self.model_path: self.print_exc('ERROR: No model path specified in ImageConverter.') return tex_path = texture[0] tex_basename = os.path.splitext(os.path.basename(tex_path))[0] if not os.path.isabs(tex_path): if '../' in tex_path and model_path: # This texture path is using relative paths. # We assume that the working directory is the model's directory tex_path = os.path.join(os.path.dirname(model_path), tex_path) else: tex_path = os.path.join(self.model_path, tex_path) tex_path = tex_path.replace('\\', os.sep).replace('/', os.sep) if not os.path.exists(tex_path): self.print_exc('ERROR: Could not convert {}: Missing RGB texture!'.format(tex_path)) return png_tex_path = os.path.join(os.path.dirname(tex_path), tex_basename + '.png') png_tex_path = png_tex_path.replace('\\', os.sep).replace('/', os.sep) print('Converting to PNG...', png_tex_path) if len(texture) == 1: # Only one texture, we can save this immediately if tex_path.lower().endswith('.rgb'): output_img = PNMImage() output_img.read(Filename.from_os_specific(tex_path)) if output_img.num_channels in (1, 2) and 'golf_ball' not in tex_path and 'roll-o-dex' not in tex_path: # HACK: Toontown output_img.set_color_type(4) for i in range(output_img.get_x_size()): for j in range(output_img.get_y_size()): output_img.set_alpha(i, j, output_img.get_gray(i, j)) else: output_img = self.read_texture(tex_path, alpha=False) elif len(texture) == 2: img = self.read_texture(tex_path, alpha=True) # Two textures: the second one should be a RGB file alpha_path = texture[1] if not os.path.isabs(alpha_path): if '../' in alpha_path and model_path: # This texture path is using relative paths. # We assume that the working directory is the model's directory alpha_path = os.path.join(os.path.dirname(model_path), alpha_path) else: alpha_path = os.path.join(self.model_path, alpha_path) alpha_path = alpha_path.replace('\\', os.sep).replace('/', os.sep) if not os.path.exists(alpha_path): self.print_exc('ERROR: Could not convert {} with alpha {}: Missing alpha texture!'.format(tex_path, alpha_path)) return alpha_img = PNMImage() alpha_img.read(Filename.from_os_specific(alpha_path)) alpha_img = self.resize_image(alpha_img, img.get_x_size(), img.get_y_size()) output_img = PNMImage(img.get_x_size(), img.get_y_size(), 4) output_img.alpha_fill(1) output_img.copy_sub_image(img, 0, 0, 0, 0, img.get_x_size(), img.get_y_size()) for i in range(img.get_x_size()): for j in range(img.get_y_size()): output_img.set_alpha(i, j, alpha_img.get_gray(i, j)) output_img.write(Filename.from_os_specific(png_tex_path))
def build(self, exit_behav): self.drv_info = self.props.gameprops.drivers_info menu_props = self.menu_props widgets = [Text(_('Select the driver'), pos=(0, .8), **menu_props.text_args)] t_a = self.menu_props.text_args.copy() del t_a['scale'] self.name = Text(_('Write your name:'), pos=(-.1, .6), scale=.06, align='right', wordwrap=128, **t_a) self.drivers = [] for row, col in product(range(2), range(4)): idx = col + row * 4 drv_btn = ImgBtn( scale=(.24, .24), pos=(-.75 + col * .5, .3 - row * .64), frame_col=(0, 0, 0, 0), img=self.props.gameprops.drivers_img.path % idx, cmd=self.on_click, extra_args=[idx], **self.menu_props.imgbtn_args) name = Text( '', pos=(-.75 + col * .5, .01 - row * .64), scale=.046, **t_a) drv_btn._name_txt = name widgets += [drv_btn, name] self.drivers += [widgets[-2]] sign = lambda pos_x: '\1green\1+\2' if pos_x > 0 else '' psign = lambda pos_x, sgn=sign: '+' if pos_x == 0 else sgn(pos_x) def ppcol(x): return '\1green\1%s\2' % x if x > 0 else '\1red\1%s\2' % x pcol = lambda x: x if x == 0 else ppcol(x) lab_lst = [(_('adherence'), .09), (_('speed'), .21), (_('stability'), .15)] widgets += list(map( lambda lab_def: self._add_lab(*(lab_def + (row, col))), lab_lst)) txt_lst = [(self.drv_info[idx - 1].adherence, .09), (self.drv_info[idx - 1].speed, .21), (self.drv_info[idx - 1].stability, .15)] widgets += list(map( lambda txt_def: self._add_txt( *txt_def + (psign, pcol, col, row)), txt_lst)) self.sel_drv_img = Img( self.props.gameprops.cars_img % self.mediator.car, parent=base.a2dBottomLeft, pos=(.3, .4), scale=.28) instr_txt = _( 'If you use the keyboard, press FIRE to edit the field, then ' "ENTER when you're done") instr = Text(instr_txt, pos=(1.4, .6), scale=.042, wordwrap=16, **t_a) widgets += [self.sel_drv_img, self.name, instr] self.add_widgets(widgets) ffilterpath = self.eng.curr_path + 'yyagl/assets/shaders/filter.vert' with open(ffilterpath) as ffilter: vert = ffilter.read() shader = load_shader(vert, frag) if shader: self.sel_drv_img.set_shader(shader) self.sel_drv_img.set_transparent() self.t_s = TextureStage('ts') self.t_s.set_mode(TextureStage.MDecal) empty_img = PNMImage(1, 1) empty_img.add_alpha() empty_img.alpha_fill(0) tex = Texture() tex.load(empty_img) self.sel_drv_img.set_texture(self.t_s, tex) ThanksPageGui.build(self, exit_behav=exit_behav)
def build(self): self.drv_info = self.props.gameprops.drivers_info menu_props = self.menu_props widgets = [Text(_('Select the drivers'), pos=(0, .91), **menu_props.text_args)] t_a = self.menu_props.text_args.copy() del t_a['scale'] self.name = Text(_('Write your names:'), pos=(-.1, .7), scale=.06, align='right', wordwrap=128, **t_a) self.drivers = [] for row, col in product(range(2), range(4)): idx = col + row * 4 drv_btn = ImgBtn( scale=(.24, .24), pos=(-.75 + col * .5, .1 - row * .64), frame_col=(0, 0, 0, 0), img=self.props.gameprops.drivers_img.path % idx, cmd=self.on_click, extra_args=[idx], **self.menu_props.imgbtn_args) name = Text( '', pos=(-.75 + col * .5, -.19 - row * .64), scale=.046, **t_a) drv_btn._name_txt = name widgets += [drv_btn, name] self.drivers += [widgets[-2]] sign = lambda pos_x: '\1green\1+\2' if pos_x > 0 else '' psign = lambda pos_x, sgn=sign: '+' if pos_x == 0 else sgn(pos_x) def ppcol(x): return '\1green\1%s\2' % x if x > 0 else '\1red\1%s\2' % x pcol = lambda x: x if x == 0 else ppcol(x) lab_lst = [(_('adherence'), -.11), (_('speed'), .01), (_('stability'), -.05)] widgets += list(map( lambda lab_def: self._add_lab(*(lab_def + (row, col))), lab_lst)) txt_lst = [(self.drv_info[idx - 1].adherence, -.11), (self.drv_info[idx - 1].speed, .01), (self.drv_info[idx - 1].stability, -.05)] widgets += list(map( lambda txt_def: self._add_txt( *txt_def + (psign, pcol, col, row)), txt_lst)) self.sel_drv_img = [] self.tss = [] instr_txt = _( 'If you use the keyboard, press FIRE to edit the field, then ' "ENTER when you're done. Other players can't move while someone" 'is writing (since, with keyboards, some letters may be bound to ' 'movements).') instr = Text(instr_txt, pos=(1.28, .8), scale=.042, wordwrap=24, **t_a) widgets += [self.name, instr] for i, car in enumerate(self.mediator.cars): self.sel_drv_img += [Img( self.props.gameprops.cars_img % car, parent=base.a2dBottomLeft, pos=(.3, 1.74 - i * .46), scale=.22)] widgets += [self.sel_drv_img[-1]] ffilterpath = self.eng.curr_path + 'yyagl/assets/shaders/filter.vert' with open(ffilterpath) as ffilter: vert = ffilter.read() shader = load_shader(vert, frag) if shader: self.sel_drv_img[-1].set_shader(shader) self.sel_drv_img[-1].set_transparent() self.tss += [TextureStage('ts')] self.tss[-1].set_mode(TextureStage.MDecal) empty_img = PNMImage(1, 1) empty_img.add_alpha() empty_img.alpha_fill(0) tex = Texture() tex.load(empty_img) self.sel_drv_img[-1].set_texture(self.tss[-1], tex) self.ents = [Entry( scale=.06, pos=(0, .8 - .12 * i), entry_font=menu_props.font, width=12, frame_col=menu_props.btn_col, initial_text=self.props.gameprops.player_name or _('your name'), text_fg=menu_props.text_active_col) for i in range(len(self.mediator.cars))] self.add_widgets(self.ents) self.add_widgets(widgets) ThanksPageGui.build(self, exit_behav=False) self.update_tsk = taskMgr.add(self.update_text, 'update text') self.enable_buttons(False)
def build(self, exit_behav): self.drv_info = self.props.gameprops.drivers_info menu_args = self.menu_args widgets = [Text(_('Select the driver'), pos=(-.2, .8), **menu_args.text_args)] t_a = self.menu_args.text_args.copy() del t_a['scale'] self.name = Text(_('Write your name:'), pos=(-.3, .6), scale=.06, align='right', wordwrap=128, **t_a) self.drivers = [] for row, col in product(range(2), range(4)): idx = col + row * 4 drv_btn = ImgBtn( scale=.24, pos=(-.95 + col * .5, 1, .3 - row * .64), frameColor=(0, 0, 0, 0), image=self.props.gameprops.drivers_img.path % idx, command=self.on_click, extraArgs=[idx], **self.menu_args.imgbtn_args) name = Text( '', pos=(-.95 + col * .5, .01 - row * .64), scale=.046, **t_a) drv_btn._name_txt = name widgets += [drv_btn, name] self.drivers += [widgets[-1]] sign = lambda pos_x: '\1green\1+\2' if pos_x > 0 else '' psign = lambda pos_x, sgn=sign: '+' if pos_x == 0 else sgn(pos_x) def ppcol(x): return '\1green\1%s\2' % x if x > 0 else '\1red\1%s\2' % x pcol = lambda x: x if x == 0 else ppcol(x) lab_lst = [(_('adherence'), .09), (_('speed'), .21), (_('stability'), .15)] widgets += map( lambda lab_def: self.__add_lab(*(lab_def + (row, col))), lab_lst) txt_lst = [(self.drv_info[idx - 1].adherence, .09), (self.drv_info[idx - 1].speed, .21), (self.drv_info[idx - 1].stability, .15)] widgets += map( lambda txt_def: self.__add_txt( *txt_def + (psign, pcol, col, row)), txt_lst) self.sel_drv_img = Img( self.props.gameprops.cars_img % self.mediator.car, parent=base.a2dBottomLeft, pos=(.3, 1, .4), scale=.28) widgets += [self.sel_drv_img, self.name] self.add_widgets(widgets) ffilterpath = self.eng.curr_path + 'yyagl/assets/shaders/filter.vert' with open(ffilterpath) as ffilter: vert = ffilter.read() shader = load_shader(vert, frag) if shader: self.sel_drv_img.set_shader(shader) self.sel_drv_img.set_transparency(True) self.t_s = TextureStage('ts') self.t_s.set_mode(TextureStage.MDecal) empty_img = PNMImage(1, 1) empty_img.add_alpha() empty_img.alpha_fill(0) tex = Texture() tex.load(empty_img) self.sel_drv_img.set_texture(self.t_s, tex) ThanksPageGui.build(self, exit_behav=exit_behav)
def palettize(self, palette_img, create_rgb=True): """ Runs all palettization procedures on the given PaletteImage. Creates an RGB version of the palette if requested. :palette_img: The PaletteImage you want to palettize. :create_rgb: Would you like to create an RGB variant of the palette? True by default. """ # We need to know the palette's prior size if not palette_img.size_known: raise PalettizerException( "Palette image's size is not known, this is a fatal error!") palette_name = palette_img.basename if self.debug: print( f'[{palette_img.page.group.dirname}] Compiling {palette_name}..' ) # Our max distortion is 1, as we do not want to resize the palette to be smaller accidentally max_distortion = 1 # This array holds all of our PNMImage source textures imgs = [] # We're going to check all of the source textures # so that we can load all of them and determine our palette's final size for placement in palette_img.placements: sources = placement.texture.sources # We need to know the size of all source textures # If a source texture's size is not known, that means that it has been defined but did not exist on the disk when creating textures.boo for source in sources: if not source.size_known: print( f'Warning: Size is not known for source {source.filename}, please consider fixing the texture path and re-running egg-palettize' ) # Source (original) full resolution texture size source = sources[0] x_size = source.x_size y_size = source.y_size # Prior texture position and size tex_position = placement.position tex_x_size = tex_position.x_size tex_y_size = tex_position.y_size # DISTORTER # Fold the points until they scream out # DISTORTER # Change the way it sounds # We need to calculate the maximum distortion for both our X and Y (U/V) coordinates if x_size != tex_x_size: x_distortion = x_size / tex_x_size if x_distortion > max_distortion: max_distortion = x_distortion if y_size != tex_y_size: y_distortion = y_size / tex_y_size if y_distortion > max_distortion: max_distortion = y_distortion # If we have more than one source, that means our texture # has been defined multiple times for the same group... # Panda3D uses the first source texture only, so that's what we'll do. # But we'll make sure to print a warning either way! if len(sources) > 1: source2 = sources[1] if source2.x_size != x_size or source2.y_size != y_size: print( f'Two different source textures are defined for {palette_name}: {source.filename} ({x_size} {y_size}) vs {source2.filename} ({source2.x_size} {source2.y_size})' ) # Time to load the source file from Pandora! img = self.read_texture(source.filename) # Add the source image to our list imgs.append(img) # Well, time to calculate the palette's final size! # We will multiply the current size with the highest distortion. # We do NOT calculate X and Y distortion separately. # Doing so would destroy the aspect ratio of the palette. current_x_size = palette_img.x_size current_y_size = palette_img.y_size new_x_size = round(current_x_size * max_distortion) new_y_size = round(current_y_size * max_distortion) # Power of two time! # It's easier for the game engine to load, as it does not have to scale it automatically. new_x_size, new_y_size = self.scale_power_of_2(new_x_size, new_y_size) # We've changed the palette size. It is necessary to recalculate our texture distortion. x_distortion = new_x_size / current_x_size y_distortion = new_y_size / current_y_size # Create our palette image with four channels. # We will cut down the last channel when necessary. # Having a fourth, empty channel would only increase the file size. new_image = PNMImage(new_x_size, new_y_size, 4) new_image.alpha_fill(1) # Textures with alpha always have four channels set (three for RGB and one for Alpha). has_alpha = palette_img.properties.effective_channels in (2, 4) rgb_only = palette_img.properties.format == TextureGlobals.F_alpha alpha_image = None # If necessary and possible, create an alpha image as well. # Textures with alpha always have four channels set (three for RGB and one for Alpha). if create_rgb and has_alpha and not rgb_only: alpha_image = PNMImage(new_x_size, new_y_size, 1) alpha_image.set_type(PalettizeGlobals.RGB_TYPE) for i, placement in enumerate(palette_img.placements): # Find the loaded source image from before... texture_img = imgs[i] # Calculate the placement of our image! tex_position = placement.placed # Determine the upper left and lower right corners # with some matrix magic. transform = placement.compute_tex_matrix() ul = transform.xform_point(LTexCoordd(0.0, 1.0)) lr = transform.xform_point(LTexCoordd(1.0, 0.0)) # Calculate the top, left, bottom and right corners. top = int(math.floor((1.0 - ul[1]) * new_y_size + 0.5)) left = int(math.floor(ul[0] * new_x_size + 0.5)) bottom = int(math.floor((1.0 - lr[1]) * new_y_size + 0.5)) right = int(math.floor(lr[0] * new_x_size + 0.5)) tex_x_size = right - left tex_y_size = bottom - top org_x_size = round(tex_position.x_size * x_distortion) org_y_size = round(tex_position.y_size * y_distortion) tex_x = round(tex_position.x * x_distortion) tex_y = round(tex_position.y * y_distortion) # Resize our image to the desired size. texture_img = self.resize_image(texture_img, tex_x_size, tex_y_size) for y in range(tex_y, tex_y + org_y_size): sy = y - top # UV wrapping modes - V component (for Y texture coordinate) if placement.placed.wrap_v == TextureGlobals.WM_clamp: sy = max(min(sy, tex_y_size - 1), 0) elif placement.placed.wrap_v == TextureGlobals.WM_mirror: sy = (tex_y_size * 2) - 1 - ( (-sy - 1) % (tex_y_size * 2)) if sy < 0 else sy % (tex_y_size * 2) sy = sy if sy < tex_y_size else 2 * tex_y_size - sy - 1 elif placement.placed.wrap_v == TextureGlobals.WM_mirror_once: sy = sy if sy < tex_y_size else 2 * tex_y_size - sy - 1 # Repeat texture sy = tex_y_size - 1 - ( (-sy - 1) % tex_y_size) if sy < 0 else sy % tex_y_size elif placement.placed.wrap_v == TextureGlobals.WM_border_color: if sy < 0 or sy >= tex_y_size: continue else: # Repeat texture sy = tex_y_size - 1 - ( (-sy - 1) % tex_y_size) if sy < 0 else sy % tex_y_size for x in range(tex_x, tex_x + org_x_size): sx = x - left # UV wrapping modes - U component (for X texture coordinate) if placement.placed.wrap_u == TextureGlobals.WM_clamp: sx = max(min(sx, tex_x_size - 1), 0) elif placement.placed.wrap_u == TextureGlobals.WM_mirror: sx = (tex_x_size * 2) - 1 - ( (-sx - 1) % (tex_x_size * 2)) if sx < 0 else sx % (tex_x_size * 2) sx = sx if sx < tex_x_size else 2 * tex_x_size - sx - 1 elif placement.placed.wrap_u == TextureGlobals.WM_mirror_once: sx = sx if sx >= 0 else ~sx # Repeat texture sx = tex_x_size - 1 - ( (-sx - 1) % tex_x_size) if sx < 0 else sx % tex_x_size elif placement.placed.wrap_u == TextureGlobals.WM_border_color: if sx < 0 or sx >= tex_x_size: continue else: # Repeat texture sx = tex_x_size - 1 - ( (-sx - 1) % tex_x_size) if sx < 0 else sx % tex_x_size new_image.set_xel(x, y, texture_img.get_xel(sx, sy)) new_image.set_alpha(x, y, texture_img.get_alpha(sx, sy)) if alpha_image: alpha_image.set_gray(x, y, texture_img.get_alpha(sx, sy)) return new_image, alpha_image, has_alpha, rgb_only
def build(self): self.drv_info = self.props.gameprops.drivers_info menu_props = self.menu_props widgets = [ Text(_('Select the drivers'), pos=(0, .91), **menu_props.text_args) ] t_a = self.menu_props.text_args.copy() del t_a['scale'] self.name = Text(_('Write your names:'), pos=(-.1, .7), scale=.06, align='right', wordwrap=128, **t_a) self.drivers = [] for row, col in product(range(2), range(4)): idx = col + row * 4 drv_btn = ImgBtn(scale=(.24, .24), pos=(-.75 + col * .5, .1 - row * .64), frame_col=(0, 0, 0, 0), img=self.props.gameprops.drivers_img.path % idx, cmd=self.on_click, extra_args=[idx], **self.menu_props.imgbtn_args) name = Text('', pos=(-.75 + col * .5, -.19 - row * .64), scale=.046, **t_a) drv_btn._name_txt = name widgets += [drv_btn, name] self.drivers += [widgets[-2]] sign = lambda pos_x: '\1green\1+\2' if pos_x > 0 else '' psign = lambda pos_x, sgn=sign: '+' if pos_x == 0 else sgn(pos_x) def ppcol(x): return '\1green\1%s\2' % x if x > 0 else '\1red\1%s\2' % x pcol = lambda x: x if x == 0 else ppcol(x) lab_lst = [(_('adherence'), -.11), (_('speed'), .01), (_('stability'), -.05)] widgets += list( map(lambda lab_def: self._add_lab(*(lab_def + (row, col))), lab_lst)) txt_lst = [(self.drv_info[idx - 1].adherence, -.11), (self.drv_info[idx - 1].speed, .01), (self.drv_info[idx - 1].stability, -.05)] widgets += list( map( lambda txt_def: self._add_txt(*txt_def + (psign, pcol, col, row)), txt_lst)) self.sel_drv_img = [] self.tss = [] instr_txt = _( 'If you use the keyboard, press FIRE to edit the field, then ' "ENTER when you're done. Other players can't move while someone " 'is writing (since, with keyboards, some letters may be bound to ' 'movements).') instr = Text(instr_txt, pos=(1.28, .8), scale=.042, wordwrap=24, **t_a) widgets += [self.name, instr] for i, car in enumerate(self.mediator.cars): self.sel_drv_img += [ Img(self.props.gameprops.cars_img % car, parent=base.a2dBottomLeft, pos=(.3, 1.74 - i * .46), scale=.22) ] widgets += [self.sel_drv_img[-1]] ffilterpath = self.eng.curr_path + 'yyagl/assets/shaders/filter.vert' with open(ffilterpath) as ffilter: vert = ffilter.read() shader = load_shader(vert, frag) if shader: self.sel_drv_img[-1].set_shader(shader) self.sel_drv_img[-1].set_transparent() self.tss += [TextureStage('ts')] self.tss[-1].set_mode(TextureStage.MDecal) empty_img = PNMImage(1, 1) empty_img.add_alpha() empty_img.alpha_fill(0) tex = Texture() tex.load(empty_img) self.sel_drv_img[-1].set_texture(self.tss[-1], tex) all_names = self.props.gameprops.player_names + self.props.gameprops.stored_player_names[ len(self.props.gameprops.player_names):] self.ents = [ Entry(scale=.06, pos=(0, .8 - .12 * i), entry_font=menu_props.font, width=12, frame_col=menu_props.btn_col, initial_text=all_names[i] if i < len(all_names) else _('your name'), text_fg=menu_props.text_active_col) for i in range(len(self.mediator.cars)) ] self.add_widgets(self.ents) self.add_widgets(widgets) ThanksPageGui.build(self, exit_behav=False) self.update_tsk = taskMgr.add(self.update_text, 'update text') self.enable_buttons(False)
def bld_page(self): self.skills = [drv[2] for drv in self.props.drivers] menu_gui = self.mdt.menu.gui menu_args = self.mdt.menu.gui.menu_args widgets = [ OnscreenText(text=_('Select the driver'), pos=(0, .8), **menu_gui.menu_args.text_args) ] self.track_path = self.mdt.menu.track t_a = self.mdt.menu.gui.menu_args.text_args.copy() del t_a['scale'] name = OnscreenText(_('Write your name:'), pos=(-.1, .6), scale=.06, align=TextNode.A_right, **t_a) self.ent = DirectEntry(scale=.08, pos=(0, 1, .6), entryFont=menu_args.font, width=12, frameColor=menu_args.btn_color, initialText=self.props.player_name or _('your name')) self.ent.onscreenText['fg'] = menu_args.text_fg self.drivers = [] for row, col in product(range(2), range(4)): idx = (col + 1) + row * 4 widgets += [ ImgBtn(scale=.24, pos=(-.75 + col * .5, 1, .25 - row * .5), frameColor=(0, 0, 0, 0), image=self.props.drivers_img[0] % idx, command=self.on_click, extraArgs=[idx], **self.mdt.menu.gui.menu_args.imgbtn_args) ] self.drivers += [widgets[-1]] sign = lambda x: '\1green\1+\2' if x > 0 else '' psign = lambda x: '+' if x == 0 else sign(x) def ppcol(x): return '\1green\1%s\2' % x if x > 0 else '\1red\1%s\2' % x pcol = lambda x: x if x == 0 else ppcol(x) def add_lab(txt, pos_z): return OnscreenText(txt + ':', pos=(-.95 + col * .5, pos_z - row * .5), scale=.046, align=TextNode.A_left, **t_a) def add_txt(val, pos_z): return OnscreenText('%s%s%%' % (psign(val), pcol(val)), pos=(-.55 + col * .5, pos_z - row * .5), scale=.052, align=TextNode.A_right, **t_a) lab_lst = [(_('adherence'), .04), (_('speed'), .16), (_('stability'), .1)] widgets += map(lambda lab_def: add_lab(*lab_def), lab_lst) txt_lst = [(self.skills[idx - 1][1], .04), (self.skills[idx - 1][0], .16), (self.skills[idx - 1][2], .1)] widgets += map(lambda txt_def: add_txt(*txt_def), txt_lst) self.img = OnscreenImage(self.props.cars_img % self.mdt.car, parent=base.a2dBottomRight, pos=(-.38, 1, .38), scale=.32) widgets += [self.img, name, self.ent] map(self.add_widget, widgets) fpath = eng.curr_path + 'yyagl/assets/shaders/filter.vert' with open(fpath) as ffilter: vert = ffilter.read() shader = Shader.make(Shader.SL_GLSL, vert, frag) self.img.setShader(shader) self.img.setTransparency(True) self.t_s = TextureStage('ts') self.t_s.setMode(TextureStage.MDecal) empty_img = PNMImage(1, 1) empty_img.add_alpha() empty_img.alpha_fill(0) tex = Texture() tex.load(empty_img) self.img.setTexture(self.t_s, tex) ThanksPageGui.bld_page(self) self.update_tsk = taskMgr.add(self.update_text, 'update text') self.enable_buttons(False)