RPG collision detection!

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
smiller
Prole
Posts: 8
Joined: Sun Oct 10, 2010 7:25 pm

RPG collision detection!

Post by smiller »

Code: Select all

function love.load()
    -- our tiles
    tile = {}
    for i=0,3 do -- change 3 to the number of tile images minus 1.
        tile[0] = love.graphics.newImage( "test1.bmp" ) --the tiles are loaded to be used.
	tile[1] = love.graphics.newImage( "test2.bmp" )
	tile[2] = love.graphics.newImage( "test3.bmp" )
	tile[3] = love.graphics.newImage( "pic.png" )
    end
    
    -- the map; the 0,1,2,3 etc. are the things you see above! (tile[0] etc.)
    map={
    { 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0}, 
    { 3, 1, 0, 0, 2, 2, 2, 0, 3, 0, 3, 0, 1, 1, 1, 0, 0, 3, 0, 0, 0},
    { 3, 1, 0, 0, 2, 0, 2, 0, 3, 0, 3, 0, 1, 0, 0, 0, 0, 0, 3, 0, 0},
    { 3, 1, 1, 0, 2, 2, 2, 0, 0, 3, 0, 0, 1, 1, 0, 0, 0, 0, 0, 3, 0},
    { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3},
    { 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 2},
    { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
    { 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
    { 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
    { 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
    { 0, 2, 2, 2, 0, 3, 3, 3, 0, 1, 1, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0},
    { 0, 2, 0, 0, 0, 3, 0, 3, 0, 1, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 1},
    { 0, 2, 0, 0, 0, 3, 0, 3, 0, 1, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0},
    { 0, 2, 2, 2, 0, 3, 3, 3, 0, 1, 1, 1, 0, 2, 2, 2, 0, 0, 0, 0, 0},
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
    { 0, 1, 0, 0, 2, 2, 2, 0, 3, 0, 3, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0},
    { 0, 1, 0, 0, 2, 0, 2, 0, 3, 0, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
    { 0, 1, 1, 0, 2, 2, 2, 0, 0, 3, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0},
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3},
    { 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0},
    { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
    { 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
    { 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
    }
--need to find a way to make "buffer tiles" outside the map, like Pokemon
    -- map variables
    map_w = #map[1] -- Obtains the width of the first row of the map
    map_h = #map -- Obtains the height of the map
    map_x = 0 --starting position of when the game is started.
    map_y = 0
    map_display_buffer = 2 -- We have to buffer one tile before and behind our viewpoint.
                               -- Otherwise, the tiles will just pop into view, and we don't want that.
    map_display_w = 20
    map_display_h = 15
    tile_w = 64
    tile_h = 64
    love.keyboard.setKeyRepeat( 20, 400 )
    end
    
function draw_map()
    offset_x = map_x % tile_w
    offset_y = map_y % tile_h
    firstTile_x = math.floor(map_x / tile_w)
    firstTile_y = math.floor(map_y / tile_h)
    
    for y=1, (map_display_h + map_display_buffer) do
        for x=1, (map_display_w + map_display_buffer) do
            -- Note that this condition block allows us to go beyond the edge of the map.
            if y+firstTile_y >= 1 and y+firstTile_y <= map_h
                and x+firstTile_x >= 1 and x+firstTile_x <= map_w
            then
                love.graphics.draw(
                    tile[map[y+firstTile_y][x+firstTile_x]], 
                    (x*tile_w) - offset_x - tile_w/2, 
                    (y*tile_h) - offset_y - tile_h/2)
            end
        end
    end
end

function love.keypressed(key,unicode)
    -- get input
    if key == "up" then
	map_y = map_y -64 --Look into a way to make this transition work smoothly but still snap to the tile.
    end
    if key == "down" then
        map_y = map_y+64
    end

    if key == "left" then
        map_x = map_x -64
    end
    if key == "right" then
        map_x = map_x+64
    end
    
    --we need a button to give the four diagnol arrows, signalling which button pushes can occur at those arrows. Then, down-left, down-right, etc. need to make their movement.

    -- check boundaries
    if map_x < 0 then
        map_x = 0
    end

    if map_y < 0 then
        map_y = 0
    end 
 
    if map_x > map_w * tile_w - map_display_w * tile_w then
        map_x = map_w * tile_w - map_display_w * tile_w
    end
 
    if map_y > map_h * tile_h - map_display_h * tile_h then
        map_y = map_h * tile_h - map_display_h * tile_h
    end
    
    if 
end

function love.draw()
    draw_map()
end
Basically, I'm making a dungeon crawler (except more like building crawler) RPG. Cool, used the tutorial, got it WORKING, know how all of it works, finally... (after much tinkering!) except I do not know how to add collision detection.

This was my thought process: I could tell it that tile[1], tile[2], and tile[3] are impassable objects. Thus, it does not move through the object (it's position stays the same). However, I do not know how to approach writing this. I do not know how to have it find what tile it is on, it seems like it draws the tiles, but that there is no real way to get back to the position of the tiles (if you get what I mean). I have been trying for a while now, and I am absolutely stumped!

I'm not looking for someone to write it for me, though... I want to try to get this on my own!

(Also, yes, i know there are a lot of comments. These were for someone else.. who happened to have too busy of a schedule to work with me anymore >.<;)

Thanks for helping a newbie out. ^^
User avatar
walesmd
Prole
Posts: 22
Joined: Fri Oct 08, 2010 3:11 am
Location: Augusta, GA
Contact:

Re: RPG collision detection!

Post by walesmd »

We'll assume 3 is the only impassable tile, this would go within your keypressed() functions that handles movement.

Code: Select all

if map[map_y][map_x] ~= "3" then
  -- Do the movement
end
Because we are not including a condition for the impassable object (3), nothing will happen.
smiller
Prole
Posts: 8
Joined: Sun Oct 10, 2010 7:25 pm

Re: RPG collision detection!

Post by smiller »

that introduces a problem though because the values of the tiles are not directly linked to map_x and map_Y, so it just gives me nil. :/
User avatar
walesmd
Prole
Posts: 22
Joined: Fri Oct 08, 2010 3:11 am
Location: Augusta, GA
Contact:

Re: RPG collision detection!

Post by walesmd »

Ah, so map_x and map_y are actually holding the grid coordinates as defined by LOVE (rather than the indexes for the map variable) - I'd imagine some division by 64 (or whatever your tile size is) could correct this easily enough.
smiller
Prole
Posts: 8
Joined: Sun Oct 10, 2010 7:25 pm

Re: RPG collision detection!

Post by smiller »

Still having a little difficulty translating from english to code.
tilerowcheck = #map[offset_x/64]
tilecheck = (what tile are we on that row?) offset_y/64 = the left-right position, return the column number.
tileid= tilerowcheck value and tilecheck value, return id of the tile.
I'm looking at various ways to do this, but at the moment, I'm struggling on "computer thinking"...
User avatar
arquivista
No longer with us
Posts: 266
Joined: Tue Jul 06, 2010 8:39 am
Location: Insert Geolocation tag here
Contact:

Re: RPG collision detection!

Post by arquivista »

Hi smiller you could perhaps take some ideas from my abandoned roguelike engine including the way i do collision detection
http://love2d.org/forums/viewtopic.php?f=5&t=1942

walesmd way will do the work for now but you will notice that you will need later a better way when you have a lot of tiles (grass, flowers, sand, etc) that you can walk on. Better way to do collision detection in roguelike fashion that it's to give to each tile a flag to turn it "walkable" or not and do a routine check if the place where you go can be stepped or not.
--------------------------------------------------------
To Do: Insert Signature Here
--------------------------------------------------------
Post Reply

Who is online

Users browsing this forum: Google [Bot] and 67 guests