示例#1
0
void Projectile::Run(float elapsed_time)
{
  if (HasReachedDestination())
  {
    float factor, attenuation;

    time_left -= elapsed_time;
    factor     = time_left / timeout;
    attenuation = base_attenuation / factor;
    SetAttenuation(0, 0, (attenuation < 0 ? 1000 : attenuation));
  }
  else
  {
    LPoint3f objective    = target.get_pos(node_path.get_parent());
    LPoint3f position     = node_path.get_pos();
    LPoint3f distance     = position - objective;
    float    max_distance = max(max(abs((long)distance.get_x()), abs((long)distance.get_y())), abs((long)distance.get_z()));
    LPoint3f movement;

    if (max_distance <= speed)
    {
      node_path.set_pos(objective);
      node_path.hide();
      HitsTarget.Emit();
    }
    else
    {
      movement.set_x(-(speed * (distance.get_x() / max_distance)));
      movement.set_y(-(speed * (distance.get_y() / max_distance)));
      movement.set_z(-(speed * (distance.get_z() / max_distance)));
      node_path.set_pos(node_path.get_pos() + movement);
    }
  }
}
示例#2
0
void SceneCamera::CenterCameraOn(NodePath np)
{
  if (_useTrackball)
    _window->center_trackball(np);
  else
  {
    _centeringCamera   = true;
    _objectivePos      = np.get_pos(_window->get_render());
    _objectivePos.set_z(_objectivePos.get_z() + _camera_height);

    LPoint3f cameraRot = _camera.get_hpr();
    float    rad2deg   = 3.1415926535897 / 180;

    cameraRot.set_x(cameraRot.get_x() * rad2deg);
    cameraRot.set_y(cameraRot.get_y() * rad2deg);
    cameraRot.set_z(cameraRot.get_z() * rad2deg);

    _objectivePos.set_x(np.get_x() + sin(cameraRot.get_x()) * 100);
    _objectivePos.set_y(np.get_y() + tan(cameraRot.get_y()) * 100);

    if (_currentCameraAngle == 1)
      _objectivePos.set_y(_objectivePos.get_y() + 80 + (140 - _camera_height) / 1.35);
    else
    {
      _objectivePos.set_x(_objectivePos.get_x() + 25 - (_camera_height - 50) * 0.85);
      _objectivePos.set_y(_objectivePos.get_y() + 40 - (_camera_height - 50) * 1);
    }
  }
}
WaypointGenerator::WaypointGenerator(World* world, MapObject* object, LPoint4 margin, LPoint2 spacing, bool corner_origin) : world(world), object(object)
{
  LPoint3f size = NodePathSize(object->render);

  spacingx = spacing.get_x();
  spacingy = spacing.get_y();
  sizex    = (size.get_x() - (margin.get_x() + margin.get_z())) / spacingx + 1;
  sizey    = (size.get_y() - (margin.get_y() + margin.get_w())) / spacingy + 1;

  if (corner_origin)
  {
    initPosX = -(margin.get_x() - size.get_x());
    initPosY = -(margin.get_y() - size.get_y());
    spacingx = -spacingx;
    spacingy = -spacingy;
  }
  else
  {
    initPosX = margin.get_x() - (size.get_x() / 2);
    initPosY = margin.get_y() - (size.get_y() / 2);
  }
  if (!(object->collider.node.is_empty()))
  {
    LPoint3f collision_node_pos = object->collider.node.get_pos();

    initPosX -= collision_node_pos.get_x();
    initPosY -= collision_node_pos.get_y();
  }
  initPosZ = size.get_z() + 50.f;
}
示例#4
0
// This function handles the collision between the ball and a wall
void World::wall_collide_handler(const CollisionEntry& colEntry)
   {
   // First we calculate some numbers we need to do a reflection
   NodePath renderNp = m_windowFrameworkPtr->get_render();
   // The normal of the wall
   LVector3f norm = colEntry.get_surface_normal(renderNp) * -1;
   // The current speed
   float curSpeed = m_ballV.length();
   // The direction of travel
   LVector3f inVec = m_ballV / curSpeed;
   // Angle of incidence
   float velAngle = norm.dot(inVec);
   LPoint3f hitDir = colEntry.get_surface_point(renderNp) - m_ballRootNp.get_pos();
   hitDir.normalize();
   // The angle between the ball and the normal
   float hitAngle = norm.dot(hitDir);

   // Ignore the collision if the ball is either moving away from the wall
   // already (so that we don't accidentally send it back into the wall)
   // and ignore it if the collision isn't dead-on (to avoid getting caught on
   // corners)
   if(velAngle > 0 && hitAngle > .995)
      {
      // Standard reflection equation
      LVector3f reflectVec = (norm * norm.dot(inVec * -1) * 2) + inVec;

      // This makes the velocity half of what it was if the hit was dead-on
      // and nearly exactly what it was if this is a glancing blow
      m_ballV = reflectVec * (curSpeed * (((1-velAngle)*.5)+.5));
      // Since we have a collision, the ball is already a little bit buried in
      // the wall. This calculates a vector needed to move it so that it is
      // exactly touching the wall
      LPoint3f disp = (colEntry.get_surface_point(renderNp) -
                       colEntry.get_interior_point(renderNp));
      LPoint3f newPos = m_ballRootNp.get_pos() + disp;
      m_ballRootNp.set_pos(newPos);
      }
   }
