Das ist der Jeopardy-Clone, den ich in Anlehnung an das 36C3-Event geschrieben habe. Wer immer Lust hat, darf und soll Fragen beisteuern
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

463 lines
15 KiB

#!/usr/bin/env python3
# -.-coding=UTF8 -.-
#
# A more or less rewrite of the original pygame version
# by james Turk in 2007
#
# Greetings
#
# kresse 2020
import sys
import os
import pygame
from pygame.locals import *
import pygame_input as pgi
# Constants
# COLORS
BLACK = (0,0,0)
WHITE = (255,255,255)
RED = (255,0,0)
YELLOW= (255,255,0)
GREEN = (0,255,0)
BLUE = (0,0,200)
LITE_BLUE =(100,100,220)
# Dimension of the display Window
#
# SOLLTE BESSER ABGEFRAGT WERDEN
#
x_dim =1200
y_dim =768
#
# Dimension of the display Window
x_dim =1920
y_dim =1080
# Folder for sound effects
sfx = "assets//sfx//"
graphics = "assets//graphics//"
# globales
spieler = []
JOYSTICKS = []
spieler_anzahl = 4
_image_library = {}
modus = "aussuchen"
# titelmusik
musik = True
# Graphics import
# https://www.raspberry-pi-geek.de/ausgaben/rpg/2014/04/grafikausgaben-mit-python-und-pygame/2/
def get_image(path):
#
global _image_library
image = _image_library.get(path)
if image == None:
canonicalized_path = path.replace('/', os.sep).replace('\\', os.sep)
image = pygame.image.load(canonicalized_path)
_image_library[path] = image
return image
class Frage:
def __init__(self,kategorie,punkte,frage,antwort):
self.frage = frage
self.antwort = antwort
self.kategorie = kategorie
self.punkte = punkte
self.farbe = BLUE
class Fragen:
def __init__(self,paketordner):
#print ("Fragen wird aufgerufen")
self.fragenfeld = []
self.anzahl_fragen = 0
self.paketordner = paketordner
f = open(paketordner+"//"+"fragen.jeopardy")
lines = f.readlines()
for line in lines:
data = line.strip().split(':')
self.frageHinzufuegen(*data)
def frageHinzufuegen(self, kategorie, punkte, q, a):
self.fragenfeld.append (Frage(kategorie,punkte ,q,a))
self.anzahl_fragen += 1
#print(self.anzahl_fragen)
# ist 30 nach (0-29)
class Spieler():
def __init__(self,name="SPIELER",nummer=0):
Farbliste = (RED, YELLOW, GREEN, LITE_BLUE)
#
self.name = name
self.punkte = 0
self.nr = nummer % spieler_anzahl
self.color = Farbliste[self.nr]
def buzz():
pygame.mixer.Sound(sfx+'game-fx-1.wav').play()
def percent_tile(x1, y1, x2, y2):
return pygame.Rect( int(x_dim*x1/100), int(y_dim*y1/100), int(x_dim*x2/100), int(y_dim*y2/100) )
def main():
# ich bin echt genervt, das das hier so definiert werden muss,
# während Farben usw einfach global sind
global musik
global fragen
global background
def textCentered( str, skiperoo=-75):
#
# Rekursive Funktion zur Beschriftung
#
choperoo = len(str)
font = smallFont
# fill background
#screen.blit(background, (0, 0))
# draw string and see if it is too long
text = font.render(str, 1, WHITE)
# if string is too long, choperoo!
while text.get_rect().width > screen.get_rect().width:
for c in range(int(choperoo/2) , int(choperoo)):
if str[c] == ' ':
choperoo = c
break
# redraw string
text = font.render(str[:choperoo], 1, WHITE)
# find the centered rect for the drawing
cr = text.get_rect()
cr.center = screen.get_rect().center
cr.y += skiperoo
# draw
screen.blit(text, cr)
if choperoo != len(str):
textCentered(str[choperoo:], skiperoo+cr.height)
def wandAnzeigen(screen):
global fragen
BG_COLOR = BLUE
FG_COLOR = WHITE
GRID_COLOR = LITE_BLUE
wall_font_name = fontFile
big_font_size = 90
small_font_size = 48
screen.blit(background, (0, 0))
if modus =="aussuchen":
xStart, xEnd = 0, int(x_dim )
yStart, yEnd = 0, int(y_dim*0.9)
xStep = int(xEnd/6)
yStep = int(yEnd/6)
# Beschriftung
for x in range(0, 6):
ausgabe = " "+(fragen.fragenfeld[x*5].kategorie)
ausgabe = ausgabe.replace('\\n' , '\n ')
pgi.text_output (screen,percent_tile(x*16.6,0,18,20),ausgabe,BG_COLOR,FG_COLOR,wall_font_name,small_font_size)
for y in range(0, 5):
jetztfrage = fragen.fragenfeld[x*5+y]
if jetztfrage.farbe == BLUE:
pgi.text_output (screen,percent_tile(x*16.7, (y+1)*90*(yStep/yEnd), 18, 20), " "+ str(fragen.fragenfeld[x*5+y].punkte), BG_COLOR, FG_COLOR,wall_font_name, big_font_size)
else:
pgi.text_output (screen,percent_tile(x*16.7, (y+1)*90*(yStep/yEnd), 18, 20), "", jetztfrage.farbe, BLACK, wall_font_name, big_font_size)
# Gitter zeichnen
for x in range(xStart, xEnd+1, xStep):
pygame.draw.line(screen, GRID_COLOR, (x, yStart), (x, yEnd), 5)
for y in range(yStart, yEnd+1, yStep):
pygame.draw.line(screen, GRID_COLOR, (xStart, y), (xEnd, y), 5)
# Spieler
for _ in spieler:
pgi.text_output (screen,percent_tile(_.nr * 100 / spieler_anzahl, 100 - 10 , 100 / spieler_anzahl , 10), (_.name + ': ' + str(_.punkte)) , _.color, BLACK, wall_font_name, small_font_size)
def frageAnzeigen(aktuelleFrageNr,fragen,druecker):
question=fragen.fragenfeld[aktuelleFrageNr]
Anzeigetext=question.frage
action =""
if question.farbe == BLUE:
#frage anzeigen
if question.frage[-4:]== ".png":
#Besorge Bild und Zeige es formatfüllend
x=get_image(fragen.paketordner+ "//" + question.frage)
x= pygame.transform.scale(x, (x_dim, y_dim))
screen.blit(x,(0,0))
elif question.frage[-4:]== ".wav":
action = fragen.paketordner + "//"+ question.frage
pgi.text_output (screen,percent_tile(40, 40, 30, 30), "(S)OUND" , BLUE, WHITE, font_name="arial", font_size=40)
else:
#print (Anzeigetext)
textCentered(Anzeigetext)
#
if druecker == -99:
drueckertext="WIR WARTEN...."
pgi.text_output (screen,percent_tile(40, 85, 24, 15), drueckertext, BLUE, BLACK, font_name="arial", font_size=40)
else:
pgi.text_output (screen,percent_tile(40, 85, 24, 15)," "+ druecker.name, (druecker.color), BLACK , font_name="arial", font_size=40)
else:
Anzeigetext = " Die FRAGE HATTEN WIR SCHON !!!"
textCentered(Anzeigetext)
return action
def antwortAnzeigen(aktuelleFrageNr, fragen):
question = fragen.fragenfeld[aktuelleFrageNr]
Anzeigetext = question.antwort
textCentered(Anzeigetext)
x = get_image(graphics+"antwort.png")
x = pygame.transform.scale(x, (int(x_dim), int(y_dim*.2)))
screen.blit(x, (0,y_dim*0.79))
print("hacKNerdy .... Neuer! Lauter! Bunter! ")
# initialiseren
pygame.init()
pygame.mixer.music.load(sfx+'theme.mp3')
if musik == True:
pygame.mixer.music.play(0)
# Buzzer initialisieren
for i in range(0, pygame.joystick.get_count()):
JOYSTICKS.append(pygame.joystick.Joystick(i))
JOYSTICKS[-1].init()
print("Detected joystick '%s'" % JOYSTICKS[-1].get_name())
# fonts einladen
fontFile = "assets//fonts//Roboto-Medium.ttf"
smallFont = pygame.font.Font(fontFile , 38)
bigFont = pygame.font.Font(fontFile, 70)
# Anzeigetafel initialisieren und mit Titelbild zeigen
screen = pygame.display.set_mode((x_dim, y_dim))
pygame.display.set_caption('hacKNerdy')
pygame.mouse.set_visible(1)
background = pygame.Surface(screen.get_size())
background = background.convert()
background.fill(BLUE)
pygame.display.flip()
#
pygame.display.toggle_fullscreen()
#
x = get_image("assets//graphics//bootsplash.png")
#
x = pygame.transform.scale(x, (x_dim, y_dim))
screen.blit(x, (0,0))
pygame.display.flip()
if musik == True:
pygame.mixer.music.play(0)
# Fragenpaket auswählen
# Use Surface at Rect to print Text, with BGColor, TextColor in Font With Size
pgi.text_output(screen, percent_tile(5, 85, 40, 15), "Welches Fragenpaket?", BLACK, GREEN, font_name = "ocra", font_size = 40)
#pgi.text_output(screen, percent_tile(5, 85, 40, 15), "Welches Fragenpaket?", BLACK, GREEN, font_name = "ocra", font_size = 40)
# Use Surface at Rect to input Text, with BGColor, TextColor in Font With Size
fragenpaket = pgi.text_input(screen, percent_tile(45, 85, 40, 15), BLACK, GREEN, font_name = "ocra", font_size = 40)
if fragenpaket == "":
fragenpaket = "1"
print ("Fragenpaket " + fragenpaket + " Gewählt ")
#
#
# Hier muss noch eine Kontrolle rein, ob der Ordner und alle Dateien existieren!
#
#
fragen = Fragen(fragenpaket)
try:
screen.blit(background, (0, 0))
x = get_image(fragenpaket + "//splash.png")
x = pygame.transform.scale(x, (x_dim, y_dim))
screen.blit(x, (0,0))
pygame.display.flip()
#print ("Bild gefunden")
except:
#print("nicht gefunden")
#
screen.blit(background, (0, 0))
x = get_image("assets//graphics//bootsplash.png")
#background = pygame.Surface(screen.get_size())
pygame.display.flip()
x = pygame.transform.scale(x, (x_dim, y_dim))
screen.blit(x, (0,0))
pygame.display.flip()
print ("Warning:\nNo specific splash.png in " + fragenpaket + " found, using default instead")
pass
# initialize Spieler
for spieler_nr in range(spieler_anzahl):
# Use Surface at Rect to print Text, with BGColor, TextColor in Font With Size
question = "Name des " + str(spieler_nr+1) + ". Spielers? "
pgi.text_output(screen, percent_tile(5, 85, 40, 15), question, BLUE, WHITE, font_name = fontFile, font_size=40)
# Use Surface at Rect to input Text, with BGColor, TextColor in Font With Size
player_name = pgi.text_input(screen, percent_tile(45, 85, 40, 15), BLUE, WHITE, font_name = fontFile, font_size=40)
spieler.append(Spieler(player_name[0:11], spieler_nr))
# Startstatus
quit = False
druecker = -99
modus = "aussuchen"
mauspos = None
# Das Teil für die Framerate
clock = pygame.time.Clock()
# Hauptschleife
while not quit:
clock.tick(30)
for event in pygame.event.get():
if event.type == QUIT:
quit = True
elif event.type == KEYDOWN:
if event.key == K_ESCAPE:
quit = True
elif event.key == ord('m'):
if musik == False:
pygame.mixer.music.play(0)
musik = True
else:
pygame.mixer.music.stop()
musik = False
elif event.key == ord('y'):
pygame.mixer.Sound(sfx + 'game-fx-1.wav').play()
elif event.key == ord('a'):
pygame.mixer.Sound(sfx + 'game-fx-2.wav').play()
elif event.key == ord('s'):
pygame.mixer.Sound(questionWav).play()
actionWav = ""
if druecker == -99 and modus == "frage":
for _ in range(spieler_anzahl):
if event.key == (49 + _ ):
druecker = spieler[ _ ]
buzz()
#
elif druecker == -99 and event.type == JOYBUTTONDOWN:
#
if event.button//5 < len(spieler):
druecker = spieler[event.button // 5]
if modus == "frage":
#
buzz()
elif event.type == MOUSEBUTTONDOWN:
mauspos = (pygame.mouse.get_pos())
if modus == "aussuchen":
wandAnzeigen(screen)
if mauspos != None:
# Berechnug der angeklickten Frage
if (int(mauspos[1]/int(0.9*y_dim/6)) > 0) and (int(mauspos[1]/int(0.9*y_dim/6)) < 6):
aktuelleFrage = (int(mauspos[0]/int(x_dim/6))*5 + int(mauspos[1]/int(0.9*y_dim/6))-1 )
modus = "frage"
mauspos = None
druecker= -99
elif modus == "frage":
screen.blit(background, (0, 0))
action = frageAnzeigen(aktuelleFrage,fragen , druecker)
questionWav= action
if mauspos != None:
modus = "antwort"
mauspos = None
elif modus == "antwort":
screen.blit(background, (0, 0))
antwortAnzeigen(aktuelleFrage,fragen)
if mauspos != None:
if fragen.fragenfeld[aktuelleFrage].farbe == BLUE:
fragen.anzahl_fragen -= 1
fragen.fragenfeld[aktuelleFrage].farbe = WHITE
# Berechnung Ja/Nicht gewertet/Nein
if ((mauspos[1]/int(0.8*y_dim)) > 0.8) and druecker != -99:
if (0 == int(mauspos[0]/int(x_dim/3))):
# Gültig !
druecker.punkte += int(fragen.fragenfeld[aktuelleFrage].punkte)
fragen.fragenfeld[aktuelleFrage].farbe = druecker.color
elif (2 == int(mauspos[0]/int(x_dim/3))):
# Falsch !
druecker.punkte -= int(fragen.fragenfeld[aktuelleFrage].punkte)
fragen.fragenfeld[aktuelleFrage].punkte= ""
if fragen.anzahl_fragen < 1:
wandAnzeigen(screen)
if musik == True:
while not(pygame.mixer_music.get_busy()):
pygame.mixer.music.play(0)
i = 0
for x in (" "," E"," N"," D"," E"," "):
fragen.fragenfeld[i*5].kategorie = x
i += 1
modus = "aussuchen"
druecker = -99
mauspos = None
pygame.display.flip()
if __name__ == '__main__':
main()
1