Howdy, Stranger!

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

Lua chopter

edited August 2013 in Code Sharing Posts: 437

Just a game to add as a bonus in the physics game

Code:

--# Main

-- theCave
widthRatio = 1
heightRatio= 1
displayMode(FULLSCREEN)
-- Use this function to perform your initial setup
function setup()
   cave   = Cave()
   paused = false
   winner = false
end

-- This function gets called once every frame
function draw()
    -- This sets a dark background color 
    background(0)

    -- This sets the line thickness
    strokeWidth(5)

    -- Do your drawing here
    cave:draw()
end

function touched(touch)
    cave:touched(touch)
end

--# CavePlayer
CavePlayer = class()

function CavePlayer:init()
    self.position    = vec2(166*widthRatio, HEIGHT/2)
    self.linearSpeed = vec2(1000,1000) -- trick for the engine  
    self.img         = readImage("SpaceCute:Rocketship") 
    self.sx          = 66*widthRatio
    self.sy          = 66*heightRatio
    self.speed       = 0.02
    self.accel       = 0.01
    self.gravity     = 0.2
    self.motor       = 0.8
end

function CavePlayer:move()
    self.position.y = self.position.y - self.speed
    self.speed      = self.speed + self.accel + self.gravity
    
    if self.position.y <  0 then
        self.position.y = 0
        self.speed      = 0
    end
    
    if self.position.y > HEIGHT then
        self.position.y = HEIGHT
        self.speed      = -0.1*self.speed
    end
end

function CavePlayer:draw()
    if not paused and not winner then
        self:move()
    end
    pushMatrix()
        translate(self.position.x,self.position.y)
       -- rotate(self.angle)
        local angle = -self.speed*5
         if angle > 90 then
            angle = 90
         end
         if angle < -90 then
            angle = -90
         end
        rotate(angle)
        sprite(self.img, 0,0, self.sx, self.sy)
    popMatrix()
end

function CavePlayer:touched(touch)
    if touch.state == BEGAN or touch.state == MOVING then
        self.accel = -self.motor
    elseif touch.state == ENDED then
        self.accel = self.gravity
    end
end

function CavePlayer:destroy()
    -- trick
end

--# Explosion 

Explosion = class()
function Explosion:init(_position, power,r,g,b)
    -- you can accept and set parameters here
    self.duration = 0.6
    self.currentTime = 0
    self.endTime = self.currentTime + self.duration
    self.size = math.random(6,123)
    self.blastSize = self.size + power*6
    self.currentSize = self.size
    self.position = _position
    self.R = r
    self.G = g
    self.B = b
end

function Explosion:isDone()
    return self.currentTime > self.endTime*2
end

function Explosion:draw()
    self.currentTime = self.currentTime + 1/30

    -- Time in the attack, 0 to 1
    glowTime = (self.currentTime)/self.duration

    pushStyle()

    noFill()
    stroke(self.R, self.G, self.B, 255*(1-glowTime))
    strokeWidth(10*(1-glowTime))

    self.currentSize = self.blastSize * glowTime + (self.size * (1-glowTime))
    p = self.position
    ellipse(p.x, p.y, self.currentSize)

    popStyle()
end

--# Cave
------ THE CAVE
Cave = class()
function Cave:init()
    self.ball     = CavePlayer()
    self.borders  = {}
    self.obstacles= {}
    self.speed    = 6
    self.frame    = 0
    self.fmod     = math.fmod -- efficience issues
    self.sin      = math.sin
    self.ospeed   = 120 -- obstacles speed
    self.score    = 0
    self.bscore   = readLocalData("cave_score",0)
end

