Codea Competition (Need input on v2)

Cool. Like it. 2 competitors in the game section.

Uh @Zoyt is it ok to post my game code here

ENEMY_SPAWN_EASY = 0
ENEMY_SPAWN_HARD = 1

EnemyHorde = class()

function EnemyHorde:init()
    -- you can accept and set parameters here
    self.frame = 0
    self.units = {} -- enemy units
    self.heroBullets = {} -- hero's bullets
    self.explosions = {}
    self.enemySize = 50
    self.killCount = 0
    self.spawnPattern = ENEMY_SPAWN_EASY 
end

function EnemyHorde:draw()
    self.frame = (self.frame+1)%128

    pushStyle()

    if self.spawnPattern == ENEMY_SPAWN_EASY then
        fill(123, 25, 100, 255)
    else
        fill(16, 221, 4, 255)
    end

    stroke(62, 33, 37, 255)
    strokeWidth(4)

    -- Spawn random enemy every 100 frames
    if self.frame%50 == 0 then
        spawn = vec2( math.random(WIDTH), HEIGHT + self.enemySize )
        table.insert( self.units, spawn )
    end

    for i,v in ipairs(self.units) do
        -- Move unit down
        v.y = v.y - 5    

        -- If hard, move in sine wave
        if self.spawnPattern == ENEMY_SPAWN_HARD then
            -- Compute movement vector
            sideMove = vec2( math.sin(v.y * 0.02) * 60, 0 )
            v = v + sideMove
        end

        -- Cull unit
        culled = false
        if (v.y + self.enemySize) < 0 then
            table.remove(self.units, i)
            culled = true -- no continue statement
        end 

        -- Check if hit by a bullet
        if culled == false then
            for j,b in ipairs(self.heroBullets) do
                if v:dist(b) < self.enemySize/2 then
                    table.remove(self.units, i)
                    table.remove(self.heroBullets, j)
                    
                    -- Explode!
                    table.insert(self.explosions, Explosion(v))

                    -- Update killCount
                    self.killCount = self.killCount + 1
                end
            end
        end

        -- Draw unit
        sprite("Tyrian Remastered:Blimp Boss", v.x, v.y, self.enemySize, self.enemySize)
        
    end

    -- Draw explosions
    for i,e in ipairs(self.explosions) do
        e:draw()

        if e:isDone() then
            table.remove(self.explosions,i)
        end
    end

    popStyle()
end
Explosion = class()

function Explosion:init(pos)
    self.position = pos
    self.opacity = 255
    self.time = 0
    self.lines = {}

    sound("explode",1285)

    for i = 1,10 do
        dir = vec2(0,1)
        dir = dir:rotate( math.rad(math.random(360)) )
        table.insert( self.lines, dir*math.random(2,7) )
    end
end

function Explosion:isDone()
    return self.opacity <= 0
end

function Explosion:draw()
    self.time = self.time + 1.939
    
    pushStyle()
    lineCapMode(ROUND)
    strokeWidth(6)
    smooth()
    stroke(255, 146, 0, 255)

    p = self.position
    for i,v in ipairs(self.lines) do
        vt = p + v * self.time
        line(p.x, p.y, vt.x, vt.y) 
    end

    self.opacity = 255 * (1 - (self.time/30));

    popStyle()
end
Invader = class()

function Invader:init()
    self.position = vec2(0,0)
    self.bullets = {}
    self.frame = 0
end

function Invader:spawnBullet()
    sound("shoot",77)
    table.insert( self.bullets, vec2( self.position.x, self.position.y + 30 ) )
end

function Invader:drawBullets()
    -- Spawn bullets
    if self.frame%30 == 0 then
        self:spawnBullet()
    end

    -- Move, draw, cull bullets
    for i,v in ipairs(self.bullets) do
        v.y = v.y + 3

        rect(v.x, v.y, 2.5, 45)

        if v.y > (HEIGHT + 10) then
            table.remove(self.bullets,i)
        end 
    end
end

function Invader:draw()
    self.frame = (self.frame + 1)%128

    pushMatrix()
    pushStyle()
    
    -- Set up basic graphical style
    lineCapMode(ROUND)
    strokeWidth(8)
    stroke(222, 12, 12, 255)
    smooth()
    noFill()

    -- Transform to pos
    translate(self.position.x, self.position.y)

    -- Draw our triangle invader
    -- 60 pixels high, 40 pixels wide
   fill(47, 34, 34, 255)
     line( 0, 30, 20, -30 )
    line( 0, 30,-20, -30 )
    line( -20, -30, 20, -30 )
    sprite("Tyrian Remastered:Boss D")

    popMatrix()

    self:drawBullets()

    popStyle()
end

function Invader:touched(touch)
    -- Codea currently does not automatically call this method
end
hero = nil
enemies = nil
bgLines = nil
explosion = nil

GAME_PLAYING = 0
GAME_DEAD = 1
state = GAME_PLAYING

-- Use this function to perform your initial setup
function setup()
    state = GAME_PLAYING

    iparameter("BackgroundSpawnRate",0,3,2)

    hero = Invader()
    hero.position = vec2(WIDTH/2, 150)

    enemies = EnemyHorde()
    enemies.heroBullets = hero.bullets

    bgLines = StreamingLines()
end

