예제 #1
0
	def update_moving(self):
		# 跳跃
		if self.cur_state_idx == 2:
			return
		# 行走
		prev_pos = math3d.vector(self.pos)
		self.moving_dir = self.get_user_input(g_moving_speed)
		if self.moving_dir.is_zero:
			return
		cur_moving = math3d.vector(self.moving_dir)
		self.up_ofs = math3d.vector(0, 0, 0)
		result = self.move()
		# 平走失败
		if result.hit:
			# 尝试上楼
			self.step_up()
			# 按移动方向移动
			self.move_and_slide()
		result = self.step_down()
		# 踏空 或 可站立行走
		if not result.hit or self.can_stand(self.pos, result.point, result.normal):
			return
		# 上楼失败,重置信息,直行
		self.moving_dir = cur_moving
		self.pos = prev_pos
		self.no_up_slide = True
		self.move_and_slide()
		self.no_up_slide = False
예제 #2
0
	def logic(self):
		if self._style == STYLE_FREELOOK:
			accel = math3d.vector(0, 0, 0)
			if self._is_forward:
				accel += self._camera.rotation_matrix.forward
			elif self._is_back:
				accel -= self._camera.rotation_matrix.forward
			elif self._is_left:
				accel -= self._camera.rotation_matrix.right
			elif self._is_right:
				accel += self._camera.rotation_matrix.right
			elif self._is_up:
				accel += self._camera.rotation_matrix.up
			elif self._is_down:
				accel -= self._camera.rotation_matrix.up
			top_speed = self._topspeed * 20.0 if self._fast_move else self._topspeed
			if not accel.is_zero:
				accel.normalize()
				self._velocity += accel * top_speed
			else:
				self._velocity -= self._velocity * 0.1
			if self._velocity.length_sqr > top_speed * top_speed:
				self._velocity.normalize()
				self._velocity *= top_speed
			elif self._velocity.is_zero:
				self._velocity = math3d.vector(0, 0, 0)
			if self._velocity != math3d.vector(0, 0, 0):
				self._camera.position += self._velocity
		self.on_mouse_move()
예제 #3
0
	def update_dropping(self):
		down = math3d.vector(0, - g_gravity, 0)
		self.moving_dir = self.get_user_input(g_drop_control_speed)
		self.moving_dir += down
		self.target_pos = self.pos + self.moving_dir
		result = self.sweep_test(self.pos, self.target_pos)
		if not result.hit:
			# 什么都没碰到,继续下落
			self.pos = self.target_pos
			self.pos = self.pos
			return
		# 碰撞后是否可站立
		standing_pos = math3d.vector(0, 0, 0)
		standing_pos.intrp(self.pos, self.target_pos, result.fraction)
		if self.can_stand(standing_pos, result.point, result.normal):
			self.update_collide_pos(result.fraction)
			# 进入行走态
			self.update_collide_pos(result.fraction)
			self.cur_state_idx = 0
			return
		# 进行滑动
		result = self.slide(result)
		if result.hit:
			self.update_collide_pos(result.fraction)
			if self.can_stand(self.pos, result.point, result.normal):
				# 进入行走态
				self.cur_state_idx = 0
예제 #4
0
	def update_dropping(self):
		if self.state == tower_const.TOWER_STATE_MOVING:
			return

		down = math3d.vector(0, tower_const.GRAVITY, 0)

		cur_pos = math3d.vector(*self.pos)

		self.target_pos = cur_pos + down

		result = self.sweep_test(cur_pos, self.target_pos)

		if not result.hit:
			self.pos = self.target_pos.x, self.target_pos.y, self.target_pos.z
			self.set_state(tower_const.TOWER_STATE_DROPPING)
			return
		self.update_collide_pos(result.fraction)
		self.set_state(tower_const.TOWER_STATE_MOVING)

		global g_tower_init_pos
		init_z = g_tower_init_pos[1]
		init_z -= 5
		g_tower_init_pos = (0, init_z, -100)

		cam = iworld3d.get_camera(tower_const.SCENE_LAYER)
		position = cam.position
		position.y -= 5
		cam.position = position
예제 #5
0
	def init(self):
		self.bill = None
		self.moving_dir = math3d.vector(0, 0, 0) # 移动方向
		self.target_pos = math3d.vector(0, 0, 0) # 目标位置
		self.is_dragging = False # 是否被鼠标拖动
		self.mouse_pos = (0, 0)  # 鼠标拖动位置
		self.pre_mouse_pos = (0, 0) # 上一次鼠标的位置
예제 #6
0
	def init(self):
		self.bill = None
		self.moving_dir = math3d.vector(0, 0, 0)
		self.target_pos = math3d.vector(0, 0, 0)
		self.pos = g_tower_init_pos[0], g_tower_init_pos[1], g_tower_init_pos[2]

		print "init pos", self.pos
예제 #7
0
	def on_key_msg(self, msg, key):
		super(demo, self).on_key_msg(msg, key)
		if key == game.VK_W and msg==game.MSG_KEY_PRESSED:
			self.player.position += math3d.vector(0,0,5)
		elif key == game.VK_S and msg==game.MSG_KEY_PRESSED:
			self.player.position += math3d.vector(0,0,-5)
		elif key == game.VK_A and msg==game.MSG_KEY_PRESSED:
			self.player.position += math3d.vector(-5,0,0)
		elif key == game.VK_D and msg==game.MSG_KEY_PRESSED:
			self.player.position += math3d.vector(5,0,0)
예제 #8
0
	def logic(self):
		if self.obj.position.x > 50:
			self.obj.position = math3d.vector(-50, self.obj.position.y, self.obj.position.z)
		else:
			self.obj.position = math3d.vector(self.obj.position.x + 1, self.obj.position.y, self.obj.position.z)
			
		if self.hp <= 0:
			self.hp = 1
		else:
			self.set_hp(self.hp - 0.01)
예제 #9
0
	def set_yawpitchdist(self, yaw, pitch, dist):
		if self._target:
			self._camera.position = self._target.position
			self._camera.rotation_matrix = self._target.rotation_matrix
			self._camera.yaw(yaw)
			self._camera.pitch(-pitch)
			self.move_relative(-dist)
		else:
			self._camera.set_placement(
				dist,
				math3d.vector(0, -1, -1),
				math3d.vector(0, 1, 0))
예제 #10
0
	def update_plane_shadow(self):
		# 以player位置作射线,计算碰撞到哪个石头
		p0 = self.pos
		coldata = iphy3d.hit_by_ray(eggyolk2_const.SCENE_LAYER, \
			math3d.vector(p0[0], p0[1], p0[2]),\
			math3d.vector(p0[0], p0[1]+10000, p0[2]))
		if coldata.hit:
			self.sprite.set_shadow_visible(True)
			self.sprite.clear_shadows()
			# 使用场景内置的0号光照
			self.sprite.add_plane_shadow((coldata.normal, coldata.point), "light_1")
		else:
			self.sprite.set_shadow_visible(False)
예제 #11
0
	def update_dropping(self):
		if self.state == eggyolk2_const.PLAYER_STATE_MOVING:
			return
		down = math3d.vector(0, eggyolk2_const.GRAVITY, 0)
		cur_pos = math3d.vector(*self.pos)
		self.target_pos = cur_pos + down
		result = self.sweep_test(cur_pos, self.target_pos)
		if not result.hit:
			# 没碰到东西,继续下落
			self.pos = self.target_pos.x, self.target_pos.y, self.target_pos.z
			self.set_state(eggyolk2_const.PLAYER_STATE_DROPPING)
			return
		# 发现碰撞,更新位置
		self.update_collide_pos(result.fraction)
		self.set_state(eggyolk2_const.PLAYER_STATE_MOVING)
예제 #12
0
	def create_3d_ui(self, depth):
		ui = iworld3d.create_scene3d_ui(scn_file, depth = depth)
		model = iworld3d.model3d(gim_file, "", ui.get_ui_id())
		fx = iworld3d.fx3d(fx_file, 1, layer_id = ui.get_ui_id())
		model.posistion = math3d.vector(0.0, 0.0, 0.0)
		fx.position = math3d.vector(0.0, 20.0, 0.0)
		fx.restart()
		sce = ui.get_scene()
		camera = sce.get_camera()
		camera.set_placement(
			model.position + math3d.vector(0.0, 20.0, 45.0),
			math3d.vector(0, 0, -1),
			math3d.vector(0, 1, 0))
		# 设置完场景信息后,更新一下
		ui.update()
		return ui, model
