My Crazy Birds Game

Major Bug Fixing :-??

Hi All, I’m only in high school and just new to Codea and really like how it works and am really interested in learning it some more I was wondering if any one could help me with my code it is really stuffed up but with a bit of work it could work. It is a kind of Angry Birds remake and would like it to calculate the score and after 10seconds it saves a high score and sakes to start again currently I just ripped some codes from this website and mashed them all together but I don’t really know how to mash them all together. I really hope someone can help as soon as possible because it would be something I would be really proud of making with the help of the community. Thanks.

function setup()    
    --highScore:clear()    -- uncomment to clear high score list
    x=0  
   b1=Ball()
   b1:Setup(100,100,20,20)
  b2=Brick()
  b2:Setup(880,220,20,100,0)
  b3=Brick()
  b3:Setup(800,220,20,100,0)
  b4=Brick()
  b4:Setup(880,100,20,100,0)
  b5=Brick()
  b5:Setup(800,100,20,100,0)
  b6=Brick()
  b6:Setup(800,320,100,20,0)
  b7=Brick()
  b7:Setup(800,200,100,20,0)

    score=-150
    
    displayMode(FULLSCREEN)

   floor=physics.body(POLYGON,vec2(0,0),vec2(WIDTH,0),vec2(WIDTH,93),vec2(0,93))
   floor.type=STATIC
   floor.y=-1

   roof=physics.body(POLYGON,vec2(0,0),vec2(WIDTH,0),vec2(WIDTH,80),vec2(1,0))
   roof.type=STATIC
   roof.y=768

   wall=physics.body(POLYGON,vec2(0,0),vec2(1,0),vec2(1,1000),vec2(0,1000))
   wall.type=STATIC
   wall.x=1

   wall2=physics.body(POLYGON,vec2(0,0),vec2(1000,0),vec2(100,1000),vec2(0,1000))
   wall2.type=STATIC
   wall2.x=1000
    
     t={}  -- table of timers
    table.insert(t,timer(400,700,800))  -- x,y position, time limit
    
    -- start the game before showing the highscore list
    --hs=highScore(0)       -- create an instance of highscore
    --gameOver=false
    
    -- show the highscore list before starting the game
    hs=highScore(1)        -- create an instance of highscore
    gameOver=true

    score=0
    if isKeyboardShowing() then
        hideKeyboard()
    end
end

function draw()
    spriteMode(CENTER)
    sprite("Documents:Sky",HEIGHT/2,WIDTH/2,1300,835)
   -- This sets the line thickness
   strokeWidth(0)

   -- Do your drawing here
   DrawEnvironment()

    textMode(CENTER)
    fill(255)    
    
    if gameOver then
        if hs.scoreDone then    -- done updating the score
            hs.scoreDone=false   -- set to false   
            score=0            -- reset score for next game
            gameOver=false    -- allow next game to start
        else
            hs:scoreRoutine(score)    -- update current score
        end   -- play the game
    end
end

function DrawEnvironment()
   
    
    x=x+1
    sprite("Platformer Art:Cloud 3",x,650,280,150)
     for a,b in pairs(t) do
        b:draw()
    font("Verdana-Bold")
    fill(0, 0, 0, 255)
    fontSize(100)
    textWrapWidth(800)
    text("Crazy Birds", WIDTH/2, 700)
    pushStyle()
    fontSize(40)
    text("Score:"..score,WIDTH/2,HEIGHT/1.5)
    popStyle()
    fontSize(20)
    text("Last High Score"..hs.currHS,WIDTH/2,500)
    if not gameOver then
            touched(t)
        
        end
    

   b2:Update()
   b3:Update()
   b4:Update()
   b5:Update()
   b6:Update()
   b7:Update()
   b1:Update()
   strokeWidth(0)
   fill(29, 255, 0, 255)
   rect(-1,75,WIDTH+2,20)
   fill(105, 83, 31, 255)
   rect(-1,1,WIDTH+2,80)
    
end

function touched(t)
    hs:touched(t)
    b1:touched(t)    -- call the highscore touched routine
            if t.tapCount == 3 and t.state == ENDED then
            gameOver=true 
end

function keyboard(k)
    hs:keyboard(k)    -- call the highscore keyboard routine
end
            end
    end
highScore = class()

function highScore:init(type)    -- initialize variables
    self.tab={}
    self.name="Crazy Birds"
    self.count=0 
    self.score=0
    self.str=""    
    if type==1 then
        -- 1st time, don't ask for initials, then show highscore
        self.getInitials=false
        self.readS=true
        self.shown=true
    else 
        -- 1st time, ask for initials, then show highscore       
        self.getInitials=true
        self.readS=false
        self.showS=false
    end    
    self.currHS=""
    self.scoreDone=false
    self:scoreRoutine(0)
