Skip to content

Instantly share code, notes, and snippets.

@programmingpixels

programmingpixels/step1.py

Last active Jan 14, 2021
Embed
What would you like to do?
import pygame
import pygame.freetype
from pygame.sprite import Sprite
from pygame.rect import Rect
BLUE = (106, 159, 181)
WHITE = (255, 255, 255)
def create_surface_with_text(text, font_size, text_rgb, bg_rgb):
""" Returns surface with text written on """
font = pygame.freetype.SysFont("Courier", font_size, bold=True)
surface, _ = font.render(text=text, fgcolor=text_rgb, bgcolor=bg_rgb)
return surface.convert_alpha()
class UIElement(Sprite):
""" An user interface element that can be added to a surface """
def __init__(self, center_position, text, font_size, bg_rgb, text_rgb):
"""
Args:
center_position - tuple (x, y)
text - string of text to write
font_size - int
bg_rgb (background colour) - tuple (r, g, b)
text_rgb (text colour) - tuple (r, g, b)
"""
self.mouse_over = False # indicates if the mouse over the element
# create the default image
default_image = create_surface_with_text(
text=text, font_size=font_size, text_rgb=text_rgb, bg_rgb=bg_rgb
)
# create the image that shows when mouse is over the element
highlighted_image = create_surface_with_text(
text=text, font_size=font_size * 1.2, text_rgb=text_rgb, bg_rgb=bg_rgb
)
# add both images and their rects to lists
self.images = [default_image, highlighted_image]
self.rects = [
default_image.get_rect(center=center_position),
highlighted_image.get_rect(center=center_position),
]
# calls the init method of the parent sprite class
super().__init__()
# properties that vary the image and its rect when the mouse is over the element
@property
def image(self):
return self.images[1] if self.mouse_over else self.images[0]
@property
def rect(self):
return self.rects[1] if self.mouse_over else self.rects[0]
def update(self, mouse_pos):
if self.rect.collidepoint(mouse_pos):
self.mouse_over = True
else:
self.mouse_over = False
def draw(self, surface):
""" Draws element onto a surface """
surface.blit(self.image, self.rect)
def main():
pygame.init()
screen = pygame.display.set_mode((800, 600))
# create a ui element
uielement = UIElement(
center_position=(400, 400),
font_size=30,
bg_rgb=BLUE,
text_rgb=WHITE,
text="Hello World",
)
# main loop
while True:
for event in pygame.event.get():
pass
screen.fill(BLUE)
uielement.update(pygame.mouse.get_pos())
uielement.draw(screen)
pygame.display.flip()
# call main when the script is run
if __name__ == "__main__":
main()
import pygame
import pygame.freetype
from pygame.sprite import Sprite
from pygame.rect import Rect
BLUE = (106, 159, 181)
WHITE = (255, 255, 255)
def create_surface_with_text(text, font_size, text_rgb):
""" Returns surface with text written on """
font = pygame.freetype.SysFont("Courier", font_size, bold=True)
surface, _ = font.render(text=text, fgcolor=text_rgb)
return surface.convert_alpha()
class UIElement(Sprite):
""" An user interface element that can be added to a surface """
def __init__(self, center_position, text, font_size, text_rgb):
"""
Args:
center_position - tuple (x, y)
text - string of text to write
font_size - int
text_rgb (text colour) - tuple (r, g, b)
"""
self.mouse_over = False # indicates if the mouse over the element
# create the default image
default_image = create_surface_with_text(
text=text, font_size=font_size, text_rgb=text_rgb
)
# create the image that shows when mouse is over the element
highlighted_image = create_surface_with_text(
text=text, font_size=font_size * 1.2, text_rgb=text_rgb
)
# add both images and their rects to lists
self.images = [default_image, highlighted_image]
self.rects = [
default_image.get_rect(center=center_position),
highlighted_image.get_rect(center=center_position),
]
# calls the init method of the parent sprite class
super().__init__()
# properties that vary the image and its rect when the mouse is over the element
@property
def image(self):
return self.images[1] if self.mouse_over else self.images[0]
@property
def rect(self):
return self.rects[1] if self.mouse_over else self.rects[0]
def update(self, mouse_pos):
if self.rect.collidepoint(mouse_pos):
self.mouse_over = True
else:
self.mouse_over = False
def draw(self, surface):
""" Draws element onto a surface """
surface.blit(self.image, self.rect)
def main():
pygame.init()
screen = pygame.display.set_mode((800, 600))
# create a ui element
uielement = UIElement(
center_position=(400, 400),
font_size=30,
text_rgb=WHITE,
text="Hello World",
)
# main loop
while True:
for event in pygame.event.get():
pass
screen.fill(BLUE)
uielement.update(pygame.mouse.get_pos())
uielement.draw(screen)
pygame.display.flip()
# call main when the script is run
if __name__ == "__main__":
main()
import pygame
import pygame.freetype
from pygame.sprite import Sprite
from pygame.rect import Rect
from enum import Enum
BLUE = (106, 159, 181)
WHITE = (255, 255, 255)
def create_surface_with_text(text, font_size, text_rgb, bg_rgb):
""" Returns surface with text written on """
font = pygame.freetype.SysFont("Courier", font_size, bold=True)
surface, _ = font.render(text=text, fgcolor=text_rgb, bgcolor=bg_rgb)
return surface.convert_alpha()
class UIElement(Sprite):
""" An user interface element that can be added to a surface """
def __init__(self, center_position, text, font_size, bg_rgb, text_rgb, action=None):
"""
Args:
center_position - tuple (x, y)
text - string of text to write
font_size - int
bg_rgb (background colour) - tuple (r, g, b)
text_rgb (text colour) - tuple (r, g, b)
action - the gamestate change associated with this button
"""
self.mouse_over = False
default_image = create_surface_with_text(
text=text, font_size=font_size, text_rgb=text_rgb, bg_rgb=bg_rgb
)
highlighted_image = create_surface_with_text(
text=text, font_size=font_size * 1.2, text_rgb=text_rgb, bg_rgb=bg_rgb
)
self.images = [default_image, highlighted_image]
self.rects = [
default_image.get_rect(center=center_position),
highlighted_image.get_rect(center=center_position),
]
# assign button action
self.action = action
super().__init__()
@property
def image(self):
return self.images[1] if self.mouse_over else self.images[0]
@property
def rect(self):
return self.rects[1] if self.mouse_over else self.rects[0]
def update(self, mouse_pos, mouse_up):
""" Updates the mouse_over variable and returns the button's
action value when clicked.
"""
if self.rect.collidepoint(mouse_pos):
self.mouse_over = True
if mouse_up:
return self.action
else:
self.mouse_over = False
def draw(self, surface):
""" Draws element onto a surface """
surface.blit(self.image, self.rect)
def main():
pygame.init()
screen = pygame.display.set_mode((800, 600))
quit_btn = UIElement(
center_position=(400, 500),
font_size=30,
bg_rgb=BLUE,
text_rgb=WHITE,
text="Quit",
action=GameState.QUIT,
)
# main loop
while True:
mouse_up = False
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONUP and event.button == 1:
mouse_up = True
screen.fill(BLUE)
ui_action = quit_btn.update(pygame.mouse.get_pos(), mouse_up)
if ui_action is not None:
return
quit_btn.draw(screen)
pygame.display.flip()
class GameState(Enum):
QUIT = -1
if __name__ == "__main__":
main()
import pygame
import pygame.freetype
from pygame.sprite import Sprite
from pygame.rect import Rect
from enum import Enum
BLUE = (106, 159, 181)
WHITE = (255, 255, 255)
def create_surface_with_text(text, font_size, text_rgb, bg_rgb):
""" Returns surface with text written on """
font = pygame.freetype.SysFont("Courier", font_size, bold=True)
surface, _ = font.render(text=text, fgcolor=text_rgb, bgcolor=bg_rgb)
return surface.convert_alpha()
class UIElement(Sprite):
""" An user interface element that can be added to a surface """
def __init__(self, center_position, text, font_size, bg_rgb, text_rgb, action=None):
"""
Args:
center_position - tuple (x, y)
text - string of text to write
font_size - int
bg_rgb (background colour) - tuple (r, g, b)
text_rgb (text colour) - tuple (r, g, b)
action - the gamestate change associated with this button
"""
self.mouse_over = False
default_image = create_surface_with_text(
text=text, font_size=font_size, text_rgb=text_rgb, bg_rgb=bg_rgb
)
highlighted_image = create_surface_with_text(
text=text, font_size=font_size * 1.2, text_rgb=text_rgb, bg_rgb=bg_rgb
)
self.images = [default_image, highlighted_image]
self.rects = [
default_image.get_rect(center=center_position),
highlighted_image.get_rect(center=center_position),
]
self.action = action
super().__init__()
@property
def image(self):
return self.images[1] if self.mouse_over else self.images[0]
@property
def rect(self):
return self.rects[1] if self.mouse_over else self.rects[0]
def update(self, mouse_pos, mouse_up):
""" Updates the mouse_over variable and returns the button's
action value when clicked.
"""
if self.rect.collidepoint(mouse_pos):
self.mouse_over = True
if mouse_up:
return self.action
else:
self.mouse_over = False
def draw(self, surface):
""" Draws element onto a surface """
surface.blit(self.image, self.rect)
def main():
pygame.init()
screen = pygame.display.set_mode((800, 600))
game_state = GameState.TITLE
while True:
if game_state == GameState.TITLE:
game_state = title_screen(screen)
if game_state == GameState.NEWGAME:
game_state = play_level(screen)
if game_state == GameState.QUIT:
pygame.quit()
return
def title_screen(screen):
start_btn = UIElement(
center_position=(400, 400),
font_size=30,
bg_rgb=BLUE,
text_rgb=WHITE,
text="Start",
action=GameState.NEWGAME,
)
quit_btn = UIElement(
center_position=(400, 500),
font_size=30,
bg_rgb=BLUE,
text_rgb=WHITE,
text="Quit",
action=GameState.QUIT,
)
buttons = [start_btn, quit_btn]
while True:
mouse_up = False
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONUP and event.button == 1:
mouse_up = True
screen.fill(BLUE)
for button in buttons:
ui_action = button.update(pygame.mouse.get_pos(), mouse_up)
if ui_action is not None:
return ui_action
button.draw(screen)
pygame.display.flip()
def play_level(screen):
return_btn = UIElement(
center_position=(140, 570),
font_size=20,
bg_rgb=BLUE,
text_rgb=WHITE,
text="Return to main menu",
action=GameState.TITLE,
)
while True:
mouse_up = False
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONUP and event.button == 1:
mouse_up = True
screen.fill(BLUE)
ui_action = return_btn.update(pygame.mouse.get_pos(), mouse_up)
if ui_action is not None:
return ui_action
return_btn.draw(screen)
pygame.display.flip()
class GameState(Enum):
QUIT = -1
TITLE = 0
NEWGAME = 1
if __name__ == "__main__":
main()
import pygame
import pygame.freetype
from pygame.sprite import Sprite
from pygame.rect import Rect
from enum import Enum
from pygame.sprite import RenderUpdates
BLUE = (106, 159, 181)
WHITE = (255, 255, 255)
def create_surface_with_text(text, font_size, text_rgb, bg_rgb):
""" Returns surface with text written on """
font = pygame.freetype.SysFont("Courier", font_size, bold=True)
surface, _ = font.render(text=text, fgcolor=text_rgb, bgcolor=bg_rgb)
return surface.convert_alpha()
class UIElement(Sprite):
""" An user interface element that can be added to a surface """
def __init__(self, center_position, text, font_size, bg_rgb, text_rgb, action=None):
"""
Args:
center_position - tuple (x, y)
text - string of text to write
font_size - int
bg_rgb (background colour) - tuple (r, g, b)
text_rgb (text colour) - tuple (r, g, b)
action - the gamestate change associated with this button
"""
self.mouse_over = False
default_image = create_surface_with_text(
text=text, font_size=font_size, text_rgb=text_rgb, bg_rgb=bg_rgb
)
highlighted_image = create_surface_with_text(
text=text, font_size=font_size * 1.2, text_rgb=text_rgb, bg_rgb=bg_rgb
)
self.images = [default_image, highlighted_image]
self.rects = [
default_image.get_rect(center=center_position),
highlighted_image.get_rect(center=center_position),
]
self.action = action
super().__init__()
@property
def image(self):
return self.images[1] if self.mouse_over else self.images[0]
@property
def rect(self):
return self.rects[1] if self.mouse_over else self.rects[0]
def update(self, mouse_pos, mouse_up):
""" Updates the mouse_over variable and returns the button's
action value when clicked.
"""
if self.rect.collidepoint(mouse_pos):
self.mouse_over = True
if mouse_up:
return self.action
else:
self.mouse_over = False
def draw(self, surface):
""" Draws element onto a surface """
surface.blit(self.image, self.rect)
class Player:
""" Stores information about a player """
def __init__(self, score=0, lives=3, current_level=1):
self.score = score
self.lives = lives
self.current_level = current_level
def main():
pygame.init()
screen = pygame.display.set_mode((800, 600))
game_state = GameState.TITLE
while True:
if game_state == GameState.TITLE:
game_state = title_screen(screen)
if game_state == GameState.NEWGAME:
player = Player()
game_state = play_level(screen, player)
if game_state == GameState.NEXT_LEVEL:
player.current_level += 1
game_state = play_level(screen, player)
if game_state == GameState.QUIT:
pygame.quit()
return
def title_screen(screen):
start_btn = UIElement(
center_position=(400, 400),
font_size=30,
bg_rgb=BLUE,
text_rgb=WHITE,
text="Start",
action=GameState.NEWGAME,
)
quit_btn = UIElement(
center_position=(400, 500),
font_size=30,
bg_rgb=BLUE,
text_rgb=WHITE,
text="Quit",
action=GameState.QUIT,
)
buttons = RenderUpdates(start_btn, quit_btn)
return game_loop(screen, buttons)
def play_level(screen, player):
return_btn = UIElement(
center_position=(140, 570),
font_size=20,
bg_rgb=BLUE,
text_rgb=WHITE,
text="Return to main menu",
action=GameState.TITLE,
)
nextlevel_btn = UIElement(
center_position=(400, 400),
font_size=30,
bg_rgb=BLUE,
text_rgb=WHITE,
text=f"Next level ({player.current_level + 1})",
action=GameState.NEXT_LEVEL,
)
buttons = RenderUpdates(return_btn, nextlevel_btn)
return game_loop(screen, buttons)
def game_loop(screen, buttons):
""" Handles game loop until an action is return by a button in the
buttons sprite renderer.
"""
while True:
mouse_up = False
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONUP and event.button == 1:
mouse_up = True
screen.fill(BLUE)
for button in buttons:
ui_action = button.update(pygame.mouse.get_pos(), mouse_up)
if ui_action is not None:
return ui_action
buttons.draw(screen)
pygame.display.flip()
class GameState(Enum):
QUIT = -1
TITLE = 0
NEWGAME = 1
NEXT_LEVEL = 2
if __name__ == "__main__":
main()
import pygame
import pygame.freetype
from pygame.sprite import Sprite
from pygame.rect import Rect
from enum import Enum
from pygame.sprite import RenderUpdates
BLUE = (106, 159, 181)
WHITE = (255, 255, 255)
def create_surface_with_text(text, font_size, text_rgb, bg_rgb):
""" Returns surface with text written on """
font = pygame.freetype.SysFont("Courier", font_size, bold=True)
surface, _ = font.render(text=text, fgcolor=text_rgb, bgcolor=bg_rgb)
return surface.convert_alpha()
class UIElement(Sprite):
""" An user interface element that can be added to a surface """
def __init__(self, center_position, text, font_size, bg_rgb, text_rgb, action=None):
"""
Args:
center_position - tuple (x, y)
text - string of text to write
font_size - int
bg_rgb (background colour) - tuple (r, g, b)
text_rgb (text colour) - tuple (r, g, b)
action - the gamestate change associated with this button
"""
self.mouse_over = False
default_image = create_surface_with_text(
text=text, font_size=font_size, text_rgb=text_rgb, bg_rgb=bg_rgb
)
highlighted_image = create_surface_with_text(
text=text, font_size=font_size * 1.2, text_rgb=text_rgb, bg_rgb=bg_rgb
)
self.images = [default_image, highlighted_image]
self.rects = [
default_image.get_rect(center=center_position),
highlighted_image.get_rect(center=center_position),
]
self.action = action
super().__init__()
@property
def image(self):
return self.images[1] if self.mouse_over else self.images[0]
@property
def rect(self):
return self.rects[1] if self.mouse_over else self.rects[0]
def update(self, mouse_pos, mouse_up):
""" Updates the mouse_over variable and returns the button's
action value when clicked.
"""
if self.rect.collidepoint(mouse_pos):
self.mouse_over = True
if mouse_up:
return self.action
else:
self.mouse_over = False
def draw(self, surface):
""" Draws element onto a surface """
surface.blit(self.image, self.rect)
class Player:
""" Stores information about a player """
def __init__(self, score=0, lives=3, current_level=1):
self.score = score
self.lives = lives
self.current_level = current_level
def main():
pygame.init()
screen = pygame.display.set_mode((800, 600))
game_state = GameState.TITLE
while True:
if game_state == GameState.TITLE:
game_state = title_screen(screen)
if game_state == GameState.NEWGAME:
player = Player()
game_state = play_level(screen, player)
if game_state == GameState.NEXT_LEVEL:
player.current_level += 1
game_state = play_level(screen, player)
if game_state == GameState.QUIT:
pygame.quit()
return
def title_screen(screen):
start_btn = UIElement(
center_position=(400, 400),
font_size=30,
bg_rgb=BLUE,
text_rgb=WHITE,
text="Start",
action=GameState.NEWGAME,
)
quit_btn = UIElement(
center_position=(400, 500),
font_size=30,
bg_rgb=BLUE,
text_rgb=WHITE,
text="Quit",
action=GameState.QUIT,
)
buttons = RenderUpdates(start_btn, quit_btn)
return game_loop(screen, buttons)
def play_level(screen, player):
return_btn = UIElement(
center_position=(140, 570),
font_size=20,
bg_rgb=BLUE,
text_rgb=WHITE,
text="Return to main menu",
action=GameState.TITLE,
)
nextlevel_btn = UIElement(
center_position=(400, 400),
font_size=30,
bg_rgb=BLUE,
text_rgb=WHITE,
text=f"Next level ({player.current_level + 1})",
action=GameState.NEXT_LEVEL,
)
buttons = RenderUpdates(return_btn, nextlevel_btn)
return game_loop(screen, buttons)
def game_loop(screen, buttons):
""" Handles game loop until an action is return by a button in the
buttons sprite renderer.
"""
while True:
mouse_up = False
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
if event.type == pygame.MOUSEBUTTONUP and event.button == 1:
mouse_up = True
screen.fill(BLUE)
for button in buttons:
ui_action = button.update(pygame.mouse.get_pos(), mouse_up)
if ui_action is not None:
return ui_action
buttons.draw(screen)
pygame.display.flip()
class GameState(Enum):
QUIT = -1
TITLE = 0
NEWGAME = 1
NEXT_LEVEL = 2
if __name__ == "__main__":
main()
@programmingpixels

This comment has been minimized.

Copy link
Owner Author

@programmingpixels programmingpixels commented Nov 18, 2020

The file: step1_without_bg_rgb.py
Is an example of how you can complete step1 without specifying any object's background colours. If you're just interested in following the tutorials then the primary files you might like to compare your code with are:

  1. step1.py
  2. step2.py
  3. step3.py
  4. step4.py
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment