VertexArray declaration inside a class - c++

I'm trying to create a struct containing a point primitive and a method to draw it. However, declaration of a sf::VertexArray outside of method doesn't seem to work. The exactly same declaration inside a method works perfectly fine. Here are the code samples and the error. SFML version 2.1
edit: in both cases using namespace std; is used.
Works:
struct Point
{
int dot_x, dot_y;
sf::Color dot_color;
Point (int x = 50, int y = 50, sf::Color color = sf::Color::Green) {
dot_color = color;
dot_x = x;
dot_y = y;
}
virtual void draw() {
sf::VertexArray dot(sf::Points, 1);
dot[0].position = sf::Vector2f(dot_x,dot_y);
dot[0].color = dot_color;
window.draw(dot);
}
};
Does not work:
struct Point {
sf::VertexArray dot(sf::Points, 1);
Point (int x = 50, int y = 50, sf::Color color = sf::Color::Green) {
dot[0].position = sf::Vector2f(x,y);
dot[0].color = color;
}
virtual void draw() {
window.draw(dot);
}
};
Errors (all pointing at the VertexArray declaration string):
E:\CodeBlocks\Labs\sem3\sfml1\main.cpp|64|error: 'sf::Points' is not a type|
E:\CodeBlocks\Labs\sem3\sfml1\main.cpp|64|error: expected identifier before numeric constant|
E:\CodeBlocks\Labs\sem3\sfml1\main.cpp|64|error: expected ',' or '...' before numeric constant|

sf::VertexArray dot(sf::Points, 1);
This is a declaration of a variable with an initialiser: you can only write those at namespace or function scope. The parser is suitably confused, as you have it in your class scope. It's basically trying to parse it as a function declaration but, since neither sf::Points nor 1 are types, this approach ultimately fails also.
You should use the constructor's member initialiser list here:
struct Point
{
sf::VertexArray dot;
Point (int x = 50, int y = 50, sf::Color color = sf::Color::Green)
: dot(sf::Points, 1)
{
dot[0].position = sf::Vector2f(x,y);
dot[0].color = color;
}
virtual void draw()
{
window.draw(dot);
}
};

Related

c++: Proper way to initialize static fields of member struct

I got this:
// mouse.h
class Mouse {
private:
struct Pos {
static GLfloat x;
static GLfloat y;
};
static Pos last;
}
and this:
// mouse.cpp
// 1)
Mouse::Pos Mouse::last = {};
// 2)
Mouse::Pos Mouse::last = { 0.0, 0.0 };
// 3)
Mouse::last.x = 0.0f;
Mouse::last.y = 0.0f;
1), 2) and 3) are the attempts I've made at initializing that thing. I understand that the header should declare that last is static, and that the source should initialize it, but something has been wrong with all my attempts. Could someone please tell me the correct way to do such a thing? Am I missing some very important point? Is this nonsense? It is important that the fields are static. Thanks.
You don't need to declare Pos content as static.
// mouse.h
class Mouse {
private:
struct Pos {
GLfloat x;
GLfloat y;
};
static Pos last;
}
Mouse::Pos Mouse::last = { 0.0, 0.0 };
This should work too
It is important that the fields are static.
Then last will not have any state. It will simply refer to the static x and y values inside Mouse::Pos.
#include "mouse.h"
GLfloat Mouse::Pos::x = 10;
GLfloat Mouse::Pos::y = 10;
Mouse::Pos Mouse::last{};
wandbox example
The following asserts pass:
assert(Mouse::last.x == 10);
assert(Mouse::last.y == 10);

Passing an enum of a structure to other functions and assigning the values

