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.

75
game.py
View File

@ -1,10 +1,17 @@
import logging
import pygame
from random import randint
import random
import gameUtils
import NoPELib
#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):
def __init__(self, *args, **kwargs):
"""
@ -18,18 +25,16 @@ class Game(gameUtils.Game):
# Don't remove this. It does important things. :3
super().__init__(*args, **kwargs)
# TODO: Utilise self.pm (the player manager)
# TODO: Add background music
# TODO: Add muzzle flash
# TODO: Add animations for blank firing and real firing
self.em = NoPELib.ExpansionsManager(self.pm, includeExpansions=['ShockColar1'])
# TODO: Utilise 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.
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
self.playSound = pygame.mixer.Sound.play
@ -39,11 +44,18 @@ class Game(gameUtils.Game):
self.gunLoad = pygame.mixer.Sound("./assets/gun-load.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.gunFlash = pygame.image.load("./assets/muzzleflash.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('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)
@ -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.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
if randint(1,6) == 6:
if random.randint(1,6) == 6:
self.playSound(self.gunShot)
self.turnHandler.playing[0].punish(self.shockScale)
self.turnHandler.next()
self.gun.playAnim('fire')
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
#remember to add shock
else:
self.playSound(self.gunBlank)
self.gun.playAnim('blank')
return 0
def onEvent(self, event):
@ -94,10 +139,12 @@ class Game(gameUtils.Game):
self.playSound(self.gunSpin)
elif event.type == gameUtils.AnimFinish:
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)
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 = min(self.shockScale, 1) #keeps shockScale in bounds
@ -107,12 +154,10 @@ class Game(gameUtils.Game):
game logic that should be ran once per frame in here.
"""
# Don't remove this. It does important things. :3
super().update()
#screen code
self.surf.fill("black")
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):
"""