Page 1 of 2

moving a polygon

Posted: Thu Feb 20, 2014 1:58 pm
by laurad
Hi so right now I have managed to make this triangle rotate but how can i make it so that when you press "up" the triangle will move upwards?
Thanks

Code: Select all

function love.load()
	angle = 0
end

function love.update(dt)
	keyboard(dt)
end

function keyboard(dt)
	if love.keyboard.isDown("left") then
		angle = angle - 3 * dt
	end
	
	if love.keyboard.isDown("right") then
		angle = angle + 3 * dt
	end
	
	if love.keyboard.isDown("up") then
	end
end

function love.draw()
	love.graphics.push()
	love.graphics.scale(0.5, 0.5)
	love.graphics.translate(150,150)  
	love.graphics.rotate(angle)        
	love.graphics.translate(-150,-150)
	love.graphics.polygon('line', 100, 100, 200, 100, 150, 200)
	love.graphics.pop()
end

Re: moving a polygon

Posted: Thu Feb 20, 2014 2:30 pm
by Plu
You'd need to apply the same modifcation to all the points in the polygon. So first stuff the points in a table, and then update all their x or y coordinates depending on where you are moving.

Something like below (warning, untested.)

Code: Select all


points = { 100, 200, 200, 100, 150, 200 }

function love.update( dt )
  if love.keyboard.isDown('up') then
    for key, value in ipairs( points ) do
      -- only change the Y coords if going up!
      if key % 2 == 0 then
        ipairs[key] = ipairs[key] + 10*dt -- or whatever speed you want
      end
    end
  end

function love.draw()
  love.graphics.polygon('line', points )
end

Re: moving a polygon

Posted: Thu Feb 20, 2014 2:58 pm
by Azhukar
This is what you want.

Code: Select all

local function triangleCenter(x1,y1,x2,y2,x3,y3)
	return (x1+x2+x3)/3,(y1+y2+y3)/3 --averaged point coordinates
end

local angle,posX,posY --local variables prevent accidental overwriting by other files

local function keyboard(dt)
	local rotationSpeed = math.pi*dt --half of a circle per second
	local movementSpeed = 200*dt --200 pixels per second

	if love.keyboard.isDown("left") then
		angle = (angle-rotationSpeed)%(math.pi*2)
	end

	if love.keyboard.isDown("right") then
		angle = (angle+rotationSpeed)%(math.pi*2)
	end

	if love.keyboard.isDown("up") then
		posX = posX + movementSpeed*math.sin(-angle)
		posY = posY + movementSpeed*math.cos(-angle)
	end
	
	if love.keyboard.isDown("down") then
		posX = posX - movementSpeed*math.sin(-angle)
		posY = posY - movementSpeed*math.cos(-angle)
	end
end

function love.load()
	angle = 0
	posX = 100
	posY = 100
end

function love.update(dt)
	keyboard(dt)
end

function love.draw()
	local x1,y1,x2,y2,x3,y3 = 0,0,100,0,50,100 --triangle point coordinates
	local sx,sy = 0.5,0.5 --scale
	local cx,cy = triangleCenter(x1,y1,x2,y2,x3,y3)

	love.graphics.push()
	love.graphics.translate(posX,posY) --first translate to position
	love.graphics.scale(sx,sy)
	love.graphics.rotate(angle)
	love.graphics.translate(-cx,-cy)
	love.graphics.polygon('line',x1,y1,x2,y2,x3,y3)
	love.graphics.pop()
end
EDIT: fixed position to be center based
EDIT2: optimization thanks to micha

Re: moving a polygon

Posted: Thu Feb 20, 2014 3:26 pm
by laurad
Plu wrote:You'd need to apply the same modifcation to all the points in the polygon. So first stuff the points in a table, and then update all their x or y coordinates depending on where you are moving.

Something like below (warning, untested.)

Code: Select all


points = { 100, 200, 200, 100, 150, 200 }

function love.update( dt )
  if love.keyboard.isDown('up') then
    for key, value in ipairs( points ) do
      -- only change the Y coords if going up!
      if key % 2 == 0 then
        ipairs[key] = ipairs[key] + 10*dt -- or whatever speed you want
      end
    end
  end

function love.draw()
  love.graphics.polygon('line', points )
end
Thanks! The triangle moves up, but now when I rotate the triangle won't rotate from its center

Re: moving a polygon

Posted: Thu Feb 20, 2014 3:32 pm
by laurad
Azhukar wrote:This is what you want.

Code: Select all

local function triangleCenter(x1,y1,x2,y2,x3,y3)
	return (x1+x2+x3)/3,(y1+y2+y3)/3 --averaged point coordinates
end

local angle,posX,posY --local variables prevent accidental overwriting by other files

local function keyboard(dt)
	local rotationSpeed = math.pi*dt --half of a circle per second
	local movementSpeed = 200*dt --200 pixels per second

	if love.keyboard.isDown("left") then
		angle = (angle-rotationSpeed)%(math.pi*2)
	end

	if love.keyboard.isDown("right") then
		angle = (angle+rotationSpeed)%(math.pi*2)
	end

	if love.keyboard.isDown("up") then
		posX = posX + movementSpeed*math.sin(-angle)
		posY = posY + movementSpeed*math.cos(-angle)
	end
	
	if love.keyboard.isDown("down") then
		posX = posX - movementSpeed*math.sin(-angle)
		posY = posY - movementSpeed*math.cos(-angle)
	end
