3
\$\begingroup\$

I've got an issue while rendering 2d images with my own simple 2D camera object. First my setup:

  1. a star initial position 0,0
  2. a planet circles the star initial position 300, 300, moves at a radius of 300 and an angle of 10.5
  3. a playership inital position 512, 384 [half screen size]

Every object the camera is attached to should be rendered centered on the screen.

When I attach my camera to my player ship everything is rendered as expected. Even when I move my ship everything looks fine.

It's getting weird when I attach my camera to my moveing planet. Then it looks like that it's no longer orbiting the star. It looks like he's orbiting my playership.

I'm just a hobby gamedev so any advice would be good. Following is my code of interesst (I think):

rendering of active objects orders are Star, Planet then PlayerShip

void GameObjects::Galaxy::OnDraw(irr::IrrlichtDevice *irrlichtDevice)
{
  INT64 sectorX = std::get<0>(m_activeSector);
  INT64 sectorY = std::get<1>(m_activeSector);

  for (std::list<GameObjects::PTR_BODY>::iterator itObject = this->m_renderableObjects[sectorX][sectorY].begin(); itObject != this->m_renderableObjects[sectorX][sectorY].end(); itObject++)
  {
    if ((*itObject)->IsInPlayerView(this->m_camera->GetPosition(), this->m_camera->GetRenderRadius()))
    {
      // draw all objects, except the one the camera is attached to. thats drawn by the camera
      if ((*itObject).get() != this->m_camera->GetAttachedObject().get())
      {
        irr::core::vector2df posToRender = (*itObject)->Position() - this->m_camera->GetPosition();
        (*itObject)->OnDraw(irrlichtDevice, posToRender);
      }
    }
  }
}

Camera class

Camera2D::Camera2D() : m_screenWidth(0), m_screenHeight(0)
{
}

Camera2D::Camera2D(INT32 screenWidth, INT32 screenHeight) : m_screenWidth(screenWidth), m_screenHeight(screenHeight)
{
  m_screenCenterX = screenWidth / 2;
  m_screenCenterY = screenHeight / 2;
}

Camera2D::~Camera2D()
{
}

void Camera2D::OnUpdate(DOUBLE timeElapsed)
{
  if (this->m_objectToFollow.get() != nullptr)
  {
    this->SetPosition(this->m_objectToFollow->Position());
  }
  //else
  //{
  //  this->SetPosition(irr::core::vector2df(0, 0));
  //}
}   
void Camera2D::OnDraw(irr::IrrlichtDevice *irrlichtDevice)
{
  irr::core::vector2df screenCenter(this->m_screenCenterX, this->m_screenCenterY);
  this->m_objectToFollow->OnDraw(irrlichtDevice, screenCenter);
}

void Camera2D::AttachToObject(GameObjects::PTR_BODY objectToFollow)
{
  this->m_objectToFollow = objectToFollow;
}

star rendering

void GameObjects::Star::OnDraw(irr::IrrlichtDevice *irrlichtDevice, irr::core::vector2df &relativPos)
{                                                                                                             
  INT32 halfSpriteWidth = this->m_sprite->getSize().Width / 2;                                                
  INT32 halSpriteHeight = this->m_sprite->getSize().Height / 2;                                               

  int screenX = relativPos.X -halfSpriteWidth;                                                                
  int screenY = relativPos.Y -halSpriteHeight;                                                                

  irrlichtDevice->getVideoDriver()->draw2DImage(this->m_sprite, irr::core::vector2d<INT32>(screenX, screenY));
}

star update

void GameObjects::Star::OnUpdate(DOUBLE timeElapsed)
{
  // update planets
  for (std::list<boost::shared_ptr<Planet>>::iterator itPlanet = this->m_planets.begin(); itPlanet != this->m_planets.end(); itPlanet++)
  {
    (*itPlanet)->OnUpdate(timeElapsed);
  }

  // update asteroids
  for (std::list<boost::shared_ptr<Asteroid>>::iterator itAsteroid = this->m_asteroids.begin(); itAsteroid != this->m_asteroids.end(); itAsteroid++)
  {
    (*itAsteroid)->OnUpdate(timeElapsed);
  }
}

Planet rendering

