Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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

This comment has been minimized.

Copy link
Owner Author

mieki256 commented Nov 16, 2018

sprites.gif

sprites

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.