Auto-auf-Ring4.py
Mit einem Auto auf einem Ring durch einen Tunnel fahren und dabei die Stäbe umfahren.
Für das Spiel braucht man die Datei textur.tga
Auto-auf-Ring4a.py — text/python-source, 9 KB (9606 bytes)
Dateiinhalt
''' Created on 15.04.2011 - 20-04-2011, Probestudium Informatik LMU 2011 @author: Florian Der Spieler faehrt auf einem sich drehenden Ring. Mit der Maus kann das Auto um den Ring rotiert werden. Es geht darum, moeglich ''' ### from visual import* from visual.controls import * from random import* from math import * import thread import Image scene = display(height = 1000,\ width = 1000,\ fullscreen=True,\ forward=(-1,-0.5,0) ,\ up = (-1,0,0),\ fov = 2,\ center=(0,0,0),\ range = 1.5,\ userspin = False,\ userzoom = False,\ autoscale = False) # Programmfenster ### Erstellung der Textur fuer den Tunnel textur = "textur" im = Image.open("textur.tga") # Oeffnen des Bildes materials.saveTGA(textur,im) # Speichern des Bildes intern pano = materials.texture(data=im, mapping="spherical") # Darstellungsart scene.title=("Weiche den Hindernissen aus!") welt = frame() system = frame(frame = welt) bahn = ring(frame = system, axis=(0,1,0), radius = 20, thickness = .8, material = materials.wood) tunnel = ring(frame = system, axis = (0,1,0), radius = 20, thickness = 3, material = pano) auto = box(frame = welt,color = color.red, length = 1, height = .3, width = .3, y = bahn.thickness+.15, z = bahn.radius) hitL = label(frame = welt,text="Hits:", space=0.2, pos = auto.pos, opacity=0.25, yoffset = 10) StartL = label(frame = welt,space = 0.2, pos = auto.pos, opacity = 0.25, text = "Sammle moeglichst viel Hits!! \n Start mit Leertaste",yoffset = 70) origin = vector(0,0,bahn.radius) mode = 1 start = 0 ListHindernisse = [] #lamp = local_light(pos=(0,0,0), color=color.yellow) scene.center=auto.pos drehwinkel = 0 if scene.fullscreen==False: cwindow = controls(title = "Einstellungen", height = 400, width = 400) view = menu(text = "Sichtmodus", pos = (0,50), height = 20, width = 140) view.items.append(("Bewegung mit Auto", lambda: sichtModus(1))) view.items.append(("Unbewegter Beobachter", lambda: sichtModus(0))) def fahren(): global drehwinkel, mode drehwinkel = 0 auto.rotateWinkel=0 auto.rotateWinkel2 =0 while true: rate(60) if start == 1: x=scene.center rotateWinkel = radians(7*(scene.mouse.pos.z-x.z)) auto.rotate(angle=rotateWinkel, axis = (1,0,0), origin = (0,0,bahn.radius)) if mode == 1: welt.rotate(angle=-rotateWinkel, axis =(1,0,0), origin = (0,0,bahn.radius)) system.rotate(angle=radians(0.5), axis = (0,1,0)) drehwinkel = drehwinkel + 0.5 scene.center=(welt.frame_to_world(auto.pos).x,welt.frame_to_world(auto.pos).y,welt.frame_to_world(auto.pos).z) scene.forward=(-1,-welt.frame_to_world(auto.pos).y/2, 0) scene.up=(auto.pos.y,auto.pos.z,auto.pos.x) hitL.pos = auto.pos auto.rotateWinkel = (auto.rotateWinkel + rotateWinkel)%(2*pi) auto.rotateWinkel2 =(auto.rotateWinkel2+rotateWinkel)%(2*pi) elif start == 2: break def hindernisse2(runde): "Setzen der Hindernisse fuer eine Runde" pos = vector(0,0,bahn.radius) # Erstes Hinderniss wird bei Startposition des Autos gesetzt winkel = 360./(18.*runde) # Berechnung des Winkelabstands zwischen zwei Hindernissen, abhaengig von der Runde ListHindernisse.append((ring(frame=system,pos = pos, radius = 2, thickness = 0.3, rotateWinkel = pi/2,\ color = color.orange))) #lamp = local_light(frame = system,pos=pos, color=color.orange) pos=vector(pos.x*cos(radians(winkel))-pos.z*sin(radians(winkel)),pos.y,\ pos.z*cos(radians(winkel))+pos.x*sin(radians(winkel))) thread.start_new(Effekt2, (pos,)) for i in range(int(360/winkel)-1): ListHindernisse.append((box(frame=system, pos=pos, length=0.1,\ color=color.hsv_to_rgb((random(),1,1)),\ height=tunnel.thickness*2, width=0.1, axis=(pos.z,pos.y,-pos.x)))) # neues Hindernis an Liste anhaengen rotateWinkel = randrange(0,180) ListHindernisse[-1].rotate(angle=radians(rotateWinkel), axis=(pos.z,pos.y,-pos.x)) # Hindernis nach Zufall um Bahn drehen ListHindernisse[-1].rotateWinkel = rotateWinkel pos=vector(pos.x*cos(radians(winkel))-pos.z*sin(radians(winkel)),pos.y,\ pos.z*cos(radians(winkel))+pos.x*sin(radians(winkel))) # Berechnung der neuen Hindernisposition mit Vektordrehung def hits2(): hits = 0 alphaA = acos(vector(0,bahn.thickness,0).dot(vector(0,bahn.thickness,0.5*auto.width)) / \ (mag(vector(0,bahn.thickness,0))*mag(vector(-0.5*auto.width,bahn.thickness,0)))) alphaB = acos(vector(0,bahn.thickness,0).dot(vector(0,bahn.thickness,0.05)) / \ (mag(vector(0,bahn.thickness,0))*mag(vector(-0.05,bahn.thickness,0)))) alphaG = (alphaA + alphaB) / 2 #print "aA =", alphaA #print "aB =", alphaB while true: time.sleep(0.02) for obj in ListHindernisse: #print system.frame_to_world(obj.pos).x if system.frame_to_world(obj.pos).x<=0.8 and system.frame_to_world(obj.pos).x>=-0.8 and system.frame_to_world(obj.pos).z>bahn.radius-0.5: #objVector = vector(system.frame_to_world(obj.axis).x,system.frame_to_world(obj.axis).z,system.frame_to_world(obj.axis).y) winkel1 = acos(((auto.pos-origin).dot(vector(0,bahn.thickness,0))) / (mag(auto.pos-origin)*mag ( vector(bahn.thickness,0)))) #winkel1 = auto.rotateWinkel2 winkel2a = radians(obj.rotateWinkel) winkel2b = radians(180-obj.rotateWinkel) winkela = abs(winkel2a-winkel1) winkelb = abs(winkel2b-winkel1) #print obj,system.frame_to_world(obj.pos), auto.pos-origin, degrees(winkela) if winkela <= alphaG or winkelb <= alphaG or 2*pi-winkel2a <=alphaG or 2*pi-winkel2b <= alphaG: hits=hits+1 hitL.text = "Hits: "+str(hits) thread.start_new(Effekt, (obj.color,)) #print winkela," ",winkelb while system.frame_to_world(obj.pos).x<=0.8: time.sleep(0.02) pass def neueHindernisse(): global ListHindernisse, drehwinkel,round, start, StartL while true: time.sleep(0.1) if drehwinkel > 360*round and round > 5: start = 2 StartL.pos = auto.pos StartL.visible = True StartL.text = "GAME OVER \n Press escape!" break elif drehwinkel > 360*round and round <= 5: round=round+1 for obj in ListHindernisse: obj.visible = False ListHindernisse=[] #lamp.visible = false hindernisse2(round) time.sleep(5) def Effekt(color): boxList = [] for i in range(30): boxList.append(box(frame=welt,pos=auto.pos + vector(-1,0,0),width=0.1,height=0.1,length=0.1,\ color=color)) boxList[-1].v=vector(-0.1,uniform(-0.5,0.5),uniform(-0.5,0.5)) for i in range(50): for obj in boxList: obj.pos=obj.pos+obj.v time.sleep(0.02) for obj in boxList: obj.visible = false return None def Effekt2(pos): boxList = [] for i in range(100): boxList.append(sphere(frame = welt, pos = pos,color=color.hsv_to_rgb((random(),1,1)),\ radius = 0.5, v = vector(-0.1,uniform(-0.5,0.5),uniform(-0.5,0.5)) )) for i in range(25): for obj in boxList: obj.pos = obj.pos + obj.v time.sleep(0.05) for obj in boxList: obj.visible = false def sichtModus(modeN): global mode if modeN !=mode: if modeN == 1: welt.rotate(angle=-auto.rotateWinkel, axis =(1,0,0), origin = (0,0,bahn.radius)) if modeN ==0: welt.rotate(angle=auto.rotateWinkel, axis =(1,0,0), origin = (0,0,bahn.radius)) mode = modeN def sichtModusKey(): global mode while true: time.sleep(0.1) if scene.kb.keys !=0: s = scene.kb.getkey() if s=="v": if mode == 0: welt.rotate(angle=-auto.rotateWinkel, axis =(1,0,0), origin = (0,0,bahn.radius)) elif mode == 1: welt.rotate(angle=auto.rotateWinkel, axis =(1,0,0), origin = (0,0,bahn.radius)) mode = (mode+1)%2 time.sleep(1) def startstop(): global start while true: time.sleep(0.1) if scene.kb.keys !=0: s = scene.kb.getkey() if s==" ": if start == 0: StartL.visible=false elif start == 1: StartL.text = "Pause" StartL.pos = auto.pos StartL.visible = true start = (start+1)%2 time.sleep(0.5) thread.start_new(startstop, ()) fahren = thread.start_new(fahren, ()) round = 0 thread.start_new(neueHindernisse, ()) thread.start_new(hits2, ()) thread.start_new(sichtModusKey,()) if scene.fullscreen==false: while true: rate(10) cwindow.interact()