Page 1 of 3

Those physics

Posted: Wed Aug 11, 2010 6:08 pm
by Mizore
Hello, i have been messing with this awesome system. Apparently for some reason i cant get physics work properly.

Code: Select all

tile = {}
tile_s = 24

map=
{
{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,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,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,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,8,5,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,6,3,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,6,3,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,6,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,1,1,1,1,1,1,1,1,1,5,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,6,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,7,2,2,2,2,2,2,2,2,2,3,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,6,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,7,2,2,2,2,2,2,2,2,2,2,3,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,6,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,7,2,2,2,2,2,2,2,2,2,2,2,3,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,1,1,1,1,5,0,0,0,0,0,0,6,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,7,2,2,2,2,2,2,2,2,2,2,2,2,3,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},
{2,2,2,2,2,3,0,0,0,0,0,0,6,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,7,2,2,2,2,2,2,2,2,2,2,2,2,2,3,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,8,1,1,1,1,1,1,1},
{2,2,2,2,2,3,0,0,0,0,0,0,6,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,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,8,1,1,7,2,2,2,2,2,2,2},
{2,2,2,2,2,3,0,0,0,0,0,0,6,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,7,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,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,8,1,1,7,2,2,2,2,2,2,2,2,2,2},
{2,2,2,2,2,3,0,0,0,0,0,0,6,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,7,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,0,0,0,0,0,0,8,5,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,8,1,1,7,2,2,2,2,2,2,2,2,2,2,2,2,2},
{2,2,2,2,2,3,0,0,0,0,0,0,6,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,7,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,0,0,0,0,0,8,7,4,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,1,1,7,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2},
{2,2,2,2,2,4,1,1,1,1,1,1,7,3,0,0,0,0,0,0,0,0,0,0,0,0,0,8,7,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,1,1,1,1,1,7,2,2,4,1,1,1,1,1,1,5,0,0,0,0,0,0,0,0,0,0,0,0,8,1,1,1,7,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2},
{2,2,2,2,2,2,2,2,2,2,2,2,2,3,0,0,0,0,0,0,0,0,0,0,0,0,8,7,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,0,0,0,0,0,0,0,0,0,0,8,1,7,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2},
{2,2,2,2,2,2,2,2,2,2,2,2,2,3,0,0,0,0,0,0,0,0,0,0,0,8,7,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,0,0,0,0,0,0,0,0,0,8,7,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2},
{2,2,2,2,2,2,2,2,2,2,2,2,2,3,0,0,0,0,0,0,0,0,0,0,8,7,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,0,0,0,0,0,0,0,0,8,7,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2},
{2,2,2,2,2,2,2,2,2,2,2,2,2,4,1,1,1,1,1,1,1,1,1,1,7,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,1,1,1,1,1,1,1,1,7,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2},
{2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2},
{2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2},
{2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}
}

tile[0] = love.graphics.newImage("images/map/tileEmpty.png")
tile[1] = love.graphics.newImage("images/map/tileGrass1.png")
tile[2] = love.graphics.newImage("images/map/tileDirt1.png")
tile[3] = love.graphics.newImage("images/map/tileDirtEdge1.png")
tile[4] = love.graphics.newImage("images/map/tileGrassDirtEdge1.png")
tile[5] = love.graphics.newImage("images/map/tileGrassEdge1.png")
tile[6] = love.graphics.newImage("images/map/tileDirtEdge2.png")
tile[7] = love.graphics.newImage("images/map/tileGrassDirtEdge2.png")
tile[8] = love.graphics.newImage("images/map/tileGrassEdge2.png")

boxes = {}
boxes[0] = love.graphics.newImage("images/other/box.png")
boxes[1] = love.graphics.newImage("images/other/collisionbox.png")

font['menu'] = love.graphics.newFont(24)
font['small'] = love.graphics.newFont(10)

love.graphics.setFont(font['small'])

map_offset_x = 0
map_offset_y = 0
mapScrollSpeed = 500

world = love.physics.newWorld(2400, 600)
world:setGravity(0, 100)
world:setMeter(64)

bodies = {}
shapes = {}

mapbodies = {}
mapshapes = {}

n = 0

for y, yl in pairs(map) do
	for x, xl in pairs(map[1]) do
		if map[y][x] == 0 then
			
		else
			mapbodies[n] = love.physics.newBody(world, ((x - 1) * tile_s) + map_offset_x, ((y - 1) * tile_s) + map_offset_y, 0, 0)
			mapshapes[n] = love.physics.newRectangleShape(mapbodies[n], 0, 0, 24, 24)
			n = n + 1
		end
	end
end

for i = 0, 10 do
	bodies[i] = love.physics.newBody(world, 650/2+i*30, 50, 15, 1) --place the body in the center of the world, with a mass of 15
	shapes[i] = love.physics.newRectangleShape(bodies[i], 0, 0, 24, 24)
end

function love.draw()
	for i = 0, 10 do
		love.graphics.draw(boxes[0], bodies[i]:getX() + map_offset_x, bodies[i]:getY() + map_offset_y, bodies[i]:getAngle())
	end
	
	generateMap()
	
	
	n = 0
	for i, l in pairs(mapbodies) do
		love.graphics.draw(
			boxes[1],
			mapbodies[i]:getX() + map_offset_x,
			mapbodies[i]:getY() + map_offset_y,
			mapbodies[i]:getAngle()
		)
		n = n + 1
	end
end

function love.keypressed(key)
	if key == "escape" then
		love.filesystem.load("main.lua")()
		love.load()
	end
end

function love.update(dt)
	world:update(dt)
	if love.keyboard.isDown("left") then
		map_offset_x = map_offset_x + mapScrollSpeed * dt
	end
	if love.keyboard.isDown("right") then
		map_offset_x = map_offset_x - mapScrollSpeed * dt
	end
	
	if love.keyboard.isDown("d") then --press the right arrow key to push the ball to the right
		bodies[1]:applyForce(400, 0)
	elseif love.keyboard.isDown("a") then --press the left arrow key to push the ball to the left
		bodies[1]:applyForce(-400, 0)
	elseif love.keyboard.isDown("w") then --press the up arrow key to set the ball in the air
		bodies[1]:applyForce(0, -400)
	end
end

function generateMap()
	for y, yl in pairs(map) do
		for x, xl in pairs(map[1]) do
			love.graphics.draw(tile[map[y][x]], ((x - 1) * tile_s)+  map_offset_x, ((y - 1) * tile_s) + map_offset_y)
		end
	end
end
And i have video to show where is problem. (the red boxes are map collision boxes)

(Video may still be processing.)

Thank you.

Re: Those physics

Posted: Wed Aug 11, 2010 6:21 pm
by Robin
Thing is, you combine two things here that aren't meant to co-exist: tiles and physics. First you need to decide whether you need tiles or physics, then get the other part out. I'd say you need tiles, but I'm not sure.

Re: Those physics

Posted: Wed Aug 11, 2010 6:30 pm
by Mizore
I don't actually understand why they can coexist with each other, map is design is made of tiles, and invisible stationary physics blocks as non collide-able platform.

Re: Those physics

Posted: Wed Aug 11, 2010 6:37 pm
by Jasoco
Yeah. I hate to say it... again... but 2d side-scrollers and Physics just don't work together. You need to make your own engine and "physics" like Nintendo does and Pixel (Who made Cave Story) and other companies, Sega, everyone. Everyone has a side-scrolling engine. It's not impossible to make. Just hard to perfect.

I tried a few times and failed myself. But one day I will get one.

Edit: One day SOMEONE here will make a working side-scroller engine framework and offer it as an example to Löve users so we can stop getting these same questions every week.

Re: Those physics

Posted: Wed Aug 11, 2010 6:43 pm
by Regret
The problem is with assuming that :getX() returns a value that you can directly use to draw rectangles.

:getX() returns the exact middle of a physics object, so to properly draw a rectangle you need to substract it's width / height to get the top left corner.

Furthermore, to properly draw a rotating rectangle you have to use something like this:

Code: Select all

local ax,ay =  boxshape:getPoints()  --actually returns the coordinates that make up the polygonal shape (for rectangle its 8 variables)
love.graphics.draw(boximage,ax + offsetx,ay + offsety,boxbody:getAngle())

Re: Those physics

Posted: Wed Aug 11, 2010 6:54 pm
by Mizore
Regret wrote:The problem is with assuming that :getX() returns a value that you can directly use to draw rectangles.

:getX() returns the exact middle of a physics object, so to properly draw a rectangle you need to substract it's width / height to get the top left corner.

Furthermore, to properly draw a rotating rectangle you have to use something like this:

Code: Select all

local ax,ay =  boxshape:getPoints()  --actually returns the coordinates that make up the polygonal shape (for rectangle its 8 variables)
love.graphics.draw(boximage,ax + offsetx,ay + offsety,boxbody:getAngle())
Thanks. Fixed few issues. Collisions work perfectly without rotation, if rotation is enabled... it f*s up.

Re: Those physics

Posted: Wed Aug 11, 2010 6:58 pm
by Robin
Still, you need to roll your own physics.

love.physics is very capable, but using it here is using a hammer to drive screws in the wall.

Re: Those physics

Posted: Wed Aug 11, 2010 7:40 pm
by Mizore
And, now i wonder how to make my own physics...

Re: Those physics

Posted: Wed Aug 11, 2010 8:16 pm
by Regret
Mizore wrote:Collisions work perfectly without rotation, if rotation is enabled... it f*s up.
Again as I said the problem is in drawing. Collisions work fine, you are drawing your world wrong.

Re: Those physics

Posted: Wed Aug 11, 2010 8:27 pm
by bartbes
Instead of correcting the x and y values, use the offsets to set the origin to center (ox and oy). (it'll fix rotation)