I get some problems with 3-dimensional navigation: I would like to control a character in a 3D space, and a camera following it. But I get some problems with the rotations and the collisions: If i turn my character on his back, the control via the keyboard changes: The left key turns it to the right and right one turns it to the left. In addition, if I want to turn after a collision, my character doesn't turn on itself but around an invisible point in the space.
How can I solve these problems ?
( I join my source file )
Thanks in advance ;-)
HuGo
ps: I can read English & French
# -*- indent-tabs-mode: t -*- import sys, os import soya import soya.sdlconst as sdlconst
soya.init("Kuiper - t3_test0",width=900,height=700)
soya.path.append(os.path.join(os.path.dirname(sys.argv[0]), "data"))
class KeyboardController:
#@ Directions
left_key_down = 0
right_key_down = 0
up_key_down = 0
down_key_down = 0
#@ Actions
a_key_down = 0
z_key_down = 0
def next(self):
"""Returns the next action"""
for event in soya.process_event():
if event[0] == sdlconst.KEYDOWN:
if event[1] in (sdlconst.K_q, sdlconst.K_ESCAPE):
sys.exit() # Quit the game
#@ Directions
elif event[1] == sdlconst.K_LEFT: self.left_key_down = 1
elif event[1] == sdlconst.K_RIGHT: self.right_key_down = 1
elif event[1] == sdlconst.K_UP: self.up_key_down = 1
elif event[1] == sdlconst.K_DOWN: self.down_key_down = 1
#@ Actions
elif event[1] == sdlconst.K_a: self.a_key_down = 1
elif event[1] == sdlconst.K_z: self.z_key_down = 1
elif event[0] == sdlconst.KEYUP:
if event[1] == sdlconst.K_LEFT: self.left_key_down = 0
elif event[1] == sdlconst.K_RIGHT: self.right_key_down = 0
elif event[1] == sdlconst.K_UP: self.up_key_down = 0
elif event[1] == sdlconst.K_DOWN: self.down_key_down = 0
#@ Actions
elif event[1] == sdlconst.K_a: self.a_key_down = 0
elif event[1] == sdlconst.K_z: self.z_key_down = 0
return (self.left_key_down - self.right_key_down,
self.up_key_down - self.down_key_down,
self.a_key_down - self.z_key_down)
class Ship(soya.World):
"A character in the game."
def __init__(self, parent, controller):
soya.World.__init__(self, parent)
# getting the ship model
ship_model = soya.Model.get("caterpillar_head")
# creating the ship
self.body = soya.Body(self, ship_model)
self.controller = controller
self.speed = soya.Vector(self)
self.h_rotation_speed = 0.0 # horizontal
self.v_rotation_speed = 0.0 # vertical
self.h_keys = 0
self.v_keys = 0
self.acc_keys = 0
# Setting a mass
self.body.mass = soya.SphericalMass(2)
# Creating a Geometry object for each Body
soya.GeomSphere(self.body,1.2)
def begin_round(self):
self.begin_action(self.controller.next())
soya.World.begin_round(self)
def begin_action(self, action):
# Reset
#self.speed.x = self.speed.y = self.speed.z = 0.0
if action:
self.h_keys = action[0]
self.v_keys = action[1]
self.acc_keys = action[2]
if self.h_keys:
self.h_rotation_speed += 0.5 * self.h_keys
else:
self.h_rotation_speed *= 0.8
if self.v_keys:
self.v_rotation_speed += -0.5 * self.v_keys
else:
self.v_rotation_speed *= 0.8
if self.acc_keys:
self.speed.z += -0.1 * self.acc_keys
#self.body.add_force(\
# soya.Vector(self.body,0,0,-1000 * self.acc_keys))
else:
self.speed.y *= 0.8
def advance_time(self, proportion):
soya.World.advance_time(self, proportion)
self.add_mul_vector(proportion, self.speed)
self.rotate_y(proportion * self.h_rotation_speed)
self.rotate_x(proportion * self.v_rotation_speed)
class IntegratedCamera(soya.Camera):
def __init__(self, parent, character):
soya.Camera.__init__(self, parent)
self.character = character
def begin_round(self):
self.look_at(self.character)
# create world
scene = soya.World()
# Creates a character in the scene/level, with a keyboard controller
character = Ship(scene, KeyboardController())
character.set_xyz(0,0,0)
head_model = soya.Model.get("caterpillar_head")
heads = (
soya.Body(scene,head_model),
soya.Body(scene,head_model))
## Adding a mass ##
for head in heads:
head.mass = soya.SphericalMass(25)
soya.GeomSphere(heads[0],1.2)
soya.GeomSphere(heads[1],1.2)
# Miroir
import soya.sphere
material = soya.Material()
material.environment_mapping = 1
ball_world=soya.sphere.Sphere()
for face in ball_world.children:
face.smooth_lit=1
face.material=material
ball_world.set_xyz(0,0,20)
######
#placing the body face to face
heads[0].x = -25
heads[1].x = 25
heads[0].look_at(heads[1])
heads[1].look_at(heads[0])
#pushing them forward
for head in heads:
head.add_force(soya.Vector(head,0,0,-5000))
# adding camera
camera = IntegratedCamera(character, character)
camera.set_xyz(0,0,30)
#placing light over the duel
light = soya.Light(scene)
light.set_xyz(0, 10,0)
#running soya
soya.set_root_widget(camera)
ml = soya.MainLoop(scene)
ml.main_loop()
_______________________________________________ Soya-user mailing list [email protected] https://mail.gna.org/listinfo/soya-user
