I've gotten decent at c++ over the last year, and this is my most complicated project yet:
#include "math.h"
#include <vector>
#include "DarkGDK.h"
#include "D3DFunc.h"
using namespace std;
class circPhy;
class vector2
{
public:
float x;
float y;
vector2();
vector2(const float& a,const float& b);
vector2 operator+ (const vector2& b); //vector addition
vector2& operator+= (const vector2& b);
vector2 operator- (const vector2& b); //vector subtraction
vector2& operator-= (const vector2& b);
vector2 operator* (const float& b); //vector scalar multiplication
vector2& operator*= (const float& b);
vector2 operator/ (const float& b); //vector scalar division
vector2& operator/= (const float& b);
float operator* (const vector2& b); //dot product
void normalize();
void normalize(const float& dist);
vector2 normalized();
vector2 normalized(const float& dist);
float length();
};
class verletPoint
{
public:
vector2 pos;
vector2 lastpos;
vector2 accel;
verletPoint();
verletPoint(const vector2& position,const vector2& last_position,const vector2& acceleration);
verletPoint(const vector2& position,const vector2& last_position);
verletPoint(const vector2& position);
void updateVerlet(const float timestep);
};
struct collisionDataTemp
{
float depth;
vector2 normal;
circPhy* bod;
};
class circPhy
{
public:
float M;
float R;
bool updateable;
verletPoint center;
collisionDataTemp coll;
circPhy(){}
circPhy(const float center_x,const float center_y,const float radius, bool moveable);
void updateVerlet(const float timestep);
bool checkColl(circPhy* colObj);
bool checkColl(circPhy* colObj,const float dist);
void processColl();
};
void DarkGDK(void)
{
dbSetDisplayMode(640,480,32);
int number_of_bodies = 5;
int lastclick=0;
d3dInit();
dbSyncOn();
dbSyncRate(60);
dbRandomize(dbTimer());
vector<circPhy> r;
int moveobj=0;
for(int n=0;n<number_of_bodies;n++)
r.push_back(circPhy(dbRnd(dbScreenWidth()),dbRnd(dbScreenHeight()),dbRnd(5)+5,true));
while ( LoopGDK ( ) )
{
dbCLS();
dbInk(dbRGB (0, 0, 255),dbRGB (0, 0, 255));
if(!dbSpaceKey())
for(int n=0;n<number_of_bodies;n++)
{
if(dbControlKey()==1)
{
r[n].center.accel=vector2();
r[n].center.lastpos=r[n].center.pos;
}
else
{
vector2 accel=vector2(0.0f,0.0f);
for(int i=0;i<number_of_bodies;i++)
{
if(i!=n && r[i].updateable)
{
vector2 temp = r[i].center.pos-r[n].center.pos;
float dist = temp.length();
temp.normalize(dist);
//now dist is the distance between the circle and the mouse, and accel is a unit vector
dist=r[n].M*r[i].M*.001f/(dist*dist);
//dist=(dist>.1f)?.1f:dist;
temp*=dist;
accel+=temp;
}
}
r[n].center.accel=accel;
}
float* t=&r[n].center.pos.x;
*t=(*t>=0)? ((*t<=dbScreenWidth())?*t:dbScreenWidth()) :0;
t=&r[n].center.pos.y;
*t=(*t>=0)? ((*t<=dbScreenHeight())?*t:dbScreenHeight()) :0;
for(int i=0;i<number_of_bodies;i++)
{
if(r[n].checkColl(&r[i]))
{r[n].processColl();}
}
r[n].updateVerlet(2);
}
if(dbMouseClick() && lastclick!=dbMouseClick())
{
if(dbMouseClick()==1)
{
r.push_back(circPhy(dbMouseX(),dbMouseY(),dbRnd(5)+5,true));
number_of_bodies++;
}
if(dbMouseClick()==2)
{
r.push_back(circPhy(dbMouseX(),dbMouseY(),dbRnd(5)+5,false));
number_of_bodies++;
}
if(dbMouseClick()==4)
{
r.push_back(circPhy(dbMouseX(),dbMouseY(),dbRnd(100)+5,false));
number_of_bodies++;
moveobj=r.size()-1;
}
}
if(dbMouseClick()==4)
{
r[moveobj].center.pos=vector2(dbMouseX(),dbMouseY());
}
if(lastclick==4 && dbMouseClick()!=4)
{
r.erase(r.begin()+moveobj);
number_of_bodies--;
}
lastclick=dbMouseClick();
for(int n=0;n<number_of_bodies;n++)
d3dCircle(r[n].center.pos.x,r[n].center.pos.y,r[n].R,0);
dbText(0,0,"number of bodies:");
dbText(0,16,dbStr(number_of_bodies));
dbText(0,32,"framerate (capped @ 60):");
dbText(0,48,dbStr(dbScreenFPS()));
dbCircle(365,351,63);
dbSync();
}
return;
}
//class vector2
//{
vector2::vector2()
{
x = y = 0.0f;
}
vector2::vector2(const float& a,const float& b)
{
x=a;
y=b;
}
vector2 vector2::operator+ (const vector2& b)
{
vector2 temp;
temp.x=x+b.x;
temp.y=y+b.y;
return temp;
}
vector2& vector2::operator+= (const vector2& b)
{
if(this!=&b)
{
x=x+b.x;
y=y+b.y;
}
return *this;
}
vector2 vector2::operator-(const vector2& b)
{
vector2 temp;
temp.x=x-b.x;
temp.y=y-b.y;
return temp;
}
vector2& vector2::operator-=(const vector2& b)
{
if(this!=&b)
{
x=x-b.x;
y=y-b.y;
}
return *this;
}
float vector2::operator* (const vector2& b)
{
return (x*b.x+y*b.y);
}
vector2 vector2::operator* (const float& b)
{
vector2 temp;
temp.x=x*b;
temp.y=y*b;
return temp;
}
vector2& vector2::operator*= (const float& b)
{
x=x*b;
y=y*b;
return *this;
}
vector2 vector2::operator/ (const float& b)
{
vector2 temp=vector2(0.0f,0.0f);
if(b>0)
{
temp.x=x/b;
temp.y=y/b;
}
return temp;
}
vector2& vector2::operator/= (const float& b)
{
if(b>0)
{
x=x/b;
y=y/b;
}
return *this;
}
void vector2::normalize()
{
float dist = sqrt(x*x+y*y);
x/=dist;
y/=dist;
}
void vector2::normalize(const float& dist)
{
x/=dist;
y/=dist;
}
vector2 vector2::normalized()
{
float dist = sqrt(x*x+y*y);
return vector2(x/dist,y/dist);
}
vector2 vector2::normalized(const float& dist)
{
return vector2(x/dist,y/dist);
}
float vector2::length()
{
float n=x*x+y*y;
return sqrt(n>0?n:0);
}
//}
verletPoint::verletPoint()
{
vector2 pos (0.0f,0.0f);
vector2 lastpos (0.0f,0.0f);
vector2 accel (0.0f,0.0f);
}
verletPoint::verletPoint(const vector2 & position, const vector2 & last_position, const vector2 & acceleration)
{
pos=position;
lastpos=last_position;
accel=acceleration;
}
verletPoint::verletPoint(const vector2 & position,const vector2 & last_position)
{
pos=position;
lastpos=last_position;
vector2 accel (0.0f,0.0f);
}
verletPoint::verletPoint(const vector2 & position)
{
pos=position;
lastpos=position;
vector2 accel (0.0f,0.0f);
}
void verletPoint::updateVerlet(const float timestep)
{
vector2 temp=pos;
pos+=pos-lastpos+accel*timestep*timestep;
lastpos=temp;
}
circPhy::circPhy(const float center_x,const float center_y,const float radius, bool movable)
{
M=radius*radius;
R=radius;
updateable=movable;
center=verletPoint(vector2(center_x,center_y),vector2(center_x,center_y));
}
void circPhy::updateVerlet(const float timestep)
{
if(updateable)
center.updateVerlet(timestep);
}
bool circPhy::checkColl(circPhy* colObj)
{
if(this!=colObj)
{
vector2 n = colObj->center.pos - center.pos;
float dist=n.length();
if(dist>=R+colObj->R)
return false;
n.normalize();
coll.normal = n;
coll.depth = R+colObj->R-dist;
coll.bod = colObj;
return true;
}
else return false;
}
bool circPhy::checkColl(circPhy* colObj,const float dist)
{
vector2 n = colObj->center.pos - center.pos;
if(dist>=R+colObj->R)
return false;
n.normalize(dist);
coll.normal=n;
coll.depth=R+colObj->R-dist;
coll.bod=colObj;
return true;
}
void circPhy::processColl()
{
if(updateable)
{
if(coll.bod->updateable)
{
vector2 movement = coll.normal*coll.depth*.5f;
center.pos-=movement;
coll.bod->center.pos+=movement;
}
else
{
vector2 movement = coll.normal*coll.depth;
center.pos-=movement;
}
}
}
seen in action here:
http://www.youtube.com/watch?v=28G7k0MTfxg
So, I'm decent at c++. But... that program isn't too complicated. The hardest c++ syntax thing in there might be operator overloading or vectors. It's good, but I don't really think it's enough to say that I know c++. What about stuff like multithreading, or any of the many c++ keywords I don't understand? How can I learn about stuff like this? Not only am I interested in becoming a better programmer, but all of these syntax thingies I don't know of surely have a use, for better memory management, less errors, easier debugging, more shortcuts, etc. Basically, what are some good projects, or do you have some good tips on how I should proceed from here? I don't really want to start a project and then figure out I'm doing something completely wrong - I could have memory leaks, bad coding, and possible crash points all over the place without knowing it (I think I have some unsolved synchronization problems in some of my java programs)
Even more of a specific and direct question: What are some of the biggest problems, advancements, or learning leaps you've had in c++?
Is't life, I ask, is't even prudence, to bore thyself and bore thy students?