end

function love.load()
	angle = 0
	posX = 100
	posY = 100
end

function love.update(dt)
	keyboard(dt)
end

function love.draw()
	local x1,y1,x2,y2,x3,y3 = 0,0,100,0,50,100 --triangle point coordinates
	local sx,sy = 0.5,0.5 --scale
	local cx,cy = triangleCenter(x1,y1,x2,y2,x3,y3)

	love.graphics.push()
	love.graphics.translate(posX-cx*sx,posY-cy*sx) --first translate to position
	
	love.graphics.scale(sx,sy)
	
	love.graphics.translate(cx,cy) --rotate around center
	love.graphics.rotate(angle)
	love.graphics.translate(-cx,-cy)
	
	love.graphics.polygon('line',x1,y1,x2,y2,x3,y3)
	love.graphics.pop()
end
EDIT: fixed position to be center based
Thank you so much! That works

Re: moving a polygon

Posted: Thu Feb 20, 2014 4:14 pm
by micha
Just a sidenote: The implementation of Azhukar uses love.graphics.translate and love.graphics.rotate to place the triangle at the correct position. These functions rotate and translate everything that is drawn afterwards. That is why they are usually used for implementing camera movement. If you want to have your triangle as a player on a map, then you should rather change the triangles coordinates and keep a fixed camera instead of moving the camera to move the triangle on screen. This involves some trigonometry (a bit less, if you decide to use images instead of polygons). Trigonometry is also inside love.graphics.rotate, but since it is hidden for the user, the usage is easier.

Re: moving a polygon

Posted: Thu Feb 20, 2014 4:27 pm
by Azhukar
micha wrote:That is why they are usually used for implementing camera movement. If you want to have your triangle as a player on a map, then you should rather change the triangles coordinates and keep a fixed camera instead of moving the camera to move the triangle on screen.
Use of coordinate transformation functions is entirely up to the programmer, he has no camera system implemented and even if he had he could still use the functions without a problem.

I have a camera system and I always handle all object drawing through coordinate transformation for rotation and positioning, since I don't have to implement different methods for different objects (which would most likely result in the same effect for more effort).

Re: moving a polygon

Posted: Thu Feb 20, 2014 6:04 pm
by laurad
Azhukar wrote:This is what you want.

Code: Select all

local function triangleCenter(x1,y1,x2,y2,x3,y3)
	return (x1+x2+x3)/3,(y1+y2+y3)/3 --averaged point coordinates
end

local angle,posX,posY --local variables prevent accidental overwriting by other files

local function keyboard(dt)
	local rotationSpeed = math.pi*dt --half of a circle per second
	local movementSpeed = 200*dt --200 pixels per second

	if love.keyboard.isDown("left") then
		angle = (angle-rotationSpeed)%(math.pi*2)
	end

	if love.keyboard.isDown("right") then
		angle = (angle+rotationSpeed)%(math.pi*2)
	end

	if love.keyboard.isDown("up") then
		posX = posX + movementSpeed*math.sin(-angle)
		posY = posY + movementSpeed*math.cos(-angle)
	end
	
	if love.keyboard.isDown("down") then
		posX = posX - movementSpeed*math.sin(-angle)
		posY = posY - movementSpeed*math.cos(-angle)
	end
end

function love.load()
	angle = 0
	posX = 100
	posY = 100
end

function love.update(dt)
	keyboard(dt)
end

function love.draw()
	local x1,y1,x2,y2,x3,y3 = 0,0,100,0,50,100 --triangle point coordinates
	local sx,sy = 0.5,0.5 --scale
	local cx,cy = triangleCenter(x1,y1,x2,y2,x3,y3)

	love.graphics.push()
	love.graphics.translate(posX-cx*sx,posY-cy*sx) --first translate to position
	
	love.graphics.scale(sx,sy)
	
	love.graphics.translate(cx,cy) --rotate around center
	love.graphics.rotate(angle)
	love.graphics.translate(-cx,-cy)
	
	love.graphics.polygon('line',x1,y1,x2,y2,x3,y3)
	love.graphics.pop()
end
EDIT: fixed position to be center based
how could I check collision of the triangle with another object?

Re: moving a polygon

Posted: Thu Feb 20, 2014 8:15 pm
by Azhukar
laurad wrote:how could I check collision of the triangle with another object?
Depends on which geometric shape is colliding with which shape.

You could try using one of the collision libraries lying around on LOVE wiki/forum, make your own collision detection/response yourself or learn how to use the love.physics module.

If you want very simple collisions you can pretend each object is a circle, walls are rectangles and start from there.

Re: moving a polygon

Posted: Thu Feb 20, 2014 9:08 pm
by micha
Azhukar wrote:Use of coordinate transformation functions is entirely up to the programmer,
Yes, of course.
I haven't done any line/polygon based game and I agree that in this case it can indeed be beneficial to use the transformations.

And you can even shorten your code and save one transformation. Replace these lines:

Code: Select all

love.graphics.translate(posX-cx*sx,posY-cy*sx) --first translate to position
love.graphics.scale(sx,sy)
love.graphics.translate(cx,cy) --rotate around center
by these:

Code: Select all

love.graphics.translate(posX,posY) --first translate to position
love.graphics.scale(sx,sy)