Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

$10 Explosion Competition

edited June 2014 in Competition Posts: 198

Its simple. Its cheap. Hopefully it is enough to inspire you to dig up your explosion code and post it here. It's $10 sent via payapl to the best explosion code out there.

I have always been fascinated by explosions. I almost took a job in Amarillo Texas just so I could build hydrogen bombs, the biggest man made explosions I know of. Thankfully my altruistic self won out and I decided it would be better for humanity if I used my skills to produce power to bless the lives of others, rather than destroy them.

The competition will run through July 7th. With the winner announced by July 14th.
The criteria is as follows:

  1. Attitude. How do you treat others? Are you nice and helpful (10 pts) or a troll, arrogant, and unhelpful (0 pts).
  2. Code Sharing. Is it able to be used and modified without restriction (10 pts), displayed so that others can see, but all rights retained (5 pts), or not shared at all (0 pts).
  3. Usability. Is it simple to implement and use in code (10 pts), or does it take a nuclear science degree to figure out how to set it up to use in code (0 pts)?
  4. Readibiltiy. Is the code simple to read with lots of comments (10 pts)? Or does it require prophetic skills to interpret and decipher the technique used (0 pts)?
  5. Awesomeness. Does it make you go, "Wow, I wish I was able to code stuff like that?" (up to 10 pts).
  6. Frames per second. Can it run at a full 60 fps (up to 10 pts)? Or does it lag out with stuttery frames on older iPads?
  7. Judging slush fund. 10 points that the judge (currently only me) or judges (if someone would like to volunteer to help make it more fair, please do so), that the judge can use any way he/she sees fit. If you are a judge you will be not be allowed to receive the $10. Feel free to participate, you can still win, but realize the $10 will go to the person with the most points who is not a judge.

Hopefully that covers everything. It's meant to be fun, enjoyable, and help facilitate learning about how to make explosions in games.

Please post all entries, comments, and code in this thread.

To be considered for judging you must include somewhere in your entry post the following word spelled backwards, "aibohphobia". Thus the judges can do a search and gather all the entries and look at them one by one.