function touchingAtPos()
    if CurrentTouch.state == BEGAN or 
       CurrentTouch.state == MOVING then
        return vec2( CurrentTouch.x, CurrentTouch.y )
    end 

    return nil
end

-- This function gets called once every frame
function draw()
    background(12, 0, 255, 255)

    bgLines.spawnRate = BackgroundSpawnRate

    bgLines:update()
    bgLines:draw()

    if state == GAME_PLAYING then 
        -- Process touch
        touch = touchingAtPos()
        if touch then
            if touch.x < (hero.position.x - 10) then
                hero.position.x = hero.position.x - 3
            elseif touch.x > (hero.position.x + 10) then
                hero.position.x = hero.position.x + 3
            end
        end

        if enemies.killCount == 5 then
            enemies.spawnPattern = ENEMY_SPAWN_HARD
        end

        enemies:draw()

        hero:draw()

        -- Check if hero is hit
        for i,v in ipairs(enemies.units) do
            if v:dist(hero.position) < 60 then
                state = GAME_DEAD
                explosion = Explosion(hero.position)
            end
        end
    elseif state == GAME_DEAD then
        if explosion then
            explosion:draw()
            if explosion:isDone() then
                explosion = nil
            end
        end
    end
end
-- This class draws the lines streaming past in the background
-- of the game. We spawn and delete them in the self.lines table

----------------------------------------------
-- Single line
----------------------------------------------
StreamLine = class()
function StreamLine:init(pos, vel)
    self.position = pos
    self.velocity = vel
end

function StreamLine:update()
    self.position.y = self.position.y - self.velocity
end

function StreamLine:draw()
    p = self.position
    line(p.x,p.y,p.x,p.y + self.velocity)
end

function StreamLine:shouldCull()
    -- Check if off the bottom of the screen
    if (self.position.y + self.velocity) < 0 then
        return true
    end 

    return false
end

----------------------------------------------
-- All lines
----------------------------------------------
StreamingLines = class()

function StreamingLines:init()
    self.minSpeed = 5
    self.speed = 30
    self.spawnRate = 2
    self.lines = {}
end

function StreamingLines:updateAndCull()
    toCull = {}
    for i,v in ipairs(self.lines) do
        if v:shouldCull() then
            -- table.insert( toCull, i )
            table.remove( self.lines, i )
        else
            v:update()
        end
    end

    -- print("Removing ", #toCull)
    --for i = #toCull,1,-1 do
    --    table.remove( self.lines, i )
    --end
end

function StreamingLines:update()
    -- Create spawnRate lines per update
    for i = 1,self.spawnRate do
        -- Generate random spawn location
        vel = math.random(self.minSpeed, self.speed)
        spawn = vec2( math.random(WIDTH), HEIGHT + vel )

        table.insert(self.lines, StreamLine(spawn, vel))
    end

    -- Update and cull offscreen lines
    self:updateAndCull()
end

function StreamingLines:draw()
    --print("Num lines = ", #self.lines)

    pushStyle()

    noSmooth()
    stroke(252, 205, 6, 173)
    strokeWidth(2)
    lineCapMode(SQUARE)
 
    for i,v in ipairs(self.lines) do
        v:draw()
    end

    popStyle()
end

@MICHAEL please remember to put three ~ characters on the lines above and below your code blocks. Otherwise the code will be unreadable and messy in your posts. I’ve fixed it for you this time.

Also, I wouldn’t recommend sharing your code directly in a competition thread when you have multiple tabs, as it makes it difficult to follow the content of the thread.

Thank you @John sorry for forgetting about the ~~~ do you have any recommendations as to how I should go about posting my code for this competition I was unsure of the best way

A lot of people use posterous.com which lets you post stuff via email, by setting up an account and emailing to send@posterous.com (i think). You can then provide the links on the forum.

post@posterous.com.

I strongly recommend gist.github.com. Has versioning, easy copy and paste. Posterous worked better for binary files like .codea and screenshots.

Next time I do this, I’ll try to do a better way on my website. Thanks for the participation!

Just tried your game, @Mark. Really fun. Couldn’t get past the second level though :slight_smile:

Thanks. If it’s any consolation, I still die on that stage about 1/2 the time, and it probably took me me a dozen tries to get past the third screen. I only bothered to actually put in four “hand crafted” puzzles, after which the levels are generated randomly, and usually end up being easier than the first four.

The level transition sequence is pretty fantastic. I really like the way everything blasts out and the new level comes in.

@mark I am sitting in class and just tried your game it is awesome I was having trouble with stage 2 so I gave myself a little fuel boost :smiley:

@Bortels and @John thank you I will post code there and just put a link to it from a comment

@Simeon, you can think of this whole game as my leaning the joys of translate() and playing with scale. I tried actively varying the scale so that the ship is actually always the same physical distance from the “sun,” but I found it kind of disorientating.

Oh, and I cheated by using a global variable for scale, but then these classes are’t exactly the kind of thing you’d extract for another program in any case.

It’s stretching the term “space” to its limits, but I’d like to submit my program for exploring “Complex Euclidean Space”: http://www.math.ntnu.no/~stacey/HowDidIDoThat/iPad/Codea.html (scroll down to the projects, the one named “Complex Plane”).

@MICHAEL - If you could give a link to the code, that would be great. (Mabey put it on a hidden page on WordPress) Thanks!