spielgeruest_mini.py
spielgeruest_mini.py — Python Source, 7 KB (7997 bytes)
Dateiinhalt
from visual import * from threading import Thread PORT = 50000 class Feld(frame): def __init__(self, nummer, farbe, groesse=1): frame.__init__(self) self.nummer=nummer self.feld = box(frame=self, material=materials.plastic, width=groesse, length=groesse, height=groesse/20, color=farbe) class Spielfigur(frame): def __init__(self, farbe, besitzer, nummer, groesse=1): frame.__init__(self) self.besitzer = besitzer self.nummer = nummer self.feldnr = 0 #Nummer des Feldes, auf dem die Figur steht self.body = cone(frame=self, color=farbe, axis=(0,1,0), # Kegelkoerper radius=0.375*groesse, material=materials.wood) self.head = sphere(frame=self, color=farbe, y=1*groesse,# Kugelkopf radius=0.25*groesse,material=materials.wood) class Spielbrett(Thread): def __init__(self): Thread.__init__(self) self.figurenliste = [] self.felderliste = [] self.aufbauen() def aufbauen(self): zahl = 5 for i in range (zahl*zahl): if i%2==0: c = color.white else: c = color.red x = Feld(i,c) x.pos=(i%zahl*2,0,i/zahl*2) self.felderliste.append(x) z = Spielfigur(color.green, 0, 0) self.figurenliste.append(z) u = Spielfigur(color.yellow, 1, 0) self.figurenliste.append(u) u.pos = self.felderliste[zahl*zahl-1].pos def figur_setzen(self,spielernr,figurnr,zielnr): #erst die richtige Figur in der Liste finden for f in self.figurenliste: if f.besitzer==spielernr and f.nummer==figurnr: figur = f break #dann das richtige feld in der anderen Liste finden for feld in self.felderliste: if feld.nummer == zielnr: figur.pos=feld.pos figur.feldnr = feld.nummer break def run(self): pick = None spielernr = -1 #die spielernummer figurnr = -1 #die figurnummer zielnr = -1 #die zielposition (als nummer) while True: rate(30) if scene.mouse.events: sme = scene.mouse.getevent() #wenn ein Objekt geklickt und bewegt wird if sme.drag and sme.pick: #testen, ob zu einer figur gehoert for f in self.figurenliste: if sme.pick in f.objects: spielernr = f.besitzer figurnr = f.nummer break else: f = None drag_pos = sme.pickpos # where on the object drag_pos.y = 0 #### neu pick = f #wenn eine Figur losgelassen wird, wird das naechstgelegene Feld ermittelt elif sme.drop and pick: zielnr=pick.feldnr #vorerst ist die alte Position der Figur das Ziel #Suchen nach naechstgelegenem neuen Feld for feld in self.felderliste: feldmitte = feld.pos#kann noch verbessert werden if mag(feldmitte - pick.pos) < .8: zielnr=feld.nummer #gefunden! break #--------------------# self.controller.weiterleiten(str(spielernr)+","+str(figurnr)+","+str(pick.feldnr)+","+str(zielnr)) #--------------------# #self.figur_setzen(spielernr,figurnr,zielnr) pick = None #wenn eine Figur angeklickt worden ist, wird ihre Position der Maus angepasst if pick: # project onto xy plane, even if scene rotated: new_pos = scene.mouse.project(normal=(0,1,0)) if new_pos != drag_pos: # if mouse has moved #offset for where the ball was clicked: pick.pos += new_pos - drag_pos drag_pos = new_pos # update drag position pick.pos = new_pos + pick.pos - drag_pos drag_pos = new_pos # update drag position '''Diese Klasse ermoeglicht die Netzkommunikation. Bau sie in dein Projekt ein. Die eigentliche Spielklasse braucht ein Referenzattribut auf ein Objekt dieser Steuerungs-Klasse, und kann dann mittels der Steuerungs-Methode weiterleiten(nachricht) einen String an die Steuerung schicken, die ihrerseits das an den Server weiterleitet. (Was der Server macht, steht in der Datei "server_class.py", die sich im selben Verzeichnis befinden muss.) Der Konstruktor verlangt ein Objekt, dem er die Nachrichten des Servers schicken soll, also das eigentliche Spiel, und optional einen Port. Jedes Team sollte eine eigene fuenstellige Portnummer waehlen.''' class Steuerung(Thread): def __init__(self, spiel, port=50000): Thread.__init__(self) self.view=spiel # UDP-Client, der den Server als Subprozess startet import subprocess # Modul zum Starten von Subprozessen import socket # Modul fuer Netzwerkkommunikation self.PORT = port #Anlegen eines Socket self.s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # AF_INET = IPv4, SOCK_DGRAM = UDP self.s.setsockopt(socket.SOL_SOCKET,socket.SO_BROADCAST,1) # Broadcast ermoeglichen #Testen, ob es schon einen Server auf diesem Port gibt, notfalls selber starten try: self.s.sendto("print 'wer hoert mich?'", ('255.255.255.255', self.PORT)) # sende Nachricht 'an alle' self.s.settimeout(2) # warte 1/2 Sekunde.. print (self.s.recvfrom(64)[0]) # gibt Servermeldung aus #ein Problem, wenn timeout einmal gesetzt ist... self.s.settimeout(3000) except: # reagiert auf Zeitueberschreitung print ("Kein Server vorhanden - starte Server") # Rueckmeldung subprocess.Popen(['python','server_class.py',str(self.PORT)]) # Server starten self.s.setblocking(1) # nicht-blockierend self.s.sendto("print 'hallo'", ('255.255.255.255', self.PORT)) self.start() #Endlosmethode zum Abhoeren des Ports auf Nachrichten def run(self): while True: nachricht = self.s.recvfrom(128)[0] self.auswerten(nachricht) #Methode zum Auswerten der eingegangenen Nachricht def auswerten(self,nachricht): exec (nachricht) #Methode zum Weiterleiten, wird von Spiel genutzt def weiterleiten(self, nachricht): # HIER CODE EINFUEGEN, DER AUSGEFUEHRT WERDEN SOLL teile=nachricht.split(",") nachricht = "self.view.figur_setzen("+teile[0]+","+teile[1]+","+teile[3]+")" self.s.sendto(nachricht, ('255.255.255.255', self.PORT)) # versenden der Nachricht an Tupel(IP, PORT) if __name__ == "__main__": spiel = Spielbrett() #das eigentliche Spiel steuerung = Steuerung(spiel, PORT) #Die Steuerung, mit dem Spiel und einem Port als Argument spiel.controller = steuerung #Setzen des Referenzattributs spiel.start() #Das Spiel muss von Thread erben, hier wird dessen run-Methode gestartet