Page 1 of 1

How to make things 'move' across screen?

Posted: Thu Feb 23, 2017 11:35 pm
by Annabelle
So, I have a simple game working, and I'm trying to make things, 'move' across the screen. (As well as be generated off screen, and then moved onto screen?)

I'd like to do this so I can have power-ups be found, as well as stuff player can collect. It'll also enable me to draw background stuff to make it more interesting as It goes by.

So far this is my current approach: (Simplified, took out irrelevant UI stuff.) I'm using HUMP camera to lock cam to player, keeping them in middle. Acceleration/movement is basically having background move in opposite direction. Which I think can be applied to this game.

Code: Select all

-- Load other classes I need.
camera = require('camera')

function love.load(arg)
	-- We'll change the default background colour to something a bit more cute. (i.e. Not black.)
	love.graphics.setBackgroundColor(25, 25, 25)
	-- Making the player entity. (Space ship.)
	player = {
		x = 344, -- X location.
		y = 300, -- Y location.
		v = 0,   -- Player velocity.
		img = nil, 	-- Will load later.
		w = nil, -- Width of image.
		h = nil  -- Height of image.
	}
	player.img = love.graphics.newImage('assets/entities/player_ship.png')
	player.w, player.h = player.img:getDimensions()
	-- End making player.
	-- Make background quad and image.
	bgImg  = love.graphics.newImage('assets/bg.png')
	-- Background quad coordinates.
	quadCoord = {
		x = 0,
		y = 0
	}
	bgQuad = love.graphics.newQuad(0, 0, 896 + bgImg:getWidth(), 600 + bgImg:getHeight(), bgImg:getDimensions())
	bgImg:setWrap('repeat', 'repeat')
	-- Init camera.
	cam = camera(player.x, player.y)
end

function love.update(dt)
	-- Lets get the location of the mouse. (Angle compared to the location of our player.)
	mouse_angle = math.atan2(love.mouse.getY() - player.y, love.mouse.getX() - player.x)
	-- Move the ship in the direction we're facing. Using acceleration and stuff.
	-- Normal move.
	if love.keyboard.isDown('w') then
		if player.v < 1000 then
			player.v = player.v + 100
			if player.v > 1000 then
				player.v = 1000
			end
		end
		quadCoord.x = (quadCoord.x - math.cos(mouse_angle) * player.v * dt) % bgImg:getWidth()
		quadCoord.y = (quadCoord.y - math.sin(mouse_angle) * player.v * dt) % bgImg:getHeight()
	else
		if player.v > 0 then
			player.v = player.v - 10
		end
		quadCoord.x = (quadCoord.x - math.cos(mouse_angle) * player.v * dt) % bgImg:getWidth()
		quadCoord.y = (quadCoord.y - math.sin(mouse_angle) * player.v * dt) % bgImg:getHeight()
	end
	cam:lockPosition(player.x, player.y)
end

function love.draw(dt)
-- Draw background.
	love.graphics.draw(bgImg, bgQuad, quadCoord.x - bgImg:getWidth(), quadCoord.y - bgImg:getHeight())
	-- Camera starts.
	cam:attach()
	-- Draw player.
	love.graphics.draw(player.img, player.x, player.y, mouse_angle, 1, 1, player.w / 2, player.h / 2)
	-- Camera ends. Draw any overlayed/UI stuff past this point.
	cam:detach()
end
So how can I do what I set out to do? I haven't the faintest idea how to start. Everytime I try the item just is stuck in same place on screen. :/

Re: How to make things 'move' across screen?

Posted: Fri Feb 24, 2017 12:21 am
by Tjakka5
In your current approach you move the background around to give the illusion of movement.
However, the same kind of logic can be applied to make an object actually move:

First off, you need an object (table) with the following values:
X position, Y position, X velocity, Y velocity.

Then, every frame you add the velocities to the positions. You do this in love.update.

Code: Select all

-- Create our object named 'sphere'
local sphere = {
   x  = 0,
   y  = 0,
   vx = 100,
   vy = 10,
}

-- love.update function. This gets called every frame and performs all the logic.
function love.update(dt)
   -- Take the current position, and add the velocities onto them.
   sphere.x = sphere.x + (sphere.vx * dt) -- We multiply by 'dt' so they move equally fast regardless of framerate.
   sphere.y = sphere.y + (sphere.vy * dt)
end

-- love.draw function. This gets called every frame and draws everything.
function love.draw()
   love.graphics.circle("fill", sphere.x, sphere.y, 50) -- Draw our sphere
end
Hope this helps!

Re: How to make things 'move' across screen?

Posted: Fri Feb 24, 2017 1:03 am
by Annabelle
How would I handle having stuff off screen? Just only render it if it's on screen?

Re: How to make things 'move' across screen?

Posted: Fri Feb 24, 2017 1:06 am
by Positive07
You check if it's on the screen, using the x, y coordinates and it'w width and height. If the x is bigger than the screen width or the y is bigger than the screen height then it's outside, same if the x coordinate is less than minus the object width or the y coordinate is less than minus the object height

Re: How to make things 'move' across screen?

Posted: Fri Feb 24, 2017 3:11 am
by s-ol
Positive07 wrote: Fri Feb 24, 2017 1:06 am You check if it's on the screen, using the x, y coordinates and it'w width and height. If the x is bigger than the screen width or the y is bigger than the screen height then it's outside, same if the x coordinate is less than minus the object width or the y coordinate is less than minus the object height
also you don't really need to care if you know most things are staying pretty close (worst case you start getting fps problems and improve it then). If you draw a 200x100 rectangle at (-300, 100) nothing will happen on screen but its not an error or something.