Compare commits

..

20 Commits

Author SHA1 Message Date
1bd3ebe2f6 Added name in corner 2025-07-16 15:21:37 +01:00
bd3a986699 Added expansion manager implementation 2025-07-16 12:08:22 +01:00
ceca244290 Improved gun fire animation 2025-07-05 00:46:26 +01:00
72f1891c87 Changed nextPlayer() call to happen after new animations 2025-06-25 12:29:46 +01:00
4dc7d0dda5 Updated fire animation & re-enabled looping for better previews 2025-06-25 12:27:41 +01:00
e5b8316409 Removed TODO 2025-06-25 12:19:37 +01:00
45123c39b6 Implemented extra animations 2025-06-25 12:15:55 +01:00
e932c88cc3 Added / modified (maybe) gun animations 2025-06-25 12:12:29 +01:00
5a62ca10d0 Moved away from deprecated gameUtils.RoundTable() 2025-06-25 08:01:50 +01:00
ccf08724ab Switched from importing randint to importing random 2025-06-25 08:00:32 +01:00
2deb001322 Removed comments
Muzzle flash will be done in animation,
BG music was done in commit a6a64cdf69
2025-06-24 14:46:44 +01:00
c155e11d87 Added motivational comment 2025-06-24 14:45:16 +01:00
0a2305f4cc Added basic popup code 2025-06-24 14:36:57 +01:00
2e59e718e6 Added timeout ID check 2025-06-24 10:16:13 +01:00
647d230fe0 Removed important line
FOR I CAN SEE THE FUTURE, THAT BASTARD WILL PUSH AN UPDATE THAT REMOVES THE NEED FOR THIS (I've lost it, team)
2025-06-24 10:02:44 +01:00
f258cf8982 Updated TODO because I forgot how Russian Roulette works 2025-06-24 05:54:46 +00:00
39045c3882 Oh my god I'm stupid, fixed game not launching 2025-06-23 20:19:32 +01:00
a6a64cdf69 Added background music, background music is currently randomly selected between 2 audio files on startup 2025-06-23 20:16:43 +01:00
7b0338c092 Added more example turn code 2025-06-23 14:45:56 +01:00
7628c59b36 Added TODO 2025-06-23 14:45:43 +01:00
6 changed files with 61 additions and 16 deletions

BIN
assets/gun-blank.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 KiB

BIN
assets/gun-fire.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 MiB

After

Width:  |  Height:  |  Size: 259 KiB

BIN
assets/surrounded.ogg Normal file

Binary file not shown.

BIN
assets/twiceoritsluck.ogg Normal file

Binary file not shown.

77
game.py
View File

@ -1,10 +1,17 @@
import logging import logging
import pygame import pygame
from random import randint import random
import gameUtils import gameUtils
import NoPELib
#Oh god here we go. I'm gonna screw up this entire thing #Oh god here we go. I'm gonna screw up this entire thing
def transform(value, minA, maxA, minB, maxB):
"""
Translates `value` from `minA`-`maxA` to `minB`-`maxB`.
"""
return ((value - minA) / (maxA - minA)) * (maxB - minB) + minB
class Game(gameUtils.Game): class Game(gameUtils.Game):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
""" """
@ -18,18 +25,16 @@ class Game(gameUtils.Game):
# Don't remove this. It does important things. :3 # Don't remove this. It does important things. :3
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.em = NoPELib.ExpansionsManager(self.pm, includeExpansions=['ShockColar1'])
# TODO: Utilise self.pm (the player manager)
# TODO: Add background music
# TODO: Add muzzle flash
# TODO: Add animations for blank firing and real firing
# TODO: Utilise the following new sounds: # TODO: Utilise the following new sounds:
# gun-load: Should be played at the beginning of the game, # gun-load: Should be played at the beginning of the game,
# and should have an animation accompanying it. # and should have an animation accompanying it.
# see Brosef for the animation. # see Brosef for the animation.
self.turnHandler = gameUtils.RoundTable(1, self.pm) # TODO: Add a hook to see if the current player has become inactive.
playerName = random.choice(list(self.pm.keys()))
self.currentlyPlaying = self.pm[playerName]
#Sounds for the gun :3 #Sounds for the gun :3
self.playSound = pygame.mixer.Sound.play self.playSound = pygame.mixer.Sound.play
@ -38,12 +43,19 @@ class Game(gameUtils.Game):
self.gunSpin = pygame.mixer.Sound("./assets/gun-spin.mp3") self.gunSpin = pygame.mixer.Sound("./assets/gun-spin.mp3")
self.gunLoad = pygame.mixer.Sound("./assets/gun-load.mp3") self.gunLoad = pygame.mixer.Sound("./assets/gun-load.mp3")
self.gunCyclinderStop = pygame.mixer.Sound("./assets/gun-cylinder-stop.mp3") self.gunCyclinderStop = pygame.mixer.Sound("./assets/gun-cylinder-stop.mp3")
#Background Music commands
self.unloadMusic = pygame.mixer.music.unload
self.stopMusic = pygame.mixer.music.stop
self.playMusic = pygame.mixer.music.play
#self.gun = pygame.load_animation('./assets/gun-spin.webp') #self.gun = pygame.load_animation('./assets/gun-spin.webp')
self.gunFlash = pygame.image.load("./assets/muzzleflash.png") self.gunFlash = pygame.image.load("./assets/muzzleflash.png")
self.gun = self.createAnimObj('gun', './assets/gun-base.png') self.gun = self.createAnimObj('gun', './assets/gun-base.png')
self.gun.addAnimation(gameUtils.AnimationHandler('spin', './assets/gun-spin.webp', 60)) self.gun.addAnimation(gameUtils.AnimationHandler('spin', './assets/gun-spin.webp', 60))
self.gun.addAnimation(gameUtils.AnimationHandler('blank', './assets/gun-blank.webp', 60))
self.gun.addAnimation(gameUtils.AnimationHandler('fire', './assets/gun-fire.webp', 60))
self.shockScale = 0 #controls shock level sent to PDO (on a scale of 0 to 1) self.shockScale = 0 #controls shock level sent to PDO (on a scale of 0 to 1)
@ -61,15 +73,48 @@ class Game(gameUtils.Game):
self.gunScale = min(self.size[1]/self.gunh,self.size[0]/self.gunw) #calculates how to scale the gun so that it stays on the screen self.gunScale = min(self.size[1]/self.gunh,self.size[0]/self.gunw) #calculates how to scale the gun so that it stays on the screen
self.font = pygame.font.SysFont('', 64)
#Selects random music to play at the start of the game, might change because I just threw this together.
#I feel horrible writing this code this feels super unoptimised :c
# Bro I'm gonna be honest, there's not much I'd change about that, you're good.
# The only thing I can think if just moving `set_volume()` to after both if statements.
self.musicNumber = random.randint(1,2)
if self.musicNumber == 1:
pygame.mixer.music.load("./assets/surrounded.ogg")
self.playMusic(-1)
pygame.mixer.music.set_volume(0.5)
if self.musicNumber == 2:
pygame.mixer.music.load("./assets/twiceoritsluck.ogg")
self.playMusic(-1)
pygame.mixer.music.set_volume(0.5)
def nextPlayer(self):
playerIndex = list(self.pm.keys()).index(self.currentlyPlaying.name)
playerIndex += 1
if playerIndex >= len(self.pm):
playerIndex = 0
playerName = list(self.pm.keys())[playerIndex]
self.currentlyPlaying = self.pm[playerName]
self.popup('Next player', f'Pass shocker to {self.currentlyPlaying.name},\nthen press R-CTRL+ENTER to continue.')
def fire(self):#LETS GO GAMBLING def fire(self):#LETS GO GAMBLING
if randint(1,6) == 6: if random.randint(1,6) == 6:
self.playSound(self.gunShot) self.playSound(self.gunShot)
self.turnHandler.playing[0].punish(self.shockScale) self.gun.playAnim('fire')
self.turnHandler.next() expansionIDs = self.em.lookupPlayer(self.currentlyPlaying.name)
shocker = self.em[expansionIDs[0]]
iMin, iMax = self.currentlyPlaying.expansions['ShockCollar1']['shcokRange']
v = round(transform(self.shockScale, 0, 1, iMin, iMax))
print(f'Shocking {self.currentlyPlaying.name} with intensity {v}')
shocker.step((False, 0.5, v))
print(f'{self.currentlyPlaying.name} is fucking dead.')
return 0.04 return 0.04
#remember to add shock #remember to add shock
else: else:
self.playSound(self.gunBlank) self.playSound(self.gunBlank)
self.gun.playAnim('blank')
return 0 return 0
def onEvent(self, event): def onEvent(self, event):
@ -94,10 +139,12 @@ class Game(gameUtils.Game):
self.playSound(self.gunSpin) self.playSound(self.gunSpin)
elif event.type == gameUtils.AnimFinish: elif event.type == gameUtils.AnimFinish:
if event.objectID == self.gun.objectID and event.animationID == 'spin': if event.objectID == self.gun.objectID and event.animationID == 'spin':
self.timeout("FireDelay",randint(750,2000)/1000) self.timeout("FireDelay",random.randint(750,2000)/1000)
self.playSound(self.gunCyclinderStop) self.playSound(self.gunCyclinderStop)
elif event.objectID == self.gun.objectID and event.animationID in ['blank', 'fire']:
self.nextPlayer()
elif event.type == gameUtils.Timeout: elif event.type == gameUtils.Timeout and event.timeoutID == 'FireDelay':
self.shockScale += self.fire() #check if the user gets shot self.shockScale += self.fire() #check if the user gets shot
self.shockScale = min(self.shockScale, 1) #keeps shockScale in bounds self.shockScale = min(self.shockScale, 1) #keeps shockScale in bounds
@ -106,13 +153,11 @@ class Game(gameUtils.Game):
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.
""" """
# Don't remove this. It does important things. :3
super().update()
#screen code #screen code
self.surf.fill("black") self.surf.fill("black")
self.surf.blit(gameUtils.centre(pygame.transform.scale_by(self.gun.getFrame(), self.gunScale), self.size)) self.surf.blit(gameUtils.centre(pygame.transform.scale_by(self.gun.getFrame(), self.gunScale), self.size))
self.surf.blit(self.font.render(f'Current player: {self.currentlyPlaying.name}', True, (255, 255, 255)), (0, 0))
def close(self): def close(self):
""" """