import math as maths import logging import pygame import gameUtils import NoPELib import numpy as np def rotateRad(surface: pygame.Surface, radians: float) -> pygame.Surface: """ Rotates a surface clockwise in radians. """ # Calculate the degrees deg = radians*(180/maths.pi) # Convert to CCW becaus for some reason that's what Pygame uses? deg *= -1 # Rotate the surface return pygame.transform.rotate(surface, deg) class Game(gameUtils.Game): def __init__(self, *args, **kwargs): """ Ran when the game starts. You have access to the following variables: self.surf (pygame.Surface): This is the surface you draw onto. self.pm (NoPELib.PlayerManager): This is where your players are stored. self.cfg (dict): Everything from the `game.toml` file. You can access it like this: self.details['title'] """ # Don't remove this. It does important things. :3 super().__init__(*args, **kwargs) self.wheelSurf = pygame.Surface([min(self.size)]*2) # Don't ask. font = pygame.font.SysFont('', 32) items = [f'Example item {i+1}' for i in range(17)] # Calculate circle radius circleR = self.wheelSurf.size[0] / 2 # Draw the base circle pygame.draw.circle(self.wheelSurf, (25, 25, 25), (circleR, circleR), circleR) # Calculate the gap, in radians, between each item gap = maths.pi * 2 / len(items) for idx, item in enumerate(items): # Calculate the radians of this item rad = (idx / len(items)) * maths.pi * 2 # Calculate the vector from that vector = maths.cos(rad), maths.sin(rad) # Calculate the end position of a line based on the vector endPos = np.add(np.multiply(vector, circleR), circleR) # Draw the dividing line pygame.draw.line(self.wheelSurf, (128, 128, 128), (circleR, circleR), endPos) # Create a surface that our text will be rendered onto textSurf = pygame.Surface(self.wheelSurf.size, pygame.SRCALPHA) # Render the item text text = font.render(item, True, (255, 255, 255)) # 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)) # Draw debug lines #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, (0, 255, 0), (circleR, circleR), (circleR, textSurf.size[1])) # Rotate the text surface textSurf = rotateRad(textSurf, rad+gap/2) # Blit the text surface to the wheel surface self.wheelSurf.blit(gameUtils.centre(textSurf, self.wheelSurf.size), (0, 0)) def onEvent(self, event): """ Ran when an event is fired. Args: event (pygame.Event): The event that was fired. """ pass def update(self): """ Ran once per frame, put your drawing code and any game logic that should be ran once per frame in here. """ self.surf.blit(gameUtils.centre(self.wheelSurf, self.size), (0, 0)) def close(self): """ Ran when the game closes. """ pass