From 06ed8a8dde3c4e007b7664209170d6062eb5e600 Mon Sep 17 00:00:00 2001 From: Brosef Date: Mon, 16 Jun 2025 19:30:43 +0100 Subject: [PATCH] Transitioned to "base game" "engine" --- __init__.py | 105 ++++++++++++++++++++++++++++++++++++++++++++++ __main__.py | 119 +++++++++++++++++++--------------------------------- game.toml | 7 ++++ 3 files changed, 156 insertions(+), 75 deletions(-) create mode 100644 __init__.py create mode 100644 game.toml diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..7dfb883 --- /dev/null +++ b/__init__.py @@ -0,0 +1,105 @@ +import logging +import pygame +from random import randint +#import NoPELib +#import PDOLib + +class Game: + def __init__(self, surface, size): + """ + Ran when the game starts. + + Args: + surface (pygame.Surface): The surface you draw to. + size (list[int, int]): The size of the surface. + """ + + pygame.init() + self.surface = surface + self.size = size + self.clock = pygame.time.Clock() + #Sounds for the gun :3 + self.playSound = pygame.mixer.Sound.play + self.gunBlank = pygame.mixer.Sound("sfx/gun-blank.mp3") + self.gunShot = pygame.mixer.Sound("sfx/gun-shot.mp3") + self.gunSpin = pygame.mixer.Sound("sfx/gun-spin.mp3") + + self.gun = pygame.image.load_animation("gun.webp") + self.gunFlash = pygame.image.load("images/muzzleflash.png") + + self.shockScale = 0 #controls shock level sent to PDO (on a scale of 0 to 1) + #gun varialbes + self.startSpin = False + self.spinning = False + self.spinInc = 0 + + def fire(self):#LETS GO GAMBLING + if randint(1,6) == 6: + self.playSound(self.gunShot) + return 0.04 + #remember to add shock + else: + self.playSound(self.gunBlank) + return 0 + + def onEvent(self, event): + """ + Ran when an event is fired. + + Args: + event (pygame.Event): The event that was fired + """ + + if event.type == pygame.KEYDOWN: + if event.key == pygame.K_1: + self.playSound(self.gunBlank) + elif event.key == pygame.K_2: + self.playSound(self.gunShot) + elif event.key == pygame.K_3: + self.playSound(self.gunSpin) + elif event.key == pygame.K_SPACE: + self.startSpin = True + + def draw(self): + """ + Ran once per frame, put your drawing code in here + """ + + #gun code WOO + if self.startSpin == True or self.spinning == True:#check if space was pressed or if the gun is already spinning + self.spinning = True #keep the gun spinning + if self.spinInc == 0: + self.playSound(self.gunSpin) + self.spinInc += 1 #next gun frame + if self.spinInc == len(self.gun): #if we've reached the end + self.spinInc = 0 #reset frame count + self.spinning = False #stop spinning + self.startSpin = False #what did i say bitch? stop spinning + self.shockScale += self.fire() #check if the user gets shot + if self.shockScale > 1: self.shockScale=1 #keeps shockScale in bounds + + #screen code + self.surface.fill("black") + self.surface.blit(self.gun[self.spinInc][0],(0,0))#draw the gun + #screen.blit(pygame.transform.scale_by(MainSurface,1),(0,yOffset))#renders the main surface to the screen, while also scaling it for the required display resolution + + # TODO: + # I've removed the whole "main surface" thing for now, + # because I'm not sure how we're going to deal with it + # from now on right now. I'll fix this later when it's + # a bit clearer on how NoPE-Lib will draw the players + # and how the base game should draw that. + # - Brosef + + # TODO: + # Actually scale the gun with self.size, and centre it + + pygame.display.flip() + + self.clock.tick(60) + + def close(self): + """ + Ran when the game closes + """ + pass diff --git a/__main__.py b/__main__.py index 422630d..b98f690 100644 --- a/__main__.py +++ b/__main__.py @@ -1,89 +1,58 @@ +# Import the game code +import __init__ + +import argparse +import tomllib +import pathlib import pygame -from random import randint +import os -#Oh god here we go. I'm gonna screw up this entire thing - -screenw = 730 -screenh = 1080 -yOffset = 0 +# Store the current working directory +# This is used to revert the cd change +originalCWD = os.getcwd() -pygame.init() +# Get the path of the game +basePath = pathlib.Path(__file__).parent.resolve() -gun = pygame.image.load_animation("gun.webp") -GunFlash = pygame.image.load("images/muzzleflash.png") +# Set the current working directory +# to the base path of the game +os.chdir(basePath) -# TODO: Add a random delay between the spin and fire +# Load the game.toml data +with open('game.toml', 'r') as f: + gameData = tomllib.loads(f.read()) -# TODO: Utiles the following new sounds: -# gun-load: Should be played at the beginning of the game, -# and should have an animation accompanying it. -# see Brosef for the animation. -# gun-cylinder-stop: Plays directly after the load -# animation is complete. -# gun-spin/blank/shot are all used in their original ways. +# Parse command line arguments +parser = argparse.ArgumentParser(prog=gameData['name']) +parser.add_argument('-sw', '--width', type=int, default=1280) +parser.add_argument('-sh', '--height', type=int, default=720) +parser.add_argument('-f', '--fullscreen', action='store_true') +args = parser.parse_args() -#Sounds for the gun :3 -PlaySound = pygame.mixer.Sound.play -GunBlank = pygame.mixer.Sound("sfx/gun-blank.mp3") -GunShot = pygame.mixer.Sound("sfx/gun-shot.mp3") -GunSpin = pygame.mixer.Sound("sfx/gun-spin.mp3") +# Initialise screen +flags = 0 +if args.fullscreen: flags |= pygame.FULLSCREEN +screen = pygame.display.set_mode((args.width, args.height), flags) +pygame.display.set_caption(gameData['name']) -screen = pygame.display.set_mode((screenw,screenh)) -MainSurface = pygame.Surface((screenw,screenh-yOffset)) -pygame.display.set_caption("Russian Roulette") -clock = pygame.time.Clock() +# Initialise game +game = __init__.Game(screen, screen.size) -running = True #you better start running... -shockScale = 0 #controls shock level sent to PDO (on a scale of 0 to 1) +# Set to False when the game should exit +run = True -#gun variables -startSpin = False -spinning = False -spinInc = 0 - -def fire(shockScale):#LETS GO GAMBLING - if randint(1,6) == 6: - PlaySound(GunShot) - return 0.04 - #remember to add shock - else: - PlaySound(GunBlank) - return 0 - -while running: +while run: + # Event loop for event in pygame.event.get(): if event.type == pygame.QUIT: - running = False - elif event.type == pygame.KEYDOWN: - if event.key == pygame.K_1: - PlaySound(GunBlank) - elif event.key == pygame.K_2: - PlaySound(GunShot) - elif event.key == pygame.K_3: - PlaySound(GunSpin) - elif event.key == pygame.K_SPACE: - startSpin = True - - #gun code WOO - if startSpin == True or spinning == True:#check if space was pressed or if the gun is already spinning - spinning = True #keep the gun spinning - if spinInc == 0: - PlaySound(GunSpin) - spinInc += 1 #next gun frame - if spinInc == len(gun): #if we've reached the end - spinInc = 0 #reset frame count - spinning = False #stop spinning - startSpin = False #what did i say bitch? stop spinning - shockScale += fire(shockScale) #check if the user gets shot - if shockScale > 1: shockScale=1 #keeps shockScale in bounds - - #screen code - screen.fill("black") - MainSurface.blit(gun[spinInc][0],(0,0))#draw the gun - screen.blit(pygame.transform.scale_by(MainSurface,1),(0,yOffset))#renders the main surface to the screen, while also scaling it for the required display resolution - - pygame.display.flip() - - clock.tick(60) + run = False + + game.onEvent(event) + + # Draw loop + game.draw() +# Clean up +os.chdir(originalCWD) +game.close() pygame.quit() \ No newline at end of file diff --git a/game.toml b/game.toml new file mode 100644 index 0000000..4110132 --- /dev/null +++ b/game.toml @@ -0,0 +1,7 @@ +# The ID used for logging +id = "russianRoulette" +# The name used for setting the windows +# title, and for displaying in the launcher +name = "Russian Roulette" +# The description displayed by the launcher +description = ":3"