SuperTux: jump helper

This commit is contained in:
pelya
2014-11-09 02:04:25 +02:00
parent 9a5a6890d4
commit 1c9076f222

View File

@@ -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 <algorithm>
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