I'm using SDL library for my homework at university, the program run smoothly at first but then I created a class using SDL as member like this:
#pragma once
#include <SDL.h>
#include <string>
#include <SDL_image.h>
#include <cstring>
using namespace std;
class Anh
{
public:
SDL_Surface * SURFACE;
SDL_Texture * TEXTURE;
SDL_Rect RECT;
void ganAnh(string a, SDL_Renderer *renderer);
void setRect(int a, int b, int c, int d);
};
and Object.cpp
#include "Object.h"
void Anh::ganAnh(string a, SDL_Renderer * renderer)
{
SURFACE = IMG_Load(a.c_str);
TEXTURE = SDL_CreateTextureFromSurface(renderer, SURFACE);
}
void Anh::setRect(int a, int b, int c, int d)
{
RECT.x = a;
RECT.y = b;
RECT.w = c;
RECT.h = d;
}
This is the declaration of variable in Source.cpp before main:
Anh Image;
Anh Bar;
But when I used this class members in my function
void LoadBar(SDL_Renderer *renderer, string a)
{
SDL_RenderCopy(renderer, Image.TEXTURE, NULL, &Image.RECT);
Bar.RECT.x = (720 - Bar.RECT.w * a.length()) / 2;
for (int i = 0; i < a.length(); i++)
{
SDL_RenderCopy(renderer, Bar.TEXTURE, NULL, &Bar.RECT);
Bar.RECT.x += 50;
if (i == a.length() - 1) Bar.RECT.x = (720 - Bar.RECT.w * a.length()) / 2;
}
}
It reported C2228 left of '.TEXTURE' must have class/struct/union and
C2660 'SDL_RenderCopy': function does not take 2 arguments
Every time I access class member I got that error. Please help me!
I don't see an instantiation for Bar in your function LoadBar.
For Example:
Anh * Bar = new Anh();
Edit:
Ok, the declaration seems to be not the problem.
But, did you have looked here?
https://msdn.microsoft.com/en-gb/library/3y365xw6.aspx
-> So, if you have not declared another Image or Bar variable the access to your member is not correct.
Related
I am coding a terminal based game in c++ using the ncurses library, and I would like the enemy class to be able to access the players location which I can access from within my main function using p->yLoc and p->xLoc, however, I cannot access these variables from within my enemy::move function, as it just returns the error p was not declared in this scope.
Here is my code:
enemy.h:
#ifndef _ENEMY_H_
#define _ENEMY_H_
#include "player.h"
#include <unistd.h>
void Enemy::move(){
int playerY, playerX;
int yMv, xMv;
while (1){
playerY = p->yLoc;
playerX = p->xLoc;
if (playerY > yLoc) {
mvdown();
} else if (playerY < yLoc) {
mvup();
}
if (playerX > xLoc){
mvright();
} else if (playerX < xLoc) {
mvleft();
}
sleep(1);
}
}
player.h
#ifndef _PLAYER_H_
#define _PLAYER_H_
class Player {
public:
Player(WINDOW * win, int y, int x, char c);
void mvup();
void mvdown();
void mvleft();
void mvright();
int getmv();
void display();
int xLoc, yLoc, xMax, yMax;
private:
char character;
WINDOW * curwin;
};
Player::Player(WINDOW * win, int y, int x, char c){
curwin = win;
yLoc = y;
xLoc = x;
getmaxyx(curwin, yMax, xMax);
keypad(curwin, true);
character = c;
}
main.cpp
#include <ncurses.h>
#include "player.h"
#include <string>
#include <ctime>
#include <cstdlib>
#include "enemy.h"
#include <thread>
using namespace std; // I understand this is bad practice
int main(){
// starts ncurses
initscr();
noecho();
cbreak();
int yMax, xMax;
getmaxyx(stdscr, yMax, xMax);
WINDOW * playwin = newwin(20, 50, (yMax/2)-10, 10);
box(playwin, 0, 0);
refresh();
wrefresh(playwin);
if (nodelay (playwin, 1) == ERR) {
// an error has occurred
}
Player * p = new Player(playwin, 1, 1, '#'); // params: (window to display in, starting y, starting x, character to display)
Enemy * e = new Enemy(playwin, 10, 10, 'x'); // same here
thread enemyLoop(&Enemy::move, e); // start the movement for the enemy in a different thread
while(p->getmv() != 'x'){ // leave the game with the key x
// updates the location of the two sprites, and refreshes the window.
p->display();
e->display();
wrefresh(playwin);
}
endwin();
return 0;
}
If Enemy::move is supposed to know about the other players location then you have to pass the player as argument:
void Enemy::move(const Player &p)
e->move(*p);
Then the function can access the players position.
Note: why are you allocating the player and enemy on the heap. there really is no need for that.
I'm getting an error that says:
SZ_GameItem - No appropriate default constructor available.
Here's parts of the codes:
main.cpp:
#include <iostream>
#include "SDL.h"
#include "SDL_image.h"
#include "SDL_mixer.h"
using namespace std;
#include "SZ_timer.h"
SZ_Timer aTimer;
const int DELTA_TIME = 10;
bool done = false;
#include "SZ_Player.h"
SZ_Player examplePlayer;
#include "SZ_GameItem.h"
SZ_GameItem exampleItem;
int main(int argc, char *argv[])
{
if (SDL_Init(SDL_INIT_EVERYTHING) < 0);
// Creates the game window
SDL_Window* game_window = SDL_CreateWindow("Rise", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
// Creates the game render to draw on the game window.
SDL_Renderer* game_renderer = SDL_CreateRenderer(game_window, 0, 0);
// Game Loop
examplePlayer.Init();
while (!done)
{
aTimer.resetTicksTimer();
examplePlayer.Update();
examplePlayer.Input();
exampleItem.Update();
SDL_SetRenderDrawColor(game_renderer, 0, 0, 20, SDL_ALPHA_OPAQUE);
SDL_RenderClear(game_renderer);
examplePlayer.Render(game_renderer);
exampleItem.Render(game_renderer);
SDL_RenderPresent(game_renderer);
// If less time has passed than allocated block, wait difference
if (aTimer.getTicks() < DELTA_TIME)
{
SDL_Delay(DELTA_TIME - aTimer.getTicks());
}
}
SDL_Quit();
// Exits program
return 0;
}
SZ_GameItem.cpp:
#include "SZ_GameItem.h"
SZ_GameItem::SZ_GameItem(int eX, int eY, int eW, int eH)
{
x = eX;
y = eY;
height = eH;
width = eW;
rect.x = x;
rect.y = y;
rect.h = height;
rect.w = width;
velocity.x = 1;
velocity.y = 0;
}
SZ_GameItem::~SZ_GameItem()
{
}
void SZ_GameItem::Input()
{
}
void SZ_GameItem::Update()
{
rect.x = x;
rect.y = y;
rect.h = height;
rect.w = width;
x = x + velocity.x;
y = y + velocity.y;
}
void SZ_GameItem::Render(SDL_Renderer* pRenderer)
{
SDL_SetRenderDrawColor(pRenderer, 255, 255, 255, 255);
SDL_RenderDrawRect(pRenderer, &rect);
}
SZ_GameItem.h:
#ifndef aGameItem
#define aGameItem
#include <iostream>
#include "SDL.h"
#include "SZ_Vector2D.h"
class SZ_GameItem
{
public:
SZ_GameItem(int x, int y, int w, int h);
~SZ_GameItem();
void Update();
void Input();
void Render(SDL_Renderer* aRenderer);
SZ_Vector2D velocity;
int x, y, height, width;
private:
SDL_Rect rect;
};
#endif
When you write this line:
SZ_GameItem exampleItem;
you actually declare and initialize a variable of type SZ_GameItem. And in this case, it implicitly initializes the variable using the default constructor (that is, which takes no argument), but you haven't provided one. A default constructor can be implicitly defined in some cases, but as you provided a user-defined constructor, with signature SZ_GameItem(int x, int y, int w, int h), the default constructor is not implicitly defined.
What needs be done is to either initialize this variable yourself using the constructor your provided, or provide a default constructor.
So I recently downloaded the SDL_2 libraries and all the components and wanted to create a simple GUI/UI that had a "button" with a picture in it. I've looked up a few guides and I've copied and rewritten a lot of code as well. But the latest code sample that I found that worked was in C which contained no classes and was pretty messy. So I rewrote it into C++ but for some reason, it does not want to load the image.
I've purposely not posted any Destructor or any functions that I'm 99% sure was not causing the issue. To the post, to not make it too long, I believe the error is in the const void clear function, but I'm not sure.
Any ideas on why? Been trying to figure this out for a long time now, thank you for any advise / Help :)
Window.h:
#pragma once
#include <SDL.h>
class Window
{
public:
Window(const char* title, int width, int height);
~Window();
void getEvents();
const void clear();
inline const bool isClosed() { return _closed; }
private:
const char* _title = "SDL_6";
int _width = 480;
int _height = 720;
bool _closed = false;
bool init();
SDL_Window *_window = nullptr;
SDL_Renderer *_renderer = nullptr;
SDL_Surface *_surface = nullptr;
};
Window.cpp:
#include "Window.h"
#include <iostream>
#include <SDL_image.h>
#define IMG_PATH "D:\\Picture\\Bowser\\star.jpg"
Window::Window(const char *title, int width, int height) :
_title(title), _width(width), _height(height)
{
_closed = !init();
}
const void Window::clear()
{
int w = 120;
int h = 120;
SDL_Texture *img = NULL;
SDL_Rect texr;
texr.x = 120;
texr.y = 120;
texr.h = 120;
texr.w = 120;
const char* file = "D:\\Pictures\\bowser\\star.jpg";
SDL_Surface *IMG_Load(const char* file);
SDL_RenderClear(_renderer);
SDL_RenderCopy(_renderer, img, NULL, &texr);
img = IMG_LoadTexture(_renderer, IMG_PATH);
SDL_QueryTexture(img, NULL, NULL, &w, &h);
SDL_RenderPresent(_renderer);
}
main.cpp
#include "Window.h"
int main(int argc, char* argv[])
{
Window window("SDL_6", 720, 480);
while (!window.isClosed())
{
window.getEvents();
window.clear();
}
return 0;
}
So the answer was to not declare the:
SDL_Surface IMG_Load(const char file); but to call it instead, also changed the order of the code in the: const void Window::clear() function. Thank you for the answer O'Neil :-)
I am writing a board game using C++ (with SFML2.2 library, Xcode 6.1.1). I created two classes: block and board. The idea is to create a 4x4 vector of blocks inside board. The codes are below:
In block.h
#ifndef __Game1024__block__
#define __Game1024__block__
#include <stdio.h>
#include <iostream>
#endif /* defined(__Game1024__block__) */
using namespace std;
class block{
public:
sf::RectangleShape rect;
sf::Text text;
block();
block(const int X,const int Y,const double size, const double blockSize, const double charSize, const int value, const sf::Color fillColor, const sf::Color textColor);
};
In block.cpp
#include <SFML/Audio.hpp>
#include <SFML/Graphics.hpp>
#include <string>
#include <sstream>
#include "block.h"
using namespace std;
block::block(){}
block::block(const int X,const int Y,const double size, const double blockSize, const double charSize, const int value, const sf::Color fillColor, const sf::Color textColor){
double centerX = (X+0.5)*size;
double centerY = (Y+0.5)*size;
stringstream ss;
ss << value;
string sval = ss.str();
rect.setSize(sf::Vector2f(blockSize,blockSize));
rect.setOrigin(blockSize/2.0, blockSize/2.0);
rect.setPosition(centerX, centerY);
rect.setFillColor(fillColor);
text.setStyle(sf::Text::Bold);
text.setCharacterSize(charSize);
text.setString(sval);
text.setColor(textColor);
text.setOrigin(text.getLocalBounds().width/2.0, text.getLocalBounds().height);
text.setPosition(centerX, centerY);
}
In board.h
#ifndef __Game1024__board__
#define __Game1024__board__
#include <stdio.h>
#endif /* defined(__Game1024__board__) */
#include <vector>
#include "block.h"
using namespace std;
class board{
private:
int winSizeX;
int winSizeY;
int margin;
double charSize;
public:
vector<vector<block>> matrix;
board();
board(int winSizeX_,int winSizeY_,int margin_, double charSize_);
void draw();
};
And in board.cpp
#include "board.h"
//#include <SFML/Audio.hpp>
#include <SFML/Graphics.hpp>
#include "block.h"
using namespace std;
board::board(){}
board::board(int winSizeX_,int winSizeY_,int margin_, double charSize_){
winSizeX = winSizeX_;
winSizeY = winSizeY_;
margin = margin_;
charSize = charSize_;
matrix = vector<vector<block>>(4,vector<block>(4));
double size = winSizeX/4.0; // = 256
double blockSize = size - 2*margin;
const sf::Color fillColor = sf::Color::Red;
const sf::Color textColor = sf::Color::White;
sf::Font font;
if(!font.loadFromFile("./sansation.ttf")){
exit(EXIT_FAILURE);
};
for (int i = 0; i < 4; ++i){
for (int j = 0; j < 4; ++j){
int value = 4*j + i + 1;
matrix[i][j] = block(i,j,size,blockSize, charSize,value,fillColor,textColor);
matrix[i][j].text.setFont(font);
matrix[i][j].text.setOrigin(matrix[i][j].text.getLocalBounds().width/2.0,b[i][j].text.getLocalBounds().height);
}
}
}
The error comes from board.cpp
matrix[i][j] = block(i,j,size,blockSize, charSize,value,fillColor,textColor);
One weird thing is when I typed matrix[i][j] = block, the autofill of my IDE (Xcode) will generate
matrix[i][j] = block(<#const int X#>, <#const int Y#>, <#const double size#>, <#const double blockSize#>, <#const double charSize#>, <#const int value#>, <#const int fillColor#>, <#const int textColor#>)
The last two arguments of constructor block are changed from type sf::Color into int.
If I create a 4x4 vector of blocks in the main.cpp file and call the constructor of block, there is no error...
Any help?
Thanks in advance!
[Update] I attached the scrrenshot of the error message
Thanks #molbdnilo
I made a stupid mistake that I forgot to include the SFML header in "block.h"
#include <SFML/Graphics.hpp>
Now problem solved! Thanks for all advices. I am new to C++ projects, please feel free to speak out all my bad practices in the code. Very helpful!
I'm trying to write a game of checkers in SDL. When I compile my code, I get this error:
std::basic_ifstream>::basic_ifstream(conststd::basic_ifstream> &)' : attempting to reference a deleted function
From what I can find on the web, this means that the compile has helpfully deleted my constructor for some reason, and now it can't find it again. (Bad organization if you ask me) Why could this be?
Board.h:
#include <fstream>
class Board
{
public:
SDL_Surface * boardSurface;
int boardArray[8][8];
private:
std::ifstream boardFile;
SDL_Surface * blackPiece;
SDL_Surface * whitePiece;
SDL_Surface * darkSquare;
SDL_Surface * lightSquare;
public:
Board(char filename[], SDL_PixelFormat * format);
private:
void loadFile(char filename[]);
void makeSurface();
void debugPrint();
void debugBlit();
};
Board.cpp:
#include <SDL.h>
#include <fstream>
#include <iostream>
#include <stdlib.h>
#include "board.h"
#include "loaders.h"
Board::Board(char filename[], SDL_PixelFormat * format)
{
//inits images
loaders imageLoader;
blackPiece = imageLoader.load_image("images/blackPiece.png", format);
whitePiece = imageLoader.load_image("images/whitePiece.png", format);
darkSquare = imageLoader.load_image("images/darkSquare.png", format);
lightSquare = imageLoader.load_image("images/lightSquare.png", format);
boardSurface = SDL_CreateRGBSurface(0, 780, 480, 8, 0, 0, 0, 0);
loadFile(filename);
debugPrint();
debugBlit();
}
void Board::loadFile(char filename[])
{
boardFile.open(filename);
char currentLine[9] = {};
for (int line = 0; line <= 7; line++)
{
boardFile.getline(currentLine, 9);
for (int square = 0; square <= 7; square++)
{
int currentSquare = (int)currentLine[square] - '0';
boardArray[line][square] = currentSquare;
}
}
}
void Board::makeSurface()
{
}
void Board::debugPrint()
{
for (int line = 0; line <= 7; line++)
{
for (int square = 0; square <= 7; square++)
{
std::cout << boardArray[line][square];
}
std::cout << std::endl;
}
}
void Board::debugBlit()
{
for (int y = 0; y <= 4; y++)
{
if (SDL_BlitSurface(blackPiece, NULL, boardSurface, NULL) != 0)
{
std::cout << SDL_GetError();
}
}
}
The error happens because you have an std::ifstream data member, and you are probably trying to copy a Board somewhere, or have some code that requires the copy constructor to be accessible.
std::ifstream boardFile;
The Board compiler-provided copy constructor tries to copy the stream, but the stream is not copyable. So you have to either provide your own copy constructor to do something clever, or remove code that requires the Board copy constructor.