@Ignatz, awesome, YAY, I will lose!
Some ideas based on the old Star Wars arcade game.
http://www.youtube.com/watch?v=uaFJjkI2Myg
http://www.youtube.com/watch?v=dtQOWb_L7JI
Looking to combine the two but struggling. I want to treat the pseudo 3d stuff (code below) as a background and effectively use as a canvas on top of which I run the second code. The issue is that I have introduced depth and now the second set of code intermingles with the first. Is there a way around this? e.g resetting the perspective view? I’ve included a simple sprite example in the code.
Also, as an extra I’d like to remove the flicker (I suspect this is when the moving sprites get too close or just behind the camera position).
Thanks in advance!
displayMode(FULLSCREEN)
function setup()
img=readImage("Platformer Art:Block Brick")
d=50
camPos=vec3(0,0,2.5*d)
x=0
trenchlen=30
end
function draw()
background(0)
perspective()
camera(camPos.x,camPos.y,camPos.z,0,0,0)
--left wall
pushMatrix()
rotate(90,0,1,0)
translate(x,0,-d/2)
for i=-d,trenchlen*d,d do
tint(255,255-15*math.abs(i/d))
sprite(img,i,0,d)
end
popMatrix()
--right wall
pushMatrix()
rotate(-90,0,1,0)
translate(-x,0,-d/2)
for i=d,-trenchlen*d,-d do
tint(255,255-15*math.abs(i/d))
sprite(img,i,0,d)
end
popMatrix()
--floor
pushMatrix()
rotate(-90,0,0,1)
rotate(-90,0,1,0)
translate(-x,0,-d/2)
for i=d,-trenchlen*d,-d do
tint(255,255-15*math.abs(i/d))
sprite(img,i,0,d)
end
popMatrix()
--[[
--surface if you allow progression above trench top
pushMatrix()
rotate(-90,0,0,1)
rotate(-90,0,1,0)
translate(-x,40,20)
for i=d,-trenchlen*d,-d do
tint(255,255-15*math.abs(i/d))
sprite(img,i,0,d)
sprite(img,i,40,d)
sprite(img,i,80,d)
sprite(img,i,120,d)
end
popMatrix()
pushMatrix()
rotate(-90,0,0,1)
rotate(-90,0,1,0)
translate(-x,-40,20)
for i=d,-trenchlen*d,-d do
tint(255,255-15*math.abs(i/d))
sprite(img,i,0,d)
sprite(img,i,-40,d)
sprite(img,i,-80,d)
sprite(img,i,-120,d)
end
popMatrix()
]]--
noTint()
x = x - 2
if x<=-d then x=0 end
camPos.x=(CurrentTouch.x-WIDTH/2)/(WIDTH*0.05)
camPos.y=math.max(-10,(CurrentTouch.y-HEIGHT/2)/(HEIGHT*0.025))
--doesn't appear on screen (proabaly to do with camera position)
sprite("Planet Cute:Character Cat Girl",WIDTH/2,HEIGHT/2)
--appears but forced "depth"
pushMatrix()
translate(0,0,-100)
sprite("Planet Cute:Character Cat Girl",0,0)
popMatrix()
end
@West - To superimpose 2D on 3D, do this
--draw your 3D stuff, then
ortho()
viewMatrix(matrix())
--now draw your 2D stuff
@West - the jumping is to do with the way you are skipping forward by one tile, as each one passes the camera. I haven’t looked at it in depth, but it’s just a matter of proper synchronisation, I think.
@West - you shouldn’t draw things in 3D with sprites, use a mesh like this
displayMode(FULLSCREEN)
function setup()
img=readImage("Platformer Art:Block Brick"):copy(3,3,64,64)
w,h=80,50
d=w --NB flickers if w~=d
trench=CreateTrench(30,w,h,d,img)
offset=0
speed=1
end
function CreateTrench(n,w,h,d,img)
local d=w
local m=mesh{}
m.texture=img
local v,t={},{}
--left side
for i=1,n do
local x,y1,y2,z1,z2=-w/2,-h/2,h/2,-d/2-i*d,d/2-i*d
local v1,v2,v3,v4=vec3(x,y1,z1),vec3(x,y1,z2),vec3(x,y2,z2),vec3(x,y2,z1)
local vv={v1,v2,v3,v3,v4,v1} for i=1,6 do v[#v+1]=vv[i] end
end
--right side
for i=1,n do
local x,y1,y2,z1,z2=w/2,-h/2,h/2,d/2-i*d,-d/2-i*d
local v1,v2,v3,v4=vec3(x,y1,z1),vec3(x,y1,z2),vec3(x,y2,z2),vec3(x,y2,z1)
local vv={v1,v2,v3,v3,v4,v1} for i=1,6 do v[#v+1]=vv[i] end
end
--bottom
for i=1,n do
local x1,x2,y,z1,z2=-w/2,w/2,-h/2,-d/2-i*d,d/2-i*d
local v1,v2,v3,v4=vec3(x1,y,z1),vec3(x2,y,z1),vec3(x2,y,z2),vec3(x1,y,z2)
local vv={v1,v2,v3,v3,v4,v1} for i=1,6 do v[#v+1]=vv[i] end
end
--textures
local tt={vec2(0,0),vec2(1,0),vec2(1,1),vec2(1,1),vec2(0,1),vec2(0,0)}
for i=1,#v,6 do
for j=1,6 do t[#t+1]=tt[j] end
end
m.vertices=v
m.texCoords=t
m:setColors(color(255))
return m
end
function draw()
background(0)
perspective()
camera(0,5,10,0,5,0)
pushMatrix()
translate(0,0,offset)
trench:draw()
popMatrix()
--this adjustment makes it an infinite trench
offset=math.fmod(offset+speed,d)
ortho()
viewMatrix(matrix())
sprite("Space Art:Green Ship",WIDTH/2,HEIGHT/2-50)
end
@Ignatz - fab - just what I was after - I used sprites after following one of your intro tutorials - not sure why sprite didn’t work but I’ve not really done much in 3D and not sure if I’ll put in the time to learn it at the moment. Thanks again though - appreciate it!
3D is the best, well worth learning
Did someone say…
Trench run?
Haha
(Your X-wing came in handy then)
Yes, I added a tie fighter and a trench section to the obj importer, that’s what the trench run thing is built with.
Combined version of Death Star trench run - big thanks to @Ignatz for his help.
http://www.youtube.com/watch?v=NAhjQxxD1yY
http://imgur.com/uiFiiwE
http://imgur.com/gtKqxRv
http://imgur.com/14oqLos
-- Trench
displayMode(FULLSCREEN)
-- Use this function to perform your initial setup
function setup()
starfield=image(WIDTH,HEIGHT)
setContext(starfield)
fill(255)
for i=1,100 do
ellipse(math.random(WIDTH),math.random(HEIGHT),3)
end
setContext()
dest=vec2(WIDTH/2,HEIGHT/2)
target=vec2(-10,200)
lim=2
laser={}
xwing={}
for i=1,4 do
addXwing()
end
counter=0
img=readImage("Project:surface"):copy(0,0,50,50)
w,h=80,50
d=w --NB flickers if w~=d
trench=CreateTrench(30,w,h,d,img)
offset=0
speed=5
camx=0
camy=5
end
function CreateTrench(n,w,h,d,img)
local d=w
local m=mesh{}
m.texture=img
local v,t={},{}
--left side
for i=1,n do
local x,y1,y2,z1,z2=-w/2,-h/2,h/2,-d/2-i*d,d/2-i*d
local v1,v2,v3,v4=vec3(x,y1,z1),vec3(x,y1,z2),vec3(x,y2,z2),vec3(x,y2,z1)
local vv={v1,v2,v3,v3,v4,v1} for i=1,6 do v[#v+1]=vv[i] end
end
--right side
for i=1,n do
local x,y1,y2,z1,z2=w/2,-h/2,h/2,d/2-i*d,-d/2-i*d
local v1,v2,v3,v4=vec3(x,y1,z1),vec3(x,y1,z2),vec3(x,y2,z2),vec3(x,y2,z1)
local vv={v1,v2,v3,v3,v4,v1} for i=1,6 do v[#v+1]=vv[i] end
end
--bottom
for i=1,n do
local x1,x2,y,z1,z2=-w/2,w/2,-h/2,-d/2-i*d,d/2-i*d
local v1,v2,v3,v4=vec3(x1,y,z1),vec3(x2,y,z1),vec3(x2,y,z2),vec3(x1,y,z2)
local vv={v1,v2,v3,v3,v4,v1} for i=1,6 do v[#v+1]=vv[i] end
end
--textures
local tt={vec2(0,0),vec2(1,0),vec2(1,1),vec2(1,1),vec2(0,1),vec2(0,0)}
for i=1,#v,6 do
for j=1,6 do t[#t+1]=tt[j] end
end
m.vertices=v
m.texCoords=t
m:setColors(color(255))
return m
end
-- This function gets called once every frame
function draw()
-- This sets a dark background color
background(40, 40, 50)
perspective()
camera(0,5,10,0,5,0)
pushMatrix()
translate(target.x,-target.y,offset)
print(target.x,target.y)
trench:draw()
popMatrix()
--this adjustment makes it an infinite trench
offset=math.fmod(offset+speed,d)
ortho()
viewMatrix(matrix())
strokeWidth(5)
for i,l in pairs(laser) do
stroke(115, 255, 0, 255)
line(l.x1,l.y1,l.x1+l.s1*math.cos(l.a1),l.y1+l.s1*math.sin(l.a1))
l.x1 = l.x1 + l.s1*math.cos(l.a1)
l.y1 = l.y1 + l.s1*math.sin(l.a1)
line(l.x2,l.y2,l.x2+l.s2*math.cos(l.a2),l.y2+l.s2*math.sin(l.a2))
l.x2 = l.x2 + l.s2*math.cos(l.a2)
l.y2 = l.y2 + l.s2*math.sin(l.a2)
line(l.x3,l.y3,l.x3+l.s3*math.cos(l.a3),l.y3+l.s3*math.sin(l.a3))
l.x3 = l.x3 + l.s3*math.cos(l.a3)
l.y3 = l.y3 + l.s3*math.sin(l.a3)
line(l.x4,l.y4,l.x4+l.s4*math.cos(l.a4),l.y4+l.s4*math.sin(l.a4))
l.x4 = l.x4 + l.s4*math.cos(l.a4)
l.y4 = l.y4 + l.s4*math.sin(l.a4)
l.f = l.f - 11
if l.f<0 then
for i,x in pairs(xwing) do
if vec2(l.tx,l.ty):dist(vec2(x.x,x.y))<20*x.size then
x.active=2
sound(SOUND_EXPLODE, 14788)
end
end
table.remove(laser,i)
end
end
for i,x in pairs(xwing) do
tint(255,x.fade)
pushMatrix()
translate(x.x,x.y)
rotate(x.a)
if x.active==1 then
sprite("Project:xwing",0,0,x.size*100)
else
sprite("Tyrian Remastered:Explosion Huge",0,0,x.size*100)
end
popMatrix()
noTint()
x.x = x.x -2+math.random(3)
x.y = x.y -2+math.random(3)
x.a = x.a + math.sin(ElapsedTime+x.off)/5
if x.active==1 then
if x.size<1 then x.size = x.size + 0.002
else
x.size = x.size +0.007*math.sin(ElapsedTime+x.off)
end
elseif x.active==2 then
x.size = x.size * 1.08
x.fade = x.fade - 3
if x.fade<0 then
x.active=0
end
end
end
for i,x in pairs(xwing) do
if x.active==0 then table.remove(xwing,i) end
end
dest.x=(CurrentTouch.x-WIDTH/2)/(WIDTH*0.05)
dest.y=math.max(-10,(CurrentTouch.y-HEIGHT/2)/(HEIGHT*0.025))
if target.x<dest.x then target.x = target.x + 1 end
if target.x>dest.x then target.x = target.x - 1 end
if target.y<dest.y then target.y = target.y + 1 end
if target.y>dest.y then target.y = target.y - 1 end
sprite("Project:cockpit",WIDTH/2,HEIGHT/2)
counter = counter + math.random(3)
if counter>300 then
addXwing()
counter=0
end
end
function touched(t)
if t.state==ENDED then
local a1=math.atan(t.y-0,t.x-0)
local s1=vec2(t.x,t.y):dist(vec2(0,0))
local a2=math.atan(-(HEIGHT-t.y),t.x-0)
local s2=vec2(t.x,t.y):dist(vec2(0,HEIGHT))
local a3=math.atan(-(HEIGHT-t.y),-(WIDTH-t.x))
local s3=vec2(t.x,t.y):dist(vec2(WIDTH,HEIGHT))
local a4=math.atan(t.y,-(WIDTH-t.x))
local s4=vec2(t.x,t.y):dist(vec2(WIDTH,0))
table.insert(laser,{tx=t.x,ty=t.y,f=255,a1=a1,s1=s1/25,x1=0,y1=0,a2=a2,s2=s2/25,x2=0,y2=HEIGHT,a3=a3,s3=s3/25,x3=WIDTH,y3=HEIGHT,a4=a4,s4=s4/25,x4=WIDTH,y4=0})
sound(SOUND_SHOOT, 30296)
end
end
function addXwing()
table.insert(xwing,{x=WIDTH*0.45+math.random(math.floor(WIDTH*0.1)),y=HEIGHT*0.45+math.random(math.floor(HEIGHT*0.1)),size=0.1,a=-14+math.random(30),off=math.random(10),fade=255,active=1})
end
How to make the rotation without the mistake rotation, that he rotates ten then pause, the he teleports ten, … I want that he will rotate in one direction and not 10° then pause then in one millisecond more 10°…
displayMode(OVERLAY)
displayMode(FULLSCREEN)
supportedOrientations(WIDTH)
function setup()
stars = {}
z = 20
zy = 25
starship_table = {}
lazer_table = {}
end
function draw()
translate(WIDTH/2, HEIGHT/2)
rotate(ElapsedTime * 10)
--background
background(0, 0, 0, 255)
for x = -25, 25 do
stars[x] = {}
for y = -19, 18 do
stars[x][y] = false
strokeWidth(2)
stroke(255, 255, 255, 255)
line(x * z, y * z - 2.5, x * z, y * z + 2.5)
line(x * z - 2.5, y * z, x * z + 2.5, y * z)
end
end
--starship
sprite("Tyrian Remastered:Boss B")
--lazer
for y = 1, 14 do
lazer_table[y] = false
stroke(125, 200, 150, 255)
strokeWidth(10)
line(0, y * zy - 385, 0, y * zy - 375)
end
end
This happens:
@TokOut the reason why you’re seeing a pause followed by a ten degree rotation, pause, rotation etc, is because your frame rate has dropped so low. As the rotation is set by ElapsedTime, when the frame rate is low the time between frames becomes high. The main reason for the frame rate being low I imagine is the starfield. There are a number of ways you could speed it up, but perhaps the simplest would be to draw it once to an image in setup, and then sprite the image in draw.
Behold the power of a fully operational Death Star!
Retro mode can be unlocked as an Easter (Christmas?) Egg:
Okay then here my code:
displayMode(OVERLAY)
displayMode(FULLSCREEN)
supportedOrientations(WIDTH)
function setup()
img = readImage("Project:Competition Image")
rotation = 10
end
function draw()
translate(WIDTH/2, HEIGHT/2)
rotate(ElapsedTime * rotation)
sprite(img, 0, 0)
end
For the sprite use this code:
displayMode(OVERLAY)
displayMode(FULLSCREEN)
supportedOrientations(WIDTH)
function setup()
stars = {}
z = 20
zy = 25
starship_table = {}
lazer_table = {}
end
function draw()
translate(WIDTH/2, HEIGHT/2)
--background
background(0, 0, 0, 255)
for x = -25, 25 do
stars[x] = {}
for y = -19, 18 do
stars[x][y] = false
strokeWidth(2)
stroke(255, 255, 255, 255)
line(x * z, y * z - 2.5, x * z, y * z + 2.5)
line(x * z - 2.5, y * z, x * z + 2.5, y * z)
end
end
--starship
sprite("Tyrian Remastered:Boss B")
--lazer
for y = 1, 14 do
lazer_table[y] = false
stroke(125, 200, 150, 255)
strokeWidth(10)
line(0, y * zy - 385, 0, y * zy - 375)
end
end
You will see this: