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
- Create large canvas to draw a single circle to (large used so scaling doesn't look terrible)
- Draw circle to the canvas
- Get the ImageData from the canvas
- Create a new image based on the ImageData
- Create a new SpriteBatch using the new image created
- Create x # of circles and add them to the SpriteBatch. For each circle use SpriteBatch:setColor() to give it a random color
- Update movments of circles in the love.update() callback
- Draw the SpriteBatch to the screen
Code: Select all
sb:setColor(lm.random(0, 255), lm.random(0, 255), lm.random(0, 255))
sb.set( ... )
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?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.
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