Question about Spritebatch:setColor

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.
Post Reply
User avatar
dartvalince
Prole
Posts: 6
Joined: Wed May 27, 2015 7:17 pm

Question about Spritebatch:setColor

Post by dartvalince »

I tried searching here on the forum, but couldn't find a clear answer, or found posts of similar questions with no replies. I'm hoping someone can help me with this.

I am currently experimenting with using SpriteBatches to reduce the amount of draw calls I am producing in my current project/game. The game itself is simple, and relies on circles being drawn to the screen, all of different sizes, but as well different colors. I set out to make a sandboxed version of this using SpriteBatches to test it out, but I'm hitting a brick wall with the color part.

What i expect my code to do
  1. Create large canvas to draw a single circle to (large used so scaling doesn't look terrible)
  2. Draw circle to the canvas
  3. Get the ImageData from the canvas
  4. Create a new image based on the ImageData
  5. Create a new SpriteBatch using the new image created
  6. Create x # of circles and add them to the SpriteBatch. For each circle use SpriteBatch:setColor() to give it a random color
  7. Update movments of circles in the love.update() callback
  8. Draw the SpriteBatch to the screen
Step 6 above is where I'm having a problem. You can see in the code below, i use the following (sb is the SpriteBatch, lm is love.math):

Code: Select all

sb:setColor(lm.random(0, 255), lm.random(0, 255), lm.random(0, 255))
sb.set(  ... )
Now based on what is said on the wiki page, this should set the color for the next sprite added yes?
https://love2d.org/wiki/SpriteBatch:setColor wrote: Sets the color that will be used for the next add and set operations. Calling the function without arguments will clear the color.
However when I actually run this, all of the sprites are the same color everytime. Is there something i'm missing? or does the setColor method set the color for the SpriteBatch overall and not each one added?


Here is my code

Code: Select all

local lg = love.graphics
local lm = love.math
function love.load()
  font = love.graphics.newFont(20)
  love.window.setMode(1280, 720)

  --[[
    first create the canvas that a single
    circle will be drawn to
  --]]
  local cw = 100 -- canvas width
  local ch = 100 -- canvas height
  circleCanvas = lg.newCanvas(cw,ch)
  lg.setCanvas(circleCanvas)
    circleCanvas:clear()
    lg.setColor(255,255,255,100)
    lg.circle('fill', cw/2, ch/2, (cw/2) - 1)
    lg.setColor(255,255,255,255)
    lg.circle('line', cw/2, ch/2, (cw/2) -1 )
  lg.setCanvas()

  -- next, get the image data from the canvas
  circleImageData = circleCanvas:getImageData()

  --  now create an image from the ImageData object
  circleImg = lg.newImage(circleImageData)

  --  finally add the image to a new SpriteBatch
  sb = lg.newSpriteBatch(circleImg, 5000, 'stream')


  --[[
    To test the Spritebatch, we are going to create
    x# of circles with the for loop below, and store
    each circle in the circles table.  This will
    be used in the love.update() to move them
  ]]
  circles = {}

  --[[
   Adjust this value to test different number of circles
  and how it will affect the overall FPS
  --]]
  numCircles = 100

  --  Create the circles and add them to the SpriteBatch
  for i=1, numCircles, 1 do
    local circle = {}
    circle.x = lm.random(0, lg.getWidth())
    circle.y = lm.random(0, lg.getHeight())
    circle.radius = lm.random(10, 50)
    circle.velocity = {
      x = lm.random(-20, 20),
      y = lm.random(-20, 20)
    }

    circle.ox = circleImg:getWidth()/2
    circle.oy = circleImg:getHeight()/2
    circle.sx = ((circle.radius * 2)/circleImg:getWidth())
    circle.sy = ((circle.radius * 2)/circleImg:getHeight())
    circle.rotation = 0

    sb:bind()
      sb:setColor(lm.random(0, 255), lm.random(0, 255), lm.random(0, 255))
      circle.id = sb:add(circle.x, circle.y, circle.rotation, circle.sx, circle.sy, circle.ox, circle.oy, 0, 0)
    sb:unbind()

    table.insert(circles, circle)
  end


end

function love.update(dt)
  --  Update the x & y of each circle
  for i, circle in ipairs(circles) do
    circle.x = circle.x + (circle.velocity.x * dt)
    circle.y = circle.y + (circle.velocity.y * dt)
    sb:set(circle.id, circle.x, circle.y, circle.rotation, circle.sx, circle.sy, circle.ox, circle.oy, 0, 0)
  end
end

function love.draw()
  love.graphics.setFont(font)
  lg.draw(sb)
  lg.print('FPS: ' .. love.timer.getFPS(), 0, 0)

end
and attached is the game.love file for this
Attachments
game.love
(1.02 KiB) Downloaded 97 times
User avatar
bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

Re: Question about Spritebatch:setColor

Post by bartbes »

Well, the phrasing might be awkward, but it affects all next adds and sets, so the first time love.update runs (which is before the first time love.draw runs), all sprites get set, and thus their colour changes to the last one specified using setColor.
User avatar
dartvalince
Prole
Posts: 6
Joined: Wed May 27, 2015 7:17 pm

Re: Question about Spritebatch:setColor

Post by dartvalince »

That makes a ton of sense. So, there really wouldn't be any way of controlling the color of each individual item added to the spritebatch through set color. Technically, i only need two colors for the game, so I could do two separate spritebatchs. Would this hinder performance much, or is there a much better way of doing this?
User avatar
bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

Re: Question about Spritebatch:setColor

Post by bartbes »

There is a way, and before love.update they do all have different colours, if you want that to persist though, you need to call setColor with the right colours in love.update too.
Post Reply

Who is online

Users browsing this forum: Bing [Bot], Google [Bot] and 3 guests