end

function highScore:scoreRoutine(score)    -- run routines
    if self.getInitials then
        if self.score==0 then
            self.score=score
        end
        self:initials()
    end
    if self.readS then
        self:readScore()
    end
    if self.showS then
        self:showScore()
    end
end

function highScore:clear()    -- clear highscores
    clearLocalData()
end

function highScore:touched(t)
    if t.state==BEGAN and t.tapCount==2 and -- start next game
            not self.scoreDone and self.score==0 then
        self.getInitials=true
        self.readS=false
        self.showS=false
        self.str=""
        self.count=0
        self.scoreDone=true
    end
end

function highScore:initials()    -- initials prompt
    pushStyle()
    fontSize(25)
    fill(23, 198, 133, 255)
    text("Current score   "..self.score,WIDTH/2,HEIGHT-50)
    text("Enter your initials (max 3)",WIDTH/2,HEIGHT-100)
    text("then press return",WIDTH/2,HEIGHT-130)
    text("GAME OVER",WIDTH/2,HEIGHT-300)
    rectMode(CENTER)
    stroke(255)
    strokeWidth(3)
    noFill()
    rect(WIDTH/2,HEIGHT-200,100,50)
    fill(255)
    text(self.str,WIDTH/2,HEIGHT-200)
    if not isKeyboardShowing() then
        showKeyboard()
        self.count=0
        self.str=""
    end 
    popStyle()
end

function highScore:keyboard(k)    -- get initials
    if k==RETURN then
        if self.str~="" and string.sub(self.str,1,1)~=" " then
            self.str=self.str .. "   "
            self.str=string.sub(self.str,1,3)
            self:update()
            self.str=""
            self.count=0
            self.readS=true
            self.getInitials=false
            hideKeyboard()
        else
            self.str=""
            self.count=0
        end
        return
    end
    self.count=self.count+1
    if k==BACKSPACE then
        self.str=string.sub(self.str,1,string.len(self.str)-1)
        self.count=string.len(self.str)
    elseif self.count<4 then
        self.str=self.str..k
    end
    self.str=string.upper(self.str)
end

function highScore:readScore()    -- read existing highscores
    self.tab={}
    local t=listLocalData()
    if #t==0 then    -- no scores, create empty list
        for z=1,10 do
            local str=string.format("...%02d",z)
            saveLocalData(str,0)
        end
        t=listLocalData()
    end
    for a,b in ipairs(t) do
        local v=readLocalData(b)
        self.str=string.format("%6d - %s",v,b)
        table.insert(self.tab,self.str)
    end
    self.str=""
    table.sort(self.tab,function(a,b) return a>b end) -- sort high to low
    local off=string.find(self.tab[1],"-")
    self.currHS=string.sub(self.tab[1],1,off-2)
    self.showS=true
end

function highScore:showScore()    -- show scores
    pushStyle()
    background(31, 57, 62, 255)
    fontSize(40)
    font("Courier-Bold")
    fill(245, 255, 0, 255)
    text(self.name,WIDTH/2,HEIGHT-100)
    fill(255, 127, 0, 255)
    text("High Scores",WIDTH/2,HEIGHT-180)
    fontSize(25)
    for a,b in ipairs(self.tab) do
        if a>10 then    -- remove lowest scores
            local off=string.find(b,"-")
            local init=string.sub(b,off+2,string.len(b))
            saveLocalData(init,nil)
        else
            fill(24, 134, 246, 255)
            self.str=string.format("%s  %2d",string.sub(b,1,string.len(b)-2),a)
            text(self.str,WIDTH/2,HEIGHT-200-a*25)
        end
    end
    fill(0, 255, 0, 255)
    text("Double tap screen to start game.",WIDTH/2,HEIGHT-600)
    popStyle()
end

function highScore:update()    -- update highscore list
    for z=1,10 do
        local str=string.format("%s%02d",self.str,z)
        local scr=readLocalData(str)
        if scr==nil then
            saveLocalData(str,self.score)
            break
        end
        if self.score>=scr then
            saveLocalData(str,self.score)
            self.score=scr
        end
    end
    self.score=0
end


Ball = class()

function Ball:Setup(x,y,radius,r)
   -- you can accept and set parameters here
   self.x = x
   self.y = y
    self.radius = radius

   self.body=physics.body(CIRCLE,radius)
   self.body.x = x
    self.body.dx=0
    self.body.dy=0
    self.applyf=false
   self.body.y = y
    self.body.angle = r

   self.body.restitution=0.5
