-- Misc
function newGame()
spinTimer = 0
soundTimer = 0
timer = 200
crashed = false
east = 0
north = 250
heading = 0
roll = 0
pitch = 0
speed = 0
gas = 50
altimeter.val = 0
flightTimer.val = 0
end
function createMapElements()
local i
trees.texture ="Planet Cute:Tree Short"
trees2.texture ="Planet Cute:Tree Ugly"
trees.setColors(255,255,255,255)
mud.texture = "Small World:Dirt Patch"
bushes.texture = "Small World:Bush"
rocks.texture = "Tyrian Remastered:Rock 3"
for i = 1, 2000 do
bushes:addRect(math.random(20000) - 10000,
math.random(9800) - 10000, 32, 27)
end
for i = 1, 500 do
mud:addRect(math.random(20000) - 10000,
math.random(4000) - 10000, 130, 100)
end
for i = 1, 1000 do
trees:addRect(math.random(10000) - 10200,
math.random(5800), 100, 171)
trees:addRect(math.random(10000) + 200,
math.random(5800), 100, 171)
end
for i = 1, 1500 do
trees2:addRect(math.random(20000) - 10000,
math.random(4000) + 5600 , 100, 171)
end
i =0
for x = 1, 100 do
for y = 1, 100 do
ground:addRect(x*500 - 25000,y*500-25000,500,500)
i = i + 1
if y < 48 and y > 40 then
ground:setRectColor(i, 88+math.random(64),
154+math.random(64), 33)
elseif y <= 40 then
ground:setRectColor(i, 144+math.random(64),
144+math.random(64), 33)
elseif y == 70 then
ground:setRectColor(i, 155+math.random(64),
154+math.random(55), 122)
elseif y > 70 then
ground:setRectColor(i, 22, 22, 155+math.random(55))
elseif x < 20 and y < 30 then
ground:setRectColor(i, 100, 100 + math.random(40),
30, 255)
elseif x > 50 and y < 15 then
ground:setRectColor(i, 22, 22, 155+math.random(55))
else
ground:setRectColor(i, 22, 166+math.random(55),22)
end
end
end
for x = 1, 100 do
y = 50 + math.random(2) - 1
ground:setRectColor(5000 + i, 22, 22, 151+math.random(55))
end
runway = mesh()
runway:addRect(0,0,200,2000)
runway:setRectColor(1, 122, 122, 122)
end
function newTarget(i)
local z
z = math.floor(math.random(3) + 1) * 500
target[i] = vec3( math.random(20000) - 10000,
math.random(20000) - 10000, z)
end
function calcPosition()
-- direction
if speedo.val > 10 then
heading = heading + horizon.roll / 100
if heading < 0 then heading = heading + 360 end
if heading > 360 then heading = heading - 360 end
end
-- position
north = north - math.cos(math.rad(heading)) * speedo.val/20
if north > 25000 then north = -25000
elseif north < -25000 then north = 25000 end
east = east - math.sin(math.rad(heading)) * speedo.val/20
if east > 25000 then east = -25000
elseif east < -25000 then east = 25000 end
-- altitude
altimeter.val = altimeter.val - 0.1
altimeter.val = altimeter.val - math.abs(horizon.roll) / 50
altimeter.val = altimeter.val + (horizon.pitch * -speedo.val / 60)
if speedo.val + horizon.pitch * 100 < 60 then
stall= true
if altimeter.val > 0 then
altimeter.val = altimeter.val - 1
spinTimer = spinTimer + 10
sound(SOUND_JUMP, 40113)
end
else
stall = false
spinTimer = 0
end
if altimeter.val <= 0 then
-- on ground
-- check for landing / crash
altimeter.val = 0
if east < -200 or east > 200 or north > 2300
or north < -1300 then
--big crash
crashed = true
timer = 0
speedo.val = 0
sound(SOUND_EXPLODE, 18933)
status = 1
else
-- on runway
if horizon.pitch < 0 then
speedo.val = speedo.val - 1
fontSize(22)
text("Brakes Applied. Tilt forward to release.",
WIDTH / 2, 320)
end
end
else
-- in air
speedo.val = speedo.val + horizon.pitch * 2
end
-- speed
if timer > 0 then
speedo.val = speedo.val + throttle.val / 100
else
fontSize(22)
text("Out of gas.", WIDTH / 2, 320)
end
if speedo.val < 0 then speedo.val=0 end
if speedo.val > 222 then speedo.val = 220 end
-- fuel
timer = timer - throttle.val * 0.001
if timer < 0 then timer = 0 end
-- sound
if timer > 0 and soundTimer + 0.1 < ElapsedTime then
if throttle.val > 30 then
sound(DATA,
"ZgNAFAA6Pz05PDxCIsyOvCq8qT4jd5g+JAA7fz9EREFCOz5F")
elseif throttle.val > 0 then
sound(DATA,
"ZgNAFw06Ozs5Pj5FmteWPa+b2j419Z8+JAA4f0FER0VCOz1I")
end
soundTimer = ElapsedTime
end
-- timer
pushStyle()
fill(165, 207, 223, 99)
fontSize(96)
textAlign(LEFT)
textMode(CORNER)
text(math.floor(timer), 20, 300)
fill(223, 138, 138, 185)
textMode(CENTER)
textAlign(CENTER)
font("MarkerFelt-Wide")
if stall and altimeter.val > 10 then
text("Stall Warning", WIDTH / 2, HEIGHT / 2)
end
popStyle()
end
Deleted – see new version below
-- Misc2
function showInstructions()
local i
pushStyle()
fill(46, 45, 25, 255)
rect(10, 315, WIDTH - 20, HEIGHT - 330)
fill(219, 219, 219, 255)
rect(20, 320, WIDTH - 40, HEIGHT - 340)
stroke(67, 67, 67, 255)
line(WIDTH / 2, 330, WIDTH / 2, HEIGHT - 50)
textAlign(LEFT)
textMode(CORNER)
fontSize(24)
fill(0, 0, 0, 255)
font("HelveticaNeue-Bold")
text("Log Book", 30, HEIGHT - 50)
fill(23, 50, 167, 255)
font("Noteworthy-Light")
strokeWidth(1)
for i = 1, 14 do
line(40, HEIGHT - i * 43 - 50,
WIDTH / 2 - 10, HEIGHT - i * 43 - 50)
line(WIDTH / 2 + 10, HEIGHT - i * 43 - 50,
WIDTH - 40, HEIGHT - i * 43 - 50)
end
fontSize(24 * WIDTH / 768)
textWrapWidth(330 * WIDTH / 768)
text("1. Tilt device left and right to change direction.",
40, HEIGHT - 142)
text("2. Tilt device forward to dive and back to climb.",
40, HEIGHT - 227)
text("3. Hold device flat for level flight.",
40, HEIGHT - 273)
text("4. Tilt forward to release brakes on runway.",
40, HEIGHT - 355)
text("5. If you try to climb too quickly you will"..
" lose speed and stall.", 40, HEIGHT - 442)
text("6. To recover from a stall tilt forward "..
" and gain speed.", 40, HEIGHT - 528)
text("7. It takes more power to hold altitude during "..
" steeply banked turns.", 40, HEIGHT - 652)
text("8. When the timer runs down, you're out of fuel. "..
" ", WIDTH / 2 + 10, HEIGHT - 142)
text("9. Fly to targets to get extra fuel. "..
" ", WIDTH / 2 + 10, HEIGHT - 186)
text("10. Smaller targets give more fuel. "..
" ", WIDTH / 2 + 10, HEIGHT - 229)
text("11. Ease off on the throttle to save fuel. "..
" ", WIDTH / 2 + 10, HEIGHT - 315)
text("12. Good luck!"..
" ", WIDTH / 2 + 10, HEIGHT - 357)
text(" Turn on control of throttle by acceleration. "..
" Warning! Requires a lot of space and willingness"..
" to look like an idiot.", WIDTH / 2 + 10, HEIGHT - 560)
text("(c) 2012 by Mark Sumner"..
" ", WIDTH / 2 + 60, HEIGHT - 659)
stroke(0, 0, 0, 255)
strokeWidth(2)
fill(219, 219, 219, 255)
accelFrame:draw()
strokeWidth(5)
stroke(31, 179, 22, 255)
if accelMode then
line(accelFrame.left, accelFrame:midY(),
accelFrame:midX(), accelFrame.bottom)
line(accelFrame.right, accelFrame.top,
accelFrame:midX(), accelFrame.bottom)
end
popStyle()
end
For what it’s worth, my record flight time is 630, but I expect it’s possible to keep flying nearly infinitely if you manage your fuel and build up altitude when possible.
Have fun.
Thank you. You always make incredible things.
I already pasted the code but I got an error at line 79 in main program about “compare number with nil”.
78 i = readLocalData("PlaneCrazyBest")
79 if i >0 then
To solve the error, I mark the line 78 as comment and it works.
78 --i = readLocalData("PlaneCrazyBest")
EDIT: Another solution by not marking as a comment in order to read the highest score
i = readLocalData("PlaneCrazyBest") or 0
I’m definitely going to try this one out. After working on my shape explorer, I had the idea of using the iPad itself as a control device, measuring the pitch and yaw, but I got too busy to pursue the idea. So I’m excited to see someone’s done it.
oh wow! i cant find my answer in the code so… a very bisic question @mark :
how do you basicly do the map-drawings (not the little map, the big map where the plane is drawn on)? by drawing simply everything and translating it by the plane position? or are the out-of-screen-elements not drawn? I am interested in this me because i tried something comparable…
@sanit – thanks. I inserted that line for reading the high score, then never went back to test what happened if it wasn’t there.
@Maxiking16 – I’m using meshes, with rotate, translante, and scale (although I think scale is commeted out in this version) to adjust to the plane’s position. The big map itself is actually a stack of meshes – one for the square “ground” rects, one for the tree textures. one for runways. Then on top of that are some features drawn with primitives, like the details on the runway. Then there’s the plane, which is actually not quite at the center of rotation because I wanted to give you more space to see “ahead” than you’d get with the plane at the center of the screen. And the sprite for the plane itself is rotated 180 degrees. So I frequently get lost in mental fog thinking “okay, so the plane is heading north northeast. Now… what do I do with the meshes, and why is the mini map upside down?” I can tell you that, compared to iterating through arrays of sprites or primitives, meshes draw MUCH faster.
@Andrew_Stacey You should see the original test. Not only did I use the iPad for pitch and yaw, I used acceleration for the throttle. So to make the plane go faster you had to actually get up and move, and if you slowed down the plane slowed down. I may put a switch in there to turn that feature back on, but it does make it hard to play the game without an open space the size of a football field.
Please do, I love the acceleration idea
Speedometer = class()
function Speedometer:init(x, y, r)
self.x = x
self.y = y
self.r = r
self.val = 0
end
function Speedometer:draw()
local x, y, r, s
x = self.x
y = self.y
r = self.r
if self.val > 270 then self.val = 270 end
font("ArialMT")
pushMatrix()
pushStyle()
translate(x, y)
fill(61, 61, 61, 255)
stroke(84, 84, 84, 255)
rect(-r/2-5, -r/2-5, r+10, r+10)
fill(19, 19, 19, 255)
ellipse(-r/2+5, -r/2+5, 10)
ellipse(-r/2+5, r/2-5, 10)
ellipse(r/2-5, -r/2+5, 10)
ellipse(r/2-5, r/2-5, 10)
strokeWidth(3)
fill(176, 176, 176, 255)
stroke(219, 191, 149, 255)
ellipse(0, 0, r)
stroke(141, 139, 139, 255)
ellipse(0,0,r-10)
stroke(0, 0, 0, 255)
noFill()
strokeWidth(19)
ellipse(0,0,r-50)
stroke(248, 248, 248, 255)
strokeWidth(13)
ellipse(0,0,r-55)
noStroke()
fill(176, 176, 176, 255)
if r > 160 then
rect(-r/2+20,0,40,40)
rect(-40,r/2-60,40,40)
rect(-50,15,40,40)
end
stroke(0, 0, 0, 255)
strokeWidth(1)
rotate(180)
fontSize(9)
fill(0, 0, 0, 255)
for i=0,27 do
line(r/2-37,0,r/2-30,0)
rotate(10)
if i/2 == math.floor(i/2) then
s = 260 - i * 10
text(s, r/2-15, 0)
end
end
rotate(-10)
-- set needle
rotate(-self.val)
stroke(255, 0, 0, 255)
strokeWidth(5)
line(0,0,r/3,0)
stroke(82, 82, 82, 255)
strokeWidth(3)
fill(90, 90, 90, 255)
stroke(219, 191, 149, 255)
ellipse(0, 0, 25)
stroke(141, 139, 139, 255)
ellipse(0,0,20)
fill(0, 0, 0, 255)
font("ArialMT")
fontSize(12)
popMatrix()
text("Speed", self.x, self.y - 20)
popStyle()
end
Throttle = class()
function Throttle:init(l, b, r, t)
-- you can accept and set parameters here
self.x = x
self.frame = Frame(l, b, r, t)
self.val = 0
end
function Throttle:draw()
local dy, vy
noStroke()
self.frame:gloss( color(155, 155, 155, 255))
pushMatrix()
pushStyle()
translate(self.frame.left, self.frame.bottom)
-- base
strokeWidth(3)
stroke(127, 127, 127, 255)
fill(92, 92, 92, 255)
rect(0, self.frame:height() - 40, self.frame:width(), 40)
stroke(167, 40, 23, 255)
line(20, 20, self.frame:width() - 20, 20)
stroke(35, 35, 35, 255)
line(20, self.frame:height() / 2 ,
50, self.frame:height() / 2)
line(20, self.frame:height() / 2 + 20,
50, self.frame:height() /2 + 20)
line(20, self.frame:height() / 2 - 20,
50, self.frame:height() /2 - 20)
-- axis
vy = 100 / (self.frame:height() - 40)
dy = self.val / vy + 40
noStroke()
fill(51, 51, 51, 255)
rect(self.frame:width()/2 - 15, self.frame:height()-40- dy, 5, dy)
fill(127, 127, 127, 255)
rect(self.frame:width()/2 - 10, self.frame:height()-40- dy, 10, dy)
fill(165, 165, 165, 255)
rect(self.frame:width()/2 - 0, self.frame:height()-40- dy, 15, dy)
fill(78, 31, 31, 255)
strokeWidth(1)
rect(self.frame:width()/2-35, self.frame:height()-40- dy + 15,
70, 20)
fill(43, 43, 43, 255)
rect(self.frame:width()/2-25, self.frame:height()-40- dy + 5,
50, 10)
rect(self.frame:width()/2-25, self.frame:height()-40- dy + 35,
50, 10)
-- knob
fontSize(14)
fill(0, 0, 0, 255)
text("Throttle", self.frame:width()/2, self.frame:height() - 20)
line(2, self.frame:height()-vy * 50 , 20,
self.frame:height()-vy * 50)
popStyle()
popMatrix()
end
function Throttle:touched(t)
local dy, vy
if self.frame:touched(t) then
dy = self.frame.top - 80 - t.y
vy = 100 / (self.frame:height() - 40)
self.val = dy * vy
end
if self.val < 0 then self.val = 0 end
end
My apologies on the length. I’m certain others here could have done it not just better, but more neatly and elegantly. But my coding style really hasn’t changed since the invention of rocks.
@Mark - Thanks for the code! And by the way, your coding style isn’t too bad. It’s good enough that I can almost tell what it does without running it.
Will you add an objetive or mission? I like all those control and the ground flow, good job, congrats!
@jaurix originally I had several runways and had all the plane’s trips require landing and stopping at those locations. But it was just too tough for starting off. Landing the plane successfully takes too much practice.
So I created the “fly to a target” bit as a warm up exercise. Then I… ran out of time.
I hope no one minds me digging up old projects and making zips of them.
There seems to be a problem with gameplay that I can’t solve: I have to tilt forward to turn the brakes off, but I can’t achieve liftoff without tilting upward, and any time I tilt upward the brakes turn on again!
It doesn’t seem from the above comments like this is how it’s supposed to run; can anyone spot what’s wrong in the code?
@UberGoober Thanks for consolidating these, it’s a very noble task
Tapping on the ‘Pilot’s Log’ it seemed to imply that the brake stuff was intended. I managed to get off the ground for all of about 5 seconds before I stalled at least :lol:
I’m happy to say I’ve also added this to codea-community-repo and can now be downloaded and run via the WebRepo project.
How did you get it off the ground? You have to tip the pad down or else the brakes activate but you have to tip the pad up to achieve liftoff. It’s an unsolvable riddle, like why people make fruitcake!
I can do it if I increase the throttle, tilt forward to release the breaks and then tilt back as I reach the end of the runway. Seems to work like that.