Created
March 8, 2017 17:53
-
-
Save Attila717/f7afe692fa18f27b3712a2c4cbf8a14b to your computer and use it in GitHub Desktop.
My first Codea game
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--# 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