1 /*
2  * Copyright (C) 2006-2019 Christopho, Solarus - http://www.solarus-games.org
3  *
4  * Solarus is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * Solarus is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 #ifndef SOLARUS_STRAIGHT_MOVEMENT_H
18 #define SOLARUS_STRAIGHT_MOVEMENT_H
19 
20 #include "solarus/core/Common.h"
21 #include "solarus/core/Point.h"
22 #include "solarus/movements/Movement.h"
23 #include <cstdint>
24 #include <string>
25 
26 namespace Solarus {
27 
28 /**
29  * \brief A straight movement represented as a speed vector
30  * whose properties (speed and angle) can be changed.
31  */
32 class StraightMovement: public Movement {
33 
34   public:
35 
36     StraightMovement(bool ignore_obstacles, bool smooth);
37 
38     void notify_object_controlled() override;
39     void update() override;
40     void set_suspended(bool suspended) override;
41     bool has_to_move_now() const;
42 
43     // speed vector
44     double get_x_speed() const;
45     double get_y_speed() const;
46     double get_speed() const;
47     void set_dim_speed(uint32_t& delay,
48                        uint32_t& next_move_date,
49                        double &current_speed,
50                        int& move,
51                        double target_speed,
52                        double keep_factor);
53     void set_x_speed(double x_speed, double keep_factor = 0);
54     void set_y_speed(double y_speed, double keep_factor = 0);
55     void set_speed(double speed);
56     double get_angle() const override;
57     void set_angle(double angle);
58     int get_max_distance() const;
59     void set_max_distance(int max_distance);
60     bool is_smooth() const;
61     void set_smooth(bool smooth);
62     int get_displayed_direction4() const override;
63 
64     // movement
65     virtual bool is_started() const override;
66     virtual bool is_finished() const override;
67     void set_finished();
68     virtual void stop() override;
69 
70     const std::string& get_lua_type_name() const override;
71 
72   protected:
73 
74     void set_next_move_date(uint32_t& current_next_move_date, uint32_t next_move_date);
75 
76     void update_smooth_xy();
77     void update_smooth_x();
78     void update_smooth_y();
79 
80     void update_non_smooth_xy();
81 
82   private:
83 
84     // speed vector
85     double angle;                /**< angle between the speed vector and the horizontal axis in radians */
86     double x_speed;              /**< X speed of the object to move in pixels per second.
87                                   * 0: stopped
88                                   * positive value: moving to the right
89                                   * negative value: moving to the left */
90     double y_speed;              /**< Y speed of the object to move in pixels per second.
91                                   * 0: stopped
92                                   * positive value: moving downwards
93                                   * negative value: moving upwards */
94 
95     uint32_t next_move_date_x;   /**< Date of the next x move in ticks. */
96     uint32_t next_move_date_y;   /**< Date of the next y move in ticks. */
97 
98     // the following fields are redundant and can be computed from x_speed and y_speed
99     uint32_t x_delay;            /**< Delay in ticks between an x move of 1 pixel.
100                                   * x_delay = 200 / |x_speed| */
101     uint32_t y_delay;            /**< Delay in ticks between an y move of 1 pixel.
102                                   * y_delay = 200 / |y_speed| */
103     int x_move;                  /**< Number of pixels of the next x move : 0, 1 or -1. */
104     int y_move;                  /**< Number of pixels of the next y move : 0, 1 or -1. */
105 
106     Point initial_xy;            /**< Initial position used for the max distance check
107                                   * (reset whenever the movement changes changes) */
108     int max_distance;            /**< After this distance in pixels from the initial position,
109                                   * or when an obstacle is reached, the movement will stop
110                                   * (0 means no limit) */
111     bool finished;               /**< When max_distance is not zero, indicates
112                                   * that max_distance or an obstacle is reached */
113     bool smooth;                 /**< Makes the movement adjust its trajectory
114                                   * when an obstacle is close */
115 
116 };
117 
118 }
119 
120 #endif
121 
122