Difference between revisions of "Camera Scripts"

From X-Moto
Jump to: navigation, search
Line 25: Line 25:
 
  -- ExtendedCamera
 
  -- ExtendedCamera
 
  do
 
  do
  local CamX, CamY = 0, 0
+
  local CamX, CamY = 0, 0
 +
 
 +
  function Game.CameraPos()
 +
    return CamX, CamY
 +
  end
 +
  function Game.CameraPosAbs()
 +
    local x, y = Game.GetPlayerPosition()
 +
    return x + CamX + 0.6, y + CamY
 +
  end
 
    
 
    
  function Game.CameraPos()
+
  local Game_CameraMove = Game.CameraMove
    return CamX, CamY
+
  function Game.CameraMove(x, y, ...)
  end
+
    if x ~= 0 and y ~= 0 then
  function Game.CameraPosAbs()
+
      CamX = CamX + x
    local x, y = Game.GetPlayerPosition()
+
      CamY = CamY + y
    return x + CamX + 0.6, y + CamY
+
      return Game_CameraMove(x, y, ...)
  end
+
    end
+
  end
  local Game_CameraMove = Game.CameraMove
+
  function Game.CameraMoveTo(x, y)
  function Game.CameraMove(x, y, ...)
+
    return Game.CameraMove(x - CamX, y - CamY)
    if x ~= 0 and y ~= 0 then
+
  end
      CamX = CamX + x
+
  function Game.CameraMoveAbs(x, y)
      CamY = CamY + y
+
    local px, py = Game.CameraPosAbs()
      return Game_CameraMove(x, y, ...)
+
    return Game.CameraMove(x - px, y - py)
    end
+
  end
  end
 
  function Game.CameraMoveTo(x, y)
 
    return Game.CameraMove(x - CamX, y - CamY)
 
  end
 
  function Game.CameraMoveAbs(x, y)
 
    local px, py = Game.CameraPosAbs()
 
    return Game.CameraMove(x - px, y - py)
 
  end
 
 
  end
 
  end
 
  -- /ExtendedCamera
 
  -- /ExtendedCamera
Line 65: Line 65:
 
Example:
 
Example:
 
  function OnLoad()
 
  function OnLoad()
  StaticCamera(Game.GetEntityPos("cam1"))  -- make the camera always look at "cam1" sprite
+
  StaticCamera(Game.GetEntityPos("cam1"))  -- make the camera always look at "cam1" sprite
  return true
+
  return true
 
  end
 
  end
  
Line 72: Line 72:
 
  -- StaticCamera
 
  -- StaticCamera
 
  do
 
  do
  local camX, camY
+
  local camX, camY
  local oldTick
+
  local oldTick
 +
 
 +
  local function MyTick()
 +
    local ret = oldTick and oldTick() or true
 +
    Game.CameraMoveAbs(camX, camY)
 +
    return ret
 +
  end
 
    
 
    
  local function MyTick()
+
  function StaticCamera(x, y)
    local ret = oldTick and oldTick() or true
+
    if x then
    Game.CameraMoveAbs(camX, camY)
+
      if camX == nil then
    return ret
+
        oldTick = Tick
  end
+
        Tick = MyTick
+
      end
  function StaticCamera(x, y)
+
      camX, camY = x, y
    if x then
+
      Game.CameraMoveAbs(camX, camY)
      if camX == nil then
+
    else
        oldTick = Tick
+
      if camX then
        Tick = MyTick
+
        Tick = oldTick
      end
+
        camX, camY = nil, nil
      camX, camY = x, y
+
        Game.CameraMoveTo(0, 0)
      Game.CameraMoveAbs(camX, camY)
+
      end
    else
+
    end
      if camX then
+
  end
        Tick = oldTick
 
        camX, camY = nil, nil
 
        Game.CameraMoveTo(0, 0)
 
      end
 
    end
 
  end
 
 
  end
 
  end
 
  -- /StaticCamera
 
  -- /StaticCamera
Line 118: Line 118:
 
Example:
 
Example:
 
  function OnLoad()
 
  function OnLoad()
  UseZoneCamera(3)  -- if you have only 3 cameras: "cam1", "cam2", "cam3"
+
  UseZoneCamera(3)  -- if you have only 3 cameras: "cam1", "cam2", "cam3"
  return true
+
  return true
 
  end  
 
  end  
  
