A jak z tą powiększającą się pamięcią tak o 1MB w przedziale od 20sekund do minuty, kiedy w ogóle się nie ruszam, a zrenderowane są tylko 2/3 obiekty?
Co do klas:
manager
#include "Human.h"
#include "Cleaver.h"
#include "PlayerGun.h"
#include "FileManager.h"
class EntityManager
{
public:
typedef enum EntityType
{
none = 0,
player = 1,
human = 2,
playerGun = 3,
cleaver = 4,
};
EntityType currentType;
EntityManager();
~EntityManager();
void Update();
void Draw(SDL_Renderer *renderer);
void AddComponent(std::string name, EntityType type, SDL_Renderer *renderer);
void AddPlayerGun(int x, int y, int moveDirection, SDL_Renderer *renderer);
void CreateEntity(std::vector<std::vector<std::string>> map);
void ClearEntity();
int getList(int x);
int getNumOfEntities();
private:
FileManager file;
std::vector<std::vector<Entity*>> ent;
int entitySize;
};
#endif // !
#include "EntityManager.h"
EntityManager::EntityManager()
{
this->currentType = none;
}
EntityManager::~EntityManager()
{
for (auto &e : entity)
{
for (const auto &en : e)
{
delete en;
}
e.clear();
}
entity.clear();
}
void EntityManager::Update()
{
for (const auto &e : entity)
{
for (const auto &en : e)
{
if (en->entityState == Entity::eLive)
{
en->Update();
}
}
}
for (auto &e : entity)
{
auto RemoveIt = std::remove_if(e.begin(), e.end(), [](const Entity* p)
{
return p->entityState == Entity::eDead;
});
for (auto it = RemoveIt; it != e.end(); ++it)
{
delete *it;
}
e.erase(RemoveIt, e.end());
}
}
void EntityManager::Draw(SDL_Renderer * renderer)
{
for (const auto &e : entity)
{
for (const auto &en : e)
{
if (en->entityState == Entity::eLive)
{
en->Draw(renderer);
}
}
}
}
int EntityManager::getList(int x)
{
return x / 100;
}
int EntityManager::getNumOfEntities()
{
int num = 0;
for (const auto &e : entity)
{
num += e.size();
}
return num;
}
void EntityManager::AddComponent(std::string name, EntityType type, SDL_Renderer *renderer)
{
std::vector<std::vector<std::string>> attributes;
std::vector<std::vector<std::string>> contents;
std::vector<float> eX, eY, eMS, eRG, eMD, cRadius;
file.LoadFromFile(name, attributes, contents, name);
for (int i = 0; i < attributes.size(); i++)
{
for (int j = 0; j < attributes[i].size(); j++)
{
std::string att = attributes[i][j];
std::string con = contents[i][j];
float conf = atof(con.c_str());
int coni = atoi(con.c_str());
if (att == "x") eX.push_back(conf);
else if (att == "y") eY.push_back(conf);
else if (att == "ms") eMS.push_back(conf);
else if (att == "range") eRG.push_back(conf);
else if (att == "moveDirection") eMD.push_back(coni);
else if (att == "radius") cRadius.push_back(coni);
}
}
for (int i = 0; i < contents.size(); i++)
{
switch (type)
{
case human:
entity[getList(eX[i])].push_back(new Human(eX[i], eY[i], eMS[i], eRG[i], eMD[i], renderer));
break;
case cleaver:
entity[getList(eX[i])].push_back(new Cleaver(eX[i], eY[i], cRadius[i], 0, eMD[i], renderer));
break;
}
}
}
void EntityManager::AddPlayerGun(int x, int y, int moveDirection, SDL_Renderer *renderer)
{
entity[getList(x)].push_back(new PlayerGun(x,y, moveDirection, renderer));
}
void EntityManager::CreateEntity(std::vector<std::vector<std::string>> map)
{
for (int y = 0; y < map.size(); y+=5)
{
std::vector<Entity*> tempEnt;
for (int i = 0; i < map[y].size(); i++)
{
entity.push_back(tempEnt);
}
}
entitySize = entity.size();
}
void EntityManager::ClearEntity()
{
for (auto &e : entity)
{
for (const auto &en : e)
{
delete en;
}
e.clear();
}
}
Tak wywołuje na mapie
void GameplayScreen::LoadMap(SDL_Renderer *renderer)
{
file.LoadFromFile("Map", map);
entityManager.ClearEntity();
entityManager.CreateEntity(map);
entityManager.AddComponent("Human", EntityManager::EntityType::human, renderer);
entityManager.AddComponent("Cleaver", EntityManager::EntityType::cleaver, renderer);
}
render i update entityManager.Update(); entityManager.Draw(renderer);
całe entity
#pragma once
#ifndef ENTITY_H
#define ENTITY_H
#include "Texture.h"
#include "Vector2.h"
#include "FileManager.h"
class Entity
{
public:
typedef enum JumpState
{
eOnGround = 0,
eJump = 1,
eFalling = 2,
};
JumpState jumpState;
typedef enum EntityState
{
eDead = -1,
eLive = 0,
};
EntityState entityState;
Entity();
~Entity();
virtual void Draw(SDL_Renderer *renderer);
virtual void Update();
virtual void UpdatePosX();
virtual void UpdatePosY(float moveSpeed);
virtual void EntityPhysics();
virtual void moveAnimation(int maxSpriteID);
virtual void resetJump();
int getX(), getY();
int getHitBoxX(), getHitBoxY();
int getMoveDirection();
int getRange();
int getJumpState();
float getVelX();
float getVelY();
float getJumpSpeed();
float getGravity();
void setSpriteID(int id);
int getSpriteID();
int getBlockID();
protected:
FileManager file;
Texture eSprite;
bool spawnEntity;
bool bDestroy;
float posX, posY;
float hitBoxX, hitBoxY;
float moveSpeed;
float velX, velY;
int spriteSize;
int spriteID;
int moveAnim;
unsigned int passedTime;
unsigned int moveAnimationTime;
//-------- jump ---------
float jumpSpeed;
int moveDirection;
int blockID;
int range, counterRange;
};
#endif // !1
Pokaże tylko te najważniesze metody, bo gettersy i settersy to wiadomo jak wyglądają
Entity::~Entity()
{
eSprite.free();
}
void Entity::Draw(SDL_Renderer * renderer) {}
void Entity::Update() {}
void Entity::UpdatePosX()
{
if (moveDirection)
{
if ((posX + hitBoxX > 1200) || (range > 0 && counterRange >= range))
{
counterRange = 0;
moveDirection = !moveDirection;
}
else
{
counterRange += velX;
posX += velX;
}
}
else
{
if ((posX < 10) || range > 0 && counterRange >= range)
{
counterRange = 0;
moveDirection = !moveDirection;
}
else
{
counterRange += velX;
posX -= velX;
}
}
}
void Entity::UpdatePosY(float moveSpeed)
{
if (moveSpeed > 0)
{
if (posY + hitBoxY < 500)
{
posY += moveSpeed;
}
else velY = 0;
}
else if (moveSpeed < 0)
{
//if ()
{
posY += moveSpeed;
}
//else velY = 0;
}
}
void Entity::EntityPhysics()
{
if (posY + hitBoxY < 500)
{
velY += gravity;
jumpState = eFalling;
}
else if (jumpState == eFalling)
{
velY = 0;
jumpState = eOnGround;
}
UpdatePosY(velY/jumpFactor);
}
//metoda animacji jest trochę źle napisana, ale działa
void Entity::moveAnimation(int maxSpriteID)
{
if (moveAnim)
{
if (SDL_GetTicks() - 100 - velX >= moveAnimationTime)
{
moveAnimationTime = SDL_GetTicks();
if (spriteID >= maxSpriteID)
{
setSpriteID(0);
}
else spriteID++;
}
}
}
Gravity i jumpFactor określiłem w jednym pliku jako
define gravity 3
define jumpFactor 3.2
żeby dla kazdej klasy, która będzie korzystac z grawitacji nie trzeba bylo robic nowych zmiennych, też nie wiem czy to dobry pomysł, dlatego piszę.
Dla przykładu pokaze tylko jedną klasę, która dziedziczy, bo po co więcej
#pragma once
#ifndef HUMAN_H
#define HUMAN_H
#include "Entity.h"
class Human : public Entity
{
public:
Human(int x, int y, int ms, int rg, int moveDirection, SDL_Renderer *renderer);
~Human();
void Draw(SDL_Renderer *renderer);
void Update();
private:
};
#endif // ! HUMAN_H
#include "Human.h"
Human::Human(int x, int y, int ms, int rg, int moveDirection, SDL_Renderer *renderer)
{
this->spriteID = 0;
this->moveDirection = moveDirection;
this->posX = x;
this->posY = y;
this->range = rg;
this->velX = ms;
this->velY = 0;
this->counterRange = 0;
this->hitBoxX = 30;
this->hitBoxY = 57;
eSprite = Texture("Human/humanSprites", renderer);
spriteSize = (int)(eSprite.getWidth() / 33) - 1;
if (velX > 0) moveAnim = true;
}
Human::~Human()
{
Entity::~Entity();
//eSprite.free();
}
void Human::Draw(SDL_Renderer* renderer)
{
if (entityState != eDead)
{
SDL_Rect humanDestRect;
humanDestRect.x = spriteID * 32;
humanDestRect.y = 0;
humanDestRect.w = 32;
humanDestRect.h = 58;
SDL_Rect humanRect;
humanRect.x = posX;
humanRect.y = posY;
humanRect.w = 32;
humanRect.h = 57;
eSprite.Draw(humanDestRect, humanRect, renderer, !moveDirection);
}
}
void Human::Update()
{
if (posY > 1000)
{
entityState = eDead;
}
if (entityState == eLive)
{
moveAnimation(spriteSize);
EntityPhysics();
UpdatePosX();
}
}
W destrukorze pojawia się eSprite->free();
tutaj ono:
void Texture::free()
{
mTexture = NULL;
SDL_DestroyTexture(mTexture);
}
Nie wiem w sumie dlaczego przy każdym enumie dawałem typedefa skoro nazwy nie są jakoś długie, ale to chyba nic nie zmienia.
tutaj jeszcze plik z którego czytam Humana
Human:{x, y, ms, range, moveDirection}
39, 500, 1, 250, 0
300, 500, 3, 0, 1
Human;
Na koniec chciałbym jeszcze bardzo mocno podziękować za czas, który poświęciliście dla mnie i za każdą cenną radę, którą będę mógł wykorzystać w przyszłości.