Comments

  • Hi there! Are you looking for a visual/partical animation, physics effect, or both?

  • edited June 2014 Posts: 198

    I am looking for whatever you would enjoy coding the most. It is meant to be an enjoyable, leisurely, competition. Feel free to do multiple explosions.

  • Posts: 1,976

    I'm working on my own explosion entry, and I'll have done it a little bit.

    (In case if you wondered how many people would enter)

  • I have started my entry. It works! But the way I set up initial angles/velocity of particles made it so that if I use enough particles, the explosion is a square shape xD Going to restructure those calculations so it will be more circular, and more random.

  • Posts: 198

    @skythecoder and @riverforge, great work. Keep it up. Take your time, there is plenty of it left :)

  • Can I share my source for a critique and for advice before submitting it?

  • Posts: 198

    @riverforge absolutely. The judging won't start until after July 7th.

  • edited June 2014 Posts: 7

    Okay, so it's definitely sloppy/disorganized. I was really just trying to figure out what approach to take, and I've modified a lot of it. That being said, I set it up to make totally custom explosions based on the parameters. So you should be able to paste in just this main and then tweak the parameters while running it.

    Here's how they work:

    gN --> the number of rectangles drawn in the explosion

    gT --> This adjusts the speed of the explosion and the time before the
    rectangles start to fall (gravity) and the rate at which the alpha level changes. Larger numbers = slow motion

    gR_min --> the minimum random number for speed/angle

    gR_max --> the maximum random number for speed/angle

    gDone --> 0 means the animation is occurring. Do not adjust the parameter gN unless gDone = 1 ----important note: drag gDone back to 0 to start the new explosion----

    Some of the explosions look good, some look bad. Play with the parameters and tell me what you think :)

    It's very pixel-like. I made it this way because I'm using spritely in my projects so a square based explosion works well with it.

    -- Explosion
    
    -- Use this function to perform your initial setup
    function setup()
        print("Hello World!")
        parameter.integer("gN", 1, 500, 20)
        parameter.integer("gT", 2, 25, 10)
        parameter.number("gR_min", -1000, 0, -100)
        parameter.number("gR_max", 0, 1000, 100)
        parameter.integer("gDone", 0, 1, 0, InitExplosion)
        InitExplosion()
    end
    
    -- This function gets called once every frame
    function draw()
        -- This sets a dark background color
        background(0, 0, 0, 255)
    
        -- This sets the line thickness
        strokeWidth(5)
        -- Do your drawing here
        Explosion()
        DrawExplosion()
    
    end
    
    function InitExplosion()
        rectMode(CENTER)
        fill(255, 155, 0, 255)
        stroke(255, 206, 0, 255)
        if x == nil then
            x = WIDTH/2
        end
        if y == nil then
            y = HEIGHT/2
        end
        if w == nil then
            w = WIDTH/75
        end
        if h == nil then
            h = HEIGHT/75
        end
        lR_max = gR_max/gT
        lR_min = gR_min/gT
        Rect = {}
        Rect.stime = ElapsedTime
        Rect.timestep = 0.000000001
        Rect.alpha = 255
        Rect.done = 0
        for eN = 0, gN do
            Rect[eN] = {}
            Rect[eN].x = x
            Rect[eN].y = y
            Rect[eN].w = w
            Rect[eN].h = h
            Rect[eN].stepx = math.random(lR_min, lR_max)/gT
            Rect[eN].stepy = math.random(lR_min, lR_max)/gT
            Rect[eN].decx = Rect[eN].stepx/gT
            Rect[eN].decy = Rect[eN].stepy/gT
        end
    end
    
    function Explosion()
        if gDone == 0 then
          --  if ElapsedTime >= Rect.stime + Rect.timestep then
                for eN = 0, gN do
                    dec_max = math.ceil(gR_max/(gT*gT))
                    Rect[eN].stepy = Rect[eN].stepy - (math.random(1, dec_max)/(gT*gT*2))
                    if Rect[eN].stepx >= 0 then
                        stepx = Rect[eN].stepx - (Rect[eN].decx)
                        else
                        stepx = Rect[eN].stepx - (Rect[eN].decx)
                    end
                    if Rect[eN].stepy >= 0 then
                        stepy = Rect[eN].stepy - (Rect[eN].decy)
                        else
                        stepy = Rect[eN].stepy - (Rect[eN].decy)
                    end
                    Rect[eN].x = Rect[eN].x + stepx
                    Rect[eN].y = Rect[eN].y + stepy
                end
                Rect.stime = ElapsedTime
                Rect.alpha = Rect.alpha - (30/gT)
                if Rect.alpha <= 0 then
                    gDone = 1
                end
                fill(255, 155, 0, Rect.alpha)
                stroke(255, 206, 0, Rect.alpha)
            -- end
        end
    end
    
    function DrawExplosion()
        if gDone ==  0 then
            for eN = 0, gN do
                rect(Rect[eN].x, Rect[eN].y, Rect[eN].w, Rect[eN].h)
            end
        end
    end
    
  • edited June 2014 Posts: 425

    Here is my entry so far: aibohphobia

    Updated again, and again,and again... And again!

    Try playing around with the parameters
    Particles now can bounce of the edges


    --# Main -- explosions function setup() img=readImage("Planet Cute:Star") --_save("explosions","3.0",true) --displayMode(FULLSCREEN) parameter.watch("FPS") parameter.watch("#explosions") parameter.integer("numSparks",10,500,50) parameter.number("damping",1.01,1.10,1.05) parameter.number("velocity",0.1,1,0.5) parameter.integer("MODE",1,3,2)--img,sq,circ parameter.boolean("constant",false) parameter.boolean("atTouch",false) parameter.boolean("Rebound",true) parameter.number("GRAVITY",0,5) parameter.integer("Xwind",-10,10,0) parameter.integer("Ywind",-10,10,0) explosions = {} print("\ntap for an explosion\n") print("scroll down to see all the parameters") print("MODES:\n1=image\n2=square\n3=circle") end function draw() gravity = vec2(0,-GRAVITY) wind = vec2(Xwind,Ywind) FPS=1/DeltaTime background(0) blendMode(ADDITIVE) for i =1, #explosions do explosions[i]:draw(gravity,wind) end cullexplosions() if constant then explosions[#explosions+1] = Sparks(origin.x,origin.y,numSparks/10,col,nil,30) end if not atTouch then origin=vec2(WIDTH/2,HEIGHT/2)end end --sprite() function touched(touch) if atTouch then origin=vec2(touch.x,touch.y)end if touch.state == BEGAN and not constant then explosions[#explosions+1] = Sparks(origin.x,origin.y,numSparks,col,nil,30) end end function cullexplosions() for i=#explosions,1,-1 do if not explosions[i].alive then table.remove(explosions,i) end end end --# Spark Spark = class() function Spark:init(x,y,c,t,size) self.texture = img self.size = math.random(size-20,size+20) self.pos = vec2(x,y) local vel = vec2(0,self.size*velocity) self.velocity = vel:rotate(math.random(360)) self.col = color(255, 255, 0, 255) self.alive = true self.angle = math.random(360) self.rotationdirection = math.random(-2,2) self.damping=damping --[[ self.IsSquare=Square self.IsImg=Image ]] self.type=MODE end function Spark:draw(g,w) local _gravity = g or vec2(0,-1) local _wind = w or vec2(1,0) self:move(_gravity,_wind) pushMatrix() translate(self.pos.x,self.pos.y) rotate(self.angle) if self.type==1 then tint(self.col) sprite(self.texture,0,0, self.size) else fill(self.col) if self.type==2 then rectMode(CENTER) rect(0,0, self.size,self.size) else ellipse(0,0, self.size) end end popMatrix() end function Spark:move(g,w) self.size = self.size / self.damping--math.random(1.1,1.5) self.col.a = self.col.a /(self.damping) self.col.r = self.col.r / self.damping self.col.g = self.col.g / (self.damping^3) self.velocity = self.velocity / self.damping self.velocity = self.velocity + g self.pos = self.pos + self.velocity self.pos = self.pos + w self.pos = self.pos + g if self.col.a <= 100 then self.alive = false end self.angle = self.angle + self.rotationdirection*self.velocity:len() if Rebound then if self.pos.y<=0 then self.velocity.y=math.max(self.velocity.y,-self.velocity.y)end if self.pos.y>=HEIGHT then self.velocity.y=math.min(self.velocity.y,-self.velocity.y)end if self.pos.x<=0 then self.velocity.x=math.max(self.velocity.x,-self.velocity.x)end if self.pos.x>=WIDTH then self.velocity.x=math.min(self.velocity.x,-self.velocity.x)end end end Sparks = class() function Sparks:init(x,y,amount,col,img,size) self.alive = true self.sparktable={} for i = 1, amount do self.sparktable[i]=Spark(x,y,col or color(math.random(200,255), math.random(0,200), 0,255),img,size) end end function Sparks:draw(grav,wind) for i = 1, #self.sparktable do self.sparktable[i]:draw(grav,wind) end local i = 1 while i <= #self.sparktable do if not self.sparktable[i].alive then table.remove(self.sparktable,i) i = i - 1 end i = i + 1 end if #self.sparktable == 0 then self.alive = false end end
  • Posts: 454

    aibohphobia

    My entry shouldn't win cos it's just a tweak of an old particle effect shader I did yonks ago.

    Run it and touch the screen. Can stutter with a lot of simultaneous touches, but smooth if touched gently.

    --# Main
    -- Particle Effect
    
    -- Use this function to perform your initial setup
    function setup()
        displayMode(FULLSCREEN)
        --to get ghost trails
        backingMode(RETAINED)
        --b=Backup("Particle Effect Ver 007")
        --sprite("Tyrian Remastered:Explosion Huge")
        particles = Particles(readImage("Tyrian Remastered:Explosion Huge"), 100)
    end
    
    function touched(touch)
        if touch.state == BEGAN then
            x,y = touch.x,touch.y
            for i=1,100 do
                particles:addParticle(x, y, math.random(WIDTH)-x, math.random(HEIGHT)-y, math.random(10), 0, math.random(4000)-2000, math.random(50)+70, math.random(200)-100, 1, -1, 2^(math.random(5)-1) + (math.random(2)-1) * 32, 2^(math.random(5)-1), 2^(math.random(5)-1), 2^(math.random(5)-1), color(255,255,255, 255))
            end
        end
    end
    
    -- This function gets called once every frame
    function draw()
        output.clear()
        --debug info
        print(1/DeltaTime)
        print(particles.numParticles)
    
        --background(0, 0, 0, 5)
        fill(0, 0, 0, 20)
        --fade to black
        rect(0, 0 , WIDTH, HEIGHT)
    
        --draw the particles
        particles:draw()
    end
    
    
    --# Particles
    Particles = class()
    
    function Particles:init(particleImage, gravity)
        self.particleMesh = mesh()
        self.particleMesh.shader = shader(ParticleShader.vertexShader, ParticleShader.fragmentShader)
        self.particleMesh.texture = particleImage
        self.particleMesh.shader.gravity = gravity
        self.particleBuffers = {}
        --x,y is the start location z,w is the movement to the end location
        self.particleBuffers["startAndEnd"] = self.particleMesh:buffer("startAndEnd")
        --x,y is the start time and time to live z,w is the start rotation and delta rotation
        self.particleBuffers["timeAndRotation"] = self.particleMesh:buffer("timeAndRotation")
        --x,y is the start size and delta size, z,w is the start alpha and alpha delta
        self.particleBuffers["sizeAndAlpha"] = self.particleMesh:buffer("sizeAndAlpha")
        --easing mode x is position, y is rotation, z is size, w is alpha
        --modes
        --type 1 linear, 2 quadin, 4 quadout, 8 expoin, 16 expoout
        --apply gravity (only applies to position) add 32
        self.particleBuffers["easing"] = self.particleMesh:buffer("easing")
    
        self.particleDeath = {}
        self.numParticles = 0
    end
    
    function Particles:draw()
        self.particleMesh.shader.time = ElapsedTime
        self.particleMesh:draw()
    end
    
    function Particles:addParticle(startX,startY,endDeltaX, endDeltaY, timeToLive, startAngle, deltaAngle, startSize, deltaSize, startAlpha, deltaAlpha, easePos, easeSize, easeRot, easeAlpha, particleColor)
        etime = ElapsedTime
        firstVertex = 0
        for i=1,self.numParticles do
            if self.particleDeath[i] < etime then
                firstVertex = i*6-5
                break
            end
        end
        if firstVertex == 0 then
            firstVertex = self.particleMesh.size + 1
            self.particleMesh:addRect(0,0,1,1)
            self.particleBuffers["startAndEnd"]:resize(firstVertex + 5)
            self.particleBuffers["timeAndRotation"]:resize(firstVertex + 5)
            self.particleBuffers["sizeAndAlpha"]:resize(firstVertex + 5)
            self.particleBuffers["easing"]:resize(firstVertex + 5)
            self.numParticles = self.numParticles + 1
        end
        self.particleMesh:setRectColor((firstVertex+5)/6, particleColor)
        self.particleDeath[(firstVertex+5)/6] = etime+timeToLive
        for i=firstVertex,firstVertex+5 do
            self.particleBuffers["startAndEnd"][i] = vec4(startX,startY,endDeltaX, endDeltaY)
            self.particleBuffers["timeAndRotation"][i] = vec4(etime, timeToLive, math.rad(startAngle), math.rad(deltaAngle))
            self.particleBuffers["sizeAndAlpha"][i] = vec4(startSize, deltaSize, startAlpha, deltaAlpha)
            self.particleBuffers["easing"][i] = vec4(easePos, easeSize, easeRot, easeAlpha)
        end
    end
    
    
    
    ParticleShader = {
    vertexShader = [[
    //
    // A basic vertex shader
    //
    
    //This is the current model * view * projection matrix
    // Codea sets it automatically
    uniform mat4 modelViewProjection;
    uniform float time;
    uniform float gravity;
    
    //This is the current mesh vertex position, color and tex coord
    // Set automatically
    attribute vec4 color;
    attribute vec4 position;
    attribute vec2 texCoord;
    attribute vec4 startAndEnd;
    attribute vec4 timeAndRotation;
    attribute vec4 sizeAndAlpha;
    attribute vec4 easing;
    
    //This is an output variable that will be passed to the fragment shader
    varying lowp vec4 vColor;
    varying highp vec2 vTexCoord;
    
    void main()
    {
        //Pass the mesh color to the fragment shader
        vColor = easing;
        vColor = color;
        vTexCoord = texCoord;
        vec4 lPosition = position;
        if (time < (timeAndRotation.x + timeAndRotation.y)) {
            //type 1 linear, 2 quadin, 4 quadout, 8 expoin, 16 expoout
            float timeDelta = (time - timeAndRotation.x)/timeAndRotation.y;
            float positionDelta = timeDelta;
            float rotationDelta = timeDelta;
            float sizeDelta = timeDelta;
            float alphaDelta = timeDelta;
            if (mod(easing.x, 4.0) > 1.5) {
                positionDelta = pow(timeDelta, 2.0);
            }
            if (mod(easing.x, 8.0) > 3.5) {
                positionDelta = 1.0 - pow((1.0-timeDelta),2.0);
            }
            if (mod(easing.x, 16.0) > 7.5) {
                positionDelta = pow(2.0, 10.0 * (timeDelta - 1.0)) - 0.001;
            }
            if (mod(easing.x, 32.0) > 15.5) {
                positionDelta = 1.001 * (-pow(2.0, -10.0 * timeDelta) + 1.0);
            }
    
            if (mod(easing.y, 4.0) > 1.5) {
                rotationDelta = pow(timeDelta, 2.0);
            }
            if (mod(easing.y, 8.0) > 3.5) {
                rotationDelta = 1.0 - pow((1.0-timeDelta),2.0);
            }
            if (mod(easing.y, 16.0) > 7.5) {
                rotationDelta = pow(2.0, 10.0 * (timeDelta - 1.0)) - 0.001;
            }
            if (mod(easing.y, 32.0) > 15.5) {
                rotationDelta = 1.001 * (-pow(2.0, -10.0 * timeDelta) + 1.0);
            }
    
            if (mod(easing.z, 4.0) > 1.5) {
                sizeDelta = pow(timeDelta, 2.0);
            }
            if (mod(easing.z, 8.0) > 3.5) {
                sizeDelta = 1.0 - pow((1.0-timeDelta),2.0);
            }
            if (mod(easing.z, 16.0) > 7.5) {
                sizeDelta = pow(2.0, 10.0 * (timeDelta - 1.0)) - 0.001;
            }
            if (mod(easing.z, 32.0) > 15.5) {
                sizeDelta = 1.001 * (-pow(2.0, -10.0 * timeDelta) + 1.0);
            }
    
            if (mod(easing.w, 4.0) > 1.5) {
                alphaDelta = pow(timeDelta, 2.0);
            }
            if (mod(easing.w, 8.0) > 3.5) {
                alphaDelta = 1.0 - pow((1.0-timeDelta),2.0);
            }
            if (mod(easing.w, 16.0) > 7.5) {
                alphaDelta = pow(2.0, 10.0 * (timeDelta - 1.0)) - 0.001;
            }
            if (mod(easing.w, 32.0) > 15.5) {
                alphaDelta = 1.001 * (-pow(2.0, -10.0 * timeDelta) + 1.0);
            }
    
            float sinAngle = sin(timeAndRotation.z + rotationDelta * timeAndRotation.w);
            float cosAngle = cos(timeAndRotation.z + rotationDelta * timeAndRotation.w);
            lPosition.xy = vec2(dot(lPosition.xy, vec2(cosAngle, -sinAngle)),
                    dot(lPosition.xy, vec2(sinAngle, cosAngle)));
            lPosition.xy = lPosition.xy * (sizeAndAlpha.x + sizeDelta * sizeAndAlpha.y);
            lPosition.xy = lPosition.xy + startAndEnd.xy + (startAndEnd.zw * positionDelta);
    
            if (mod(easing.x,64.0) > 31.5) {
                //adjust position by gravity
                lPosition.y = lPosition.y - (0.5 * gravity * pow((time - timeAndRotation.x), 2.0));
            }
    
            //not sure why just alpha channel isn't working...
            //vColor.a = sizeAndAlpha.z + (alphaDelta * sizeAndAlpha.w);
            vColor = vColor * sizeAndAlpha.z + (alphaDelta * sizeAndAlpha.w);
        }
        else {
            lPosition = vec4(-1000.0,-1000.0, -1000.0, -1000.0);
        }
        //Multiply the vertex position by our combined transform
        gl_Position = modelViewProjection * lPosition;
    }
    ]],
    fragmentShader = [[
    //
    // A basic fragment shader
    //
    
    //Default precision qualifier
    precision highp float;
    
    //This represents the current texture on the mesh
    uniform lowp sampler2D texture;
    
    //The interpolated vertex color for this fragment
    varying lowp vec4 vColor;
    
    //The interpolated texture coordinate for this fragment
    varying highp vec2 vTexCoord;
    
    void main()
    {
        //Sample the texture at the interpolated coordinate
        lowp vec4 col = texture2D( texture, vTexCoord ) * vColor;
    
        //Set the output color to the texture color
        gl_FragColor = col;
    }
    ]]
    }
    
  • Posts: 2,161

    @spacemonkey That's a lot of conditionals! I wonder if it couldn't be improved with a little mathematics ...

  • edited June 2014 Posts: 454

    @Andrew_Stacey possibly, the conditionals are mostly types of tweening which I took almost verbatim from the tweening lua that I believe Codea uses. And all the If's are pulling out bit's from the parameters to see which modes you want the particle to run in. It's good old fashioned generic, poor performing code ;-)

    aibohphobia

    Here's another one. It's based on http://www.clicktorelease.com/blog/vertex-displacement-noise-3d-webgl-glsl-three-js fixed for Codea. You need http://www.clicktorelease.com/blog/vertex-displacement-webgl-glsl-perlin-noise-three-js/explosion.png in your images for the readImage on line 8.

    Grab code here: https://gist.github.com/sp4cemonkey/7caadf6d098be9e0d865

    Here's another version. It puts the explosion into 2d space via a tweaked projection matrix and will go bang on touch points. at 4 explosions simultaneously runs smooth, but degrades from there if you touch too fast.

    code: https://gist.github.com/sp4cemonkey/b6cd5c718a7598717700 this also has some comments to explain usage

  • Posts: 1,976

    I got my entry in over here, it's a 3D explosion with a particle system into a small and easy class.

  • Posts: 198

    These entries are amazing. You are all fantastic programmers.

  • Posts: 198

    @spacemonkey, I see no reason why your entry cannot be part of the competition. There is no reason you cannot submit code you have worked on previously.

  • Posts: 735

    Here's a particle based example using the ship parts which come with Codea, though could be easily customised with your own parts

    -- Particle Explosion by West
    displayMode(FULLSCREEN)
    -- Use this function to perform your initial setup
    function setup()
        --particle based explosion
        --use doParticles() in draw() to draw the particles
        --explodeStar() and explodeShip() create explosions
    
        --Feel free to use, modify improve as you like
    
        particles={} -- a table to hold the particle
        touches={} --a table to track individual touches
        gravity=0.2 --a constant value for gravity
        ground=HEIGHT/7 --a constant for the ground level
        shipparts={"Space Art:Part Red Hull 1","Space Art:Part Red Hull 2","Space Art:Part Red Hull 3","Space Art:Part Red Hull 4",
        "Space Art:Part Red Hull 5","Space Art:Part Red Wing 1","Space Art:Part Red Wing 2","Space Art:Part Red Wing 3","Space Art:Part Red Wing 4"} --a table for the graphical components of the explosion
    end
    
    -- This function gets called once every frame
    function draw()
        -- set up the scene
        background(27, 27, 49, 255)
        strokeWidth(3)
        line(0,ground,WIDTH,ground) --draw a ground line
        doParticles()
    end
    function doParticles()
            --loop through the particle table
        for i,p in pairs(particles) do
            pushMatrix()
            tint(255,255,255,p.fade)  --set the transparency of the particle based on its fade property
            translate(p.x,p.y) --- move it to the correct position
            rotate(p.rotation) --rotate it by the coorect amount
            sprite(p.img,0,0,p.w,p.h) --draw the particle
            noTint() -- remove transparencies
            popMatrix()
            --if the particle is a star or smoke then fade it out
            if p.type<3 then
                p.fade = p.fade -1
                --if the star or smoke has faded to invisible then remove it
                if p.fade<0 then
                    table.remove(particles,i)
                end
            end
            --rotate the particle
            p.rotation = p.rotation + p.rotspd
            --adjust the position of the particle
            p.x = p.x + p.xspd
            p.y = p.y + p.yspd
    
            --if the particle is smoke then increase the size of it
            if p.type==2 then
                p.w = p.w + 0.1
                p.h = p.h + 0.1
            end
    
            --if the particle is a "solid" object
            if p.type>2 then
                --add a smoke particle at a random time
                if math.random(14)==1 then
                    local s=math.random(10)
                    table.insert(particles,{img="Cargo Bot:Smoke Particle",x=p.x,y=p.y,w=5+s,h=5+s,angle=a,fade=255,rotation=0, rotspd=-4+math.random(7),xspd=0,yspd=1,type=2})
                end
                --check to see if there is collision with the ground or walls and iff so, bounce it off
                if p.y<ground then
                    p.y = p.y -p.yspd
                    p.yspd = p.yspd *-0.7
                    p.xspd = p.xspd *0.95
                end
                if p.x<0 or p.x>WIDTH then
                    p.x = p.x -p.xspd
                    p.xspd = p.xspd *-0.9
                end
                --slow the rotation of the particle if it is coming to rest
                if math.abs(p.xspd)+math.abs(p.yspd)<2 then
                    if p.rotspd<0 then p.rotspd = p.rotspd + 0.2 else p.rotspd = p.rotspd -0.2 end
                    if math.abs(p.rotspd)<2 then p.rotspd=0 end
                    if math.abs(p.xspd)+math.abs(p.yspd)<0.2 then
                        p.xspd=0
                        p.yspd=0
                        p.timer = p.timer + 1
                        if p.timer>200 then
                            explodeStar(p.x,p.y,15+math.random(25))
                            table.remove(particles,i)
                        end
                    end
                end
                --appy the effect of gravity to the particle
                p.yspd = p.yspd - gravity
            end
        end
    end
    function explodeStar(xin,yin,sizein)
        --generate an explosion at position xin,yin with sizein indicating the density of the explosion.
        --stars
        for a=1,360,sizein do
            local spd=7+math.random(40)/10
            table.insert(particles,{img="Cargo Bot:Star Filled",x=xin,y=yin,w=25,h=25,angle=a,fade=255,rotation=0, rotspd=-4+math.random(7),xspd=spd*math.sin(math.rad(a)),yspd=spd*math.cos(math.rad(a)),type=1})
        end
    end
    function explodeShip(xin,yin)
        --solid bits of ship
        for i=1,#shipparts do
            local spd=2+math.random(20)/10
            a=math.random(360)
            table.insert(particles,{img=shipparts[i],x=xin,y=yin,w=25,h=25,angle=a,fade=255,rotation=0, rotspd=-4+math.random(7),xspd=spd*math.sin(math.rad(a)),yspd=spd*math.cos(math.rad(a)),type=3,timer=0})
        end
    end
    
    function touched(touch)
        if touch.state==ENDED or touch.state==CANCELLED then
            --draw an explosion when a touch event is finished
            if touch.y>ground then
                explodeStar(touch.x,touch.y,math.random(10))
                explodeShip(touch.x,touch.y)
            end
            touches[touch.id] = nil
        else
            touches[touch.id] = touch
        end
    end
    
    
    
  • Posts: 198

    These are all fantastic entries!

  • Posts: 198

    Less than a week left! :)

  • edited July 2014 Posts: 1,595

    I wasn't going to enter but I had to make an explosion (2d) for my game. It's as close as I've gotten all day, has a stupid name due to having a class called Explosion already (Updated, set size and draw with smaller explosions, big ones can lag if theres more than 2):


    --# Explozun Explozun = class() function Explozun:init(pos,...) -- you can accept and set parameters here self.pos = pos self.m = mesh() self.m.texture = readImage("Documents:circgrad") self.ex = {} self.finished = false if ... then self.size = ... else self.size = 50 end for i=1,self.size do self.ex[i] = {} local mr = math.random(50,70) self.ex[i].r = self.m:addRect(pos.x,pos.y,mr,mr) self.ex[i].pos = pos local bias = vec2(math.random(-50,50),math.random(-50,50))*0.1 self.ex[i].vel = (vec2(math.sin(((math.pi*2)/self.size)*i),math.cos(((math.pi*2)/self.size)*i))*math.random(10,100))/250 self.ex[i].vel = self.ex[i].vel*self.size*0.5 self.ex[i].size = vec2(mr,mr)*(self.size*0.03+1.5) self.ex[i].time = mr*0.05+7 self.ex[i].sets = mr*0.05+6 end self.time = 7 end function Explozun:draw() local alpha = math.max(self.time*50,50) for k,v in pairs(self.ex) do self.ex[k].pos = v.pos + v.vel self.ex[k].vel = self.ex[k].vel*(0.93-(v.pos:dist(self.pos)/900)) --[[local size = v.size-(1-self.time)*v.size*2 size.x = math.max(size.x,0) size.y = math.max(size.y,0)]] size = v.size*((v.sets)-self.time)/v.sets if self.time>1 then else alpha = self.time*50 end self.m:setRect(v.r,v.pos.x,v.pos.y,size.x,size.y) end self.time = self.time-0.04*(DeltaTime*60) if self.time<0 then self.finished = true end local time = 7-self.time pushStyle() self.m:setColors(50,50,50,alpha) blendMode(SRC_COLOR,ONE_MINUS_SRC_COLOR,ZERO,ONE) self.m:draw() if self.time>0.8 then self.m:setColors(math.max(255-time*40,40),math.max(150-time*20,30),time*5,math.max(self.time*50+50,0)) blendMode(SRC_COLOR,ONE,ONE_MINUS_SRC_ALPHA,ONE) self.m:draw() end popStyle() end function Explozun:touched(touch) -- Codea does not automatically call this method end --# Main -- tapCount -- Use this function to perform your initial setup function setup() p = {} id = 0 explozuns = {} parameter.watch("1/DeltaTime") Sizes = 30 parameter.integer("Sizes",1,100,30) end function touched(t) if t.state == BEGAN then id = id + 1 table.insert(explozuns,Explozun(vec2(t.x,t.y),Sizes)) end if t.state == MOVING then id = id + 1 if id%2 == 0 then table.insert(explozuns,Explozun(vec2(t.x,t.y),Sizes)) end end end -- This function gets called once every frame function draw() -- This sets a edark background color background(61, 61, 156, 255) -- This sets the line thickness strokeWidth(5) -- Do your drawing here for k,v in pairs(explozuns) do v:draw() if v.finished then table.remove(explozuns,k) end end end
  • Posts: 198

    These were all great entries. Judging is almost complete. I'll announce the results on the 14th as stated above.

  • Posts: 425

    :-SS

  • Jmv38Jmv38 Mod
    Posts: 3,295

    with luatee code you can use

        self.m.texture = readImage("Tyrian Remastered:Explosion Huge")
    

    for the texture

  • edited July 2014 Posts: 1,595

    @Jmv38 here's the texture i thought I included it:

    circgrad = image(100,100)
    pushStyle()
    setContext(circgrad)
        fill(255, 255, 255, 15)
        for i=1,25 do
            ellipse(50,50,i*4)
        end
    setContext()
    popStyle()
    
  • Posts: 198

    Texture added, looks good!

  • Posts: 198

    After much judging coder takes the prize. Everyone else tied for second. Coder gets ten dollars and everyone else that participated gets five dollars. Please pm me the email address you want me to PayPal the money too. Thank you all and I hope you had fun.

  • Posts: 454

    Just throw my $5 at some charity of your choice.

  • Posts: 1,595

    @MrScience101 that's very charitable of you!

  • Posts: 127

    I liked so much @Luatee 's explosion. And I even prefer it without texture :)

  • Posts: 1,595

    @deactive thank you, I tried to make it as realistic as possible for 2D but without the texture it doesn't quite match it.

  • Posts: 425

    @MrScience101 thanks, I'm honoured :\"> . Same as @spacemonkey , please donate my prize to charity too.

  • Posts: 198

    I did not expect so many charitable donations. I guess I'll have to figure out one to give to, any particular one you want?

  • Posts: 425

    Animals :(|) ?

  • edited July 2014 Posts: 1,595

    Doctors without borders? Sign me up for the charity event.

  • Posts: 735

    Likewise - add mine to the charity donation.

  • Hello here ! I have found a cartoon explosion from Two Lives Left (twolivesleft.com/prototypes/cartoon-explosions/) today and I have rewrite it for Codea : https://gist.github.com/HyroVitalyProtago/6b85d82eb534a4c8a844. Maybe a lot of people don't know about this cool effect...

    Have a good day !

  • Posts: 198

    That's really neat! Thanks for sharing

  • Thank you for the donations to charity. It went to helping a family whose father suffered a stroke and lost his job. Then the mother was suspended from her job. It provided apples, meat, potatoes, carrots, milk and other necessities (twice!) to some very hungry children who were very, very, thankful. Never seen teen age children cry before for receiving food. It was both heartwarming and heartbreaking at the same time. Thank you for your donations.

  • Posts: 2,042

    @MrScience101, that is so great to hear. I applaud all of you for donating.

  • Posts: 1,976

    @MrScience101 Oh crud, I forgot to reply. I wanted mine to go to charity too. Is it too late?

  • I assumed everyone who did not send me a pm wanted their winnings to go to charity. If this was in error, just send me a pm and I'll send the money via paypal. So no you were not too late at all.

Sign In or Register to comment.