Line 132: Line 132:
 
  -- UseZoneCamera
 
  -- UseZoneCamera
 
  function UseZoneCamera(CamCount, keep_sprites)
 
  function UseZoneCamera(CamCount, keep_sprites)
  -- const
+
  -- const
  local stick_radius = 0.5
+
  local stick_radius = 0.5
  local y_coeff = 0.8
+
  local y_coeff = 0.8
  -- /const
+
  -- /const
 
+
 
  local Cams = {}
+
  local Cams = {}
  local CurCam
+
  local CurCam
  local CamX, CamY = 0, 0
+
  local CamX, CamY = 0, 0
 
+
 
  local abs = math.abs
+
  local abs = math.abs
  local sqrt = math.sqrt
+
  local sqrt = math.sqrt
 
+
 
  local function ChangeCam()
+
  local function ChangeCam()
    local x, y = Game.GetPlayerPosition()
+
    local x, y = Game.GetPlayerPosition()
   
+
   
    local function dist(cam)
+
    local function dist(cam)
      local c = Cams[cam]
+
      local c = Cams[cam]
      local dx, dy = abs(c[1] - x), abs(c[2] - y)*y_coeff
+
      local dx, dy = abs(c[1] - x), abs(c[2] - y)*y_coeff
      return sqrt(dx*dx + dy*dy)/c[3]
+
      return sqrt(dx*dx + dy*dy)/c[3]
    end
+
    end
   
+
   
    local cam = CurCam
+
    local cam = CurCam
    local m = cam and (dist(cam) - stick_radius)
+
    local m = cam and (dist(cam) - stick_radius)
 
+
 
    for i = 1, CamCount do
+
    for i = 1, CamCount do
      local d = dist(i)
+
      local d = dist(i)
      if not m or d < m then
+
      if not m or d < m then
        m = d
+
        m = d
        cam = i
+
        cam = i
      end
+
      end
    end
+
    end
    CurCam = cam
+
    CurCam = cam
    Game.CameraMoveAbs(Cams[cam][1], Cams[cam][2])
+
    Game.CameraMoveAbs(Cams[cam][1], Cams[cam][2])
  end
+
  end
 
+
 
  for i = 1, CamCount do
+
  for i = 1, CamCount do
    local name = "cam"..i
+
    local name = "cam"..i
    local cam = {Game.GetEntityPos(name)}
+
    local cam = {Game.GetEntityPos(name)}
    cam[3] = Game.GetEntityRadius(name)
+
    cam[3] = Game.GetEntityRadius(name)
    Cams[i] = cam
+
    Cams[i] = cam
    if not keep_sprites then  Game.KillEntity(name)  end
+
    if not keep_sprites then  Game.KillEntity(name)  end
  end
+
  end
  ChangeCam()
+
  ChangeCam()
 
+
 
  local oldTick = Tick
+
  local oldTick = Tick
  Tick = function()
+
  Tick = function()
    local ret = oldTick and oldTick() or true
+
    local ret = oldTick and oldTick() or true
    ChangeCam()
+
    ChangeCam()
    return ret
+
    return ret
  end
+
  end
 
  end
 
  end
 
  -- /UseZoneCamera
 
  -- /UseZoneCamera
  
 
Author: GrayFace
 
Author: GrayFace

Revision as of 10:47, 23 August 2009

Here are some scripts you can use in your level.

Extended Camera

This script adds new functions to control camera position.

Game.CameraPos() returns camera position (x, y) relative to player position.

Usage: x, y = Game.CameraPos()

Game.CameraPosAbs() returns camera position (x, y) in level coordinates.

Usage: x, y = Game.CameraPosAbs()

Game.CameraMoveTo(x, y) moves the camera to position (x, y) relative to player.

Example: Game.CameraMoveTo(0, 0) -- return camera to its normal state

Game.CameraMoveAbs(x, y) moves the camera to position (x, y) in level coordinates.

Example: Game.CameraMoveTo(Game.GetEntityPos("cam1")) -- make camera look at "cam1" sprite

To use the functions add this script to your Lua file:

