Skip to content

Instantly share code, notes, and snippets.

@mieki256
Created November 16, 2018 14:02
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 mieki256/f6b8ea8a935c21d0b6a19ab22b31b7ae to your computer and use it in GitHub Desktop.
Save mieki256/f6b8ea8a935c21d0b6a19ab22b31b7ae to your computer and use it in GitHub Desktop.
TIC-80 shoot 'em up sample
-- title: stg sample 5
-- author: mieki256
-- desc: short description
-- script: lua
scrw,scrh=240,136
-- --------------------
-- Player class
Player={}
Player.new=function()
local o={
alive=true,step=0,
x=scrw/5,y=scrh/2,
sprid=5,t=0,
life=5,dead=false,nodamage=0,
shott=0
}
o.collision={o.x,o.y,1},
setmetatable(o,{__index=Player})
return o
end
Player.update=function(self)
if self.step ==0 then
if self.nodamage > 0 then
self.nodamage=self.nodamage-1
end
if self.dead then
self.step=1
self.t=0
self.sprid=32
if self.life > 0 then
self.life=self.life-1
end
else
local spd=2.0
local dx,dy=0,0
if btn(0) then dy=-spd end
if btn(1) then dy=spd end
if btn(2) then dx=-spd end
if btn(3) then dx=spd end
if dx~=0 and dy~=0 then
local d=math.cos(math.rad(45))
dx=dx*d
dy=dy*d
end
self.x=self.x+dx
self.y=self.y+dy
self.x=math.min(math.max(self.x,8),scrw-8)
self.y=math.min(math.max(self.y,8),scrh-8)
self.collision[1]=self.x
self.collision[2]=self.y
-- shot
if btnp(4) then self.shott=0 end
if btn(4) and self.shott%7==0 then
local x,y=self.x,self.y
spd=6
table.insert(bullets,Bullet.new(x+10,y,spd,0))
-- table.insert(bullets,Bullet.new(x,y,spd,12))
-- table.insert(bullets,Bullet.new(x,y,spd,-12))
-- table.insert(bullets,Bullet.new(x,y,spd,180))
end
end
elseif self.step==1 then
self.sprid=32+2*(self.t % 16 // 8)
if self.t>=90 then
self.dead=false
self.step=0
self.nodamage=180
self.sprid=5
end
end
self.shott=self.shott+1
self.t=self.t+1
end
Player.draw=function(self)
if self.step==0 then
if self.nodamage>0 and
(self.nodamage>>2)%2==0 then
return
end
end
spr(self.sprid,self.x-8,self.y-8,
14,1,0,0,2,2)
end
Player.hit=function(self,o)
if self.nodamage<=0 then
self.dead=true
end
end
Player.shot=function(self,o)
end
-- --------------------
-- Bullet class
Bullet={}
Bullet.new=function(_x,_y,_spd,_ang)
local ra=math.rad(_ang)
local o={
alive=true,
x=_x,y=_y,spd=_spd,ang=_ang,
dx=_spd*math.cos(ra),
dy=_spd*math.sin(ra),
collision={_x,_y,5},sprid=7
}
setmetatable(o,{__index=Bullet})
return o
end
Bullet.update=function(self)
self.x=self.x+self.dx
self.y=self.y+self.dy
self.collision[1]=self.x
self.collision[2]=self.y
if self.x<-4 or self.x>scrw+4 or
self.y<-4 or self.y>scrh+4 then
self.alive=false
end
end
Bullet.draw=function(self)
spr(self.sprid,self.x-4,self.y-4,
0,1,0,0,1,1)
end
Bullet.hit=function(self,o)
end
Bullet.shot=function(self,o)
self.alive=false
self.collision={}
end
-- --------------------
-- Enemy Bullet class
Ebullet={}
Ebullet.new=function(_x,_y,_spd,_ang)
local ra=math.rad(_ang)
local o={
alive=true,
x=_x,y=_y,spd=_spd,ang=_ang,
dx=_spd*math.cos(ra),
dy=_spd*math.sin(ra),
collision={_x,_y,1},sprid=14,t=0
}
setmetatable(o,{__index=Ebullet})
return o
end
Ebullet.update=function(self)
self.x=self.x+self.dx
self.y=self.y+self.dy
self.collision[1]=self.x
self.collision[2]=self.y
self.sprid=14+(self.t%10//5)
if self.x<-4 or self.x>scrw+4 or
self.y<-4 or self.y>scrh+4 then
self.alive=false
end
self.t=self.t+1
end
Ebullet.draw=function(self)
spr(self.sprid,self.x-4,self.y-4,
0,1,0,0,1,1)
end
Ebullet.hit=function(self,o)
end
Ebullet.shot=function(self,o)
self.alive=false
self.collision={}
end
function bornEnemyBulletToPlayer(x,y,spd,d)
local dx,dy
dx=player.x-x
dy=player.y-y
if dx*dx+dy*dy>d*d then
local ang=math.deg(math.atan2(dy,dx))
table.insert(ebullets,
Ebullet.new(x,y,spd,ang))
end
end
-- --------------------
-- Zako enemy class
Zako={}
Zako.new=function(_x,_y,_spd,_ang)
local ra=math.rad(_ang)
local o={
alive=true,
x=_x,y=_y,spd=_spd,ang=_ang,
dx=_spd*math.cos(ra),
dy=_spd*math.sin(ra),
sprid=1,t=0,collision={_x,_y,6},
shotwait=math.random(50,90)
}
setmetatable(o,{__index=Zako})
return o
end
Zako.update=function(self)
self.x=self.x+self.dx
self.y=self.y+self.dy
self.collision[1]=self.x
self.collision[2]=self.y
if self.x<-32 or self.x>scrw+32 or
self.y<-32 or self.y>scrh+32 then
self.alive=false
elseif self.shotwait <=0 then
self.shotwait=90
bornEnemyBulletToPlayer(self.x,self.y,1,80)
end
self.shotwait=self.shotwait-1
self.t=self.t+1
end
Zako.draw=function(self)
spr(self.sprid,self.x-8,self.y-8,
14,1,0,0,2,2)
end
Zako.hit=function(self,o)
self.alive=false
self.collision={}
score=score+10
bornExplo(self.x,self.y)
end
Zako.shot=function(self,o)
end
-- --------------------
-- Explosion effect class
Explosion={}
Explosion.new=function(_x,_y)
local o={
alive=true,x=_x,y=_y,t=0,
cols={15,15,9,6,0},r=20
}
setmetatable(o,{__index=Explosion})
return o
end
Explosion.update=function(self)
self.r=self.r-1
if self.r<3 then self.alive=false end
self.t=self.t+1
end
Explosion.draw=function(self)
local x,y,r,c,rr
rr=6
c=self.cols[(self.t-1)%(#self.cols)+1]
for i=1,3 do
x=self.x+math.random(-rr,rr)
y=self.y+math.random(-rr,rr)
r=math.max(2,self.r / i)
circ(x,y,r,c)
end
end
function bornExplo(_x,_y)
local o=Explosion.new(_x,_y)
table.insert(explosions,o)
end
-- --------------------
function objsUpdate(objs)
for i,o in ipairs(objs) do
o:update()
end
end
function objsDraw(objs)
for i,o in ipairs(objs) do
o:draw()
end
end
function objsRemove(objs)
local l=#objs
for i=l,1,-1 do
if not objs[i].alive then
table.remove(objs,i)
end
end
end
function bornEnemys()
if t % 25==0 then
local spd,ang,x,y
spd=1.5
x=scrw+16
y=((scrh-8)/2)*math.sin(math.rad(t%360))+(scrh/2)
ang=180+20*((y-(scrh/2))/(scrh/2))+math.random(-20,20)
table.insert(enemys,Zako.new(x,y,spd,ang))
end
end
function hitcheckCirc(e,b)
if not next(b.collision) then
return false
end
local x,y,r
x=e.collision[1]-b.collision[1]
y=e.collision[2]-b.collision[2]
r=e.collision[3]+b.collision[3]
if x*x+y*y <=r*r then return true end
return false
end
function hitcheck()
-- enemys vs bullet
for i,e in ipairs(enemys) do
if e.alive and next(e.collision) then
for j,b in ipairs(bullets) do
if b.alive and hitcheckCirc(e,b) then
e:hit(b)
b:shot(e)
break
end
end
end
end
if player.alive==false or
not next(player.collision) then
return
end
-- enemys vs player
for i,e in ipairs(enemys) do
if e.alive and hitcheckCirc(player,e) then
player:hit(e)
return
end
end
-- enemy bullets vs player
for i,b in ipairs(ebullets) do
if b.alive and hitcheckCirc(player,b) then
player:hit(b)
break
end
end
end
-- init
score=0
t=0
player=Player.new()
bullets={}
enemys={}
ebullets={}
explosions={}
-- main loop
function TIC()
-- update
bornEnemys()
hitcheck()
objsUpdate(bullets)
objsUpdate(enemys)
objsUpdate(ebullets)
objsUpdate(explosions)
player:update()
objsRemove(bullets)
objsRemove(enemys)
objsRemove(ebullets)
objsRemove(explosions)
-- draw
cls(0)
objsDraw(explosions)
objsDraw(bullets)
objsDraw(enemys)
objsDraw(ebullets)
player:draw()
local s="LIFE: "..player.life
s=s.." SCORE: "..score
s=s.." enemys: "..#enemys
print(s,2,2)
t=t+1
end
@mieki256
Copy link
Author

sprites.gif

sprites

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment