0

The program shows player texture for both the player and the hazard. Which is very strange, considering i have checked with debugger and createHazards creates hazards with the right texture(hazard texture).

#include <iostream>
#include <raylib.h>
#include <random>

int getRandomInt(int start, int end)
{
  std::random_device rd;
  std::mt19937 gen(rd());
  std::uniform_int_distribution<> dis(start, end);
  return dis(gen);
}

class MovingObject
{
public:
  Texture2D Texture;
  Rectangle Geometry;
  Vector2 Position;
  float Velocity;
  char SpriteSheetCount;
  char CurrentSpriteNumber = 0;

  float UpdateTime{1.0 / 12.0};
  int Frame{0};
  float CurrentTime{0};

  std::string TexturePath;

  MovingObject()
  {
  }

  MovingObject(const char *texturePath, float velocity, char spriteSheetCount) : Velocity(velocity), SpriteSheetCount(spriteSheetCount), TexturePath(texturePath)
  {
    Texture = LoadTexture(texturePath);
  }

  ~MovingObject()
  {
    UnloadTexture(Texture);
  }

  void SetSprite(char number = 0)
  {
    CurrentSpriteNumber = number;
    Geometry.x = number * Geometry.width;
  }

  void SetVelocity(float velocity)
  {
    Velocity = velocity;
  }

  virtual void Move(float dT = 1, float accelerationRatio = 1) = 0;
};

class Player : public MovingObject
{
public:
  float JumpVelocity = -40000;

  Player(const char *texturePath, short windowWidth, short windowHeight, float velocity, char spriteSheetCount = 6) : MovingObject(texturePath, velocity, spriteSheetCount)
  {
    Geometry = {
        0.0,
        0.0,
        (float)Texture.width / spriteSheetCount, (float)Texture.height};
    Position = {(float)windowWidth / 2 - Texture.width / 2, (float)windowHeight - Texture.height};
  };

  bool IsInAir(int windowHeight)
  {
    return Position.y < windowHeight - Geometry.height;
  }

  bool IsNearTheGround(int windowHeight, int offset = 50)
  {
    return Position.y + offset < windowHeight - Geometry.height;
  }

  void Move(float dT = 1, float accelerationRatio = 1)
  {
    Position.y += Velocity * dT * accelerationRatio;
  }

  void Jump(float dT = 1)
  {
    Velocity += JumpVelocity * dT;
  }
};

class Hazard : public MovingObject
{
public:
  Hazard()
  {
  }
  Hazard(const char *texturePath, short windowWidth, short windowHeight, float velocity, char spriteSheetCount = 8) : MovingObject(texturePath, velocity, spriteSheetCount)
  {
    Geometry = {0.0, 0.0, (float)Texture.width / spriteSheetCount, (float)Texture.height};
    Position = {(float)windowWidth, (float)windowHeight - Texture.height / spriteSheetCount};
  }

  void Move(float dT = 1, float accelerationRatio = 1)
  {
    Position.x += Velocity * dT * accelerationRatio;
  }

  void ResetPosition(short windowWidth, float offset = 0)
  {
    Position.x = windowWidth + offset;
  }
};

void HandlePlayerMovement(Player &player, short windowHeight, short g, float dT, int accelerationRation)
{
  if (!player.IsInAir(windowHeight))
  {
    player.Velocity = 0;
  }

  else
  {
    player.SetVelocity(player.Velocity + (g * dT));
  }

  if (IsKeyPressed(KEY_SPACE))
  {
    if (!player.IsNearTheGround(windowHeight))
    {
      player.Jump(dT);
    }
  }
  player.Move(dT, accelerationRation);
}

void HandleHazardsMovement(Hazard *hazards, int hazardCount, short windowWidth, float dT, float accelerationRatio)
{
  for (int i = 0; i < hazardCount; i++)
  {
    hazards[i].Move(dT, accelerationRatio);
    if (hazards[i].Position.x + hazards[i].Geometry.width <= 0)
    {
      hazards[i].ResetPosition(windowWidth + getRandomInt(0, 500));
    };
  }
}

