Handling collisions with objects that use vector of unique pointers - c++

#pragma once
#include "Entity.h"
#include <iostream>
class Projectile : public Entity
{
public:
Projectile() {}
Projectile(float x, float y) {
load("Graphics/Projectile.png");
m_sprite.setPosition(x, y);
m_speed = 400;
}
};
#pragma once
#include "Entity.h"
#include <iostream>
#include "Projectile.h"
enum class Color {
red,
yellow,
brown,
blue
};
class Enemy : public Entity
{
public:
Enemy(const Color& c, const sf::Vector2f& pos) {
switch (c) {
case Color::blue:
{
load("Graphics/blueEnemy.png");
}
break;
case Color::red:
{
load("Graphics/redEnemy.png");
}
break;
case Color::yellow:
{
load("Graphics/yellowEnemy.png");
}
break;
case Color::brown:
{
load("Graphics/brownEnemy.png");
}
break;
}
setPos(pos);
m_speed = 100;
}
};
#pragma once
#include "Entity.h"
#include "Projectile.h"
#include <vector>
class Spaceship : public Entity
{
public:
Spaceship();
void move(float);
void shoot(float);
void update(float);
void draw(sf::RenderWindow*) override;
private:
bool wasSpacePressed;
std::vector<std::unique_ptr<Projectile>> m_projectiles;
sf::Clock m_clock;
};
class EnemyFleet : public Entity
{
public:
EnemyFleet();
~EnemyFleet();
void move(float);
bool isEnemyBottom() const;
bool isLeftMost() const;
bool isRightMost() const;
void moveX(float);
void moveDown();
void update(float);
void draw(sf::RenderWindow*) override;
private:
std::vector<std::unique_ptr<Enemy>> m_enemyFleet;
bool m_leftToRight; //motion of the enemyfleet
float m_speedModifier;
};
I want to be able to delete a projectile and enemy when they collide with each other, but I'm not sure how to do this since unique_ptr cannot be copied into any parameter in some collision manager class bc it has exclusive ownership. Is unique_ptr still something i should use bc i dont have to call delete (like if its a raw ptr)?

Yes, you can't copy unique_ptr, but you can copy or get reference from object that unique_ptr points to (Projectile and Enemy).
//Example
bool collision_manager::is_collision(Projectile & pr, Enemy & en) {
if (pr.position() == en.position()) {
return true;
}
return false
}
// similar for other objects that contain vector of unique_ptr
Projectile & Spaceship::get_Projectile(size_t num) {
if(num < m_projectiles.length()) {
return *projectiles.at(num);
}
throw std::invalid_argument("some alert info");
}
Instead of copying you can also use std::move(unique_ptr...).

Related

Use of deleted Function when pushing class object to std::vector?

I have two classes as shown below.
When i try to populate a vector of Entity objects in the Spawner Entity class,it gives me this error
error: use of deleted function 'Entity::Entity(Entity&&)'
I cant figure out why it wont call the constructor and push the class object on the vector
Also, I Have inherited the Entity Class in the Spawner Entity
Entity.h
#pragma once
#include<iostream>
#include<vector>
#include<SFML/Window.hpp>
#include<SFML/Graphics.hpp>
class Entity
{
private:
sf::RenderWindow win;
sf::RectangleShape enemy;
public:
Entity();
void InitializeEntity();
void Update(const float* DeltaTime);
void Render(sf::RenderWindow& mWindow);
};
Entity.cpp
Entity::Entity()
{
InitializeEntity();
}
void Entity::InitializeEntity()
{
enemy.setPosition(rand()%255+1,rand()%255+1);
enemy.move(rand()%255+1,rand()%255+1);
enemy.setSize(sf::Vector2f(50.f,50.f));
sf::Color color(rand()%255+1,rand()%255+1,rand()%255+1);
enemy.setFillColor(color);
enemy.setOutlineColor(sf::Color::White);
enemy.setOutlineThickness(2.f);
}
void Entity::Render(sf::RenderWindow& mWindow)
{
mWindow.draw(enemy);
}
SpawnerEntity.h
#pragma once
#include<iostream>
#include<vector>
#include<SFML/Window.hpp>
#include<SFML/Graphics.hpp>
#include "Entity.h"
class SpawnerEntity:public Entity
{
private:
float SpawnTimer;
float SpawnTimerMax;
int MaxEnemies;
bool done;
//std::vector<Entity> SpawnedEnemies;
public:
SpawnerEntity();
void InitializeEntity();
void SpawnSubEntities(std::vector<Entity> &enemies);
bool CheckSpawnDone();
};
SpawnerEntity.cpp
#include "SpawnerEntity.h"
SpawnerEntity::SpawnerEntity()
{
SpawnTimerMax=1.f;
SpawnTimer=SpawnTimerMax;
MaxEnemies=10;
done=false;
}
bool SpawnerEntity::CheckSpawnDone()
{
return done;
}
void SpawnerEntity::SpawnSubEntities(std::vector<Entity> &enemies)
{
for(int i=0;i<MaxEnemies;i++)
{
std::cout << "SPAWNED" << '\n';
enemies.push_back(Entity()); //this line here gives me the above error
}
done=true;
}