function Cave:createObstacle()
    local last = self.borders[#self.borders-1]
    local obstacle = vec2( WIDTH, 0)
    if last then
        obstacle.x = last.x
        obstacle.y = math.random(last.y+77, HEIGHT-last.y-77)
        obstacle.y = math.min ( 
            obstacle.y, 
            HEIGHT - last.y - 77*2
        )
        obstacle.y = math.max (
            obstacle.y, 
            last.y + 77*2
        )
    end
    
    table.insert(self.obstacles, obstacle)
end


function Cave:createBorder()
    local last   = self.borders[#self.borders-1]
    if last and last.x>WIDTH+100 then return end
    local border = vec2( WIDTH/2,
      (HEIGHT/3)/2 - self.sin(ElapsedTime)*25 - 77
    )
    if last then
        border.x = last.x + 77*widthRatio
    end
    
    table.insert(self.borders, border)
end

function Cave:pointInsideRect(x,y,sx,sy,tx,ty)
    local sx = math.floor(sx/2)
    local sy = math.floor(sy/2)
    return 
     tx>= (x-sx) and tx<=(x+sx) and
     ty<= (y+sy) and ty>=(y-sy)
end

function Cave:update()
    self.frame = self.frame + 1
    if self.fmod(self.frame, self.speed/3)==0 then
        self:createBorder()
        self.score = self.score + 1
    end
    if self.fmod(self.frame, self.ospeed)==0 then
        self:createObstacle()
    end
    local dMin = 1000
    for i,o in ipairs(self.obstacles) do
        o.x = o.x - self.speed 
        if o.x < -77 then
            table.remove(self.obstacles, i)
        else
            local d = o:dist(self.ball.position)
            if dMin > d then dMin = d end
        end
    end
    
    local df = 77*widthRatio
    local px = self.ball.position.x
    local py = self.ball.position.y
    for i,w in ipairs(self.borders) do
        w.x = w.x - self.speed
        if w.x<-df then
            table.remove(self.borders, i)     
        elseif 
            self:pointInsideRect(w.x,w.y,df,df*2,px,py) or
            self:pointInsideRect(w.x,HEIGHT - w.y,df,df*2,px,py)
        then
            dMin = 0
            
        end
    end
    
    return math.floor(dMin)
end

function Cave:drawBorders()
    if not paused and not winner then
        local d = self:update()
        if d <78 then 
            winner = true
            self.explosion = Explosion(self.ball.position, 60, 200,11,11)
            if self.score > self.bscore then
                self.bscore = self.score 
                saveLocalData("cave_score", self.score)
            end
        end   
        fill(43, 77, 226, 255)
        text("Score:"..self.score, 166, 166)
        text("Best:"..self.bscore, WIDTH-166, 166)
        
    elseif winner then
        text("Score:".. self.score..". Press restart", WIDTH/2, HEIGHT/2)
    end
    fill(60, 235, 30, 255)
    noStroke()
    rectMode(CENTER)
    for i,w in ipairs(self.borders) do 
        rect(w.x,w.y,77*widthRatio, w.y*2)
        rect(w.x,HEIGHT-w.y,77*widthRatio, w.y*2)
    end
    
    for i,o in ipairs(self.obstacles) do
        rect(o.x, o.y, 77, 77*2)
    end
end
function Cave:draw()
    self:drawBorders()
    self.ball:draw()
    if self.explosion then
      if self.explosion:isDone() then
           self.explosion = nil
      else
           self.explosion:draw()
      end
    end
end

function Cave:touched(touch)
    self.ball:touched(touch)
end

Tagged:

Comments

  • Posts: 2,820

    Nice job.

  • Jmv38Jmv38 Mod
    edited August 2013 Posts: 3,297

    Badlands and Pong got married and had a baby....
    Cool

  • Posts: 372

    nice @juaxix

  • Posts: 437

    Added an explosion from my first game with Codea (2011) :)

  • Posts: 1,255

    Actually, it looks more like a marriage between Scramble and Choplifter. Which isn't a bad thing at all.

  • Posts: 66

    Any idea why i get a black screen!? Ipad 1 - created new project and pasted the code in....

  • Posts: 437

    uhm, maybe you have to put files in another order, try to copy paste in a single tab

  • Jmv38Jmv38 Mod
    Posts: 3,297

    @akiva sure i have an idea!
    Try this: https://gist.github.com/JMV38/6015514
    And let me know the result

  • edited August 2013 Posts: 66

    @Jvm38 -- the fix runs and says finished
    @juaxix -- if I paste in a single tab I get the same error I mention below

  • Posts: 66

    Tried it -- now I get an error message in Cave:

    Line 133

    Function arguments expected near '

  • Posts: 437

    What is your line 133?

  • Posts: 66

    in Cave:draw()

    self:explosion.draw()

  • edited August 2013 Posts: 437

    should be self.explosion:draw()
    :)

  • Posts: 66

    that works. Thanks

  • Posts: 66

    Really nice -- I lowered the movement sensitivity a bit. (Changed 0.01 to 0.005)

    On question: How are you checking collision detection? the ship can overlap with obstacles a noticeable amount before it counts as a collision.

  • Posts: 437

    it takes the size of the ship, you may need to adjust size in x and y in cavePlayer , self.sx, self.sy, the same for the obstacles, it just check if a point is inside a rectangle

Sign In or Register to comment.