Page 1 of 1

Fixed Movement For Cursor

Posted: Wed Apr 09, 2014 3:28 am
by JaquesEdrillavo
Hey, new guy here.

Im trying to figure it out the movement for a cursor for game Im making.
What I want is the cursor to move in a grid like manner (or a fixed number of pixels).
At this moment, I got the cursor to stop with a little momentum, but I can't figure it out.

Does anyone have idea how to do this?

Thank you!

Re: Fixed Movement For Cursor

Posted: Wed Apr 09, 2014 6:21 am
by Germanunkol
Hi, welcometo the forums!

If I understand correctly, you want to draw something (a cursor) depending on where the mouse pointer is, but fixed to a grid. I wrote a quick example of how to do that:

Code: Select all


local cursorX, cursorY
local GRID_SIZE = 30

function love.load()
	-- love.mouse.setVisible(false)
end

function love.draw()
	love.graphics.setColor(150,155,255,150)
	love.graphics.rectangle( "fill", cursorX, cursorY, GRID_SIZE, GRID_SIZE )
	love.graphics.setColor(255,255,255,255)
	love.graphics.rectangle( "line", cursorX, cursorY, GRID_SIZE, GRID_SIZE )
end

function love.update( dt )
	local x, y = love.mouse.getPosition()
	cursorX = math.floor(x / GRID_SIZE) * GRID_SIZE
	cursorY = math.floor(y / GRID_SIZE) * GRID_SIZE
end
Short explanation: The x and y values are retreived from the mouse. Then they are devided by the GRID_SIZE, so in other words, "how many times does the grid size fit into the current position" or "which grid tile are we currently in". Then we use math.floor (rounds down to the nearest integer) to cut off any trailing digits after the . and make it an integer. When that's done we have the coordinates, as integers, of the grid tile we're on - so then all we need to do is multiply it by GRID_SIZE again to get the position of where the grid tile starts.

If you don't want to see the real mouse pointer, comment in the line in function love.load().

Is this what you were looking for?

Re: Fixed Movement For Cursor

Posted: Thu Apr 10, 2014 12:56 am
by JaquesEdrillavo
Germanunkol wrote:Hi, welcometo the forums!

If I understand correctly, you want to draw something (a cursor) depending on where the mouse pointer is, but fixed to a grid. I wrote a quick example of how to do that:

Code: Select all


local cursorX, cursorY
local GRID_SIZE = 30

function love.load()
	-- love.mouse.setVisible(false)
end

function love.draw()
	love.graphics.setColor(150,155,255,150)
	love.graphics.rectangle( "fill", cursorX, cursorY, GRID_SIZE, GRID_SIZE )
	love.graphics.setColor(255,255,255,255)
	love.graphics.rectangle( "line", cursorX, cursorY, GRID_SIZE, GRID_SIZE )
end

function love.update( dt )
	local x, y = love.mouse.getPosition()
	cursorX = math.floor(x / GRID_SIZE) * GRID_SIZE
	cursorY = math.floor(y / GRID_SIZE) * GRID_SIZE
end
Short explanation: The x and y values are retreived from the mouse. Then they are devided by the GRID_SIZE, so in other words, "how many times does the grid size fit into the current position" or "which grid tile are we currently in". Then we use math.floor (rounds down to the nearest integer) to cut off any trailing digits after the . and make it an integer. When that's done we have the coordinates, as integers, of the grid tile we're on - so then all we need to do is multiply it by GRID_SIZE again to get the position of where the grid tile starts.

If you don't want to see the real mouse pointer, comment in the line in function love.load().

Is this what you were looking for?

Yes!
That movement is exactly what I needed. :awesome:
The only thing is to migrate it for keyboard movement.

I think it will be easier to post the code im working on for the player.
Like I said, I can move the cursor, but I want it to move in the same way as your code does.

Thank you very much!

Code: Select all

 player = {}

local
	cursor = love.graphics.newImage("Images/cursor.png")
	cursorW = cursor:getWidth()
	cursorH = cursor:getHeight()
	windowW = love.window.getWidth()
	windowH = love.window.getHeight()

	

function player.load()
	player.x = 5
	player.y = 5
	player.xvel = 0
	player.yvel = 0
	player.friction = 25
	player.speed = 3250
	player.width = cursorW
	player.height = cursorH
	grid_size = 32
end

function player.draw()
	love.graphics.draw(cursor, player.x, player.y)
end

function player.physics(dt)
	player.x = player.x + player.xvel * dt
	player.y = player.y + player.yvel * dt
	player.xvel = player.xvel * (1 - math.min(dt * player.friction, 1))
	player.yvel = player.yvel * (1 - math.min(dt * player.friction, 1))
		
end

function player.move(dt)
	if love.keyboard.isDown("right") then
		player.xvel = player.xvel + 32
	end
	if love.keyboard.isDown("left") then
		player.xvel = player.xvel - 32
	end
	if love.keyboard.isDown("up") then
		player.yvel = player.yvel - 32
	end
	if love.keyboard.isDown("down") then
		player.yvel = player.yvel + 32
	end
end

function player.boundary()

	if player.x < 0 then
		player.x = 0
		player.xvel = 0
	end
	if player.x + cursorW > windowW then
		player.x = windowW - cursorW
		player.xvel = 0
	end
	if player.y < 0 then
		player.y = 0
		player.yvel = 0
	end
	if player.y + cursorH > windowH then
		player.y = windowH - cursorH
		player.yvel = 0
	end
	
end

