What can I do with love.graphics.point ???

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.
napolux
Prole
Posts: 8
Joined: Wed Dec 02, 2015 7:37 pm

What can I do with love.graphics.point ???

Post 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.

Image

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 :D

My code is available here: https://github.com/napolux/devember/blo ... /stars.lua
User avatar
Beelz
Party member
Posts: 234
Joined: Thu Sep 24, 2015 1:05 pm
Location: New York, USA
Contact:

Re: What can I do with love.graphics.point ???

Post 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.

Code: Select all

if self:hasBeer() then self:drink()
else self:getBeer() end
GitHub -- Website
User avatar
s-ol
Party member
Posts: 1077
Joined: Mon Sep 15, 2014 7:41 pm
Location: Cologne, Germany
Contact:

Re: What can I do with love.graphics.point ???

Post 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.

s-ol.nu /blog  -  p.s-ol.be /st8.lua  -  g.s-ol.be /gtglg /curcur

Code: Select all

print( type(love) )
if false then
  baby:hurt(me)
end
bobbyjones
Party member
Posts: 730
Joined: Sat Apr 26, 2014 7:46 pm

Re: What can I do with love.graphics.point ???

Post by bobbyjones »

It probably would be faster to use an image with a spritebatch. Well unless you render the stars to a canvas once.
napolux
Prole
Posts: 8
Joined: Wed Dec 02, 2015 7:37 pm

Re: What can I do with love.graphics.point ???

Post by napolux »

Thanks, I'll probably try another approach
User avatar
Ulydev
Party member
Posts: 445
Joined: Mon Nov 10, 2014 10:46 pm
Location: Paris
Contact:

Re: What can I do with love.graphics.point ???

Post 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().
User avatar
zorg
Party member
Posts: 3470
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: What can I do with love.graphics.point ???

Post 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.
Last edited by zorg on Thu Dec 03, 2015 11:40 am, edited 2 times in total.
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
User avatar
s-ol
Party member
Posts: 1077
Joined: Mon Sep 15, 2014 7:41 pm
Location: Cologne, Germany
Contact:

Re: What can I do with love.graphics.point ???

Post 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.

s-ol.nu /blog  -  p.s-ol.be /st8.lua  -  g.s-ol.be /gtglg /curcur

Code: Select all

print( type(love) )
if false then
  baby:hurt(me)
end
bobbyjones
Party member
Posts: 730
Joined: Sat Apr 26, 2014 7:46 pm

Re: What can I do with love.graphics.point ???

Post by bobbyjones »

zorg just an unrelated question but what's your fps with 50k stars lol. That's a lot.
napolux
Prole
Posts: 8
Joined: Wed Dec 02, 2015 7:37 pm

Re: What can I do with love.graphics.point ???

Post 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... :D
Post Reply

Who is online

Users browsing this forum: Bing [Bot] and 4 guests