Page 1 of 2
What can I do with love.graphics.point ???
Posted: Wed Dec 02, 2015 8:12 pm
by napolux
First of all, hello everyone!
I would like to create a simple animated starfield using points, I started from this little example
https://love2d.org/wiki/love.graphics.point and I added a size. Now I want to add alpha to the points and move them around, simulating a sort of parallax: bigger objects are brighter and will move faster.
Is my approach ok or should I use sprites instead of points? Can I assign points to variable in the stars table and reference them while I update?
Sorry for the stupid questions, but I'm fairly new to this
My code is available here:
https://github.com/napolux/devember/blo ... /stars.lua
Re: What can I do with love.graphics.point ???
Posted: Thu Dec 03, 2015 1:43 am
by Beelz
I'm not exactly sure what you mean... Do you want the stars to all move around randomly, or all together? If you want them moving together I would suggest just translating the camera. Also I would tile an image of stars, as opposed to rendering hundreds of points. IMO point is only useful for things like bullets and particles.
Re: What can I do with love.graphics.point ???
Posted: Thu Dec 03, 2015 1:56 am
by s-ol
@Beelz: the whole idea is rendering a Startfield point-by-point, instead of using a prefab space image.
Alpha is part of the color, so you can do love.graphics.setColor(255, 255, 255, 120) for a half-transparent point for example. Of course you can save the points in a table, but I am not sure whether there is a löve function that draws a number of points at once, and there definetely isn't one that draws multiple points with different colors (alphas) - you need to write your own loop for that.
Re: What can I do with love.graphics.point ???
Posted: Thu Dec 03, 2015 4:36 am
by bobbyjones
It probably would be faster to use an image with a spritebatch. Well unless you render the stars to a canvas once.
Re: What can I do with love.graphics.point ???
Posted: Thu Dec 03, 2015 6:13 am
by napolux
Thanks, I'll probably try another approach
Re: What can I do with love.graphics.point ???
Posted: Thu Dec 03, 2015 6:58 am
by Ulydev
Code: Select all
local Starfield = {}
Starfield.__index = Starfield
function Starfield:new(density)
local starfield = {}
setmetatable(starfield, Starfield)
starfield.density = density
self.stars = {}
return starfield
end
function Starfield:onLoad()
for i = 1, self.density do --number of stars
self.stars[i] = {x = love.math.random()*WWIDTH, y = love.math.random()*WHEIGHT, size = love.math.random()*4+.1}
end
end
function Starfield:update(dt, x, y)
for i = 1, #self.stars do
self.stars[i].x, self.stars[i].y = (self.stars[i].x + x*dt)%WWIDTH, (self.stars[i].y + y*dt)%WHEIGHT
end
end
function Starfield:draw()
love.graphics.setColor(255, 255, 255)
for i = 1, #self.stars do
love.graphics.setPointSize(self.stars[i].size)
love.graphics.point(self.stars[i].x, self.stars[i].y, self.stars[i].size)
end
end
return Starfield
Create a star field with myStarfield = Starfield:new(50), and call myStarfield:onLoad().
Then, update it with myStarfield:update(dt, moveX, moveY) and draw it with myStarfield:draw().
Re: What can I do with love.graphics.point ???
Posted: Thu Dec 03, 2015 9:23 am
by zorg
Modified Ulydev's code a bit; now it includes parallax:
Code: Select all
-- This will be a table returned at the end of the file, holds all the code necessary to create starfields
local Starfield = {}
-- This is here so that the starfields you create will have everything inside them.
Starfield.__index = Starfield
-- degrees to radians constant
local d2r = math.pi/180
function Starfield:new(density)
local starfield = {}
-- This gives the above created starfield every function (and variable) the Starfield table in this file has.
setmetatable(starfield, Starfield)
-- Saves the given density value
starfield.density = density
-- Creates an empty table that will hold the stars' data.
self.stars = {}
return starfield
end
function Starfield:load()
local w, h = love.graphics.getDimensions()
-- This loop will set up all the stars with their position, size and visibility generated randomly.
for i = 1, self.density do --number of stars
self.stars[i] = {
x = love.math.random()*w,
y = love.math.random()*h,
size = love.math.random()*1.4+.1,
z = love.math.random()*8+.5, -- depth
radiance = love.math.random(1,255) -- alpha (transparency)
}
end
end
function Starfield:update(dt, x, y)
-- If we don't pass in an x or y value, take it as 0 by default
x, y = x or 0, y or 0
local w, h = love.graphics.getDimensions()
for i = 1, #self.stars do
-- Modify each star's position, but wrap them around the screen (with the % modulo/modulus, or remainder operator)
self.stars[i].x, self.stars[i].y = (self.stars[i].x + x*dt)%w, (self.stars[i].y + y*dt)%h
end
end
function Starfield:draw()
local w, h = love.graphics.getDimensions()
for i = 1, #self.stars do
-- this helps translate each star with differing amounts, creating a parallax effect
local parallax = self.stars[i].z * math.tan(90 / 2 * d2r)
love.graphics.push()
love.graphics.setPointSize(self.stars[i].size)
love.graphics.setColor(255, 255, 255, self.stars[i].radiance)
-- We modify the drawn positions with the parallax.
love.graphics.point(self.stars[i].x*parallax, self.stars[i].y*parallax, self.stars[i].size)
love.graphics.pop()
end
end
return Starfield
Here's a test main.lua:
Code: Select all
local starfield,sf
function love.load()
starfield = require 'starfield'
-- create a new starfield with 50k stars.
sf = starfield:new(50000)
-- and we initialize it (generate the stars)
sf:load()
end
function love.update(dt)
local x, y = 0,0
-- movement
if love.keyboard.isDown('left') then x = x - 100 end
if love.keyboard.isDown('right') then x = x + 100 end
if love.keyboard.isDown('up') then y = y - 100 end
if love.keyboard.isDown('down') then y = y + 100 end
sf:update(dt, x ,y)
end
function love.draw()
sf:draw()
end
Edit: added comments to explain stuff better
Also, note that this code doesn't treat a bigger star as being closer (and moving faster), since those properities are separate from one another.
Re: What can I do with love.graphics.point ???
Posted: Thu Dec 03, 2015 10:58 am
by s-ol
nanoplux, if you are new to LÖVE and/our Lua, DON'T use a SpriteBatch, a Shader or a Canvas for this. Points are perfectly fine for just trying out how to do a parallax Starfield and even if it were performance critical, not trying without other means would be premature optimization.
also your code is perfectly fine and I doubt that you will learn much by using Ulydevs code.
Do you know how parallaxity "works" mathematically?
I would start by adding dt as a parameter to the updateStars function (see the wiki for dt) and then move each star (set a new value for x) by an amount proportional (or otherwise related) to it's size - that will make small starts move slower than large stars.
After that you can do some custom movement, for example depending on the mouse position or keyboard input.
Re: What can I do with love.graphics.point ???
Posted: Thu Dec 03, 2015 5:23 pm
by bobbyjones
zorg just an unrelated question but what's your fps with 50k stars lol. That's a lot.
Re: What can I do with love.graphics.point ???
Posted: Thu Dec 03, 2015 7:25 pm
by napolux
zorg wrote:Modified Ulydev's code a bit; now it includes parallax:
This is the example I was looking for, very well commented and easy to understand. Thanks a lot (both of you)!
I'll study and modify it to make it manage star size and speed...