Page 1 of 1

[Solved] Hump.camera + love.physics

Posted: Thu Sep 26, 2019 2:16 pm
by Thorkal
Hi everyone,

For my project, I use love.physics and camera is handled by hump.camera. I don't want all the stuff on screen move when the player moves, so every entity has a variable set to true if I want then to be camera independent. This is the case for a square that I always want at the top of the screen (it only moves on the x axis). This square is a physics body, so my player can collide with it (but it shouldn't happen if what I want to do would work).

For now, the drawn shape of the square is always at the top of the screen as I want, but the body seems affected by the camera and when I climb up with my player, it scrolls down with the other elements.

Here is the part where my entities are drawn :

Code: Select all

function Entities:draw()
  Entities:orderByZIndex()
  for i, e in ipairs(self.entityList) do
    if not e.cameraIndependant then
      camera:attach()
    end
    e:draw()
    if e.shape ~= nil then
      --love.graphics.polygon('line', e.body:getWorldPoints(e.shape:getPoints()))
    end
    if not e.cameraIndependant then
      camera:detach()
    end
  end
end
And here is the core of my class with which I have the issue :

Code: Select all

local Class = require 'libs.hump.class'
local Entity = require 'entities.Entity'
local Platform = require 'entities.Platform'


local pGenerator = Class{
  __includes = Entity -- pGenerator class inherits our Entity class
}

function pGenerator:init(world, w, h, acc)
  local x = 5 + w
  local y = 0

  Entity.init(self, x, y, w, h)

  self.acc = acc or 0

  self.dir = 1

  self.world = world
  self.precTime = 0
  self.time = 0

  self.body = love.physics.newBody(self.world, x, y, 'dynamic')
  self.body:setGravityScale(0)
  self.body:setFixedRotation(true)
  self.shape = love.physics.newRectangleShape(w, h)
  self.fixture = love.physics.newFixture(self.body, self.shape)
  self.fixture:setFriction(5)

  self.leftSensor = love.physics.newRectangleShape(-w/2, 0, 4, h)
  self.fixture = love.physics.newFixture(self.body, self.leftSensor)
  self.fixture:setCategory(4)
  self.fixture:setUserData(self)
  self.fixture:setSensor(true)

  self.rightSensor = love.physics.newRectangleShape(w/2, 0, 4, h)
  self.fixture = love.physics.newFixture(self.body, self.rightSensor)
  self.fixture:setCategory(5)
  self.fixture:setUserData(self)
  self.fixture:setSensor(true)

  self.stop = false
  self.cameraIndependant = true

end

function pGenerator:update(dt)

  self.time = self.time + dt
  self.body:setLinearVelocity(self.acc*self.dir*dt, 0)

  step = 2

  if math.floor(self.time)-self.precTime == step and self.stop == false then
    self.precTime = math.floor(self.time)
    local platform = Platform(self.world, self.body:getX(), self.h+2, self.w, 2)
    Entities:add(platform)
  end
end

function pGenerator:setDir(dir)
  self.dir = dir
end

function pGenerator:getDir()
  return self.dir
end

function pGenerator:draw()
  love.graphics.polygon('fill', self.body:getWorldPoints(self.shape:getPoints()))
  --love.graphics.polygon('line', self.body:getWorldPoints(self.leftSensor:getPoints()))
  --love.graphics.polygon('line', self.body:getWorldPoints(self.rightSensor:getPoints()))
  love.graphics.setColor(1, 1, 1)
  Entity:draw(self)
end

return pGenerator
Thanks for your help

Re: Hump.camera + love.physics

Posted: Thu Sep 26, 2019 2:53 pm
by pgimeno
Conceptually, moving the camera does not move the world, it literally moves the camera just like moving a camera in real life doesn't move the world that it is filming. If your camera is always focused on the player, what you effectively have is a camera attached to the player. If you want other entities to be static with respect to the camera, you need to move the other entities exactly like the camera, because that's how they will be static with respect to the camera. Detaching the camera is not the way to do it. How would you have an object always in front of the camera in real life as you move the camera? By having the object follow the camera everywhere (or attaching the object to the camera).

Alternatively, you can forget about the camera and move the world instead. It's hard to recommend a strategy without understanding what you're after.

One problem of love.physics is that it's difficult to make objects do arbitrary movements without calling setPosition, and calling it can cause problems with collisions. Again, it's hard to give advice without knowing the details of your project, but if possible, implementing your own physics and using a collision library could perhaps work better for you.

Re: Hump.camera + love.physics

Posted: Thu Sep 26, 2019 3:25 pm
by TheHUG
Another possible solution:
If your camera is always centered on the player, then you can just setLinearVelocity() on the camera-stationary objects to be equal to that of the player (not sure what order love physics resolves force, acceleration, velocity, depending on that and how you move your player around you may need to use setLinearAcceleration() or one of the others instead)

Are these object's positions relative to the player always the same, or if they collide with something in the environment, could they be bounced so they move relative to the player?

Re: Hump.camera + love.physics

Posted: Thu Sep 26, 2019 4:40 pm
by Thorkal
Okay, thank you to you two.

I, as pgimeno suggested, attached my square to the camera and used setLinearVelocity on it when my player is at a certain minimum distance from it and it works well.