Make collision boxes stay when camera is used

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
soulgirl2020
Prole
Posts: 6
Joined: Thu Jun 18, 2020 11:47 pm

Make collision boxes stay when camera is used

Post by soulgirl2020 »

I'm making a basic 1986 Zelda game and so far I am comfortable using love.physics and setting up the collisions boxes and things of that nature. Once I tried to move the camera down all my boxes don't stay where they're supposed to be at. I only have an offset of -3 for the camera. They collision boxes just remain on the screen, how do I go about updating this?

Main.lua

Code: Select all

Class = require 'class'
push = require 'push'
require 'Util'
require 'Player'
require 'BoxP'
require 'BoxE1'
require 'Enemy1'
require 'Enemy2'
require 'Enemy3'
require 'Enemy_fire'


-- Initialize classes to main
 my_player =  Player:init()
 my_enemy_1 = Enemy1:init()
 my_enemy_2 = Enemy2:init()
 my_enemy_3 = Enemy3:init()
 enemy_fire = Enemy_fire:init()
 my_enemy1_box = BoxE1:init()


 

TILE_EMPTY = -1

-- Tree tiles
TILE_TREE = 4

-- Top wall tiles
TILE_WALL = 2
SECRET_WALL = 6

TILE_HEART = 1


-- close resolution to NES but 16:9
VIRTUAL_WIDTH = 432
VIRTUAL_HEIGHT = 243

-- actual window resolution
WINDOW_WIDTH = 1280
WINDOW_HEIGHT = 720

local SCROLL_SPEED = 65

love.graphics.setDefaultFilter('nearest', 'nearest')

local tileWidth = 16
local tileHeight = 16
local mapWidth = 30
local mapHeight = 28
local xOffset = 8
local yOffset = 10
local tiles = {}

local p = love.physics

function love.load()
    world = love.physics.newWorld()
    -- Create collision boxes for each object
    wall_left = {}
        wall_left.b = p.newBody(world,8,115,'static')
        wall_left.s = p.newRectangleShape(tileWidth,225)
        wall_left.f = p.newFixture(wall_left.b,wall_left.s)

    wall_right = {}
        wall_right.b = p.newBody(world,424,1,'static')
        wall_right.s = p.newRectangleShape(tileWidth,450)
        wall_right.f = p.newFixture(wall_right.b,wall_right.s)

    wall_top = {}
        wall_top.b = p.newBody(world,210,11,'static')
        wall_top.s = p.newRectangleShape(420,tileHeight)
        wall_top.f = p.newFixture(wall_top.b,wall_top.s)

    wall_bottom = {}
        wall_bottom.b = p.newBody(world,210,235,'static')
        wall_bottom.s = p.newRectangleShape(377,tileHeight)
        wall_bottom.f = p.newFixture(wall_bottom.b,wall_bottom.s)

    secret_wall = {}
        secret_wall.b = p.newBody(world,377,235,'static')
        secret_wall.s = p.newRectangleShape(416,tileHeight)
        secret_wall.f = p.newFixture(secret_wall.b,secret_wall.s)

    tree_top = {}
        tree_top.b = p.newBody(world,151,75,'static')
        tree_top.s = p.newRectangleShape(tileWidth * 11 - 5,tileHeight)
        tree_top.f = p.newFixture(tree_top.b,tree_top.s)

    tree_bottom = {}
        tree_bottom.b = p.newBody(world,151,140,'static')
        tree_bottom.s = p.newRectangleShape(tileWidth * 11 - 5,tileHeight)
        tree_bottom.f = p.newFixture(tree_bottom.b,tree_bottom.s)

    tree_left = {}
        tree_left.b = p.newBody(world,344,105,'static')
        tree_left.s = p.newRectangleShape(tileWidth,tileHeight * 7)
        tree_left.f = p.newFixture(tree_left.b,tree_left.s)
       
        player.b = p.newBody(world,Player.x + 8,Player.y + 11,'dynamic')
        player.b:setFixedRotation(true)
        player.s = p.newRectangleShape(16,16)
        player.f = p.newFixture(player.b,player.s)

        enemy1.b = p.newBody(world,Enemy1.x + 8,Enemy1.y + 11,'dynamic')
        enemy1.b:setFixedRotation(true)
        enemy1.s = p.newRectangleShape(16,16)
        enemy1.f = p.newFixture(enemy1.b,enemy1.s)

        enemy2.b = p.newBody(world,Enemy2.x,Enemy2.y,'dynamic')
        enemy2.b:setFixedRotation(true)
        enemy2.s = p.newRectangleShape(16,16)
        enemy2.f = p.newFixture(enemy2.b,enemy2.s)

        enemy3.b = p.newBody(world,Enemy3.x ,Enemy3.y ,'dynamic')
        enemy3.b:setFixedRotation(true)
        enemy3.s = p.newRectangleShape(16,16)
        enemy3.f = p.newFixture(enemy3.b,enemy3.s)

             
    push:setupScreen(VIRTUAL_WIDTH, VIRTUAL_HEIGHT, WINDOW_WIDTH, WINDOW_HEIGHT, {
        fullscreen = false,
        resizable = true
    })
    
    spritesheet = love.graphics.newImage('Sprites/hearts_tree_walls.png')
   
    
    -- camera offsets
    camX = 0
    camY = -3

    sprites = generateQuads(spritesheet, 16, 16)
    
    -- cache width and height of map in pixels
    mapWidthPixels = mapWidth * tileWidth
    mapHeightPixels = mapHeight * tileHeight

