Full project need help

----------
--button--
----------
Button = class()

function Button:init(x)
    -- you can accept and set parameters here
    self.displayname=start
    self.pos=vec2(0,0)    
    self.size=vec2(0,0)
    self.action=nil
    self.color=color(113,66,190,255)
end

function Button:draw()
    -- Codea does not automatically call this method
    fill(self.color)
    font("ArialRoundedMTBold")
    fontSize(22)
    local w,h=textSize(self.displayname)
    w = w + 20
    h = h + 30
    roundRect(self.pos.x-w/2,
    self.pos.y-h/2,w,h,30)
    self.size=vec2(w,h)
    textMode(CENTER)
    fill(54,65,96,255)
    text(self.displayname,self.pos.x+2,self.pos.y-2)
    fill(255,255,255,255)
    text(self.displayname,self.pos.x,self.pos.y)
    popStyle()
end
function Button:hit(p)
    local l =self.pos.x-self.size.x/2
    local r =self.pos.x+self.size.x/2
    local t =self.pos.y-self.size.y/2
    local b =self.pos.y+self.size.y/2
    if p.x>l and 
       p.x<r and
       p.y>b and
       p.y<t then return true
    end
return false
end
function Button:touched(touch)
    -- Codea does not automatically call this method
    if touch.state==ENDED and self:hit(vec2(touch.x,touch.y)) then if self.action then self.action() 
    end 
    end
end

-----------
--enemyhorde
-----------


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
        tint(255, 255, 255, 255)
    else
        tint(223, 138, 142, 255)
    end

    stroke(217, 158, 105, 255)
    strokeWidth(8)

    -- Spawn random enemy every 100 frames
    if self.frame%100 == 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:Enemy Ship D", v.x, v.y, 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
----------


Explosion = class()

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

    sound(SOUND_EXPLODE, 227)

    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 + 0.5
    
    pushStyle()

    lineCapMode(ROUND)
    strokeWidth(20)
    smooth()
    stroke(255,255,255,math.max(self.opacity,0))

    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


----------
---main---
----------
hero = nil
enemies = nil
bgLines = nil
explosion = nil
menu=0
GAME_PLAYING = 1
GAME_DEAD = 2
state = menu

 
-- Use this function to perform your initial setup
function setup() 
  state = menu
         button=Button("")
 Button.action=function() Buttonpressed() 
  end  
 state = GAME_PLAYING  
 
    parameter.integer("BackgroundSpawnRate",0,3,2)
    parameter.integer("difficulty",1,3,3)

    hero = Invader()
    hero.position = vec2(WIDTH/2,HEIGHT/2)
 
    enemies = EnemyHorde()
    enemies.heroBullets = hero.bullets
 
    bgLines = StreamingLines()
     
    highscore = readLocalData("highscore")
 
    if not highscore then
        highscore = 0
    end
   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()
    drawbutton()
    displayMode()
    background(0, 0, 0, 255)
    
     
    sprite("Documents:minecraft", WIDTH/2, HEIGHT/2)
    bgLines.spawnRate = BackgroundSpawnRate

    bgLines:update()
    bgLines:draw()

    if state == GAME_PLAYING then
            
        -- Process touch
        touch = touchingAtPos()
        if touch then
         if CurrentTouch.x < (hero.position.x) then
            hero.position.x = hero.position.x - 5
         elseif CurrentTouch.x > (hero.position.x) then
            hero.position.x = hero.position.x + 5
         end
         if CurrentTouch.y < (hero.position.y) then
            hero.position.y = hero.position.y - 5 
         elseif CurrentTouch.y > (hero.position.y) then
            hero.position.y = hero.position.y + 5
         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) < 40 then
                state = GAME_DEAD
                explosion = Explosion(hero.position)
                saveLocalData("highscore", highscore)
                 
                if score >= highscore then
                    didGetHighScore = true
                end
            end
        end
    elseif state == GAME_DEAD then
        if explosion then
            explosion:draw()
            if explosion:isDone() then
                explosion = nil
            end
        end
         
        fontSize(60)
        textMode(CENTER)
        text("GAME OVER",WIDTH/2,HEIGHT/2)
         
        if didGetHighScore == true then
            fontSize(40)
            text("NEW HIGH SCORE!",WIDTH/2,HEIGHT/2 - 80)
            state=menu
        end
         
    end
     
    -- Draw scores
    if difficulty == 3 then
    score = enemies.killCount * 100
    fill(255)
    font("Futura-CondensedExtraBold")
    fontSize(30)
    textMode(CORNER)
    text("Score: "..score, 10, HEIGHT - 50)
    
     end
    if difficulty == 2 then
    score = enemies.killCount * 50
    fill(255)
    font("Futura-CondensedExtraBold")
    fontSize(30)
    textMode(CORNER)
    text("Score: "..score, 10, HEIGHT - 50)
    
     end
    if difficulty == 1 then
    score = enemies.killCount * 25
    fill(255)
    font("Futura-CondensedExtraBold")
    fontSize(30)
    textMode(CORNER)
    text("Score: "..score, 10, HEIGHT - 50)
    
     end
    
    -- update high score
    if score > highscore then
        highscore = score
    end
     
    hs = "High Score: "..highscore
    hswidth = textSize(hs)
    text(hs, WIDTH - hswidth - 10, HEIGHT - 50)
    
