Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --# Main
- hero = nil
- enemies = nil
- bgLines = nil
- explosion = nil
- GAME_PLAYING = 1
- GAME_PAUSE = 2
- GAME_DEAD = 0
- state = GAME_PLAYING
- right = 1
- straight = 2
- left = 3
- heroState = straight
- supportedOrientations(LANDSCAPE_ANY,PORTRAIT_ANY)
- -- Use this function to perform your initial setup
- function setup()
- state = GAME_PLAYING
- displayMode(FULLSCREEN)
- supportedOrientations(CurrentOrientation)
- BackgroundSpawnRate = 3
- w = WIDTH
- h = HEIGHT
- pc = color(127, 127, 127, 255)
- npc = color(255, 255, 255, 255)
- t = "Tyrian Remastered:Pause Circle"
- pauseButton = button("pause",20,h - 70,70,h - 20,pc,npc,t)
- t = "Tyrian Remastered:Arrow Left"
- leftButton = button("left",20,50,100,100,pc,npc,t)
- t = "Tyrian Remastered:Arrow Right"
- rightButton = button("right",150,50,230,100,pc,npc,t)
- t = "Tyrian Remastered:Icon Ship Shoot"
- shootButton = button("shoot",w - 120,50,w - 50,120,pc,npc,t)
- buttons = {pauseButton,leftButton,rightButton,shootButton}
- hero = Invader()
- hero.position = vec2(WIDTH/2, 180)
- 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()
- background(0, 0, 0, 255)
- pushStyle()
- for b = 1,#buttons do
- buttons[b]:touched()
- buttons[b]:draw()
- end
- popStyle()
- bgLines.spawnRate = BackgroundSpawnRate
- bgLines:update()
- bgLines:draw()
- if state == GAME_PLAYING then
- -- steer the hero
- local ls = leftButton:getInfo()[2]
- local rs = rightButton:getInfo()[2]
- if ls == 1 or ls == 2 then
- hero.position.x = hero.position.x - 5
- heroState = left
- elseif rs == 1 or rs == 2 then
- hero.position.x = hero.position.x + 5
- heroState = right
- else
- heroState = straight
- end
- if enemies.killCount == 5 then
- enemies.spawnPattern = ENEMY_SPAWN_HARD
- elseif enemies.killCount == 15 then
- enemies.spawnPattern = ENEMY_SPAWN_DEADLY
- end
- enemies:draw()
- hero:draw()
- -- Check if hero is hit
- for i,v in ipairs(enemies.units) do
- if v:dist(hero.position) < 60 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
- end
- -- setting text mode
- fill(255)
- font("Futura-CondensedExtraBold")
- fontSize(30)
- textMode(CORNER)
- -- update high score
- score = enemies.killCount * 100
- if score > highscore then
- highscore = score
- end
- hs = "High Score: "..highscore
- hswidth = textSize(hs)
- text(hs, WIDTH - hswidth - 10, HEIGHT - 50)
- -- Draw scores
- s = "Score: "..score
- swidth = textSize(s)
- text(s, WIDTH - hswidth - 50 - swidth, HEIGHT - 50)
- end
- --# EnemyHorde
- ENEMY_SPAWN_EASY = 0
- ENEMY_SPAWN_HARD = 1
- ENEMY_SPAWN_DEADLY = 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 = 60
- self.killCount = 0
- self.spawnPattern = ENEMY_SPAWN_EASY
- end
- function EnemyHorde:draw()
- self.frame = (self.frame+1)%128
- pushStyle()
- 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
- elseif self.spawnPattern == ENEMY_SPAWN_DEADLY then
- -- Compute movement vector
- sideMove = vec2( math.sin(v.y * 0.02) * 100, 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 == ENEMY_SPAWN_EASY then
- sprite("Tyrian Remastered:Enemy Ship C 3", v.x, v.y, self.enemySize)
- elseif self.spawnPattern == ENEMY_SPAWN_HARD then
- sprite("Tyrian Remastered:Enemy Ship C 2", v.x, v.y, self.enemySize)
- elseif self.spawnPattern == ENEMY_SPAWN_DEADLY then
- sprite("Tyrian Remastered:Enemy Ship C 1", 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
- self.size = 65
- self.texture = "Tyrian Remastered:Ship B"
- 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
- local ss = shootButton:getInfo()[2]
- if ss == 1 or ss == 2 then
- if self.frame%30 == 0 then
- self:spawnBullet()
- end
- end
- -- Move, draw, cull bullets
- for i,v in ipairs(self.bullets) do
- v.y = v.y + 3
- sprite("Tyrian Remastered:Bullet Fire C",v.x, v.y,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
- smooth()
- -- Transform to pos
- translate(self.position.x, self.position.y)
- -- Set the texture
- if heroState == left then
- self.texture = "Tyrian Remastered:Ship B L1"
- elseif heroState == straight then
- self.texture = "Tyrian Remastered:Ship B"
- elseif heroState == right then
- self.texture = "Tyrian Remastered:Ship B R1"
- end
- -- Draw our invader
- sprite(self.texture,0,0,self.size)
- popMatrix()
- self:drawBullets()
- popStyle()
- end
- function Invader:touched(touch)
- -- Codea currently does not automatically call this method
- end
- --# Background
- -- 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
- --# Other_Stuff
- -------------------|
- button = class() --|
- -------------------|
- -- by max tamussino
- -- contact: max@visuals.at
- function button:init(title,x1,y1,x2,y2,colorPressed,colorNotPressed,image1,image2)
- -- this button class makes it easier to create buttons. the best thing is: it keeps
- -- the touched function short ;)
- -- so here is how to use it:
- -- - the title the title should be a string, and should represent the function of the button,
- -- like: "closeButton"
- -- - x1,y1,x2,y2 are the coordinates
- -- - good to know: the button can either be a rect or a sprite (in spritely or not).
- -- 1) For the rect:
- -- - colorPressed: the color the rect is filled with when the button is pressed.
- -- - colorNotPressed: the color the rect is filled with when the button is not pressed.
- -- - image1: must be set to ""rect"" (string!!).
- -- - image2: must be nil.
- -- - coordinates: for rectMode(CORNERS)
- -- 2) For the sprite:
- -- Two possibilities:
- -- a) changing image:
- -- - this possibility changes the normal image (image1) to image2 if
- -- the button is touched.
- -- - colorPressed and colorNotPressed both must be nil.
- -- - image1: normal image
- -- - image2: displayed instead of the normal one when touched.
- -- b) changing tint:
- -- - this possibility changes the fill color of the sprite if the 1
- -- button is touched
- -- - colorPressed: the tint() if the button is not touched
- -- - colorNotPressed: the tint() if the button is touched
- -- - image2: must be nil
- --
- --
- -- the button:getInfo() function returns a table with the title ( [1] )and the state( [2] ).
- -- to use this, you can can keep track of your buttonstates like this:
- --
- --
- --
- --
- -- if button:getInfo()[2] == 3 then
- -- if button:getInfo()[1] == "closeButton" then
- -- close()
- -- elseif button:getInfo()[1] == "openMenuButton" then
- -- if not menuShown then
- -- menuShown = true
- -- else
- -- menuShown = false
- -- end
- -- elseif button:getInfo()[1] == "showHelpScreenButton" then
- -- if not helpScreenShown then
- -- helpScreenShown = true
- -- else
- -- helpScreenShown = false
- -- end
- -- end
- -- end
- --
- -- i hope it helps you guys! have fun creating buttons! :)
- self.title = title
- self.x1 = x1
- self.y1 = y1
- self.x2 = x2
- self.y2 = y2
- self.cp = colorPressed
- self.cnp = colorNotPressed
- self.image1 = image1
- if not self.cp then
- if not self.cnp then
- self.image2 = image2
- end
- end
- self.pressed = false
- rectMode(CORNERS)
- end
- function button:draw()
- spriteMode(CORNERS)
- if self.state == 1 or self.state == 2 then
- self.pressed = true
- else
- self.pressed = false
- end
- if self.image1 == "rect" then
- if self.pressed then
- fill(self.cp)
- rect(self.x1 - 1,self.y1 - 1,self.x2 - 1,self.y2 - 1)
- else
- fill(self.cnp)
- rect(self.x1,self.y1,self.x2,self.y2)
- end
- elseif self.image2 then
- if self.pressed then
- sprite(self.image2,self.x1 - 2,self.y1 - 2,self.x2 - 2,self.y2 - 2)
- else
- sprite(self.image1,self.x1,self.y1,self.x2,self.y2)
- end
- else
- if self.pressed then
- tint(self.cp)
- sprite(self.image1,self.x1 - 2,self.y1 - 2,self.x2 - 2,self.y2 - 2)
- else
- tint(self.cnp)
- sprite(self.image1,self.x1,self.y1,self.x2,self.y2)
- end
- end
- if self.state == 3 then
- if ElapsedTime > endTime + 0.01 then
- self.state = 0
- end
- end
- end
- function button:touched()
- t = CurrentTouch
- if t.x > self.x1 and t.y > self.y1 and t.x < self.x2 and t.y < self.y2 then
- if t.state == BEGAN then
- self.state = 1
- touching = true
- elseif t.state == MOVING then
- self.state = 2
- elseif t.state == ENDED then
- if touching then
- self.state = 3
- end
- touching = false
- endTime = ElapsedTime
- end
- else
- self.state = 0
- end
- end
- function button:getInfo()
- return {self.title, self.state}
- end
- -----------------------|
- Explosion = class() --|
- -----------------------|
- function Explosion:init(pos)
- self.position = pos
- self.opacity = 255
- self.time = 0
- self.lines = {}
- sound("explode",967)
- 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
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement