indexing description: "[ Hunting scene. ]" date: "$Date$" revision: "$Revision$" class HUNT_SCENE inherit EM_GOOF_LEVEL_SCENE redefine handle_key_down_event, handle_key_up_event, redraw end DOUBLE_MATH undefine default_create end EM_BITMAP_FACTORY rename make as make_bitmap_factory undefine default_create end create make_hunt feature -- Initialization make_hunt(level_file: STRING a_min_size, a_range: INTEGER) is -- Make 'current' local rnd1, rnd2: DOUBLE gravity: EM_GOOF_DIRECTIONAL_GRAVITY -- Gravity force gravity_direction: EM_VECTOR_2D -- Gravity force direction gun_image: EM_BITMAP do -- Make bitmap factory make_bitmap_factory -- Load level make(level_file) -- Set difficulty values min_size := a_min_size range := a_range -- Create font create font.make_from_ttf_file("../../../resource/font/ttf/bitstream/vera.ttf", 20) -- Make calculation task label create label_task.make("test1", font) label_task.set_x(10) label_task.set_y(740) main_container.extend(label_task) -- Make points label create label_points.make("test2", font) label_points.set_x(900) label_points.set_y(740) main_container.extend(label_points) -- Make powder label create label_powder.make("test2", font) label_powder.set_x(500) label_powder.set_y(740) main_container.extend(label_powder) -- Stop physics physics.set_speed(0) -- Make random create random.make random.set_seed(time.ticks) random.forth -- Create gravity rnd1 := random.double_item random.forth rnd2 := random.double_item random.forth create gravity_direction.make(rnd1*0.02-0.01,0.1+0.01*rnd2) create gravity.make(gravity_direction) physics.add_force(gravity) -- Create player create_bitmap_from_image("./images/ball.png") check bitmap_exists: last_bitmap /= void end create player.make(last_bitmap, 512, 720, physics) physics.add_object(player) -- Create player's gun create_bitmap_from_image("images/gun.png") check last_bitmap /= void end gun_image := last_bitmap -- create gun.make_multiple_picture(gun_images, 0, 0, physics) create gun.make(gun_image, 0, 0, physics) player.add_item(gun) powder := 10 label_powder.set_value(get_powder_string) -- Create first calculation task create_calculation(30) end feature -- Drawing redraw is -- Redraw scene do gun.set_arc(gun.arc+0.05*gun_rotation) Precursor{EM_GOOF_LEVEL_SCENE} end feature -- Properties font: EM_TTF_FONT -- Font for drawing label_task: EM_STRING -- Displays task calculation label_points: EM_STRING -- Display player's points label_powder: EM_STRING -- Display player's points random: RANDOM -- Random number generator task_string: STRING -- Calculation task string player: PLAYER_VEHICLE -- Player's vehicle gun: EM_GOOF_ROTATABLE -- Player's gun gun_rotation: DOUBLE -- How to rotate the gun powder: DOUBLE -- How much powder to load? points: INTEGER -- How many points? min_size: INTEGER -- Minimum size for number in calculations range: INTEGER -- Range for numbers in calculations feature -- Action get_powder_string: STRING is -- Get descriptive powder string require enough_powder: powder >= 8 not_too_much_powder: powder <= 16 do if powder = 8 then result := "not really any powder" elseif powder = 9 then result := "a pinch of powder" elseif powder = 10 then result := "some powder" elseif powder = 11 then result := "a bit more powder" elseif powder = 12 then result := "quite some powder" elseif powder = 13 then result := "much powder" elseif powder = 14 then result := "even more powder" elseif powder = 15 then result := "powder! more powder!" elseif powder = 16 then result := "THE BIG BANG!" end end create_calculation(result_count: INTEGER) is -- Create taks local counter, operation: INTEGER operation_string: STRING -- Operation string representation (+,-,*,/) operand_1, operand_2, operation_result: INTEGER -- Operands and result rnd1: DOUBLE -- Random values fake_result: INTEGER -- Fake result do -- Choose Operation operation := (random.double_item * 4).rounded if operation = 0 then operation := 4 end random.forth -- Make operation parameters if operation = 1 then -- Addition operation_string := "+" operand_1 := (random.double_item * range).rounded + min_size random.forth operand_2 := (random.double_item * range).rounded + min_size random.forth operation_result := operand_1 + operand_2 elseif operation = 2 then -- Subtraction operation_string := "-" operand_1 := (random.double_item * range).rounded + min_size random.forth operand_2 := (random.double_item * range).rounded + min_size random.forth operation_result := operand_1 - operand_2 elseif operation = 3 then -- Multiplication operation_string := "*" from operation_result := range + min_size + 1 until operation_result <= range + min_size loop operand_1 := (random.double_item * sqrt(range)).rounded + min_size random.forth operand_2 := (random.double_item * sqrt(range)).rounded + min_size random.forth operation_result := operand_1 * operand_2 end elseif operation = 4 then -- Division operation_string := "/" operation_result := (random.double_item * sqrt(range)).rounded + min_size random.forth operand_2 := (random.double_item * sqrt(range)).rounded + min_size random.forth operand_1 := operand_2 * operation_result end -- Create task string task_string := operand_1.out + " " + operation_string + " " + operand_2.out + " =" -- Display task string label_task.set_value(task_string) -- Display player's points label_points.set_value("Points: " + points.out) -- Create operation result create_ball(operation_result,true) -- Create fake results from counter := 1 until counter > result_count loop from fake_result := operation_result until operation_result /= fake_result loop rnd1 := random.double_item random.forth fake_result := (rnd1 * range).rounded + min_size end create_ball(fake_result,false) counter := counter + 1 end end create_ball(number: INTEGER is_correct: BOOLEAN) is -- Create ball with 'number' local result_object: RESULT_OBJECT rnd1,rnd3,rnd4: DOUBLE do create_bitmap_from_image("./images/crate.png") check bitmap_exists: last_bitmap /= void end rnd1 := random.double_item random.forth rnd3 := random.double_item random.forth rnd4 := random.double_item random.forth create result_object.make_result(last_bitmap, (rnd1 * 768 + 128).rounded, (rnd3*80).rounded, physics, number, is_correct, agent add_points) result_object.set_friction(1+rnd4) physics.add_object(result_object) result_object.update_collidable(physics.collision_detector, true) end fire_shell is -- Fire a shell local shell: SHELL do create_bitmap_from_image("./images/shell.png") check bitmap_exists: last_bitmap /= void end create shell.make (last_bitmap, player.position.x, player.position.y, physics) shell.movement.set_x(sine(gun.arc)*powder) shell.movement.set_y(cosine(gun.arc)*powder) shell.set_arc(gun.arc+Pi) physics.add_object(shell) shell.update_collidable(physics.collision_detector, true) end add_points(some_points: INTEGER) is -- Add some points do points := points + some_points label_points.set_value("Points: " + points.out) if some_points = 10 then create_calculation(30) elseif some_points = -5 then create_calculation(30) end end feature {NONE} -- Event handlers handle_key_down_event (a_keyboard_event: EM_KEYBOARD_EVENT) is -- Handle key down event. do if a_keyboard_event.key = a_keyboard_event.sdlk_d then -- Move player right player.movement.set_x(player.movement.x+5) elseif a_keyboard_event.key = a_keyboard_event.sdlk_a then -- Move player left player.movement.set_x(player.movement.x-5) elseif a_keyboard_event.key = a_keyboard_event.sdlk_e then -- Rotate gun gun_rotation := gun_rotation - 1 elseif a_keyboard_event.key = a_keyboard_event.sdlk_q then -- Rotate gun gun_rotation := gun_rotation + 1 elseif a_keyboard_event.key = a_keyboard_event.sdlk_w then -- Use more powder if powder < 16 then powder := powder + 1 label_powder.set_value(get_powder_string) end elseif a_keyboard_event.key = a_keyboard_event.sdlk_s then -- Use less powder if powder > 8 then powder := powder - 1 label_powder.set_value(get_powder_string) end elseif a_keyboard_event.key = a_keyboard_event.sdlk_x then -- Fire gun fire_shell elseif a_keyboard_event.key = a_keyboard_event.sdlk_home then -- Begin physics physics.set_speed(50) elseif a_keyboard_event.key = a_keyboard_event.sdlk_escape then event_loop.stop end end handle_key_up_event (a_keyboard_event: EM_KEYBOARD_EVENT) is -- Handle key up event. do if a_keyboard_event.key = a_keyboard_event.sdlk_d then player.movement.set_x(player.movement.x-5) elseif a_keyboard_event.key = a_keyboard_event.sdlk_a then player.movement.set_x(player.movement.x+5) elseif a_keyboard_event.key = a_keyboard_event.sdlk_e then gun_rotation := gun_rotation + 1 elseif a_keyboard_event.key = a_keyboard_event.sdlk_q then gun_rotation := gun_rotation - 1 end end end