37. Shooting gallery
Now that I’ve built a couple of 3D projects, I can see why the early video games stuck to empty space and tabletops to keep things simple.
Another early type of video game was the shooting gallery, either with rows of objects moving left and right, or little people popping up in windows and doors to be shot at. In the next couple of posts I’m going to tackle the second of these, and it includes some interesting stuff.
In this post, I’m going to start slowly, by figuring out how the aiming and shooting will happen. I’d like cross hair sights that appear above my finger when it touches the screen, and I’d like to shoot when a second finger touches the screen. So this is going to be largely about touches.
Touch
Here is my touch code. It is quite simple to decide which finger is aiming and which finger is shooting, because each touch gets its own unique ID number
function touched(touch) if touch.state==BEGAN then --user has just touched, hasn't let go yet numtouches=numtouches+1 --keep count if numtouches==1 then --if first touch, it is aiming, store details aim.id=touch.id --so we know which touch is which when we shoot aim.x=touch.x aim.y=touch.y end elseif touch.state==MOVING then --finger is moving if touch.id==aim.id then --if the aiming finger, store new x,y aim.x=touch.x aim.y=touch.y end elseif touch.state==ENDED then if touch.id==aim.id then aim.id=0 --if aiming finger lifted, remove scope elseif numtouches>1 then --if more than one finger, bang bang! shots[#shots+1]={x=aim.x,y=aim.y+scopeBuffer} --add shot to table end numtouches=numtouches-1 --adjust touch count end end
So Codea makes it quite easy, by tracking when the user presses down, slides a finger, or lifts it off the screen. If a touch is the first (there are no others at the moment, then it must be the aiming finger, and we store the x,y details as it moves. If it is a different touch, we wait for it to end and then we fire a shot (actually, we just add the x.y values to a table of shots fired).
Scope sights
I’d like cross hair sights, that will appear above the finger on screen. Here is my code. Note how rather than keep drawing all these circles and lines all the time, I draw them just once, onto an image, and then I’ll draw this image on the screen after that.
function createScope() scopeBuffer=70 --draw scope this many pixels above finger (so user can see scope!) scopeOuterRing=50 --pixels wide scopeInnerRing=20 crossHairExtends=10 --crosshairs extend this far outside rings local s=scopeOuterRing+crossHairExtends*2 --total width --since we're drawing the same scope a lot, we create an image imgScope=image(s,s) setContext(imgScope) --start drawing on the image instead of the screen ellipseMode(CENTER) strokeWidth(.5) --lines one pixel wide stroke(94, 89, 89, 255) --dark colour fill(0,0,0,0) --transparent fill (the last item, alpha, is nil) ellipse(s/2,s/2,scopeOuterRing) --draw rings ellipse(s/2,s/2,scopeInnerRing) line(s/2,0,s/2,s) --draw crosshairs line(0,s/2,s,s/2) setContext() --stop drawing on image end
Then I need to draw everything on the screen. I syart by drawing a little target to shoot at, then the scope sights, then any shots fired.
function draw() background(195, 211, 215, 255) popStyle() --draw target stroke(82, 181, 199, 255) --outer circle colour strokeWidth(25) fill(120, 141, 186, 255) --inner circle colour ellipse(WIDTH/2,HEIGHT/2,100) if aim.id>0 then --if aiming, draw scope sprite(imgScope,aim.x,aim.y+scopeBuffer) end --draw past shots on screen for i,v in pairs(shots) do fill(shotColour) strokeWidth(0) ellipse(v.x,v.y,shotSize) end pushStyle() end
And that’s pretty much it, apart from a few lines in the setup function.
This is how the screen looks
http://instagram.com/p/YSOP0jBHXl/
Next, I want to be able to zoom in, and lastly, I want to add moving targets.