I'm writing a Snake game in C++, I have a structure for a section of the snake which contains, data such as x position, y position, direction etc.
I have it all working, setting all the data to integers, I just would like to change some of the data types to enum's because it looks a lot neater and easier to understand.
I've tried lots and looked online but I can't seem to find anything.
This is some of the Structure:
struct SnakeSection
{
int snakePosX;
int snakePosY;
int SectionType;
// Tail = 0, Body = 1, Head = 2
int animation;
enum Direction
{
Up = 0,
Right = 1,
Down = 2,
Left = 3
};
};
My attempt at trying to pass one of the Directions to another function:
void PlayerSnake::createSnake()
{
// Parameters are direction, x and y pos, the blocks are 32x32
addSection(SnakeSection::Direction::Right, mStartX, mStartY, 2);
}
Then I tried setting the direction to the one passed in in that function:
void PlayerSnake::addSection(SnakeSection::Direction dir, int x, int y, int type)
{
//Create a temp variable of a Snake part structure
SnakeSection bufferSnake;
bufferSnake.Direction = dir;
bufferSnake.animation = 0;
//is it head tail or what? This is stored in the Snake section struct
//TODO Add different sprites for each section
bufferSnake.SectionType = type;
//assign the x and y position parameters to the snake section struct buffer
bufferSnake.snakePosX = x;
bufferSnake.snakePosY = y;
//Push the new section to the back of the snake.
lSnake.push_back(bufferSnake);
}
error: invalid use of enum SnakeSection::Direction
Thanks
The error on the following line ...
bufferSnake.Direction = dir;
... is reasoned, that besides declaring the enum type, you'll still have to have a class member variable to store it:
struct SnakeSection
{
int snakePosX;
int snakePosY;
int SectionType;
// Tail = 0, Body = 1, Head = 2
int animation;
enum Direction
{
Up = 0,
Right = 1,
Down = 2,
Left = 3
};
Direction direction_; // <<<<<<<<<<<<<< THAT'S WHAT'S MISSING IN YOUR CODE
};
And refer to
bufferSnake.direction_= dir; // <<<<<<<<<<<<<< THAT'S THE MEMBER VARIABLE YOU'LL
// HAVE TO REFER TO!

Why do I get an EXC_BAD_ACCESS when reading back a private class variable?

I have a Rectangle class shown below:
Header:
class Rectangle: public Polygon {
private:
float _width, _height;
public:
Rectangle(float width, float height);
float getWidth(float* width) const;
float getHeight(float* height) const;
bool isCollidingWith(Rectangle* other) const;
};
Selected Implementation:
Rectangle::Rectangle(float width, float height) : Polygon(explodeRect(width, height, new struct vertex[4]), 4) {
printf("creating rect %f x %f\n", width, height);
_width = width;
_height = height;
printf("set _width to %f\n", _width);
}
float Rectangle::getWidth(float* width) const {
printf("_w: %f\n", _width);
*width = _width;
return *width;
//return (*width = _width);
}
float Rectangle::getHeight(float* height) const {
return (*height = _height);
}
I initialize an instance of the Rectangle class, and the output indicates that the _width variable is being correctly assigned. However, when I later try to read the variable using the getWidth method, I get an EXC_BAD_ACCESS error on the line:
printf("_w: %f\n", _width);
Why can I no longer read this variable? I get the same problem with the _height variable as well.
EDIT: I would also like to note that if I skip reading the width, I get an error trying to read public variables directly from the object, e.g. when I try to read its x position with obj->x.
EDIT 2: Could this be from the fact that the object is an instance of a subclass of Rectangle, and this subclass is defined in a different file than Rectangle is? I am also reading the values from a third file.
EDIT 3: More code below.
I am trying to re-create Tetris with OpenGL. In my display method, I have this code to draw the rectangles:
if(fallingBlock != nullptr) {
printf("drawing falling block at (%f, %f)\n", fallingBlock->x, fallingBlock->y);
draw(fallingBlock);
}
fallingBlock is defined as a global variable at the top of my file:
Block* fallingBlock;
From my main, I call an initVars method that subsequently calls a startDroppingBlock method. Here it is:
void startDroppingBlock() {
Block* block = availableBlocks[random() % numAvailableBlocks].copy();
block->x = 0.5;
block->y = SCREEN_TOP;
block->dy = -0.01f;
//printf("copied block is at (%f, %f)\n", block->x, block->y);
fallingBlock = block;
}
And here is my block drawing method:
void draw(Block* obj) {
bool shape[3][3];
obj->getShape(shape);
//printf("got shape: {%d, %d, %d}, {%d, %d, %d}, {%d, %d, %d}\n", shape[0][0], shape[0][1], shape[0][2], shape[1][0], shape[1][1], shape[1][2], shape[2][0], shape[2][1], shape[2][2]);
/*float pieceWidth;
obj->getWidth(&pieceWidth);
pieceWidth /= 3.0f;*/
float pieceWidth = obj->getWidth();
for(unsigned int i=0; i<3; i++) {
for(unsigned int j=0; j<3; j++) {
if(shape[i][j]) {
Square rect = Square(pieceWidth);
rect.x = obj->x + pieceWidth * j;
rect.y = obj->y + pieceWidth * i;
rect.color = obj->color;
draw(&rect);
}
}
}
}
I get an EXC_BAD_ACCESS error on the line [...]. Why can I no longer read this variable? I get the same problem with the _height variable as well. [later...] I have tried both float pieceWidth; obj->getWidth(&pieceWidth); and obj->getWidth(new float) - the actual error is on the line where I read _width, before I even use the passed in pointer. [later...] I modified the getWidth and getHeight methods to just simply return _width and _height. Now I just get an error on return _width;
In this case I see you are using a Rectangle* pointer as obj->getWidth which can as well lead to a bad access error if obj is not a valid pointer.
It is to note that I don't quite understand your getter method at all. A simplified (and possibly standard) version of it might be:
float Rectangle::getWidth() const {
return _width;
}
With the only difference that when you used:
// float a;
// float b;
a = rect.getWidth(&b);
you can now do:
// float a;
// float b;
a = b = rect.getWidth();
which is possibly cleaner and will surely don't cause such an error. A good rule of thumb is never to use pointers when possible. If you need to modify a variable inside a function just use a reference.

