Links und Funktionen
Sprachumschaltung

Navigationspfad


Inhaltsbereich

spielgeruest_mini.py

Python Source icon 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

Funktionsleiste