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()