simple particle question

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
Conifer
Prole
Posts: 4
Joined: Thu Oct 22, 2020 9:48 pm

simple particle question

Post by Conifer »

Hi guys,

I'm learning Love2d and Lua overall and I've been creating pong which taught me a lot, but I was wondering how can I create a trail particle that is emitted behind my ball (square in fact..) As it moves.

Is that something difficult to achieve for a beginner? Could anyone point me in the right directions? Perhaps a guide or libraries too that could make my life easier...

Thank you!
MrFariator
Party member
Posts: 512
Joined: Wed Oct 05, 2016 11:53 am

Re: simple particle question

Post by MrFariator »

To create a simple trail, you can keep track of the ball's x and y positions every frame, and store those into a table. Each entry in the table would then be a single "particle". Then you can loop through that said table, and for each stored position draw another rectangle, circle, or whatever other shape you want to represent the trail. After the trail is of certain length, you can start removing the oldest entries from the table, so that the trail won't simply draw the entire path the ball has taken.

One main note is that you might have to fill in the "gaps" that might be produced if the ball moves fast enough. This can be achieved by spawning a particle every N units for a given distance traveled in a frame. Simply take the x and y positions at the start and end of the frames (plus maybe any surfaces the ball bounced from), and spawn the particles along those coordinates.

That's the basic gist that you can get started with. From there on you can toy with things like transparency, shrinking the trail particles after they spawn, and so on.
User avatar
ReFreezed
Party member
Posts: 612
Joined: Sun Oct 25, 2015 11:32 pm
Location: Sweden
Contact:

Re: simple particle question

Post by ReFreezed »

This can easily be achieved with LÖVE's built-in particle system functionality.

Code: Select all

local playerX = 300
local playerY = 300
local particleSystem

function love.load()
	-- Create a simple image with a single white pixel to use for the particles.
	-- We could load an image from the hard drive but this is just an example.
	local imageData = love.image.newImageData(1, 1)
	imageData:setPixel(0,0, 1,1,1,1)

	local image = love.graphics.newImage(imageData)

	-- Create and initialize the particle system object.
	particleSystem = love.graphics.newParticleSystem(image, 1000)
	particleSystem:setEmissionRate(150)
	particleSystem:setParticleLifetime(.7, 1)
	particleSystem:setSizes(2)
	particleSystem:setSpread(2*math.pi)
	particleSystem:setSpeed(20, 30)
	particleSystem:setColors(1,1,1,1, 1,1,0,1, 1,0,0,1, 1,0,0,0)
end

function love.update(dt)
	-- Update player position.
	local moveSpeed = 250
	if love.keyboard.isDown("left")  then  playerX = playerX - moveSpeed * dt  end
	if love.keyboard.isDown("right") then  playerX = playerX + moveSpeed * dt  end
	if love.keyboard.isDown("up")    then  playerY = playerY - moveSpeed * dt  end
	if love.keyboard.isDown("down")  then  playerY = playerY + moveSpeed * dt  end

	-- Move the particle system's particle emitter to the player's position so
	-- that newly spawned particles appear where the player currently is.
	particleSystem:moveTo(playerX, playerY)
	particleSystem:update(dt) -- This performs the simulation of the particles.
end

function love.draw()
	love.graphics.setColor(1, 1, 1)
	love.graphics.print("Arrow keys to move", 10, 10)

	-- Draw the particle system. Note that we don't need to give the draw()
	-- function any coordinates here as all individual particles have their
	-- own position (which only the particleSystem object knows about).
	love.graphics.setColor(1, 1, 1)
	love.graphics.draw(particleSystem)

	-- Draw the player.
	love.graphics.setColor(0, .5, 1)
	love.graphics.circle("fill", playerX, playerY, 10)
end
Tools: Hot Particles, LuaPreprocess, InputField, (more) Games: Momento Temporis
"If each mistake being made is a new one, then progress is being made."
Conifer
Prole
Posts: 4
Joined: Thu Oct 22, 2020 9:48 pm

Re: simple particle question

Post by Conifer »

ReFreezed wrote: Fri Oct 23, 2020 11:34 pm This can easily be achieved with LÖVE's built-in particle system functionality.

Code: Select all

local playerX = 300
local playerY = 300
local particleSystem

