PageRenderTime 41ms CodeModel.GetById 30ms app.highlight 7ms RepoModel.GetById 1ms app.codeStats 1ms

/main.lua

http://github.com/ansca/TinyPenguin
Lua | 366 lines | 205 code | 118 blank | 43 comment | 22 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
  9-- Demonstrates how to use create draggable objects with multitouch. Also shows how to move
 10-- an object to the front of the display hierarchy.
 11
 12require ("physics")
 13
 14physics.start()
 15physics.setGravity(0,9.8)
 16-- physics.setDrawMode("hybrid")
 17
 18local mainGroup = display.newGroup()
 19
 20local clouds = {}
 21table.insert(clouds, "cloud_1.png");table.insert(clouds, "cloud_2.png")
 22table.insert(clouds, "cloud_3.png");table.insert(clouds, "cloud_4.png")
 23
 24local cloudVelocityX = -40
 25local hillToCloudRatio = 5
 26local cloudInterval = 1
 27
 28local hillYPosition = display.contentHeight  - display.contentHeight / 4 -- The y position of the bottom of the hill
 29
 30local sideBuffer = display.contentWidth
 31
 32-- The offset (where the bottom of a hill will be place)
 33-- We want the offset to be a big negative so there is are hills to the left of the screen
 34local hillOffSet =  -sideBuffer
 35
 36local bird
 37local birdRadius = 18
 38local birdFixedCoordX = display.contentWidth / 5
 39local minBirdHorzVel = 350--display.contentWidth / 10
 40local birdAppliedForce = 0.15
 41
 42local hillHeight = 40
 43local hillAmpMinValue = .5
 44local hillAmpRange = .7
 45local isFingerDown = false
 46
 47-- 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)
 48local imagesGroup = display.newGroup()
 49local mainGroup = display.newGroup()
 50
 51local bird = display.newRect( 0, 0, 0, 0 )
 52
 53function main()
 54	display.setStatusBar( display.HiddenStatusBar )	
 55	
 56	initBackground()
 57	
 58	initHills()
 59	initBird()
 60	
 61	startGame()
 62	
 63end
 64
 65function initBackground()
 66	
 67	local img = display.newImage( "background.png", true)
 68	imagesGroup:insert(img)
 69	
 70end
 71
 72function initBird()
 73	bird = display.newImage( "penguin.png", birdFixedCoordX, 300)
 74	physics.addBody(bird, "dynamic", {friction=0, bounce=0.1, radius=birdRadius})
 75	mainGroup:insert(bird)	
 76	bird.isFixedRotation = false
 77	
 78	local onScreenTouch = function(event)
 79		if(event.phase == "began") then
 80			fingerDown = true
 81		end
 82		
 83		if(event.phase == "ended" or event.phase == "cancelled") then
 84			fingerDown = false
 85		end
 86	end
 87	
 88	bird.x1 = false
 89	bird.x2 = false
 90	bird.y1 = false
 91	bird.y2 = false
 92	bird.colName = false
 93
 94	bird.isHit = function( x1 , x2 , y1 , y2 , colName )
 95	
 96		bird.x1 = x1
 97		bird.x2 = x2
 98		bird.y1 = y1
 99		bird.y2 = y2
