Error: redefinition of default parameter : parameter 3 but not redefining? - c++

As far as I can see the code for this class works yet it will not compile and is throwing the error mentioned in the title. Below is the header file.
This is using the SDL standard libraries.
texture2D.h
#ifndef TEXTURE2D_H
#define TEXTURE2D_H
#include <SDL.h>
#include <string>
#include "Commons.h"
using namespace::std;
class Texture2D
{
SDL_Renderer* mRenderer;
SDL_Texture* mTexture;
int mWidth;
int mHeight;
public:
Texture2D(SDL_Renderer* renderer);
~Texture2D();
bool LoadFromFile(string path);
void Free();
void Render(Vector2D newPosition, SDL_RendererFlip flip, double angle = 0.0f);
int GetWidth() { return mWidth; }
int GetHeight() { return mHeight; }
};
#endif

I imagine your definition of Render looks like this
In .cpp
void Texture2D::Render(Vector2D newPosition, SDL_RendererFlip flip, double angle = 0.0f)
{
...
}
When it should be
void Texture2D::Render(Vector2D newPosition, SDL_RendererFlip flip, double angle )
{
...
}
You only supply the default value in the declaration ( normally .h )

Related

unique_ptr incomplete type for forward declaration with default destructor

My question is quite related to this thread:
std::unique_ptr with an incomplete type won't compile
I understood the concept of incomplete type with unique_ptr and need to provide the default destructor for the holding class. However, I'm still getting following error:
invalid use of incomplete type ‘class Game::Sprite’
Following is my simplified code. Please let me know if I'm still missing something here? :
/*
* Game.h
*/
#pragma once
#include <string>
#include <unordered_map>
#include "SDL.h"
class Game {
public:
Game();
~Game();
void run();
const int SCREEN_WIDTH = 800;
const int SCREEN_HEIGHT = 600;
private:
void setup();
void loadResources();
void createWorld();
void loop();
window mWindow;
renderer mRenderer;
class Sprite;
using sprite = std::unique_ptr<Sprite>;
sprite mPlayer;
struct Resource {
std::string name;
std::string path;
};
enum class ResourceType {
TEXTURE, IMAGE, AUDIO
};
std::unordered_map<ResourceType, Resource> mResourceList;
std::unordered_map<std::string, texture> mTextureHolder;
};
/*
* Game.cpp
*/
#include <Game.h>
...
#include "Sprite.h"
Game::Game() {
...
}
void Game::run() {
setup();
loadResources();
loop();
}
void Game::setup() {
...
}
void Game::loadResources() {
...
}
void Game::createWorld() {
...
}
void Game::loop() {
bool stop = false;
SDL_Event e;
while (!stop) {
while (SDL_PollEvent(&e) != 0) {
if (e.type == SDL_QUIT) {
stop = true;
}
}
//clear screen
SDL_RenderClear(mRenderer.get());
//render texture
// this gives error:
mPlayer->renderFrame(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, 0, 0);
//update screen
SDL_RenderPresent(mRenderer.get());
}
}
//default destructor (tried explicit implmentation too)
Game::~Game() = default;
/*
* Sprite.h
*/
#pragm once
#include "SDL.h"
#include <cstdint>
class Sprite {
public:
Sprite(renderer renderer, texture texture, uint32_t width, uint32_t height);
void renderFrame(uint32_t dstX, uint32_t dstY, uint32_t offsetX,
uint32_t offsetY);
void setTexture(texture texture);
private:
renderer mRenderer;
texture mTexture;
uint32_t mWidth;
uint32_t mHeight;
};
/*
* Sprite.cpp
*/
#include "Sprite.h"
Sprite::Sprite(renderer renderer, texture texture, uint32_t width,
uint32_t height) :
mRenderer(renderer), mTexture(std::move(texture)), mWidth(width), mHeight(
height) {
}
void Sprite::renderFrame(uint32_t dstX, uint32_t dstY, uint32_t offsetX,
uint32_t offsetY) {
...
}
void Sprite::setTexture(texture texture) {
...
}

Player sprite not displaying in window

