From 1c9076f2224e3a1c1ef024cec71dcf0883bcedef Mon Sep 17 00:00:00 2001 From: pelya Date: Sun, 9 Nov 2014 02:04:25 +0200 Subject: [PATCH] SuperTux: jump helper --- project/jni/application/supertux/android.diff | 298 +++++++++++++++++- 1 file changed, 292 insertions(+), 6 deletions(-) diff --git a/project/jni/application/supertux/android.diff b/project/jni/application/supertux/android.diff index b03b8782d..10f562963 100644 --- a/project/jni/application/supertux/android.diff +++ b/project/jni/application/supertux/android.diff @@ -13,6 +13,87 @@ index 9a9dde2..c7e2aad 100644 FILE(GLOB TINYGETTEXT_SOURCES_CXX RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} external/tinygettext/src/*.cpp) SET_SOURCE_FILES_PROPERTIES(${TINYGETTEXT_SOURCES_CXX} PROPERTIES COMPILE_DEFINITIONS HAVE_SDL) +diff --git a/configure b/configure +index b728243..75a4bb4 100755 +--- a/configure ++++ b/configure +@@ -6,4 +6,4 @@ set -e + mkdir -p build + cd build + cmake .. "$@" +- ++make -j8 +diff --git a/src/control/controller.cpp b/src/control/controller.cpp +index 49996e2..8b4d13c 100644 +--- a/src/control/controller.cpp ++++ b/src/control/controller.cpp +@@ -16,6 +16,9 @@ + + #include "control/controller.hpp" + ++#include "video/renderer.hpp" ++#include "video/video_system.hpp" ++ + const char* Controller::controlNames[] = { + "left", + "right", +@@ -84,4 +87,23 @@ Controller::update() + oldControls[i] = controls[i]; + } + ++bool ++Controller::mouse_pressed() const ++{ ++ return mousePressed; ++} ++ ++Vector ++Controller::mouse_pos() const ++{ ++ return mousePos; ++} ++ ++void ++Controller::set_mouse(int x, int y, bool pressed) ++{ ++ mousePressed = pressed; ++ mousePos = VideoSystem::current()->get_renderer().to_logical(x, y); ++} ++ + /* EOF */ +diff --git a/src/control/controller.hpp b/src/control/controller.hpp +index 210159d..eba103a 100644 +--- a/src/control/controller.hpp ++++ b/src/control/controller.hpp +@@ -17,6 +17,8 @@ + #ifndef HEADER_SUPERTUX_CONTROL_CONTROLLER_HPP + #define HEADER_SUPERTUX_CONTROL_CONTROLLER_HPP + ++#include "math/vector.hpp" ++ + class Controller + { + public: +@@ -58,6 +60,10 @@ public: + /** returns true if the control has just been released this frame */ + bool released(Control control) const; + ++ bool mouse_pressed() const; ++ Vector mouse_pos() const; ++ void set_mouse(int x, int y, bool pressed); ++ + virtual void reset(); + virtual void update(); + +@@ -66,6 +72,8 @@ protected: + bool controls[CONTROLCOUNT]; + /** control status at last frame */ + bool oldControls[CONTROLCOUNT]; ++ bool mousePressed; ++ Vector mousePos; + }; + + #endif diff --git a/src/control/game_controller_manager.cpp b/src/control/game_controller_manager.cpp index 6680c04..401eacc 100644 --- a/src/control/game_controller_manager.cpp @@ -26,7 +107,7 @@ index 6680c04..401eacc 100644 #include diff --git a/src/control/input_manager.cpp b/src/control/input_manager.cpp -index ce612d4..2be2fd5 100644 +index ce612d4..2ab1d85 100644 --- a/src/control/input_manager.cpp +++ b/src/control/input_manager.cpp @@ -19,8 +19,8 @@ @@ -53,7 +134,7 @@ index ce612d4..2be2fd5 100644 { } -@@ -71,15 +71,16 @@ void +@@ -71,15 +71,25 @@ void InputManager::process_event(const SDL_Event& event) { switch(event.type) { @@ -69,11 +150,20 @@ index ce612d4..2be2fd5 100644 keyboard_manager->process_key_event(event.key); break; ++ case SDL_MOUSEBUTTONDOWN: ++ case SDL_MOUSEBUTTONUP: ++ keyboard_manager->process_mouse_event(event.button); ++ break; ++ ++ case SDL_MOUSEMOTION: ++ keyboard_manager->process_mouse_event(event.motion); ++ break; ++ +#if 0 case SDL_JOYAXISMOTION: if (!m_use_game_controller) joystick_manager->process_axis_event(event.jaxis); break; -@@ -126,7 +127,7 @@ InputManager::process_event(const SDL_Event& event) +@@ -126,7 +136,7 @@ InputManager::process_event(const SDL_Event& event) case SDL_CONTROLLERDEVICEREMAPPED: log_debug << "SDL_CONTROLLERDEVICEREMAPPED" << std::endl; break; @@ -111,7 +201,7 @@ index e848067..fe1b785 100644 { public: diff --git a/src/control/keyboard_manager.cpp b/src/control/keyboard_manager.cpp -index ca4e461..dd1908c 100644 +index ca4e461..cf67877 100644 --- a/src/control/keyboard_manager.cpp +++ b/src/control/keyboard_manager.cpp @@ -18,7 +18,7 @@ @@ -155,11 +245,30 @@ index ca4e461..dd1908c 100644 Controller::Control control; /* we use default keys when the menu is open (to avoid problems when +@@ -209,4 +213,18 @@ KeyboardManager::bind_next_event_to(Controller::Control id) + wait_for_key = id; + } + ++void ++KeyboardManager::process_mouse_event(const SDL_MouseMotionEvent& event) ++{ ++ m_parent->get_controller()->set_mouse(event.x, event.y, event.state & SDL_BUTTON_LMASK); ++} ++ ++void ++KeyboardManager::process_mouse_event(const SDL_MouseButtonEvent& event) ++{ ++ if (event.button != SDL_BUTTON_LEFT) ++ return; ++ m_parent->get_controller()->set_mouse(event.x, event.y, event.state == SDL_PRESSED); ++} ++ + /* EOF */ diff --git a/src/control/keyboard_manager.hpp b/src/control/keyboard_manager.hpp -index 07885f9..aae6da9 100644 +index 07885f9..ae02e33 100644 --- a/src/control/keyboard_manager.hpp +++ b/src/control/keyboard_manager.hpp -@@ -41,7 +41,7 @@ public: +@@ -41,10 +41,13 @@ public: ~KeyboardManager(); void process_key_event(const SDL_KeyboardEvent& event); @@ -168,6 +277,12 @@ index 07885f9..aae6da9 100644 void process_console_key_event(const SDL_KeyboardEvent& event); void process_menu_key_event(const SDL_KeyboardEvent& event); ++ void process_mouse_event(const SDL_MouseMotionEvent& event); ++ void process_mouse_event(const SDL_MouseButtonEvent& event); ++ + void bind_next_event_to(Controller::Control id); + + private: diff --git a/src/gui/dialog.cpp b/src/gui/dialog.cpp index e536c9c..55602c0 100644 --- a/src/gui/dialog.cpp @@ -196,6 +311,177 @@ index fd253e9..adc20ce 100644 } const MenuItem& +diff --git a/src/object/player.cpp b/src/object/player.cpp +index c2bfb0e..897fa20 100644 +--- a/src/object/player.cpp ++++ b/src/object/player.cpp +@@ -148,6 +148,7 @@ Player::Player(PlayerStatus* _player_status, const std::string& name_) : + grabbed_object(NULL), + sprite(), + airarrow(), ++ jumparrow(), + floor_normal(), + ghost_mode(false), + edit_mode(false), +@@ -164,6 +165,7 @@ Player::Player(PlayerStatus* _player_status, const std::string& name_) : + // constructor + sprite = SpriteManager::current()->create("images/creatures/tux/tux.sprite"); + airarrow = Surface::create("images/engine/hud/airarrow.png"); ++ jumparrow = Surface::create("images/engine/menu/scroll-down.png"); + idle_timer.start(IDLE_TIME[0]/1000.0f); + + SoundManager::current()->preload("sounds/bigjump.wav"); +@@ -223,6 +225,12 @@ Player::init() + + climbing = 0; + ++ jump_helper = false; ++ jump_helper_draw = false; ++ jump_helper_jump = false; ++ jump_helper_move_left = false; ++ jump_helper_move_right = false; ++ + physic.reset(); + } + +@@ -494,12 +502,14 @@ Player::handle_horizontal_input() + + float dirsign = 0; + if(!duck || physic.get_velocity_y() != 0) { +- if(controller->hold(Controller::LEFT) && !controller->hold(Controller::RIGHT)) { ++ if((controller->hold(Controller::LEFT) && !controller->hold(Controller::RIGHT)) ++ || jump_helper_move_left) { + old_dir = dir; + dir = LEFT; + dirsign = -1; +- } else if(!controller->hold(Controller::LEFT) +- && controller->hold(Controller::RIGHT)) { ++ } else if((!controller->hold(Controller::LEFT) ++ && controller->hold(Controller::RIGHT)) ++ || jump_helper_move_right) { + old_dir = dir; + dir = RIGHT; + dirsign = 1; +@@ -691,7 +701,7 @@ Player::handle_vertical_input() + { + // Press jump key + if(controller->pressed(Controller::JUMP)) jump_button_timer.start(JUMP_GRACE_TIME); +- if(controller->hold(Controller::JUMP) && jump_button_timer.started() && can_jump) { ++ if (((controller->hold(Controller::JUMP) && jump_button_timer.started()) || jump_helper_jump) && can_jump) { + jump_button_timer.stop(); + if (duck) { + // when running, only jump a little bit; else do a backflip +@@ -711,7 +721,7 @@ Player::handle_vertical_input() + } + } + // Let go of jump key +- else if(!controller->hold(Controller::JUMP)) { ++ else if(!(controller->hold(Controller::JUMP) || jump_helper_jump)) { + if (!backflipping && jumping && physic.get_velocity_y() < 0) { + jumping = false; + early_jump_apex(); +@@ -789,6 +799,8 @@ Player::handle_input() + /* Handle vertical movement: */ + handle_vertical_input(); + ++ handle_jump_helper(); ++ + /* Shoot! */ + if (controller->pressed(Controller::ACTION) && (player_status->bonus == FIRE_BONUS || player_status->bonus == ICE_BONUS)) { + if(Sector::current()->add_bullet( +@@ -1068,6 +1080,13 @@ Player::draw(DrawingContext& context) + context.draw_surface(airarrow, Vector(px, py), LAYER_HUD - 1); + } + ++ // Show where Tux will land after using jump helper ++ if (jump_helper_draw && Sector::current() && Sector::current()->camera) { ++ float px = jump_helper_x + (get_bbox().p2.x - get_bbox().p1.x) / 2 - jumparrow.get()->get_width() / 2; ++ float py = get_bbox().p1.y; ++ context.draw_surface(jumparrow, Vector(px, py), LAYER_HUD - 1); ++ } ++ + std::string sa_prefix = ""; + std::string sa_postfix = ""; + +@@ -1582,4 +1601,50 @@ Player::handle_input_climbing() + physic.set_acceleration(0, 0); + } + ++void ++Player::handle_jump_helper() ++{ ++ if (!Sector::current() || !Sector::current()->camera) ++ return; ++ ++ if (controller->mouse_pressed() && can_jump && !jump_helper) ++ { // Select a target to jump ++ jump_helper_draw = true; ++ jump_helper_x = controller->mouse_pos().x + Sector::current()->camera->get_translation().x; ++ } ++ ++ if (!controller->mouse_pressed() && can_jump && !jump_helper && jump_helper_draw) ++ { // Initiate the jump ++ jump_helper = true; ++ jump_helper_x = controller->mouse_pos().x + Sector::current()->camera->get_translation().x; ++ // Do not use scriptiong controller - we need to be able to cancel jump helper mid-jump ++ jump_helper_move_left = false; ++ jump_helper_move_right = false; ++ if (jump_helper_x > get_pos().x) ++ jump_helper_move_right = true; ++ else ++ jump_helper_move_left = true; ++ jump_helper_jump = true; ++ } ++ ++ if (jump_helper) ++ { ++ float friction = WALK_ACCELERATION_X * (on_ice ? ICE_FRICTION_MULTIPLIER : NORMAL_FRICTION_MULTIPLIER); ++ float frictionDistance = physic.get_velocity_x() * physic.get_velocity_x() / friction / 2.0f; ++ if (controller->mouse_pressed() // Cancel a jump if user presses any button ++ || controller->hold(Controller::JUMP) || controller->hold(Controller::ACTION) ++ || controller->hold(Controller::DOWN) || controller->hold(Controller::UP) ++ || controller->hold(Controller::LEFT) || controller->hold(Controller::RIGHT) ++ || (jump_helper_x >= get_pos().x - frictionDistance && jump_helper_move_left) // Reached destination - finish the jump ++ || (jump_helper_x <= get_pos().x + frictionDistance && jump_helper_move_right)) ++ { ++ jump_helper = false; ++ jump_helper_draw = false; ++ jump_helper_jump = false; ++ jump_helper_move_left = false; ++ jump_helper_move_right = false; ++ } ++ } ++} ++ + /* EOF */ +diff --git a/src/object/player.hpp b/src/object/player.hpp +index 3dda1fd..7e57676 100644 +--- a/src/object/player.hpp ++++ b/src/object/player.hpp +@@ -244,6 +244,7 @@ private: + + void handle_horizontal_input(); + void handle_vertical_input(); ++ void handle_jump_helper(); + + void activate(); + void deactivate(); +@@ -314,6 +315,15 @@ public: + + SurfacePtr airarrow; /**< arrow indicating Tux' position when he's above the camera */ + ++ ++ SurfacePtr jumparrow; /**< arrow indicating wherer Tux' will jump */ ++ bool jump_helper; /**< Jump helper for touchscreens to perform precise jumps */ ++ bool jump_helper_jump; ++ bool jump_helper_move_left; ++ bool jump_helper_move_right; ++ bool jump_helper_draw; ++ float jump_helper_x; ++ + Vector floor_normal; + void position_grabbed_object(); + void try_grab(); diff --git a/src/physfs/physfs_sdl.cpp b/src/physfs/physfs_sdl.cpp index 277f993..356dae0 100644 --- a/src/physfs/physfs_sdl.cpp