示例#5
0
// Accepts arrow keys to move either the player or the menu cursor,
// Also deals with grid checking and collision detection
void World::move()
   {
   // If the camera-left key is pressed, move camera left.
   // If the camera-right key is pressed, move camera right.

   NodePath cameraNp = m_windowFrameworkPtr->get_camera_group();
   cameraNp.look_at(m_ralph);
   if(m_keyMap[K_cam_left] != false)
      {
      cameraNp.set_x(cameraNp, -20 * ClockObject::get_global_clock()->get_dt());
      }
   if(m_keyMap[K_cam_right] != false)
      {
      cameraNp.set_x(cameraNp, +20 * ClockObject::get_global_clock()->get_dt());
      }

   // save ralph's initial position so that we can restore it,
   // in case he falls off the map or runs into something.

   LPoint3f startPos = m_ralph.get_pos();

   // If a move-key is pressed, move ralph in the specified direction.

   if(m_keyMap[K_left])
      {
      m_ralph.set_h(m_ralph.get_h() + 300 * ClockObject::get_global_clock()->get_dt());
      }
   if(m_keyMap[K_right])
      {
      m_ralph.set_h(m_ralph.get_h() - 300 * ClockObject::get_global_clock()->get_dt());
      }
   if(m_keyMap[K_forward])
      {
      m_ralph.set_y(m_ralph, -25 * ClockObject::get_global_clock()->get_dt());
      }

   // If ralph is moving, loop the run animation.
   // If he is standing still, stop the animation.

   if(m_keyMap[K_forward] || m_keyMap[K_left] || m_keyMap[K_right])
      {
       if(!m_isMoving)
          {
          m_ralph.loop("run", true);
          m_isMoving = true;
          }
      }
   else
      {
      if(m_isMoving)
         {
         m_ralph.stop("run");
         m_ralph.pose("walk", 5);
         m_isMoving = false;
         }
      }

   // If the camera is too far from ralph, move it closer.
   // If the camera is too close to ralph, move it farther.

   LPoint3f camVec = m_ralph.get_pos() - cameraNp.get_pos();
   camVec.set_z(0);
   float camDist = camVec.length();
   camVec.normalize();
   if(camDist > 10.0)
      {
      cameraNp.set_pos(cameraNp.get_pos() + camVec*(camDist-10));
      camDist = 10.0;
      }
   if(camDist < 5.0)
      {
      cameraNp.set_pos(cameraNp.get_pos() - camVec*(5-camDist));
      camDist = 5.0;
      }

   // Now check for collisions.

   NodePath renderNp = m_windowFrameworkPtr->get_render();
   m_collisionTraverser.traverse(renderNp);

   // Adjust ralph's Z coordinate.  If ralph's ray hit terrain,
   // update his Z. If it hit anything else, or didn't hit anything, put
   // him back where he was last frame.

   m_ralphGroundHandlerPtr->sort_entries();
   if(m_ralphGroundHandlerPtr->get_num_entries() > 0 &&
      m_ralphGroundHandlerPtr->get_entry(0)->get_into_node()->get_name() == "terrain")
      {
      m_ralph.set_z(m_ralphGroundHandlerPtr->get_entry(0)->get_surface_point(renderNp).get_z());
      }
   else
      {
      m_ralph.set_pos(startPos);
      }

   // Keep the camera at one foot above the terrain,
   // or two feet above ralph, whichever is greater.

   m_camGroundHandlerPtr->sort_entries();
   if(m_camGroundHandlerPtr->get_num_entries() > 0 &&
      m_camGroundHandlerPtr->get_entry(0)->get_into_node()->get_name() == "terrain")
      {
      cameraNp.set_z(m_camGroundHandlerPtr->get_entry(0)->get_surface_point(renderNp).get_z()+1.0);
      }
   if(cameraNp.get_z() < m_ralph.get_z() + 2.0)
      {
      cameraNp.set_z(m_ralph.get_z() + 2.0);
      }

   // The camera should look in ralph's direction,
   // but it should also try to stay horizontal, so look at
   // a floater which hovers above ralph's head.

   m_floaterNp.set_pos(m_ralph.get_pos());
   m_floaterNp.set_z(m_ralph.get_z() + 2.0);
   cameraNp.look_at(m_floaterNp);
   }