예제 #13
0
	def on_mouse_dragging(self):
		if not self.is_dragging:
			return
		# 下落的时候也可以拖拽
		self.set_state(eggyolk2_const.PLAYER_STATE_MOVING)
		# 得到世界坐标
		p, d = iworld3d.screen_to_world(eggyolk2_const.SCENE_LAYER, 
			self.mouse_pos[0], self.mouse_pos[1])
		d.normalize()
		position = p + d * ((-100 - p.z) / d.z) # 实际应用中需保证射线足够长,且摄像机在屏幕后方
												# 此处为了保证射线在z轴方向的投影长度要大于100
												# 这里position.z近似等于-100
		pre_pos = self.pos
		pre_pos_v = math3d.vector(*pre_pos)
		# 计算长度
		d = position - pre_pos_v
		# 避免最后一次移动带来的抖动和对0向量规范化
		if d.length < 1:
			return
		d.normalize()
		p = pre_pos_v + d * 2
		# 每帧向鼠标位置移动单位向量的距离
		self.pos = p.x, p.y, p.z
		# 静态碰撞演示
		if self.anything_collision():
			self.pos = pre_pos
예제 #14
0
	def get_user_input(self, speed):
		dir = math3d.vector(0, 0, 0)
		# 前进
		if idemo_glb.API.is_press_key(game.VK_W):
			dir.z += 1.0
			if self.cur_state_idx == 0:
				self.cur_anim_idx = 1
		if idemo_glb.API.is_press_key(game.VK_S):
			dir.z -= 1.0
			if self.cur_state_idx == 0:
				self.cur_anim_idx = 2
		if idemo_glb.API.is_press_key(game.VK_A):
			dir.x -= 1.0
			if self.cur_state_idx == 0:
				self.cur_anim_idx = 1
		if idemo_glb.API.is_press_key(game.VK_D):
			dir.x += 1.0
			if self.cur_state_idx == 0:
				self.cur_anim_idx = 1
		if dir.is_zero:
			return dir
		if dir.z < 0:
			speed *= 0.5
		dir = self.camera.rotation_matrix.mulvec3x3(dir)
		dir.y = 0
		dir.normalize()
		dir *= speed
		return dir
예제 #15
0
	def update_collide_pos(self, fraction):
		cur_pos = math3d.vector(*self.pos)
		length = (cur_pos - self.target_pos).length
		moved = length * fraction
		if moved < eggyolk2_const.MARGIN:
			return
		cur_pos.intrp(cur_pos, self.target_pos, (moved - eggyolk2_const.MARGIN) / length)
		self.pos = cur_pos.x, cur_pos.y, cur_pos.z
예제 #16
0
	def __init__(self, scene):
		self.pre_anim_idx = 4
		self.cur_anim_idx = 4
		# 状态
		self.state = [
			self.update_moving,
			self.update_dropping,
			self.update_jumpping,
		]
		self.cur_state_idx = 1 # 初始态
		self.sce = scene
		self.avt_mgr = iworld3d.avatar_mgr()
		self.model = self.avt_mgr.create("me", idemo_glb.API.get_my_avatar())
		# 圆柱体
		size = self.model.bounding_box * model_scale
		self.col_obj = iphy3d.col_cylinder(size.x, size.y)
		self.col_obj.add_to_scene3d()
		self._pos = init_pos
		self.base_pos = math3d.vector(0, size.y, 0) #avt的基点在脚下
		self.pos = self._pos
		self.model.scale = (model_scale, model_scale, model_scale)
		self.model.anim_rate = 1.5 #速度播快一点
		self.camera = self.sce.get_camera()
		self.camera.set_placement(
			self.pos + math3d.vector(0.0, 45.0, 45.0),
			math3d.vector(0, -1, -1),
			math3d.vector(0, 1, 0))
		self.moving_dir = math3d.vector(0, 0, 0)
		self.jump_begin = math3d.vector(0, 0, 0) # 起跳位置
		self.target_pos = math3d.vector(0, 0, 0)
		self.up_ofs = None # 上提高度
		self.no_up_slide = False
		self.play_animation()
		self.is_debug_draw = False
예제 #17
0
	def manual_stop(self):
		if self._style == STYLE_FREELOOK:
			self._is_forward = False
			self._is_back = False
			self._is_left = False
			self._is_right = False
			self._is_up = False
			self._is_down = False
			self._velocity = math3d.vector(0, 0, 0)
예제 #18
0
	def on_key_msg(self, msg, key):
		super(demo, self).on_key_msg(msg, key)
		if msg == game.MSG_KEY_PRESSED:
			if key >= game.VK_NUM0 and key <= game.VK_NUM9:
				# 相机控制演示
				# 小键盘46表示相机沿x轴左右平移
				# 小键盘28表示相机沿y轴上下平移
				# 小键盘13表示相机沿z轴前后平移
				# 小键盘79表示相机沿y轴左右旋转
				# 小键盘5表示相机对准主角小蛋黄
				# 小键盘0表示相机恢复初始状态
				cam = iworld3d.get_camera(SCENE_LAYER)
				position = cam.position
				if key == game.VK_NUM4:
					position.x -= CAMERA_MOVE_STEP
				elif key == game.VK_NUM6:
					position.x += CAMERA_MOVE_STEP
				elif key == game.VK_NUM8:
					position.y -= CAMERA_MOVE_STEP
				elif key == game.VK_NUM2:
					position.y += CAMERA_MOVE_STEP
				elif key == game.VK_NUM1:
					position.z += CAMERA_MOVE_STEP
				elif key == game.VK_NUM3:
					position.z -= CAMERA_MOVE_STEP
				elif key == game.VK_NUM7:
					self.cam_rot -= 1
					cam.rotate_to_xyz(y=self.cam_rot*math.pi/200)
				elif key == game.VK_NUM9:
					self.cam_rot += 1
					cam.rotate_to_xyz(y=self.cam_rot*math.pi/200)
				elif key == game.VK_NUM5:
					cam.look_at(self.player.position)
				elif key == game.VK_NUM0:
					# 还原位置
					position = math3d.vector(0,0,0)
					forward = math3d.vector(0,0,-1)
					up = math3d.vector(0,-1,0)
					# 还原旋转矩阵
					# 演示rotation_matrix的用法
					cam.rotation_matrix = math3d.matrix.make_orient(forward, up)
					# 实际上此用法等同于这个接口
					#iworld3d.set_camera_placement(SCENE_LAYER, position, forward, up)
				cam.position = position
예제 #19
0
	def step_up(self):
		self.up_ofs = math3d.vector(0, g_climb_height, 0)
		self.target_pos = self.pos + self.up_ofs
		result = self.sweep_test(self.pos, self.target_pos)
		if not result.hit:
			self.pos = self.target_pos
			return
		temp = self.pos
		self.update_collide_pos(result.fraction)
		self.up_ofs = self.pos - temp
예제 #20
0
	def moving(self):
		if self.moving_dir.is_zero:
			return
		cur_pos = math3d.vector(*self.pos)
		self.target_pos = cur_pos + self.moving_dir
		result = self.sweep_test(cur_pos, self.target_pos)
		if not result.hit:
			self.pos = self.target_pos.x, self.target_pos.y, self.target_pos.z
			return
		self.update_collide_pos(result.fraction)
예제 #21
0
	def move(self):
		if self.moving_dir.is_zero:
			return
		self.model.rotation_matrix = math3d.matrix.make_orient(self.moving_dir,
			math3d.vector(0.0, 1.0, 0.0))
		self.target_pos = self.pos + self.moving_dir
		result = self.sweep_test(self.pos, self.target_pos)
		if not result.hit:
			# 可行
			self.pos = self.target_pos
		return result
예제 #22
0
	def step_down(self):
		# 正常来说,你让角色最大能跨的高度,取负就是它能踏下最大高度
		down = math3d.vector(0, g_climb_height, 0)
		self.target_pos = self.pos - self.up_ofs - down
		result = self.sweep_test(self.pos, self.target_pos)
		if not result.hit:
			self.pos = self.target_pos
			self.cur_state_idx = 1
			return result
		self.update_collide_pos(result.fraction)
		return result
예제 #23
0
	def logic(self):
		if self.player:
			self.camera.position = self.player.position-CAMERA_DISTANCE
			self.camera.look_at(self.player.position)
			
			# 主角位置设为场景自动加载的中心点
			self.scn.set_view_position(self.player.position)
			
			# 动态添加外围的场景
			x = int(self.player.position.x+200)/400
			y = int(self.player.position.z+200)/400
			if (abs(x)>=2 or abs(y)>=2) and (x, y) not in self.scene_pos:
				self.scene_pos[(x, y)] = 1
				self.scn.auto_load_scene(SCN_FILE%4, math3d.vector(x*400, 0, y*400))
예제 #24
0
	def __init__(self, camera):
		self._camera = camera
		self._target = None
		self._orbiting = False
		self._zooming = False
		self._topspeed = 2
		self._velocity = math3d.vector(0, 0, 0)
		self._is_forward = False
		self._is_back = False
		self._is_left = False
		self._is_right = False
		self._is_up = False
		self._is_down = False
		self._fast_move = False
		self._style = STYLE_FREELOOK
