TestCamera.h 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. #pragma once
  2. #include "test.h"
  3. #include <map>
  4. DECLARE_SMART(Camera, spCamera);
  5. class Camera : public Actor
  6. {
  7. public:
  8. spActor _content;
  9. Camera()
  10. {
  11. addEventListener(TouchEvent::TOUCH_DOWN, CLOSURE(this, &Camera::onEvent));
  12. addEventListener(TouchEvent::TOUCH_UP, CLOSURE(this, &Camera::onEvent));
  13. addEventListener(TouchEvent::MOVE, CLOSURE(this, &Camera::onEvent));
  14. addEventListener(TouchEvent::WHEEL_DIR, CLOSURE(this, &Camera::onEvent));
  15. _transform.identity();
  16. }
  17. void setContent(spActor content)
  18. {
  19. _content = content;
  20. addChild(content);
  21. }
  22. struct touch
  23. {
  24. Vector2 current;
  25. Vector2 previous;
  26. };
  27. std::map<int, touch> _touches;
  28. void onEvent(Event* ev)
  29. {
  30. TouchEvent* te = safeCast<TouchEvent*>(ev);
  31. const Vector2& pos = te->localPosition;
  32. if (te->type == TouchEvent::TOUCH_DOWN)
  33. {
  34. touch& t = _touches[te->index];
  35. t.previous = t.current = pos;
  36. }
  37. if (te->type == TouchEvent::TOUCH_UP)
  38. {
  39. auto it = _touches.find(te->index);
  40. if (it != _touches.end())
  41. _touches.erase(it);
  42. }
  43. if (te->type == TouchEvent::WHEEL_DIR)
  44. {
  45. if (te->wheelDirection.y != 0.0f)
  46. {
  47. float scale = te->wheelDirection.y < 0 ? 0.95f : 1.05f;
  48. _transform.translate(-Vector3(pos.x, pos.y, 0));
  49. _transform.scale(Vector3(scale, scale, 1));
  50. _transform.translate(Vector3(pos.x, pos.y, 0));
  51. }
  52. }
  53. if (te->type == TouchEvent::MOVE && !_touches.empty())
  54. {
  55. touch& t = _touches[te->index];
  56. t.previous = t.current;
  57. t.current = pos;
  58. if (_touches.size() == 1)
  59. {
  60. Vector2 offset = t.current - t.previous;
  61. _transform.translate(Vector3(offset.x, offset.y, 0));
  62. }
  63. else
  64. {
  65. touch* p1, *p2;
  66. for (auto& t : _touches)
  67. {
  68. if (t.first == te->index)
  69. p1 = &t.second;
  70. else
  71. p2 = &t.second;
  72. }
  73. Vector2 center = (p1->current + p2->current) / 2;
  74. Vector2 prevCenter = (p1->previous + p2->previous) / 2;
  75. float dist = p1->current.distance(p2->current);
  76. float prevDist = p1->previous.distance(p2->previous);
  77. float scale = dist / prevDist;
  78. Vector2 offset = center - prevCenter;
  79. p1->previous = p1->current;
  80. p2->previous = p2->current;
  81. _transform.translate(Vector3(offset.x, offset.y, 0));
  82. _transform.translate(-Vector3(center.x, center.y, 0));
  83. _transform.scale(Vector3(scale, scale, 1));
  84. _transform.translate(Vector3(center.x, center.y, 0));
  85. }
  86. }
  87. update();
  88. }
  89. void doUpdate(const UpdateState& us)
  90. {
  91. }
  92. void update()
  93. {
  94. Transform tr(_transform);
  95. _content->setTransform(tr);
  96. }
  97. Matrix _transform;
  98. };
  99. class TestCamera : public Test
  100. {
  101. public:
  102. TestCamera()
  103. {
  104. spCamera cam = new Camera;
  105. cam->attachTo(content);
  106. cam->setSize(content->getSize());
  107. spSprite map = new Sprite();
  108. map->setResAnim(resources.getResAnim("map"));
  109. cam->setContent(map);
  110. spButton button = new Button;
  111. button->setPosition(map->getSize() / 2);
  112. button->setResAnim(resourcesUI.getResAnim("button"));
  113. button->attachTo(map);
  114. button->setAnchor(0.5f, 0.5f);
  115. button->addEventListener(TouchEvent::CLICK, CLOSURE(this, &TestCamera::testClick));
  116. }
  117. void testClick(Event* event)
  118. {
  119. notify("clicked");
  120. }
  121. };