Compare commits

..

4 Commits

Author SHA1 Message Date
b2cc7a996f Did the "LEGO Island fix" 2025-06-26 07:29:31 +01:00
b0c752f946 Added TODOs 2025-06-26 07:22:09 +01:00
71693518a8 Added text margins 2025-06-26 07:21:57 +01:00
a8814fdfe1 Added basic spin animation 2025-06-26 07:21:41 +01:00

74
game.py
View File

@ -1,21 +1,50 @@
import math as maths import math as maths
import logging import logging
import pygame import random
import time
import gameUtils import gameUtils
import NoPELib import NoPELib
import numpy as np import numpy as np
import pygame
# TODO: Add the ability to re-draw the wheel to hightlight the selected item
# TODO: Prevent another animation from starting when the wheel's spinning
# TODO: Convery fade in / out time to be random
# TODO: Make random finer (to prevent a range of 4-5 only having two possible speeds)
def translate(value, aMin, aMax, bMin, bMax):
"""
Translates `value` to go from `aMin`-`aMax` to `bMin`-`bMax`
Stolen from StackOverflow because we don't have time to do shit
properly here.
"""
aRange = (aMax - aMin)
bRange = (bMax - bMin)
return (((value - aMin) * bRange) / aRange) + bMin
def rotateRad(surface: pygame.Surface, radians: float) -> pygame.Surface: def rotateRad(surface: pygame.Surface, radians: float) -> pygame.Surface:
""" """
Rotates a surface clockwise in radians. Rotates a surface clockwise in radians and re-centres it.
""" """
# Calculate the degrees # Calculate the degrees
deg = radians*(180/maths.pi) deg = radians*(180/maths.pi)
# Rotate the surface re-centre
return rotateDeg(surface, deg)
def rotateDeg(surface: pygame.Surface, degrees: float) -> pygame.Surface:
"""
Rotates a surface clockwise in degrees and re-centres it.
"""
# Convert to CCW becaus for some reason that's what Pygame uses? # Convert to CCW becaus for some reason that's what Pygame uses?
deg *= -1 degrees *= -1
# Rotate the surface # Rotate surface which will expand it
return pygame.transform.rotate(surface, deg) rotSurface = pygame.transform.rotate(surface, degrees)
# re-centre it to the orinal surface bounding box
rotSurface = gameUtils.centre(rotSurface, surface.size)
return rotSurface
class Game(gameUtils.Game): class Game(gameUtils.Game):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
@ -32,10 +61,24 @@ class Game(gameUtils.Game):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.wheelSurf = pygame.Surface([min(self.size)]*2) # Don't ask. self.wheelSurf = pygame.Surface([min(self.size)]*2) # Don't ask.
self.wheelRotation = 0
# How long (in seconds) it takes for the wheel to get to full speed
self.WHEEL_SPIN_FADE_IN = 0.25
# How long (in seconds) it takes for the wheel to go back to stationary
self.WHEEL_SPIN_FADE_OUT = 2.5
# The minimum and maximum speeds of the wheel
self.WHEEL_SPEED_RANGE = [360, 550]
# Holds the decided speed of the wheel
self.wheelSpinSpeed = 0
# When the wheel started its spin animation
self.wheelAnimStart = 0
font = pygame.font.SysFont('', 32) font = pygame.font.SysFont('', 32)
items = [f'Example item {i+1}' for i in range(17)] items = [f'Example item {i+1}' for i in range(17)]
# How many pixels away from the outer side of the
# circle the text should be
textMargin = 5
# Calculate circle radius # Calculate circle radius
circleR = self.wheelSurf.size[0] / 2 circleR = self.wheelSurf.size[0] / 2
@ -59,7 +102,7 @@ class Game(gameUtils.Game):
# Render the item text # Render the item text
text = font.render(item, True, (255, 255, 255)) text = font.render(item, True, (255, 255, 255))
# Draw the item text onto the text surface, centred to the right # Draw the item text onto the text surface, centred to the right
textSurf.blit(text, (textSurf.size[0]-text.get_width(), self.size[1]//2 - text.get_height()//2)) textSurf.blit(text, (textSurf.size[0]-text.get_width()-textMargin, self.size[1]//2 - text.get_height()//2))
# Draw debug lines # Draw debug lines
#pygame.draw.rect(textSurf, (0, 128, 255), (0, 0, textSurf.size[0], textSurf.size[1]), 1) #pygame.draw.rect(textSurf, (0, 128, 255), (0, 0, textSurf.size[0], textSurf.size[1]), 1)
#pygame.draw.line(textSurf, (255, 0, 0), (circleR, circleR), (textSurf.size[0], circleR)) #pygame.draw.line(textSurf, (255, 0, 0), (circleR, circleR), (textSurf.size[0], circleR))
@ -67,7 +110,7 @@ class Game(gameUtils.Game):
# Rotate the text surface # Rotate the text surface
textSurf = rotateRad(textSurf, rad+gap/2) textSurf = rotateRad(textSurf, rad+gap/2)
# Blit the text surface to the wheel surface # Blit the text surface to the wheel surface
self.wheelSurf.blit(gameUtils.centre(textSurf, self.wheelSurf.size), (0, 0)) self.wheelSurf.blit(textSurf, (0, 0))
def onEvent(self, event): def onEvent(self, event):
@ -77,14 +120,27 @@ class Game(gameUtils.Game):
Args: Args:
event (pygame.Event): The event that was fired. event (pygame.Event): The event that was fired.
""" """
pass if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
self.wheelSpinSpeed = random.randint(*self.WHEEL_SPEED_RANGE)
self.wheelAnimStart = time.perf_counter()
def update(self): def update(self):
""" """
Ran once per frame, put your drawing code and any Ran once per frame, put your drawing code and any
game logic that should be ran once per frame in here. game logic that should be ran once per frame in here.
""" """
self.surf.blit(gameUtils.centre(self.wheelSurf, self.size), (0, 0)) self.surf.blit(rotateDeg(gameUtils.centre(self.wheelSurf, self.size), self.wheelRotation), (0, 0))
animTime = time.perf_counter() - self.wheelAnimStart
if animTime < self.WHEEL_SPIN_FADE_IN + self.WHEEL_SPIN_FADE_OUT:
if animTime < self.WHEEL_SPIN_FADE_IN:
speed = translate(animTime, 0, self.WHEEL_SPIN_FADE_IN, 0, self.wheelSpinSpeed)
else:
speed = translate(animTime, self.WHEEL_SPIN_FADE_IN, self.WHEEL_SPIN_FADE_IN+self.WHEEL_SPIN_FADE_OUT, self.wheelSpinSpeed, 0)
self.wheelRotation += speed * self.timeDelta
self.wheelRotation %= 360
print(self.wheelRotation)
def close(self): def close(self):
""" """