end


function Ball:Update()
   self:draw()

end


function Ball:draw()
   pushMatrix()
   translate(self.body.x,self.body.y)
   rotate(self.body.angle)
    sprite("Space Art:Asteroid Small")
   popMatrix()

end


function Ball:touched(touch)
        
   self.tx = touch.x
   self.ty = touch.y
   if touch.state == BEGAN then
       inTouch = true
       self.velocity = {}
   end
   if touch.state == MOVING then
       table.insert(self.velocity,1,vec2(touch.deltaX,touch.deltaY))
   end
   if touch.state == ENDED then
       self.dx = 0
       self.dy = 0
       self.n = 0
       for i = 1,10 do
           if self.velocity[i] then
               self.n = self.n + 1
           self.dx = self.dx + self.velocity[i].x
           self.dy = self.dy + self.velocity[i].y
           end
       end
       if self.n >0 then
       self.dx = self.dx / self.n
       self.dy = self.dy / self.n
    print(self.dx)
    print(self.dy)
    
    self.applyf = true
       end
       inTouch = false 
    self.body.type = DYNAMIC
    self.body:applyForce(vec2(self.dx*45,self.dy*45))
       sound(SOUND_HIT, 13058)
    
   end
    
    end

Brick = class()

function Brick:Setup(x,y,w,h,r)
   -- you can accept and set parameters here
   self.x = x
   self.y = y
   self.w = w
   self.h = h

   self.body=physics.body(POLYGON,vec2(0,0),vec2(w,0),vec2(w,h),vec2(0,h))
   self.body.x = x
   self.body.y = y
    self.body.angle = r

   self.body.restitution=0.5
end


function Brick:Update()
   self:draw()

end


function Brick:draw()
   pushMatrix()
   translate(self.body.x,self.body.y)
   rotate(self.body.angle)
    fill(255, 0, 14, 255)
    rect(0,0,self.w,self.h)
   popMatrix()

end


function Brick:touched(touch)
   -- Codea does not automatically call this method
end
function collide(contact)
    if contact.state==BEGAN then 
        sound(SOUND_BLIT, 29671)
        score = score + 10
    end
end


timer=class()

function timer:init(x,y,limit)
    self.x=x
    self.y=y
    self.limit=limit
    self.counter=0
end

function timer:draw()
    if self.counter>self.limit then
        str=string.format("duoble tap to save score:  %.2f",self.limit/100)
    else
        self.counter=self.counter+1
        str=string.format("Time Limit %.2f:  %.2f",self.limit/100,self.counter/100)
    end
    text(str,self.x,self.y)  
end

it would take time but any help would be much appreciated

@timbrand92 - first, welcome.

I’ve formatted your code neatly by putting three ~ on a line before, and after, your code.

You make it sound as though you’ve patched together sections of code from different projects, without really understanding what they do. If that is the case, then I doubt anyone is going to spend a lot of time fixing this for you, because it is important that you understand your own code (even if it is borrowed code), and if you won’t take the time to do that, why should someone else? If this is the situation, then I suggest you put this project to one side, and take time to learn Lua and Codea before attempting something this complex.

If on the other hand, you do know what you’re doing but are stuck on something specific, it will be easier for us to help if you narrow it down some more. There is a lot of code there.

@timbrand92 the main thing I can see is you’ve made classes without an class:init() function so the classes aren’t being initialised and therefore neither are the variables inside them, from my experience this can lead to big problems. I can see you’ve used code from different examples by people like @dave1707 (who might be able to put some more help toward this) and others. The examples are there for this and for you to use whichever way you like, but I advise against snipping and pasting bits of code as they will not be interlinked like they are when you code it yourself.

I suggest taking a look at the structure of Dave’s high score class your using and apply that to your other classes. Other than that very good start, getting stuck in is the best way to learn.

@timbrand92 I’ll look thru your code and see what I can do, but that won’t be until later today.

@timbrand92 I corrected the code and got it to play the game and save the score. I sent a PM with the code. If you have other questions, let me know.

Thanks guys for your help! it’s much appreciated. @Ignatz your right but I started with my own code and learnt simple basics but I wanted to try extend over that and yes I did pull some stuff of here and try to add it to my game and I might be overdoing it but this is just a learning process. I was also wondering how to put a swipe limit to every time a player plays? I’m sorry to have to be very new and not know much but you have to start leaning somewhere and I tried fixing my code but it was not something I was capable of doing.

@timbrand92 - I’m not criticising, don’t get me wrong. We all start from scratch, and it’s not easy. I’m simply suggesting that you will find it much easier to write and debug code if you add a little at a time, especially if you’re a beginner.