-- sets a tile at a given x-y coordinate to an integer value

    -- first, fill map with empty tiles
    for y = 1, mapHeight do
        for x = 1, mapWidth do
            
            -- support for multiple sheets per tile; storing tiles as tables 
            setTile(x, y, TILE_EMPTY)
        end
    end
    -- create wall tiles on the bottom of the screen
    for y = mapHeight / 2 + 1, mapHeight / 2 + 1  do
        for x = 0, 25 do
            setTile(x, y, TILE_WALL)
        end
    end
    -- Secret wall
    if player.b:isTouching(secret_wall.b) then
        for y = mapHeight / 2 + 1, mapHeight / 2 + 1  do
            for x = 26, 26 do
                setTile(x, y, TILE_EMPTY)
            end
        end
    else
    for y = mapHeight / 2 + 1, mapHeight / 2 + 1  do
        for x = 26, 26 do
            setTile(x, y, SECRET_WALL)
        end
    end
end
    --left hand side tile
    for y = 0, 25  do
        for x = 1, 1 do
            setTile(x, y, TILE_WALL)
        end
    end
    -- Upper right hand side tiles
    for y = 0, 25  do
        for x = 27, 27 do
            setTile(x, y, TILE_WALL)
        end
    end
    --Top screen tiles
    for y = 1, 1   do
        for x = 0, 26 do
            setTile(x, y, TILE_WALL)
        end
    end
    -- tree top left
    for y = 5, 5   do
        for x = 5, 15 do
            setTile(x, y, TILE_TREE)
        end
    end
    -- tree bottom-left
    for y = 9, 9   do
        for x = 5, 15 do
            setTile(x, y, TILE_TREE)
        end
    end
    -- tree right 
    for y = mapHeight / 2 - 10, mapHeight / 2 - 4   do
        for x = 22, 22 do
            setTile(x, y, TILE_TREE)
        end
    end
    for y = mapHeight / 2 - 12, mapHeight / 2 - 12   do
        for x = 26, 26 do
            setTile(x, y, TILE_HEART)
        end
    end

    love.window.setTitle('Legend of Zelda Demo')

    love.keyboard.keysPressed = {}
    love.keyboard.keysReleased = {}

end

function setTile(x, y, id)
    tiles[(y - 1) * mapWidth + x] = id
end

-- gets the tile type at a given pixel coordinate
function tileAt(x, y)
    return {
        x = math.floor(x / tileWidth) + 1,
        y = math.floor(y / tileHeight) + 1,
        id = getTile(math.floor(x / tileWidth) + 1, math.floor(y / tileHeight) + 1)
    }
end

-- returns an integer value for the tile at a given x-y coordinate
function getTile(x, y)
    return tiles[(y - 1) * mapWidth + x]
end

function collides(tile)
    -- define our collidable tiles
     collidables = {
        TILE_TREE,TILE_WALL,SECRET_WALL
    }

    -- iterate and return true if our tile type matches
    for _, v in ipairs(collidables) do
        if tile.id == v then
            return true
        end
    end
    return false
