relative position of a object

I have a map built that is very large. I am trying to integrate the particle candy product into the map to add smoke and fire in places. The problem that I am trying to fix is that the objects in particle candy are place by relative position to the screen, not the absolute position on the map.

I have objects setup as Spawn points for the effects, I just need to be able to convert their world coordinates to relative screen coordinates. I see conversion utilities to go the other way, but nothing that would help me bring it back.

I grab my objects

-- Load the map  
local map = lime.loadMap("Chapter 1.tmx")  
local objectlayer = map:getObjectLayer("Player Objects")  
local stack1 = objectlayer:getObject("Nuclear Stack 1")  
local stack2 = objectlayer:getObject("Nuclear Stack 2")  
local stack3 = objectlayer:getObject("Nuclear Stack 3")  

Then I create my emitters

-- CREATE AN EMITTER (NAME, SCREENW, SCREENH, ROTATION, ISVISIBLE, LOOP)  
Particles.CreateEmitter("Smoke1" , stack1.x, stack1.y, 0, true, true)  
Particles.CreateEmitter("Smoke2" , stack2.x, stack2.y, 0, true, true)  
Particles.CreateEmitter("Smoke3" , stack3.x, stack3.y, 0, true, true)  
  
Particles.CreateParticleType ("SmokeParticles1", Properties)  
Particles.CreateParticleType ("SmokeParticles2", Properties)  
Particles.CreateParticleType ("SmokeParticles3", Properties)  
  
-- FEED EMITTERS (EMITTER NAME, PARTICLE TYPE NAME, EMISSION RATE, DURATION, DELAY)  
Particles.AttachParticleType("Smoke1" , "SmokeParticles1", 2, 9999, 0)   
Particles.AttachParticleType("Smoke2" , "SmokeParticles2", 2, 9999, 0)   
Particles.AttachParticleType("Smoke3" , "SmokeParticles3", 2, 9999, 0)   
  
-- TRIGGER THE EMITTERS  
Particles.StartEmitter("Smoke1")  
Particles.StartEmitter("Smoke2")  
Particles.StartEmitter("Smoke3")  

So for example, my stack1.x is 8000 and my stack1.y is 55. I am able to start the Emitters in the right place as you enter the Frame, but as soon as I move to the right, the emitters stay at screen.x + 8000 always keeping them out of view.

I was going to update the emitters location based on the screen movement and then disable the emitters once the level is complete.

Any ideas would be appreciated. I know this looks like a Particle Candy question, but it is really about understanding where objects are relative to the viewable screen. [import]uid: 32632 topic_id: 6865 reply_id: 306865[/import]

I’ve not had a chance to play with Particle Candy yet however am I right in thinking that a worldToScreenPosition function would fit the bill? [import]uid: 5833 topic_id: 6865 reply_id: 23952[/import]

I believe so. I am assuming that would give me the relative position of my object.x and object.y from the x and y origin of the current viewable screen. Then when my x dips below 480 (landscape view of the game), I can enable the emitters and run a main() loop changing emitter position along side the object position to have them map up.
[import]uid: 32632 topic_id: 6865 reply_id: 23954[/import]

I assume/hope so too :slight_smile: I will give it a try now and report back. [import]uid: 5833 topic_id: 6865 reply_id: 23955[/import]

It is nearly 3am so I can’t fully guarantee this will work but add it into lime-utils.lua and give it a whirl :slight_smile:

[code]

— Converts a world position into a screen position
@param map The current Map.
@param position The world position.
@return The screen position.
function worldToScreenPosition(map, position)

local newPosition = {}

if map.world then
newPosition.x = position.x - map.world.x
newPosition.y = position.y - map.world.y
end

return newPosition
end

[/code] [import]uid: 5833 topic_id: 6865 reply_id: 23960[/import]

On second thought, I don’t think that will work. I will look at it again after some sleep. [import]uid: 5833 topic_id: 6865 reply_id: 23961[/import]

Cheers

no rush at all [import]uid: 32632 topic_id: 6865 reply_id: 23963[/import]

