Camera2D.hx 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. import h3d.Engine;
  2. import h2d.TextInput;
  3. import h2d.Camera;
  4. import h2d.Graphics;
  5. import h2d.TileGroup;
  6. import hxd.Key;
  7. import hxd.Res;
  8. //PARAM=-D resourcesPath=../../tiled_res
  9. class Camera2D extends SampleApp {
  10. var camera : Camera;
  11. var followCamera : Camera;
  12. var followPoint : Graphics;
  13. var sliderAnchorX : h2d.Slider;
  14. var sliderCamAnchorX : h2d.Slider;
  15. var sliderCamAnchorY : h2d.Slider;
  16. var sliderCamX : h2d.Slider;
  17. var sliderCamY : h2d.Slider;
  18. var sliderCamScaleX : h2d.Slider;
  19. var sliderCamScaleY : h2d.Slider;
  20. var cameraPositionMarker : h2d.Graphics;
  21. var reportCameraParameterChangedAfterSync : Bool = false;
  22. override function onResize() {
  23. super.onResize();
  24. // Change slider min max values according to screen size
  25. sliderCamX.minValue = -s2d.width; sliderCamX.maxValue = s2d.width;
  26. sliderCamY.minValue = -s2d.height; sliderCamY.maxValue = s2d.height;
  27. onCameraParameterChanged();
  28. reportCameraParameterChangedAfterSync=true;
  29. }
  30. private function setSliderAndTextInputValue( slider : h2d.Slider, value : Float ) {
  31. slider.value = value;
  32. var tf : h2d.TextInput = hxd.impl.Api.downcast(slider.parent.getChildAt(2),h2d.TextInput);
  33. if(tf!=null) tf.text = "" + hxd.Math.fmt(value);
  34. }
  35. private function onCameraParameterChanged() {
  36. updateCamSliderValues();
  37. cameraPositionMarker.x = camera.x;
  38. cameraPositionMarker.y = camera.y;
  39. }
  40. private function updateCamSliderValues() {
  41. setSliderAndTextInputValue(sliderCamAnchorX, camera.anchorX);
  42. setSliderAndTextInputValue(sliderCamAnchorY, camera.anchorY);
  43. setSliderAndTextInputValue(sliderCamScaleX, camera.scaleX);
  44. setSliderAndTextInputValue(sliderCamScaleY, camera.scaleY);
  45. setSliderAndTextInputValue(sliderCamX, camera.x);
  46. setSliderAndTextInputValue(sliderCamY, camera.y);
  47. }
  48. override private function init() {
  49. super.init();
  50. // Second camera for sample controls
  51. var uiCamera = new Camera();
  52. // layerVisible allows to filter out layers that camera should not render.
  53. uiCamera.layerVisible = (idx) -> idx == 2;
  54. s2d.add(fui, 2);
  55. // Add UI camera to scene. Note that order of cameras in array matters, as they are rendered in-order.
  56. s2d.addCamera(uiCamera);
  57. // Only one camera can handle user input events.
  58. // When assigning newly-created camera as interactiveCamera - adding it to Scene can be omitted, as it will be added automatically.
  59. s2d.interactiveCamera = uiCamera;
  60. // See Tiled sample
  61. var followX = s2d.width * .5;
  62. var followY = s2d.height * .5;
  63. var tileSize = 16;
  64. var tmx = Res.tileMap.toMap();
  65. var tset = Res.tiles.toTile();
  66. var tiles = tset.gridFlatten(tileSize, 0, 0);
  67. for ( l in tmx.layers ) {
  68. var group : TileGroup = new TileGroup(tset);
  69. // Props layer won't be visible on main camera, but will be visible in the follower camera.
  70. s2d.add(group, l.name == "Props" ? 1 : 0);
  71. group.x = followX - tmx.width * (tileSize / 2);
  72. group.y = followY - tmx.height * (tileSize / 2);
  73. var y = 0, x = 0;
  74. for (gid in l.data) {
  75. if (gid != 0) group.add(x * tileSize, y * tileSize, tiles[gid-1]);
  76. if (++x == tmx.width) {
  77. x = 0;
  78. y++;
  79. }
  80. }
  81. }
  82. addText("User arrow keys to move the green arrow");
  83. followPoint = new Graphics(s2d);
  84. followPoint.beginFill(0xff00);
  85. followPoint.moveTo(0, -5);
  86. followPoint.lineTo(5, 5);
  87. followPoint.lineTo(-5, 5);
  88. followPoint.setPosition(followX, followY);
  89. // Anchor allows to adjust the position of camera target relative to it's top-left corner in scene viewport ratio.
  90. // 0.5 would ensure that whatever position camera points at would at the center of it's viewport.
  91. // Providing Scene instance to camera constructor automatically adds it to the Scene camera list.
  92. followCamera = new Camera(s2d);
  93. // Set viewport to take up bottom-left quarter of the screen and clip out contents outside of it.
  94. followCamera.setAnchor(0.5, 0.5);
  95. followCamera.setViewport(s2d.width * .5, s2d.height * .5, s2d.width * .5, s2d.height * .5);
  96. followCamera.setScale(2, 2);
  97. followCamera.clipViewport = true;
  98. followCamera.layerVisible = (idx) -> idx != 2; // skip UI layer
  99. followCamera.follow = followPoint;
  100. followCamera.followRotation = true;
  101. // Scene.camera proeprty provides an alias to `Scene.cameras[0]`.
  102. camera = s2d.camera;
  103. camera.setAnchor(0.5, 0.5);
  104. camera.setPosition(s2d.width * .5, s2d.height * .5);
  105. camera.layerVisible = (idx) -> idx == 0;
  106. // Marker for primary camera position
  107. cameraPositionMarker = new h2d.Graphics(s2d);
  108. cameraPositionMarker.x= camera.x;
  109. cameraPositionMarker.y= camera.y;
  110. cameraPositionMarker.beginFill(0xff0000,0.5);
  111. cameraPositionMarker.drawRect(-10, -1, 20, 2);
  112. cameraPositionMarker.drawRect(-1, -10, 2, 20);
  113. cameraPositionMarker.endFill();
  114. addText("Camera controls");
  115. sliderCamAnchorX=addSlider("Anchor X", function() { return camera.anchorX; }, function(v) { camera.anchorX = v; onCameraParameterChanged();}, 0, 1);
  116. sliderCamAnchorY=addSlider("Anchor Y", function() { return camera.anchorY; }, function(v) { camera.anchorY = v; onCameraParameterChanged();}, 0, 1);
  117. sliderCamX=addSlider("X", function() { return camera.x; }, function(v) { camera.x = v; onCameraParameterChanged();}, -s2d.width, s2d.width);
  118. sliderCamY=addSlider("Y", function() { return camera.y; }, function(v) { camera.y = v; onCameraParameterChanged();}, -s2d.height, s2d.height);
  119. // Scale and rotation happens around anchored position, so in case of anchor [0.5, 0.5] it would scale and rotate around center of the camera viewport.
  120. addSlider("Rotation", function() { return hxd.Math.radToDeg(camera.rotation); }, function(v) { camera.rotation = hxd.Math.degToRad(v); onCameraParameterChanged(); }, 0, 360);
  121. sliderCamScaleX=addSlider("Scale X", function() { return camera.scaleX; }, function(v) { camera.scaleX = v; onCameraParameterChanged();}, 0, 5);
  122. sliderCamScaleY=addSlider("Scale Y", function() { return camera.scaleY; }, function(v) { camera.scaleY = v; onCameraParameterChanged();}, 0, 5);
  123. }
  124. override function render(e:Engine) {
  125. super.render(e);
  126. if(reportCameraParameterChangedAfterSync)
  127. {
  128. reportCameraParameterChangedAfterSync=false;
  129. onCameraParameterChanged();
  130. }
  131. }
  132. override function update(dt:Float) {
  133. super.update(dt);
  134. if (Key.isDown(Key.SHIFT)) dt *= 3;
  135. if (Key.isDown(Key.LEFT)) followPoint.rotation -= dt;
  136. if (Key.isDown(Key.RIGHT)) followPoint.rotation += dt;
  137. var forward = followPoint.rotation - Math.PI * .5;
  138. if (Key.isDown(Key.UP)) {
  139. followPoint.x += Math.cos(forward) * 60 * dt;
  140. followPoint.y += Math.sin(forward) * 60 * dt;
  141. }
  142. if (Key.isDown(Key.DOWN)) {
  143. followPoint.x -= Math.cos(forward) * 60 * dt;
  144. followPoint.y -= Math.sin(forward) * 60 * dt;
  145. }
  146. if (Key.isReleased(Key.SPACE)) {
  147. followPoint.setPosition(s2d.width * .5, s2d.height * .5);
  148. followPoint.rotation = 0;
  149. }
  150. }
  151. static function main() {
  152. hxd.Res.initEmbed();
  153. new Camera2D();
  154. }
  155. }