Jomkin wrote: ↑Mon Nov 02, 2020 10:48 pm
Code: Select all
camera:setScale(*,*)
camera.x = ((player1.x + player2.x + player3.x)/3) - screenWidth
camera.y = ((player1.y + player2.y + player3.y)/3) - screenHeight
Shouldn't that be the average between the maximum and minimum position? The player that lies between max and min should not influence the camera position IMO. So:
Code: Select all
local min, max = math.min, math.max
local minX = min(min(player1.x, player2.x), player3.x)
local maxX = max(max(player1.x, player2.x), player3.x)
local minY = min(min(player1.y, player2.y), player3.y)
local maxY = max(max(player1.y, player2.y), player3.y)
camera.x = (minX + maxX)/2 -- - screenWidth (can't understand why the "- screenWidth")
camera.y = (minY + maxY)/2
The zoom factor should be the smallest of the ratios between the distance from centre to the edge of the screen at a zoom of 1x, and the distance from centre to min/max, but I imagine that you need to set some margins and maybe a zoom-in limiter.
Since both numerator and denominator should be divided by 2, I've simplified away the division by 2 below.
Code: Select all
-- You'll have to find an appropriate margin in each direction.
-- Note that the actual margin will be half the value below,
-- because of the simplification.
local marginX, marginY = 20, 20
local zoomX = screenWidth / (maxX - minX + marginX)
local zoomY = screenHeight / (maxY - minY + marginY)
local zoom = min(min(zoomX, zoomY), 1) -- limit zoom to no more than 1x
camera:setScale(zoom, zoom)
(edited because I screwed up the division order)
Edit2: Quick and dirty PoC:
Code: Select all
local camera = require 'cam11'()
local min, max = math.min, math.max
local isDown = love.keyboard.isScancodeDown
local marginX, marginY = 20, 50
local playerW = 10
local playerH = 30
local player1 = {x = 20, y = 20}
local player2 = {x = 50, y = 450}
local player3 = {x = 720, y = 30}
local playerSpeed = 200
local curPlayer = player1
local screenWidth = 800
local screenHeight = 600
if love.graphics.getWidth() ~= screenWidth then
love.graphics.setMode(screenWidth, screenHeight)
end
function love.update(dt)
if isDown("a") then curPlayer.x = curPlayer.x - playerSpeed * dt end
if isDown("d") then curPlayer.x = curPlayer.x + playerSpeed * dt end
if isDown("w") then curPlayer.y = curPlayer.y - playerSpeed * dt end
if isDown("s") then curPlayer.y = curPlayer.y + playerSpeed * dt end
local minX = min(min(player1.x, player2.x), player3.x)
local maxX = max(max(player1.x, player2.x), player3.x)
local minY = min(min(player1.y, player2.y), player3.y)
local maxY = max(max(player1.y, player2.y), player3.y)
camera:setPos((minX + maxX) * 0.5, (minY + maxY) * 0.5)
local zoomX = screenWidth / (maxX - minX + marginX)
local zoomY = screenHeight / (maxY - minY + marginY)
local zoom = min(min(zoomX, zoomY), 1) -- limit zoom to no more than 1x
camera:setZoom(zoom)
end
local function setColourFor(n)
local n_player = player1
if n == 2 then n_player = player2 end
if n == 3 then n_player = player3 end
if n_player == curPlayer then
love.graphics.setColor(1, 0.5, 0)
else
love.graphics.setColor(0.5, 1, 1)
end
end
function love.draw()
camera:attach()
setColourFor(1)
love.graphics.rectangle("fill",
player1.x - playerW*0.5, player1.y - playerH*0.5, playerW, playerH)
setColourFor(2)
love.graphics.rectangle("fill",
player2.x - playerW*0.5, player2.y - playerH*0.5, playerW, playerH)
setColourFor(3)
love.graphics.rectangle("fill",
player3.x - playerW*0.5, player3.y - playerH*0.5, playerW, playerH)
love.graphics.setColor(1, 1, 1)
camera:detach()
end
function love.keypressed(keycode, scancode)
if scancode == '1' then curPlayer = player1 end
if scancode == '2' then curPlayer = player2 end
if scancode == '3' then curPlayer = player3 end
if scancode == 'escape' then return love.event.quit() end
end
(use wasd for movement; to switch player use 1, 2, 3 of the regular keyboard, not of the keypad)
Needs
https://notabug.org/pgimeno/cam11