Moving a Rectangle in SDL2
How would I move the rectangle around the screen?
The position of our Rectangle
object on the screen is determined by the x
and y
members of its internal SDL_Rect
variable (Rect
). To move the rectangle, you simply need to change the values of Rect.x
and Rect.y
.
The key is when and how you modify these values. This typically happens in response to user input or as part of an animation update cycle.
Moving with Keyboard Input
A common way to move objects is using the keyboard arrow keys. You can handle this within the HandleEvent
function by checking for SDL_KEYDOWN
events.
// Rectangle.h
// ...
#include <iostream> // For std::cout
class Rectangle {
public:
// ... (Constructor, Render, other methods) ...
void HandleEvent(const SDL_Event& E) {
if (E.type == SDL_MOUSEMOTION) {
// ... (hover logic) ...
} else if (
E.type == SDL_WINDOWEVENT &&
E.window.event == SDL_WINDOWEVENT_LEAVE
) {
// ... (hover logic) ...
} else if (E.type == SDL_MOUSEBUTTONDOWN) {
// ... (click logic) ...
} else if (E.type == SDL_KEYDOWN) {
// Check which key was pressed
switch (E.key.keysym.sym) {
case SDLK_UP: Rect.y -= 5; break;
case SDLK_DOWN: Rect.y += 5; break;
case SDLK_LEFT: Rect.x -= 5; break;
case SDLK_RIGHT: Rect.x += 5; break;
default: break;
}
std::cout << "New pos: (" << Rect.x << ", "
<< Rect.y << ")\\n";
}
}
// ... (isWithinRect) ...
private:
SDL_Rect Rect;
// ... (Color, HoverColor, isPointerHovering) ...
};
In this example, pressing an arrow key modifies Rect.x
or Rect.y
by 5 pixels, causing the rectangle to jump to the new position in the next frame when Render()
is called.
Moving Smoothly with an Update()
Method
For continuous or time-based movement (like animation or physics), you'd typically add an Update()
method to your Rectangle
class and call it from the main loop. This method often takes deltaTime
(the time since the last frame) as an argument to ensure movement speed is consistent regardless of frame rate.
// Rectangle.h
// ...
class Rectangle {
public:
// ... (Constructor, Render, HandleEvent) ...
// Add velocity members
float velocityX{0.0f};
float velocityY{0.0f};
void Update(float deltaTime) {
// Update position based on velocity and time
// Use float for intermediate calculation for smoothness
float newX = static_cast<float>(Rect.x) + velocityX * deltaTime;
float newY = static_cast<float>(Rect.y) + velocityY * deltaTime;
// Update the actual integer position
Rect.x = static_cast<int>(newX);
Rect.y = static_cast<int>(newY);
}
// ... (Getters/Setters for velocity might be useful) ...
private:
SDL_Rect Rect;
// ... (Other members) ...
};
You would then need to:
- Calculate
deltaTime
in yourmain
loop (using SDL timing functions). - Call
Rect.Update(deltaTime)
every frame within the main loop, likely before the rendering steps. - Modify
velocityX
andvelocityY
based on input or game logic (e.g., inHandleEvent
or other logic).
The core mechanism remains the same: modify Rect.x
and Rect.y
. The choice between handling movement in HandleEvent
(for direct input response) or Update
(for continuous/time-based movement) depends on the desired behavior.
We cover Update()
methods (sometimes also called Tick()
methods) and timing in detail later in the course.
Rectangles and SDL_Rect
Learn to create, render, and interact with basic rectangles using the SDL_Rect
and SDL_Color
types.