Can't pass a string to my class function

I have a class with this function:
void Render(SDL_Surface *source,SDL_Surface *destination,string img)
{
SDL_Rect offset;
offset.x = m_x;
offset.y = m_y;
source = IMG_Load(img);
offset.w = source->w;
offset.h = source->h;
}
For some reason though even with include <string> at the top of the header file it won't allow it. I get:
Identifier, "string" is undefined.
Im passing the data like this on my main file:
btn_quit.Render(menu,screen,"button.png");
When i execute i get :
'Button::Render' : function does not take 3 arguments
But this site says string is the correct syntax for the data type (at the bottom): http://www.cplusplus.com/doc/tutorial/variables/
Can some one explain what I am doing wrong ?
I may suggest you change Render function to below:
void Render(SDL_Surface *source,SDL_Surface *destination,const std::string& img)
{
SDL_Rect offset;
offset.x = m_x;
offset.y = m_y;
source = IMG_Load(img.c_str());
offset.w = source->w;
offset.h = source->h;
}
use std::string instead of string
pass img reference instead of passing by value
change from IMG_Load(img); to IMG_Load(img.c_str());

Using inheritance to pass a non-static variable between classes

I'm researching UI's as a portfolio project and I ran into a little bit of trouble when it comes to inheritance. The problem I'm facing is this: I have two classes, R_GUI, in which I draw the form, and Button, where I draw the buttons. I want the Buttons to be positioned inside the FORM. I store the FORM position as form_x, and form_y. Here are my two classes:
class R_GUI
{
private:
bool get_pos_only_once;
bool move_form;
public:
int form_x, form_y;
int form_height, form_width;
int handle_bar_y;
inline void Form(int pos_x, int pos_y, int height, int width);
//inline void Button(int id, string ButtonText, int pos_x, int pos_y);
inline void Update_form(void);
inline void UPDATE(void);
inline ~R_GUI( );
inline R_GUI( )
{
d3dInit();
get_pos_only_once = false;
move_form = false;
form_x = 0;
form_y = 0;
handle_bar_y = 40;
}
};
and the Button class:
class Button: public R_GUI
{
private:
int b_form_x, b_form_y;
int b_handle_y;
int button_width, button_height;
public:
inline void Draw(string ButtonText, int b_pos_x, int b_pos_y);
Button()
{
b_form_x = R_GUI::form_x;
b_form_y = R_GUI::form_y;
b_handle_y = 20;
button_width = 90;
button_height = 35;
}
~Button();
};
As you can see, I'm trying to give b_form_x the value of form_x (which is a variable from R_GUI). form_x has a value, given in Form( );:
inline void R_GUI::Form(int pos_x, int pos_y, int height, int width)
{
if(get_pos_only_once == false)
{
form_x = pos_x;
form_y = pos_y;
form_height = height;
form_width = width;
get_pos_only_once = true;
}
//Create the form outline
d3dLine(pos_x,pos_y,pos_x+width,pos_y,dbRGB(50,50,50));
d3dLine(pos_x,pos_y,pos_x,pos_y+height,dbRGB(50,50,50));
d3dLine(pos_x+width,pos_y,pos_x+width,pos_y+height,dbRGB(50,50,50));
d3dLine(pos_x,pos_y+height,pos_x+width,pos_y+height,dbRGB(50,50,50));
//Create the handle bar
d3dLine(pos_x,pos_y+handle_bar_y,pos_x+width,pos_y+handle_bar_y,dbRGB(50,50,50));
//Fill the Handlebar;
d3dBox(pos_x,pos_y,pos_x+width,pos_y+handle_bar_y,dbRGB(3,3,3),dbRGB(3,3,3),dbRGB(3,3,3),dbRGB(3,3,3));
}
Yet, when I update the Form's Position, R_GUI::form_x value doesn't change. Any idea what I am doing wrong?
You don't want to have a second variable in your subclass (b_form_x). Eliminate it entirely. Instead, you want to use this->form_x, which in the Button will be inherited from R_GUI. The same applies for b_form_y.
this refers to the current instance of an object, and contains not only your local member variables but also any member variables inherited from classes all the way up the hierarchy as well.