100		bird.colName = colName
101	
102	end
103	
104	bird.endHit = function( colName )
105	
106		if colName == bird.colName then
107			bird.x1 = false
108			bird.x2 = false
109			bird.y1 = false
110			bird.y2 = false
111			bird.colName = false
112		end
113	
114	end
115
116	
117	-- Makes the bird move at a min rate horizontally 
118	local moveBirdHorz = function(event)
119		
120		-- Touching Ground
121		if bird.x1 ~= false then
122		
123			-- Matt - First Get Current Velocity
124			local xVel, yVel = bird:getLinearVelocity()
125			local vel = math.sqrt ( ( xVel * xVel ) + ( yVel * yVel ) )
126			
127			-- Calculate Slope Of Ground
128			local birdAngle = -( math.atan2( bird.y1 - bird.y2 , bird.x1 - bird.x2 ) * ( 180 / math.pi ) )
129			
130			-- Rotate Bird
131			bird.rotation = birdAngle
132			
133			--if ( vel < minBirdHorzVel ) then
134				-- Matt - Calculate X Velocity Based On Bird Direction
135				local newXVel = ( math.sin( ( birdAngle - 5 ) * math.pi / 180 ) * minBirdHorzVel )
136				local newYVel = ( math.cos( ( birdAngle - 5 ) * math.pi / 180 ) * minBirdHorzVel )
137				-- Matt - Apply New Velocity To Bird
138				bird:setLinearVelocity( newYVel , newXVel )
139				
140			--end
141		
142		else
143		
144			-- Matt - First Get Current Velocity
145			local xVel, yVel = bird:getLinearVelocity()
146
147			-- Matt - Calculate Angle Of Travel
148			local birdAngle = math.atan2( yVel , xVel ) * ( 180 / math.pi )
149			
150			-- Rotate Bird
151			bird.rotation = birdAngle
152			
153			-- Matt - Calculate Velocity of Travel
154			local vel = math.sqrt ( ( xVel * xVel ) + ( yVel * yVel ) )
155			--print ( vel )
156		
157			-- Matt - Check Min Velocity Against Actual Velocity
158			if ( vel < minBirdHorzVel ) then
159			
160				-- Matt - Calculate X Velocity Based On Bird Direction
161				local newXVel = ( math.sin( birdAngle * math.pi / 180 ) * minBirdHorzVel )
162				local newYVel = ( math.cos( birdAngle * math.pi / 180 ) * minBirdHorzVel )
163			
164				-- Matt - Apply New Velocity To Bird
165				--bird:setLinearVelocity( newYVel , newXVel )
166
167			end
168		
169		end
170		
171	end
172	
173	Runtime:addEventListener("touch", onScreenTouch)
174	Runtime:addEventListener("enterFrame", moveBirdHorz)
175
176
177end
178
179
180-- Moves the main group such that the bird is always in a fixed x coord
181function startGame()
182
183	local moveMainGroup = function(event) 
184		local birdContentCoordX, notNeeded = bird:localToContent(0,0)
185		local diff = birdContentCoordX - birdFixedCoordX
186		
187		mainGroup.x = mainGroup.x - diff
188	end
189	
190	
191	Runtime:addEventListener("enterFrame", moveMainGroup)
192
193	local increaseDifficulty = function(event)
194	
195	end
196end
197
198function createCloud()
199	
200	local cloud = display.newImage(clouds[math.random(1, #clouds)])
201	cloud.y = hillYPosition * math.random()
202	cloud.x = display.contentWidth + cloud.width / 2 + cloud.width * 2 * math.random()
203	
204	physics.addBody(cloud, "kinematic", {isSensor = true})
205	cloud:setLinearVelocity(cloudVelocityX, 0)
206
207	imagesGroup:insert(cloud)
208
209	return clould
210end
211
212
213function initHills()
214	
215	while(hillOffSet < display.contentWidth + sideBuffer) do			
216		createHill()
217	end
218end
219
220-- Creates one hill
221-- Code borrowed from: http://www.cocos2d-iphone.org/forum/topic/14136/page/3
222function createHill()
223	
224	local physicsBodyHeight = 30
225
226	local x1 = hillOffSet
227	local yStaringPosition = display.contentHeight  - display.contentHeight / 4
228	
229	local h_height = hillHeight + math.random(hillHeight) 
230		
231	-- Hill amplitude scale
232	local h_amp = hillAmpMinValue  + math.random() * hillAmpRange
233
234	local y1 = h_height
235	
236	local objects = {}	
237		
238	if(cloudInterval % hillToCloudRatio == 0) then 
239		local cloud = createCloud()
240		table.insert(objects, cloud)
241	end
242	cloudInterval = cloudInterval + 1
243	
244	local lineGroup = display.newGroup()
245	mainGroup:insert(lineGroup, 0)
246	
247	local angleStep = 20
248		
249	local angle
250	for angle = angleStep, 360, angleStep do
251			
252			local points = {}
253			
254			local x2 = hillOffSet + angle/h_amp
255			local y2 = h_height * math.cos(math.rad(angle))
256
257			local rect = display.newRect(0,0,1,1)
258			-- rect.isVisible = false
259			
260			-- Going to make a rectangle for each line segment 
261			table.insert(points, x2) 
262			table.insert(points, hillYPosition - h_height + y2 + physicsBodyHeight)
263				
264			table.insert(points, x1)
265			table.insert(points, hillYPosition - h_height + y1 +physicsBodyHeight)
266				
267			table.insert(points, x1)
268			table.insert(points, hillYPosition - h_height + y1)
269			
270			table.insert(points, x2)
271			table.insert(points, hillYPosition - h_height + y2)
272			
273			
274			-- Matt - Capturing values
275			local startX = x2
276			local startY = hillYPosition - h_height + y1
277			local endX = x1
278			local endY = hillYPosition - h_height + y2
279			
280			local fillAngle
281			local fillX1, fillY2
282			local fillX2, fillX2
283			fillX2 = x2
284			
285			-- Fils in the hill with a color
286			for fillAngle = angle - angleStep, angle do
287
288				local fillX = hillOffSet + fillAngle/h_amp
289				local fillY = h_height * math.cos(math.rad(fillAngle))
290				
291				local line = display.newLine(fillX, hillYPosition - h_height + fillY, fillX - 100, display.contentHeight)
292				line:setColor(hsv(fillAngle % 360 == 0 and 1 or fillAngle,.4,.8))
293				
294				line.width = 3
295				mainGroup:insert(line)
296				table.insert(objects, line)
297				
298			end
299			
300			physics.addBody(rect, "static", {w=0, bounce=0.0, shape=points})
301			mainGroup:insert(rect)
302			table.insert(objects, rect)
303			
304			rect.xPos = x2
305			
306			rect.name = "col_"..x1
307			-- Collision Handler
308			rect.collision = function( self , event )
309		
310				-- On Collision
311				if ( event.phase == "began" ) then
312			
313					event.other.isHit( startX , endX , startY , endY, rect.name )
314	
315				end
316				
317				if ( event.phase == "ended" ) then
318			
319					event.other.endHit(rect.name)
320	
321				end
322	
323			end
324			rect:addEventListener( "collision" , rect )
325
326			x1 = x2
327			y1 = y2	
328			
329			if(angle == 360) then
330
331				local onRectEnterFrame
332				onRectEnterFrame = function(event)
333
334					local rectContentCoordX, notNeeded = rect:localToContent(rect.xPos,0)
335					if(rectContentCoordX < 0) then 
336
337						Runtime:removeEventListener("enterFrame", onRectEnterFrame)
338						
339						for key,body in pairs(objects) do
340							body:removeSelf()
341						end
342						
343						createHill()
344					end
345				end
346				Runtime:addEventListener("enterFrame", onRectEnterFrame)
347			end
348		end
349		
350		hillOffSet = x1	
351		
352		
353	mainGroup:insert(bird) -- Keep the bird on the top display levels
354end
355
356-- Helps us make pretty colors by converting hsv to rgb
357-- From http://pastebin.com/pqXgvyCs
358function hsv(h,s,v,a)
359        local c, h_ = v*s, (h%360)/60
360        local x = c*(1-(h_%2-1))
361        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
362        
363		return (c_[1]+m)*255,(c_[2]+m)*255,(c_[3]+m)*255,a or 255
364end
365
366main()