I’m working on lesson 68–Map Bounds–and my code reflects what’s present in the course, but my character is still running off the edge of the map. What am I missing?
topdown.cpp
#include "raylib.h"
#include "raymath.h"
#include "Character.h"
int main()
{
int windowWidth{384};
int windowHeight{384};
// Initialize Window
InitWindow(windowWidth, windowHeight, "Ashley's Top Down");
// Initialize Background
Texture2D map = LoadTexture("nature_tileset/gamemap.png");
Vector2 mapPos{0.0, 0.0};
const float mapScale{4.0f};
SetTargetFPS(60);
Character knight;
knight.setScreenPos(windowWidth, windowHeight);
while (!WindowShouldClose())
{
BeginDrawing();
ClearBackground(WHITE);
mapPos = Vector2Scale(knight.getWorldPos(), -1.f);
// draw the map
DrawTextureEx(map, mapPos, 0.0, mapScale, WHITE);
knight.tick(GetFrameTime());
// check map bounds
if (knight.getWorldPos().x < 0.f ||
knight.getWorldPos().y < 0.f ||
knight.getWorldPos().x + windowWidth > map.width * mapScale ||
knight.getWorldPos().y + windowHeight > map.height * mapScale)
{
knight.undoMovement();
}
}
EndDrawing();
// End drawing
UnloadTexture(map);
CloseWindow();
}
Character.h
#include "raylib.h"
class Character
{
public:
// get worldPos
Character();
Vector2 getWorldPos() { return worldPos; }
void setScreenPos(int winWidth, int winHeight);
void tick(float deltaTime);
void undoMovement();
private:
Texture2D texture{LoadTexture("characters/knight_idle_spritesheet.png")};
Texture2D idle{LoadTexture("characters/knight_idle_spritesheet.png")};
Texture2D run{LoadTexture("characters/knight_run_spritesheet.png")};
Vector2 screenPos{};
Vector2 worldPos{};
Vector2 worldPosLastFrame{};
// +1 = facing right, -1 = facing left
float rightLeft{1.f};
// animation variables
float runningTime{};
int frame;
int maxFrames{6};
float updateTime{1.f / 12.f};
float speed {4.f};
float width{};
float height{};
};
Character.cpp
#include "raylib.h"
#include "Character.h"
#include "raymath.h"
Character::Character()
{
float width = texture.width/maxFrames;
float height = texture.height;
}
void Character::setScreenPos(int winWidth, int winHeight)
{
screenPos = {
(float)winWidth / 2.0f - 4.0f * (0.5 * width),
(float)winHeight / 2.0f - 4.0f * (0.5 * height),
};
}
void Character::tick(float deltaTime)
{
worldPosLastFrame = worldPos;
Vector2 direction{};
if (IsKeyDown(KEY_A))
direction.x -= 1.0;
if (IsKeyDown(KEY_D))
direction.x += 1.0;
if (IsKeyDown(KEY_W))
direction.y -= 1.0;
if (IsKeyDown(KEY_S))
direction.y += 1.0;
if (Vector2Length(direction) != 0.0)
{
// set worldPos = worldPos + direction
worldPos = Vector2Add(worldPos, Vector2Scale(Vector2Normalize(direction), speed));
direction.x < 0.f ? rightLeft = -1.f : rightLeft = 1.f;
texture = run;
}
else
{
texture = idle;
}
// update animation frame
runningTime += deltaTime;
if (runningTime >= updateTime)
{
frame++;
runningTime = 0.f;
if (frame > maxFrames)
frame = 0;
}
// draw knight
Rectangle source{frame * width, 0.f, rightLeft * width, height};
Rectangle dest{screenPos.x, screenPos.y, 4.0f * width, 4.0 * height};
DrawTexturePro(texture, source, dest, Vector2{}, 0.f, WHITE);
}
void Character::undoMovement()
{
worldPos = worldPosLastFrame;
}