예제 #25
0
	def __init__(self):
		super(demo, self).__init__()
		iworld3d.init()
		self.scn = iworld3d.create_scene3d(SCN_FILE%1)
		
		self.player = iworld3d.model3d("idemos/res/eggyolk/world3d/xiaodanhuang.gim")
		self.player.pos = (0,0,0)
		
		self.camera = iworld3d.get_camera(iworld3d.NO_2D_LAYER)

		# 预先生成如下分块的场景,其中1为刚生成的self.scn
		# 323
		# 212
		# 323
		for offset in ((-1,0), (1,0), (0,-1), (0,1)):
			self.scn.auto_load_scene(SCN_FILE%2, math3d.vector(offset[0]*400, 0, offset[1]*400))
		for offset in ((1,1), (-1,1), (1,-1), (-1,-1)):
			self.scn.auto_load_scene(SCN_FILE%3, math3d.vector(offset[0]*400, 0, offset[1]*400))
		
		self.scn.set_view_range(100)
		# 如果设置1000,则一开始就能看到所有场景
		# self.scn.set_view_range(1000)

		self.scene_pos = {}	# 记录动态加载的场景位置
예제 #26
0
	def on_mouse_move(self):
		if not g_mouse_dragging:
			idemo_glb.API.show_sys_mouse(True)
			idemo_glb.API.lock_cursor_pos(False)
			return
		dx, dy = idemo_glb.API.lock_cursor_pos(True)
		prev_rotation = self.camera.rotation_matrix
		dis = (self.camera.position - self.pos).length
		self.camera.yaw(dx * g_pixel_to_angel, iworld3d.SPACE_TYPE_WORLD)
		self.camera.pitch(dy * g_pixel_to_angel)
		pos = self.pos - self.camera.rotation_matrix.forward * dis
		# 控制相机高度
		if pos.y < 2.0 or pos.y > 60.0:
			self.camera.rotation_matrix = prev_rotation
			return
		self.camera.set_placement(pos, self.camera.rotation_matrix.forward, math3d.vector(0, 1, 0))
예제 #27
0
	def flash_to_pos(self, screen_x, screen_y):
		# 得到世界坐标
		p, d = iworld3d.screen_to_world(eggyolk2_const.SCENE_LAYER, 
			screen_x, screen_y)
		d.normalize()
		position = p + d * ((-100 - p.z) / d.z) # 实际应用中需保证射线足够长,且摄像机在屏幕后方
												# 此处为了保证射线在z轴方向的投影长度要大于100
												# 这里position.z近似等于-100
		# 射线起点为摄像机的位置,终点为屏幕上物体所在层的位置
		if not self.is_ray_hit(math3d.vector(0, 0, 0), position):
			# 为了避免边缘的碰撞,再做一次static_test
			pre_pos = self.pos
			self.pos = position.x, position.y, position.z
			if self.anything_collision():
				self.pos = pre_pos
				return
			self.set_state(eggyolk2_const.PLAYER_STATE_DROPPING)
예제 #28
0
	def update_jumpping(self):
		up = math3d.vector(0, 2.0 * g_gravity, 0)
		self.moving_dir = self.get_user_input(g_jumpping_control_speed)
		self.moving_dir += up
		self.target_pos = self.pos + self.moving_dir
		result = self.sweep_test(self.pos, self.target_pos)
		if not result.hit:
			self.pos = self.target_pos
			if self.pos.y - self.jump_begin.y > g_max_jump_height:
				self.pos.y = self.jump_begin.y + g_max_jump_height
				self.cur_state_idx = 1
			self.pos = self.pos
			return
		self.update_collide_pos(result.fraction)
		if self.can_stand(self.pos, result.point, result.normal):
			self.cur_state_idx = 0
		else:
			self.cur_state_idx = 1
예제 #29
0
	def rand_init(self):
		x = random.random() * 50 * random.choice([-1, 1])
		y = random.random() * 40 * random.choice([-1, 1])
		z = (random.random() + 0.2) * -200
		self.obj.position = math3d.vector(x, y, z)
예제 #30
0
	def can_stand(self, pos, hit_point, normal):
		if pos.y - hit_point.y < g_climb_height:
			return False
		if normal.dot(math3d.vector(0.0, 1.0, 0.0)) < 0.5:
			return False
		return True