c++ [gamestate] function does not take in correct argument error

Hello i have problem of compile my code
i follow http://gamedevgeek.com/tutorials/managing-game-states-in-c/ tutorial
but it fail to compile and i don't know why.
the error msg from visual studio
here is my code
the CGameEngine modify code
#include <vector>
#include "GameState.h"
#include "GameEngine.h"
class GameState;
class GameStateManager
{
public:
GameStateManager(GameEngine* engine, MSG * msg);
~GameStateManager();
void Cleanup();
void ChangeState(GameState* state);
void Update();
bool Running() { return m_running; }
void Quit();
private:
std::vector<GameState *> states;
bool m_running;
GameEngine * m_engine;
MSG *m_msg;
};
#include "GameStateManager.h"
GameStateManager::GameStateManager(GameEngine* engine, MSG * msg)
:m_engine{ engine }, m_msg{ msg }, m_running{ true }
{
}
GameStateManager::~GameStateManager()
{
}
void GameStateManager::Cleanup()
{
while (!states.empty()) {
states.back()->Exit();
states.pop_back();
}
}
void GameStateManager::Quit()
{
m_running = false;
m_msg->message = WM_QUIT;
}
void GameStateManager::ChangeState(GameState* state)
{
if (!states.empty()) {
states.back()->Exit();
states.pop_back();
}
states.push_back(state);
states.back()->Enter(m_engine, m_msg);
}
void GameStateManager::Update()
{
states.back()->Update(this);
}
the CGameState modify code
#include "GameStateManager.h"
class GameState
{
public:
GameState() {}
virtual ~GameState() {}
virtual void Enter(GameEngine * , MSG * ) = 0;
virtual void Update(GameStateManager* game) =0;
virtual void Exit() = 0;
};
one of the state class
#include "MainMenu.h"
class Logo :public GameState
{
public:
Logo();
~Logo();
static Logo* Instance()
{
return &m_Logo;
}
void Enter(GameEngine * engine, MSG * msg);
void Update(GameStateManager* game);
void Exit();
private:
static Logo m_Logo;
};
#include "Logo.h"
Logo::Logo()
{
}
Logo::~Logo()
{
}
void Logo::Enter(GameEngine * engine, MSG * msg)
{
m_GameEngine_Info = engine;
m_msg = msg;
}
void Logo::Update(GameStateManager* game)
{
}
void Logo::Exit()
{
}
i get no compile error when editing the code, but when i try compile it get this error.
You have circular includes. Use include guards and replace
#include "GameStateManager.h"
with
class GameStateManager;
in GameState.h. Move this include into GameState.cpp.
Do similar with #include "GameEngine.h" and #include "GameState.h" in GameStateManager.h and GameStateManager.cpp.

error: base operand of '->' has non-pointer type

