indexing description: "[ This class describes a car ]" date: "$Date$" revision: "$Revision$" "This class describes a car" date: "$Date$" revision: "$Revision$" class CAR inherit EM_3D_SPHERE_COLLIDABLE EM_3D_OBJECT EM_TIME_SINGLETON export {NONE} all end DOUBLE_MATH export {NONE} all end create make feature {NONE} -- Initialization make is -- Create car local obj_loader: EM_3D_OBJ_LOADER -- The obj loader do create obj_loader.make obj_loader.load_file ("objects/car1.obj") obj_loader.set_color (1, 0, 0, 1) model := obj_loader.create_object scale.set(1,1,1) width := model.width height := model.height depth := model.depth set_scale (0.2, 0.2, 0.2) end feature -- Commands turn_left is -- Turn left do if speed >= 0 then angle := angle - steerspeed else angle := angle + steerspeed end if angle < 0 then angle := angle + 360 elseif angle >= 360 then angle := angle - 360 end end turn_right is -- Turn right do if speed >= 0 then angle := angle + steerspeed else angle := angle - steerspeed end if angle < 0 then angle := angle + 360 elseif angle >= 360 then angle := angle - 360 end end move_forward is -- Increase speed forward/decrease speed backward do if speed > -speed_forward then speed := speed - speedup end end move_backward is -- Decrease speed forward/increase speed backward do if speed < speed_backward then speed := speed + speedup end end update is -- Update the car do -- Compute time difference and update last_time time_diff := time.ticks - last_time last_time := time.ticks update_origin set_rotation (0, angle, 0) end feature -- Status speed: DOUBLE -- Speed of the movement angle: DOUBLE -- The current angle to the world direction: EM_3D_VECT is -- The direction of the car local length: DOUBLE do if (angle >= 0 and angle < 45) or (angle >= 315 and angle <= 360) then result.set (-tangent(angle/360*2*pi), 0, -1) elseif (angle >= 45 and angle < 135) then result.set (-1, 0, tangent((angle-90)/360*2*pi)) elseif (angle >= 135 and angle < 225) then result.set (tangent(angle/360*2*pi), 0, 1) elseif (angle >= 225 and angle < 315) then result.set (1, 0, -tangent((angle-270)/360*2*pi)) end -- normalize length := result.length result.set (result.x/length, result.y/length, result.z/length) end type_id: INTEGER is 1 -- The id given to all instances of `current' generating class feature -- Car informations speed_forward: DOUBLE is 0.02 speed_backward: DOUBLE is 0.005 speedup: DOUBLE is 0.0005 steerspeed: DOUBLE is 0.8 feature -- Collision detection bounding_sphere_center: EM_3D_VECT is -- Center of the bounding sphere do --TODO improve result.set (direction.x*0.5*width, 0, direction.z*0.5*depth) result := origin + result end bounding_sphere_radius: DOUBLE is -- Radius of the bounding sphere do result := width.max (height) result := result.max (depth) result := result / 2 end feature {NONE} -- Implementation model: EM_3D_OBJECT -- The car model last_time: INTEGER -- The last time where we updated the car time_diff: INTEGER -- Time since the last update old_location: EM_3D_VECT -- The location we had before, used for collision handling update_origin is -- Update the origin do old_location := origin origin := origin + (direction * speed * (time_diff / 10)) end feature {EM_3D_OBJECT} -- Implementation of the 3d object draw_object is do model.draw_object end feature {EM_COLLISION_DETECTOR_3D} -- Implementation of collision detection on_collide (other: EM_COLLIDABLE_3D) is -- `current' collided with `other' do -- go back to old position and stop car speed := 0 origin := old_location end invariant angle_in_range: angle >= 0 and angle <= 360 speed_in_range: speed >= -speed_backward and speed <= speed_forward end