Initial Commit
This commit is contained in:
300
lib/interface.py
Normal file
300
lib/interface.py
Normal file
@@ -0,0 +1,300 @@
|
||||
#!~/.pyenv/versions/3.11.6/bin/python
|
||||
#
|
||||
# Copyright (c) 2024 Cutieguwu | Olivia Brooks
|
||||
#
|
||||
# -*- coding:utf-8 -*-
|
||||
# @Title: Interface Items.
|
||||
# @Author: Cutieguwu | Olivia Brooks
|
||||
# @Email: owen.brooks77@gmail.com | obroo2@ocdsb.ca
|
||||
# @Description: Interface items for menus and scenes in a pygame game.
|
||||
#
|
||||
# @Script: interface.py
|
||||
# @Date Created: 22 Mar, 2024
|
||||
# @Last Modified: 13 Jun, 2024
|
||||
# @Last Modified by: Cutieguwu | Olivia Brooks
|
||||
# ----------------------------------------------------------
|
||||
|
||||
import pygame
|
||||
from lib.system import FEATURES
|
||||
|
||||
|
||||
class Button():
|
||||
"""
|
||||
Creates a button on a window.
|
||||
"""
|
||||
|
||||
def __init__(self, game, name, x, y, image_neutral, image_hover, function, args=None):
|
||||
self.TYPE = "button"
|
||||
|
||||
width = image_neutral.get_width() # Can use neutral image as all images should have identical sizes.
|
||||
height = image_neutral.get_height()
|
||||
|
||||
self.GAME = game
|
||||
self.WINDOW = self.GAME.WINDOW
|
||||
scale = self.GAME.SCALE.scaleUi
|
||||
|
||||
self.function = function
|
||||
self.functionArgs = args
|
||||
|
||||
self.ID = name
|
||||
|
||||
self.IMAGES = {
|
||||
"neutral": pygame.transform.scale(image_neutral, (width * scale, height * scale)),
|
||||
"hover": pygame.transform.scale(image_hover, (width * scale, height * scale))
|
||||
}
|
||||
|
||||
Interface_Functions.convert_images(self)
|
||||
|
||||
self.rect = self.IMAGES["neutral"].get_rect()
|
||||
self.rect.topleft = (x * scale, y * scale)
|
||||
|
||||
# Cannot overwrite rect.collidepoint with Interface_Functions.collidepoint.
|
||||
|
||||
self.time_delay = 0
|
||||
|
||||
self.GAME.gameInteractables.append(self) # Add to button to refresh.
|
||||
|
||||
def draw(self):
|
||||
"""
|
||||
Draws button on screen.
|
||||
"""
|
||||
|
||||
Interface_Functions.draw(self)
|
||||
|
||||
def is_hovered(self):
|
||||
"""
|
||||
Checks if button is hovered.
|
||||
"""
|
||||
|
||||
return Interface_Functions.collidepoint(self, pygame.mouse.get_pos())
|
||||
|
||||
def remove(self):
|
||||
"""
|
||||
Clears button from screen.
|
||||
"""
|
||||
|
||||
Interface_Functions.destroy(self)
|
||||
|
||||
class Progress_bar():
|
||||
"""
|
||||
Creates a progress bar that updates based on a scale.
|
||||
"""
|
||||
|
||||
def __init__(self, game, x, y, barWidth:int, bobberImages:list, barImageLeft, barImageRight, barImageClear, barImageFill):
|
||||
"""
|
||||
x: distance in percent from window origin.
|
||||
y: distance in percent from window origin.
|
||||
barWidth: Percent of window width filled.
|
||||
"""
|
||||
|
||||
self.GAME = game
|
||||
self.WINDOW = self.GAME.WINDOW
|
||||
|
||||
self.x = (x / 100) * self.WINDOW.width
|
||||
self.y = (y / 100) * self.WINDOW.height
|
||||
|
||||
for image in bobberImages:
|
||||
image.convert_alpha()
|
||||
|
||||
self.bobberImages = bobberImages
|
||||
|
||||
self.barImages = {
|
||||
"left": barImageLeft.convert_alpha(),
|
||||
"right": barImageRight.convert_alpha(),
|
||||
"clear": barImageClear.convert_alpha(),
|
||||
"fill": barImageFill.convert_alpha()
|
||||
}
|
||||
|
||||
self.bobberState = 0
|
||||
self.bobberStateRange = len(bobberImages)
|
||||
|
||||
self.widthLeft = self.barImages["left"].get_width()
|
||||
self.widthRight = self.barImages["right"].get_width()
|
||||
|
||||
self.barFillWidth = int("%.0f" % ((self.WINDOW.width * (barWidth / 100)) - (self.widthLeft + self.widthRight)))
|
||||
|
||||
self.barHeight = self.barImages["left"].get_height()
|
||||
self.bobberHeight = self.bobberImages[self.bobberState].get_height()
|
||||
|
||||
self.barCenterOffset = (self.barHeight / 2) - (self.barImages["clear"].get_height() / 2)
|
||||
|
||||
self.bobberTimer = 0
|
||||
|
||||
def draw(self, rangeComplete, rangeTotal, framerate=30):
|
||||
|
||||
self.bobberTimer = self.bobberTimer + 1
|
||||
|
||||
rangeComplete = int("%.0f" % (rangeComplete * self.barFillWidth / rangeTotal))
|
||||
|
||||
self.WINDOW.window.blit(self.barImages["left"], (self.x, self.y))
|
||||
self.WINDOW.window.blit(self.barImages["right"], (self.x + self.widthLeft + self.barFillWidth, self.y))
|
||||
|
||||
for i in range(0, rangeComplete):
|
||||
self.WINDOW.window.blit(self.barImages["fill"], (self.x + self.widthLeft + i, self.y + self.barCenterOffset))
|
||||
|
||||
for i in range(rangeComplete, self.barFillWidth):
|
||||
self.WINDOW.window.blit(self.barImages["clear"], (self.x + self.widthLeft + i, self.y + self.barCenterOffset))
|
||||
|
||||
if (self.bobberTimer / framerate) > 0.25:
|
||||
self.bobberTimer = 0
|
||||
if self.bobberState == self.bobberStateRange - 1:
|
||||
self.bobberState = 0
|
||||
else:
|
||||
self.bobberState = self.bobberState + 1
|
||||
|
||||
self.WINDOW.window.blit(self.bobberImages[self.bobberState], (self.x + rangeComplete, self.y - (self.bobberHeight / 2)))
|
||||
|
||||
class Checkbox():
|
||||
"""
|
||||
Creates a Checkbox on a window.
|
||||
"""
|
||||
|
||||
def __init__(self, game, name, x, y, image_neutral, image_hover, image_active, condition, function=None, args=None):
|
||||
self.TYPE = "checkbox"
|
||||
|
||||
width = image_neutral.get_width() # Can use neutral image as all images should have identical sizes.
|
||||
height = image_neutral.get_height()
|
||||
|
||||
self.GAME = game
|
||||
self.WINDOW = self.GAME.WINDOW
|
||||
scale = self.GAME.SCALE.scaleUi
|
||||
|
||||
self.function = function
|
||||
self.functionArgs = args
|
||||
|
||||
self.ID = name
|
||||
|
||||
self.IMAGES = {
|
||||
"neutral": pygame.transform.scale(image_neutral, (width * scale, height * scale)),
|
||||
"hover": pygame.transform.scale(image_hover, (width * scale, height * scale)),
|
||||
"active": pygame.transform.scale(image_active, (width * scale, height * scale))
|
||||
}
|
||||
|
||||
Interface_Functions.convert_images(self)
|
||||
|
||||
self.rect = self.image_neutral.get_rect()
|
||||
self.rect.topleft = (x * scale, y * scale)
|
||||
|
||||
self.time_delay = 0
|
||||
|
||||
self.condition = condition
|
||||
|
||||
self.GAME.gameInteractables.append(self) # Add to checkbox to refresh.
|
||||
|
||||
def draw(self):
|
||||
"""
|
||||
Draws checkbox on screen.
|
||||
"""
|
||||
|
||||
Interface_Functions.draw(self)
|
||||
|
||||
def is_hovered(self):
|
||||
"""
|
||||
Checks if checkbox is hovered.
|
||||
"""
|
||||
|
||||
return Interface_Functions.is_hovered(self)
|
||||
|
||||
def remove(self):
|
||||
"""
|
||||
Clears checkbox from screen.
|
||||
"""
|
||||
|
||||
Interface_Functions.destroy(self)
|
||||
|
||||
|
||||
class Interface_Functions():
|
||||
"""
|
||||
All functions called by interface objects.
|
||||
"""
|
||||
|
||||
def __init__(self, game):
|
||||
self.GAME = game
|
||||
|
||||
def convert_images(object):
|
||||
"""
|
||||
Converts the object's images to pygame format increasing performance.
|
||||
"""
|
||||
|
||||
temp = {}
|
||||
|
||||
for image in object.IMAGES.items():
|
||||
temp[image[0]] = image[1].convert_alpha()
|
||||
|
||||
object.IMAGES = temp
|
||||
|
||||
def destroy(object):
|
||||
"""
|
||||
Destroys the interface object.
|
||||
"""
|
||||
|
||||
temp = []
|
||||
|
||||
for interactable in object.GAME.gameInteractables:
|
||||
if interactable != object:
|
||||
temp.append(interactable)
|
||||
|
||||
object.GAME.gameInteractables = temp
|
||||
|
||||
del object
|
||||
|
||||
def draw(object):
|
||||
"""
|
||||
Draws interface object.
|
||||
"""
|
||||
|
||||
if object.TYPE == "checkbox" and object.condition():
|
||||
object.WINDOW.window.blit(object.IMAGES["active"], (object.rect.x, object.rect.y))
|
||||
elif object.is_hovered():
|
||||
object.WINDOW.window.blit(object.IMAGES["hover"], (object.rect.x, object.rect.y))
|
||||
else:
|
||||
object.WINDOW.window.blit(object.IMAGES["neutral"], (object.rect.x, object.rect.y))
|
||||
|
||||
def enter_fullscreen(self):
|
||||
"""
|
||||
Enters Fullscreen if possible.
|
||||
"""
|
||||
|
||||
if self.GAME.WINDOW.toggle_fullscreen():
|
||||
FEATURES["Fullscreen"]["is_active"] = True
|
||||
|
||||
def exit_to_desktop(self):
|
||||
|
||||
self.GAME.levelOn = False
|
||||
self.GAME.menuOn = False
|
||||
self.GAME.sceneOn = False
|
||||
self.GAME.gameOn = False
|
||||
|
||||
def collidepoint(object, coords:tuple):
|
||||
"""
|
||||
Rewritten version of pygame rect.collidepoint.
|
||||
"""
|
||||
|
||||
x, y, width, height = object.rect
|
||||
dx = width + x
|
||||
dy = height + y
|
||||
|
||||
|
||||
if coords[0] in range(x, dx + 1) and coords[1] in range(y, dy + 1):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def is_hovered(object):
|
||||
"""
|
||||
Checks if mouse is hovering interface object.
|
||||
"""
|
||||
|
||||
return Interface_Functions.collidepoint(object, pygame.mouse.get_pos())
|
||||
|
||||
def return_to_game(self):
|
||||
"""
|
||||
Exits a pause state.
|
||||
"""
|
||||
|
||||
for button in self.GAME.LEVEL.layout.INTERACTABLES:
|
||||
button.remove()
|
||||
|
||||
self.GAME.menuOn = False
|
||||
|
||||
self.GAME.LEVEL.load_level_state()
|
||||
Reference in New Issue
Block a user