Example #1
0
    def order_reversed_spritesheet(self, flipped_sheet):
        """Reorganize the frames in a flipped sprite sheet so that
        they are in the same order as the original sheet.

        Args:
            flipped_sheet: A PyGame Surface containing a flipped sprite
                sheet.

        Returns:
            A PyGame Surface containing the sprite sheet with each frame
            flipped and in the correct order.
        """
        ordered_sheet = Surface((self.spritesheet.get_width(),
                                 self.spritesheet.get_height()),
                                SRCALPHA)
        ordered_sheet.convert_alpha()

        for frame_index in xrange(0, self.get_num_of_frames()):
            frame_x = self.get_width() * frame_index
            old_frame_index = self.get_num_of_frames() - 1 - frame_index
            old_region = self.get_frame_region(old_frame_index)

            ordered_sheet.blit(flipped_sheet, (frame_x, 0), old_region)

        return ordered_sheet
Example #2
0
    def update(self, duration):
        """ update all the contained linewidgets.
        Return right away if no text has changed.
        """

        if self.dirty == 0:  # no new text has been added
            return

        # make the box
        size = self.rect.size
        bgcolor = self.bgcolor
        if bgcolor:  # completely opaque bg
            img = Surface(size)
            img.fill(self.bgcolor)
            img = img.convert()
        else:  # more or less transparent
            img = Surface(size, SRCALPHA)  # handles transparency
            transparency = 50  # 0 = transparent, 255 = opaque
            img.fill((0, 0, 0, transparency))  # black
            img = img.convert_alpha()

        # blit each line
        for wid in self.linewidgets:
            wid.update(duration)
            img.blit(wid.image, wid.rect)

        self.image = img
        self.dirty = 0
Example #3
0
    def __init__(self, evManager, numlines=3, rect=(0, 0, 100, 20), txtcolor=(255, 0, 0), bgcolor=None):
        Widget.__init__(self, evManager)

        self._em.reg_cb(ChatlogUpdatedEvent, self.on_remotechat)
        self._em.reg_cb(MGameAdminEvt, self.on_gameadmin)
        self._em.reg_cb(MNameChangeFailEvt, self.on_namechangefail)
        self._em.reg_cb(MMyNameChangedEvent, self.on_namechangesuccess)
        self._em.reg_cb(MNameChangedEvt, self.on_namechangesuccess)
        self._em.reg_cb(MdHpsChangeEvt, self.on_updatehps)

        self.font = Font(None, config_get_fontsize())
        self.rect = rect
        size = rect.size
        self.txtcolor = txtcolor
        self.bgcolor = bgcolor
        if bgcolor:  # completely opaque bg
            img = Surface(size)
            img.fill(self.bgcolor)
            img = img.convert()
        else:  # more or less transparent
            img = Surface(self.rect.size, SRCALPHA)  # handles transparency
            transparency = 50  # 0 = transparent, 255 = opaque
            img.fill((0, 0, 0, transparency))  # black
            img = img.convert_alpha()
        self.image = img

        self.maxnumlines = numlines
        self.linewidgets = deque(maxlen=numlines)  # deque of TextLabelWidgets
Example #4
0
    def update(self, duration):
        """ update all the contained linewidgets
        TODO: check that it works with transparent bg
        """

        if self.dirty == 0:
            return

        # make the box
        size = self.rect.size
        bgcol = self.bgcolor
        if bgcol:  # only display a bg img if bgcolor specified
            img = Surface(size)
            img.fill(bgcol)
            img = img.convert()
        else:  # more or less transparent
            img = Surface(size, SRCALPHA)  # handles transparency
            transparency = 50  # 0 = transparent, 255 = opaque
            img.fill((0, 0, 0, transparency))
            img = img.convert_alpha()

        # blit each line
        numelemts = min(len(self.texts), self.maxnumlines)
        for i in range(numelemts):
            wid = self.linewidgets[i]
            wid.set_text(self.texts[-i - 1])
            wid.update(duration)
            img.blit(wid.image, wid.rect)

        self.image = img
def make_surface(size: Tuple[int, int], alpha: bool=True, used_colors: List[Color]=[], bg_color: Optional[Color]=None):
    if bg_color is not None:
        fill_color = bg_color
    else:
        used_colors = set(used_colors)
        for i in range(256):
            fill_color = (i, i, i)
            if fill_color not in used_colors:
                break
    surface = Surface(size)
    surface.fill(fill_color)
    if pygame.display.get_init():
        if alpha and bg_color is None:
            surface.convert_alpha()
            surface.set_colorkey(surface.get_at((0, 0)))
        else:
            surface.convert()

    return surface
Example #6
0
    def __init__(self, evManager, rect=None):
        Widget.__init__(self, evManager)
        # Widget init sets dirty to true, hence the actual rendering
        # will be done in InputFieldWidget.update(), called by the view renderer.

        self._em.reg_cb(NonprintableKeyEvent, self.on_invisiblekeypushed)
        self._em.reg_cb(UnicodeKeyPushedEvent, self.on_visiblekeypushed)
        self._em.reg_cb(DownClickEvent, self.on_downclick)

        self.text = ""
        self.font = Font(None, config_get_fontsize())

        if rect:
            self.rect = rect
        else:
            self.rect = Rect((0, 0), (100, config_get_fontsize() + 4))
            # 100px = default width,
            # 25px = font height, 4px = 1 px for each of border-bottom,
            # padding bottom, padding top, and border top.

        # rectangle to be drawn around the box as border
        border_rect = Rect((0, 0), self.rect.size)
        # draw and store unfocused empty box
        emptyboxImg = Surface(self.rect.size)
        self.unfocused_bgcolor = config_get_unfocusedinput_bgcolor()
        self.unfocused_txtcolor = config_get_unfocusedinput_txtcolor()
        emptyboxImg.fill(self.unfocused_bgcolor)
        pygame.draw.rect(emptyboxImg, self.unfocused_txtcolor, border_rect, 2)
        self.unfocused_emptyboxImg = emptyboxImg.convert_alpha()
        self.image = emptyboxImg
        # draw and store focused empty box
        emptyboxImg = Surface(self.rect.size)
        self.focused_bgcolor = config_get_focusedinput_bgcolor()
        self.focused_txtcolor = config_get_focusedinput_txtcolor()
        emptyboxImg.fill(self.focused_bgcolor)
        pygame.draw.rect(emptyboxImg, self.focused_txtcolor, border_rect, 2)
        self.focused_emptyboxImg = emptyboxImg.convert_alpha()

        self.textPos = (4, 2)  # 4px padding-left and 2px padding-top
Example #7
0
    def update(self, duration):
        """ reblit the entries on my rect """
        if self.dirty == 0:
            return

        # make the transparent box
        size = self.rect.size
        img = Surface(size, SRCALPHA)
        transparency = 50 # 0 = transparent, 255 = opaque
        img.fill((0, 0, 0, transparency))
        img = img.convert_alpha() # TODO: alpha or color key?

        # blit each entry
        for entry in self.entries:
            entry.update(duration)
            img.blit(entry.image, entry.rect)

        self.image = img
    def add_underline(self):
        """Draws an underline on the text Surface, on top the text."""
        # The underline will be drawn from the bottom of the text Surface
        # and will extend its entire horizontal length.
        text_width = self.rect.width
        text_height = self.rect.height

        start_point = (0, text_height - 4)
        end_point = (text_width, text_height - 4)

        # The underline is drawn onto a new Surface with the same dimensions
        # as the text Surface, but slightly taller to account for the
        # underline. The text is drawn on top.
        new_image = Surface((text_width, text_height + 4), pygame.SRCALPHA, 32)
        new_image = new_image.convert_alpha()
        draw.line(new_image, UNDERLINE_COLOUR, start_point,
                  end_point, UNDERLINE_SIZE)
        new_image.blit(self.image, (0, 0))

        self.image = new_image