-- ExtendedCamera
do
  local CamX, CamY = 0, 0
  
  function Game.CameraPos()
    return CamX, CamY
  end
  function Game.CameraPosAbs()
    local x, y = Game.GetPlayerPosition()
    return x + CamX + 0.6, y + CamY
  end
 
  local Game_CameraMove = Game.CameraMove
  function Game.CameraMove(x, y, ...)
    if x ~= 0 and y ~= 0 then
      CamX = CamX + x
      CamY = CamY + y
      return Game_CameraMove(x, y, ...)
    end
  end
  function Game.CameraMoveTo(x, y)
    return Game.CameraMove(x - CamX, y - CamY)
  end
  function Game.CameraMoveAbs(x, y)
    local px, py = Game.CameraPosAbs()
    return Game.CameraMove(x - px, y - py)
  end
end
-- /ExtendedCamera

Author: GrayFace

Static Camera

This script lets you set the camera to a fixed position. The camera will not follow the player any more.

StaticCamera(x, y) will set the camera to (x, y) coordinates in the level

StaticCamera() (without parameters) will reset the camera, so it will follow the player again

Example:

function OnLoad()
  StaticCamera(Game.GetEntityPos("cam1"))  -- make the camera always look at "cam1" sprite
  return true
end

To use Static Camera add Extended Camera script to your Lua file and then add this script:

-- StaticCamera
do
  local camX, camY
  local oldTick
  
  local function MyTick()
    local ret = oldTick and oldTick() or true
    Game.CameraMoveAbs(camX, camY)
    return ret
  end
 
  function StaticCamera(x, y)
    if x then
      if camX == nil then
        oldTick = Tick
        Tick = MyTick
      end
      camX, camY = x, y
      Game.CameraMoveAbs(camX, camY)
    else
      if camX then
        Tick = oldTick
        camX, camY = nil, nil
        Game.CameraMoveTo(0, 0)
      end
    end
  end
end
-- /StaticCamera

Author: GrayFace

Zone Camera (sprites based)

This script is based on idea from Cigam_Interesting Effect 03 (Zone Camera) level. It implements it using camera sprites instead of zones.

Usage:

Create sprites in your level at points where you want cameras to be. Name them "cam1", "cam2", "cam3" and so on. (use Effects -> X-moto -> Other -> Change Id in Inkscape) I suggest using invisible sprites.

Then call UseZoneCamera(cam_count, keep_cams) to turn zone cameras on.

cam_count parameter is the number of cameras.

If keep_cams parameter is true, the sprites used as cameras will remain on the level. If it's false or not specified, the sprites will be deleted once zone camera is activated.

Example:

function OnLoad()
  UseZoneCamera(3)  -- if you have only 3 cameras: "cam1", "cam2", "cam3"
  return true
end 

You can also make some camera preferable. Change its Sprite scale value to do so. (in Effects -> X-moto -> Entities -> Sprite dialog) Set bigger value to make the camera more 'respected'. The script likes bigger cameras ;)

Test your level in 1280x1024 resolution to make sure player is always visible.

Note: don't use Zone Camera if it doesn't fit your level. It brings certain inconvenience into playing. IMO, it may be good only for rooms-based levels.

To use Zone Camera add Extended Camera script to your Lua file and then add this script:

-- UseZoneCamera
function UseZoneCamera(CamCount, keep_sprites)
  -- const
  local stick_radius = 0.5
  local y_coeff = 0.8
  -- /const
  
  local Cams = {}
  local CurCam
  local CamX, CamY = 0, 0
  
  local abs = math.abs
  local sqrt = math.sqrt
  
  local function ChangeCam()
    local x, y = Game.GetPlayerPosition()
    
    local function dist(cam)
      local c = Cams[cam]
      local dx, dy = abs(c[1] - x), abs(c[2] - y)*y_coeff
      return sqrt(dx*dx + dy*dy)/c[3]
    end
    
    local cam = CurCam
    local m = cam and (dist(cam) - stick_radius)
  
    for i = 1, CamCount do
      local d = dist(i)
      if not m or d < m then
        m = d
        cam = i
      end
    end
    CurCam = cam
    Game.CameraMoveAbs(Cams[cam][1], Cams[cam][2])
  end
  
  for i = 1, CamCount do
    local name = "cam"..i
    local cam = {Game.GetEntityPos(name)}
    cam[3] = Game.GetEntityRadius(name)
    Cams[i] = cam
    if not keep_sprites then  Game.KillEntity(name)  end
  end
  ChangeCam()
  
  local oldTick = Tick
  Tick = function()
    local ret = oldTick and oldTick() or true
    ChangeCam()
    return ret
  end
end
-- /UseZoneCamera

Author: GrayFace