Permalink
Browse files

Working on Collision, ropeJoint and Balloon GOO

  • Loading branch information...
1 parent 50084bf commit d9803cbb819f5f5adf3c019be784b94f1268426c Martino Ferrari committed Apr 13, 2012
Showing with 287 additions and 162 deletions.
  1. +63 −37 balloongoo.cpp
  2. +6 −4 balloongoo.h
  3. +47 −78 collisionlistener.cpp
  4. +1 −0 collisionlistener.h
  5. +1 −0 dynamicgoo.cpp
  6. +1 −0 fixedgoo.cpp
  7. +6 −4 goo.cpp
  8. +6 −3 goo.h
  9. +5 −0 joint.cpp
  10. +3 −2 joint.h
  11. +74 −20 level.cpp
  12. +3 −1 level.h
  13. +4 −4 mainwidget.cpp
  14. +1 −0 removablegoo.cpp
  15. +66 −9 ropejoint.cpp
View
100 balloongoo.cpp
@@ -1,55 +1,81 @@
#include "balloongoo.h"
+#include "goo.h"
#include "tools.h"
BalloonGoo::BalloonGoo(b2World *world, QPoint p, int radius, QObject *parent):
- Goo(radius,parent)
+ DynamicGoo(world,p,radius,parent)
{
- b2BodyDef def; //body definition
- def.awake=true; //is active
- def.type=b2_dynamicBody; //is dynamci (react at force impulse and collision)
- def.position=toVec(p); //set the position
- body=world->CreateBody(&def); //create the physical body
- b2CircleShape shape; //define the shape
- shape.m_p.SetZero(); //position of the shape
- shape.m_radius=radius; //radius
- b2FixtureDef fixDef; //Definition of the phisical parameters
- fixDef.restitution=0.3; //collision restitution
- fixDef.density=0.0; //density
- fixDef.friction=0.8; //friction
- fixDef.shape=&shape; //assign the shape
- fixDef.userData=this; //assign a copy of the object at the body so during the contact is possible to know the info of the goo
- body->CreateFixture(&fixDef); //create the fixture
- body->SetLinearDamping(0.1);//Not sure about this parameter
-// b2MassData* mass=new b2MassData();
-// mass->center.SetZero();
-// mass->I=0.;
-// mass->mass=10.0 ;
-// body->SetMassData(mass);
- moovable=true; //flags
- dragable=true;
- active=false;
- maxJoints=7; //parameters
+ color=Qt::yellow;
+
+ maxJoints=1; //parameters
+ type=BALOON;
}
void BalloonGoo::paint(QPainter &p){
+ if (isSleeping()) emit checkForNeighbors(getPPosition());
+
+ this->moveToTarget();
+
p.setPen(Qt::darkGray);
- p.setBrush(Qt::yellow);
- p.drawEllipse(toPoint(body->GetPosition()),getRadius(),getRadius());
+
+ p.setBrush((isSleeping() ? Qt::darkGray : Qt::yellow));
+ if (!active){
+ p.drawEllipse(toPoint(body->GetPosition()),getRadius(),getRadius());
+ }
+ else{
+ p.drawEllipse(toPoint(body->GetPosition()),2*getRadius(),2*getRadius());
+ }
}
-void BalloonGoo::paintDebug(QPainter &p){
- p.setPen(Qt::darkGray);
- p.setBrush(Qt::transparent);
+bool BalloonGoo::createLink(Goo *goo){
+ if (!active && nJoints()<maxJoints){
+ active=true;
+ body->SetGravityScale(-0.5);
+ if (sleeping) sleeping=false;
+ links.push_back(goo);
+ if (following) stopFollow();
+ return true;
+ }
+ else return false;
+}
- p.drawEllipse(toPoint(body->GetPosition()),getRadius(),getRadius());
+bool BalloonGoo::destroyLink(Goo *goo){
+ if (isLinked(goo)){
+ links.removeAt(links.indexOf(goo));
+ emit this->destroyJoint(this,goo);
+ active=false;
+ body->SetGravityScale(1);
+ if (!isDragging() && !hasJoint()) body->SetActive(false);
+ return true;
+ }
+ else return false;
+}
+
+void BalloonGoo::drag(){
+ onGround=false;
+ stopFollow();
+ if (!dragging){
+ info.gScale=body->GetGravityScale();
+ info.speed=body->GetLinearVelocity();
+ info.aForce=body->GetAngularVelocity();
+ }
+ body->SetActive(false);
+ if (hasJoint()) {
+ for (int i=0;i<links.count();i++) destroyLink(links.at(i));
+ }
+ dragging=true;
}
-void BalloonGoo::contactGround(){
- //TODO
+bool BalloonGoo::isDragable(){
+ if (!isSleeping()) return true;
+ else return false;
}
-void BalloonGoo::contactGround(QPoint p){
- if (p.isNull()) return;
- //TODO
+
+void BalloonGoo::paintDebug(QPainter &p){
+ p.setPen(Qt::darkGray);
+ p.setBrush(Qt::transparent);
+
+ p.drawEllipse(toPoint(body->GetPosition()),getRadius(),getRadius());
}
View
10 balloongoo.h
@@ -1,15 +1,17 @@
#ifndef BALLOONGOO_H
#define BALLOONGOO_H
-#include "goo.h"
+#include "dynamicgoo.h"
#include <Box2D/Box2D.h>
-class BalloonGoo : public Goo
+class BalloonGoo : public DynamicGoo
{
public:
BalloonGoo(b2World* world, QPoint p=QPoint(0,0),int radius=15,QObject *parent = 0);
- void contactGround();
- void contactGround(QPoint p);
+ void drag();
+ bool createLink(Goo *goo);
+ bool destroyLink(Goo *goo);
+ bool isDragable();
private:
bool active;
public slots:
View
125 collisionlistener.cpp
@@ -45,50 +45,6 @@ void CollisionListener::PreSolve(b2Contact *contact, const b2Manifold *oldManifo
if (t==NULL){
th=static_cast<Thorn*>(contact->GetFixtureB()->GetBody()->GetUserData());
if (th!=NULL) a->destroyThis();
- else if (!t && !th&& a) { //if isn't any of the both and first body is a goo
- if (a){//advice the goo that he/it touch the ground
- b2Vec2 p=oldManifold->localPoint;
- //CHANGE CORDINATE SYSTEM
- p= contact->GetFixtureA()->GetBody()->GetWorldPoint(p);
- //p.x=b->getVPosition().x+p.x;
- //FOR UNKNOW REAZON SOMETIMES THE COLLISION POINT IS COMPLITLY WRONG
- //SO I MADE THIS WORK AROUND TO FIX IT
- //WORKAROUND
- //CHECK IF THE COLLISION POINT IS TOO DISTANT FROM MY BODY FOR BE A CORRECT POINT
- if ((p-a->getVPosition()).Length()>50 && a->hasJoint()) {
- //SOSTITUITION OF THE COLLISION POINT WITH MY BODY POINT
- p=a->getVPosition();
- //RETRIVE THE NORMAL OF THE COLLISION
- b2Vec2 n=oldManifold->localNormal;
- //NORMALY THE NORMAL IS CORRECT
- //BUT I EXPERIMENTED SOME ERROR ALSO WITH THE NORMAL
- //CHECK IF Y COMPONTENT OF THE NORMAL IS BIGGER OF THE X
-
-// if (fabs(n.y)>fabs(n.x)){
-// //CHECK IF THE Y COMPONENT IS BIGGER THAN 0 SO ADD -20 TO P.Y
-// if (n.y>0) p.y+=20;
-// //ELSE ADD +20 TO P.Y
-// else p.y+=20;
-// }
-// //ELSE
-// else{
-// //CHECK IF X COMPONENT IS BIGGER THE 0 SO ADD -20 TO P.X
-// if (n.x>0) p.x+=20;
-// //ELSE ADD +20 TO P.X
-// else p.x+=20;
-// }
- p.x-=20*((n.x)/(n.Length()>0.001 && n.Length()<10000 ? n.Length() : n.x ));
- p.y+=20*(n.y)/(n.Length()>0.001 && n.Length()<10000 ? n.Length() : n.y);
- if ((a->getVPosition()-p).Length()>50) p=b->getVPosition();
- if (abs((a->getVPosition()-p).Length()-20.0)>1.0) qWarning()<<(a->getVPosition()-p).Length();
- }
- //END WORKAROUND
- //CALL CONTACTGROUND WITH THE CALCULATED P
- qWarning()<<"Incredibilmente qua!";
-// if (a->hasJoint()) a->contactGround(toPoint(p));
-// else if (a->isDragging()) emit stopGOO(a->getPPosition()); //Advice to stop the goo
- }
- }
}
//check for avoid to drag a goo inside the target
// else if (a->isDragging()) a->contactGround(a->getPPosition());
@@ -100,44 +56,57 @@ void CollisionListener::PreSolve(b2Contact *contact, const b2Manifold *oldManifo
if (t==NULL) {
th=static_cast<Thorn*>(contact->GetFixtureA()->GetBody()->GetUserData());
if (th!=NULL ) b->destroyThis();
- else if (!t&&!th&&b) { //ELSE IS GROUND
- if (b){
- //RETRIVE COLLISION POINT
- b2Vec2 p=oldManifold->localPoint;
- //CHANGE CORDINATE SYSTEM
- p= contact->GetFixtureA()->GetBody()->GetWorldPoint(p);
- //p.x=b->getVPosition().x+p.x;
- //FOR UNKNOW REAZON SOMETIMES THE COLLISION POINT IS COMPLITLY WRONG
- //SO I MADE THIS WORK AROUND TO FIX IT
- //WORKAROUND
- //CHECK IF THE COLLISION POINT IS TOO DISTANT FROM MY BODY FOR BE A CORRECT POINT
- if ((p-b->getVPosition()).Length()>50 && b->hasJoint()) {
- //SOSTITUITION OF THE COLLISION POINT WITH MY BODY POINT
- p=b->getVPosition();
- //RETRIVE THE NORMAL OF THE COLLISION
- b2Vec2 n=oldManifold->localNormal;
- //NORMALY THE NORMAL IS CORRECT
- //BUT I EXPERIMENTED SOME ERROR ALSO WITH THE NORMAL
- //Compute the angle
- float angle=atan2(n.y,n.x);
- //Compute x,y of the vector
- float px=20.0*cos(angle);
- float py=20.0*sin(angle);
- p.x+=px;
- p.y+=py;
-
- }//END WORKAOROUND
-
- if (b->hasJoint()) b->contactGround(toPoint(p));
- else if (b->isDragging()) emit stopGOO(b->getPPosition()); //Advice to stop the goo
- }
- }
}
- //check for avoid to drag a goo inside the target
- //else if (b->isDragging()) b->contactGround(b->getPPosition());
}
contact->SetEnabled(true); //contact is enabled here
}
}
+void CollisionListener::PostSolve(b2Contact *contact, const b2ContactImpulse *impulse){
+
+ Goo*a,*b; //for get the goo involved in the contact
+ a=static_cast<Goo*>(contact->GetFixtureA()->GetUserData()); //Dynamic cast is for retrive (if any) the goo object of the first body involved
+ b=static_cast<Goo*>(contact->GetFixtureB()->GetUserData()); //Dynamic cast is for retrive (if any) the goo object of the second body involved
+ if (!a){
+ Target * t=NULL; //target
+ Thorn* th=NULL; //thorn
+ t=static_cast<Target*>(contact->GetFixtureA()->GetBody()->GetUserData()); //Check if is target
+ //check if is a thorn
+ if (t==NULL) {
+ th=static_cast<Thorn*>(contact->GetFixtureA()->GetBody()->GetUserData());
+ if (!t&&!th&&b&&contact->GetFixtureA()->GetBody()->GetType()==b2_staticBody) { //ELSE IS GROUND
+ if (b){
+ //RETRIVE COLLISION POINT
+ b2Vec2 p=contact->GetManifold()->localPoint;
+ //CHANGE CORDINATE SYSTEM
+ p= contact->GetFixtureA()->GetBody()->GetWorldPoint(p);
+ //p.x=b->getVPosition().x+p.x;
+ //FOR UNKNOW REAZON SOMETIMES THE COLLISION POINT IS COMPLITLY WRONG
+ //SO I MADE THIS WORK AROUND TO FIX IT
+ //WORKAROUND
+ //CHECK IF THE COLLISION POINT IS TOO DISTANT FROM MY BODY FOR BE A CORRECT POINT
+ if ((p-b->getVPosition()).Length()>50 && b->hasJoint()) {
+ //SOSTITUITION OF THE COLLISION POINT WITH MY BODY POINT
+ p=b->getVPosition();
+ //RETRIVE THE NORMAL OF THE COLLISION
+ b2Vec2 n=contact->GetManifold()->localNormal;
+ //NORMALY THE NORMAL IS CORRECT
+ //BUT I EXPERIMENTED SOME ERROR ALSO WITH THE NORMAL
+ //Compute the angle
+ float angle=atan2(n.y,n.x);
+ //Compute x,y of the vector
+ float px=20.0*cos(angle);
+ float py=20.0*sin(angle);
+ p.x+=px;
+ p.y+=py;
+
+ }//END WORKAOROUND
+
+ if (b->hasJoint()) b->contactGround(toPoint(p));
+ else if (b->isDragging()) emit stopGOO(b->getPPosition()); //Advice to stop the goo
+ }
+ }
+ }
+ }
+}
View
1 collisionlistener.h
@@ -12,6 +12,7 @@ class CollisionListener : public QObject, public b2ContactListener
public:
explicit CollisionListener(QObject *parent = 0); //Constructor
void PreSolve(b2Contact *contact, const b2Manifold *oldManifold); //Pre solve of the collision
+ void PostSolve(b2Contact *contact, const b2ContactImpulse *impulse);
signals:
void destroyGOO(Goo * goo); //signal to destroy a goo (Ex: a goo collide with a thorn)
View
1 dynamicgoo.cpp
@@ -36,6 +36,7 @@ DynamicGoo::DynamicGoo(b2World *world, QPoint p, int radius, QObject *parent):
dragable=true;
maxJoints=7; //parameters
speed=50;
+ type=DYNAMIC;
}
void DynamicGoo::catched(){
View
1 fixedgoo.cpp
@@ -19,6 +19,7 @@ FixedGoo::FixedGoo(b2World *world, QPoint p, int radius, QObject *parent):
maxJoints=5;
onGround=true;
groundPoint=p;
+ type=FIXED;
}
void FixedGoo::paint(QPainter &p){
View
10 goo.cpp
@@ -30,6 +30,11 @@ Goo::Goo( int radius, QObject *parent) :
target=NULL;
prevTarget=NULL;
+ type=NONE;
+}
+
+GooType Goo::getType(){
+ return type;
}
//Check if is on ground
@@ -179,7 +184,7 @@ bool Goo::destroyLink(Goo *goo){
// j=j->GetNext();
// }
// }
- if (isDragging() && !hasJoint()) body->SetActive(false);
+ if (!isDragging() && !hasJoint()) body->SetActive(false);
return true;
}
@@ -218,9 +223,6 @@ void Goo::drag(){
info.speed=body->GetLinearVelocity();
info.aForce=body->GetAngularVelocity();
}
-// body->SetLinearVelocity(b2Vec2(0,0));
-// body->SetGravityScale(0);
-// body->SetAngularVelocity(0.0);
if (!hasJoint()) body->SetActive(false);
dragging=true;
View
9 goo.h
@@ -7,6 +7,7 @@
#include <Box2D/Box2D.h>
+enum GooType {NONE,FIXED,DYNAMIC,REMOVIBLE,BALOON,STICKY};
struct dragInfo{
b2Vec2 speed;
@@ -19,6 +20,8 @@ class Goo : public QObject
Q_OBJECT
public:
explicit Goo(int radius=15,QObject *parent = 0);
+ //GET TYPE
+ GooType getType();
int nJoints();
int getMaxJoints();
@@ -30,7 +33,7 @@ class Goo : public QObject
bool removeGuest();
//Function to drag and drop goo
- void drag();
+ virtual void drag();
void drop();
void drop(b2Vec2 speed);
//select unselect goo
@@ -70,11 +73,11 @@ class Goo : public QObject
QList <Goo*> getLinks();
Goo* getPrevious();
-private:
+protected:
+ GooType type;
QList <Goo*> links;
int radius;
dragInfo info;
-protected:
b2Body* body; //physical body
//FLAGS
bool dragable; // If the user can drag it
View
5 joint.cpp
@@ -7,6 +7,7 @@ Joint::Joint(Goo *a, Goo *b, b2World *world,bool child, QObject *parent):
this->a=a;
this->b=b;
+ type=NORMAL;
if (!child) initialize(world);
}
@@ -76,3 +77,7 @@ bool Joint::has(Goo *a, Goo *b){ //Check if the joint link this two goo
return false;
}
+JointType Joint::getType(){
+ return type;
+}
+
View
5 joint.h
@@ -6,7 +6,7 @@
#include <QPainter>
#include "goo.h"
-
+enum JointType {NORMAL, ROPE};
class Joint : public QObject
{
Q_OBJECT
@@ -17,8 +17,9 @@ class Joint : public QObject
void paintDebug(QPainter &p);
b2Joint* getJoint(); //To have acces at the material b2joint
bool has(Goo*a,Goo*b); //To check if this joint link this two GOO
-
+ JointType getType();
protected:
+ JointType type;
virtual void initialize(b2World * world);
b2Joint* joint; //The phisical joint
Goo *a,*b; //the two linked goo
View
94 level.cpp
@@ -12,6 +12,9 @@
#include "thorn.h"
#include "stickylink.h"
+#include "balloongoo.h"
+#include "ropejoint.h"
+
#include "collisionlistener.h"
@@ -217,14 +220,24 @@ void Level::moveOf(QPoint dP){
}
bool Level::makeJoint(Goo *a, Goo *b){
+ bool baloon=false;
+ if (a->getType()==BALOON ||b->getType()==BALOON) baloon=true;
if (!a->createLink(b)) return false;
if (!b->createLink(a)) {
a->destroyLink(b);
return false;
}
- Joint* j=new Joint(a,b,world,false,this);
- joints.push_back(j);
- connect(j,SIGNAL(destroyJoint(Joint*)),this,SLOT(destroyJoint(Joint*)));
+ if (!baloon){
+ Joint* j= new Joint(a,b,world,false,this);
+ joints.push_back(j);
+ connect(j,SIGNAL(destroyJoint(Joint*)),this,SLOT(destroyJoint(Joint*)));
+
+ }
+ else {
+ RopeJoint *rj=new RopeJoint(b,a,world,this);
+ joints.push_back(rj);
+ connect(rj,SIGNAL(destroyJoint(Joint*)),this,SLOT(destroyJoint(Joint*)));
+ }
return true;
}
@@ -235,7 +248,7 @@ QList<QPoint> Level::possibleJoints(QPoint p){
for (int i=0;i<goos.length();i++){
if (goos[i]->canHaveJoint()) {
d=pv-goos[i]->getVPosition();
- if (d.LengthSquared()>=50*50 && d.LengthSquared()<=150*150 )
+ if (d.LengthSquared()>=50*50 && d.LengthSquared()<=(dragged->getType()==BALOON ? 200*200 : 150*150 ))
l.push_back(goos[i]->getPPosition());
}
@@ -244,24 +257,37 @@ QList<QPoint> Level::possibleJoints(QPoint p){
}
bool Level::createJoints(QPoint p){
+
QList<Goo*> l;
b2Vec2 pv=toVec(p);
b2Vec2 d;
for (int i=0;i<goos.length();i++){
- if (goos[i]->canHaveJoint()) {
+ if (goos[i]->canHaveJoint() && goos[i]->hasJoint()) {
d=pv-goos[i]->getVPosition();
- if (d.LengthSquared()>=50*50 && d.LengthSquared()<=150*150 && !l.contains(goos[i]))
+ if (d.LengthSquared()>=50*50 && d.LengthSquared()<=(dragged->getType()==BALOON ? 200*200 : 150*150 ) && !l.contains(goos[i]))
l.push_back(goos[i]);
}
}
- if (l.length()>1||dragged->hasJoint()){
- for (int i=0;i<l.length();i++){
- if (makeJoint(dragged,l[i])) continue;
+ if (dragged->getType()!=BALOON){
+ if (l.length()>1||dragged->hasJoint()){
+ for (int i=0;i<l.length();i++){
+ if (makeJoint(dragged,l[i])) continue;
+ }
+ return true;
}
- return true;
+ else return false;
+ }
+ else {
+ if (l.length() && !dragged->hasJoint()){
+ QList <QPoint> lp;
+ for (int i=0;i<l.length();i++)
+ lp.push_back(l[i]->getPPosition());
+ makeJoint(dragged,getGooAt(getNearest(dragged->getPPosition(),lp)));
+ return true;
+ }
+ else return false;
}
- else return false;
}
void Level::timerEvent(QTimerEvent *e){
@@ -295,15 +321,30 @@ void Level::timerEvent(QTimerEvent *e){
if (target) target->checkTower(goos);
if (target) target->applyForces(goos);
- int gravity=world->GetGravity().Length();
- for(int i=0;i<ballGoos.length();i++)//Apply a force to the balloon to let it fly
- {
- ballGoos.at(i)->getBody()->ApplyForceToCenter(b2Vec2(0,-gravity*1.1));
- }
+// int gravity=world->GetGravity().Length();
+// for(int i=0;i<ballGoos.length();i++)//Apply a force to the balloon to let it fly
+// {
+// ballGoos.at(i)->getBody()->ApplyForceToCenter(b2Vec2(0,-gravity*1.1));
+// }
repaint();
stickyToCreate.clear();
}
+QPoint Level::getNearest(QPoint p,QList<QPoint> l){
+ QPoint p0=p;
+ QPoint dp;
+ float dt,d=10000;
+ for (int i=0;i<l.length();i++){
+ dp=p-l[i];
+ dt=dp.x()*dp.x()+dp.y()*dp.y();
+ if (dt<d) {
+ d=dt;
+ p0=l[i];
+ }
+ }
+ return p0;
+}
+
void Level::paintEvent(QPaintEvent *e){
QPainter p(this);
@@ -326,11 +367,15 @@ void Level::paintEvent(QPaintEvent *e){
if (ground) ground->paint(p);
if (target) target->paint(p);
- if (drag && possibility.length()>1)
+ if (drag && (dragged->getType()!=BALOON &&possibility.length()>1))
{
for (int i=0;i<possibility.length();i++)
p.drawLine(dragged->getPPosition(),possibility[i]);
}
+ else if (drag && dragged->getType()==BALOON){
+ p.drawLine(dragged->getPPosition(),getNearest(dragged->getPPosition(),possibility));
+ }
+
for (int i=0;i<objects.length();i++)
objects[i]->paint(p);
for (int i=0;i<joints.length();i++) {
@@ -526,7 +571,7 @@ void Level::giveTarget(Goo *previous){
bool ok=false;
float distance=300;
for (int i=0;i<goos.length();i++){
- if (goos[i]!=goo&&goos[i]->hasJoint()&&goos[i]->isOnGround()&&abs(goos[i]->getPPosition().y()-pos.y())<15&&(goos[i]->getVPosition()-goo->getVPosition()).Length()<=distance){
+ if (goos[i]!=goo&&goos[i]->hasJoint()&&goos[i]->getType()!=BALOON &&goos[i]->isOnGround()&&abs(goos[i]->getPPosition().y()-pos.y())<15&&(goos[i]->getVPosition()-goo->getVPosition()).Length()<=distance){
next=goos[i];
distance=(toVec(pos)-goos[i]->getVPosition()).Length();
ok=true;
@@ -543,7 +588,7 @@ void Level::giveTarget(Goo *previous){
Goo * target=previous->getLinks().at(0);
b2Vec2 d=this->target->getVPosition()-target->getVPosition();
for (int i=1;i<previous->getLinks().length();i++){
- if ((goo->getPrevious()!=previous->getLinks().at(i)) && (this->target->getVPosition()-previous->getLinks().at(i)->getVPosition()).LengthSquared()<d.LengthSquared()){
+ if ((goo->getPrevious()!=previous->getLinks().at(i))&& previous->getLinks().at(i)->getType()!=BALOON && (this->target->getVPosition()-previous->getLinks().at(i)->getVPosition()).LengthSquared()<d.LengthSquared()){
target=previous->getLinks().at(i);
d=this->target->getVPosition()-previous->getLinks().at(i)->getVPosition();
}
@@ -769,6 +814,15 @@ void Level::setTarget(QPoint target){
void Level::setStartArea(int n, QRect area,int type){
int x,y;
+ x=area.x();
+ y=area.y();
+// BalloonGoo* dg=new BalloonGoo(world,QPoint(x,y),RADIUS);
+// goos.push_back(dg);
+// connect(dg,SIGNAL(nextTargetPlease(Goo*)),this,SLOT(giveTarget(Goo*)));
+// connect(dg,SIGNAL(destroyGoo()),this,SLOT(destroyGOO()));
+// connect(dg,SIGNAL(destroyJoint(Goo*,Goo*)),this,SLOT(destroyJoint(Goo*,Goo*)));
+// connect(dg,SIGNAL(createSticky(QPoint)),this,SLOT(createSticky(QPoint)));
+// connect(dg,SIGNAL(checkForNeighbors(QPoint)),this,SLOT(checkForNeighbors(QPoint)));
for (int i=0;i<n;i++){
x=area.x()+qrand()%area.width();
y=area.y()+qrand()%area.height();
@@ -853,7 +907,7 @@ void Level::setGoo(QPoint center,int id, int type){
else if (type==3){ //Create a balloon goo
BalloonGoo* bg=new BalloonGoo(world,center,RADIUS);
goos.push_back(bg);
- ballGoos.append(bg);
+// ballGoos.append(bg);
goo=bg;
//connect(bg,SIGNAL(nextTargetPlease(Goo*)),this,SLOT(giveTarget(Goo*)));
connect(bg,SIGNAL(destroyGoo()),this,SLOT(destroyGOO()));
View
4 level.h
@@ -64,7 +64,7 @@ class Level : public QGLWidget //QWidget <--To use without openGL
QList<Goo*> goos; //All the goos!
QList<Goo*> goosToDestroy; //GOOs to be destroyed the next update!
- QList<BalloonGoo*> ballGoos; //Balloon goos
+// QList<BalloonGoo*> ballGoos; //Balloon goos
QList<Joint*> joints; //All the joints!
QList<Joint*> jointsToDestroy; //Joints to be destroyed the next update!
@@ -102,6 +102,8 @@ class Level : public QGLWidget //QWidget <--To use without openGL
Goo* getGooAt(QPoint p); //Funciton to get (if any) a goo in a point +/- the radius of the goo
+ QPoint getNearest(QPoint p,QList<QPoint> l);
+
//Function to translate the gui
void moveUp();
void moveDown();
View
8 mainwidget.cpp
@@ -55,17 +55,17 @@ void MainWidget::levelSelected()//Create the level selected
if (multiwindow){
if (!debug)
- level=new Level(geometry,levelS->getLevelSelected(),STANDARD); //Create the level
+ level=new Level(geometry,levelS->getLevelSelected(),STANDARD,true); //Create the level
else{
- level=new Level(geometry,levelS->getLevelSelected(),DEBUG); //Create the level
+ level=new Level(geometry,levelS->getLevelSelected(),DEBUG,true); //Create the level
qWarning()<<"Level object created";
}
}
else {
if (!debug)
- level=new Level(geometry,levelS->getLevelSelected(),STANDARD,this); //Create the level
+ level=new Level(geometry,levelS->getLevelSelected(),STANDARD,false,this); //Create the level
else{
- level=new Level(geometry,levelS->getLevelSelected(),DEBUG,this); //Create the level
+ level=new Level(geometry,levelS->getLevelSelected(),DEBUG,false,this); //Create the level
qWarning()<<"Level object created";
}
}
View
1 removablegoo.cpp
@@ -5,6 +5,7 @@
RemovableGoo::RemovableGoo(b2World *world, QPoint point, int radius, QObject *parent) :
DynamicGoo(world,point,radius,parent)
{
+ type=REMOVIBLE;
color=Qt::yellow; //the recognize color of normal dynamic goo is yellow;
}
View
75 ropejoint.cpp
@@ -1,12 +1,16 @@
#include "ropejoint.h"
+#include <qmath.h>
+#include <QDebug>
#include <QPen>
#include "tools.h"
RopeJoint::RopeJoint(Goo *a, Goo *b, b2World *world, QObject *parent) :
Joint(a,b,world,true,parent)
{
this->world=world;
+ initialize(world);
+ type=ROPE;
}
RopeJoint::~RopeJoint(){
@@ -29,32 +33,79 @@ void RopeJoint::initialize(b2World *world){
jDef.bodyB=b->getBody();
jDef.localAnchorA=a->getVPosition();
jDef.localAnchorB=b->getVPosition();
- jDef.maxLength=200;
- joint=(b2RopeJoint*)world->CreateJoint(&jDef);
+ jDef.maxLength=500;
float x,y,x0,y0;
x0=a->getVPosition().x;
y0=a->getVPosition().y;
float mx,my;
- mx=b->getVPosition().x-a->getVPosition().y;
+
+
+ mx=b->getVPosition().x-a->getVPosition().x;
my=b->getVPosition().y-a->getVPosition().y;
+ float d=qSqrt(mx*mx+my*my);
+ mx/=d;
+ my/=d;
int n,k;
- n=50;
- k=jDef.maxLength/n;
+ n=30;
+ k=d/n;
b2PolygonShape shape;
- shape.SetAsBox(k/2,k/4);
+ shape.SetAsBox(k*mx/2,k*my/2);
b2FixtureDef fd;
fd.shape = &shape;
- fd.density = 20.0f;
+ fd.density = 0.0;
fd.friction = 0.2f;
+
fd.filter.categoryBits = 0x0001;
fd.filter.maskBits = 0xFFFF & ~0x0002;
b2RevoluteJointDef jd;
jd.collideConnected = false;
+ float d2=500-d;
+ int n2=d2/k;
b2Body* prevBody = a->getBody();
+
+ for (int i=0; i<n2/2;i++){
+ x=x0+i*k;
+ y=y0;
+ b2BodyDef bd;
+ bd.type = b2_dynamicBody;
+ bd.position.Set(x,y);
+
+ b2Body* body = world->CreateBody(&bd);
+ body->CreateFixture(&fd);
+ body->SetGravityScale(0);
+ b2Vec2 anchor(x, y);
+ jd.Initialize(prevBody, body, anchor);
+
+ joints.push_back(world->CreateJoint(&jd));
+ bodies.push_back(body);
+
+ prevBody = body;
+ }
+
+ for (int i=0;i<n2/2;i++){
+ x=x0+n2/2*k-i*k;
+ y=y0;
+
+ b2BodyDef bd;
+ bd.type = b2_dynamicBody;
+ bd.position.Set(x,y);
+
+ b2Body* body = world->CreateBody(&bd);
+ body->CreateFixture(&fd);
+ body->SetGravityScale(0);
+ b2Vec2 anchor(x, y);
+ jd.Initialize(prevBody, body, anchor);
+
+ joints.push_back(world->CreateJoint(&jd));
+ bodies.push_back(body);
+
+ prevBody = body;
+ }
+
for (int i=0;i<n-1;i++){
x=x0+mx*(i*k);
y=y0+my*(i*k);
@@ -65,7 +116,7 @@ void RopeJoint::initialize(b2World *world){
b2Body* body = world->CreateBody(&bd);
body->CreateFixture(&fd);
-
+ body->SetGravityScale(0.2);
b2Vec2 anchor(x, y);
jd.Initialize(prevBody, body, anchor);
@@ -75,18 +126,24 @@ void RopeJoint::initialize(b2World *world){
prevBody = body;
}
+
jd.Initialize(prevBody, b->getBody(), b->getVPosition());
+
joints.push_back(world->CreateJoint(&jd));
+ joint=(b2RopeJoint*)world->CreateJoint(&jDef);
+ b->move(QPoint(mx*500,my*500));
}
void RopeJoint::paint(QPainter &p){
+ if (!a->isLinked(b) || !b->isLinked(a)) emit this->destroyJoint(this);
QPen pen(Qt::black,3);
p.setPen(pen);
for (int i=0;i<bodies.length()-1;i++){
p.drawLine(toPoint(bodies[i]->GetPosition()),toPoint(bodies[i+1]->GetPosition()));
}
-
+ p.drawLine(a->getPPosition(),b->getPPosition());
}
+

0 comments on commit d9803cb

Please sign in to comment.