Ok so I got it to work. Not sure if I am going about it in the most efficient way, but after running the bloody thing about a million times, the code is bound to be a little sloppy.

So…first I load the map and get my objects

-- Load the map  
local map = lime.loadMap("Chapter 1.tmx")  
local objectlayer = map:getObjectLayer("Player Objects")  
local stack1 = objectlayer:getObject("Nuclear Stack 1")  
local stack2 = objectlayer:getObject("Nuclear Stack 2")  
local stack3 = objectlayer:getObject("Nuclear Stack 3")  

Then, I create my emitters using the x and y returned by my Stack objects

-- CREATE AN EMITTER (NAME, SCREENW, SCREENH, ROTATION, ISVISIBLE, LOOP)  
Particles.CreateEmitter("Smoke1" , stack1.x, stack1.y, 0, false, true)  
Particles.CreateEmitter("Smoke2" , stack2.x, stack2.y, 0, false, true)  
Particles.CreateEmitter("Smoke3" , stack3.x, stack3.y, 0, false, true)  

Notice that SCREENW = stack1.x and SCREENH = stack1.y

Next I setup a MAIN() loop to handle changes in distance between the screen and the World coordinates of the stack objects.

local Smoke1 = Particles.GetEmitter("Smoke1")  
local Smoke2 = Particles.GetEmitter("Smoke2")  
local Smoke3 = Particles.GetEmitter("Smoke3")  
  
----------------------------------------------------------------  
-- MAIN LOOP  
----------------------------------------------------------------  
local function main( event )  
  
 local stack1x = stack1.x  
 local stack1y = stack1.y  
 local world1x = lime.utils.screenToWorldPosition(map,{x=0,y=0})  
 local world1y = lime.utils.screenToWorldPosition(map,{x=0,y=0})  
 local delta1x = stack1x - world1x.x  
 local delta1y = stack1y - world1y.y  
 deltaStack1 = {x=delta1x, y=delta1y}  
 print("stack1 location = " .. deltaStack1.x .. " " .. deltaStack1.y)  
 local stack2x = stack2.x  
 local stack2y = stack2.y  
 local world2x = lime.utils.screenToWorldPosition(map,{x=0,y=0})  
 local world2y = lime.utils.screenToWorldPosition(map,{x=0,y=0})  
 local delta2x = stack2x - world2x.x  
 local delta2y = stack2y - world2y.y  
 deltaStack2 = {x=delta2x, y=delta2y}  
 print("stack2 location = " .. deltaStack2.x .. " " .. deltaStack2.y)  
 local stack3x = stack3.x  
 local stack3y = stack3.y  
 local world3x = lime.utils.screenToWorldPosition(map,{x=0,y=0})  
 local world3y = lime.utils.screenToWorldPosition(map,{x=0,y=0})  
 local delta3x = stack3x - world3x.x  
 local delta3y = stack3y - world3y.y  
 deltaStack3 = {x=delta3x, y=delta3y}  
 print("stack3 location = " .. deltaStack3.x .. " " .. deltaStack3.y)  
  
 Smoke1.x = deltaStack1.x  
 Smoke1.y = deltaStack1.y  
 Smoke2.x = deltaStack2.x  
 Smoke2.y = deltaStack2.y  
 Smoke3.x = deltaStack3.x  
 Smoke3.y = deltaStack3.y  
  
 -- UPDATE PARTICLES  
 Particles.Update()  
 -- DISPLAY PARTICLE COUNT  
 --print("PARTICLES:"..Particles.CountParticles())  
end  

I know this is not the best way, but it works. I found out that if you feed the lime.utils.screenToWorldPosition function x=0,y=0 then it returns the world coordinates for the upper left hand corner of the viewable screen. Then it was just a matter of taking that number and subtracting it from the coordinates of my stack object.

anyway I am chuffed to get it working feel like one jammy bugger tonight.

Cheers and thanks for the help. Let me know if you have a better way to implement the function. I am all about cleaning up AND helping you improve the depth of Lime. [import]uid: 32632 topic_id: 6865 reply_id: 23984[/import]