end

function love.resize(w,h)
    push:resize(w,h)
end

function love.keyboard.wasReleased(key)
    if (love.keyboard.keysReleased[key]) then
        return true
    else
        return false
    end
end

function love.keypressed(key)
    if key == 'escape' then
        love.event.quit()
    end

    love.keyboard.keysPressed[key] = true
end

function love.keyreleased(key)
    love.keyboard.keysReleased[key] = true
end

function love.update(dt)

    if love.keyboard.isDown('w') then
        camY = math.max(0,camY - dt * SCROLL_SPEED)

    elseif love.keyboard.isDown('s') then

        camY = math.min(camY + dt * SCROLL_SPEED, mapHeightPixels - VIRTUAL_HEIGHT)
    end

    world:update(dt)
    Player:update(dt)
    Enemy1:update(dt)
    Enemy2:update(dt)
    Enemy3:update(dt)
    BoxE1:update(dt)
    --Enemy_fire:update(dt)

    -- reset all keys pressed and released this frame
    love.keyboard.keysPressed = {}
    love.keyboard.keysReleased = {}
   
end

function love.draw()
    push:apply('start')
    -- Clears screen with light brown color
    love.graphics.clear(252/255, 216/255, 169/255, 1)

    -- Draws left wall
    love.graphics.polygon('line',wall_left.b:getWorldPoints(wall_left.s:getPoints()))
   
    -- Draws right wall
    love.graphics.polygon("line", wall_right.b:getWorldPoints(wall_right.s:getPoints()))

    -- Draws top wall
    love.graphics.polygon("line", wall_top.b:getWorldPoints(wall_top.s:getPoints()))

    -- Draws bottom wall
    love.graphics.polygon("line", wall_bottom.b:getWorldPoints(wall_bottom.s:getPoints()))

    -- Draws secret wall
    love.graphics.polygon("line", secret_wall.b:getWorldPoints(secret_wall.s:getPoints()))

    -- Draws Top tree
    love.graphics.polygon("line", tree_top.b:getWorldPoints(tree_top.s:getPoints()))

    -- Draws Bottom tree
    love.graphics.polygon("line", tree_bottom.b:getWorldPoints(tree_bottom.s:getPoints()))

     -- Draws left tree
     love.graphics.polygon("line", tree_left.b:getWorldPoints(tree_left.s:getPoints()))

    -- Draws Link's(player) collision box
    love.graphics.polygon("line", player.b:getWorldPoints(player.s:getPoints()))

    -- Draws enemy1's collision box
    love.graphics.polygon("line", enemy1.b:getWorldPoints(enemy1.s:getPoints()))
    
    -- Draws enemy2's collision box
    love.graphics.polygon("line", enemy2.b:getWorldPoints(enemy2.s:getPoints()))
    
    -- Draws enemy3's collision box
    love.graphics.polygon("line", enemy3.b:getWorldPoints(enemy3.s:getPoints()))

    love.graphics.translate(math.floor(-camX + 0.5), math.floor(-camY + 0.5))
    local scaleX = -1
    for y = 1, mapHeight do
        for x = 1, mapWidth do
            local tile = getTile(x, y)
            if tile ~= TILE_EMPTY then
                love.graphics.draw(spritesheet, sprites[tile],
                    (x - 1) * tileWidth, (y - 1) * tileHeight)
            end
        end
    end
    Player:render()
    Enemy1:render()
    Enemy2:render()
    Enemy3:render()
    --BoxP:draw()
    --BoxE1:draw()
    push:apply('end')
end


User avatar
pgimeno
Party member
Posts: 3656
Joined: Sun Oct 18, 2015 2:58 pm

Re: Make collision boxes stay when camera is used

Post by pgimeno »

By moving love.graphics.translate before the boxes?
soulgirl2020
Prole
Posts: 6
Joined: Thu Jun 18, 2020 11:47 pm

Re: Make collision boxes stay when camera is used

Post by soulgirl2020 »

THANK YOU!!!! I keep forgetting that everything at the bottom of the code is rendered last. That makes sense, I'll keep that in mind.
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], Google [Bot] and 3 guests