Merry Christmas and welcome to the 1K Asteroids Challenge.
This time we're making a clone of the arcade classic Asteroids.
The more authentic and fun, the better.
Guidelines:
- the entire game must be contained in a single Lua file (1024 bytes or less)
- external assets (images, sounds, fonts) are not allowed
- asteroids, the player ship and bullets should wrap around the screen
- the gameplay must reset when you destroy all the asteroids or when you die
- bullets should have a limited range/lifetime
- the ship speed should not exceed that of the bullets
Extra credit:
- delta
- explosion effects
- score
- difficulty (asteroids should get bigger/break apart as you progress)
- different "models" for the asteroids
- sound effects
1K Asteroids Challenge
1K Asteroids Challenge
Last edited by ivan on Mon Dec 26, 2016 5:28 am, edited 6 times in total.
Re: 1K Asteroids Challenge
This was fun and it didn't take very long. It could be much more compact but I went a little overboard with the polygon generation. Also, I changed the controls a little bit, since in the original Asteroids the rotation of the ship is independent of its velocity. I think it's more fun this way.
Minified (1,004 bytes):
Non-minified (for the curious):
Controls: WASD and Space bar
Minified (1,004 bytes):
Code: Select all
L=love;D=L.keyboard.isDown;G=L.graphics;W,H=G.getDimensions()M=math;N=M.random;function L.load()S={8,0,-8,4,-8,-4,8,0,x=W/2,y=H/2,a=0,v=0}R={S}E=32;for d=1,E do b={x=N(W),y=N(H),a=N()*M.pi*2,v=N(64),e=1}for e=0,6 do c=N(8,16)a=e/6*M.pi*2;b[e*2+1]=M.cos(a)*c;b[e*2+2]=M.sin(a)*c end;b[15]=b[1]b[16]=b[2]R[#R+1]=b end end;function C(a,b)return b.e and(a.x-b.x)^2+(a.y-b.y)^2<128 end;function L.keypressed(f)if f=='space'then R[#R+1]={0,0,8,0,x=S.x,y=S.y,a=S.a,v=256,l=3}end end;function L.update(g)h,v=0,0;if D('a')then h=-2 elseif D('d')then h=2 elseif D('w')then v=128 elseif D('s')then v=-128 end;S.a=S.a+h*g;S.v=M.max(M.min(S.v+v*g,128),-128)for f,b in pairs(R)do b.x=(b.x+M.cos(b.a)*b.v*g)%W;b.y=(b.y+M.sin(b.a)*b.v*g)%H;if b.l then b.l=b.l-g;for e,i in pairs(R)do if C(b,i)then b.l=0;R[e]=nil;E=E-1 end end;if b.l<=0 then R[f]=nil end elseif C(S,b)then E=0 end end;if E==0 then L.load()end end;function L.draw()for j,b in pairs(R)do G.origin()G.translate(b.x,b.y)G.rotate(b.a)G.line(unpack(b))end end
Code: Select all
L=love
D=L.keyboard.isDown
G=L.graphics
W,H=G.getDimensions()
M=math
N=M.random
function L.load()
S={8,0,-8,4,-8,-4,8,0,x=W/2,y=H/2,a=0,v=0}
R={S}
E=32
for i=1,E do
b={x=N(W),y=N(H),a=N()*M.pi*2,v=N(64),e=1}
for j=0,6 do
c=N(8,16)
a=j/6*M.pi*2
b[j*2+1]=M.cos(a)*c
b[j*2+2]=M.sin(a)*c
end
b[15]=b[1]
b[16]=b[2]
R[#R+1]=b
end
end
function C(a,b)
return b.e and (a.x-b.x)^2+(a.y-b.y)^2<128
end
function L.keypressed(k)
if k=='space' then
R[#R+1]={0,0,8,0,x=S.x,y=S.y,a=S.a,v=256,l=3}
end
end
function L.update(dt)
h,v=0,0
if D('a')then
h=-2
elseif D('d')then
h=2
elseif D('w')then
v=128
elseif D('s')then
v=-128
end
S.a=S.a+h*dt
S.v=M.max(M.min(S.v+v*dt,128),-128)
for k,b in pairs(R)do
b.x=(b.x+M.cos(b.a)*b.v*dt)%W
b.y=(b.y+M.sin(b.a)*b.v*dt)%H
if b.l then
b.l=b.l-dt
for j,e in pairs(R)do
if C(b,e)then
b.l=0
R[j]=nil
E=E-1
end
end
if b.l<=0 then
R[k]=nil
end
elseif C(S,b)then
E=0
end
end
if E==0 then
L.load()
end
end
function L.draw()
for _,b in pairs(R)do
G.origin()
G.translate(b.x,b.y)
G.rotate(b.a)
G.line(unpack(b))
end
end
- Attachments
-
- asteroids.1k.love
- version 2
- (724 Bytes) Downloaded 281 times
- Jasoco
- Inner party member
- Posts: 3726
- Joined: Mon Jun 22, 2009 9:35 am
- Location: Pennsylvania, USA
- Contact:
Re: 1K Asteroids Challenge
I'm giving this a try right now. It's so challenging. I'm doing pretty well except that I'm not. I'm already near the limit and haven't even implemented bullets or broken up asteroids yet.
I don't even know how you'd do sound without an audio file in Löve but I'd be curious.
I'll post my result when I complete it.
Edit: Ha, about ~100 bytes passed the limit and it's still buggy and not complete.
Edit: Yeah, this is pretty difficult. My best was like ~1200 bytes so I decided to just add some more stuff to it and made it 1357 bytes.
It has colored entities (Added back when I gave up on the limit) and scoring and levels. (Also added) But it doesn't have rocks that break up. It also has a limit of 10 rocks and 10 bullets at once as all entities are loaded at once and just marked as dead and reused.
I also don't even use love.load or love.update and instead just grab Delta myself in love.draw.
It was a fun challenge and took my entire night.
I don't even know how you'd do sound without an audio file in Löve but I'd be curious.
I'll post my result when I complete it.
Edit: Ha, about ~100 bytes passed the limit and it's still buggy and not complete.
Edit: Yeah, this is pretty difficult. My best was like ~1200 bytes so I decided to just add some more stuff to it and made it 1357 bytes.
It has colored entities (Added back when I gave up on the limit) and scoring and levels. (Also added) But it doesn't have rocks that break up. It also has a limit of 10 rocks and 10 bullets at once as all entities are loaded at once and just marked as dead and reused.
I also don't even use love.load or love.update and instead just grab Delta myself in love.draw.
Code: Select all
_=love G=_.graphics k=_.keyboard.isDown D=_.timer.getDelta M=math R,P=M.random,M.pi W,H,B=800,600,0 G.setLineWidth(2) q=pairs K=0 t=1 function _.draw() if not g then T=0 E={} for i=1,21 do E[i]={id=i,d=0,x=R()*W,y=R()*H,s=3,a=R()*(P*2),n=0,l=0,k=1,m=20} f=E[i]if i==1 then f.x,f.y,f.a,f.s,f.k=W/2,H/2,P,2,0 elseif i>1 and i<12 then f.k=-1 f.m=60 f.s=.2 end end g=1 end E[1].a=E[1].a+(k("a")and-P or k("d")and P or 0)*D() G.setColor(255,255,255) G.print("Score: "..K.." Level: "..t, 0, 0) for i,e in q(E) do sp=i>11 and e.s*e.m or i>1 and 180 or(k("w") and 120 or 0) e.x=(e.x+M.cos(e.a)*D()*sp)%W e.y=(e.y+M.sin(e.a)*D()*sp)%H e.l=e.l-D() if e.l<=0 and e.k==-1 then e.d=1 end for j,u in q(E) do if i~=j then if M.sqrt((u.x-e.x)^2+(u.y-e.y)^2)<(e.s+u.s)*10 and u.d==0 then if e.k==0 and u.k==1 then g=nil K=0 T=0 t=1 elseif e.k==-1 and u.k==1 and e.d==0 then e.d,u.d=1,1 T=T+1 K=K+10*t if T>=10 then g=nil t=t+1 print("Level") end end end end end id=e.id b=(id>1 and id<12) if id ~= 1 then e.n=e.n+D() end G.setColor(id==1 and {255,255,255} or b and {255,0,0} or {0,255,0}) G.origin() G.translate(e.x,e.y) G.rotate(e.a) G.scale(1,id==1 and .8 or 1) if e.d==0 then G.circle("line",0,0,id==1 and 16 or b and 2 or e.s*10,id==1 and 3 or 7) end end end function _.keypressed(k) if k=="l" then B=(B+1)%10 e,p=E[B+2],E[1] e.x,e.y,e.a,e.l,e.d=p.x,p.y,p.a,5,0 end end
Re: 1K Asteroids Challenge
Merry Christmas!
The challenge was fun, thanks!
My entry:
994B
controls:
A: turn left
D: turn right
W: accelerate
L: fire
guidelines:
- all should be covered
extras:
- asteroids breaks into smaller pieces
- spaceship thruster "animation"
- points
cheating:
- the spaceship is circle (rather then triangle) to save a few bytes
The challenge was fun, thanks!
My entry:
994B
controls:
A: turn left
D: turn right
W: accelerate
L: fire
guidelines:
- all should be covered
extras:
- asteroids breaks into smaller pieces
- spaceship thruster "animation"
- points
cheating:
- the spaceship is circle (rather then triangle) to save a few bytes
Code: Select all
L=love
G=L.graphics
d=L.keyboard.isDown
r=L.math.random
C,S=math.cos,math.sin
X=table.remove
k=G.circle
l='line'
W,H=800,600
z=1
p=0
function K(q,s,x,y)for i=1,q do
A[#A+1]=s>5 and{x=x or r(W),y=y or r(H),u=r(-.8,.8),v=r(-.8,.8),s=s}or N
end end
function L.draw()if z then
I,O=W/2,H/2
U,Y=0,0
M,J=1,0
B={}A={}K(20,32)z=N
end
k(l,I,O,5)G[l](I,O,I+M*9,O+J*9)if d'w'then U,Y=U+M*.1,Y+J*.1
_=r()>.5 and k(l,I-M*6,O-J*6,3)end
I,O=I+U,O+Y
q=.1*(d'a'and-1 or d'd'and 1 or 0)M,J=C(q)*M-S(q)*J,S(q)*M+J*C(q)j=(U^2+Y^2)^.5
if j>5 then U,Y=U/j*5,Y/j*5 end
I,O=I%W,O%H
for i=#B,1,-1 do
b=B[i]b.l=b.l+1
b.x,b.y=(b.x+b.u)%W,(b.y+b.v)%H k(l,b.x,b.y,2)_=b.l>64 and X(B,i)end
if #A==0 then z=1 end
for i=#A,1,-1 do
a=A[i]s=a.s
a.x,a.y=(a.x+a.u)%W,(a.y+a.v)%H k(l,a.x,a.y,s,7)if(a.x-I)^2+(a.y-O)^2<s^2 then
z=1;p=0 end
for j=#B,1,-1 do
b=B[j]if(a.x-b.x)^2+(a.y-b.y)^2<s^2 then
X(B,j)X(A,i)K(2,s/2,a.x,a.y)p=p+1 end
end
end
G.print(p)end
function L.keypressed(k)B[#B+1]=k=='l'and{x=I,y=O,u=M*8,v=J*8,l=0}or N end
- Attachments
-
- asteroids_994B.love
- (778 Bytes) Downloaded 216 times
- Jasoco
- Inner party member
- Posts: 3726
- Joined: Mon Jun 22, 2009 9:35 am
- Location: Pennsylvania, USA
- Contact:
Re: 1K Asteroids Challenge
Suddenly I feel inadequate.
Re: 1K Asteroids Challenge
I'm totally going to do this challenge. Give me a day or two.
Re: 1K Asteroids Challenge
Just made this, more could definitely be done but i'll do that when i don't feel tired.
It was really fun to make, though!
Guidelines: Ship speed isn't capped, but otherwise follows perfectly.
Extras: Uses delta time.
929 Bytes
Source Code:
It was really fun to make, though!
Guidelines: Ship speed isn't capped, but otherwise follows perfectly.
Extras: Uses delta time.
929 Bytes
Code: Select all
L=love;G=L.graphics;R=L.math.random;W,H=G.getDimensions()h="fill"M=math;i,j=M.sin,M.cos;k=L.keyboard.isDown;l=table.remove;m=os.time;o={}b={}function p()o={}b={}for t=1,30 do o[t]={R(0,W),R(0,H),j(R(0,9))*9,i(0,9)*9,9}end;a=W/2;c=H/2;d=0;e=0;f=0 end;function L.draw()q=2*L.timer.getDelta()s=#o>0 or p()d=k"left"and d-2*q or k"right"and d+2*q or d;g=k"up"and 9*q or k"down"and 9*-q or 0;e=e+j(d)*g;f=f+i(d)*g;a=(a+e*q)%W;c=(c+f*q)%H;b[#b+1]=k"space"and r and{a,c,j(d)*50,i(d)*50,m()+5}or n;r=not k"space"for t,u in pairs(o)do s=(a-u[1])*(a-u[1])+(c-u[2])*(c-u[2])<u[5]*u[5]and p()u[1]=(u[1]+u[3]*q)%W;u[2]=(u[2]+u[4]*q)%H;G.circle(h,u[1],u[2],u[5])end;for t,u in pairs(b)do u[1]=(u[1]+u[3]*q)%W;u[2]=(u[2]+u[4]*q)%H;G.circle(h,u[1],u[2],3)for v,w in pairs(o)do s=(u[1]-w[1])*(u[1]-w[1])+(u[2]-w[2])*(u[2]-w[2])<w[5]*w[5]and l(o,v)and l(b,t)end;s=m()>u[5]and l(b,t)end;G.origin()G.translate(a,c)G.rotate(d)G.line(-9,-9,9,0,-9,9)end
Code: Select all
local player_x,player_y,player_r,player_xspd,player_yspd,player_spd
local Fill,sin,cos,keyDown,tableRemove,osTime,reset,dt,oldSpace,Exec
--^ For easy minifying!
L=love
G=L.graphics
R=L.math.random
W,H=G.getDimensions()
Fill="fill"
M=math
sin,cos = M.sin,M.cos
keyDown=L.keyboard.isDown
tableRemove=table.remove
osTime=os.time
o={}
b={}
function reset()
o={}b={}
for i=1,30 do o[i]={R(0,W),R(0,H),cos(R(0,9))*9,sin(0,9)*9,9}end
player_x=W/2
player_y=H/2
player_r=0
player_xspd=0
player_yspd=0
end
function L.draw()
dt=2*L.timer.getDelta()
Exec=#o>0 or reset()
player_r=keyDown"left" and player_r-2*dt or keyDown"right" and player_r+2*dt or player_r
player_spd=keyDown"up" and 9*dt or keyDown"down" and 9*-dt or 0
player_xspd=player_xspd+cos(player_r)*player_spd
player_yspd=player_yspd+sin(player_r)*player_spd
player_x=(player_x+player_xspd*dt)%W
player_y=(player_y+player_yspd*dt)%H
b[#b+1]=keyDown"space"and oldSpace and {player_x,player_y,cos(player_r)*50,sin(player_r)*50,osTime()+5} or n
oldSpace=not keyDown"space"
for i,v in pairs(o) do
Exec=(player_x-v[1])*(player_x-v[1])+(player_y-v[2])*(player_y-v[2]) < v[5]*v[5] and reset()
v[1]=(v[1]+v[3]*dt)%W
v[2]=(v[2]+v[4]*dt)%H
G.circle(Fill,v[1],v[2],v[5])
end
for i,v in pairs(b) do
v[1]=(v[1]+v[3]*dt)%W
v[2]=(v[2]+v[4]*dt)%H
G.circle(Fill,v[1],v[2],3)
for k,a in pairs(o) do Exec=(v[1]-a[1])*(v[1]-a[1])+(v[2]-a[2])*(v[2]-a[2]) < a[5]*a[5] and tableRemove(o,k) and tableRemove(b,i) end
Exec=osTime()>v[5] and tableRemove(b,i)
end
G.origin()
G.translate(player_x,player_y)
G.rotate(player_r)
G.line(-9,-9,9,0,-9,9)
end
- Attachments
-
- Hat1kAsteroids.love
- (2.83 KiB) Downloaded 186 times
Re: 1K Asteroids Challenge
Well done, some pretty good entries here.
So far, it looks like 0x72 did the best job in terms of gameplay.
And clever use of the "and" operator in order to avoid "if-then" statements, I'm going to steal that and use it in the next 1K challenge.
So far, it looks like 0x72 did the best job in terms of gameplay.
And clever use of the "and" operator in order to avoid "if-then" statements, I'm going to steal that and use it in the next 1K challenge.
- Jasoco
- Inner party member
- Posts: 3726
- Joined: Mon Jun 22, 2009 9:35 am
- Location: Pennsylvania, USA
- Contact:
Re: 1K Asteroids Challenge
Using "and" to avoid "if" whenever possible is my favorite thing to do now. If I'm creative enough I can combine so many into one line and avoid half a dozen ifs and locals. Well I guess we don't really bother with locals when doing these challenges. I also tried to avoid as many functions as possible since the word "function" itself takes a whole 8 bytes not including the function name and brackets.
I'll definitely wait for the next 1K challenge. The Terminal one doesn't really appeal to me though.
I'll definitely wait for the next 1K challenge. The Terminal one doesn't really appeal to me though.
Re: 1K Asteroids Challenge
Here's my entry into this challenge. It took me way too long to figure how to do this, it was tough fitting everything into 1K. I coded more features, but I had to remove them to get it under 1K.
Size: 1,021 bytes
Guidelines: All good.
Extra:
- Delta time
- Asteroids have different models
- Asteroids break apart
Controls:
Rotate left: A
Rotate right: D
Thrust: W
Shoot: K
Minified:
Source:
Size: 1,021 bytes
Guidelines: All good.
Extra:
- Delta time
- Asteroids have different models
- Asteroids break apart
Controls:
Rotate left: A
Rotate right: D
Thrust: W
Shoot: K
Minified:
Code: Select all
L=love;M=math;R=M.random;u=M.cos;U=M.sin;G=L.graphics;K=L.keyboard.isDown;W,H=800,600;Q=pairs;I=table.insert;F=99;T=9;C=0;A=function(b,c,d,e)for f=1,e do a={x=c or R(W),y=d or R(H),X=R(-F,F),Y=R(-F,F),r=b}for g=0,6 do q=R(4)*b/4;I(a,u(g)*q)I(a,U(g)*q)end;C=C+1;I(a,a[1])I(a,a[2])I(E,a)end end;L.keypressed=function(h)if h=="k"then I(E,{x=S.x,y=S.y,X=u(O)*300,Y=U(O)*300,r=3,l=2,2,2,0,0})end end;L.draw=function()D=L.timer.getDelta()if C==0 or n then E={}S={x=W/2,y=H/2,X=0,Y=0,r=6,a=0,-9,-7,9,0,-9,7}I(E,S)A(45,_,_,T)C=T;n=_ end;O=S.a;S.a=K"a"and O-3*D or(K"d"and O+3*D or O)if K"w"then S.X=S.X+u(O)*F*D;S.Y=S.Y+U(O)*F*D end;s=F*F/(S.X^2+S.Y^2)s=s>1 and 1 or s^.5;S.X=S.X*s;S.Y=S.Y*s;for f,i in Q(E)do i.x=(i.x+i.X*D)%W;i.y=(i.y+i.Y*D)%H;G.translate(i.x,i.y)G.rotate(i.a or 0)G.line(i)G.origin()for j,k in Q(E)do if(k.x-i.x)^2+(k.y-i.y)^2<(i.r+k.r)^2 and#k>9 then if i.l then A(20,k.x,k.y,k.r>20 and R(2,4)or 0)C=C-1;E[f]=_;E[j]=_ end;if i.a then n=1 end end end;if i.l then i.l=i.l-D;if i.l<0 then E[f]=_ end end end end
Code: Select all
L=love
M=math
R=M.random
u=M.cos
U=M.sin
G=L.graphics
K=L.keyboard.isDown
W,H=800,600
Q=pairs
I=table.insert
F = 99 -- max force
T = 9 -- max asteroids
C = 0 -- asteroid count
A=function(z,x,y,c)
for i=1, c do
a = {
x=x or R(W),
y=y or R(H),
X=R(-F,F),
Y=R(-F,F),
r=z,
}
for t=0, 6 do
q = R(4)*z/4
I(a, u(t)*q)
I(a, U(t)*q)
end
C = C + 1
I(a, a[1])
I(a, a[2])
I(E, a)
end
end
L.keypressed=function(k)
if k=="k" then
I(E, {
x=S.x,
y=S.y,
X=u(O)*300,
Y=U(O)*300,
r=3,
l=2,
2,2,0,0
})
end
end
L.draw=function()
D = L.timer.getDelta()
-- reset
if C==0 or n then
E = {}
S = {
x=W/2,
y=H/2,
X=0,
Y=0,
r=6,
a=0,
-9,-7,9,0,-9,7
}
I(E, S)
A(45,_,_,T)
C = T
n = _
end
O = S.a
S.a = K"a" and O - 3*D or (K"d" and O + 3*D or O)
if K"w" then
S.X = S.X + u(O)*F*D
S.Y = S.Y + U(O)*F*D
end
-- clamp speed
s = F * F / (S.X^2 + S.Y^2)
s = s > 1 and 1 or s^.5
S.X = S.X * s
S.Y = S.Y * s
for i, e in Q(E) do
e.x = (e.x + e.X*D)%W
e.y = (e.y + e.Y*D)%H
G.translate(e.x, e.y)
G.rotate(e.a or 0)
G.line(e)
G.origin()
for j, f in Q(E) do
if (f.x - e.x)^2 + (f.y - e.y)^2 < (e.r + f.r)^2 and #f>9 then
-- bullet vs asteroid
if e.l then
A(20, f.x, f.y, f.r > 20 and R(2,4) or 0)
C = C - 1
E[i] = _
E[j] = _
end
-- Ship vs asteroid
if e.a then
n=1
end
end
end
if e.l then
e.l = e.l - D
if e.l < 0 then
E[i] = _
end
end
end
end
- Attachments
-
- 1k-asteroids.love
- (798 Bytes) Downloaded 200 times
Who is online
Users browsing this forum: No registered users and 3 guests