How can variables be used by a set of classes? - c++

I have a question which I cannot seem to fathom out, as fairly newish to c++. I have a class, in which a set of variables are declared in the .h file and then initialised in the .cpp file. These same variables are used by a set of 3 other classes - and the compiler has them as out of scope. I am not sure how to link the classes so that the variables are visible by all classes. The code itself is a port from a java based language. I am using openFrameworks as my development environment, and I posted my compiler errors on the forum there if it's helpful to have a look http://www.openframeworks.cc/forum/viewtopic.php?f=8&t=4505
smoke.h
#pragma once
#ifndef SMOKE
#define SMOKE
#include "ofMain.h"
#include "VSquare.h"
#include "VBuffer.h"
#include "Particle.h"
#define LWIDTH 151
#define LHEIGHT 11
class Smoke {
public:
int WIDTH;
int HEIGHT;
int RES;
int PENSIZE;
int PNUM;
VSquare v [LWIDTH] [LHEIGHT] ;
VBuffer vbuf [LHEIGHT][LHEIGHT] ;
Particle p [30000];
int pcount;
int mouseXvel;
int mouseYvel;
int randomGust;
int randomGustMax;
float randomGustX;
float randomGustY;
float randomGustSize;
float randomGustXvel;
float randomGustYvel;
Smoke();
void init();
void draw();
};
#endif
The code in my .cpp file looks like this:
#include "Smoke.h"
Smoke::Smoke(){
WIDTH = 300; //these are the variables that go out of scope in all other classes
HEIGHT = 300;
RES = 2;
PENSIZE = 30;
PNUM = 30000;
pcount = 0;
mouseXvel = 0;
mouseYvel = 0;
randomGust = 0;
}
and one of the classes that I have a problem with:
Particle.h
#ifndef PARTICLE
#define PARTICLE
#include "ofMain.h"
class Particle{
public:
float x;
float y;
float xvel;
float yvel;
float temp;
int pos;
Particle(float xIn = 0, float yIn = 0);
void reposition();
void updatepos();
};
#endif
and the .cpp file where the errors are thrown (excerpt):
#include "Particle.h"
Particle::Particle(float xIn, float yIn){
x = xIn;
y = yIn;
}
void Particle::reposition() {
x = WIDTH/2+ofRandom(-20,20); //eg, WIDTH and HEIGHT not declared in this scope
y = ofRandom(HEIGHT-10,HEIGHT);
xvel = ofRandom(-1,1);
yvel = ofRandom(-1,1);
}
void Particle::updatepos() {
int vi = (int)(x/RES); //RES also not declared in this scope
int vu = (int)(y/RES);
if(vi > 0 && vi < LWIDTH && vu > 0 && vu < LHEIGHT) {
v[vi][vu].addcolour(2);
//and so on...
Really hoping this is something that folks can help me figure out! Thanks so much

If the WIDTH and HEIGHT are supposed to be constants, you can move them out of Smoke and just declare them as constants: const int WIDTH = 300; If they need to be members of Smoke but are still constants, then just declare them as static const int WIDTH = 300 then #include "Smoke.h" in your Particle.cpp and reference it as Smoke::WIDTH. This is like a public static variable in Java. If each Smoke object needs its own width, then you need to tell the Particle object which Smoke it needs, or pass in the WIDTH and HEIGHT to the Particle constructor.

The variables are declared within the scope of the Smoke class, so a) they're not global and b) you'll need an instance of a Smoke object in order to get your hands on them. You'd need to #include "Smoke.h", and create / obtain an instance of a Smoke object and then use e.g. mySmoke.WIDTH.
If you want the variables to be 'global' then you need to declare them outside of the scope of the Smoke class - but you'll still need to #include the relevant header.

An instance of the Smoke class will be needed if you would like to access WIDTH AND HEIGHT as they are currently defined because they are part of the smoke class.
Change your method to receive a Smoke instance and then use it in the method as follows:
void Particle::reposition(Smoke& smoke) {
x = smoke.WIDTH/2+ofRandom(-20,20); //eg, WIDTH and HEIGHT not declared in this scope
y = ofRandom(smoke.HEIGHT-10, smoke.HEIGHT);
xvel = ofRandom(-1,1);
yvel = ofRandom(-1,1);
}
int main() {
Smoke smoke;
Particle particle;
particle.reposition(smoke);
}

Related

Superclass method with subclass data

Good morning.
Im learning some concepts about inheritance and consoles manipulation.
Im pretty beginner as you could see.
So Im trying to have a single character drawn on a console and I want its position to be updated.
Now please note that I know my code is probably very bad in multiple ways and that there are probably hundreds better completely alternative ways to do this, but I want to understand some inheritance concepts first and why it doesn't work the way it is.
So, I draw my player character "X" on the console, then I update its position calling a specific member method to move it.
Now, because I made it that Player class expand DrawConsole class, I would like to call drawConsole on the Player instance.
When I do this, I have that playerA instance have its position coordinates actually updated, but the reference to the player instance have now two member called 'position', as you can see on the image.
How can I say to choice the playerA one without completely remake the code or use a completely different approach?
Or maybe simply I cant and I have actually complete change the approach?
Hope I was able to comunicate what my doubt actually is.
Here is the code
#include <ctime>
#include <cstdlib>
#include "windows.h"
#define width 100
#define height 15
class StaticBuffer
{
public:
StaticBuffer() { srand(time(0)); }
void loadBackGround(CHAR_INFO *backGround, int swidth, int sheight)
{
for (int y = 0; y < sheight; y++)
{
int rnd = rand() % 100 + 1;
for (int x = 0; x < swidth; x++)
if (y == 0 || y == sheight - 1)
{
backGround[y * swidth + x].Char.AsciiChar = (unsigned char)127;
backGround[y * swidth + x].Attributes = (unsigned char)23;
}
else if (x > 4 * rnd && x < (4 * rnd) + 5 || x > 4 * rnd / 2 && x < (4 * rnd / 2) + 5)
{
backGround[y * swidth + x].Char.AsciiChar = (unsigned char)178;
backGround[y * swidth + x].Attributes = (unsigned char)12;
}
else
{
backGround[y * swidth + x].Char.AsciiChar = 32;
backGround[y * swidth + x].Attributes = (unsigned char)3;
}
}
}
private:
};
class DrawConsole
{
public:
DrawConsole()
{
wConsole = GetStdHandle(STD_OUTPUT_HANDLE);
rConsole = GetStdHandle(STD_INPUT_HANDLE);
windowSizeInit = {0, 0, 30, 10};
windowSize = {0, 0, bufferSize.X - 1, bufferSize.Y - 1};
backGround = new CHAR_INFO[bufferSize.X * bufferSize.Y];
obstacle = new CHAR_INFO[bufferSize.X * bufferSize.Y];
inputBuffer = new INPUT_RECORD[4];
drawBackGround.loadBackGround(backGround, bufferSize.X, bufferSize.Y);
nInputWritten = 0;
nOutputWritten = 0;
playerString[0] = L'X';
charLenght = 1;
position = {10,13};
}
void drawConsole()
{
wConsole = GetStdHandle(STD_OUTPUT_HANDLE);
rConsole = GetStdHandle(STD_INPUT_HANDLE);
SetConsoleWindowInfo(wConsole, TRUE, &windowSizeInit);
wConsole = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleScreenBufferSize(wConsole, bufferSize);
SetConsoleWindowInfo(wConsole, TRUE, &windowSize);
WriteConsoleOutputA(wConsole, backGround, bufferSize, {0,0}, &windowSize);
WriteConsoleOutputCharacterW(wConsole, playerString, charLenght, position, &nOutputWritten);
}
void drawChar()
{
WriteConsoleOutputA(wConsole, backGround, bufferSize, {0,0}, &windowSize);
WriteConsoleOutputCharacterW(wConsole, playerString, charLenght, position, &nOutputWritten);
}
protected:
HANDLE wConsole;
HANDLE rConsole;
COORD bufferSize{width, height};
SMALL_RECT windowSizeInit;
SMALL_RECT windowSize;
CHAR_INFO *backGround;
CHAR_INFO *obstacle;
INPUT_RECORD *inputBuffer;
DWORD nInputWritten;
DWORD nOutputWritten;
DWORD charLenght;
StaticBuffer drawBackGround;
wchar_t playerString[2];
COORD position;
};
class Player :public DrawConsole
{
public:
Player()
{
position.X = 20;
position.Y = height - 2;
}
void movePlayerRight()
{
for (int i = 0; i < 3; i++)
position.X += 1;
}
COORD getPositionC() { return position; }
private:
COORD position;
};
Player *playerA = new Player;
DrawConsole *myConsole = new DrawConsole;
int main()
{
myConsole->drawConsole();
while (true)
{
//Sleep(5000);
playerA->movePlayerRight();
playerA->drawChar();
}
}
It depends on what you really want. If the idea is that both variables represent the same concept, you shouldn't have to re-define it in the derived class, because it is "protected" in the base class so the derived class is able to access it.
If the variables represent different things, but they happen to have the same name (which, by the way, would be a bad idea), you can qualify it with the class the variable has been defined in. So, for instance, you could do:
DrawConsole::position.X += 1;
To modify the position variable declared in DrawConsole and:
Player::position.X += 1;
To modify the position variable declared in Player
But, as I said before, I would try to avoid having two variables with the same name because it can easily result in errors.
UPDATE:
If you want to maintain the inheritance as is, just remove the attribute position from Player. The reason is as follows:
Currently, when you call drawChar, you are executing code that is in the DrawConsole class (Player itself does not define a drawChar method). This code cannot access Player::position because a method in a parent class cannot access an attribute in a child class (even if you are calling the method from an instance of the child class), so it only sees DrawConsole::position and that is the variable that it is using.
But when you call movePlayerRigth in an instance of Player, the code that is being executed is a method in the Player class. This method tries to access a position attribute and it finds out that there are two possibilities: DrawConsole::position and Player::position. In this case, it chooses Player::position because it is defined in the same class.
So, you have a method that draws the console based on DrawConsole::position and another method that modifies Player::position. This can't work and in fact if you run it, you will see that the X is not moving.
If you remove the position variable from Player, in movePlayerRight when you try to access the variable position, the code will see that Player does not define a position attribute, but it realizes that its parent class (DrawConsole) does indeed define a position attribute, and with protected access. Being protected means that code in child classes can access it directly, and so movePlayerRight will modify DrawConsole::position. In this case, both drawChar and movePlayerRight will access the same variable and it will work as expected.
So, if you want it this way, remove from the Player class the line:
COORD position;
And you will see that the code compiles and works as expected (the X moves right) because now the code in Player and the code in DrawConsole are accessing both the same variable (DrawConsole::position).

Why is my class variable changing its value between methods?

I am trying to load a bitmap animation to the screen. I have a float variable holdTime that is specified to hold the "holdtime" value for the animation. In my constructor I set the holdtimevariable to 0.1f but when I try to access the method in the class that is using the holdTime variable, the value of holdTime has changed to -107374176f. So somewhere between my constructor call and the method call the value has changed from 0.1f to -107374176f.
To make things a little bit more clearer let me show you some code:
Here is the header file for the Game class, this is where I call the constructor of the Animation class that has the holdTime variable.
#pragma once
#include "Graphics.h"
#include "Surface.h"
#include "Animation.h"
#include "FrameTimer.h"
class Game
{
public:
Game( class MainWindow& wnd );
void Go();
private:
void UpdateModel();
private:
MainWindow& wnd;
FrameTimer ft;
Surface surf = Surface("Test32x48.bmp");
Animation testAnimation = Animation(0, 0, 32, 48, 4, surf, 0.1f);
};
You see that I have this testAnimation at the bottom of the class. The last argument in the constructor call is the value that is ought be in holdTime.
This is how my Animation header file looks like:
#include "Surface.h"
#include "Graphics.h"
#include <vector>
class Animation {
public:
Animation(int x, int y, int width, int height, int count, const Surface& sprite, float holdtime, Color chroma = Colors::Magenta);
void Update(float dt);
private:
void Advance();
private:
std::vector<RectI> frames;
int iCurFrame = 0;
float holdTime = 0;
float curFrameTime = 0.0f;
};
And this is the Animation Cpp file:
#include "Animation.h"
Animation::Animation(int x, int y, int width, int height, int count,
const Surface& sprite, float holdtime, Color chroma)
:
sprite(sprite),
holdTime(holdTime),
chroma(chroma)
{
for (int i = 0; i < count; i++)
{
frames.emplace_back(x + i * width, x + (i + 1) * width,y, y + height);
}
}
void Animation::Update(float dt)
{
curFrameTime += dt;
while(curFrameTime >= holdTime) {
Advance();
curFrameTime -= holdTime;
}
}
void Animation::Advance()
{
if (++iCurFrame >= frames.size()) {
iCurFrame = 0;
}
}
There is only one method that is making use of holdTime and that is the method Update(float dt).
If we go back to the Game class and look at the Game.cpp file:
#include "MainWindow.h"
#include "Game.h"
Game::Game( MainWindow& wnd )
:
wnd( wnd ),
gfx( wnd )
{
}
void Game::Go()
{
UpdateModel();
}
void Game::UpdateModel()
{
testAnimation.Update(ft.Mark());
}
In the Method Go() we call the method UpdateModel() which in turn is calling the Update() method in the animation class. This means that the first method to be executed in the Animation class after the constructor call is the update() method. When I debug the program I can see that the value of holdtime has changed between the constructor call and the Update() method call. But I don't know how since it I am not modifying the value somewhere else. It also seemes that the new value of holdTime is garbage value.
It became a lot of code in this question and it looks a bit messy and even though I lack the skills of writing a good Title I hope I made you somewhat clear what my problem is.
Thanks!
Update:
Here is the code for the FrameTimer class since the value returned from one of its methods is passed in into the Update() method:
FrameTimer.H:
#pragma once
#include <chrono>
class FrameTimer
{
public:
FrameTimer();
float Mark();
private:
std::chrono::steady_clock::time_point last;
};
FrameTimer.cpp:
#include "FrameTimer.h"
using namespace std::chrono;
FrameTimer::FrameTimer()
{
last = steady_clock::now();
}
float FrameTimer::Mark()
{
const auto old = last;
last = steady_clock::now();
const duration<float> frameTime = last - old;
return frameTime.count();
}
Edit:
main.cpp:
int WINAPI wWinMain( HINSTANCE hInst,HINSTANCE,LPWSTR pArgs,INT )
{
MainWindow wnd( hInst,pArgs );
Game game( wnd );
while( wnd.ProcessMessage() )
{
game.Go();
}
}
As you can see the game.Go() method is the first method that is called in main.
Your Animation constructor is at fault:
Animation::Animation(int x, int y, int width, int height, int count,
const Surface& sprite, float holdtime, Color chroma)
:
sprite(sprite),
holdTime(holdTime),
chroma(chroma)
{
for (int i = 0; i < count; i++)
{
frames.emplace_back(x + i * width, x + (i + 1) * width,y, y + height);
}
}
Here you attempt to initialise the member holdTime from the parameter holdTime.
Except, there is no parameter holdTime. There is only the parameter holdtime.
Hence instead you are actually initialising the member holdTime from itself (the next nearest "match" for that name), so it only retains its original, unspecified value (and in fact, reading an uninitialised variable results in your program having undefined behaviour).
So, you see, your member variable doesn't "change" at all — you never set it correctly. You'd have known that had you put some diagnostic output inside that constructor to examine the value and see whether it's what you thought it should be. None of the rest of the code was relevant or necessary.
A properly-configured compiler should have warned you about this.

"Type" does not refer to a value on C++

I'm getting this error at OpenFrameworks artwork. But appears to be a simple C++ issue.
ofVec2f does not refer to a value
Certainly I'm having problems with pointers, but I could't understand why.
I tried to change & -> *
canvas4.cpp
void Canvas4::createStuff() {
ballCollection.clear();
for (int i=0; i<num; i++) {
ofVec2f org;
org.set(ofRandom(edge, ofGetWidth()-edge), ofRandom(edge, ofGetHeight()-edge));
float radius = ofRandom(50, 150);
ofVec2f loc;
loc.set(org.x+radius, org.y);
float offSet = ofRandom(TWO_PI);
int dir = 1;
float r = ofRandom(1);
if (r>.5) dir =-1;
myBall = new Ball(org, loc, radius, dir, offSet);
ballCollection.push_back(* myBall);
}
//
This is the constructor of Ball class;
Ball::Ball(ofVec2f &_org, ofVec2f &_loc, float _radius, int _dir, float _offSet) {
// **** error occur right here.
// use of undeclared "_org"
org = _org;
loc = _loc;
radius = _radius;
dir = _dir;
offSet = _offSet;
}
Header Canvas4.h
class Ball {
public:
ofVec2f org;
ofVec2f loc;
float sz = 10;
float theta, radius, offSet;
int s, dir, d = 60;
Ball(ofVec2f &_org, ofVec2f &_loc, float _radius, int _dir, float _offSet);
};
class Canvas4{
public:
int fc = 100;
int num = 100;
int edge = 200;
vector<Ball> ballCollection;
Boolean save = false;
ofFbo fbo;
Ball *myBall;
Canvas4();
};
This error is also caused if you call a static method using dot(.) operator instead of scope(::) operator.
OP here - In my case, the error happened due to not closing the method properly, the Canvas::createStuff() was missing "}".
Don't much more without looking at the whole of it, but off the top of my head, C++ compilers will cascade variable names as undeclared if their types are also undeclared, although you may see on out there assuming that the typeless variable is an int, leading to all sorts of goofiness.
Beyond that, check to see if ofVec2 is being included by what you have, and see what namespace it is in. Like, if ofVec2f is in some namespace, you will either need to do using namespacename; or, morepreferrably, refer to ofVec2f with its namespace prefix.

C calling a class function inside of another Class that is currently an Object

new here, so be gentle, I'm currently doing my Major Project for my course and, I'm not asking for homework to be done for me, i just can't wrap my head around a strange problem i am having and have not been able to find an answer for it, even on here. I'm using SDL for my Drawing.
I'm doing Object Orientated Programming with my Project or a "state Machine" (which sounds less painful in a newbies mind, believe me), and in the render part of my Class Game1.cpp i am trying to call a Draw Function of my Player Class, but for some unknown reason that i can not fathom, it just skips this function call completely.
I have no errors, i even used breakpoints to find out what was happening, but it just skipped it completely every time, it is drawing the screen black as well without fail. Any help as t why it is skipping this would be really appreciated.
I honestly feel like it's a simple rookie mistake, but any and all scrutiny is welcome of my code, anything i can do to better myself is appreciated.
Game1.cpp:
#include "Game1.h"
#include "PlayerCharacter.h"
Game1::Game1( World * worldObject )
{
//object setup
this->worldObject = worldObject;
setDone (false);
}
Game1::~Game1()
{
}
void Game1::handle_events()
{
//*******************************************
//**//////////////Call Input///////////////**
//*******************************************
//******Check for Keyboard Input*************
//******Check Keyboard Logic*****************
//******Check for Mouse Input****************
//The mouse offsets
x = 0, y = 0;
//If the mouse moved
if (SDL_PollEvent(&worldObject->event))
{
if( worldObject->event.type == SDL_MOUSEMOTION )
{
//Get the mouse offsets
x = worldObject->event.motion.x;
y = worldObject->event.motion.y;
}
}
//******Check Mouse Logic********************
}
void Game1::logic()
{
//*******************************************
//**//////////Collision Detection//////////**
//*******************************************
//******Check Player Bullet Collision Loop***
//Check for collision with enemies
//Check for collision with bitmap mask (walls)
//******Check Enemy Bullet Collision Loop****
//Check for Collision with Player
//Check for collision with bitmap mask (walls)
}
void Game1::render()
{
//*******************************************
//**////////////////Drawing////////////////**
//*******************************************
//******Blit Black Background****************
SDL_FillRect(worldObject->Screen , NULL , 0xff000000);
//******Blit Bitmap Mask*********************
//******Blit Flashlight**********************
//******Blit Map*****************************
//******Blit Pickups*************************
//******Blit Bullets*************************
//******Blit Player**************************
&PlayerCharacter.Draw; // <----- Skips this line completely, no idea why
//******Blit Enemies*************************
//******Blit Blackened Overlay***************
//******Blit HUD*****************************
//******Flip Screen**************************
SDL_Flip(worldObject->Screen);
}
Game1.h
#ifndef __Game1_H_INLUDED__
#define __Game1_H_INLUDED__
#include "GameState.h"
#include "SDL.h"
#include "ImageLoader.h"
using namespace IMGLoader;
class Game1 : public GameState
{
private:
//Menu Image
World * worldObject;
SDL_Rect PauseMenu,Item1Tile,Item2Tile,Item3Tile;
/*bool bPauseMenu, bItem1Tile, bItem2Tile, bItem3Tile;
int ButtonSpace,ButtonSize;
float x,y;
int Alpha1,Alpha2;*/
//Clipping Window
//SDL_Rect sclip,dclip;
public:
//Loads Menu resources
Game1 (World * worldObject);
//Frees Menu resources
~Game1();
//Main loop functions
void handle_events();
void logic();
void render();
};
#endif
PlayerCharacter.cpp
#include "PlayerCharacter.h"
SDL_Rect psclip,pdclip;
PlayerCharacter::PlayerCharacter ( float X, float Y, float dX, float dY, float Angle, float Speed, bool Existance, int Height, int Width, int Health, int Shield, SDL_Surface* Player ):Characters ( X, Y, dX, dY, Angle, Speed, Existance, Height, Width, Health )
{
this->Player = Player;
this->Shield = Shield;
this->Player = load_image("image\Player1.png");
}
void PlayerCharacter::setShield ( int Shield )
{
this->Shield = Shield;
}
int PlayerCharacter::getShield ( void )
{
return Shield;
}
void PlayerCharacter::Draw( )
{
psclip.x = 0; psclip.y = 0; psclip.w = 64; psclip.h = 64;
pdclip.x = 640; pdclip.y = 318; pdclip.w = 64; pdclip.h = 64;
SDL_BlitSurface(Player, &psclip, worldObject->Screen, &pdclip);
}
PlayerCharacter.h
#ifndef __PlayerCharacter_H_INCLUDED__
#define __PlayerCharacter_H_INCLUDED__
#include "Characters.h"
class PlayerCharacter : public Characters
{
private:
int Shield;
SDL_Surface* Player;
World *worldObject;
public:
PlayerCharacter ( float X, float Y, float dX, float dY, float Angle, float Speed, bool Existance, int Height, int Width, int Health, int Shield, SDL_Surface* Player );
void setShield ( int Shield );
int getShield ( void );
void Draw ( );
};
#endif
The line
&PlayerCharacter.Draw; // <----- Skips this line completely, no idea why
is not actually a function call. It's an expression that take the address of the Draw function in the PlayerCharacter class and does nothing with it.
I'm actually kind of surprised it compiles without errors, or at least tons of warnings.
You need to create a PlayerCharacter object, and then call the function in the object.
&PlayerCharacter.Draw is not a function call. PlayerCharacter::Draw() is not a static class method, so you need a PlayerCharacter object to invoke this method on.
You have a class PlayerCharacter, which defines what a PlayerCharacter is and what can be done with it. But as far as I see, you don't have a single PlayerCharacter object, i.e. no player character. If you had one, let's call him pc, then you could draw him with pc.Draw(). For that, you would have to instantiate the class, e.g. via PlayerCharacter pc( ... ), with the ... replaced by some appropriate values for the multitude of constructor parameters you have there. (You really want a default constructor, initializing all those to zero or other appropriate "start" value...)

How to create an object inside another class with a constructor?

So I was working on my code, which is designed in a modular way. Now, one of my classes; called Splash has to create a object of another class which is called Emitter. Normally you would just create the object and be done with it, but that doesn't work here, as the Emitter class has a custom constructor. But when I try to create an object, it doesn't work.
As an example;
Emitter has a constructor like so: Emitter::Emitter(int x, int y, int amount); and needs to be created so it can be accessed in the Splash class.
I tried to do this, but it didn't work:
class Splash{
private:
Emitter ps(100, 200, 400, "firstimage.png", "secondimage.png"); // Try to create object, doesn't work.
public:
// Other splash class functions.
}
I also tried this, which didn't work either:
class Splash{
private:
Emitter ps; // Try to create object, doesn't work.
public:
Splash() : ps(100, 200, 400, "firstimage.png", "secondimage.png")
{};
}
Edit: I know the second way is supposed to work, however it doesn't. If I remove the Emitter Section, the code works. but when I do it the second way, no window opens, no application is executed.
So how can I create my Emitter object for use in Splash?
Edit:
Here is my code for the emitter class and header:
Header
// Particle engine for the project
#ifndef _PARTICLE_H_
#define _PARTICLE_H_
#include <vector>
#include <string>
#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include "image.h"
extern SDL_Surface* gameScreen;
class Particle{
private: // Particle settings
int x, y;
int lifetime;
private: // Particle surface that shall be applied
SDL_Surface* particleScreen;
public: // Constructor and destructor
Particle(int xA, int yA, string particleSprite);
~Particle(){};
public: // Various functions
void show();
bool isDead();
};
class Emitter{
private: // Emitter settings
int x, y;
int xVel, yVel;
private: // The particles for a dot
vector<Particle> particles;
SDL_Surface* emitterScreen;
string particleImg;
public: // Constructor and destructor
Emitter(int amount, int x, int y, string particleImage, string emitterImage);
~Emitter();
public: // Helper functions
void move();
void show();
void showParticles();
};
#endif
and here is the emitter functions:
#include "particle.h"
// The particle class stuff
Particle::Particle(int xA, int yA, string particleSprite){
// Draw the particle in a random location about the emitter within 25 pixels
x = xA - 5 + (rand() % 25);
y = yA - 5 + (rand() % 25);
lifetime = rand() % 6;
particleScreen = Image::loadImage(particleSprite);
}
void Particle::show(){
// Apply surface and age particle
Image::applySurface(x, y, particleScreen, gameScreen);
++lifetime;
}
bool Particle::isDead(){
if(lifetime > 11)
return true;
return false;
}
// The emitter class stuff
Emitter::Emitter(int amount, int x, int y, string particleImage, string emitterImage){
// Seed the time for random emitter
srand(SDL_GetTicks());
// Set up the variables and create the particles
x = y = xVel = yVel = 0;
particles.resize(amount, Particle(x, y, particleImage));
emitterScreen = Image::loadImage(emitterImage);
particleImg = particleImage;
}
Emitter::~Emitter(){
particles.clear();
}
void Emitter::move(){
}
void Emitter::show(){
// Show the dot image.
Image::applySurface(x, y, emitterScreen, gameScreen);
}
void Emitter::showParticles(){
// Go through all the particles
for(vector<Particle>::size_type i = 0; i != particles.size(); i++){
if(particles[i].isDead() == true){
particles.erase(particles.begin() + i);
particles.insert(particles.begin() + i, Particle(x, y, particleImg));
}
}
// And show all the particles
for(vector<Particle>::size_type i = 0; i != particles.size(); i++){
particles[i].show();
}
}
Also here is the Splash Class and the Splash Header.
The second option should work, and I would start looking at compilation errors to see why it doesn't. In fact, please post any compilation errors you have related to this code.
In the meantime, you can do something like this:
class Splash{
private:
Emitter* ps;
public:
Splash() { ps = new Emitter(100,200,400); }
Splash(const Splash& copy_from_me) { //you are now responsible for this }
Splash & operator= (const Splash & other) { //you are now responsible for this}
~Splash() { delete ps; }
};
Well, I managed to fix it, in a hackish way though. What I did was create a default constructor, and move my normal Constructor code into a new function. Then I created the object and called the the new init function to set everything up.