The title may be worded improperly, I dunno. Here's the problem I'm having:
A day or two ago, I began work on a very simple physics engine. It lacks collision, but it contains the physics needed to operate that(ground collision is operated by a variable 'groundLevel').
Then, I have a Tiled map being drawn on the screen using STI. Of course, STI supports world collision for the map.
Since my player object doesn't function using love.physics at ALL, I'm wondering if it's possible to collide with the world without re-writing the entire player object with that in mind, or, if this is unfunctional, another method of detecting collision within this Tiled map.
As of the build attached to this post, the player object will collide with a single flat ground area, which, as previously stated, is determined by a variable 'groundLevel'. Q and E are work-in-progress attacks, complete with ending lag, while WASD and spacebar handle movement. I'm not asking for anyone to recode this for me, I simply need to know how to detect a collision within the world defined by STI without altering the entirety of the movement code to operate using love.physics, if possible.
Thanks in advance!
probably didn't write any of this in a coherent manner, but I digress
Checking World Collision Without Physics
Forum rules
Before you make a thread asking for help, read this.
Before you make a thread asking for help, read this.
Checking World Collision Without Physics
- Attachments
-
- WIP.love
- (59.43 KiB) Downloaded 203 times
Re: Checking World Collision Without Physics
Not only is not using love.physics not a hack, it probably is recommended even. You will need to go through all tiles near the player and check for collisions manually, or use a library like kikitos bump.lua.
If you go the latter route, you will need to extract the tile rectangles, it would be recommended that you also merge adjacent tiles to create larger rectangles (1 long rect instead of 20 small squares for a wall).
You can also (and this is way easier and more flexible IMO) add an object layer in Tiled and fill it with collision rectangles (then you don't need to merge and can do some trickier collision cases, like a no-collision secret wall) loop through it's contents in STI and add those to your collision engine of choice.
If you want me to I can post my standard platformer STI/bump collision code.
If you go the latter route, you will need to extract the tile rectangles, it would be recommended that you also merge adjacent tiles to create larger rectangles (1 long rect instead of 20 small squares for a wall).
You can also (and this is way easier and more flexible IMO) add an object layer in Tiled and fill it with collision rectangles (then you don't need to merge and can do some trickier collision cases, like a no-collision secret wall) loop through it's contents in STI and add those to your collision engine of choice.
If you want me to I can post my standard platformer STI/bump collision code.
Re: Checking World Collision Without Physics
Hey Quisciens,
bump.lua is a simple collision system using the idea of basic bounding boxes. As it's been said, you can dedicate a Tiled layer to collisions (either with some sort of overlay collision squares or just draw all colliding objects like the ground and walls in their own layer).
So you start bump with:
You can throw a number in bump.newWorld to change the detection grid size from 32. This is not your tile size, but how bump cuts up the location into smaller chunks for detection, from what I understand. You can see this in the demos if you hit the button for the debug mode.
Anyway, you add your player and all the tiles you want to worry about to the world.
l and t are x and y, but to the top left corner of the object. It's just like drawing a rectangle around the object.
Then, with the player, you'll just have to adjust how you handle movement, making use of either the world:move or maybe the combination of world:check and world:update functions. Basically, you send it the player (so bump knows what to check) and where the player wants to go. world:move will automatically adjust the player's positions in the bump world (not allowing it to pass through the colliding objects, stopping at them) and return to you the right positions for the player for you to use.
world:check and world:update work such that you can check where the player would be without actually moving them. So getting the returned parts from world:move without messing with the player in the bump world. But then, you can use world:update to make those adjustments. It gives you more control on when updates to bump happen.
So the basic implementation of it won't require a whole lot of changes. There's a lot of good info on bump.lua's Github page.
bump.lua is a simple collision system using the idea of basic bounding boxes. As it's been said, you can dedicate a Tiled layer to collisions (either with some sort of overlay collision squares or just draw all colliding objects like the ground and walls in their own layer).
So you start bump with:
Code: Select all
bump = require "bump"
world = bump.newWorld()
Anyway, you add your player and all the tiles you want to worry about to the world.
Code: Select all
world:add(item, item.l, item.t, item.width, item.height)
Then, with the player, you'll just have to adjust how you handle movement, making use of either the world:move or maybe the combination of world:check and world:update functions. Basically, you send it the player (so bump knows what to check) and where the player wants to go. world:move will automatically adjust the player's positions in the bump world (not allowing it to pass through the colliding objects, stopping at them) and return to you the right positions for the player for you to use.
world:check and world:update work such that you can check where the player would be without actually moving them. So getting the returned parts from world:move without messing with the player in the bump world. But then, you can use world:update to make those adjustments. It gives you more control on when updates to bump happen.
So the basic implementation of it won't require a whole lot of changes. There's a lot of good info on bump.lua's Github page.
Re: Checking World Collision Without Physics
I'm not sure about implementing either of those, primarily due to this: I want to know how to access the Tiled collision data, as generated by STI, without using love.physics, and it's worth noting that STI creates a love.physics world using the Tiled layout. Bump.lua appears as if it would conflict with that. The collision layer seems like it would work out well, if I could figure this out:
Essentially, I need to check the position of Box2D objects from my player.lua without implementing Box2D, because STI creates a Box2D world. Using this, I'd check the position of the world's tiles and collide accordingly.
Essentially, I need to check the position of Box2D objects from my player.lua without implementing Box2D, because STI creates a Box2D world. Using this, I'd check the position of the world's tiles and collide accordingly.
Re: Checking World Collision Without Physics
Simple: There is no such thing as collision data.Quisciens wrote:I'm not sure about implementing either of those, primarily due to this: I want to know how to access the Tiled collision data, as generated by STI, without using love.physics, and it's worth noting that STI creates a love.physics world using the Tiled layout. Bump.lua appears as if it would conflict with that. The collision layer seems like it would work out well, if I could figure this out:
Essentially, I need to check the position of Box2D objects from my player.lua without implementing Box2D, because STI creates a Box2D world. Using this, I'd check the position of the world's tiles and collide accordingly.
You have to interprete that on your own; take all tiles set in a layer; rectangles on an object layer or anything you can think of.
Also how would bump.lua conflict with anything? The "collision layer" method does not at all exclude bump.lua, I would even recommend using bump.lua to power your collision layer. bump.lua is very performant and feature rich and does exactly what you would need to do on your own (and no more; except probably better).
Re: Checking World Collision Without Physics
Hey Quisciens,
Let's look at the STI demo code (main.lua):
Here's an example of STI with bump.lua, being part of someone's project: viewtopic.php?f=3&t=78847&start=10#p174480
The code's a little messy, having other stuff going on, but take a look (game.lua):
It doesn't seem to be a matter of love.physics being automatically part of STI as much as STI simply allowing you to grab what you want and feed it to whatever "world" you want (be it love.physics, bump.lua, or otherwise). Using the Box2D stuff is just possible, not built in. There is no conflict.
Let's look at the STI demo code (main.lua):
Code: Select all
-- Load map
map = sti.new("map")
-- Prepare physics world
world = love.physics.newWorld(0, 0)
-- Prepare collision objects
collision = map:initWorldCollision(world)
-- Add a Custom Layer
map:addCustomLayer("Sprite Layer", 3)
local spriteLayer = map.layers["Sprite Layer"]
-- Add Custom Data
spriteLayer.sprite = {
image = love.graphics.newImage("kim.png"),
x = 1000,
y = 800,
r = 0,
}
spriteLayer.sprite.body = love.physics.newBody(world, spriteLayer.sprite.x/2, spriteLayer.sprite.y/2, "dynamic")
spriteLayer.sprite.shape = love.physics.newRectangleShape(50, 50)
spriteLayer.sprite.fixture = love.physics.newFixture(spriteLayer.sprite.body, spriteLayer.sprite.shape)
The code's a little messy, having other stuff going on, but take a look (game.lua):
Code: Select all
local sti = require "sti"
local gr = love.graphics
bump = require "bump"
world = bump.newWorld(50)
bump_debug = require 'bump_debug'
function gameload()
map = sti.new("maps/map_1")
playerload()
enemiesLayer = map.layers["enemies"]
camera:setBounds(0, 0, map.width * map.tilewidth - love.graphics.getWidth(), map.height * map.tileheight - love.graphics.getHeight() )
--creating solid block info
local mapfunction = love.filesystem.load("maps/map_1.lua")
local mapdatatable = mapfunction()
maptilesetdata = {}
for x = 1, mapdatatable.layers[1].width do
maptilesetdata[x] = {}
for y = 1, mapdatatable.layers[1].height do
maptilesetdata[x][y] = mapdatatable.layers[1].data[(y-1)*mapdatatable.layers[1].width+x]
if maptilesetdata[x][y] ~= 0 then
block_create((x-1)*32, (y-1)*32)
end
end
end
--create Collision Blocks from tiled solid blocks
for i,v in pairs(blocks) do
world:add(blocks[i], v.x,v.y,v.w,v.h)
end
for i,v in ipairs(enemiesLayer.objects) do
if v.properties.enemy then
enemy_create(v.x, v.y, v.width, v.height)
world:add(enemies[i], v.x,v.y,v.width,v.height)
end
end
end
Re: Checking World Collision Without Physics
here's bump.lua and STI with object layers:
Code: Select all
world = bump.newWorld()
map = Map.threeplat -- "macro" to load map
local col, ent, cnt = map.layers.collision, map.layers.entities, 1
assert( col, "no collision layer in map" )
assert( col.type == "objectgroup", "no collision layer in map" )
for _,r in ipairs(col.objects) do
world:add( {type = (r.type ~= "" and r.type or T_WRLD), id=cnt}, r.x, r.y, r.width, r.height )
cnt = cnt+1
end
assert( ent, "no entity layer in map" )
assert( ent.type == "objectgroup", "no entity layer in map" )
for _,r in ipairs(ent.objects) do
if r.type == "player" then
if options.playerinfo[r.name] then -- don't spawn more players than we want to
local p = Player.new( r.name, options.playerinfo[r.name], r.x, r.y )
p.spawnweapon = require("weapons."..options.spawn[1])( p, options.spawn[2] )
p.weapon = p.spawnweapon
players[r.name] = p
end
elseif r.type == "crate" then
cratespawn = { r.x, r.y, r.width, r.height }
end
end
col.visible = false
ent.visible = false
Who is online
Users browsing this forum: No registered users and 5 guests