Example #9
0
def render_text(text,
                fontname,
                font_size,
                color,
                bg_color,
                resource,
                size,
                centre=True):
    """Render the text so it will fit in the given size, reducing font
       size as needed.

       Note that this does not do any text wrapping."""
    done = False
    width, height = size
    color = convert_color(color)
    bg_color = convert_color(bg_color)
    surface = Surface(size, SRCALPHA)
    if resource.CONVERT_ALPHA:
        surface = surface.convert_alpha()
    else:
        # Don't actually render the text when testing
        return surface
    surface.fill(bg_color)
    while not done and font_size > 0:
        # We bail at font_size 1 and just clip in that case, since we're
        # out of good options
        font = resource.get_font(fontname, font_size)
        text_surf = font.render(text, True, color)
        if (text_surf.get_width() > width or text_surf.get_height() > height):
            font_size -= 1
        else:
            done = True
    if centre:
        # Centre the text in the rect
        x = max(0, (width - text_surf.get_width()) // 2)
        y = max(0, (height - text_surf.get_height()) // 2)
    else:
        x = y = 0
    surface.blit(text_surf, (x, y))
    return surface
Example #10
0
class SettingsScreen(Screen):
	""" The settings screen class.

	An instance of this class represents a settings screen.

	Attributes:
		_settings: The game settings.
		_entries: The settings entries.
		_screen: The screen to draw on.
		_width: The width of the window.
		_height: The height of the window.
		_window: The surrounding window.
		_bg: The background picture.
		_font: The font to use.
		_font_height: The height of the used font.
		_selected: The index of the selected settings entry.
		_first_y: The y coordinate of the first entry.
		_delta_y: The difference in the y axis between the entries.
		_plus_button: The pre-rendered plus button.
		_minus_button: The pre-rendered minus button.
	"""
	# color of an entry
	SELECTED_COLOR = (255, 255, 0)
	# color of the selected entry
	COLOR = (150, 150, 0)

	def __init__(self, screen, width, height, window, settings):
		""" Generates a new instance of this class.

		Generates a new instance of this class and sets the field information.

		Args:
			screen: The screen to draw on.
			width: The width of the screen.
			height: The height of the screen.
			window: The surrounding window.
			settings: The game settings.
		"""
		self._settings = settings

		self._screen = screen
		self._width = width
		self._height = height
		self._window = window
		self._bg = PictureManager.MANAGER.get_picture("menuBackground.png")
		self._bg = pygame.transform.scale(self._bg, (width, height))
		self._font = pygame.font.SysFont("arial", 24)
		self._font_height = self._font.get_linesize()
		self._selected = 0

		sound_entry = SettingsEntry(Settings.SOUND_VOLUME, "Sound", SettingsEntry.SCALE10,
									self._settings.get_value(Settings.SOUND_VOLUME), button_size=self._font_height)
		music_entry = SettingsEntry(Settings.MUSIC_VOLUME, "Music", SettingsEntry.SCALE10,
									self._settings.get_value(Settings.MUSIC_VOLUME), button_size=self._font_height)
		fx_entry = SettingsEntry(Settings.FX_VOLUME, "Effects", SettingsEntry.SCALE10,
								 self._settings.get_value(Settings.FX_VOLUME), button_size=self._font_height)
		joystick_entry = SettingsEntry(Settings.JOYSTICK, "Controller", SettingsEntry.BOOL,
								 self._settings.get_value(Settings.JOYSTICK), button_size=self._font_height)
		back_entry = SettingsEntry(None, "back", SettingsEntry.ACTION,
								 None, action=self.back)

		self._entries = (sound_entry, music_entry, fx_entry, joystick_entry, back_entry)

		self._first_y = 0.5 * (self._height - len(self._entries) * (self._font_height + 5))
		self._delta_y = self._font_height + 5

		self._plus_button = None
		self._minus_button = None

		self._unchecked_bool = None
		self._checked_bool = None

		self._prepare_buttons()

	def _prepare_buttons(self):
		""" Prepares the buttons.

		This method pre-renders the plus and minus buttons.
		"""
		# draw plus button
		self._plus_button = Surface((self._font_height, self._font_height), pygame.SRCALPHA, 32)
		self._plus_button.convert_alpha()
		pygame.draw.rect(self._plus_button, SettingsScreen.COLOR, Rect(0, self._font_height/3, self._font_height, self._font_height/3))
		pygame.draw.rect(self._plus_button, SettingsScreen.COLOR, Rect(self._font_height/3, 0, self._font_height/3, self._font_height))

		# draw minus button
		self._minus_button = Surface((self._font_height, self._font_height), pygame.SRCALPHA, 32)
		self._minus_button.convert_alpha()
		pygame.draw.rect(self._minus_button, SettingsScreen.COLOR, Rect(0, self._font_height/3, self._font_height, self._font_height/3))

		# draw unchecked bool button
		self._unchecked_bool = Surface((self._font_height, self._font_height), pygame.SRCALPHA, 32)
		self._unchecked_bool.convert_alpha()
		pygame.draw.rect(self._unchecked_bool, SettingsScreen.COLOR, Rect(0, 0, self._font_height, self._font_height), 3)

		# draw checked bool button
		self._checked_bool = Surface((self._font_height, self._font_height), pygame.SRCALPHA, 32)
		self._checked_bool.convert_alpha()
		pygame.draw.rect(self._checked_bool, SettingsScreen.COLOR, Rect(0, 0, self._font_height, self._font_height), 3)
		pygame.draw.line(self._checked_bool, SettingsScreen.COLOR, (0, 0), (self._font_height, self._font_height), 3)
		pygame.draw.line(self._checked_bool, SettingsScreen.COLOR, (0, self._font_height), (self._font_height, 0), 3)

	def draw(self):
		""" Draws the settings.

		This method draws the settings on the screen.
		"""
		self._screen.blit(self._bg, (0, 0))
		y = self._first_y
		i = 0
		for entry in self._entries:
			if self._selected == i:
				text = self._font.render(entry.text, True, SettingsScreen.SELECTED_COLOR)
			else:
				text = self._font.render(entry.text, True, SettingsScreen.COLOR)
			self._screen.blit(text, (100, y))

			if entry.type == SettingsEntry.SCALE10:
				value = self._font.render(str(entry.value), True, SettingsScreen.COLOR)
				self._screen.blit(value, (self._width - 100 - value.get_width(), y))

				entry.plus.topleft = (self._width - 95, y)
				self._screen.blit(self._plus_button, entry.plus.topleft)
				entry.minus.topleft = (self._width - 105 - value.get_width() - self._font_height, y)
				self._screen.blit(self._minus_button, entry.minus.topleft)
			elif entry.type == SettingsEntry.BOOL:
				entry.plus.topleft = (self._width - 100 - self._font_height, y)
				if entry.value:
					self._screen.blit(self._checked_bool, entry.plus.topleft)
				else:
					self._screen.blit(self._unchecked_bool, entry.plus.topleft)
			y += self._delta_y
			i += 1

	def back(self):
		""" Returns to the main menu.

		This method saves the settings and return to the main menu.
		"""
		for entry in self._entries:
			if entry.name is not None:
				self._settings.set_value(entry.name, entry.value)
		self._window.switch(window.Window.MENU)

	def key_down(self, key):
		""" Handles key down events.

		This method handles key down events.
		The pressing of the up or down key changes the selected settings entry.
		The pressing of the left or right key changes the value of the selected entry.
		The pressing of the return key performs the action of the entry.
		The pressing of the escape key returns to the main menu.

		Args:
			key: The key event information provided by pygame.
		"""
		if key == K_DOWN:
			if self._selected < len(self._entries) - 1:
				self._selected += 1
		elif key == K_UP:
			if self._selected > 0:
				self._selected -= 1
		elif key == K_RIGHT:
			self._entries[self._selected].inc()
		elif key == K_LEFT:
			self._entries[self._selected].dec()
		elif key == K_ESCAPE:
			self.back()
		elif key == K_RETURN or key == K_SPACE:
			self._entries[self._selected].act()

	def mouse_click(self, pos, button):
		""" Handles mouse click events.

		This method is handles mouse click events.

		Args:
			pos: The position of the mouse.
			button: The button pressed.
		"""
		if button == 1:
			entry = self._entries[self._selected]
			if entry.plus.collidepoint(pos):
				entry.inc()
			elif entry.minus.collidepoint(pos):
				entry.dec()
			else:
				entry.act()

	def mouse_move(self, pos):
		""" Handles mouse move events.

		This method handles mouse movement events.

		Args:
			pos: The position of the mouse.
		"""
		if pos[1] < self._first_y:
			self._selected = 0
		else:
			dy = math.trunc((pos[1] - self._first_y) / self._delta_y)
			if dy >= len(self._entries):
				dy = len(self._entries)-1
			self._selected = dy
Example #11
0
    pygame.init()
    screen = pygame.display.set_mode((300, 300))

    bg = Surface((200, 200))
    bg.fill((255, 0, 0))    
    bg = bg.convert()
    screen.blit(bg, (50, 50))

    font = Font(None, 25)
    txt = 'qwertyuiop'
    txtimg = font.render(txt, 1, (255, 255, 255)) # antialiasing w/o bg => alpha 
    
    b = Surface((100, 100), SRCALPHA)
    b.fill((111, 111, 111, 128))
    b.blit(txtimg, (10, 10))
    b = b.convert_alpha()
    screen.blit(b, (25, 25))
    
    # what's below has better perf, but bad output when antialias + transparency 
    c = Surface((100, 100))
    colkey = (255, 0, 255)
    c.set_colorkey(colkey, RLEACCEL)
    c.fill(colkey) # make the surface bg invisible
    
    c2 = Surface((100, 100))
    c2.fill((111, 111, 111))
    c2.set_alpha(128, RLEACCEL) # semi-transparent gray bg
    #c.blit(c2, (0, 0))
    c2 = c2.convert()
    txtimg2 = txtimg.convert(c) # sucks if txtimg is antialiased
    c.blit(txtimg2, (10, 10))