static float ZoneHeuristic(BoundingZone first, BoundingZone second)
{
  LPoint3f size = (first + second).size;

  return (size.get_x() * size.get_y());
}
示例#7
0
// If the ball hits a hole trigger, then it should fall in the hole.
// This is faked rather than dealing with the actual physics of it.
void World::lose_game(const CollisionEntry& entry)
   {
   // The triggers are set up so that the center of the ball should move to the
   // collision point to be in the hole
   NodePath renderNp = m_windowFrameworkPtr->get_render();
   LPoint3f toPos = entry.get_interior_point(renderNp);

   // Stop the maze task
   PT(GenericAsyncTask) rollTaskPtr = DCAST(GenericAsyncTask, AsyncTaskManager::get_global_ptr()->find_task("rollTask"));
   if(rollTaskPtr != NULL)
      {
      AsyncTaskManager::get_global_ptr()->remove(rollTaskPtr);
      }

   // Move the ball into the hole over a short sequence of time. Then wait a
   // second and call start to reset the game
   // Note: Sequence is a python only class. We have to manage using CMetaInterval for the animation
   //       with a callback event when the animation is done to callback on World::start() to restart the game.
   PT(CLerpNodePathInterval) lerp1Ptr = new CLerpNodePathInterval("lerp1",
                                                                   0.1,
                                                                   CLerpInterval::BT_no_blend,
                                                                   true,
                                                                   false,
                                                                   m_ballRootNp,
                                                                   NodePath());

   PT(CLerpNodePathInterval) lerp2Ptr = new CLerpNodePathInterval("lerp2",
                                                                  0.1,
                                                                  CLerpInterval::BT_no_blend,
                                                                  true,
                                                                  false,
                                                                  m_ballRootNp,
                                                                  NodePath());

   PT(WaitInterval) waitPtr = new WaitInterval(1);

   PT(CMetaInterval) cMetaIntervalPtr = new CMetaInterval("sequence");

   if(lerp1Ptr         == NULL ||
      lerp2Ptr         == NULL ||
      waitPtr          == NULL ||
      cMetaIntervalPtr == NULL)
      {
      nout << "ERROR: out of memory" << endl;
      return;
      }

   float endPosZ = m_ballRootNp.get_pos().get_z() - 0.9;
   LVecBase3f midEndPos(toPos.get_x(),
                       toPos.get_y(),
                       0.5*(m_ballRootNp.get_pos().get_z()+endPosZ));
   lerp1Ptr->set_end_pos(midEndPos);
   LVecBase3f endPos(toPos.get_x(),
                     toPos.get_y(),
                     endPosZ);
   lerp2Ptr->set_end_pos(endPos);

   cMetaIntervalPtr->add_c_interval(lerp1Ptr, 0, CMetaInterval::RS_previous_end);
   cMetaIntervalPtr->add_c_interval(lerp2Ptr, 0, CMetaInterval::RS_previous_end);
   cMetaIntervalPtr->add_c_interval(waitPtr , 0, CMetaInterval::RS_previous_end);
   cMetaIntervalPtr->set_done_event("restartGame");
   cMetaIntervalPtr->start();

   EventHandler::get_global_event_handler()->add_hook("restartGame", call_start, this);

   PT(GenericAsyncTask) intervalManagerTaskPtr = DCAST(GenericAsyncTask, AsyncTaskManager::get_global_ptr()->find_task("intervalManagerTask"));
   if(intervalManagerTaskPtr == NULL)
      {
      intervalManagerTaskPtr = new GenericAsyncTask("intervalManagerTask", step_interval_manager, NULL);
      if(intervalManagerTaskPtr != NULL)
         {
         AsyncTaskManager::get_global_ptr()->add(intervalManagerTaskPtr);
         }
      }
   }