This is my enum header file
//use like PostionType::President
enum PositionType
{ President,
VicePresident,
Secretary,
Treasurer,
Normal
};
And in my Ballot paper header and cpp file
#include <list>
#include <iostream>
#include "Candidate.h"
#include "PositionType.h" //include enum
class BallotPaper
{
private:
PositionType _positionbp;
std::list<Candidate> _candidatesbp;
public:
BallotPaper();
void setPositionBP(PositionType positionbp);
PositionType getPositionBP();
void setCandidateBP(std::list<Candidate> candidatesbp);
std::list<Candidate> getCandidateBP();
Candidate getCandidate(int index);
void ShowCandidates();
~BallotPaper();
};
#include "BallotPaper.h"
#include <string>
#include <iostream>
void BallotPaper::setPositionBP(PositionType positionbp)
{
_positionbp = positionbp;
}
PositionType BallotPaper::getPositionBP()
{
return _positionbp;
}
void BallotPaper::setCandidateBP(std::list<Candidate> candidatesbp)
{
_candidatesbp = candidatesbp;
}
std::list<Candidate> BallotPaper::getCandidateBP()
{
return _candidatesbp;
}
void BallotPaper::ShowCandidates()
{
for(Candidate c : _candidatesbp)
{
c->IncreaseVoteCount(); //ERROR!!!!
}
}
and this will be my candidate header and cpp file
class Candidate:public Member
{
private:
int _votecount;
PositionType _position;
public:
Candidate(std::string name, int id, std::string course, int contact, std::string joindate, PositionType currentposition) ;
~Candidate();
void setVoteCount(int votecount);
int getVoteCount();
void setPosition(PositionType position);
PositionType getPosition();
void IncreaseVoteCount(); //increase _votecount
};
#include "Candidate.h"
Candidate::Candidate()
{
_votecount = 0;
}
void Candidate::setVoteCount(int votecount)
{
_votecount = votecount;
}
int Candidate::getVoteCount()
{
return _votecount;
}
void Candidate::setPosition(PositionType position)
{
_position = position;
}
PositionType Candidate::getPosition()
{
return _position;
}
void Candidate::IncreaseVoteCount()
{
_votecount++;
}
I know is a super long code, and I appreciate for your patience in looking through it. My error is that it seems that it cannot recognize the function of "IncreaseVoteCount" in 'Candidate c'.
I have try to double check the syntax and the code for multiple times but i still don't understand what is the error here.

One or more multiply defined symbols found, error LNK1169 C++