function love.load()
	-- Create a simple image with a single white pixel to use for the particles.
	-- We could load an image from the hard drive but this is just an example.
	local imageData = love.image.newImageData(1, 1)
	imageData:setPixel(0,0, 1,1,1,1)

	local image = love.graphics.newImage(imageData)

	-- Create and initialize the particle system object.
	particleSystem = love.graphics.newParticleSystem(image, 1000)
	particleSystem:setEmissionRate(150)
	particleSystem:setParticleLifetime(.7, 1)
	particleSystem:setSizes(2)
	particleSystem:setSpread(2*math.pi)
	particleSystem:setSpeed(20, 30)
	particleSystem:setColors(1,1,1,1, 1,1,0,1, 1,0,0,1, 1,0,0,0)
end

function love.update(dt)
	-- Update player position.
	local moveSpeed = 250
	if love.keyboard.isDown("left")  then  playerX = playerX - moveSpeed * dt  end
	if love.keyboard.isDown("right") then  playerX = playerX + moveSpeed * dt  end
	if love.keyboard.isDown("up")    then  playerY = playerY - moveSpeed * dt  end
	if love.keyboard.isDown("down")  then  playerY = playerY + moveSpeed * dt  end

	-- Move the particle system's particle emitter to the player's position so
	-- that newly spawned particles appear where the player currently is.
	particleSystem:moveTo(playerX, playerY)
	particleSystem:update(dt) -- This performs the simulation of the particles.
end

function love.draw()
	love.graphics.setColor(1, 1, 1)
	love.graphics.print("Arrow keys to move", 10, 10)

	-- Draw the particle system. Note that we don't need to give the draw()
	-- function any coordinates here as all individual particles have their
	-- own position (which only the particleSystem object knows about).
	love.graphics.setColor(1, 1, 1)
	love.graphics.draw(particleSystem)

	-- Draw the player.
	love.graphics.setColor(0, .5, 1)
	love.graphics.circle("fill", playerX, playerY, 10)
end
Thank you! This is great! However, what if the object, in this matter is a ball that is a rectangle drawn with love.graphics.newRectangle rather than a sprite/img, how can I feed Particle System to use that data? Because currently I'm getting an error which is self explanatory

Code: Select all

Error

main.lua:96: bad argument #1 to 'newParticleSystem' (Texture expected, got table)


Traceback

[C]: in function 'newParticleSystem'
main.lua:96: in function 'load'
[C]: in function 'xpcall'
[C]: in function 'xpcall'
grump
Party member
Posts: 947
Joined: Sat Jul 22, 2017 7:43 pm

Re: simple particle question

Post by grump »

love.graphics.newRectangle does not even exist. That "self-explanatory" error message explains to you that ParticleSystem can only emit Textures.

Draw the rectangle to a Canvas to use it as a texture.
Conifer
Prole
Posts: 4
Joined: Thu Oct 22, 2020 9:48 pm

Re: simple particle question

Post by Conifer »

grump wrote: Sat Oct 24, 2020 1:14 pm love.graphics.newRectangle does not even exist. That "self-explanatory" error message explains to you that ParticleSystem can only emit Textures.

Draw the rectangle to a Canvas to use it as a texture.
Apologies, its love.graphics.rectangle.
I will try that solution.
User avatar
pgimeno
Party member
Posts: 3550
Joined: Sun Oct 18, 2015 2:58 pm

Re: simple particle question

Post by pgimeno »

You can also use an ImageData object to build the image. I presume it's more lightweight.

Untested:

Code: Select all

local function blankImage(x, y)
  return 1, 1, 1, 1  -- or 255,255,255,255 for older Löve
end

local function newFilledRectImage(w, h)
  local imd = love.image.newImageData(w, h)
  imd:mapPixel(blankImage)
  return love.graphics.newImage(imd)
end
User avatar
ReFreezed
Party member
Posts: 612
Joined: Sun Oct 25, 2015 11:32 pm
Location: Sweden
Contact:

Re: simple particle question

Post by ReFreezed »

Conifer wrote: Sat Oct 24, 2020 12:23 pm However, what if the object, in this matter is a ball that is a rectangle drawn with love.graphics.newRectangle rather than a sprite/img, how can I feed Particle System to use that data?
In my example, it's the particles that use the image - not the player/ball/whatever. Anyway, just replace playerX/playerY with the ball's position. The important part is particleSystem:moveTo(thingToFollowX, thingToFollowY). That's what makes the particle system spawn particles at the thing's position.
Tools: Hot Particles, LuaPreprocess, InputField, (more) Games: Momento Temporis
"If each mistake being made is a new one, then progress is being made."
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot] and 217 guests