Box2d based player movement

Show off your games, demos and other (playable) creations.
Post Reply
monolifed
Party member
Posts: 172
Joined: Sat Feb 06, 2016 9:42 pm

Box2d based player movement

Post by monolifed »

Simple player movement with box2d. It is a little wrong but I hope it helps someone.

Code: Select all

local platforms = {}
local function create_platform(world, x, y, w, h, name, fric)
	name = name or ("platform_%i"):format(#platforms + 1)
	fric = fric or 0.3
	local pl = {}
	pl.body = love.physics.newBody(world, 0, 0, "static")
	pl.shape = love.physics.newRectangleShape(x, y, w, h)
	pl.fixture = love.physics.newFixture(pl.body, pl.shape)
	pl.fixture:setUserData(name)
	pl.fixture:setFriction(fric)
	table.insert(platforms, pl)
	return pl
end

local tilew = 16
local gravity = 9.81

function love.load()
	love.graphics.setFont(love.graphics.newFont(12))
	love.physics.setMeter(tilew)

	world = love.physics.newWorld(0, gravity * tilew, true)

	create_platform(world, 400, 580, 780,  20, "ground", 0.3)
	create_platform(world,  10, 300,  20, 530, "leftwall", 0.3)
	create_platform(world,  90, 300,  20, 490, "anotherwall", 0.3)

	create_platform(world,  400, 546,  16, 48, "height", 0.3)



	player_body = love.physics.newBody(world, 400, 400, "dynamic")
	player_shape = love.physics.newRectangleShape(0, 0, 16, 16)
	player_fixture = love.physics.newFixture( player_body, player_shape)
	player_fixture:setUserData("Player")
	player_body:setMassData(player_shape:computeMass(1))
	player_body:setFixedRotation(true)

	world:setCallbacks(beginContact,endContact)
end

local keyU,keyL,keyR = false, false, false
local jumpnow = false
local onground, onwall = false, false

function love.update(dt)
	world:update(dt)
	
	local vx, vy = player_body:getLinearVelocity( )
	
	if onground then
		if not keyU then
			if keyL == keyR then
				player_body:setLinearVelocity(0.9*vx, vy)
			elseif keyL then
				player_body:setLinearVelocity(-100, vy)
			else --elseif keyR then
				player_body:setLinearVelocity(100, vy)
			end
		else
			player_body:applyLinearImpulse(0, -64)
		end
	else
		if keyU then
			if onwall and jumpnow and vy < 10 then
				player_body:applyLinearImpulse(onwall * 64, -125)
			end
		end
		
		if keyL == keyR then
			--??
		elseif keyL then
			if onwall == 1 then player_body:applyForce(-400,0)
			elseif vx < -75 then player_body:setLinearVelocity(-75, vy)
			else player_body:applyForce(-75,0) end
		else --elseif keyR then
			if onwall == -1 then player_body:applyForce(400,0)
			elseif vx > 75 then player_body:setLinearVelocity(75, vy)
			else player_body:applyForce(75,0) end
		end
	end
	
	jumpnow = false
end

function love.draw()
	for i, v in ipairs(platforms) do
		love.graphics.polygon("line", v.shape:getPoints())
	end
	love.graphics.rectangle("line", player_body:getX() - 8, player_body:getY() - 8, 16, 16)
end

function love.keypressed(k)
	if k == "space" then
		keyU = true
		jumpnow = true -- not repeat
	end
	if k == "a" then keyL = true end
	if k == "d" then keyR = true end
end

function love.keyreleased(k)
	if k == "space" then keyU = false end
	if k == "a" then keyL = false end
	if k == "d" then keyR = false end
	
	if k == "r" then
		player_body:setLinearVelocity(0,0)
		player_body:setPosition(400, 400)
	end
end

local function onPlayerContact()
	onground = false
	onwall = false
	
	for k, v in ipairs(player_body:getContacts()) do
		if v:isTouching() then
			local x, y = v:getNormal()
			if x == 0 and y < 0 then onground = v end
			if y == 0 then onwall = x end
		end
	end
	if onground then onwall = false end
end

function beginContact(a, b, c)
	if a == player_fixture or b == player_fixture then
		onPlayerContact()
	end
end

function endContact(a, b, c)
	if a == player_fixture or b == player_fixture then
		onPlayerContact()
	end
end
Attachments
main.lua
(3.39 KiB) Downloaded 159 times
Post Reply

Who is online

Users browsing this forum: darkfrei, Google [Bot], Gunroar:Cannon() and 11 guests