Related
So from an assignment I have from school, I have to make a default constructor that is supposed to set all floats and ints to 0 and all strings to "NA".
Earlier it was pretty easy I had to just do a constructor to set volume to 0, calories to 0 and etc.
My question is,
How does the syntax for setting all floats, and ints to 0 and trying to get strings to all say "NA"?
This is what I had so far
class Candy {
private:
float sweetness;
protected:
string color;
//CONSTRUCTOR//
void setName(string n);
void setFloat(float f);
void setInt(int i);
This is on another cpp file we have to do.
Candy::Candy() {
Candy(string n) {
setName(n);
}
Candy bo("NA");
}
Am I in the right direction? I am really new to this, and I am not very good with syntax. Thanks!
Use the constructors initialization list:
class Candy {
private:
float sweetness;
protected:
string color;
public:
Candy() : sweetness(0.0f), color("NA") { }
};
Or (in C++11 or later), use in-class initializers:
class Candy {
private:
float sweetness = 0.0f;
protected:
string color = "NA";
public:
Candy() = default;
};
Ok lets see your header file:
class Candy {
public:
Candy();
private:
float sweetness;
protected:
string color;
void setName(string n);
void setFloat(float f);
void setInt(int i);
};
You need to declare the constructor in the public section, so you can call it from outside. It has no return type and takes no parameters (it should set everything to 0 on its own and not values you provide it).
In the cpp-file you implement the constructor and the other methods you declared before:
#include "Candy.h" // Or whatever the filename is
Candy::Candy() {
sweetness = 0.0f;
color = "NA";
}
// Implement the other methods, I don't know what they should do
// Example:
void Candy::setName(string n) {
// Do what you want
}
Note you have to implement every method otherwise you will get errors.
I'm making a simple game of catching the fruit, but I've been having troubles with the collision logic and/or using the variables from the classes.
class row
{
public:
int x,y;
void setpoint (int xi, int yi)
{
x=xi;
y=yi;
}
float DownSpeed = 5;
void down () {
y = y+DownSpeed;
if (y==1000) {
y=0;
}
}
};
class fruit:public row
{
public:
void draw()
{
setcolor(11);
circle(x,y,20);
}
};
Then I have other classes to create the catcher, like so:
class catcher
{
protected:
float moveSpeed = 5;
public:
float catchX, catchY;
void setpoint (int xi, int yi)
{
catchX=xi;
catchY=yi;
}
void MoveLeft () {
catchX = catchX - moveSpeed;}
void MoveRight () {
catchX = catchX + moveSpeed;}
};
class character:public catcher
{
public:
void draw()
{
setcolor(15);
circle(catchX,catchY,50);
}
};
How do I call the variables of both circles into creating a collision function? I'm sorry if the codes are messy and ineffective, I'm just starting out and I'm stuck. Thanks!
Since both sets of variables are in the public part of the class, you should be able to create a function independent of either class and should be able to access the variables as long as they are declared.
void CheckCollision(float x, float y, float catchX, float catchY)
{
If(y =< catchY + 5)
{
//y resets
}
}
You’d want to check if it’s within a certain x range too though. I hope this solves your problem.
Since all the functions and variables are public. return the values of x, catchX from the functions modifying them. use the draw functions after you have the modified values.
for example modify your down function like this
int down()
{
y = y+DownSpeed;
if (y==1000)
{
y=0;
}
return y;
}
Modify the other function like wise and you will end up having your x,y and catchX, catchY values. create you collison function with these values.
I have the following classes:
//----------------------------------------------------------------------
// CHARACTER CLASS
//----------------------------------------------------------------------
class Character
{
private:
POINT2f char_position;
public:
VECTOR2f char_velocity;
Character();
~Character();
// Mutators
void SetChar_Position(POINT2f p);
void SetChar_Velocity(VECTOR2f v);
// Accessors
POINT2f GetChar_Position();
VECTOR2f GetChar_Velocity();
};
//----------------------------------------------------------------------
// PLAYER CLASS - INHERITED FROM "CHARACTER" CLASS
//----------------------------------------------------------------------
class Player : public Character
{
private:
public:
int health;
Player();
~Player();
void SetPlayer_Health(int h);
int GetPlayer_Health();
};
So essentially the player class inherits from the character class.
The Character class has member function which lets you set the characters position and velocity, which take in a POINT2f and VECTOR2f.
Within my main bit of code I create a player character Player Player1 and than set the balls velocity and position if a button is pressed:
if (ui.isActive('A')) // Check to see if "A" key is pressed
{
// Player Ball
Player1.SetChar_Velocity.x = -12.0;
Player1.SetChar_Position.x += (Player1.GetChar_Velocity.x*dt);
Player1.SetChar_Velocity.x += (acceleration*dt);
}
I'm currently getting errors that say left of .x must have class/struct/union, so I change Player1.SetChar_Velocity.x = -12.0; to Player1.SetChar_Velocity().x = -12.0; which than brings up the error expression must have class type and to few arguments in function call.
Does anyone know of a method that will allow my to only manipulate the x number of the char_velocity only. also I understand that my code to Set the .x velocity isn't correct because I'm not passing in a VECTOR2f value.
In order to achieve what you want to do, you will want the return type of you Get_ methods to be a reference (wiki). Your code will then look like
class Character
{
private:
POINT2f char_position;
public:
VECTOR2f char_velocity;
// Accessors
POINT2f& GetChar_Position() { return char_position; }
VECTOR2f& GetChar_Velocity() { return char_velocity; }
};
Also, it is often advised or required to be able to preserve const-correctness in your code, so you might want to add
const POINT2f& GetChar_Position() const { return char_position; }
const VECTOR2f& GetChar_Velocity() const { return char_velocity; }
This will allow you to do some calls like
POINT2f current_pos = a_char.GetChar_Position(); // const
a_char.GetChar_Velocity().x += 2; // non-const
Please note that it is often advised to pass the structures as const references instead of copies (although this might not hold true depending on your c++ version and your types, you can see this question for clarification), hence change your
void SetChar_Position(POINT2f pos) { char_position = pos; }
void SetChar_Velocity(VECTOR2f vel) { char_velocity = vel; }
to
void SetChar_Position(const POINT2f& pos) { char_position = pos; }
void SetChar_Velocity(const VECTOR2f& vel) { char_velocity = vel; }
Hi I'm getting the following error and am really unsure why.
class InteSiVis: public ofBaseApp //{
, public ofxMidiListener{
This occurs when I make class inresivis inherit from the ofxMidiListener class and I get the following error in the main source file
int main( ){
ofSetupOpenGL(1920,1080, OF_WINDOW);
ofRunApp( new InteSiVis()); // <-------- The error is here Allocating object of type abstract
}
This is really confusing as I have tried this with another example in the exact way and do not get this error.
class testApp : public ofBaseApp, public ofxMidiListener {
int main(){
ofSetupOpenGL(640, 480, OF_WINDOW);
ofRunApp(new testApp());
}
Could you give me an idea as to why I'm getting this error I'm calling the class in the exact same way. Thanks in advance.
///----------------------------------Edit
InteSiVis.h
class InteSiVis: public ofBaseApp //{
, public ofxMidiListener{
public:
InteSiVis() ;
void setup();
void update();
void draw();
void exit();
void keyPressed(int key);
void keyReleased(int key);
// Make an Array of Particle Systems
vector<FluidBodySim> mArrayFluidBodySim;
FluidBodySim mFluidBodySim ; ///< Simulation of fluid and rigid bodies
int mStatusWindow ; ///< Identifier for status window
unsigned mFrame ; ///< Frame counter
double mTimeNow ; ///< Current virtual time
int mMouseButtons[3] ; ///< Mouse buttons pressed
bool mInitialized ; ///< Whether this application has been initialized
int mScenario ; ///< Which scenario is being simulated now
// Scene stuff
ofEasyCam mEasyCam;
ofLight light;
// Setting Shader stuff
ofShader shader;
ofxPostProcessing post;
// Sound
float * lAudioOut; /* outputs */
float * rAudioOut;
float * lAudioIn; /* inputs */
float * rAudioIn;
int initialBufferSize; /* buffer size */
int sampleRate;
double wave,sample,outputs[2];
maxiSample piano_A1, piano_AS1, piano_B1, piano_C1, piano_CS1, piano_D1, piano_DS1, piano_E1, piano_F1, piano_FS1, piano_G1, piano_GS1;
vector<maxiPitchStretch<grainPlayerWin>*> stretches;
maxiPitchStretch<grainPlayerWin> *ts, *ts2, *ts3, *ts4, *ts5;
int nAverages;
float *ifftOutput;
int ifftSize;
// // Playing the Wav Files
void audioOut(float *output, int bufferSize, int nChannels);
double speed, grainLength, rate;
ofxMaxiFFT fft;
ofxMaxiFFTOctaveAnalyzer oct;
int current;
double pos;
} ;
testApp.h
class testApp : public ofBaseApp, public ofxMidiListener {
public:
void setup();
void draw();
void exit();
void keyPressed(int key);
void keyReleased(int key);
void mouseMoved(int x, int y );
void mouseDragged(int x, int y, int button);
void mousePressed(int x, int y, int button);
void mouseReleased();
stringstream text;
vector<ParticleSystem> ps;
//----------------------Sound---------------------------
void newMidiMessage(ofxMidiMessage& eventArgs);
ofxMidiIn midiIn;
ofxMidiOut midiOut;
ofxMidiMessage midiMessage;
void audioOut(float *output, int bufferSize, int nChannnels);
};
//----------------VIRTUAL FUNCTION
vorticitydistribution.h
class IVorticityDistribution
{
public:
virtual Vec3 GetDomainSize( void ) const = 0 ;
virtual void AssignVorticity( Vec3 & vorticity , const Vec3 & position , const Vec3 & vCenter ) const = 0 ;
} ;
class JetRing : public IVorticityDistribution
{
public:
/*! \brief Initialize parameters for a vortex ring (using a different formula from the other).
The vorticity profile resulting from this is such that the induced velocity is in [0,1].
\param fRadiusSlug - radius of central region where velocity is constant
\param fThickness - thickness of vortex ring, i.e. radius of annular core
\param vDirection - vector of ring axis, also vector of propagation
\param fSpeed - speed of slug
*/
JetRing( const float & fRadiusSlug , const float & fThickness , const Vec3 & vDirection )
: mRadiusSlug( fRadiusSlug )
, mThickness( fThickness )
, mRadiusOuter( mRadiusSlug + mThickness )
, mDirection( vDirection )
{
}
virtual Vec3 GetDomainSize( void ) const
{
const float boxSideLength = 2.f * ( mRadiusOuter ) ; // length of side of virtual cube
return Vec3( 1.0f , 1.0f , 1.0f ) * boxSideLength ;
}
virtual void AssignVorticity( Vec3 & vorticity , const Vec3 & position , const Vec3 & vCenter ) const
{
} ;
This is how things works:
class Base
{
public:
const std::string SayHi() { return "Hi"; } // a normal non-virtual method
virtual std::string GetName() { return ("Base"); } // a normal virtual method
virtual int GetValue() = 0; // a pure virtual method
};
When you declare testApp like this class testApp : public Base { ... };:
normal non-virtual methods are inherited as they are declared inside Base, and are immutable.
normal virtual methods are inherited as they are declared inside Base, you can use them >as they already are declared, or redefine them to fit a particular purpose.
pure virtual methods are not defined, the parent class only say "if you inherit from me you HAVE TO implement those by yourself, strictly matching my prototype (How I defined them)
If you don't follow those rules, you'll get errors.
Now, you have to be sure that there is no pure virtual methodes inside ofBaseApp neither ofxMidiListener that are not implemented into the children class.
Since you state that class testApp doesnt do any error, you must have a pure virtual methods in InteSiVis from the parents classes that you forgot to implement.
Well, you haven't posted enough information to be sure.
Typically when you get a message that the compiler is unable to create a class of abstract type where you are trying to instantiate a class which inherits from some interface, it means that you have not provided an implementation of one of the purely virtual methods specified by the interface.
In your implementation of testApp, have you specified an overide of any methods which you have not specified in InteSiVis? The signatures must match exactly. If they differ by a const, by a ref, a pointer, or any other way, you will get this error.
If this does not solve your problem, please post more complete information. At least the signatures of what have implemented in InteSiVis and testApp.
I've been trying to write something that will let me easily manage OpenGL using classes.
I took an approach of having a Drawable class [which shapes/etc would inherit from, and override a draw function], and then using a Controller class to iterate through a table of Drawable classes and draw them all.
The only issue that I've noticed that the draw() method is being called from the Drawable class, instead of the Rectangle class. ??
class Drawable {
public:
void draw();
};
class Rectangle : public Drawable {
public:
void draw();
};
class Controller {
public:
Drawable ents[200];
int ent_count;
void frame();
void append(Drawable item); // this will add an object onto the list
Controller();
};
void Drawable::draw() {
// this is the default drawing function, which should be overridden
}
void Rectangle::draw() {
// gl functions here
}
void Controller::frame() {
for(int i=0;i<ent_count,i++) {
ents[i].draw(); // draw all entities on the list
}
// here, a timer would loop back the frame() function
}
void Controller::append(Drawable item) {
ents[ent_count++]=item;
}
int main(void) {
Controller main_controller; // create a controller
Rectangle rect; // create a rectangle
main_controller.append(rect); // insert rectangle into controller list
main_controller.frame(); // start the frame loop
}
[if there are minor typing errors in that, it is because it was written as a summary of the method.]
This method that I've tried to use has not been very successful, and I'm pretty sure it has to do with inheritance.
Any ideas?
Entire source code:
#include <iostream>
#include <GL/glfw.h>
#include <GL/gl.h>
class Drawable {
public:
int x,y;
void draw();
void frame();
void create();
void destroy();
};
void Drawable::create() {
}
void Drawable::draw() {
}
class Rectangle : public Drawable {
public:
int w,h;
unsigned short r,g,b;
Rectangle(int x,int y, int w, int h, unsigned short r, unsigned short g, unsigned short b);
void draw();
};
void Rectangle::draw() {
glColor3ub(r,g,b);
glBegin(GL_QUADS);
glVertex2i(x,y);
glVertex2i(x+w,y);
glVertex2i(x+w,y+h);
glVertex2i(x,y+h);
glEnd();
}
Rectangle::Rectangle(int x,int y, int w, int h, unsigned short r, unsigned short g, unsigned short b) {
this->x=x;
this->y=y;
this->w=w;
this->r=r;
this->g=g;
this->b=b;
}
class Controller {
public:
Controller(int w,int h,int fsaa,bool fs,bool vsync,const char* title);
bool running;
int frame_limit;
Drawable entity[200];
int entity_count;
void fev();
void begin();
void bind();
void append(Drawable item);
};
Controller::Controller(int w,int h,int fsaa,bool fs,bool vsync,const char* title) {
int fullscreen= (fs ? GLFW_FULLSCREEN : GLFW_WINDOW);
bool window=glfwOpenWindow(w,h,0,0,0,0,10,10,fullscreen);
glfwSetWindowTitle(title);
frame_limit=120;
entity_count=0;
std::cout << (window ? "Successfully initialized a window.\n" : "Error initializing window!\n");
}
void Controller::begin() {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0,640,480,0,0,5);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClearColor(0.4f,0.4f,0.4f,1.0f);
running=true;
fev();
}
void Controller::append(Drawable item) {
entity[entity_count++]=item;
}
void Controller::fev() {
glClear(GL_COLOR_BUFFER_BIT);
for (int i=0;i<entity_count;++i) {
entity[i].draw();
}
glfwSwapBuffers();
if (frame_limit>0) {
glfwSleep(1000/frame_limit*0.001);
}
if (running) {
if (glfwGetKey(GLFW_KEY_ESC) || !glfwGetWindowParam(GLFW_OPENED)) {
running=false;
}
fev();
} else {
std::cout << "terminated!";
}
}
int main(void) {
glfwInit();
Controller main(640,480,0,false,false,"WindTitle");
Rectangle rect(50,50,50,50,50,50,50);
main.append(rect);
main.begin();
}
I've been trying to write something that will let me easily manage OpenGL using classes.
Newbies often try this. But OpenGL really doesn't translate well into OOP. The problem is, that it's a finite state machine and to map properly to OOP you'd have to to a lot of state tracking between the different classes and instances.
I myself tried at least 3 times to abstract OpenGL into a OOP scheme. It always broke in some way.
Which is not to say that you can not use OOP with OpenGL. You can't just map OpenGL concepts 1:1 into classes.
Regarding your actual problem: Use virtual functions.
As others have mentioned, it would be best to try to use some of the existing wrappers.
That said, you need to use pointers for your list of entities. You are having issues with slicing.
As some of the comments mentioned, you need to make Drawable::draw() virtual so calling draw() on a Drawable will call through to the child implementation. That said, because you are adding your Drawables to a an list of objects, instead of a list of pointers to objects, the objects are being sliced. This means that they are being converted from the child type back into Drawable objects, removing the extra information about specific types.
So instead of this:
Drawable ents[200];
You should do something like this:
std::vector<Drawable*> ents;
or if you have C++11 or Boost:
std::vector<std::shared_ptr<Drawable>> ents;
And your append method would take a reference.
void Controller::append(Drawable &item) {
ents[ent_count++] = &item;
}
or
void Controller::append(Drawable &item) {
ents.push_back(&item);
}
or
void Controller::append(std::shared_ptr<Drawable> item) {
ents.push_back(item);
}
And your render loop would be like this:
for (int i = 0; i < ents.size(); ++i) {
ents[i]->draw();
}
This loop could also be cleaned up to use iterator.
You might want to have a look at Coin3D. It is a large rich set of C++ class wrappers around OpenGL. You clould either look at how they do things of just use it. There are libraries for integration with various windowing systems (Qt, Windows, Cocoa, ...).