end
function drawbutton() 
    button.pos= vec2(400,HEIGHT/2)
    button:draw()
    end
    function buttonpressed()
        if buttonpressed()then state=GAME_PLAYING
            end
            function touched(touch)
                button:touched(touch)
            end
            end


-----------
--Invader--
-----------



Invader= class()

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

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

function Invader:drawBullets()
    -- Spawn bullets
    if difficulty== 1 then
    if self.frame%15 == 0 then
        self:spawnBullet()
    end
    end
    if difficulty== 2 then
    if self.frame%25 == 0 then
        self:spawnBullet()
    end
    end
    if difficulty== 3 then
    if self.frame%50 == 0 then
        self:spawnBullet()
    end
    end
    -- Move, draw, cull bullets
    for i,v in ipairs(self.bullets) do
        v.y = v.y + 3

        ellipse(v.x, v.y, 10, 10)

        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(255, 255, 255, 255)
    smooth()
    noFill()

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

    -- Draw our triangle invader
    -- 60 pixels high, 40 pixels wide
    sprite("Documents:ship1")

    popMatrix()

    self:drawBullets()

    popStyle()
end

function Invader:touched(touch)
    -- Codea currently does not automatically call this method
end

–##part one##–

---------------
---roundrect---
---------------    

    
        
    function roundRect(x,y,w,h,r)
    pushStyle()
    
    insetPos = vec2(x+r,y+r)
    insetSize = vec2(w-2*r,h-2*r)
    
    --Copy fill into stroke
    local red,green,blue,a = fill()
    stroke(red,green,blue,a)
    
    noSmooth()
    rectMode(CORNER)
    rect(insetPos.x,insetPos.y,insetSize.x,insetSize.y)
    
    if r > 0 then
        smooth()
        lineCapMode(ROUND)
        strokeWidth(r*2)

        line(insetPos.x, insetPos.y, 
             insetPos.x + insetSize.x, insetPos.y)
        line(insetPos.x, insetPos.y,
             insetPos.x, insetPos.y + insetSize.y)
        line(insetPos.x, insetPos.y + insetSize.y,
             insetPos.x + insetSize.x, insetPos.y + insetSize.y)
        line(insetPos.x + insetSize.x, insetPos.y,
             insetPos.x + insetSize.x, insetPos.y + insetSize.y)            
    end
    popStyle()
end

–##part two##–

-- 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 = 3
    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(179, 153, 180, 173)
    strokeWidth(2)
    lineCapMode(SQUARE)
 
    for i,v in ipairs(self.lines) do
        v:draw()
    end

    popStyle()
end

Use 3 tidles to format text in to code with a ~~~ at the beginning and one at the end

Thanks but I need to know what’s wrong

.@Mnjk78lg I was able to play this game, and got a high score of 1500 so far. As I mentioned in the other post where you wanted help, I told you that you didn’t have the variable start initialized. I initialized it with the text “qwerty” just to give it a value. See the 2nd line of code below. After doing that, that game ran and I was able to play it. I don’t know if everything is how it’s supposed to be, but it worked so far.

edit: Fun game, new high score 11,800,


function Button:init(x) -- you can accept and set parameters here
    self.displayname="qwerty"  --start 
    self.pos=vec2(0,0) 
    self.size=vec2(0,0) 
    self.action=nil 
    self.color=color(113,66,190,255) 
end

Thanks

No I’m tring to make a page with a button on it that says start then if u press it starts the game

And if u lose it will go back to it

Need help

Here is a version that I modified that shows a prompt on your game screen to “Double tap screen to play”. It also shows up when the game ends to start another game. I removed the button class since you weren’t using it and I didn’t need it here. I also removed a lot of the blank lines to cut down on the size of the code and moved the classes to the end of the code. You can modify this to your liking or just delete it if you don’t want these changes.


-- part 1 of 2

----------
---main---
----------

hero = nil
enemies = nil
bgLines = nil
explosion = nil
menu=0
GAME_PLAYING = 1
GAME_DEAD = 2
state = menu 

function setup() 
    state = menu
    parameter.integer("BackgroundSpawnRate",0,3,2)
    parameter.integer("difficulty",1,3,3)
    hero = Invader()
    hero.position = vec2(WIDTH/2,HEIGHT/2)
    enemies = EnemyHorde()
    enemies.heroBullets = hero.bullets
    bgLines = StreamingLines()
    highscore = readLocalData("highscore")
    if not highscore then
        highscore = 0
    end
    didGetHighScore=false
end 

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

