Skip to content

Instantly share code, notes, and snippets.

@Attila717
Created March 8, 2017 17:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Attila717/f7afe692fa18f27b3712a2c4cbf8a14b to your computer and use it in GitHub Desktop.
Save Attila717/f7afe692fa18f27b3712a2c4cbf8a14b to your computer and use it in GitHub Desktop.
My first Codea game
--# Main
hero = nil
enemies = nil
bgLines = nil
explosion = nil
GAME_PLAYING = 0
GAME_DEAD = 1
GAME_START = 2
function setup()
bgLines = StreamingLines()
difficulty = 0
herodead = false
ship = 0
parameter.integer("ship", 0, 2, 0)
parameter.integer("BackgroundSpawnRate",0,3,2)
-- keep track of our touches in this table
touches = {}
state = GAME_START
MainScreen:init()
AmmoBar:init(700)
Package:init()
displayMode(FULLSCREEN_NO_BUTTONS)
supportedOrientations(CurrentOrientation)
Invader:init()
parameter.boolean("ResetHighscore", false)
hero = Invader()
hero.position = vec2(WIDTH/2, 200)
enemies = EnemyHorde()
enemies.heroBullets = hero.bullets
highscore = readLocalData("highscore")
if not highscore then
highscore = 0
end
end
-- This function gets called whenever a touch
-- begins or changes state
function touched(touch)
if touch.state == ENDED then
if FBP == true then
hero:spawnBullet()
FBP = false
end
if DP1 == true then
DP1 = false
end
if DP2 == true then
DP2 = false
end
if state == GAME_DEAD then
if touch.x > WIDTH/2 - 100 and touch.x < WIDTH/2 + 100 then
if touch.y < HEIGHT/2 + 130 and touch.y > HEIGHT/2 + 30 then
restart()
end
end
end
-- When any touch ends, remove it from
-- our table
touches[touch.id] = nil
else
-- If the touch is in any other state
-- (such as BEGAN) we add it to our
-- table
touches[touch.id] = touch
end
end
function draw()
background(0, 0, 0, 255)
if ResetHighscore == true then
resetHscore()
end
bgLines.spawnRate = BackgroundSpawnRate
bgLines:update()
bgLines:draw()
if state == GAME_START then
MainScreen:draw()
for k,touch in pairs(touches) do
if MainScreenSetMode == true then
if touch.x > WIDTH/2 - 250 and touch.x < WIDTH/2 + 50 then
if touch.y > HEIGHT/2 - 30 and touch.y < HEIGHT/2 + 30 then
MainScreenSetMode = false
MainScreenStart = true
difficulty = 0
end
end
if touch.x > WIDTH/2 - 50 and touch.x < WIDTH/2 + 250 then
if touch.y > HEIGHT/2 - 30 and touch.y < HEIGHT/2 + 30 then
MainScreenSetMode = false
MainScreenStart = true
difficulty = 1
end
end
end
if MainScreenStart == true then
if touch.x > WIDTH/2 - 100 and touch.x < WIDTH/2 + 100 then
if touch.y > HEIGHT/2 - 130 and touch.y < HEIGHT/2 - 30 then
stateChange = 2
state = GAME_PLAYING
end
end
if vec2(touch.x, touch.y):dist(vec2(WIDTH/3 + WIDTH/3, HEIGHT/2 + 250)) < 100 then
ship = 0
end
if vec2(touch.x, touch.y):dist(vec2(WIDTH/2,HEIGHT/2 + 250)) < 100 then
ship = 1
end
if vec2(touch.x, touch.y):dist(vec2(WIDTH/3,HEIGHT/2 + 250)) < 100 then
ship = 2
end
if vec2(touch.x, touch.y):dist(vec2(WIDTH/3,120)) < 100 then
ship = 3
end
if vec2(touch.x, touch.y):dist(vec2(WIDTH/2,120)) < 100 then
ship = 4
end
if vec2(touch.x, touch.y):dist(vec2(WIDTH/3 + WIDTH/3,120)) < 100 then
ship = 5
end
if ship == 0 or ship == 3 then
lives = 1
end
if ship == 1 or ship == 4 then
lives = 2
end
if ship == 2 or ship == 5 then
lives = 3
end
end
end
end
if state == GAME_PLAYING then
if enemies.killCount == 5 then
enemies.spawnPattern = ENEMY_SPAWN_2
end
if enemies.killCount == 20 then
enemies.spawnPattern = ENEMY_SPAWN_3
end
enemies:draw()
hero:draw()
Package:draw()
FB:init(75, HEIGHT/2 - 75, 100, function() hero:spawnBullet() end)
FB:draw()
DPad:init(900, 75, 150, 100)
DPad:draw()
DPad:init(700, 75, 150, 100)
DPad:draw2()
AmmoBar:draw()
for j,touch in pairs(touches) do
if touch.state == BEGAN or touch.state == MOVING then
-- Update button state based on when the touch is inside it
FBP = vec2(touch.x, touch.y):dist(vec2(75,HEIGHT/2 - 75)) < 100
-- Update DPad state based on when the touch is inside it
if touch.x > 825 and touch.x < 975 then
if touch.y < 125 and touch.y > 25 then
DP1 = true
if hero.position.x < WIDTH then
if ship == 0 or ship == 3 then
hero.position.x = hero.position.x + 9
end
if ship == 1 or ship == 4 then
hero.position.x = hero.position.x + 6
end
if ship == 2 or ship == 5 then
hero.position.x = hero.position.x + 3
end
end
end
end
if touch.x > 625 and touch.x < 775 then
if touch.y < 125 and touch.y > 25 then
DP2 = true
if hero.position.x > 1 then
if ship == 0 or ship == 3 then
hero.position.x = hero.position.x - 9
end
if ship == 1 or ship == 4 then
hero.position.x = hero.position.x - 6
end
if ship == 2 or ship == 5 then
hero.position.x = hero.position.x - 3
end
end
else
DP2 = false
end
else
DP2 = false
end
end
end
-- Check if hero is hit
for i,v in ipairs(enemies.units) do
if v:dist(hero.position) < 40 then
if shield == false then
if lives == 1 then
herodead = true
state = GAME_DEAD
explosion = Explosion(hero.position)
saveLocalData("highscore", highscore)
if score >= highscore then
didGetHighScore = true
end
end
if lives == 2 or lives == 3 then
lives = lives - 1
end
end
if shield == true then
table.remove(enemies.units, i)
sound("Game Sounds One:Block 3")
shield = false
end
end
end
end
if 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)
fontSize(40)
fill(0, 10, 255, 255)
text("Restart", WIDTH/2, HEIGHT/2 + 80)
text("Quit", WIDTH/2, HEIGHT/2 - 120)
if didGetHighScore == true then
fontSize(40)
text("NEW HIGH SCORE!",WIDTH/2,HEIGHT/2 - 80)
end
for p,touch in pairs(touches) do
if touch.x > WIDTH/2 - 100 and touch.x < WIDTH/2 + 100 then
if touch.y < HEIGHT/2 - 70 and touch.y > HEIGHT/2 - 170 then
close()
end
end
end
end
-- Draw scores
if difficulty == 0 then
score = enemies.killCount * 100
end
if difficulty == 1 then
score = enemies.killCount * 150
end
fill(255)
font("Copperplate")
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
--# Multiplayer
Multiplayer = class()
function Multiplayer:init(x)
end
function Multiplayer:draw()
end
function Multiplayer:touched(touch)
end
--# AmmoBar
AmmoBar = class()
function AmmoBar:init()
-- you can accept and set parameters here
if ship == 0 or ship == 3 then
shotsLeft = 0
end
if ship == 1 or ship == 4 then
shotsLeft = 0
end
if ship == 2 or ship == 5 then
shotsLeft = 0
end
self.y2 = 700
end
function AmmoBar:draw()
noStroke()
rectMode(CORNERS)
fill(111, 111, 111, 255)
AmmoBar:bar()
rect(945, 495, 1005, 705)
fill(20, 182, 25, 255)
rect(950, 500, 1000, self.y2)
end
function AmmoBar:bar()
if ship == 0 or ship == 3 then
if shotsLeft == 10 then
self.y2 = 700
end
if shotsLeft == 8 then
self.y2 = 660
end
if shotsLeft == 6 then
self.y2 = 620
end
if shotsLeft == 4 then
self.y2 = 580
end
if shotsLeft == 2 then
self.y2 = 540
end
if shotsLeft == 0 then
self.y2 = 500
end
end
if ship == 1 or ship == 4 then
if shotsLeft == 15 then
self.y2 = 700
end
if shotsLeft == 12 then
self.y2 = 660
end
if shotsLeft == 9 then
self.y2 = 620
end
if shotsLeft == 6 then
self.y2 = 580
end
if shotsLeft == 3 then
self.y2 = 540
end
if shotsLeft == 0 then
self.y2 = 500
end
end
if ship == 2 or ship == 5 then
if shotsLeft == 20 then
self.y2 = 700
end
if shotsLeft == 16 then
self.y2 = 660
end
if shotsLeft == 12 then
self.y2 = 620
end
if shotsLeft == 8 then
self.y2 = 580
end
if shotsLeft == 4 then
self.y2 = 540
end
if shotsLeft == 0 then
self.y2 = 500
end
end
end
function AmmoBar:touched(touch)
-- Codea does not automatically call this method
end
--# EnemyHorde
ENEMY_SPAWN_1 = 0
ENEMY_SPAWN_2 = 1
ENEMY_SPAWN_3 = 2
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_1
hardmodes = true
hardmodess = true
end
function EnemyHorde:draw()
self.frame = (self.frame+1)%128
pushStyle()
if self.spawnPattern == ENEMY_SPAWN_1 then
tint(255, 255, 255, 255)
end
stroke(217, 158, 105, 255)
strokeWidth(8)
-- Spawn random enemy every 100 frames
if difficulty == 0 then
if self.frame%100 == 0 then
spawn = vec2( math.random(WIDTH), HEIGHT + self.enemySize )
table.insert( self.units, spawn )
end
end
if difficulty == 1 then
if self.frame%25 == 0 then
spawn = vec2( math.random(WIDTH), HEIGHT + self.enemySize )
table.insert( self.units, spawn )
end
end
for i,v in ipairs(self.units) do
-- Move unit down
if difficulty == 0 then
v.y = v.y - 5
end
if difficulty == 1 then
v.y = v.y - 7
end
-- If hard, move in sine wave
if self.spawnPattern == ENEMY_SPAWN_2 then
-- Compute movement vector
if hardmodes == true then
textMode(CENTER)
fill(255, 0, 0, 255)
fontSize(60)
text("Hard Mode Activated", WIDTH/2, HEIGHT/2)
if self.frame%250 == 0 then
hardmodes = false
end
end
sideMove = vec2( math.sin(v.y * 0.02) * 60, 0 )
v = v + sideMove
end
if self.spawnPattern == ENEMY_SPAWN_3 then
if hardmodess == true then
textMode(CENTER)
fill(255, 0, 0, 255)
fontSize(60)
text("Harder Mode Activated", WIDTH/2, HEIGHT/2)
if self.frame%250 == 0 then
hardmodess = false
end
end
sideMove = vec2( 2 * math.cos(v.y * 0.03) * 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
if self.spawnPattern == 0 then
sprite("Space Art:UFO", v.x, v.y, self.enemySize)
end
if self.spawnPattern == 1 then
sprite("Space Art:Part Red Hull 3", v.x, v.y, self.enemySize)
end
if self.spawnPattern == 2 then
sprite("Space Art:Part Gray Hull 5", v.x, v.y, self.enemySize)
end
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
--# Invader
Invader = class()
function Invader:init()
self.position = vec2(0,0)
self.bullets = {}
self.frame = 0
end
function Invader:spawnBullet()
if shotsLeft >= 1 then
sound("Game Sounds One:Zapper 1", 18)
table.insert( self.bullets, vec2( self.position.x, self.position.y + 50 ) )
shotsLeft = shotsLeft - 1
self.frame = 0
end
end
function Invader:drawBullets()
-- Spawn bullets
if ship == 0 or ship == 3 then
if self.frame%75 == 0 then
if shotsLeft <= 9 then
shotsLeft = shotsLeft + 1
end
end
end
if ship == 1 or ship == 4 then
if self.frame%65 == 0 then
if shotsLeft <= 14 then
shotsLeft = shotsLeft + 1
end
end
end
if ship == 2 or ship == 5 then
if self.frame%25 == 0 then
if shotsLeft <= 19 then
shotsLeft = shotsLeft + 1
end
end
end
-- Move, draw, cull bullets
for i,v in ipairs(self.bullets) do
v.y = v.y + 6
--ellipse(v.x, v.y, 10, 10)
sprite("Space Art:Green Bullet", v.x, v.y)
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)
scale(2.0)
if ship == 0 then
sprite("Documents:RedShip1")
end
if ship == 1 then
sprite("Documents:RedShip2")
end
if ship == 2 then
sprite("Documents:RedShip3")
end
if ship == 3 then
sprite("Documents:BlueShip1")
end
if ship == 4 then
sprite("Documents:BlueShip2")
end
if ship == 5 then
sprite("Documents:BlueShip3")
end
if shield == true then
sprite("Documents:Shield")
end
popMatrix()
self:drawBullets()
popStyle()
end
function Invader:touched(touch)
-- Codea currently does not automatically call this method
end
--# Package
Package = class()
function Package:init()
self.frame = 0
self.units = {}
self.packageSize = 50
shield = false
end
function Package:draw()
-- Codea does not automatically call this method
self.frame = (self.frame+1)%128
if difficulty == 0 then
if self.frame%2000001 == 0 then
randnum1 = math.random(1, 10)
if randnum1 == 3 then
spawns = vec2( math.random(WIDTH), HEIGHT + self.packageSize )
table.insert( self.units, spawns )
end
end
end
if difficulty == 1 then
if self.frame%1000001 == 0 then
randnum2 = math.random(1, 10)
if randnum2 == 3 then
spawns = vec2( math.random(WIDTH), HEIGHT + self.packageSize )
table.insert( self.units, spawns )
end
end
end
for i,v in ipairs(self.units) do
-- Move unit down
if difficulty == 0 then
v.y = v.y - 5
end
if difficulty == 1 then
v.y = v.y - 7
end
isculled = false
if (v.y + self.packageSize) < 0 then
table.remove(self.units, i)
isculled = true -- no continue statement
end
if v:dist(hero.position) < self.packageSize/2 then
table.remove(self.units, i)
shield = true
end
-- Draw unit
sprite("Documents:ShieldPack", v.x, v.y, self.packageSize)
end
end
function Package:touched(touch)
-- Codea does not automatically call this method
end
--# FB
FB = class()
function FB:init(x,y,r,action)
self.x = x
self.y = y
self.r = r
self.action = action
self.pressed = false
end
function FB:draw()
pushMatrix()
translate(self.x, self.y)
pushStyle()
noStroke()
fill(202, 170, 164, 255)
ellipseMode(CENTER)
ellipse(0,0, self.r)
fill(94, 36, 36, 255)
ellipse(0,0,self.r * 0.8)
fill(255, 0, 0, 255)
-- Adjust button appearance when being pressed
if FBP then
ellipse(0,0,self.r * 0.8)
else
ellipse(0,self.r*0.05,self.r * 0.8)
end
popStyle()
popMatrix()
end
--# DPad
DPad = class()
function DPad:init(x,y,w,h,action)
self.x = x
self.y = y
self.w = w
self.h = h
self.action = action
self.pressed = false
end
function DPad:draw()
pushMatrix()
translate(self.x, self.y)
pushStyle()
noStroke()
fill(202, 170, 164, 255)
rectMode(CENTER)
rect(0,0, self.w, self.h)
fill(94, 36, 36, 255)
rect(0,0,self.w * 0.8, self.h * 0.8)
fill(255, 0, 0, 255)
-- Adjust button appearance when being pressed
if DP1 then
rect(0,0,self.w * 0.8, self.h * 0.8)
else
rect(0,self.w*0.05,self.w * 0.8, self.h * 0.8)
end
popStyle()
popMatrix()
end
function DPad:draw2()
pushMatrix()
translate(self.x, self.y)
pushStyle()
noStroke()
fill(202, 170, 164, 255)
rectMode(CENTER)
rect(0,0, self.w, self.h)
fill(94, 36, 36, 255)
rect(0,0,self.w * 0.8, self.h * 0.8)
fill(255, 0, 0, 255)
-- Adjust button appearance when being pressed
if DP2 then
rect(0,0,self.w * 0.8, self.h * 0.8)
else
rect(0,self.w*0.05,self.w * 0.8, self.h * 0.8)
end
popStyle()
popMatrix()
end
function DPad:touched(touch)
-- Codea does not automatically call this method
end
--# Explosion
Explosion = class()
function Explosion:init(pos)
self.position = pos
self.opacity = 255
self.time = 0
self.lines = {}
if herodead == true then
sound("Game Sounds One:Explode 1", 967)
else
sound("explode",967)
end
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
--# MainScreen
MainScreen = class()
function MainScreen:init()
-- you can accept and set parameters here
MainScreenSetMode = true
MainScreenStart = false
end
function MainScreen:draw()
background(0, 0, 0, 255)
if MainScreenSetMode == true then
fill(0, 11, 255, 255)
textMode(CENTER)
fontSize(80)
font("Copperplate")
text("Mode:", WIDTH/2, HEIGHT/2 + 200)
fill(255, 255, 255, 255)
fontSize(50)
text("Easy", WIDTH/2 - 150, HEIGHT/2)
text("Hard", WIDTH/2 + 150, HEIGHT/2)
fontSize(80)
end
if MainScreenStart == true then
textMode(CENTER)
fontSize(90)
fill(0, 11, 255, 255)
font("Copperplate")
text("UNIVERSA",WIDTH/2,HEIGHT/2)
fill(255, 255, 255, 255)
if stateChange == 2 then
fill(255, 19, 0, 255)
end
fontSize(50)
text("Start", WIDTH/2, HEIGHT/2 - 80)
spriteMode(CENTER)
sprite("Documents:RedShip3", WIDTH/3, HEIGHT/2 + 250, 100)
sprite("Documents:RedShip2", WIDTH/2, HEIGHT/2 + 250, 100)
sprite("Documents:RedShip1", WIDTH/3 + WIDTH/3, HEIGHT/2 + 250, 100)
sprite("Documents:BlueShip1", WIDTH/3, 120, 100)
sprite("Documents:BlueShip2", WIDTH/2, 120, 100)
sprite("Documents:BlueShip3", WIDTH/3 + WIDTH/3, 120, 100)
fill(255, 141, 0, 255)
stroke(0, 11, 255, 255)
strokeWidth(8)
if ship == 0 then
--bottom left to bottom right
line(WIDTH/3 + WIDTH/3 - 60, HEIGHT/2 + 190, WIDTH/3 + WIDTH/3 + 60, HEIGHT/2 + 190)
--bottom left to top left
line(WIDTH/3 + WIDTH/3 - 60, HEIGHT/2 + 190, WIDTH/3 + WIDTH/3 - 60, HEIGHT/2 + 310)
--top left to top right
line(WIDTH/3 + WIDTH/3 - 60, HEIGHT/2 + 310, WIDTH/3 + WIDTH/3 + 60, HEIGHT/2 + 310)
--bottom right to top right
line(WIDTH/3 + WIDTH/3 + 60, HEIGHT/2 + 190, WIDTH/3 + WIDTH/3 + 60, HEIGHT/2 + 310)
end
if ship == 1 then
--bottom left to bottom right
line(WIDTH/2 - 60, HEIGHT/2 + 190, WIDTH/2 + 60, HEIGHT/2 + 190)
--bottom left to top left
line(WIDTH/2 - 60, HEIGHT/2 + 190, WIDTH/2 - 60, HEIGHT/2 + 310)
--top left to top right
line(WIDTH/2 - 60, HEIGHT/2 + 310, WIDTH/2 + 60, HEIGHT/2 + 310)
--bottom right to top right
line(WIDTH/2 + 60, HEIGHT/2 + 190, WIDTH/2 + 60, HEIGHT/2 + 310)
end
if ship == 2 then
--bottom left to bottom right
line(WIDTH/3 - 60, HEIGHT/2 + 190, WIDTH/3 + 60, HEIGHT/2 + 190)
--bottom left to top left
line(WIDTH/3 - 60, HEIGHT/2 + 190, WIDTH/3 - 60, HEIGHT/2 + 310)
--top left to top right
line(WIDTH/3 - 60, HEIGHT/2 + 310, WIDTH/3 + 60, HEIGHT/2 + 310)
--bottom right to top right
line(WIDTH/3 + 60, HEIGHT/2 + 190, WIDTH/3 + 60, HEIGHT/2 + 310)
end
if ship == 3 then
--bottom left to bottom right
line(WIDTH/3 - 60, 60, WIDTH/3 + 60, 60)
--bottom left to top left
line(WIDTH/3 - 60, 60, WIDTH/3 - 60, 180)
--top left to top right
line(WIDTH/3 - 60, 180, WIDTH/3 + 60, 180)
--bottom right to top right
line(WIDTH/3 + 60, 60, WIDTH/3 + 60, 180)
end
if ship == 4 then
--bottom left to bottom right
line(WIDTH/2 - 60, 60, WIDTH/2 + 60, 60)
--bottom left to top left
line(WIDTH/2 - 60, 60, WIDTH/2 - 60, 180)
--top left to top right
line(WIDTH/2 - 60, 180, WIDTH/2 + 60, 180)
--bottom right to top right
line(WIDTH/2 + 60, 60, WIDTH/2 + 60, 180)
end
if ship == 5 then
--bottom left to bottom right
line(WIDTH/3 + WIDTH/3 - 60, 60, WIDTH/3 + WIDTH/3 + 60, 60)
--bottom left to top left
line(WIDTH/3 + WIDTH/3 - 60, 60, WIDTH/3 + WIDTH/3 - 60, 180)
--top left to top right
line(WIDTH/3 + WIDTH/3 - 60, 180, WIDTH/3 + WIDTH/3 + 60, 180)
--bottom right to top right
line(WIDTH/3 + WIDTH/3 + 60, 60, WIDTH/3 + WIDTH/3 + 60, 180)
end
end
end
function MainScreen:touched(touch)
-- Codea does not automatically call this method
end
--# StreamingLines
-- 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(179, 153, 180, 173)
strokeWidth(2)
lineCapMode(SQUARE)
for i,v in ipairs(self.lines) do
v:draw()
end
popStyle()
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment