Collisions not working correctly

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
User avatar
melexm
Prole
Posts: 8
Joined: Sat Dec 22, 2012 8:01 pm

Collisions not working correctly

Post by melexm »

Hello guys,
I am trying to create a simple "Pong" Game but I probably made a mistake in the way.
The ball passes through the player and computer bars and has some strange collusion with the wall where it will "stick" to it.

Here is the source code:

Code: Select all

local sw = 600
local sh = 600
local startPush = true

local comp_score = 0
local human_score = 0

local wallL_p = {
	x = 100,
	y = 0,
	w = 10,
	h = sh,
	pp = 20
}
local wallR_p = {
	x = 500,
	y = 0,
	w = 10,
	h = sh
}

local player_p = {
	x = wallL_p.x + wallL_p.pp,
	y = sh - 40,
	w = 75,
	h = 19
}

local computer_p = {
	x = wallL_p.x + wallL_p.pp,
	y = 20,
	w = 70,
	h = 19,
	rs = 2
}

local ball_p ={
	xs = sw / 2,
	ys = sh / 2,
	radius = 10,
	impC = 1/3
}

function love.load()
	--World
	--love.physics.setMeter(64)
	world = love.physics.newWorld( 0, 0, true)

	--Left wall
	wallL = {}
	wallL.b = love.physics.newBody(world, wallL_p.x, wallL_p.y, "static")
	wallL.s = love.physics.newRectangleShape( wallL_p.w, wallL_p.h*3)
	wallL.f = love.physics.newFixture(wallL.b, wallL.s, 1 )

	---Right wall
	wallR = {}
	wallR.b = love.physics.newBody(world, wallR_p.x, wallR_p.y, "static")
	wallR.s = love.physics.newRectangleShape( wallR_p.w, wallR_p.h*3)
	wallR.f = love.physics.newFixture(wallR.b, wallR.s, 1 )

	--Player
	player = {}
	player.b = love.physics.newBody(world, player_p.x, player_p.y, "dynamic")
	player.s = love.physics.newRectangleShape( player_p.w, player_p.h)
	player.f = love.physics.newFixture(wallL.b, wallL.s, 1 )

	--Computer
	computer = {}
	computer.b = love.physics.newBody(world, computer_p.x, computer_p.y, "dynamic")
	computer.s = love.physics.newRectangleShape( computer_p.w, computer_p.h)
	computer.f = love.physics.newFixture(wallL.b, wallL.s, 1 )

	--Ball
	ball = {}
	ball.b = love.physics.newBody(world, ball_p.xs, ball_p.ys, "dynamic")
	ball.s = love.physics.newCircleShape(ball_p.radius)
	ball.f = love.physics.newFixture(ball.b, ball.s, 1 )
	ball.b:setMass(0.1)
	ball.f:setRestitution(1.1)
end

function love.update(dt)
	world:update(dt)
	if startPush == true then
		ball.b:applyLinearImpulse(  randomMinus()*math.random()*ball_p.xs*ball_p.impC  , randomMinus()*math.random()*ball_p.ys*ball_p.impC )
		startPush = false
	end
	computer.b:setX(ball.b:getX())
	player.b:setX(love.mouse.getX())
	xb,yb = ball.b:getLinearVelocity()
	if yb < 1 then
		ball.b:setLinearVelocity( 0, 100 )
	end
	if ball.b:getY()<10 or ball.b:getY()> sh-10 then
		ball.b:setLinearVelocity( 0, 0 )
		ball.b:setY(ball_p.ys)
		startPush = true;
	end
end

function love.draw()
	--Draw score
	love.graphics.setColor(0, 255, 0, 255)
    love.graphics.print("Human:"..human_score, 10, 40)
    love.graphics.print("Computer"..comp_score, 10, 60)

    --Draw walls
    love.graphics.setColor(27, 126, 224, 255)
    love.graphics.rectangle( "fill", wallL_p.x, wallL_p.y, wallL_p.w, wallL_p.h )
    love.graphics.rectangle( "fill", wallR_p.x, wallR_p.y, wallR_p.w, wallR_p.h )

    --Draw player
    love.graphics.setColor(27, 224, 57, 255)
    love.graphics.rectangle( "fill", player.b:getX(), player_p.y, player_p.w, player_p.h )

    --Draw computer
    love.graphics.setColor(217, 217, 210, 255)
    love.graphics.rectangle( "fill", computer.b:getX(), computer_p.y, computer_p.w, computer_p.h )

    --Draw ball
    love.graphics.setColor(235, 26, 36, 255)
    love.graphics.circle("fill", ball.b:getX(), ball.b:getY(), ball_p.radius)
end


function randomMinus()
	if math.random() >= 0.5 then
		return -1
	else
		return 1
	end
end
I'd really appreciate the help,
Thanks in advance.
Attachments
Pong.love
The game in a .love extension
(1.34 KiB) Downloaded 107 times
User avatar
jpnk
Prole
Posts: 8
Joined: Mon Dec 24, 2012 2:12 pm

Re: Collisions not working correctly

Post by jpnk »

you made a few typos when creating fixures. you also made the player and computer dynamic bodies - you don't want them to be pushed by the ball so they need to be static. i've corrected those issues but it still doens't work well. i've changed love.draw() to any make sure all the shapes are displayed at their actual locations. i don't have any more time to play with the code today so there you go.

p.s. try not to use body:setX/setY/setPosition/setAngle - apply forces and impulses. you could also try to use a mouse joint to move the player and the computer (i haven't tried that myself yet).

Code: Select all

local sw = 600
local sh = 600
local startPush = true

local comp_score = 0
local human_score = 0

local wallL_p = {
	x = 100,
	y = 0,
	w = 10,
	h = sh,
	pp = 20
}
local wallR_p = {
	x = 500,
	y = 0,
	w = 10,
	h = sh
}

local player_p = {
	x = wallL_p.x + wallL_p.pp,
	y = sh - 40,
	w = 75,
	h = 19
}

local computer_p = {
	x = wallL_p.x + wallL_p.pp,
	y = 20,
	w = 70,
	h = 19,
	rs = 2
}

local ball_p ={
	xs = sw / 2,
	ys = sh / 2,
	radius = 10,
	impC = 1/3
}

function love.load()
	--World
	--love.physics.setMeter(64)
	world = love.physics.newWorld( 0, 0, true)

	--Left wall
	wallL = {}
	wallL.b = love.physics.newBody(world, wallL_p.x, wallL_p.y, "static")
	wallL.s = love.physics.newRectangleShape( wallL_p.w, wallL_p.h*3)
	wallL.f = love.physics.newFixture(wallL.b, wallL.s, 1 )

	---Right wall
	wallR = {}
	wallR.b = love.physics.newBody(world, wallR_p.x, wallR_p.y, "static")
	wallR.s = love.physics.newRectangleShape( wallR_p.w, wallR_p.h*3)
	wallR.f = love.physics.newFixture(wallR.b, wallR.s, 1 )

	--Player
	player = {}
	player.b = love.physics.newBody(world, player_p.x, player_p.y, "static")
	player.s = love.physics.newRectangleShape( player_p.w, player_p.h)
	player.f = love.physics.newFixture(player.b, player.s, 1 )

	--Computer
	computer = {}
	computer.b = love.physics.newBody(world, computer_p.x, computer_p.y, "static")
	computer.s = love.physics.newRectangleShape( computer_p.w, computer_p.h)
	computer.f = love.physics.newFixture(computer.b, computer.s, 1 )

	--Ball
	ball = {}
	ball.b = love.physics.newBody(world, ball_p.xs, ball_p.ys, "dynamic")
	ball.s = love.physics.newCircleShape(ball_p.radius)
	ball.f = love.physics.newFixture(ball.b, ball.s, 1 )
	ball.b:setMass(0.1)
	ball.f:setRestitution(1.1)
end

function love.update(dt)
	world:update(dt)
	if startPush == true then
		ball.b:applyLinearImpulse(  randomMinus()*math.random()*ball_p.xs*ball_p.impC  , randomMinus()*math.random()*ball_p.ys*ball_p.impC )
		startPush = false
	end
	computer.b:setX(ball.b:getX())
	player.b:setX(love.mouse.getX())
	xb,yb = ball.b:getLinearVelocity()
	--[[if yb < 1 then
		ball.b:setLinearVelocity( 0, 100 )
	end]]
	if ball.b:getY()<10 or ball.b:getY()> sh-10 then
		ball.b:setLinearVelocity( 0, 0 )
		ball.b:setY(ball_p.ys)
		startPush = true;
	end
end

function love.draw()
	--Draw score
	love.graphics.setColor(0, 255, 0, 255)
    love.graphics.print("Human:"..human_score, 10, 40)
    love.graphics.print("Computer"..comp_score, 10, 60)

    --Draw walls
    love.graphics.setColor(27, 126, 224, 255)
    --love.graphics.rectangle( "fill", wallL_p.x, wallL_p.y, wallL_p.w, wallL_p.h )
    love.graphics.polygon( "fill", wallL.b:getWorldPoints(wallL.s:getPoints()))
    --love.graphics.rectangle( "fill", wallR_p.x, wallR_p.y, wallR_p.w, wallR_p.h )
    love.graphics.polygon( "fill", wallR.b:getWorldPoints(wallR.s:getPoints()))

    --Draw player
    love.graphics.setColor(27, 224, 57, 255)
    --love.graphics.rectangle( "fill", player.b:getX(), player_p.y, player_p.w, player_p.h )
    love.graphics.polygon( "fill", player.b:getWorldPoints(player.s:getPoints()))

    --Draw computer
    love.graphics.setColor(217, 217, 210, 255)
    --love.graphics.rectangle( "fill", computer.b:getX(), computer_p.y, computer_p.w, computer_p.h )
    love.graphics.polygon( "fill", computer.b:getWorldPoints(computer.s:getPoints()))

    --Draw ball
    love.graphics.setColor(235, 26, 36, 255)
    love.graphics.circle("fill", ball.b:getX(), ball.b:getY(), ball_p.radius)
end


function randomMinus()
	if math.random() >= 0.5 then
		return -1
	else
		return 1
	end
end
User avatar
melexm
Prole
Posts: 8
Joined: Sat Dec 22, 2012 8:01 pm

Re: Collisions not working correctly

Post by melexm »

jpnk wrote:you made a few typos when creating fixures. you also made the player and computer dynamic bodies - you don't want them to be pushed by the ball so they need to be static. i've corrected those issues but it still doens't work well. i've changed love.draw() to any make sure all the shapes are displayed at their actual locations. i don't have any more time to play with the code today so there you go.

p.s. try not to use body:setX/setY/setPosition/setAngle - apply forces and impulses. you could also try to use a mouse joint to move the player and the computer (i haven't tried that myself yet).

Code: Select all

local sw = 600
local sh = 600
local startPush = true

local comp_score = 0
local human_score = 0

local wallL_p = {
	x = 100,
	y = 0,
	w = 10,
	h = sh,
	pp = 20
}
local wallR_p = {
	x = 500,
	y = 0,
	w = 10,
	h = sh
}

local player_p = {
	x = wallL_p.x + wallL_p.pp,
	y = sh - 40,
	w = 75,
	h = 19
}

local computer_p = {
	x = wallL_p.x + wallL_p.pp,
	y = 20,
	w = 70,
	h = 19,
	rs = 2
}

local ball_p ={
	xs = sw / 2,
	ys = sh / 2,
	radius = 10,
	impC = 1/3
}

function love.load()
	--World
	--love.physics.setMeter(64)
	world = love.physics.newWorld( 0, 0, true)

	--Left wall
	wallL = {}
	wallL.b = love.physics.newBody(world, wallL_p.x, wallL_p.y, "static")
	wallL.s = love.physics.newRectangleShape( wallL_p.w, wallL_p.h*3)
	wallL.f = love.physics.newFixture(wallL.b, wallL.s, 1 )

	---Right wall
	wallR = {}
	wallR.b = love.physics.newBody(world, wallR_p.x, wallR_p.y, "static")
	wallR.s = love.physics.newRectangleShape( wallR_p.w, wallR_p.h*3)
	wallR.f = love.physics.newFixture(wallR.b, wallR.s, 1 )

	--Player
	player = {}
	player.b = love.physics.newBody(world, player_p.x, player_p.y, "static")
	player.s = love.physics.newRectangleShape( player_p.w, player_p.h)
	player.f = love.physics.newFixture(player.b, player.s, 1 )

	--Computer
	computer = {}
	computer.b = love.physics.newBody(world, computer_p.x, computer_p.y, "static")
	computer.s = love.physics.newRectangleShape( computer_p.w, computer_p.h)
	computer.f = love.physics.newFixture(computer.b, computer.s, 1 )

	--Ball
	ball = {}
	ball.b = love.physics.newBody(world, ball_p.xs, ball_p.ys, "dynamic")
	ball.s = love.physics.newCircleShape(ball_p.radius)
	ball.f = love.physics.newFixture(ball.b, ball.s, 1 )
	ball.b:setMass(0.1)
	ball.f:setRestitution(1.1)
end

function love.update(dt)
	world:update(dt)
	if startPush == true then
		ball.b:applyLinearImpulse(  randomMinus()*math.random()*ball_p.xs*ball_p.impC  , randomMinus()*math.random()*ball_p.ys*ball_p.impC )
		startPush = false
	end
	computer.b:setX(ball.b:getX())
	player.b:setX(love.mouse.getX())
	xb,yb = ball.b:getLinearVelocity()
	--[[if yb < 1 then
		ball.b:setLinearVelocity( 0, 100 )
	end]]
	if ball.b:getY()<10 or ball.b:getY()> sh-10 then
		ball.b:setLinearVelocity( 0, 0 )
		ball.b:setY(ball_p.ys)
		startPush = true;
	end
end

function love.draw()
	--Draw score
	love.graphics.setColor(0, 255, 0, 255)
    love.graphics.print("Human:"..human_score, 10, 40)
    love.graphics.print("Computer"..comp_score, 10, 60)

    --Draw walls
    love.graphics.setColor(27, 126, 224, 255)
    --love.graphics.rectangle( "fill", wallL_p.x, wallL_p.y, wallL_p.w, wallL_p.h )
    love.graphics.polygon( "fill", wallL.b:getWorldPoints(wallL.s:getPoints()))
    --love.graphics.rectangle( "fill", wallR_p.x, wallR_p.y, wallR_p.w, wallR_p.h )
    love.graphics.polygon( "fill", wallR.b:getWorldPoints(wallR.s:getPoints()))

    --Draw player
    love.graphics.setColor(27, 224, 57, 255)
    --love.graphics.rectangle( "fill", player.b:getX(), player_p.y, player_p.w, player_p.h )
    love.graphics.polygon( "fill", player.b:getWorldPoints(player.s:getPoints()))

    --Draw computer
    love.graphics.setColor(217, 217, 210, 255)
    --love.graphics.rectangle( "fill", computer.b:getX(), computer_p.y, computer_p.w, computer_p.h )
    love.graphics.polygon( "fill", computer.b:getWorldPoints(computer.s:getPoints()))

    --Draw ball
    love.graphics.setColor(235, 26, 36, 255)
    love.graphics.circle("fill", ball.b:getX(), ball.b:getY(), ball_p.radius)
end


function randomMinus()
	if math.random() >= 0.5 then
		return -1
	else
		return 1
	end
end
Thanks so much! Now it atleast works half of the time, the collisions still go nuts sometimes (especially with the wall).
- Why should I use the body:getX... ? (did you mean in the draw functions?)
- How can I stop the player and the computer to not collide with the walls? (isn't the box2d system supposed to "block" then automatically?)
- Do you have any idea of how to fix the wall collisions? (when the ball almost stops, or constantly hits the same horizontal line?)
BTW:
I've added the fixed .love file with some more minor code improvements.
Attachments
Pong.love
(1.6 KiB) Downloaded 102 times
User avatar
jpnk
Prole
Posts: 8
Joined: Mon Dec 24, 2012 2:12 pm

Re: Collisions not working correctly

Post by jpnk »

so the problem was caused by friction. turns out every fixture has non-zero friction upon creation. so i called setFriction(0) on every fixture and the problem disappeared. now the ball is bouncing correctly.
- How can I stop the player and the computer to not collide with the walls? (isn't the box2d system supposed to "block" then automatically?)
when you call setX()/setY()/setPosition() you override whatever new position box2d calculated for your bodies. also the player, the computer, and the walls are static bodies so they just don't move when something collides with them. so in this particular case i think your only option is to manually clamp positions of the paddles to the space between the walls.

if the paddles were dynamic bodies you could apply forces to them (instead of explicitly setting their position) and let box2d process collisions for you. alternatively you could create a mouse joint for each paddle and call setTaget(x, y) on it. i would work almost like invoking setPosition(x, y) directly on each body with the added bonus that collisions are now properly handled by box2d. but you can't make the paddles dynamic because they will get pushed/rotated by the ball.
- Why should I use the body:getX... ? (did you mean in the draw functions?)
i didn't quite get this question.

p.s. i changed a few positions/sizes here and there while trying to tackle the bouncing problem.

Code: Select all

local sw = 600
local sh = 600
local startPush = true

local comp_score = 0
local human_score = 0

local wallL_p = {
   x = 100,
   y = sh / 2,
   w = 10,
   h = sh,
   pp = 20
}
local wallR_p = {
   x = 500,
   y = sh / 2,
   w = 10,
   h = sh
}

local player_p = {
   --x = wallL_p.x + wallL_p.pp,
   x = sw / 2,
   y = sh - 40,
   w = 75,
   h = 19
}

local computer_p = {
   --x = wallL_p.x + wallL_p.pp,
   x = sw / 2,
   y = 20,
   w = 70,
   h = 19,
   rs = 2
}

local ball_p ={
   xs = sw / 2,
   ys = sh / 2,
   radius = 10,
   impC = 1/3
}

function love.load()
   --World
   --love.physics.setMeter(64)
   world = love.physics.newWorld( 0, 0, true)

   --Left wall
   wallL = {}
   wallL.b = love.physics.newBody(world, wallL_p.x, wallL_p.y, "static")
   wallL.s = love.physics.newRectangleShape( wallL_p.w, wallL_p.h)
   wallL.f = love.physics.newFixture(wallL.b, wallL.s, 1 )
   wallL.f:setFriction(0)

   ---Right wall
   wallR = {}
   wallR.b = love.physics.newBody(world, wallR_p.x, wallR_p.y, "static")
   wallR.s = love.physics.newRectangleShape( wallR_p.w, wallR_p.h)
   wallR.f = love.physics.newFixture(wallR.b, wallR.s, 1 )
   wallR.f:setFriction(0)

   --Player
   player = {}
   player.b = love.physics.newBody(world, player_p.x, player_p.y, "static")
   player.s = love.physics.newRectangleShape( player_p.w, player_p.h)
   player.f = love.physics.newFixture(player.b, player.s, 1 )
   player.f:setFriction(0)

   --Computer
   computer = {}
   computer.b = love.physics.newBody(world, computer_p.x, computer_p.y, "static")
   computer.s = love.physics.newRectangleShape( computer_p.w, computer_p.h)
   computer.f = love.physics.newFixture(computer.b, computer.s, 1 )
   computer.f:setFriction(0)

   --Ball
   ball = {}
   ball.b = love.physics.newBody(world, ball_p.xs, ball_p.ys, "dynamic")
   ball.s = love.physics.newCircleShape(ball_p.radius)
   ball.f = love.physics.newFixture(ball.b, ball.s, 1 )
   ball.b:setMass(0.1)
   ball.f:setRestitution(1)
   ball.f:setFriction(0)
end


function love.update(dt)
   world:update(dt)
   if startPush == true then
      ball.b:applyLinearImpulse(  randomMinus()*math.random()*ball_p.xs*ball_p.impC  , randomMinus()*math.random()*ball_p.ys*ball_p.impC )
      startPush = false
   end
   computer.b:setX(ball.b:getX())
   player.b:setX(love.mouse.getX())
   xb,yb = ball.b:getLinearVelocity()
   --[[if yb < 1 then
      ball.b:setLinearVelocity( 0, 100 )
   end]]
   if ball.b:getY()<10 or ball.b:getY()> sh-10 then
      ball.b:setLinearVelocity( 0, 0 )
      ball.b:setY(ball_p.ys)
      startPush = true;
   end

end
function love.keyreleased(key)
   if key == "r" then
   	   ball.b:setY(sh/2)
   	   ball.b:setX(sw/2)
   	   ball.b:setLinearVelocity( 0, 0 )
       ball.b:applyLinearImpulse(  randomMinus()*math.random()*ball_p.xs*ball_p.impC  , randomMinus()*math.random()*ball_p.ys*ball_p.impC )
       startPush = false
   elseif key == "q" then
       love.event.push('quit')
   end
end
function love.draw()
   --Draw score
   love.graphics.setColor(0, 255, 0, 255)
    love.graphics.print("Human:"..human_score, 10, 40)
    love.graphics.print("Computer"..comp_score, 10, 60)

    --Draw walls
    love.graphics.setColor(27, 126, 224, 255)
    --love.graphics.rectangle( "fill", wallL_p.x, wallL_p.y, wallL_p.w, wallL_p.h )
    love.graphics.polygon( "fill", wallL.b:getWorldPoints(wallL.s:getPoints()))
    --love.graphics.rectangle( "fill", wallR_p.x, wallR_p.y, wallR_p.w, wallR_p.h )
    love.graphics.polygon( "fill", wallR.b:getWorldPoints(wallR.s:getPoints()))

    --Draw player
    love.graphics.setColor(27, 224, 57, 255)
    --love.graphics.rectangle( "fill", player.b:getX(), player_p.y, player_p.w, player_p.h )
    love.graphics.polygon( "fill", player.b:getWorldPoints(player.s:getPoints()))

    --Draw computer
    love.graphics.setColor(217, 217, 210, 255)
    --love.graphics.rectangle( "fill", computer.b:getX(), computer_p.y, computer_p.w, computer_p.h )
    love.graphics.polygon( "fill", computer.b:getWorldPoints(computer.s:getPoints()))

    --Draw ball
    love.graphics.setColor(235, 26, 36, 255)
    love.graphics.circle("fill", ball.b:getX(), ball.b:getY(), ball_p.radius)
end


function randomMinus()
   if math.random() >= 0.5 then
      return -1
   else
      return 1
   end
end
User avatar
melexm
Prole
Posts: 8
Joined: Sat Dec 22, 2012 8:01 pm

Re: Collisions not working correctly

Post by melexm »

jpnk wrote:so the problem was caused by friction. turns out every fixture has non-zero friction upon creation. so i called setFriction(0) on every fixture and the problem disappeared. now the ball is bouncing correctly.
- How can I stop the player and the computer to not collide with the walls? (isn't the box2d system supposed to "block" then automatically?)
when you call setX()/setY()/setPosition() you override whatever new position box2d calculated for your bodies. also the player, the computer, and the walls are static bodies so they just don't move when something collides with them. so in this particular case i think your only option is to manually clamp positions of the paddles to the space between the walls.

if the paddles were dynamic bodies you could apply forces to them (instead of explicitly setting their position) and let box2d process collisions for you. alternatively you could create a mouse joint for each paddle and call setTaget(x, y) on it. i would work almost like invoking setPosition(x, y) directly on each body with the added bonus that collisions are now properly handled by box2d. but you can't make the paddles dynamic because they will get pushed/rotated by the ball.
- Why should I use the body:getX... ? (did you mean in the draw functions?)
i didn't quite get this question.

p.s. i changed a few positions/sizes here and there while trying to tackle the bouncing problem.

Code: Select all

local sw = 600
local sh = 600
local startPush = true

local comp_score = 0
local human_score = 0

local wallL_p = {
   x = 100,
   y = sh / 2,
   w = 10,
   h = sh,
   pp = 20
}
local wallR_p = {
   x = 500,
   y = sh / 2,
   w = 10,
   h = sh
}

local player_p = {
   --x = wallL_p.x + wallL_p.pp,
   x = sw / 2,
   y = sh - 40,
   w = 75,
   h = 19
}

local computer_p = {
   --x = wallL_p.x + wallL_p.pp,
   x = sw / 2,
   y = 20,
   w = 70,
   h = 19,
   rs = 2
}

local ball_p ={
   xs = sw / 2,
   ys = sh / 2,
   radius = 10,
   impC = 1/3
}

function love.load()
   --World
   --love.physics.setMeter(64)
   world = love.physics.newWorld( 0, 0, true)

   --Left wall
   wallL = {}
   wallL.b = love.physics.newBody(world, wallL_p.x, wallL_p.y, "static")
   wallL.s = love.physics.newRectangleShape( wallL_p.w, wallL_p.h)
   wallL.f = love.physics.newFixture(wallL.b, wallL.s, 1 )
   wallL.f:setFriction(0)

   ---Right wall
   wallR = {}
   wallR.b = love.physics.newBody(world, wallR_p.x, wallR_p.y, "static")
   wallR.s = love.physics.newRectangleShape( wallR_p.w, wallR_p.h)
   wallR.f = love.physics.newFixture(wallR.b, wallR.s, 1 )
   wallR.f:setFriction(0)

   --Player
   player = {}
   player.b = love.physics.newBody(world, player_p.x, player_p.y, "static")
   player.s = love.physics.newRectangleShape( player_p.w, player_p.h)
   player.f = love.physics.newFixture(player.b, player.s, 1 )
   player.f:setFriction(0)

   --Computer
   computer = {}
   computer.b = love.physics.newBody(world, computer_p.x, computer_p.y, "static")
   computer.s = love.physics.newRectangleShape( computer_p.w, computer_p.h)
   computer.f = love.physics.newFixture(computer.b, computer.s, 1 )
   computer.f:setFriction(0)

   --Ball
   ball = {}
   ball.b = love.physics.newBody(world, ball_p.xs, ball_p.ys, "dynamic")
   ball.s = love.physics.newCircleShape(ball_p.radius)
   ball.f = love.physics.newFixture(ball.b, ball.s, 1 )
   ball.b:setMass(0.1)
   ball.f:setRestitution(1)
   ball.f:setFriction(0)
end


function love.update(dt)
   world:update(dt)
   if startPush == true then
      ball.b:applyLinearImpulse(  randomMinus()*math.random()*ball_p.xs*ball_p.impC  , randomMinus()*math.random()*ball_p.ys*ball_p.impC )
      startPush = false
   end
   computer.b:setX(ball.b:getX())
   player.b:setX(love.mouse.getX())
   xb,yb = ball.b:getLinearVelocity()
   --[[if yb < 1 then
      ball.b:setLinearVelocity( 0, 100 )
   end]]
   if ball.b:getY()<10 or ball.b:getY()> sh-10 then
      ball.b:setLinearVelocity( 0, 0 )
      ball.b:setY(ball_p.ys)
      startPush = true;
   end

end
function love.keyreleased(key)
   if key == "r" then
   	   ball.b:setY(sh/2)
   	   ball.b:setX(sw/2)
   	   ball.b:setLinearVelocity( 0, 0 )
       ball.b:applyLinearImpulse(  randomMinus()*math.random()*ball_p.xs*ball_p.impC  , randomMinus()*math.random()*ball_p.ys*ball_p.impC )
       startPush = false
   elseif key == "q" then
       love.event.push('quit')
   end
end
function love.draw()
   --Draw score
   love.graphics.setColor(0, 255, 0, 255)
    love.graphics.print("Human:"..human_score, 10, 40)
    love.graphics.print("Computer"..comp_score, 10, 60)

    --Draw walls
    love.graphics.setColor(27, 126, 224, 255)
    --love.graphics.rectangle( "fill", wallL_p.x, wallL_p.y, wallL_p.w, wallL_p.h )
    love.graphics.polygon( "fill", wallL.b:getWorldPoints(wallL.s:getPoints()))
    --love.graphics.rectangle( "fill", wallR_p.x, wallR_p.y, wallR_p.w, wallR_p.h )
    love.graphics.polygon( "fill", wallR.b:getWorldPoints(wallR.s:getPoints()))

    --Draw player
    love.graphics.setColor(27, 224, 57, 255)
    --love.graphics.rectangle( "fill", player.b:getX(), player_p.y, player_p.w, player_p.h )
    love.graphics.polygon( "fill", player.b:getWorldPoints(player.s:getPoints()))

    --Draw computer
    love.graphics.setColor(217, 217, 210, 255)
    --love.graphics.rectangle( "fill", computer.b:getX(), computer_p.y, computer_p.w, computer_p.h )
    love.graphics.polygon( "fill", computer.b:getWorldPoints(computer.s:getPoints()))

    --Draw ball
    love.graphics.setColor(235, 26, 36, 255)
    love.graphics.circle("fill", ball.b:getX(), ball.b:getY(), ball_p.radius)
end


function randomMinus()
   if math.random() >= 0.5 then
      return -1
   else
      return 1
   end
end
Thanks man!
It works!
1)
- Why should I use the body:getX... ? (did you mean in the draw functions?)
i didn't quite get this question.
- I meant: Should I not use the getX() and getY() in the love.draw function
2) Do you have any better idea on how to create a beatable AI?
Here is something I did (but it bounces back and fourth):
computer_p.rt = reponse time (usualy something like: 0<rt<10)

Code: Select all

    if ball.b:getX() < computer.b:getX() then
       computer.b:setX(computer.b:getX()-computer_p.rt)
    elseif ball.b:getX() > computer.b:getX() then
       computer.b:setX(computer.b:getX()+computer_p.rt)
    end
Post Reply

Who is online

Users browsing this forum: No registered users and 154 guests