Quick Links: Download Gideros Studio | Gideros Documentation | Gideros community chat | DONATE
Programming Problem — Gideros Forum

Programming Problem

iWattsiWatts Member
edited June 2014 in General questions
Im trying to get fires to be added randomly to this building. I want a new fire to randomly spawn, and fires vanish after 4 seconds. Please explain how I could do this using simply methods, in only one main lua. Here is some sample code for how i plan to do it:

-- Create Timer
local messageTimer = Timer.new(4000)
-- Timer Function
function tick(event)
messageTimer:start()
AddFire = math.random(12)

flames[AddFire]:setVisible(true)
end

I want to use a timer, and every 4000 miliseconds ( 4 seconds) a flame is added or something)
thanks for the help!

Comments

  • ar2rsawseenar2rsawseen Maintainer
    Sorry, but I don't understand where is your problem?
    Something like this should work:
    function spawnFire()
        local fire = Bitmap.new(Texture.new("fire.png", true))
        fire:setPosition(math.random(0, 800), math.random(0, 400))
        stage:addChild(fire)
        Timer.delayedCall(4000, function()
            fire:removeFromParent()
        end)
    end
    Now you only need to determine the position where to spawn the fire, not simple random, but probably on windows, only right?

    And you can call this method based on how often you want to spawn fires, for example, every 5 seconds
    local timer = Timer.new(5000)
    timer:addEventListener(Event.TIMER,  spawnFire)
    timer:start()
  • iWattsiWatts Member
    I sent you a PM to continue the conversation.
    Thanks for the help!
  • Actually forums are places to share information so if it is not confidential information(like source code vs vs..) we prefer to write the problems and answers in here, not in private PMs :D
  • ar2rsawseenar2rsawseen Maintainer
    So here is what I would do:
    --coordinates where sprites can appear
    local coords = {}
    coords[1] = {x=100, y = 100}
    --etx
    Fire = Core.class(Sprite)
     
    function Fire:init()
        --pool of fires
        self.pool = {}
     
        --taken coordinates
        self.coords = {}
     
        --spawn frequency
        self.spawnRate = 1000
        self.counter = 0
     
        --add listeners
        self:addEventListener(Event.ENTER_FRAME, self.onEnterFrame, self)
        self:addEventListener(Event.REMOVED_FROM_STAGE, self.onRemoved, self)
    end
     
    function Fire:spawn()
        --first get fire from pool or create new
        local fire
        if #self.pool > 0 then
            -- get from the pool
            fire = table.remove(self.pool)
        else
            --create new
            fire = Bitmap.new(Texture.new("fire.png", true))
            fire:setAnchorPoint(0.5, 0.5)
     
            --add event listener
            fire:addEventListener(Event.MOUSE_DOWN, function(e)
                if fire:hitTestPoint(e.x, e.y) then
                    e:stopPropagation()
                    self:removeFire(fire, true)
                end
            end)
     
        end
     
        --then find suitable coordinates
        local available = {}
        for i = 1, coords do
            --if not already taken
            if not self.coords[i] then
                table.insert(available, i)
            end
        end
     
        --get random coordinates from available ones
        local ind = available[math.random(#available)]
     
        --store index as reference to fire
        fire.ind = ind
     
        --set fire to coordinates
        fire:setPosition(coords[ind].x, coords[ind].y)
     
        -- store coordinates as taken
        self.coords[ind] = true
     
        --eliminate fire after time period between 4 and 5 seconds
        Timer.delayedCall(math.random(4000, 5000), function()
            self:removeFire(fire, false)
        end)
    end
     
    function Fire:removeFire(fire, extinguished)
        --if fire is still functional
        if fire:getParent() then
            --remove fire
            fire:removeFromParent()
     
            --release coordinates from taken
            self.coords[fire.ind] = false
            fire.ind = nil
     
            --put fire to pool for reusing
            table.insert(self.pool, fire)
     
            --dispatch an event
            local event = Event.new("fire")
            event.extinguished = extinguished
            self:dispatchEvent(event)
        end
    end
     
    function Fire:onEnterFrame()
        if self.counter == self.spawnRate then
            self.counter = 0
            self:spawn()
        else
            self.counter = self.counter + 1
        end
    end
     
    --remove enter frame event when changing scene, etc
    function Fire:onRemoved()
        self:removeEventListener(Event.ENTER_FRAME, self.onEnterFrame, self)
    end
    And usage would be something like this:
    local fire = Fire.new()
    stage:addChild(fire)
    fire:addEventListener("fire", function(e)
        if e.extinguished then
            --user extinguished it, add a score
       else
          -- user did not extinguish it, remove a life
       end
    end)
    Did not test the code, wrote from the top of my head, hope that helps ;)
  • iWattsiWatts Member
    Awesome, Ill implement this, and then tell you if it works
  • iWattsiWatts Member
    edited June 2014
    Just wondering, is there an "easy" or "easier" way to do this? I could just copy/ paste but then I wouldn't learn anything. I can do basic stuff, but a lot of that language seems completely new. Is there a way to use a simple timer to tell it when to add or take away a flame?

    If you could help me get this working in simple, N00b terms and code it would be awesome, if its a more complicated problem, and I should learn a bit more before trying it, thats cool to.
    thanks!
  • iWattsiWatts Member
    Heres a copy of the main, so you can look through it to see the kind of programmer i am, and if its possible to complete this problem using knowledge that I have demonstrated
    lua
    lua
    main.lua
    12K
  • ar2rsawseenar2rsawseen Maintainer
    edited June 2014
    @iWatts sure, I see, can't tell that your solution is efficient nor elegant, but you are right, in order to learn, you would need to make a lot of mistakes.

    So what is your exact current problem?

    You have a table of flames and you can spawn new fires like this for example
    function spawnFlame()
        local available = {}
        --this way we ignore and use only flames that are not yet visible
        for i = 1, #flames do
            if not flames[i]:isVisible() then
                table.insert(available, i)
            end
        end
        local ind = available[math.random(#available)]
        flames[ind]:setVisible(true)
        Timer.delayedCall(4000, function()
            flames[ind]:setVisible(false)
            --deduct life here
        end)
    end

    Likes: Mells

    +1 -1 (+1 / -0 )Share on Facebook
  • iWattsiWatts Member
    Thanks for the help dude! Its awesome to see advanced programers help out the noobs haha. i added in what you showed me, and the program runs but fires arent added. So just so were on the same track heres the idea:
    there are 9 windows, and I have it start of by spawning 3 fires in 3 random windows (the fires are a .mov so they are moving. Ideally, fires would randomly spawn to random windows, and each fire stays for 3 seconds and then dissapears. if it dissapears, I loose a point (for not putting it out) if i shoot it with the hose, i gain a point. If you have any questions regarding my logic, feel free to ask. Lets tackle this problem!
    Thanks, iWatts
  • iWattsiWatts Member
    also, keep in mind I have an array set up at the beginning that creates flames[i] from 1 to 16, each flame holds a position in the window (flame[1] is top left, flame[2] is top middle, ect..)
  • ar2rsawseenar2rsawseen Maintainer
    yep that is just a function, you also need to call it periodically, the best way is to do something like this:
    local counter = 0
    local spawnRate = 100 --change spawn rate to what you need
    stage:addEventListener(Event.ENTER_FRAME, function()
        if counter == spawnRate then
            counter = 0
            spawnFlame()
        else
            counter = counter + 1
        end
    end)
  • iWattsiWatts Member
    were getting there. I run the program, and then a few seconds later the program closes with this problem
    Screen Shot 2014-06-11 at 5.50.03 PM.png
    463 x 102 - 18K
  • iWattsiWatts Member
    sweet. IT WORKED! Thanks so much for the help! I have a few last questions.
    1. i have a text that says you put out blank / blank fires. where would I add one to each side of that? and second how do i change how quickly they spawn, and despawn/ thanks again!
  • ar2rsawseenar2rsawseen Maintainer
    2) to increase/decrease fire rate increase/decrease value of spawnRate variable
    How quickly they disappear depends on the number in Timer.delayedCall(4000, which is 4000ms or 4 seconds
    1) I did not really understood your question :)
  • MellsMells Guru
    edited June 2014
    @ar2rsawseen I like your attitude and willingness to help/teach.

    Likes: iWatts

    twitter@TheWindApps Artful applications : The Wind Forest. #art #japan #apps
    +1 -1 (+1 / -0 )Share on Facebook
  • ar2rsawseenar2rsawseen Maintainer
    @Mells I don't mind while it does not burn me out completely :)
  • iWattsiWatts Member
    Thanks so much for your help dude! I actually figured out the first question, and thanks for reminding me of the second. Your a true lad.
Sign In or Register to comment.