Sorry for the lack of a descriptive title.
I'm getting an error "one or more multiply defined symbols found"; to be more specific, I'm getting 46 of them. One for each function in my header/source files. Using Visual Studios 2013.
Here is the relevant source code:
augments.h
#ifndef AUGMENTS_H_
#define AUGMENTS_H_
namespace Augments {
// only used for pass-ins for constructors
enum class Weapon_Type {
sword
};
enum class Head_Type {
head
};
enum class Body_Type {
body
};
// the player (Monster) has a head, body and weapon
// that augments his abilities. This will mostly
// be the thing that draws to the screen for each
// augmentation, but more importantly it contains
// specific statistics about each one.
// So if there was a body that was able to fly,
// there would be a bool that denotes this ability.
class Head : public Actor {
const Head_Type type;
public:
Head(Head_Type);
void Update(float dt);
};
class Body : public Actor {
const Body_Type type;
public:
Body(Body_Type);
void Update(float dt);
};
class Weapon : public Actor {
const Weapon_Type type;
public:
Weapon(Weapon_Type);
void Update(float dt);
};
}
using AugHead = Augments::Head;
using AugBody = Augments::Body;
using AugWep = Augments::Weapon;
#endif
augments.cpp
#include "stdafx.h"
#include "Angel.h"
#include "Augments.h"
#include "LD33.h"
Augments::Head::Head(Augments::Head_Type x) : type(x) {
switch ( x ) {
case Head_Type::head:
SetSprite("Images\\head.png");
break;
};
};
void Augments::Head::Update(float dt) {
SetPosition(Game::thePlayer->GetPosition().X,
Game::thePlayer->GetPosition().Y-
MathUtil::ScreenToWorld(Vec2i(0,40)).Y);
};
Augments::Body::Body(Augments::Body_Type x) : type(x) {
switch ( x ) {
case Body_Type::body:
SetSprite("Images\\body.png");
break;
};
}
void Augments::Body::Update(float dt) {
SetPosition(Game::thePlayer->GetPosition().X,
Game::thePlayer->GetPosition().Y);
}
Augments::Weapon::Weapon(Augments::Weapon_Type x ) : type(x) {
switch ( x ) {
case Weapon_Type::sword:
SetSprite("Images\\weapon.png");
break;
}
}
void Augments::Weapon::Update(float dt) {
SetPosition(Game::thePlayer->GetPosition().X,
Game::thePlayer->GetPosition().Y-
MathUtil::ScreenToWorld(Vec2i(0,-40)).Y);
}
monster.h
// monster related
#include "Augments.h"
#include "Angel.h"
#ifndef MONSTER_H_
#define MONSTER_H_
namespace Player {
// contains information like health attack etc
// but more important body types
class Monster : public PhysicsActor {
int max_health, curr_health;
int attack_damage;
Augments::Head* frame_head;
Augments::Weapon* frame_weapon;
Augments::Body* frame_body;
public:
void Refresh(float dt);
int R_Max_Health() const;
int R_Curr_Health() const;
int R_Attack_Damage() const;
Augments::Head* R_Frame_Head();
Augments::Weapon* R_Frame_Weapon();
Augments::Body* R_Frame_Body();
void Set_Max_Health(int);
void Set_Curr_Health(int);
void Add_Curr_Health(int);
void Set_Attack_Damage(int);
// will automatically remove old
// actors from the stage and deallocate
void Set_Frame_Head(Augments::Head_Type);
void Set_Frame_Weapon(Augments::Weapon_Type);
void Set_Frame_Body(Augments::Body_Type);
Monster(Augments::Head_Type,
Augments::Weapon_Type,
Augments::Body_Type);
};
};
using PlMonster = Player::Monster;
#endif
monster.cpp
#include "stdafx.h"
#include "Monster.h"
#include "Augments.h"
#include "Angel.h"
void Player::Monster::Refresh(float dt) {
};
int Player::Monster::R_Max_Health() const { return max_health; }
int Player::Monster::R_Curr_Health() const { return curr_health; }
int Player::Monster::R_Attack_Damage() const { return attack_damage; }
Augments::Head* Player::Monster::R_Frame_Head() { return frame_head; }
Augments::Body* Player::Monster::R_Frame_Body() { return frame_body; }
Augments::Weapon* Player::Monster::R_Frame_Weapon() { return frame_weapon; }
void Player::Monster::Set_Max_Health(int x) { max_health = x; }
void Player::Monster::Set_Curr_Health(int x) { curr_health = x; }
void Player::Monster::Add_Curr_Health(int x) { curr_health += x; }
void Player::Monster::Set_Attack_Damage(int x) { attack_damage = x; }
void Player::Monster::Set_Frame_Head(Augments::Head_Type x) {
if ( frame_head != nullptr ) {
frame_head->Destroy();
delete frame_head;
frame_head = nullptr;
}
frame_head = new Augments::Head(x);
theWorld.Add(frame_head);
};
void Player::Monster::Set_Frame_Weapon(Augments::Weapon_Type x) {
if ( frame_weapon != nullptr ) {
theWorld.Remove(frame_weapon);
delete frame_weapon;
frame_weapon = nullptr;
}
frame_weapon = new Augments::Weapon(x);
theWorld.Add(frame_weapon);
};
void Player::Monster::Set_Frame_Body(Augments::Body_Type x) {
if ( frame_body != nullptr ) {
theWorld.Remove(frame_body);
delete frame_body;
frame_body = nullptr;
}
frame_body = new Augments::Body(x);
theWorld.Add(frame_body);
};
Player::Monster::Monster(Augments::Head_Type head,
Augments::Weapon_Type weapon,
Augments::Body_Type body) {
frame_body = nullptr;
frame_head = nullptr;
frame_weapon = nullptr;
Set_Frame_Body(body);
Set_Frame_Head(head);
Set_Frame_Weapon(weapon);
}
source.cpp
#include "stdafx.h"
#include "LD33.h"
#include "Angel.h"
int main ( ) {
Game::Initialize();
theWorld.StartGame();
theWorld.Destroy();
return 0;
}
Errors include things such as:
Error 43 error LNK2005: "public: int __thiscall Player::Monster::R_Attack_Damage(void)const " (?R_Attack_Damage#Monster#Player##QBEHXZ) already defined in Augments.obj C:\Users\The Shire\Desktop\ludum_dare\ludumdare33\Code\ClientGame\source.obj ClientGame
Error 3 error LNK2005: "public: void __thiscall Player::Monster::Set_Frame_Body(enum Augments::Body_Type)" (?Set_Frame_Body#Monster#Player##QAEXW4Body_Type#Augments###Z) already defined in Augments.obj C:\Users\The Shire\Desktop\ludum_dare\ludumdare33\Code\ClientGame\LD33.obj ClientGame
And it pretty much states similar for every single function in Monster.
Sorry for just dumping a ton of code. I've been trying to debug it for awhile but couldn't come up with any reasonable solution. I have the include guards, I don't see any namespace conflicts, and everything that needs to be defined is outside of the header files. I can't find anything in augments.h that would be causing this. I also thought it might be the enums, but replacing them with just int did not work either.
I'm thinking it might be the order of the include files? hmm. Maybe there's somehow multiple source files somewhere but I would have no clue as to how. Any help?
Had included Monster.cpp in another header file on accident! Oops

Invalid conversion c++

I get this error
invalid conversion from 'GameObject*' to 'std::vector::value_type {aka SDLGameObject*}' [-fpermissive]
This is my code I don't know what is wrong because in my class MainMenu it works this is my class Playstate.cpp
bool PlayState::onEnter()
{
SDL_ShowCursor(1);
//parse the state
TheTextureManager::Instance()->load("assets/button.png", "test", TheGame::Instance()->getRenderer());
GameObject* pGameObject1 = TheGameObjectFactory::Instance()->create("MenuButton");
pGameObject1->load(new LoaderParams(120, 300, 400, 100, "test", 4, 4, 4));
m_gameObjects.push_back(pGameObject1);
}
GameObject.h
#include "LoaderParams.h"
#include <string>
using namespace std;
class GameObject {
public:
virtual void draw() = 0;
virtual void update() = 0;
virtual void clean() = 0;
virtual void load(const LoaderParams* pParams)=0;
protected:
GameObject() {}
virtual ~GameObject() {}
};
#endif /* GAMEOBJECT_H_ */
SDLGameObject.h
#ifndef SDLGAMEOBJECT_H_
#define SDLGAMEOBJECT_H_
#pragma once
#include "GameObject.h"
#include "LoaderParams.h"
#include "TextureManager.h"
#include "Vector2D.h"
class SDLGameObject : public GameObject {
public:
SDLGameObject();
virtual void draw();
virtual void update();
virtual void clean(){}
virtual void load(const LoaderParams* pParams);
Vector2D& getPosition() { return m_position; }
virtual int getWidth() { return m_width; }
virtual int getHeight() { return m_height; }
protected:
Vector2D m_position;
Vector2D m_velocity;
Vector2D m_acceleration;
int m_width;
int m_height;
int m_currentRow;
int m_currentFrame;
std::string m_textureID;
};
#endif /* SDLGAMEOBJECT_H_ */
MainMenuState.cpp here it does work!!
bool MainMenuState::onEnter()
{
SDL_ShowCursor(1);
//parse the state
TheTextureManager::Instance()->load("assets/button.png", "playbutton" , TheGame::Instance()->getRenderer());
TheTextureManager::Instance()->load("assets/exit.png", "exitbutton" , TheGame::Instance()->getRenderer());
GameObject* pGameObject = TheGameObjectFactory::Instance()->create("MenuButton");
GameObject* pGameObject1 = TheGameObjectFactory::Instance()->create("MenuButton");
pGameObject->load(new LoaderParams(120, 150, 400, 100, "playbutton", 0, 1, 2));
pGameObject1->load(new LoaderParams(120, 300, 400, 100, "exitbutton", 1, 2, 2));
m_gameObjects.push_back(pGameObject);
m_gameObjects.push_back(pGameObject1);
m_callbacks.push_back(0);
m_callbacks.push_back(s_menuToPlay);
m_callbacks.push_back(s_exitFromMenu);
//set callbacks for menu items
setCallbacks(m_callbacks);
std::cout << "Entering MainMenuState\n";
return true;
}
SDLGameObject derives from the base class GameObject. Your vector m_gameObjects stores pointers to SDLGameObject, but you are giving it a pointer to a GameObject.
This conversion is not possible as a GameObject is not necessarily an SDLGameObject.
If you are sure that this is the case you can do this:
SDLGameObject* p = dynamic_cast<SDLGameObject>(pGameObject1);
if(!p) {
// pGameObject1 is actually not an SDLGameObject
}
m_gameObjects.push_back(p);
Or change the definition of m_gameObjects to store pointers to GameObject.