DeukausGames

Enduro Game

Aug 7th, 2018
298
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 28.36 KB | None | 0 0
  1. --[[    ------------------------------------------------------------
  2.                            Main.lua
  3. --]]    ------------------------------------------------------------
  4. -- By DeukausGames
  5. -- global screen size constants
  6. bottomY = HEIGHT *.21
  7. trackWidth = WIDTH * .9 -- width of the track at the bottom
  8. horizonY = trackWidth * .55 + bottomY
  9. trackHeight = horizonY - bottomY
  10. trackLength = 100  -- in meters
  11.  
  12. -- main objects
  13. myCar = nil
  14. cars = {}
  15. day = nil
  16. track = nil
  17.  
  18. -- various global variables
  19. speed = 0                 -- for showing to the user
  20. location = 0              -- my location
  21. maxPosition = -1000       -- the location relative to me where the front-most car is
  22. lastCollisionT = -1000    -- last time i collided, for the penalty
  23. gameTime = 0              -- for reporting to the user
  24. startTime = 0             -- the time at which the game started
  25. accAngle = 0              -- gravity.z threshold for accelerating vs breaking
  26. days = 1                  -- which day we're on
  27. carsToPassInit = 150          -- on day 1 we need this many
  28. carsToPass = carsToPassInit   -- how many cars to advance to the next day
  29. gameOver = false
  30. gameStarted = false           -- whether the user has started the game
  31. gamePaused = false
  32. maxSpeed = 150
  33. regularSpeed = 85
  34.  
  35. function setup()
  36.     track = Track()
  37.     day = Day()
  38.     myCar = Car(0,0,0)
  39.     myCar.speed = 120
  40.    
  41.     watch("carsToPass")
  42.     watch("days")
  43.     watch("speed")
  44.     watch("location")
  45.  
  46.     print("Instructions:")
  47.     print("Angle fwd to accelerate")
  48.     print("Angle back to break")
  49.     print("Keep still to maintain speed")
  50.     print("Arrows to steer")
  51.     print("Touch the screen to start")
  52. end
  53.  
  54. function draw()
  55.     rectMode(CORNER)
  56.     ellipseMode(RADIUS)
  57.     speed = myCar.speed
  58.    
  59.     ------------- UPDATE GAME STATE ----------------
  60.     if not gameOver then
  61.         if not gameStarted or gamePaused then
  62.             stoppedUserInputs()
  63.         else
  64.             accelerating = runningUserInputs()     -- start, left, right, brake, etc
  65.            
  66.             -- move track around
  67.             turnTrack(gameTime,track)
  68.                
  69.             -- move the day forward in time
  70.             day:updateMode(gameTime)
  71.        
  72.             if gameStarted then
  73.                 gameTime = ElapsedTime - startTime
  74.                 location = location + DeltaTime*myCar.speed/100
  75.                 spawnNewCars()
  76.                 myCar:updateTireState()
  77.                 day:updateFogEnd(myCar.speed)
  78.             end
  79.        
  80.             -- if we're turning then apply the centrifugal force
  81.             centrifugal = track:centrifugal()
  82.             centrifugal = centrifugal * myCar.speed / 150
  83.             myCar.x = myCar.x + centrifugal/100
  84.             day:moveX(centrifugal*7)
  85.        
  86.             collided = checkForCollisions()
  87.             moveCars()
  88.         end
  89.     end
  90.  
  91.     --------------- DRAW ---------------
  92.     -- field, tracks, sky, controls, etc
  93.     drawBackground()
  94.    
  95.     --draw all cars
  96.     myCar:draw(track,day)
  97.     for i,c in ipairs(cars) do
  98.         if c.y > 0 and c.y <= .9*trackLength and c.real then
  99.             c:draw(track,day)
  100.         end
  101.     end
  102.    
  103.     day:drawFog()    -- has to be drawn last
  104.    
  105.     drawPauseButton()
  106.     drawUserFeedback(accelerating,collided)  -- userfedback at the bottom of the screen
  107. end
  108.  
  109. function moveCars()
  110.     maxPosition = -1000
  111.     for i,c in ipairs(cars) do
  112.         change = -DeltaTime*(myCar.speed-c.speed)/1.3
  113.         beforeY = c.y
  114.         c.y = c.y + change
  115.  
  116.         -- count carsPassed
  117.         if c.real then
  118.             if c.y<0 and beforeY>0 and not day.won then carsToPass = carsToPass - 1 end
  119.             if c.y>0 and beforeY<0 and not day.won then carsToPass = carsToPass + 1 end
  120.         end
  121.  
  122.         if carsToPass == 0 and not day.won then
  123.             day.won = true
  124.             print("Achievement unlocked: Day", days)
  125.         end
  126.  
  127.         -- remove cars
  128.         -- avoid collisions from the back by removing cars
  129.         if c.y>0 and beforeY<0 and collidesWithMyCar(c) then
  130.             table.remove(cars,i)
  131.         -- remove cars that are too far
  132.         elseif c.y < -5 * trackLength or c.y > 2 * trackLength then
  133.             table.remove(cars,i)
  134.         else c:updateTireState() end
  135.  
  136.         maxPosition = math.max(maxPosition,c.y)
  137.     end
  138. end
  139.  
  140. -- user inputs while the game is stopped
  141. function stoppedUserInputs()
  142.     if (CurrentTouch.state == BEGAN or CurrentTouch.state == MOVING ) then
  143.         if not gameStarted then
  144.             -- start game
  145.             gameStarted = true
  146.             startTime = ElapsedTime
  147.             accAngle = Gravity.z + .002
  148.         elseif gamePaused and pausePressed(CurrentTouch.x,CurrentTouch.y) then
  149.             gamePaused = false
  150.             accAngle = Gravity.z + .002
  151.         end
  152.     end
  153. end
  154.  
  155. -- user inputs while the game is running
  156. function runningUserInputs()
  157.     -- handle steering
  158.     if (CurrentTouch.state == BEGAN or CurrentTouch.state == MOVING ) then
  159.         if CurrentTouch.y < bottomY then
  160.             dx = .05
  161.             if day:inSnow() then dx = dx / 2 end
  162.             if CurrentTouch.x > .64 * WIDTH and CurrentTouch.x < .84 *WIDTH then
  163.                 -- go left
  164.                 myCar.x = myCar.x - dx
  165.             elseif CurrentTouch.x > .84 * WIDTH then
  166.                 -- go right
  167.                 myCar.x = myCar.x + dx
  168.             end
  169.         end
  170.        
  171.         if pausePressed(CurrentTouch.x,CurrentTouch.y) then gamePaused = true end
  172.     end
  173.  
  174.     -- handle acceleration
  175.     dz = Gravity.z - accAngle
  176.     if dz < -.03 then
  177.         myCar.speed = math.min(maxSpeed,myCar.speed+1)
  178.         return(1)
  179.     elseif dz > .08 then
  180.         myCar.speed = math.max(0,myCar.speed-3)
  181.         return(2)
  182.     end
  183.     return(3)
  184. end
  185.  
  186. lastPauseT = 0
  187. function pausePressed(x,y)
  188.     if ElapsedTime - lastPauseT < .1 then return(false) end
  189.     if x > WIDTH*.9 and y>HEIGHT*.9 then
  190.         lastPauseT = ElapsedTime
  191.         return(true)
  192.     else return(false) end
  193. end
  194.  
  195. -- turns the track left and right every now and then
  196. lastTurnT = 0
  197. function turnTrack(gameTime,track)
  198.     track:moveToTargetX()
  199.     if gameTime - lastTurnT > 5 then
  200.         track:newTargetX()
  201.         lastTurnT = gameTime
  202.     end
  203. end
  204.  
  205. function checkForCollisions()
  206.     -- with the walls
  207.     maxX = .75
  208.     if myCar.x > maxX or myCar.x < -maxX then
  209.         if myCar.x < 0 then
  210.             myCar.x = -maxX/1.2
  211.         else
  212.             myCar.x = maxX/1.2
  213.         end
  214.         myCar.speed = math.max(0,myCar.speed-maxSpeed/5)
  215.     end
  216.  
  217.     -- with other cars
  218.     for i, car in ipairs(cars) do
  219.         if collidesWithMyCar(car) then
  220.             lastCollisionT = ElapsedTime
  221.             break
  222.         end
  223.     end
  224.  
  225.     -- penalty for colliding for .5 seconds
  226.     if ElapsedTime - lastCollisionT < 1 then
  227.         myCar.speed = regularSpeed / 2
  228.         return(true)
  229.     else
  230.         return(false)
  231.     end
  232. end
  233.  
  234. -- check if this car collides with my car
  235. function collidesWithMyCar(car)
  236.     if not car.real then return(false) end
  237.     dx = math.abs(myCar.x - car.x)
  238.     dy = car.y - myCar.y
  239.     return(dx < 0.35 and dy > 0 and dy < 4)  -- based on car dimensions
  240. end
  241.  
  242. function drawBackground()
  243.     background(0, 0, 0, 255)
  244.  
  245.     -- field, track, sky, clouds
  246.     day:draw(track)
  247.  
  248.     -- botton
  249.     fill(0, 0, 0, 255)
  250.     rect(-5,0,WIDTH+10,bottomY)
  251.  
  252.     -- the left/right controls
  253.     fill(255, 255, 255, 255)
  254.     stroke(255, 255, 255, 255)
  255.     drawArrow(vec2(WIDTH*.82,bottomY*.5),180,WIDTH/750)
  256.     drawArrow(vec2(WIDTH*0.86,bottomY*.5),0,WIDTH/750)  
  257. end
  258.  
  259. function drawArrow(pos,orient,s)
  260.     pushMatrix()
  261.     resetMatrix()
  262.     pushStyle()
  263.     translate(pos.x,pos.y)
  264.     scale(s)
  265.     strokeWidth(13)
  266.     lineCapMode(PROJECT)
  267.     rotate(orient)
  268.     line(0, 0, 70,0)
  269.     line(73, 0, 50, 25)
  270.     line(73, 0,  50, -25)
  271.     popStyle()
  272.     popMatrix()
  273. end
  274.  
  275. function drawPauseButton()
  276.     pushMatrix()
  277.     translate(WIDTH*.93,HEIGHT*.93)
  278.     lineCapMode(PROJECT)
  279.     stroke(214, 214, 214, 255)
  280.     strokeWidth(10)
  281.     line(0,0,0,20)
  282.     line(12,0,12,20)
  283.     popMatrix()
  284. end
  285.  
  286. function drawUserFeedback(accelerating,collided)
  287.     if gameStarted and not gameOver then
  288.         if accelerating == 1 then
  289.             -- show green arrow forward
  290.             stroke(0, 255, 0, 255)
  291.             drawArrow(vec2(WIDTH*.1,bottomY*.25),90,WIDTH/750)
  292.         elseif accelerating == 2 then
  293.             -- show red arrow back
  294.             stroke(255,0,0,255)
  295.             drawArrow(vec2(WIDTH*.1,bottomY*.75),270,WIDTH/750)
  296.         end
  297.     end
  298.  
  299.     if collided then
  300.         strokeWidth(0)
  301.         fill(255, 243, 0, 255)
  302.         ellipse(WIDTH/2,bottomY*.5,bottomY*.25,bottomY*.25)
  303.     end
  304. end
  305.  
  306. -- why? because I was trying to get around the bug
  307. -- with sounds vs random and in the end I just didn't
  308. -- use sound
  309. function random()
  310.     return(math.random())
  311. end
  312.  
  313. --[[    ------------------------------------------------------------
  314.                            Track.lua
  315.  
  316.        Represents the track. Knows which way the horizon is pointing,
  317.        and how to draw tracks (both straight and curved)
  318.  
  319.        Note on coordinates in this class: x is in pixels relative
  320.        to the middle of the screen and y is in pixels in absolute
  321.        terms (from the bottom of the screen)
  322. --]]    ------------------------------------------------------------
  323.  
  324. Track = class()
  325.  
  326. DIRTH = 2 -- threshold at which tracks become straight, a couple of pixels from Width/2
  327.  
  328. function Track:init()
  329.     self.horizonX = 0                     -- which it's pointing now
  330.     self.horizonTargetX = self.horizonX   -- where eventually it will point
  331.  
  332.     -- the coordinates of the track at the bottom
  333.     bottomXR = trackWidth/2
  334.     bottomXL = -bottomXR
  335.     self.bottomL = vec2(bottomXL,bottomY)
  336.     self.bottomR = vec2(bottomXR,bottomY)
  337.  
  338.     -- these are calculated based on horizonX  when updated
  339.     self.horizonL = nil    -- coords of the track at the horizon
  340.     self.horizonR = nil
  341.     self.centerL = nil     -- center of curvature of the tracks
  342.     self.centerR = nil
  343.     self.rL = 0            -- radius of curvature of the tracks
  344.     self.rR = 0
  345.    
  346.     self:setHorizon(self.horizonTargetX)
  347. end
  348.  
  349. -- UPDATING FUNCTIONS
  350.  
  351. -- call this function to change the targetX to a new random position
  352. function Track:newTargetX()
  353.     self.horizonTargetX = math.floor(3*random()-1) * trackWidth/2
  354. end
  355.  
  356. -- call this function to move the horizonX closer to the target
  357. function Track:moveToTargetX()
  358.     dH = math.min(10,math.abs(self.horizonX-self.horizonTargetX))
  359.  
  360.     if self.horizonTargetX < self.horizonX then
  361.         self:setHorizon(self.horizonX-dH)
  362.     elseif self.horizonTargetX > self.horizonX then
  363.         self:setHorizon(self.horizonX+dH)
  364.     end
  365. end
  366.  
  367. -- x in pixels relative to the middle of the screen. negative is to the left
  368. function Track:setHorizon(x)
  369.     self.horizonX = x
  370.  
  371.     if self.horizonX < -DIRTH then
  372.         -- we're turning left
  373.  
  374.         -- left track
  375.         self.rL = .275 * trackWidth^2 / math.abs(self.horizonX)
  376.         self.horizonL = vec2(self.horizonX,horizonY)
  377.         self.centerL = circleCenter(self.bottomL,self.horizonL,self.rL,1,-1)
  378.  
  379.         -- right track
  380.         self.rR = 8 * self.rL
  381.         adj = -self.horizonX * WIDTH/trackWidth*.009 -- due to numerical error?
  382.         self.horizonR = vec2(self.horizonX,horizonY+adj)
  383.         self.centerR = circleCenter(self.bottomR,self.horizonR,self.rR,-1,-1)
  384.     elseif self.horizonX > DIRTH then
  385.         -- we're turning right
  386.  
  387.         -- right track
  388.         self.rR = .275 * trackWidth^2 / math.abs(self.horizonX)
  389.         self.horizonR = vec2(self.horizonX,horizonY)
  390.         self.centerR = circleCenter(self.bottomR,self.horizonR,self.rR,1,1)
  391.  
  392.         -- left track
  393.         self.rL = 8 * self.rR
  394.         adj = self.horizonX * WIDTH/trackWidth*.009  -- due to numerical error?
  395.         self.horizonL = vec2(self.horizonX,horizonY+adj)
  396.         self.centerL = circleCenter(self.bottomL,self.horizonL,self.rL,-1,1)
  397.     end
  398. end
  399.  
  400. -- calculates the center of a circle that passes through bottom and horizon
  401. -- both of which are vec2s and of radius r, returns a vec2
  402. -- ugly math ahead
  403. function circleCenter(bottom,horizon,r,mult1,mult2)
  404.     m = -(bottom.x-horizon.x)/(bottom.y-horizon.y)
  405.     b = (bottom.y+horizon.y-m*(bottom.x+horizon.x))/2
  406.     c1 = (1+m^2)
  407.     c2 = -(bottom.x+horizon.x)*c1
  408.     c3 = horizon.x^2 + (b-horizon.y)^2 - r^2
  409.     centerX = (-c2 + mult2 * math.sqrt(c2^2-4*c1*c3))/(2*c1)
  410.     centerY = mult1*math.sqrt(r^2-(centerX-bottom.x)^2)+bottom.y
  411.     return(vec2(centerX,centerY))
  412. end
  413.  
  414. -- GETTER FUNCTIONS
  415.  
  416. -- the centrifugal force on my car and clouds
  417. function Track:centrifugal()
  418.     return (-self.horizonX / (trackWidth/2))
  419. end
  420.  
  421. -- x coord of left track in pixels relative to Width/2
  422. -- y in metters
  423. function Track:leftAt(y)
  424.     return(self:atHelper(y,self.rL,self.centerL,-1))
  425. end
  426.  
  427. -- x coord of right track in pixels relative to Width/2
  428. -- y in metters
  429. function Track:rightAt(y)
  430.     return(self:atHelper(y,self.rR,self.centerR,1))
  431. end
  432.  
  433. function Track:atHelper(y,r,center,mult)
  434.     s = metersToPixels(y)
  435.     ys = s + bottomY
  436.    
  437.     if self.horizonX < -DIRTH then
  438.         -- turning left
  439.         xs = math.sqrt(r^2 - (ys - center.y)^2) + center.x
  440.         xs = xs - (9+mult*5)*s/trackHeight  -- numerical adjustment
  441.     elseif self.horizonX > DIRTH then
  442.         -- turning right
  443.         xs = -math.sqrt(r^2 - (ys - center.y)^2) + center.x
  444.         xs = xs + (9-mult*5)*s/trackHeight  -- numerical adjustment
  445.     else
  446.         -- going straight
  447.         xs = mult*(1-s/trackHeight) * trackWidth/2
  448.     end
  449.     return(xs)
  450. end
  451.  
  452. -- tracks y in meter (0,trackLength) and returns y in pixels relative to the bottom
  453. -- note that it's not a linear relationship due to perpective
  454. function metersToPixels(y)
  455.     s=y/trackLength
  456.     s = (1-s)^2.5
  457.     return((1-s)*trackHeight)
  458. end
  459.  
  460. function Track:draw()
  461.     pushStyle()
  462.     pushMatrix()
  463.     resetMatrix()
  464.  
  465.     lineCapMode(PROJECT)
  466.     translate(WIDTH/2,0)
  467.     stroke(183, 183, 183, 255)
  468.  
  469.     if math.abs(self.horizonX) <= DIRTH then
  470.         -- we're going straight
  471.         strokeWidth(5)
  472.         line(self.bottomL.x,self.bottomL.y,self.horizonX,horizonY)
  473.         line(self.bottomR.x,self.bottomR.y,self.horizonX,horizonY)
  474.     else
  475.         -- we're turning
  476.         strokeWidth(3)
  477.         noFill()
  478.         ellipse(self.centerL.x,self.centerL.y,self.rL,self.rL)
  479.         ellipse(self.centerR.x,self.centerR.y,self.rR,self.rR)
  480.     end
  481.  
  482.     popStyle()
  483.     popMatrix()
  484. end
  485.  
  486. --[[    ------------------------------------------------------------
  487.                            Day.lua
  488. --]]    ------------------------------------------------------------
  489.  
  490. Day = class()
  491.  
  492. function Day:init()
  493.     self.mode = 1         -- day, night, snow, etc
  494.     self.lastModeT = 0    -- last time we changed modes
  495.     self.clouds = {}
  496.     self.won = false      -- whether we passed all cars for this day
  497.     self.fogEnd = .5      -- for fog animation
  498.     self:makeClouds()
  499. end
  500.  
  501. function Day:makeClouds()
  502.     for i = 0, 5 do
  503.         minY = horizonY + HEIGHT / 15
  504.         maxY = HEIGHT - HEIGHT / 20
  505.         y = minY + random()*(maxY-minY)
  506.         cloud = Cloud(random()*WIDTH,y)
  507.         table.insert(self.clouds,cloud)
  508.     end
  509. end
  510.  
  511. function Day:inSnow()
  512.     return(modes[self.mode].snow)
  513. end
  514.  
  515. -- moves the day mode forward
  516. function Day:updateMode(gameTime)
  517.     if gameTime - self.lastModeT > modes[self.mode].length then -- time to change mode
  518.         self.mode = self.mode%numModes+1
  519.         self.lastModeT = gameTime
  520.         if self.mode == 1 then   -- end of the day
  521.             if carsToPass > 0 then
  522.                 print("GAME OVER")
  523.                 gameOver = true -- global variable
  524.             else
  525.                 carsToPass = carsToPassInit + 40 * days
  526.                 maxSpeed = maxSpeed + 10
  527.                 days = days + 1
  528.                 self.won = false
  529.             end
  530.         end
  531.     end
  532. end
  533.  
  534. -- moves the clounds around
  535. function Day:moveX(dx)
  536.     for i,cloud in ipairs(self.clouds) do
  537.         cloud:moveX(dx)
  538.         -- handle a clound disappearing at the edges
  539.         if cloud.position.x < -200 or cloud.position.x > WIDTH + 200 then
  540.             table.remove(self.clouds,i)
  541.             -- make a new one
  542.             minY = horizonY + HEIGHT / 15
  543.             maxY = HEIGHT - HEIGHT / 20
  544.             y = minY + random()*(maxY-minY)
  545.             x = random()*WIDTH/8
  546.             if dx>0 then x = -x else x = x + WIDTH end  -- start it a little of screen
  547.             cloud = Cloud(x,y)
  548.             table.insert(self.clouds,cloud)
  549.         end
  550.     end
  551. end
  552.  
  553. -- needs track because we need to draw track in between the field and the sky
  554. function Day:draw(track)
  555.     -- green field
  556.     strokeWidth(0)
  557.     fill(modes[self.mode].field)
  558.     rect(-5, bottomY, WIDTH+10, horizonY)
  559.  
  560.     -- track
  561.     track:draw()
  562.  
  563.     -- sky
  564.     strokeWidth(0)
  565.     fill(modes[self.mode].sky)
  566.     rect(-5, horizonY, WIDTH+10, HEIGHT)
  567.  
  568.     -- sunset
  569.     sunsetW = (HEIGHT-horizonY)*.02
  570.     if modes[self.mode].sunseta ~= nil then
  571.         fill(modes[self.mode].sunseta)
  572.         rect(-5,horizonY,WIDTH+10,sunsetW+1)
  573.     end
  574.     if modes[self.mode].sunsetb ~= nil then
  575.         fill(modes[self.mode].sunsetb)
  576.         rect(-5,horizonY+sunsetW,WIDTH+10,sunsetW+1)
  577.     end
  578.     if modes[self.mode].sunsetc ~= nil then
  579.         fill(modes[self.mode].sunsetc)
  580.         rect(-5,horizonY+sunsetW*2,WIDTH+10,sunsetW+1)
  581.     end
  582.  
  583.     -- clouds
  584.     for i,cloud in ipairs(self.clouds) do
  585.         cloud:draw(modes[self.mode].cloud1,modes[self.mode].cloud2)
  586.     end
  587. end
  588.  
  589. function Day:updateFogEnd(speed)
  590.     self.fogEnd = self.fogEnd - speed/20000
  591.     if self.fogEnd < .5 then self.fogEnd = .6 end
  592. end
  593.  
  594. function Day:drawFog()
  595.     strokeWidth(0)
  596.     if modes[self.mode].fog then
  597.         fill(74,74,74,255)
  598.         rect(-5,bottomY+(horizonY-bottomY)*self.fogEnd,WIDTH+10,HEIGHT)
  599.     end
  600. end
  601.  
  602. --[[    ------------------------------------------------------------
  603.                            Car.lua
  604. --]]    ------------------------------------------------------------
  605.  
  606. dayCarColors = {
  607.     color(255, 0, 0, 255),
  608.     color(0, 35, 255, 255),
  609.     color(11, 255, 0, 255),
  610.     color(255, 245, 0, 255)
  611. }
  612.  
  613. nightCarColors = {
  614.     color(255, 0, 0, 255),
  615.     color(255, 0, 188, 255),
  616.     color(255, 0, 188, 255),
  617.     color(255, 0, 0, 255)
  618. }
  619.  
  620. Car = class()
  621.  
  622. function Car:init(x,y,color)
  623.     self.x = x    -- between -1 and 1
  624.     self.y = y    -- from 0 to trackLength in meters
  625.     self.color = color
  626.     self.speed = regularSpeed
  627.     self.real = true  -- unreal cars help with spawning
  628.     self.tireState = true  -- for tire animation
  629.     self.tireStateHelper = 0
  630. end
  631.  
  632. function Car:updateTireState()
  633.     self.tireStateHelper = self.tireStateHelper + self.speed / 60
  634.     if self.tireStateHelper > 5 then
  635.         self.tireStateHelper = 0
  636.         self.tireState = not self.tireState
  637.     end
  638. end
  639.  
  640. function Car:draw(track,day)
  641.     -- coords of the track at this y
  642.     leftX = track:leftAt(self.y)
  643.     rightX = track:rightAt(self.y)
  644.  
  645.     -- my coord at this y
  646.     x = ((1+self.x)*rightX + (1-self.x)*leftX)/2
  647.  
  648.     s = metersToPixels(self.y) -- implemented in the track class
  649.     self:drawHelper(x,s,1-s/trackHeight,self.color,self.tireState,day)
  650. end
  651.  
  652. -- x relative to middle of the screen in pixels, y relative to the bottom of the track
  653. -- scale relative to a car at the bottom of the screen
  654. -- tireState is true or false, for animation
  655. function Car:drawHelper(x,y,s,colorIdx,tireState,day)
  656.     pushMatrix()
  657.     pushStyle()
  658.     resetMatrix()
  659.     translate(WIDTH/2+x,bottomY+y)
  660.     scale(trackWidth*s/90,trackHeight*s/108)
  661.  
  662.     if colorIdx == 0 then -- hack for my car
  663.         thisColor = color(190,190,190,255)
  664.     elseif modes[day.mode].rearlights then
  665.         thisColor = nightCarColors[colorIdx]
  666.     else
  667.         thisColor = dayCarColors[colorIdx]
  668.     end
  669.  
  670.     fill(thisColor)
  671.     stroke(thisColor)
  672.     strokeWidth(2)
  673.  
  674.     if not modes[day.mode].rearlights or colorIdx == 0 then
  675.         -- regular car
  676.         rect(-4,1,8,7) -- body horizontal
  677.         rect(-2,0,4,12) -- body vertical
  678.         rect(-6,8,12,3) -- top wing
  679.         rect(-6,8,3,4) -- left wing
  680.         rect(3,8,3,4) -- right wing
  681.         for i = 0,7 do
  682.             if tireState == (i%2==0) then startX = -8 else startX = -6 end
  683.             rect(startX,i,3,2)
  684.             rect(startX+11,i,3,2)
  685.         end
  686.     else
  687.         -- rear lights
  688.         rect(2,0,5,4)
  689.         rect(-6,0,5,4)
  690.     end
  691.     popMatrix()
  692.     popStyle()
  693. end
  694.  
  695. function spawnNewCars()
  696.     if maxPosition < 65 then -- space the cars apart
  697.         rand1 = random()
  698.         if rand1 < 0.7 then
  699.             -- spawn one car
  700.             x = (math.floor(3*random())-1)/2
  701.             newCar = Car(x,.9*trackLength,randColor())
  702.             table.insert(cars,newCar)
  703.         else
  704.             newCar = Car(0,.9*trackLength,randColor())
  705.             newCar.real = false
  706.             table.insert(cars,newCar)
  707.         end
  708.     end
  709. end
  710.  
  711. -- used above
  712. function randColor()
  713.     ncolors = table.maxn(dayCarColors)
  714.     idx = math.ceil(random()*ncolors)
  715.     return(idx)
  716. end
  717.  
  718. --[[    ------------------------------------------------------------
  719.                            Cloud.lua
  720. --]]    ------------------------------------------------------------
  721. Cloud = class()
  722.  
  723. function Cloud:init(x,y)
  724.     -- you can accept and set parameters here
  725.     self.shapes = {}
  726.     self.position = vec2(x,y)
  727.  
  728.     -- Generate random cloud
  729.     numCircles = 4
  730.     spacing = 20
  731.  
  732.     for i = 1,numCircles do
  733.         x = i * spacing - ((numCircles/2)*spacing)
  734.         y = (random() - 0.5) * 20
  735.         rad = spacing*random()+spacing
  736.         table.insert(self.shapes, {x=x, y=y, r=rad})
  737.     end
  738.  
  739.     self.width = numCircles * spacing + spacing
  740. end
  741.  
  742. function Cloud:moveX(dx)
  743.     self.position.x = self.position.x + dx
  744. end
  745.  
  746. function Cloud:draw(c1,c2)
  747.     pushStyle()
  748.     pushMatrix()
  749.  
  750.     translate(self.position.x, self.position.y)
  751.  
  752.     -- noStroke()
  753.     strokeWidth(-1)
  754.     fill(c2)
  755.  
  756.     for i,s in ipairs(self.shapes) do
  757.         ellipse(s.x, s.y - 5, s.r)
  758.     end
  759.  
  760.     fill(c1)
  761.  
  762.     for i,s in ipairs(self.shapes) do
  763.         ellipse(s.x, s.y + 5, s.r)
  764.     end
  765.  
  766.     popMatrix()
  767.     popStyle()
  768. end
  769.  
  770. --[[    ------------------------------------------------------------
  771.                            DayModes.lua
  772. --]]    ------------------------------------------------------------
  773.  
  774. modes = {
  775.     {     -- morning
  776.         length = 14,
  777.         field = color(0,68,0,255),
  778.         sky = color(24,26,167,255),
  779.         sunseta = nil,
  780.         sunsetb = nil,
  781.         sunsetc = nil,
  782.         cloud1 = color(255,255,255,255),
  783.         cloud2 = color(167,190,221,255),
  784.         rearlights = false,
  785.         snow = false,
  786.         fog = false
  787.     },
  788.  
  789.     {     -- day1
  790.         length = 17,
  791.         field = color(0,68,0,255),
  792.         sky = color(35,38,170,255),
  793.         sunseta = nil,
  794.         sunsetb = nil,
  795.         sunsetc = nil,
  796.         cloud1 = color(255, 255, 255, 255),
  797.         cloud2 = color(167,190,221,255),
  798.         rearlights = false,
  799.         snow = false,
  800.         fog = false
  801.     },
  802.  
  803.     {     -- day2
  804.         length = 17,
  805.         field = color(0,68,0,255),
  806.         sky = color(45,50,184,255),
  807.         sunseta = nil,
  808.         sunsetb = nil,
  809.         sunsetc = nil,
  810.         cloud1 = color(255,255,255,255),
  811.         cloud2 = color(167,190,221,255),
  812.         rearlights = false,
  813.         snow = false,
  814.         fog = false
  815.     },
  816.    
  817.     {     -- snow
  818.         length = 34,
  819.         field = color(255,255,255,255),
  820.         sky = color(45,50,184,255),
  821.         sunseta = nil,
  822.         sunsetb = nil,
  823.         sunsetc = nil,
  824.         cloud1 = color(255,255,255,255),
  825.         cloud2 = color(167,190,221,255),
  826.         rearlights = false,
  827.         snow = true,
  828.         fog = false
  829.     },
  830.    
  831.     {     -- afternoon
  832.         length = 4,
  833.         field = color(20,60,0,255),
  834.         sky = color(24,26,167,255),
  835.         sunseta = nil,
  836.         sunsetb = nil,
  837.         sunsetc = nil,
  838.         cloud1 = color(255,255,255,255),
  839.         cloud2 = color(167,190,221,255),
  840.         rearlights = false,
  841.         snow = false,
  842.         fog = false
  843.     },
  844.  
  845.     {     -- sunset1
  846.         length = 4,
  847.         field = color(20,60,0,255),
  848.         sky = color(24,26,167,255),
  849.         sunseta = color(104,25,154,255),
  850.         sunsetb = color(51,26,163,255),
  851.         cloud1 = color(255,255,255,255),
  852.         cloud2 = color(167,190,221,255),
  853.         sunsetc = nil,
  854.         rearlights = false,
  855.         snow = false,
  856.         fog = false
  857.     },
  858.  
  859.     {     -- sunset2
  860.         length = 4,
  861.         field = color(20,60,0,255),
  862.         sky = color(51,26,163,255),
  863.         sunseta = color(151,25,122,255),
  864.         sunsetb = color(104,25,154,255),
  865.         sunsetc = nil,
  866.         cloud1 = color(255, 255, 255, 255),
  867.         cloud2 = color(226, 220, 199, 255),
  868.         rearlights = false,
  869.         snow = false,
  870.         fog = false
  871.     },
  872.  
  873.     {     -- sunset3
  874.         length = 4,
  875.         field = color(20,60,0,255),
  876.         sky = color(51,26,163,255),
  877.         sunseta = color(167,26,26,255),
  878.         sunsetb = color(151,25,122,255),
  879.         sunsetc = color(104,25,154,255),
  880.         cloud1 = color(255,255,255,255),
  881.         cloud2 = color(212, 202, 169, 255),
  882.         rearlights = false,
  883.         snow = false,
  884.         fog = false
  885.     },
  886.  
  887.     {     -- sunset4
  888.         length = 4,
  889.         field = color(48,56,0,255),
  890.         sky = color(104,25,154,255),
  891.         sunseta = color(163,57,21,255),
  892.         sunsetb = color(167,26,26,255),
  893.         sunsetc = color(151,25,122,255),
  894.         cloud1 = color(230, 230, 230, 255),
  895.         cloud2 = color(193, 168, 107, 255),
  896.         rearlights = false,
  897.         snow = false,
  898.         fog = false
  899.     },
  900.  
  901.     {     -- sunset5
  902.         length = 4,
  903.         field = color(48,56,0,255),
  904.         sky = color(151,25,122,255),
  905.         sunseta = color(181,83,40,255),
  906.         sunsetb = color(163,57,21,255),
  907.         sunsetc = color(167,26,26,255),
  908.         cloud1 = color(204, 204, 204, 255),
  909.         cloud2 = color(251,228,187,255),
  910.         rearlights = false,
  911.         snow = false,
  912.         fog = false
  913.     },
  914.  
  915.     {     -- sunset6
  916.         length = 4,
  917.         field = color(48,56,0,255),
  918.         sky = color(167,26,26,255),
  919.         sunseta = color(162,98,33,255),
  920.         sunsetb = color(181,83,40,255),
  921.         sunsetc = color(163,57,21,255),
  922.         cloud1 = color(179, 179, 179, 255),
  923.         cloud2 = color(255,194,104,255),
  924.         rearlights = false,
  925.         snow = false,
  926.         fog = false
  927.     },
  928.  
  929.     {     -- sunset7
  930.         length = 4,
  931.         field = color(48,56,0,255),
  932.         sky = color(163,57,21,255),
  933.         sunseta = color(134,134,29,255),
  934.         sunsetb = color(162,98,33,255),
  935.         sunsetc = color(181,83,40,255),
  936.         cloud1 = color(156, 156, 156, 255),
  937.         cloud2 = color(254,157,133,255),
  938.         rearlights = false,
  939.         snow = false,
  940.         fog = false
  941.     },
  942.  
  943.     {     -- night1
  944.         length = 34,
  945.         field = color(0,0,0,255),
  946.         sky = color(74,74,74,255),
  947.         sunseta = nil,
  948.         sunsetb = nil,
  949.         sunsetc = nil,
  950.         cloud1 = color(127, 127, 127, 255),
  951.         cloud2 = color(207, 207, 207, 255),
  952.         rearlights = true,
  953.         snow = false,
  954.         fog = false
  955.     },
  956.  
  957.     {     -- fog
  958.         length = 34,
  959.         field = color(74,74,74,255),
  960.         sky = color(74,74,74,255),
  961.         sunseta = nil,
  962.         sunsetb = nil,
  963.         sunsetc = nil,
  964.         cloud1 = color(255,255,255,255),
  965.         cloud2 = color(167,190,221,255),
  966.         rearlights = true,
  967.         snow = false,
  968.         fog = true
  969.     },
  970.  
  971.     {     -- night2
  972.         length = 17,
  973.         field = color(0,0,0,255),
  974.         sky = color(74,74,74,255),
  975.         sunseta = nil,
  976.         sunsetb = nil,
  977.         sunsetc = nil,
  978.         cloud1 = color(127,127,127,255),
  979.         cloud2 = color(207,207,207,255),
  980.         rearlights = true,
  981.         snow = false,
  982.         fog = false
  983.     },
  984.  
  985.     {     -- sunrise
  986.         length = 17,
  987.         field = color(0,0,0,255),
  988.         sky = color(111,111,111,255),
  989.         sunseta = nil,
  990.         sunsetb = nil,
  991.         sunsetc = nil,
  992.         cloud1 = color(159, 159, 159, 255),
  993.         cloud2 = color(200, 200, 200, 255),
  994.         rearlights = false,
  995.         snow = false,
  996.         fog = false
  997.     }
  998. }
  999.  
  1000. numModes = table.maxn(modes)
Advertisement
Add Comment
Please, Sign In to add comment