示例#8
0
void SceneCamera::RunFollow(float elapsedTime)
{
  if (_followingNodePath)
    CenterCameraOn(_toFollow);
  LPoint3f camVec   = _objectivePos - _camera.get_pos();
  LPoint3f camSpeed;

  camSpeed = camVec / 2;
  if (camSpeed.get_x() > 0 && camSpeed.get_x() < _cameraMovementSpeed)
    camSpeed.set_x(_cameraMovementSpeed);
  else if (camSpeed.get_x() < 0 && camSpeed.get_x() > -_cameraMovementSpeed)
    camSpeed.set_x(-_cameraMovementSpeed);

  if (camSpeed.get_y() > 0 && camSpeed.get_y() < _cameraMovementSpeed)
    camSpeed.set_y(_cameraMovementSpeed);
  else if (camSpeed.get_y() < 0 && camSpeed.get_y() > -_cameraMovementSpeed)
    camSpeed.set_y(-_cameraMovementSpeed);

  if (camSpeed.get_z() > 0 && camSpeed.get_z() < _cameraMovementSpeed)
    camSpeed.set_z(_cameraMovementSpeed);
  else if (camSpeed.get_z() < 0 && camSpeed.get_z() > -_cameraMovementSpeed)
    camSpeed.set_z(-_cameraMovementSpeed);

  camSpeed = camSpeed * elapsedTime;

  LPoint3f dest = _camera.get_pos() + (camSpeed);
  LPoint3f dist = _objectivePos - dest;

  if (ABS(dist.get_x()) < ABS(camSpeed.get_x()))
    dest.set_x(_objectivePos.get_x());
  if (ABS(dist.get_y()) < ABS(camSpeed.get_y()))
    dest.set_y(_objectivePos.get_y());
  if (ABS(dist.get_z()) < ABS(camSpeed.get_z()))
    dest.set_z(_objectivePos.get_z());
  _camera.set_pos(dest);
#ifndef GAME_EDITOR
  CameraMoved.Emit();
#endif

  if (dest == _objectivePos)
    _centeringCamera = false;
}
示例#9
0
/*
 * Camera/NodePath centering and following stuff
 */
