indexing description: "[ This is a simple track for the racing game. ]" date: "$Date$" revision: "$Revision$" class SIMPLE inherit EM_GL_SCENE redefine handle_key_down_event, initialize_scene end EM_TIME_SINGLETON export {NONE} all end GL_FUNCTIONS export {NONE} all end GLU_FUNCTIONS export {NONE} all end create make_scene feature -- Initialization initialize_scene is -- Initialize the scene local keyboard: EM_KEYBOARD do Precursor {EM_GL_SCENE} create keyboard.make_snapshot keyboard.enable_repeating_key_down_events (100, 10) -- Some OpenGL settings which aren't handled by EM_GL_SCENE gl_enable (Em_gl_texture_2d) gl_tex_parameteri (EM_GL_TEXTURE_2D, EM_GL_TEXTURE_MAG_FILTER, EM_GL_FASTEST) gl_tex_parameteri (EM_GL_TEXTURE_2D, EM_GL_TEXTURE_MIN_FILTER, EM_GL_FASTEST) gl_clear_color ( 1, 1, 1, 1 ) -- create the collision detector create collision_detector.make collision_detector.set_call_both (true) initialize_lights initialize_objects -- initialize camera vectors for 2D viewing camera_position.set (0, 4, -0.2) camera_target.set (0, 0, 0) -- set start time ticks_start := time.ticks end feature {NONE} -- Event handler handle_key_down_event (a_keyboard_event: EM_KEYBOARD_EVENT) is -- Handle keyboard events. local key: INTEGER do key := a_keyboard_event.key -- Return/Esc -> exit to menu if key = a_keyboard_event.sdlk_escape or key = a_keyboard_event.sdlk_return then set_next_scene (create {START}.make_scene) start_next_scene -- w -> forward elseif key = a_keyboard_event.sdlk_w then car.move_forward -- s -> backward elseif key = a_keyboard_event.sdlk_s then car.move_backward -- a -> left elseif key = a_keyboard_event.sdlk_a then car.turn_left -- d -> right elseif key = a_keyboard_event.sdlk_d then car.turn_right -- space -> switch perspective elseif key = a_keyboard_event.sdlk_space then view_3d := not view_3d end end draw is -- Draw scene. do position_camera -- update position of car car.update -- handle collisions collision_detector.check_for_collision -- draw car car.draw -- draw the world skybox.draw builds.draw target.draw -- update and draw the arrow arrow.update (car.origin, target.origin) arrow.draw end handle_target_reached is -- Handle the target reached case do set_next_scene (create {FINISHED}.make (time.ticks - ticks_start)) start_next_scene end feature {NONE} -- implementation initialize_lights is --- Initialize the lights local light0_diffuse: ARRAY[REAL] light0_pos: ARRAY[REAL] tmp: ANY do -- create and set light create light0_diffuse.make(0, 3) create light0_pos.make(0, 3) light0_diffuse.put (1, 0) light0_diffuse.put (1, 1) light0_diffuse.put (1, 2) light0_diffuse.put (1, 3) light0_pos.put (0, 0) light0_pos.put (-10, 1) light0_pos.put (0, 2) light0_pos.put (0, 3) tmp := light0_diffuse.to_c gl_lightiv (Em_gl_light0, Em_gl_ambient, $tmp) tmp := light0_pos.to_c gl_lightfv (Em_gl_light0, Em_gl_position, $tmp) gl_enable (Em_gl_lighting) gl_enable (Em_gl_light0) gl_shade_model (Em_gl_flat) end initialize_objects is -- Initialize the objects local tmp_obj: BUILDING build_fac: BUILDING_FACTORY -- The building factory skybox_fac: SKYBOX_FACTORY -- The skybox factory target_fac: TARGET_FACTORY -- The target factory do -- Create skybox create skybox_fac.make skybox := skybox_fac.create_skybox_object skybox.set_origin (-20,0,5) collision_detector.add (skybox) -- Create buildings create builds.make_specified (2, 8, 2) create build_fac.make tmp_obj := build_fac.create_building_object tmp_obj.set_origin (-10, 0, 0) builds.extend (tmp_obj) collision_detector.add (tmp_obj) tmp_obj := build_fac.create_building_object tmp_obj.set_origin (10, 0, 0) builds.extend (tmp_obj) collision_detector.add (tmp_obj) tmp_obj := build_fac.create_building_object tmp_obj.set_origin (0, 0, -20) builds.extend (tmp_obj) collision_detector.add (tmp_obj) tmp_obj := build_fac.create_building_object tmp_obj.set_origin (-10, 0, -20) builds.extend (tmp_obj) collision_detector.add (tmp_obj) tmp_obj := build_fac.create_building_object tmp_obj.set_origin (10, 0, -20) builds.extend (tmp_obj) collision_detector.add (tmp_obj) tmp_obj := build_fac.create_building_object tmp_obj.set_origin (0, 0, -30) builds.extend (tmp_obj) collision_detector.add (tmp_obj) tmp_obj := build_fac.create_building_object tmp_obj.set_origin (-15, 0, -30) builds.extend (tmp_obj) collision_detector.add (tmp_obj) tmp_obj := build_fac.create_building_object tmp_obj.set_origin (10, 0, 5) builds.extend (tmp_obj) collision_detector.add (tmp_obj) tmp_obj := build_fac.create_building_object tmp_obj.set_origin (35, 0, -42) builds.extend (tmp_obj) collision_detector.add (tmp_obj) tmp_obj := build_fac.create_building_object tmp_obj.set_origin (-6, 0, -42) builds.extend (tmp_obj) collision_detector.add (tmp_obj) tmp_obj := build_fac.create_building_object tmp_obj.set_origin (16, 0, -17) builds.extend (tmp_obj) collision_detector.add (tmp_obj) tmp_obj := build_fac.create_building_object tmp_obj.set_origin (26, 0, -14) builds.extend (tmp_obj) collision_detector.add (tmp_obj) tmp_obj := build_fac.create_building_object tmp_obj.set_origin (38, 0, -12) builds.extend (tmp_obj) collision_detector.add (tmp_obj) tmp_obj := build_fac.create_building_object tmp_obj.set_origin (31, 0, -31) builds.extend (tmp_obj) collision_detector.add (tmp_obj) tmp_obj := build_fac.create_building_object tmp_obj.set_origin (18, 0, -33) builds.extend (tmp_obj) collision_detector.add (tmp_obj) tmp_obj := build_fac.create_building_object tmp_obj.set_origin (15, 0, -43) builds.extend (tmp_obj) collision_detector.add (tmp_obj) tmp_obj := build_fac.create_building_object tmp_obj.set_origin (5, 0, -46) builds.extend (tmp_obj) collision_detector.add (tmp_obj) -- Create target create target_fac.make target := target_fac.create_target_object target.set_origin (20, 0, 2) target.register_target_reached (agent handle_target_reached) collision_detector.add (target) -- Create arrow create arrow.make -- Create car create car.make car.set_origin (-13, 0, -68 ) collision_detector.add (car) end last_time: INTEGER -- Time for camera speed relative to frame rate position_camera is -- Position the camera and perspective local time_diff: REAL do -- didn't we already switch to 3d mode and the interval is reached? if not go_3d and time.ticks - ticks_start > 2000 then view_3d := true go_3d := true end -- Calculate `time_diff' for speed relative to frame rate (for morphing). time_diff := time.ticks - last_time last_time := time.ticks if time_diff < 0 then time_diff := 0 end time_diff := time_diff / 10 -- morph if necessary if view_3d and camera_position.y > 2 then camera_position.inc_y (-0.004 * time_diff) camera_position.inc_z (-0.0096 * time_diff) camera_target.inc_x (0.002 * time_diff) camera_target.inc_y (0.002 * time_diff) elseif not view_3d and camera_position.y < 4 then camera_position.inc_y (+0.004 * time_diff) camera_position.inc_z (+0.0096 * time_diff) camera_target.inc_x (-0.002 * time_diff) camera_target.inc_y (-0.002 * time_diff) end glu_look_at ( camera_position.x, camera_position.y, camera_position.z, camera_target.x, camera_target.y, camera_target.z, 0, 1, 0 ) -- rotate/move the camera gl_rotatef(-car.angle, 0, 1, 0) gl_translatef (-car.origin.x, -car.origin.y, -car.origin.z) end builds: EM_3D_OBJECT_CONTAINER [EM_3D_OBJECT] -- The buildings of the city skybox: SKYBOX -- The skybox target: TARGET -- The target arrow: ARROW -- The arrow to the target car: CAR -- The car view_3d: BOOLEAN -- Should we use the 3d view mode or a 2d like mode? go_3d: BOOLEAN -- Did we already switch to 3d mode? width: INTEGER is 1024 -- The width of the scene height: INTEGER is 768 -- The height of the scene collision_detector: EM_COLLISION_DETECTOR_3D -- The collision detector camera_position: EM_3D_VECT -- The camera position, used for morphing the two viewing positions camera_target: EM_3D_VECT -- The target, the camera looks at, used for morphing the two viewing positions ticks_start: INTEGER -- The ticks count when we started, used to compute the time to the target end