void HandlePlayerAnimations(Player &player, short windowHeight, float dT)
{
  if (player.IsInAir(windowHeight))
  {
    player.Frame = 2;
    player.SetSprite(player.Frame);
  }
  else
  {
    player.CurrentTime += dT;
    if (player.CurrentTime >= player.UpdateTime)
    {
      player.CurrentTime = 0.0;
      player.SetSprite(player.Frame);
      player.Frame = player.Frame > 5 ? 0 : player.Frame + 1;
    }
  }
};

void HandleHazardsAnimations(Hazard *hazards, int hazardCount, float dT)
{
  for (int i = 0; i < hazardCount; i++)
  {
    hazards[i].CurrentTime += dT;
    if (hazards[i].CurrentTime >= hazards[i].UpdateTime)
    {
      hazards[i].CurrentTime = 0.0;
      hazards[i].SetSprite(hazards[i].Frame);
      hazards[i].Frame = hazards[i].Frame > 7 ? 0 : hazards[i].Frame + 1;
    }
  }
}

Hazard *CreateHazards(int count, short windowWidth, short windowHeight, float offsetStart = -100, float offsetEnd = 100)
{
  Hazard *hazards = new Hazard[count];
  for (int i = 0; i < count; i++)
  {
    hazards[i] = Hazard("./correct/path/to/hazard/texture", windowWidth / 2, windowHeight / 2, -60);
  }
  return hazards;
};

void DrawHazards(Hazard *hazards, int hazardCount, Color color = WHITE)
{
  for (int i = 0; i < hazardCount; i++)
  {
    DrawTextureRec(hazards[i].Texture, hazards[i].Geometry, hazards[i].Position, color);
  }
}

int main()
{
  const short windowWidth{1024};
  const short windowHeight{720};

  const short g{1'000};

  const char hazardCount = 6;

  InitWindow(windowWidth, windowHeight, "Dasher");
  SetTargetFPS(60);

  Player player{"./correct/path/to/player/texture", windowWidth, windowHeight, 0};

  Hazard *hazards = CreateHazards(hazardCount, windowWidth, windowHeight, -200, 400);

  float accelerationRatio{1};

  while (!WindowShouldClose())
  {
    if (accelerationRatio <= 2.5)
    {
      accelerationRatio += 0.0001;
    }
    const float dT{GetFrameTime()};
    BeginDrawing();
    ClearBackground(WHITE);

    HandlePlayerAnimations(player, windowHeight, dT);
    HandleHazardsAnimations(hazards, hazardCount, dT);

    DrawTextureRec(player.Texture, player.Geometry, player.Position, WHITE);
    HandlePlayerMovement(player, windowHeight, g, dT, accelerationRatio);

    DrawHazards(hazards, hazardCount);
    HandleHazardsMovement(hazards, hazardCount, windowWidth, dT, accelerationRatio);

    EndDrawing();
  }

  delete[] hazards;
  CloseWindow();
}

I checked with debugger, the hazards array gets right hazard objects with correct paths to the hazard texture(texturePath is solely for debugging purposes), however it's still shows players texture instead of hazard(

genpfault
  • 51,148
  • 11
  • 85
  • 139
Hayk
  • 1
  • Unrelated tactical note: `getRandomInt` reseeds and recreates the RNG engine every time you need a number. This works, it gives a random number, but it is **brutally** expensive. Create the engine once. Seed it once. Reuse it. This can be easily done by making `rd` and `dist` `static`. Also worth making the function a template and supplying the bounds as template arguments so you can also make `gen` `static`. The less work you have to unnecessarily repeat, the better. – user4581301 Apr 04 '23 at 18:34
  • Recommendation: Climb out of the 1990s and replace `Hazard *hazards = new Hazard[count];` with a [`std::vector`](https://en.cppreference.com/w/cpp/container/vector). Significantly reduces the cognitive load on the programmer because it manages the lifespan for you. – user4581301 Apr 04 '23 at 18:38
  • Inspect `hazards[i].Texture` before drawing. Is it the expected texture? If not, start stepping through the code to see where it changed. – user4581301 Apr 04 '23 at 18:48
  • @user4581301 That's the crazy part. The texture is correct right on the line of drawing it, but it still shows players texture. Thanks for the other advices too) – Hayk Apr 04 '23 at 19:34
  • Please trim your code to make it easier to find your problem. Follow these guidelines to create a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example). – Friedrich Apr 05 '23 at 16:19

0 Answers0