Re: Fixed Movement For Cursor

Posted: Thu Apr 10, 2014 7:25 am
by Germanunkol
Hi,

The first thing that came to mind is that you could move the player right whenever the "right" key is tapped - but I assume you want to keep pressing the button and want the player to move at a constant speed?

If you want "jumping" movement, this is how I'd do it: Just modify player.draw:

Code: Select all

    function player.draw()
		local drawX, drawY
		drawX = math.floor( player.x /cursorW ) * cursorW
		drawY = math.floor( player.y /cursorH ) * cursorH

                love.graphics.draw( cursor, drawX, drawY )
    end
I assumed that cursorW and cursorH are the sizes of the steps you want the cursor to take.

Internally, the player.x and player.y are still the continuous position, not the jumping position. You'll need to keep them, but maybe rename them and calculate the player.x and player.y in player.update(), after calling player.physics and player.move...?
So something like this:

Code: Select all

function player.update( dt )
    player.move( dt )
    player.physics( dt )
    player.jumpX = math.floor( player.x /cursorW)*cursorW
    player.jumpY = math.floor( player.y /cursorH)*cursorH
end

function player.draw()
    love.graphics.draw( cursor, player.jumpX, player.jumpY )
end
Now, whenever you need to check where the player actually is (collision detection etc) simply check player.jumpX and jumpY (might want to rename those to something more useful).

Two more things:
I remembered that the "jumping" coordinates could also be calculated with:
x = player.x - player.x % cursorW
y = player.y - player.y % cursorH
I think that's a bit faster because there's one less multiplication there. The % (modulo) operator gives the "reminder" when dividing a number by another number, so subtracting that reminder from the original number will also be like rounding down to the nearest multiple of cursorW or cursorH.
But you can use either way.

Also, you use the keyword "local" at the beginning - I believe the way you use it, only cursor is made local. You'd need to prepend all the lines with a "local" in order to make the other variables local - if that's what you want to do.

Re: Fixed Movement For Cursor

Posted: Thu Apr 10, 2014 8:40 pm
by JaquesEdrillavo
Germanunkol wrote:Hi,

The first thing that came to mind is that you could move the player right whenever the "right" key is tapped - but I assume you want to keep pressing the button and want the player to move at a constant speed?

If you want "jumping" movement, this is how I'd do it: Just modify player.draw:

Code: Select all

    function player.draw()
		local drawX, drawY
		drawX = math.floor( player.x /cursorW ) * cursorW
		drawY = math.floor( player.y /cursorH ) * cursorH

                love.graphics.draw( cursor, drawX, drawY )
    end
I assumed that cursorW and cursorH are the sizes of the steps you want the cursor to take.

Internally, the player.x and player.y are still the continuous position, not the jumping position. You'll need to keep them, but maybe rename them and calculate the player.x and player.y in player.update(), after calling player.physics and player.move...?
So something like this:

Code: Select all

function player.update( dt )
    player.move( dt )
    player.physics( dt )
    player.jumpX = math.floor( player.x /cursorW)*cursorW
    player.jumpY = math.floor( player.y /cursorH)*cursorH
end

function player.draw()
    love.graphics.draw( cursor, player.jumpX, player.jumpY )
end
Now, whenever you need to check where the player actually is (collision detection etc) simply check player.jumpX and jumpY (might want to rename those to something more useful).

Two more things:
I remembered that the "jumping" coordinates could also be calculated with:
x = player.x - player.x % cursorW
y = player.y - player.y % cursorH
I think that's a bit faster because there's one less multiplication there. The % (modulo) operator gives the "reminder" when dividing a number by another number, so subtracting that reminder from the original number will also be like rounding down to the nearest multiple of cursorW or cursorH.
But you can use either way.

Also, you use the keyword "local" at the beginning - I believe the way you use it, only cursor is made local. You'd need to prepend all the lines with a "local" in order to make the other variables local - if that's what you want to do.
Thank you, I'll keep that in mind.


I figured the way to control the player movement with the keyboard, in the same fashion you showed me last time.

Here's how I made it:

Code: Select all

function love.keypressed(key)
	if key == "up" then
		player.y = math.floor(player.y - grid_size)
	end
	if key == "right" then
		player.x = math.floor(player.x + grid_size)
	end
	if key == "down" then
		player.y = math.floor(player.y + grid_size)
	end
	if key == "left" then
		player.x = math.floor(player.x - grid_size)
	end	
end
The only thing now is: I want to that, if the key is held down, the "cursor" moves faster.
Right now it only moves if you press the key.
I tried to multiply the function by dt, but no avail.

Also I don't want to leave it like that. The rest of my player movement instructions are named "player._____", so I want to follow the same scheme. Would you recommend making a movement.lua, and call it in player.lua?

Thanks for all your help!

Re: Fixed Movement For Cursor

Posted: Fri Apr 11, 2014 8:14 am
by Robin
A short hint: [wiki]love.keyboard.isDown[/wiki] called in love.update.

Re: Fixed Movement For Cursor

Posted: Sat Apr 12, 2014 7:32 pm
by JaquesEdrillavo
Robin wrote:A short hint: [wiki]love.keyboard.isDown[/wiki] called in love.update.
I've been trying to calculate in love.update an equation that calculates the whole player.move but with no avail.

I apologize, but I'm quite new with Löve, and inspite its easy coding, I still find difficult to make things work. :?

Re: Fixed Movement For Cursor

Posted: Sat Apr 12, 2014 9:21 pm
by Robin
Could you show us what you've got so far?