function draw()
    displayMode()
    background(0, 0, 0, 255)
    sprite("Documents:minecraft", WIDTH/2, HEIGHT/2)
    bgLines.spawnRate = BackgroundSpawnRate
    bgLines:update()
    bgLines:draw()    
    if state == menu then
        menu()
    end
    if state == GAME_PLAYING then
        -- Process touch
        touch = touchingAtPos()
        if touch then
            if CurrentTouch.x < (hero.position.x) then
                hero.position.x = hero.position.x - 5
            elseif CurrentTouch.x > (hero.position.x) then
                hero.position.x = hero.position.x + 5
            end
            if CurrentTouch.y < (hero.position.y) then
                hero.position.y = hero.position.y - 5 
            elseif CurrentTouch.y > (hero.position.y) then
                hero.position.y = hero.position.y + 5
            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) < 40 then
                state = GAME_DEAD
                explosion = Explosion(hero.position)
                saveLocalData("highscore", highscore)
                if score >= highscore then
                    didGetHighScore = true
                end
            end
        end
    elseif state == GAME_DEAD then
        if explosion then
            explosion:draw()
            if explosion:isDone() then
                explosion = nil
            end
        end
        fontSize(60)
        textMode(CENTER)
        text("GAME OVER",WIDTH/2,HEIGHT/2)
        if didGetHighScore == true then
            fontSize(40)
            text("NEW HIGH SCORE!",WIDTH/2,HEIGHT/2 - 80)
        end
        menu()
    end   
    -- Draw scores
    if difficulty == 3 then
        score = enemies.killCount * 100
    elseif difficulty == 2 then
        score = enemies.killCount * 50
     elseif difficulty == 1 then
        score = enemies.killCount * 25
    end
    fill(255)
    font("Futura-CondensedExtraBold")
    fontSize(30)
    textMode(CORNER)
    text("Score: "..score, 10, HEIGHT - 50)  
    -- update high score
    if score > highscore then
        highscore = score
    end
    hs = "High Score: "..highscore
    hswidth = textSize(hs)
    text(hs, WIDTH - hswidth - 10, HEIGHT - 50)
end

function menu()
    fontSize(20)
    textMode(CENTER)
    text("Double tap screen to play",WIDTH/2,HEIGHT/2-120)
end

function touched(touch)
    if touch.state==BEGAN and touch.tapCount==2 then
        setup()
        state=GAME_PLAYING
    end
end

Here is the second part.


-- part 2 of 2

-----------
--enemyhorde
-----------

ENEMY_SPAWN_EASY = 0
ENEMY_SPAWN_HARD = 1

EnemyHorde = class()

function EnemyHorde:init()
    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
        tint(255, 255, 255, 255)
    else
        tint(223, 138, 142, 255)
    end
    stroke(217, 158, 105, 255)
    strokeWidth(8)
    -- Spawn random enemy every 100 frames
    if self.frame%100 == 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:Enemy Ship D", v.x, v.y, 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
----------

Explosion = class()

function Explosion:init(pos)
    self.position = pos
    self.opacity = 255
    self.time = 0
    self.lines = {}
    sound(SOUND_EXPLODE, 227)
    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 + 0.5
    pushStyle()
    lineCapMode(ROUND)
    strokeWidth(20)
    smooth()
    stroke(255,255,255,math.max(self.opacity,0))
    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--
-----------

Invader= class()

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

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

function Invader:drawBullets()
    -- Spawn bullets
    if difficulty== 1 then
        if self.frame%15 == 0 then
            self:spawnBullet()
        end
    end
    if difficulty== 2 then
        if self.frame%25 == 0 then
            self:spawnBullet()
        end
    end
    if difficulty== 3 then
        if self.frame%50 == 0 then
            self:spawnBullet()
        end
    end
    -- Move, draw, cull bullets
    for i,v in ipairs(self.bullets) do
        v.y = v.y +3
        ellipse(v.x, v.y, 10, 10)
        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(255, 255, 255, 255)
    smooth()
    noFill()
    -- Transform to pos
    translate(self.position.x, self.position.y+50)
    -- Draw our triangle invader
    -- 60 pixels high, 40 pixels wide
    sprite("Tyrian Remastered:Enemy Ship D")
    popMatrix()
    self:drawBullets()
    popStyle()
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 = 3
    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
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()
    pushStyle()
    noSmooth()
    stroke(179, 153, 180, 173)
    strokeWidth(2)
    lineCapMode(SQUARE)
    for i,v in ipairs(self.lines) do
        v:draw()
    end
    popStyle()
end

Thx so much

Did u just do changes to main

I think I made changes in setup(), draw(), and I changed the sprites that were pointing to a sprite in your Documents that I don’t have in mine. I also got rid of the button class and roundrect and a bunch of blank lines. I didn’t really keep track of what I changed so I’m not sure if I listed all of them.

Thanks you’ve helped me a lot I just but in the slider to change ships

Put*

. @Mnjk78lg Glad I could help. If you need anything else, just ask. A suggestion for future posts, you can have more than one line of text per post. Also, if you make a mistake in a post you already sent, you can make a correction to it. I’ve done that many, many times myself. When you look at your post, to the very right of your picture is the word Edit. Just tap Edit and you’ll be able to change or add text. When done, just tap Save Comment in the lower right. Your game is interesting and fun to play. Thanks for sharing it.

Thanks I forgot to do that I’m so used to minecraft editing posts but yea thanks a lot !!!