49_Urho2DIsometricDemo.lua 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. -- Urho2D tile map example.
  2. -- This sample demonstrates:
  3. -- - Creating an isometric 2D scene with tile map
  4. -- - Displaying the scene using the Renderer subsystem
  5. -- - Handling keyboard to move a character and zoom 2D camera
  6. -- - Generating physics shapes from the tmx file's objects
  7. -- - Displaying debug geometry for physics and tile map
  8. -- Note that this sample uses some functions from Sample2D utility class.
  9. require "LuaScripts/Utilities/Sample"
  10. require "LuaScripts/Utilities/2D/Sample2D"
  11. function Start()
  12. -- Set filename for load/save functions
  13. demoFilename = "Isometric2D"
  14. -- Execute the common startup for samples
  15. SampleStart()
  16. -- Create the scene content
  17. CreateScene()
  18. -- Create the UI content
  19. CreateUIContent("ISOMETRIC 2.5D DEMO")
  20. -- Hook up to the frame update events
  21. SubscribeToEvents()
  22. end
  23. function CreateScene()
  24. scene_ = Scene()
  25. -- Create the Octree, DebugRenderer and PhysicsWorld2D components to the scene
  26. scene_:CreateComponent("Octree")
  27. scene_:CreateComponent("DebugRenderer")
  28. local physicsWorld = scene_:CreateComponent("PhysicsWorld2D")
  29. physicsWorld.gravity = Vector2.ZERO -- Neutralize gravity as the character will always be grounded
  30. -- Create camera
  31. cameraNode = Node()
  32. local camera = cameraNode:CreateComponent("Camera")
  33. camera.orthographic = true
  34. camera.orthoSize = graphics.height * PIXEL_SIZE
  35. zoom = 2 * Min(graphics.width / 1280, graphics.height / 800) -- Set zoom according to user's resolution to ensure full visibility (initial zoom (2) is set for full visibility at 1280x800 resolution)
  36. camera.zoom = zoom
  37. -- Setup the viewport for displaying the scene
  38. renderer:SetViewport(0, Viewport:new(scene_, camera))
  39. renderer.defaultZone.fogColor = Color(0.2, 0.2, 0.2) -- Set background color for the scene
  40. -- Create tile map from tmx file
  41. local tmxFile = cache:GetResource("TmxFile2D", "Urho2D/Tilesets/atrium.tmx")
  42. local tileMapNode = scene_:CreateChild("TileMap")
  43. local tileMap = tileMapNode:CreateComponent("TileMap2D")
  44. tileMap.tmxFile = tmxFile
  45. local info = tileMap.info
  46. -- Create Spriter Imp character (from sample 33_SpriterAnimation)
  47. CreateCharacter(info, true, 0, Vector3(-5, 11, 0), 0.15)
  48. -- Generate physics collision shapes from the tmx file's objects located in "Physics" (top) layer
  49. local tileMapLayer = tileMap:GetLayer(tileMap.numLayers - 1)
  50. CreateCollisionShapesFromTMXObjects(tileMapNode, tileMapLayer, info)
  51. -- Instantiate enemies and moving platforms at each placeholder of "MovingEntities" layer (placeholders are Poly Line objects defining a path from points)
  52. PopulateMovingEntities(tileMap:GetLayer(tileMap.numLayers - 2))
  53. -- Instantiate coins to pick at each placeholder of "Coins" layer (placeholders for coins are Rectangle objects)
  54. PopulateCoins(tileMap:GetLayer(tileMap.numLayers - 3))
  55. -- Check when scene is rendered
  56. SubscribeToEvent("EndRendering", HandleSceneRendered)
  57. end
  58. function HandleSceneRendered()
  59. UnsubscribeFromEvent("EndRendering")
  60. SaveScene(true) -- Save the scene so we can reload it later
  61. scene_.updateEnabled = false -- Pause the scene as long as the UI is hiding it
  62. end
  63. function SubscribeToEvents()
  64. -- Subscribe HandleUpdate() function for processing update events
  65. SubscribeToEvent("Update", "HandleUpdate")
  66. -- Subscribe HandlePostUpdate() function for processing post update events
  67. SubscribeToEvent("PostUpdate", "HandlePostUpdate")
  68. -- Subscribe to PostRenderUpdate to draw physics shapes
  69. SubscribeToEvent("PostRenderUpdate", "HandlePostRenderUpdate")
  70. -- Unsubscribe the SceneUpdate event from base class to prevent camera pitch and yaw in 2D sample
  71. UnsubscribeFromEvent("SceneUpdate")
  72. end
  73. function HandleUpdate(eventType, eventData)
  74. -- Zoom in/out
  75. Zoom(cameraNode:GetComponent("Camera"))
  76. -- Toggle debug geometry with spacebar
  77. if input:GetKeyPress(KEY_Z) then drawDebug = not drawDebug end
  78. -- Check for loading / saving the scene
  79. if input:GetKeyPress(KEY_F5) then
  80. SaveScene()
  81. end
  82. if input:GetKeyPress(KEY_F7) then
  83. ReloadScene(false)
  84. end
  85. end
  86. function HandlePostUpdate(eventType, eventData)
  87. if character2DNode == nil or cameraNode == nil then
  88. return
  89. end
  90. cameraNode.position = Vector3(character2DNode.position.x, character2DNode.position.y, -10) -- Camera tracks character
  91. end
  92. function HandlePostRenderUpdate(eventType, eventData)
  93. if drawDebug then
  94. scene_:GetComponent("PhysicsWorld2D"):DrawDebugGeometry(true)
  95. end
  96. end
  97. -- Character2D script object class
  98. Character2D = ScriptObject()
  99. function Character2D:Start()
  100. self.wounded = false
  101. self.killed = false
  102. self.timer = 0
  103. self.maxCoins = 0
  104. self.remainingCoins = 0
  105. self.remainingLifes = 3
  106. end
  107. function Character2D:Update(timeStep)
  108. local node = self.node
  109. local animatedSprite = node:GetComponent("AnimatedSprite2D")
  110. -- Set direction
  111. local moveDir = Vector3.ZERO -- Reset
  112. local speedX = Clamp(MOVE_SPEED_X / zoom, 0.4, 1)
  113. local speedY = speedX
  114. if input:GetKeyDown(KEY_LEFT) or input:GetKeyDown(KEY_A) then
  115. moveDir = moveDir + Vector3.LEFT * speedX
  116. animatedSprite.flipX = false -- Flip sprite (reset to default play on the X axis)
  117. end
  118. if input:GetKeyDown(KEY_RIGHT) or input:GetKeyDown(KEY_D) then
  119. moveDir = moveDir + Vector3.RIGHT * speedX
  120. animatedSprite.flipX = true -- Flip sprite (flip animation on the X axis)
  121. end
  122. if not moveDir:Equals(Vector3.ZERO) then
  123. speedY = speedX * MOVE_SPEED_SCALE
  124. end
  125. if input:GetKeyDown(KEY_UP) or input:GetKeyDown(KEY_W) then
  126. moveDir = moveDir + Vector3.UP * speedY
  127. end
  128. if input:GetKeyDown(KEY_DOWN) or input:GetKeyDown(KEY_S) then
  129. moveDir = moveDir + Vector3.DOWN * speedY
  130. end
  131. -- Move
  132. if not moveDir:Equals(Vector3.ZERO) then
  133. node:Translate(moveDir * timeStep)
  134. end
  135. -- Animate
  136. if input:GetKeyDown(KEY_SPACE) then
  137. if animatedSprite.animation ~= "attack" then
  138. animatedSprite:SetAnimation("attack", LM_FORCE_LOOPED)
  139. end
  140. elseif not moveDir:Equals(Vector3.ZERO) then
  141. if animatedSprite.animation ~= "run" then
  142. animatedSprite:SetAnimation("run")
  143. end
  144. elseif animatedSprite.animation ~= "idle" then
  145. animatedSprite:SetAnimation("idle")
  146. end
  147. end