/main.lua

http://github.com/ansca/TinyPenguin · Lua · 366 lines · 205 code · 118 blank · 43 comment · 28 complexity · 484dda49f2a19e62619fcf31e9f765c4 MD5 · raw file

  1. --
  2. -- Abstract: Tiny Penguin - aka Tiny Wings -
  3. --
  4. -- Version: 1.0
  5. --
  6. -- Sample code is MIT licensed, see http://developer.anscamobile.com/code/license
  7. -- Copyright (C) 2010-2011 ANSCA Inc. All Rights Reserved.
  8. -- Demonstrates how to use create draggable objects with multitouch. Also shows how to move
  9. -- an object to the front of the display hierarchy.
  10. require ("physics")
  11. physics.start()
  12. physics.setGravity(0,9.8)
  13. -- physics.setDrawMode("hybrid")
  14. local mainGroup = display.newGroup()
  15. local clouds = {}
  16. table.insert(clouds, "cloud_1.png");table.insert(clouds, "cloud_2.png")
  17. table.insert(clouds, "cloud_3.png");table.insert(clouds, "cloud_4.png")
  18. local cloudVelocityX = -40
  19. local hillToCloudRatio = 5
  20. local cloudInterval = 1
  21. local hillYPosition = display.contentHeight - display.contentHeight / 4 -- The y position of the bottom of the hill
  22. local sideBuffer = display.contentWidth
  23. -- The offset (where the bottom of a hill will be place)
  24. -- We want the offset to be a big negative so there is are hills to the left of the screen
  25. local hillOffSet = -sideBuffer
  26. local bird
  27. local birdRadius = 18
  28. local birdFixedCoordX = display.contentWidth / 5
  29. local minBirdHorzVel = 350--display.contentWidth / 10
  30. local birdAppliedForce = 0.15
  31. local hillHeight = 40
  32. local hillAmpMinValue = .5
  33. local hillAmpRange = .7
  34. local isFingerDown = false
  35. -- We need to put everything into a group so we can move it such that the bird is always in the same x coordinate (birdFixedCoordX)
  36. local imagesGroup = display.newGroup()
  37. local mainGroup = display.newGroup()
  38. local bird = display.newRect( 0, 0, 0, 0 )
  39. function main()
  40. display.setStatusBar( display.HiddenStatusBar )
  41. initBackground()
  42. initHills()
  43. initBird()
  44. startGame()
  45. end
  46. function initBackground()
  47. local img = display.newImage( "background.png", true)
  48. imagesGroup:insert(img)
  49. end
  50. function initBird()
  51. bird = display.newImage( "penguin.png", birdFixedCoordX, 300)
  52. physics.addBody(bird, "dynamic", {friction=0, bounce=0.1, radius=birdRadius})
  53. mainGroup:insert(bird)
  54. bird.isFixedRotation = false
  55. local onScreenTouch = function(event)
  56. if(event.phase == "began") then
  57. fingerDown = true
  58. end
  59. if(event.phase == "ended" or event.phase == "cancelled") then
  60. fingerDown = false
  61. end
  62. end
  63. bird.x1 = false
  64. bird.x2 = false
  65. bird.y1 = false
  66. bird.y2 = false
  67. bird.colName = false
  68. bird.isHit = function( x1 , x2 , y1 , y2 , colName )
  69. bird.x1 = x1
  70. bird.x2 = x2
  71. bird.y1 = y1
  72. bird.y2 = y2
  73. bird.colName = colName
  74. end
  75. bird.endHit = function( colName )
  76. if colName == bird.colName then
  77. bird.x1 = false
  78. bird.x2 = false
  79. bird.y1 = false
  80. bird.y2 = false
  81. bird.colName = false
  82. end
  83. end
  84. -- Makes the bird move at a min rate horizontally
  85. local moveBirdHorz = function(event)
  86. -- Touching Ground
  87. if bird.x1 ~= false then
  88. -- Matt - First Get Current Velocity
  89. local xVel, yVel = bird:getLinearVelocity()
  90. local vel = math.sqrt ( ( xVel * xVel ) + ( yVel * yVel ) )
  91. -- Calculate Slope Of Ground
  92. local birdAngle = -( math.atan2( bird.y1 - bird.y2 , bird.x1 - bird.x2 ) * ( 180 / math.pi ) )
  93. -- Rotate Bird
  94. bird.rotation = birdAngle
  95. --if ( vel < minBirdHorzVel ) then
  96. -- Matt - Calculate X Velocity Based On Bird Direction
  97. local newXVel = ( math.sin( ( birdAngle - 5 ) * math.pi / 180 ) * minBirdHorzVel )
  98. local newYVel = ( math.cos( ( birdAngle - 5 ) * math.pi / 180 ) * minBirdHorzVel )
  99. -- Matt - Apply New Velocity To Bird
  100. bird:setLinearVelocity( newYVel , newXVel )
  101. --end
  102. else
  103. -- Matt - First Get Current Velocity
  104. local xVel, yVel = bird:getLinearVelocity()
  105. -- Matt - Calculate Angle Of Travel
  106. local birdAngle = math.atan2( yVel , xVel ) * ( 180 / math.pi )
  107. -- Rotate Bird
  108. bird.rotation = birdAngle
  109. -- Matt - Calculate Velocity of Travel
  110. local vel = math.sqrt ( ( xVel * xVel ) + ( yVel * yVel ) )
  111. --print ( vel )
  112. -- Matt - Check Min Velocity Against Actual Velocity
  113. if ( vel < minBirdHorzVel ) then
  114. -- Matt - Calculate X Velocity Based On Bird Direction
  115. local newXVel = ( math.sin( birdAngle * math.pi / 180 ) * minBirdHorzVel )
  116. local newYVel = ( math.cos( birdAngle * math.pi / 180 ) * minBirdHorzVel )
  117. -- Matt - Apply New Velocity To Bird
  118. --bird:setLinearVelocity( newYVel , newXVel )
  119. end
  120. end
  121. end
  122. Runtime:addEventListener("touch", onScreenTouch)
  123. Runtime:addEventListener("enterFrame", moveBirdHorz)
  124. end
  125. -- Moves the main group such that the bird is always in a fixed x coord
  126. function startGame()
  127. local moveMainGroup = function(event)
  128. local birdContentCoordX, notNeeded = bird:localToContent(0,0)
  129. local diff = birdContentCoordX - birdFixedCoordX
  130. mainGroup.x = mainGroup.x - diff
  131. end
  132. Runtime:addEventListener("enterFrame", moveMainGroup)
  133. local increaseDifficulty = function(event)
  134. end
  135. end
  136. function createCloud()
  137. local cloud = display.newImage(clouds[math.random(1, #clouds)])
  138. cloud.y = hillYPosition * math.random()
  139. cloud.x = display.contentWidth + cloud.width / 2 + cloud.width * 2 * math.random()
  140. physics.addBody(cloud, "kinematic", {isSensor = true})
  141. cloud:setLinearVelocity(cloudVelocityX, 0)
  142. imagesGroup:insert(cloud)
  143. return clould
  144. end
  145. function initHills()
  146. while(hillOffSet < display.contentWidth + sideBuffer) do
  147. createHill()
  148. end
  149. end
  150. -- Creates one hill
  151. -- Code borrowed from: http://www.cocos2d-iphone.org/forum/topic/14136/page/3
  152. function createHill()
  153. local physicsBodyHeight = 30
  154. local x1 = hillOffSet
  155. local yStaringPosition = display.contentHeight - display.contentHeight / 4
  156. local h_height = hillHeight + math.random(hillHeight)
  157. -- Hill amplitude scale
  158. local h_amp = hillAmpMinValue + math.random() * hillAmpRange
  159. local y1 = h_height
  160. local objects = {}
  161. if(cloudInterval % hillToCloudRatio == 0) then
  162. local cloud = createCloud()
  163. table.insert(objects, cloud)
  164. end
  165. cloudInterval = cloudInterval + 1
  166. local lineGroup = display.newGroup()
  167. mainGroup:insert(lineGroup, 0)
  168. local angleStep = 20
  169. local angle
  170. for angle = angleStep, 360, angleStep do
  171. local points = {}
  172. local x2 = hillOffSet + angle/h_amp
  173. local y2 = h_height * math.cos(math.rad(angle))
  174. local rect = display.newRect(0,0,1,1)
  175. -- rect.isVisible = false
  176. -- Going to make a rectangle for each line segment
  177. table.insert(points, x2)
  178. table.insert(points, hillYPosition - h_height + y2 + physicsBodyHeight)
  179. table.insert(points, x1)
  180. table.insert(points, hillYPosition - h_height + y1 +physicsBodyHeight)
  181. table.insert(points, x1)
  182. table.insert(points, hillYPosition - h_height + y1)
  183. table.insert(points, x2)
  184. table.insert(points, hillYPosition - h_height + y2)
  185. -- Matt - Capturing values
  186. local startX = x2
  187. local startY = hillYPosition - h_height + y1
  188. local endX = x1
  189. local endY = hillYPosition - h_height + y2
  190. local fillAngle
  191. local fillX1, fillY2
  192. local fillX2, fillX2
  193. fillX2 = x2
  194. -- Fils in the hill with a color
  195. for fillAngle = angle - angleStep, angle do
  196. local fillX = hillOffSet + fillAngle/h_amp
  197. local fillY = h_height * math.cos(math.rad(fillAngle))
  198. local line = display.newLine(fillX, hillYPosition - h_height + fillY, fillX - 100, display.contentHeight)
  199. line:setColor(hsv(fillAngle % 360 == 0 and 1 or fillAngle,.4,.8))
  200. line.width = 3
  201. mainGroup:insert(line)
  202. table.insert(objects, line)
  203. end
  204. physics.addBody(rect, "static", {w=0, bounce=0.0, shape=points})
  205. mainGroup:insert(rect)
  206. table.insert(objects, rect)
  207. rect.xPos = x2
  208. rect.name = "col_"..x1
  209. -- Collision Handler
  210. rect.collision = function( self , event )
  211. -- On Collision
  212. if ( event.phase == "began" ) then
  213. event.other.isHit( startX , endX , startY , endY, rect.name )
  214. end
  215. if ( event.phase == "ended" ) then
  216. event.other.endHit(rect.name)
  217. end
  218. end
  219. rect:addEventListener( "collision" , rect )
  220. x1 = x2
  221. y1 = y2
  222. if(angle == 360) then
  223. local onRectEnterFrame
  224. onRectEnterFrame = function(event)
  225. local rectContentCoordX, notNeeded = rect:localToContent(rect.xPos,0)
  226. if(rectContentCoordX < 0) then
  227. Runtime:removeEventListener("enterFrame", onRectEnterFrame)
  228. for key,body in pairs(objects) do
  229. body:removeSelf()
  230. end
  231. createHill()
  232. end
  233. end
  234. Runtime:addEventListener("enterFrame", onRectEnterFrame)
  235. end
  236. end
  237. hillOffSet = x1
  238. mainGroup:insert(bird) -- Keep the bird on the top display levels
  239. end
  240. -- Helps us make pretty colors by converting hsv to rgb
  241. -- From http://pastebin.com/pqXgvyCs
  242. function hsv(h,s,v,a)
  243. local c, h_ = v*s, (h%360)/60
  244. local x = c*(1-(h_%2-1))
  245. local c_, m = ({{c,x,0},{x,c,0},{0,c,x},{0,x,c},{x,0,c},{c,0,x}})[math.ceil(h_)], v-c
  246. return (c_[1]+m)*255,(c_[2]+m)*255,(c_[3]+m)*255,a or 255
  247. end
  248. main()