Пример #1
0
void displayCB(){
    glClearColor(1.0, 1.0, 1.0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0.0, WIDTH, HEIGHT, 0.0);
    //for each ball
//    for(int i=0; i<N; i++) {

//        balls[i].clearForce();
//    }
    //for each rope
    //rope.update();
    //for each pair
    for(int i=0; i<N-1; i++) {
        for(int j=i+1; j<N; j++){
            collideObj(balls[i],balls[j]);
        }
    }
    //for each ball
    for(int i=0; i<N; i++) {
        collideWall(balls[i]);        
        balls[i].update();
        balls[i].draw();
    }
    glFlush();
    glutPostRedisplay();
}
Пример #2
0
void Table::update(float deltaTime)
{
	setAimline();

	if (in->Space)
		run = true;
	if(!run)
		return;
	
	ballFriction(deltaTime);

	moveBalls(deltaTime);

	collideWall(deltaTime);

	collideBall();

	spawnWhite();
}
Пример #3
0
void SpiderWebEntity::collideMapBottom()
{
  collideWall();
}
Пример #4
0
void SpiderWebEntity::collideMapTop()
{
  collideWall();
}
Пример #5
0
void SpiderWebEntity::collideMapLeft()
{
  collideWall();
}
Пример #6
0
void SpiderWebEntity::collideMapRight()
{
  collideWall();
}
Пример #7
0
void Object::doCollision(Background &bg)
{
	WallSet set;
	const TileMap &tilemap = bg.getTileMap();

	/* get tile bounds of circle */
	int l = (int)floor((pos.x-radius)/8), r = (int)ceil((pos.x+radius)/8);
	int t = (int)floor((pos.y-radius)/8), b = (int)ceil((pos.y+radius)/8);

	/* add all walls declared for the tiles */
	for (int j= t; j < b; j++)
		for (int i= l; i < r; i++)
		{
			const TileMapEntry *tme = tilemap.index(i,j);
			set.addFromTile(tme);
		}

	/* we want to ignore certain walls (tops of ladders when climbing through 
		them, and one way walls). This loop removes walls from the ignore list
		if the object doesn't intersect with it */
	{
		Wall::CPListIterator i;
		for (i = ignore.begin(); i != ignore.end();)
		{
			const Segment &s = (**i).wall.segment;

			if (!s.intersect(Circle(pos, radius)))
				ignore.erase(i++);
			else
				++i;
		}
	}

	/* all the collision gets messed up when the sometimes here/sometimes
		not walls enter the equation */
	bool irregularWalls = false;
	{
		WallSet::Iterator i;
		for (i = set.begin(); i != set.end(); ++i)
		{
			const Edge::EdgeType &type = (**i).wall.type;
			if (type == Edge::LADDER_TOP || type == Edge::ONE_WAY)
			{
				irregularWalls = true;
				break;
			}
		}
	}

	/* check all walls found above for collision */

	WallSet::Iterator i;
	Segment::List collide;

	for (i = set.begin(); i != set.end(); ++i)
	{
		const Wall &w = (**i);
		const Segment &s = w.wall.segment;

		preProcessWall(**i);

		/* don't process it if it's in the ignore list... */
		if (std::find(ignore.begin(), ignore.end(), &w) != ignore.end())
			continue;
		
		/* we wait to do segment-circle collision if we're doing complicated
			collision */
		if (!irregularWalls)
		{
			/* ...or if it doesn't even intersect the circle */
			if (!s.intersect(Circle(pos, radius)))
				continue;
		}

		if (processWall(**i))
		{
			if (irregularWalls)
				collide.push_back((**i).wall.segment);
			else
				collideWall((**i).wall.segment);
		}
	}

	/* the problem with using normal collision:
		if we have some walls that are here today/gone tomorrow the collision
		will be irregular because of the way segment-circle collision works.
		
		when the circle collides with two walls with the same normal near their
		intersection point, one of the segments will (probably) provide a shunt 
		vector that is not the normal, whereas the other (probably) will. This
		will push the object in the direction of the vector, even though it
		shouldn't.

		how to fix it (basic idea):
		* combine collinear segment that intersect at a point like in 
			Walls::addWall
		* sometimes walls will exist on the other side of this newly created
			wall. If the object is on the normal side, remove this "T-Bone" wall.
	*/
	if (irregularWalls)
	{
		/* combine collinear segments that intersect at a point,
			like in Walls::addWall */
		Segment::ListIterator k, l;

		for (k = collide.begin(); k != collide.end();)
		{
			bool removed = false;

			const Segment &s = *k;
			l = k;
			for (++l; l != collide.end(); ++l)
			{
				const Segment &t = *l;
				Point p0, p1;
				Segment::IntersectType it = s.intersect(t,p0,p1);

				if (it != Segment::COLLINEAR_POINT) continue;
				if (s.normal != t.normal) continue;

				if (p0 == t.p0)
					collide.push_back(Segment(s.p0, t.p1));
				else
					collide.push_back(Segment(t.p0, s.p1));

				collide.erase(k++);
				if (k == l)
					collide.erase(k++);
				else
					collide.erase(l);

				removed = true;
				break;
			}

			if (!removed) ++k;
		}

		/* look for edges that T-bone another segment */
		for (k = collide.begin(); k != collide.end();)
		{
			bool removed = false;
			const Segment &s = *k;
			l = k;
			for (++l; l != collide.end(); ++l)
			{
				const Segment &t = *l;
				Point p0, p1;
				Segment::IntersectType it = s.intersect(t,p0,p1);

				if (it != Segment::POINT) continue;
				/* we know that the combined segments are at the end of the
					collide list, therefore if two segments are T-boned, the
					top of the "T" must be t and the base of the "T" must be
					s.

					Therefore, if the intersection point is t, we know it can't
					be a T-bone.
				*/
				if (p0 == t.p0 || p0 == t.p1) continue;
				
				/* find which point connects the top of the "T" to the base. */
				if (p0 == s.p0)
				{
					/* we'll erase the base if the top normal points away from
						the base and if the object is on the top normal side */
					if (!t.faces(s.p1) && t.faces(pos))
					{
						collide.erase(k++);
						removed = true;
						break;
					}
				}
				else if (p0 == s.p1)
				{
					/* we'll erase the base if the top normal points away from
						the base and if the object is on the top normal side */
					if (!t.faces(s.p0) && t.faces(pos))
					{
						collide.erase(k++);
						removed = true;
						break;
					}
				}
			}
			if (!removed) ++k;
		}

		/* shunt object around to avoid collision */
		for (k = collide.begin(); k != collide.end(); ++k)
		{
			const Segment &s = *k;
			/* this check is necessary, if we check walls without moving the
				object, we get false positives */
			if (s.intersect(Circle(pos, radius)))
				collideWall(*k);
		}
	}
}
Пример #8
0
void RockMissileEntity::collideMapBottom()
{
  collisionDirection = DIRECTION_BOTTOM;
  collideWall();
}
Пример #9
0
void RockMissileEntity::collideMapTop()
{
  collisionDirection = DIRECTION_TOP;
  collideWall();
}
Пример #10
0
void RockMissileEntity::collideMapLeft()
{
  collisionDirection = DIRECTION_LEFT;
  collideWall();
}
Пример #11
0
void RockMissileEntity::collideMapRight()
{
  collisionDirection = DIRECTION_RIGHT;
  collideWall();
}
Пример #12
0
void Goomba:: move()
{
  if(isTherePlayer()){
    if(!stopToSee && !followPlayer){
      MediaPlayerManager::playGoombaWhat();
      stopToSee=true;
    }
      followPlayer=true;
  }else{
      if(followPlayer){
          returnToRoute=true;
      }
    followPlayer=false;
  }

  if(farToRoute()){
   followPlayer=false;
   returnToRoute=true;
  }

  if(followPlayer && !returnToRoute && !hitByFireball &&!stopToSee){
      if(!collideWall( positionX+((player->getPositionX()-positionX)/30),positionY+(player->getPositionY()-positionY)/30))
       {
          setAngleRotation(player->getPositionX(),player->getPositionY());
          positionX+=(player->getPositionX()-positionX)/30;
          positionY+=(player->getPositionY()-positionY)/30;
       }
  }else if(returnToRoute && !hitByFireball &&!stopToSee){
      if(horizontalMove()){
        if(positionX<xStart){
            angleRotation=90;
           positionX+=SPEED;
          if(positionX>xStart)
            positionX=xStart;
        }else{
          positionX-=SPEED;
          angleRotation=270;
          if(positionX<xStart)
            positionX=xStart;
        }
        if(positionX==xStart)
          returnToRoute=false;
      }else{
          if(positionY<yStart){
            positionY+=SPEED;
            angleRotation=180;
            if(positionY>yStart)
              positionY=yStart;
          }else{
            positionY-=SPEED;
            angleRotation=0;
            if(positionY<yStart)
              positionY=yStart;
          }
          if(positionY==yStart)
            returnToRoute=false;
      }
  }else if(!hitByFireball && !stopToSee){
    if(horizontalMove()){
      if(startToEnd){
       if(!collideWall( positionX,positionY+SPEED)){
         positionY+=SPEED;
         angleRotation=180;
       }else{
         startToEnd=false;
         angleRotation=0;
        }
      }
      else{
          if(!collideWall( positionX,positionY-SPEED)){
              positionY-=SPEED;
              angleRotation=0;
          }else{
            startToEnd=true;
            angleRotation=180;

          }
      }
     if(positionY<=yStart && (positionX<=xStart+1 || positionX>=xStart-1)){
       startToEnd=true;
       angleRotation=180;
     }else if(positionY>=yEnd && (positionX<=xStart+1 || positionX>=xStart-1)){
       startToEnd=false;
       angleRotation=0;
     }

    }else{
     if(startToEnd){
        if(!collideWall( positionX+SPEED,positionY)){
          positionX+=SPEED;
          angleRotation=90;

        }else{
          startToEnd=false;
          angleRotation=270;
        }
     }else{
      if(!collideWall( positionX-SPEED,positionY)){
        positionX-=SPEED;
        angleRotation=270;
        }else{
          startToEnd=true;
          angleRotation=90;
        }
      }
      if(positionX<=xStart && (positionY<=yStart+1 || positionY>=yStart-1)){
        startToEnd=true;
        angleRotation=90;
      }else if(positionX>=xEnd && (positionY<=yStart+1 || positionY>=yStart-1)){
        startToEnd=false;
        angleRotation=270;
      }
  }
  }
}