void GameObjects::Planet::OnDraw(irr::IrrlichtDevice *irrlichtDevice, irr::core::vector2df &relativPos)       
{                                                                                                             
  INT32 halfSpriteWidth = this->m_sprite->getSize().Width / 2;                                                
  INT32 halSpriteHeight = this->m_sprite->getSize().Height / 2;                                               

  int screenX = relativPos.X - halfSpriteWidth;                                                               
  int screenY = relativPos.Y - halSpriteHeight;                                                               

  irrlichtDevice->getVideoDriver()->draw2DImage(this->m_sprite, irr::core::vector2d<INT32>(screenX, screenY));
}

planet update

void GameObjects::Planet::OnUpdate(DOUBLE timeElapsed)
{
  if (this->GetParent()->GetType() == GameObjects::GameObjectTypeStar)
  {
    PTR_STAR pStar = boost::dynamic_pointer_cast<Star>(this->GetParent());

    FLOAT angle = (this->GetOrbitingAngle() * timeElapsed) * (M_PI / 180);
    FLOAT rotatedX = cos(angle) * (this->Position().X - pStar->Position().X) - sin(angle) * (this->Position().Y - pStar->Position().Y) + pStar->Position().X;
    FLOAT rotatedY = sin(angle) * (this->Position().X - pStar->Position().X) + cos(angle) * (this->Position().Y - pStar->Position().Y) + pStar->Position().Y;

    this->SetPosition(irr::core::vector2df(rotatedX, rotatedY));
  }
}    

Ship rendering

void GameObjects::Ship::OnDraw(irr::IrrlichtDevice *irrlichtDevice, irr::core::vector2df &relativPos)            
{                                                                                                                
  INT32 halfSpriteWidth = this->m_sprite->getSize().Width / 2;                                                   
  INT32 halSpriteHeight = this->m_sprite->getSize().Height / 2;                                                  

  int screenX = relativPos.X - halfSpriteWidth;                                                                  
  int screenY = relativPos.Y - halSpriteHeight;                                                                  

  irrlichtDevice->getVideoDriver()->draw2DImage(this->GetSprite(), irr::core::vector2d<INT32>(screenX, screenY));
}                                                                                                                

ship update

void GameObjects::Ship::OnUpdate(DOUBLE timeElapsed)
{
  FLOAT velocityX, velocityY;
  velocityX = ::cos( ((ANGLE_ADJUSTMENT + this->GetAngle()) / 180) * M_PI) * (this->GetActualSpeed() * timeElapsed);
  velocityY = ::sin( ((ANGLE_ADJUSTMENT + this->GetAngle()) / 180) * M_PI) * (this->GetActualSpeed() * timeElapsed);
  this->SetVelocity(irr::core::vector2df(velocityX, velocityY));

  FLOAT newPosX = this->Position().X + this->Velocity().X;
  FLOAT newPosY = this->Position().Y + this->Velocity().Y;

  this->SetPosition(irr::core::vector2df(newPosX, newPosY));

  irr::video::ITexture * rotatedImage = Helper::IrrlichtHelper::GetInstance()->RotateImage(this->m_sprite, this->m_angle);
  this->UpdateSprite(rotatedImage);
}

Can someone give me a hint what I'am doing wrong or what do I have to change? I though my camera would work always when I just get a relative pos like I'm doing in my Galaxy::OnDraw(...) method.

Files are to big, to upload them here. :/ Links to *.gif

CameraAttachedToMovingShip

https://i.imgur.com/H6pc5BQ.gif

CameraAttachedToMovingPlanet

https://i.imgur.com/xeyH8gg.gif

\$\endgroup\$
  • 1
    \$\begingroup\$ I suggest you upload an animated gif made with a tool such as gifcam or screentogif that shows the issue at hand. This would help us help you :) \$\endgroup\$ – Vaillancourt Oct 6 '16 at 12:11
  • \$\begingroup\$ You did not describe the behaviour of your ship. Does it move? Is it orbiting the planet? \$\endgroup\$ – Vaillancourt Oct 6 '16 at 12:12
  • \$\begingroup\$ @AlexandreVaillancourt ok thanks, will do a gif and upload it here. When my camera is attached to the ship everything is rendered as expecten. When the ship moves and when it stands still. \$\endgroup\$ – user743414 Oct 6 '16 at 12:16
  • \$\begingroup\$ @AlexandreVaillancourt Links are added \$\endgroup\$ – user743414 Oct 6 '16 at 12:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.