void SceneCamera::CenterCameraInstant(LPoint3f pos)
{
  _cameraPos = pos;

  LPoint3f cameraRot = _camera.get_hpr();
  float    rad2deg   = 3.1415926535897 / 180;

  cameraRot.set_x(cameraRot.get_x() * rad2deg);
  cameraRot.set_y(cameraRot.get_y() * rad2deg);
  cameraRot.set_z(cameraRot.get_z() * rad2deg);

  _camera.set_x(pos.get_x() + sin(cameraRot.get_x()) * 100);
  _camera.set_y(pos.get_y() + sin(cameraRot.get_y()) * 100);

  if (_currentCameraAngle == 1)
    _camera.set_y(_camera.get_y() + 80 + (140 - _camera_height) / 1.35);
  else
  {
    _camera.set_x(_camera.get_x() + 25 - (_camera_height - 50) * 0.85);
    _camera.set_y(_camera.get_y() + 40 - (_camera_height - 50) * 1);
  }
#ifndef GAME_EDITOR
  CameraMoved.Emit();
#endif
}
示例#10
0
void SceneCamera::RunScroll(float elapsedTime)
{
  if (_window->get_graphics_window() == 0)
    return ;
  MouseData     pointer      = _graphicWindow->get_pointer(0);
  unsigned char cameraMotion = MotionNone;

  float    _mouseBorderMargin   = 40;
  float    cameraSpeedX         = _cameraMovementSpeed;
  float    cameraSpeedY         = _cameraMovementSpeed;
  float    cameraMovementX;
  float    cameraMovementY;
  LPoint3f movement;
  LPoint3f cameraRot = _camera.get_hpr();
  float    rad2deg   = 3.1415926535897 / 180;

  if (pointer.get_y() <= _mouseBorderMargin)
  {
    cameraMotion |= MotionTop;
    cameraSpeedY  = cameraSpeedY * ((_mouseBorderMargin - pointer.get_y()) / _mouseBorderMargin);
  }
  else if (pointer.get_y() >= _graphicWindow->get_y_size() - _mouseBorderMargin)
  {
    cameraMotion |= MotionBottom;
    cameraSpeedY  = cameraSpeedY * ((pointer.get_y() - (_graphicWindow->get_y_size() - _mouseBorderMargin)) / _mouseBorderMargin);
  }
  if (pointer.get_x() <= _mouseBorderMargin)
  {
    cameraMotion |= MotionLeft;
    cameraSpeedX   = cameraSpeedX * ((_mouseBorderMargin - pointer.get_x()) / _mouseBorderMargin);
  }
  else if (pointer.get_x() >= _graphicWindow->get_x_size() - _mouseBorderMargin)
  {
    cameraMotion |= MotionRight;
    cameraSpeedX   = cameraSpeedX * ((pointer.get_x() - (_graphicWindow->get_x_size() - _mouseBorderMargin)) / _mouseBorderMargin);
  }

  cameraMovementX = cameraSpeedX * elapsedTime;
  cameraMovementY = cameraSpeedY * elapsedTime;
  cameraRot.set_x(cameraRot.get_x() * rad2deg);
  cameraRot.set_y(cameraRot.get_y() * rad2deg);
  cameraRot.set_z(cameraRot.get_z() * rad2deg);

  // Horizontal movement
  {
    movement.set_y(sin(cameraRot.get_x()));
    movement.set_x(cos(cameraRot.get_x()));

    if (cameraMotion & MotionLeft)
      movement *= -cameraMovementX;
    else if (cameraMotion & MotionRight)
      movement *= cameraMovementX;
    else
      movement *= 0;

    movement.set_z(0);
    _camera.set_pos(_camera.get_pos() + movement);
  }

  // Vertical movement
  {
    movement.set_x(tan(cameraRot.get_x()));
    movement.set_y(tan(cameraRot.get_y()));

    if (cameraMotion & MotionTop)
      movement *= -cameraMovementY;
    else if (cameraMotion & MotionBottom)
      movement *= cameraMovementY;
    else
      movement *= 0;

    movement.set_z(0);
    _camera.set_pos(_camera.get_pos() + movement);
  }

  if (_maxPosX != 0 || _minPosX != 0 || _maxPosY != 0 || _minPosY != 0)
  {
    if      (_camera.get_x() > _maxPosX) { _camera.set_x(_maxPosX); }
    else if (_camera.get_x() < _minPosX) { _camera.set_x(_minPosX); }
    if      (_camera.get_y() > _maxPosY) { _camera.set_y(_maxPosY); }
    else if (_camera.get_y() < _minPosY) { _camera.set_y(_minPosY); }
  }
#ifndef GAME_EDITOR
  CameraMoved.Emit();
#endif
}