Hello,

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

Reply via email to