I've been trying to create a sprite in visual studio using sfml and c++, the code itself is running fine and there appear to be no errors.
PLAYER.H
#pragma once
#include "pSprite.h"
#include "Sprite.h"
#include "Enemy.h"
#include "Input.h"
#include <Windows.h>
class Player : public pSprite
{
public:
Input input;
Player(const sf::Vector2f & size = sf::Vector2f(0, 0));
~Player();
pSprite playerSprite;
sf::Texture texture;
float playerWidth;
float playerHeight;
float playerSpeed;
void update(float dt);
void initPlayer(float x, float y);
void kill(); // set to gameover
bool isAlive();
void move();
sf::Vector2f position;
Here is the header file for the Player class which is derived from a pSprite class which itself is derived from a Sprite class in order to get around the "Cannot instantiate abstract class" error.
PLAYER.CPP
void Player::initPlayer(float x, float y)
{
position.x = x;
position.y = y;
playerWidth = 60;
playerHeight = 50;
texture.loadFromFile("player1.png");
playerSprite.setTexture(&texture);
playerSprite.setSize(sf::Vector2f(playerWidth, playerHeight));
playerSpeed = 10;
playerSprite.setPosition(position);
}
Here is the code for the function which loads the texture and should set the sprite.
initPlayer is called in the main function and should set it up ready for all other functions called in the main and for drawing and displaying.

undefined reference inheritance [duplicate]

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 6 years ago.
I created base Sprite class:
#ifndef SPRITE_H_
#define SPRITE_H_
#include<iostream>
#include<SDL2/SDL.h>
#include<SDL2/SDL_image.h>
class Sprite
{
public:
Sprite(SDL_Texture* texture, int x, int y, int w, int h, SDL_Renderer* p_renderer);
virtual ~Sprite();
SDL_Rect getRect();
SDL_Texture* loadImage(std::string file_path);
void drawSprite();
void setPosition(int x, int y);
float getXpos();
float getYpos();
private:
SDL_Renderer* gRenderer;
SDL_Texture* image;
SDL_Rect rect;
//for position update
float x_pos;
float y_pos;
};
#endif /* SPRITE_H_ */
#include "Sprite.h"
Sprite::Sprite(SDL_Texture* texture, int x, int y, int w, int h, SDL_Renderer* p_renderer)
{
gRenderer = p_renderer;
image = texture;
rect.x = x;
rect.y = y;
rect.w = w;
rect.h = h;
x_pos = x;
y_pos = y;
}
Sprite::~Sprite()
{
SDL_DestroyTexture(image);
}
float Sprite::getXpos()
{
return x_pos;
}
float Sprite::getYpos()
{
return y_pos;
}
SDL_Texture* loadImage(std::string file_path, SDL_Renderer* p_renderer)
{
return IMG_LoadTexture(p_renderer, file_path.c_str());
}
void Sprite::drawSprite()
{
SDL_RenderCopy(gRenderer, image, NULL, &rect);
}
Next I created Bird class that is using Sprite class as a base:
/*
* Bird.h
*
* Created on: 1 maj 2016
* Author: Astral
*/
#ifndef BIRD_H_
#define BIRD_H_
#include "Sprite.h"
class Bird: public Sprite
{
public:
Bird(SDL_Texture* texture, int x, int y, int w, int h, SDL_Renderer* p_renderer, float p_speed, float p_acceleration);
virtual ~Bird();
void updateBird(int x, int y);
void handleInput();
private:
float speed, acceleration;
};
#endif /* BIRD_H_ */
#include "Bird.h"
Bird::Bird(SDL_Texture* texture, int x, int y, int w, int h, SDL_Renderer* p_renderer, float p_speed, float p_acceleration):Sprite(texture, x, y, w, h, p_renderer)
{
speed = p_speed;
acceleration = p_acceleration;
}
Bird::~Bird()
{
}
void Bird::updateBird(int x, int y)
{
Sprite::setPosition(x, y);
}
Now I'm getting error and I have no idea why:
../src/Bird.cpp:18: undefined reference to `Sprite::setPosition(int, int)'
Sprite.cpp
1.
void Sprite::setPosition(int x, int y)
{
x_pos = x;
y_pos = y;
}
2.
SDL_Texture* loadImage(std::string file_path, SDL_Renderer* p_renderer)
 ↓
SDL_Texture* Sprite::loadImage(std::string file_path)

SDL 2.0 C++: Polymorphism Vectors, my objects are not loading different images

So I'm basically following a book called SDL Game Development by Shaun Mitchell.
I'm current on page 58, where it tells us how to implement polymorphism.
So far what I have down are:
- Create the main code where we do all our rendering updating etc. (Game.cpp and Game.h)
- Create a Texture manager as a singleton (TextureManager.h and TextureManager.cpp)
- Create a GameObject (GameObject.h and GameObject.cpp)
- Create a Player that inherits GameObject (Player.h and Player.cpp)
So my GameObject class basically has 3 methods: load, draw and update.
Load basically loads an image, and I use my TextureManager to do so.
Draw draws it and update just changes it positions and current frame.
I pass the name of the image which is basically the directory, the renderer and the textureID from the Game class where I call them.
Essentially the problem is that I pass in two different directories into a GameObject
and a Player, but it only loads up the last directory I pass in. As in both GameObject and Player becomes the same image.
So I think the problem lies in Game class, Player class or GameObject class.
I create the objects in Game class, and push them in vector at Game.cpp in init function
Where it says
m_go->load(100, 100, 96, 60, "assets/simba.bmp", "animate",m_pRenderer);
m_player->load(300, 300, 96, 60, "assets/download.bmp", "animate",m_pRenderer);
GameObject.h
#ifndef GAMEOBJECT_H
#define GAMEOBJECT_H
#include <string>
#include <iostream>
#include "SDL_image.h"
#include "TextureManager.h"
class GameObject
{
public:
virtual bool load(int x, int y, int width, int height, std::string name, std::string textureID, SDL_Renderer* pRenderer);
virtual void draw(SDL_Renderer* pRenderer);
virtual void update();
virtual void clean();
protected:
std::string m_textureID;
int m_currentFrame;
int m_currentRow;
int m_x;
int m_y;
int m_width;
int m_height;
};
#endif // GAMEOBJECT_H
GameObject.cpp
#include "GameObject.h"
bool GameObject::load(int x, int y, int width, int height, std::string name, std::string textureID, SDL_Renderer* pRenderer)
{
m_x = x;
m_y = y;
m_width = width;
m_height = height;
m_textureID = textureID;
m_currentRow = 1;
m_currentFrame = 1;
if(!TextureManager::Instance()->load(name, textureID, pRenderer))
{
return false;
}
return true;
}
void GameObject::draw(SDL_Renderer* pRenderer)
{
TextureManager::Instance()->drawFrame(m_textureID, m_x, m_y,m_width, m_height, m_currentRow, m_currentFrame, pRenderer);
}
void GameObject::update()
{
m_x += 1;
m_currentFrame = int(((SDL_GetTicks() / 100) % 6));
}
void GameObject::clean()
{
}
In my Player class, I do the same thing except I use the methods that are already made in GameObject
Player.h
#ifndef PLAYER_H
#define PLAYER_H
#include "GameObject.h"
class Player : public GameObject
{
public:
bool load(int x, int y, int width, int height, std::string name, std::string textureID, SDL_Renderer* pRenderer);
void draw(SDL_Renderer* pRenderer);
void update();
void clean();
};
#endif // PLAYER_H
Player.cpp
#include "Player.h"
bool Player::load(int x, int y, int width, int height, std::string name, std::string textureID, SDL_Renderer* pRenderer)
{
if(!GameObject::load(x, y, width, height, name, textureID, pRenderer))
{
return false;
}
return true;
}
void Player::draw(SDL_Renderer* pRenderer)
{
GameObject::draw(pRenderer);
}
void Player::update()
{
m_currentFrame = int(((SDL_GetTicks() / 100) % 6));
m_x -= 1;
}
void Player::clean()
{
}
This is the part where the images doesn't load the same thing happens in Game.cpp
So I basically created a vector that holds GameObjects, it told me to use it so that I could just for loop through it whenever I want to draw objects
Game.h
#ifndef GAME_H
#define GAME_H
#include <SDL.h>
#include <SDL_image.h>
#include <string.h>
#include <iostream>
#include <vector>
#include "TextureManager.h"
#include "Player.h"
class Game
{
public:
Game() {}
~Game() {}
bool init(const char* title, int xpos, int ypos, int width, int height, int flags);
void render();
void update();
void handleEvents();
void clean();
// a function to access the private running variable
bool running() { return m_bRunning; }
private:
SDL_Window* m_pWindow;
SDL_Renderer* m_pRenderer;
int m_currentFrame;
bool m_bRunning;
GameObject* m_go;
GameObject* m_player;
std::vector<GameObject*> m_gameObjects;
};
#endif
Game.cpp
#include "Game.h"
typedef TextureManager TheTextureManager; // Singleton TextureManager
Game* g_game = 0; // Game Object
bool Game::init(const char* title, int xpos, int ypos, int width,int height, int flags)
{
// attempt to initialize SDL
if(SDL_Init(SDL_INIT_EVERYTHING) == 0)
{
std::cout << "SDL init success\n";
// init the window
m_pWindow = SDL_CreateWindow(title, xpos, ypos,width, height, flags);
if(m_pWindow != 0) // window init success
{
std::cout << "window creation success\n";
m_pRenderer = SDL_CreateRenderer(m_pWindow, -1, 0);
if(m_pRenderer != 0) // renderer init success
{
std::cout << "renderer creation success\n";
SDL_SetRenderDrawColor(m_pRenderer,255,255,255,255);
}
else
{
std::cout << "renderer init fail\n";
return false; // renderer init fail
}
}
else
{
std::cout << "window init fail\n";
return false; // window init fail
}
}
else
{
std::cout << "SDL init fail\n";
return false; // SDL init fail
}
std::cout << "init success\n";
m_go = new GameObject();
m_player = new Player();
m_go->load(100, 100, 96, 60, "assets/simba.bmp", "animate",m_pRenderer);
m_player->load(300, 300, 96, 60, "assets/download.bmp", "animate",m_pRenderer);
m_gameObjects.push_back(m_go);
m_gameObjects.push_back(m_player);
m_bRunning = true; // everything inited successfully, start the main loop
return true;
}
void Game::render()
{
SDL_RenderClear(m_pRenderer); // clear the renderer to the draw color
//m_go.draw(m_pRenderer);
//m_player.draw(m_pRenderer);
for(std::vector<GameObject*>::size_type i = 0; i != m_gameObjects.size(); i++)
{
m_gameObjects[i]->draw(m_pRenderer);
}
SDL_RenderPresent(m_pRenderer); // draw to the screen
}
void Game::clean()
{
std::cout << "cleaning game\n";
SDL_DestroyWindow(m_pWindow);
SDL_DestroyRenderer(m_pRenderer);
SDL_Quit();
}
void Game::handleEvents()
{
SDL_Event event;
if(SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_QUIT:
m_bRunning = false;
break;
default:
break;
}
}
}
void Game::update()
{
//m_currentFrame = int(((SDL_GetTicks() / 100) % 6));
//m_go.update();
//m_player.update();
for(std::vector<GameObject*>::size_type i = 0; i != m_gameObjects.size(); i++)
{
m_gameObjects[i]->update();
}
}
int main(int argc, char* argv[])
{
g_game = new Game();
g_game->init("Chapter 1", 100, 100, 640, 480, 0);
while(g_game->running())
{
g_game->render();
g_game->handleEvents();
g_game->update();
SDL_Delay(10); // add the delay
}
g_game->clean();
return 0;
}
As you can see at the end of the init function, I have m_go load up simba, and m_player load up download. Even though they move in different directions (GameObject moves to the right and Player moves to the left as you can see in the classes in update method).
My program only loads download for both.
I'm not sure if the TextureManager class is related but I'll post it anyway
TextureManager.h
#ifndef TEXTUREMANAGER_H
#define TEXTUREMANAGER_H
#include <SDL.h>
#include <SDL_image.h>
#include <string.h>
#include <iostream>
#include <map>
class TextureManager
{
public:
bool load(std::string fileName,std::string id,SDL_Renderer* pRenderer);
void draw(std::string id, int x, int y, int width, int height, SDL_Renderer* pRenderer, SDL_RendererFlip flip = SDL_FLIP_NONE);
void drawFrame(std::string id, int x, int y, int width, int height, int currentRow, int currentFrame, SDL_Renderer* pRenderer, SDL_RendererFlip flip = SDL_FLIP_NONE);
std::map <std::string, SDL_Texture*> m_textureMap;
static TextureManager* Instance()
{
if(s_pInstance == 0)
{
s_pInstance = new TextureManager();
return s_pInstance;
}
return s_pInstance;
}
//typedef TextureManager TheTextureManager;
protected:
private:
TextureManager(){}
static TextureManager* s_pInstance;
};
#endif // TEXTUREMANAGER_H
TextureManager.cpp
#include "TextureManager.h"
TextureManager* TextureManager::s_pInstance = 0;
bool TextureManager::load(std::string fileName, std::string id, SDL_Renderer* pRenderer)
{
SDL_Surface* pTempSurface = IMG_Load(fileName.c_str());
if(pTempSurface == 0)
{
return false;
}
SDL_Texture* pTexture =
SDL_CreateTextureFromSurface(pRenderer, pTempSurface);
SDL_FreeSurface(pTempSurface);
// everything went ok, add the texture to our list
if(pTexture != 0)
{
m_textureMap[id] = pTexture;
return true;
}
// reaching here means something went wrong
return false;
}
void TextureManager::draw(std::string id, int x, int y, int width, int height, SDL_Renderer* pRenderer, SDL_RendererFlip flip)
{
SDL_Rect srcRect;
SDL_Rect destRect;
srcRect.x = 0;
srcRect.y = 0;
srcRect.w = destRect.w = width;
srcRect.h = destRect.h = height;
destRect.x = x;
destRect.y = y;
SDL_RenderCopyEx(pRenderer, m_textureMap[id], &srcRect,
&destRect, 0, 0, flip);
}
void TextureManager::drawFrame(std::string id, int x, int y, int width, int height, int currentRow, int currentFrame, SDL_Renderer *pRenderer, SDL_RendererFlip flip)
{
SDL_Rect srcRect;
SDL_Rect destRect;
srcRect.x = width * currentFrame;
srcRect.y = height * (currentRow - 1);
srcRect.w = destRect.w = width;
srcRect.h = destRect.h = height;
destRect.x = x;
destRect.y = y;
SDL_RenderCopyEx(pRenderer, m_textureMap[id], &srcRect,
&destRect, 0, 0, flip);
}
You are using "animate" more than once for the textureID - this needs to be unique
Your Code:
m_go->load(100, 100, 96, 60, "assets/simba.bmp", "animate", m_pRenderer);
m_player->load(300, 300, 96, 60, "assets/download.bmp", "animate", m_pRenderer)
What happens is the texture is loaded but it overwrites the existing texture which has the "animate" key in the map. Make them unique and this should resolve your issue.

Undefined reference to a private function of the class

So I'm debugging some horrible code I slung together and finally widdled my way down to (hopefully) the last error in my scene_manager.cpp but I don't seem to understand why I'm getting it.
Error
|22|undefined reference to `scene_manager::applySurface(int, int, SDL_Surface*, SDL_Surface*)'|
scene_manager.cpp
#include "scene_manager.h"
scene_manager::scene_manager(screen_manager* s){
screen = s;
}
void scene_manager::add_object(object_manager* obj){
if(game_objects.find(obj->get_name()) != game_objects.end()){
game_objects[obj->get_name()] = obj;
}
}
void applySurface(int x, int y, SDL_Surface* source, SDL_Surface* destination){
SDL_Rect offset;
offset.x = x;
offset.y = y;
SDL_BlitSurface(source, NULL, destination, &offset);
}
int scene_manager::render(){
for(iter = game_objects.begin(); iter != game_objects.end();iter++){
applySurface(game_objects.at(iter->first)->get_x(),game_objects.at(iter->first)->get_y(),game_objects.at(iter->first)->get_sprite(),screen->get_screen());
}
if(SDL_Flip(screen->get_screen()) == -1){
return 1;
}
return 0;
}
scene_manager.h
#ifndef SCENE_MANAGER_H
#define SCENE_MANAGER_H
#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include "object_manager.h"
#include "screen_manager.h"
#include <map>
#include <string>
class scene_manager{
public:
scene_manager();
scene_manager(screen_manager* s);
void add_object(object_manager* obj);
int render();
private:
std::map<std::string,object_manager*>game_objects;
std::map<std::string,object_manager*>::iterator iter;
screen_manager* screen;
void applySurface(int x, int y, SDL_Surface* source, SDL_Surface* destination);
};
#endif
It seems, this line
void applySurface(int x, int y, SDL_Surface* source, SDL_Surface* destination){
wants to read
void scene_manager::applySurface(int x, int y, SDL_Surface* source, SDL_Surface* destination){
You need the scope resolution operator when you define the applySurfacefunction outside the class.
void scene_manager::applySurface(int x, int y, SDL_Surface* source, SDL_Surface* destination){
//^^^^^^^^^^^^^