camera.py 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. import math
  2. import cocos
  3. import pyglet.window.key as key
  4. from app import keyboard_state
  5. class RTSCameraMotion(cocos.actions.Action):
  6. scale_levels = [0.5, 0.8, 1.0, 1.5, 2.0, 3.0, 5.0, 10.0]
  7. def __init__(self):
  8. super().__init__()
  9. def step(self, dt):
  10. position = getattr(self.target, 'position', (0, 0))
  11. speed = getattr(self.target, 'speed', (0, 0))
  12. force = getattr(self.target, 'force', 10000)
  13. mu_k = getattr(self.target, 'mu_k', 9)
  14. scale_request_idx = getattr(self.target, 'scale_request_idx', 3)
  15. # Handle Acceleration
  16. speed = (speed[0] + (keyboard_state[key.RIGHT] - keyboard_state[key.LEFT]) * dt * force,
  17. speed[1] + (keyboard_state[key.UP] - keyboard_state[key.DOWN]) * dt * force)
  18. # Handle Damping
  19. ds = (-mu_k*speed[0]*dt, -mu_k*speed[1]*dt)
  20. speed = (speed[0]+ds[0] if abs(ds[0]) < abs(speed[0]) else 0,
  21. speed[1]+ds[1] if abs(ds[1]) < abs(speed[1]) else 0)
  22. # Update position and speed
  23. self.target.speed = speed
  24. self.target.position = (position[0] + speed[0]*dt, position[1] + speed[1]*dt)
  25. if scroller := getattr(self.target, 'scroller'):
  26. scroller.set_focus(self.target.x, self.target.y)
  27. scroller.scale += 5*(self.scale_levels[scale_request_idx] - scroller.scale)*dt
  28. # Keep object in bounds as calculated by the scroller
  29. if self.target.x != scroller.restricted_fx:
  30. self.target.position = (scroller.restricted_fx, self.target.position[1])
  31. self.target.speed = (0.0, self.target.speed[1])
  32. if self.target.y != scroller.restricted_fy:
  33. self.target.position = (self.target.position[0], scroller.restricted_fy)
  34. self.target.speed = (self.target.speed[1], 0.0)
  35. class RTSCamera(cocos.layer.ScrollingManager):
  36. def __init__(self):
  37. pass
  38. def init(self):
  39. super().__init__()
  40. self.cam = cocos.cocosnode.CocosNode()
  41. self.cam.scroller = self
  42. self.cam_layer = cocos.layer.ScrollableLayer()
  43. self.cam_layer.add(self.cam)
  44. self.cam_motion = RTSCameraMotion()
  45. self.cam.do(self.cam_motion)
  46. self.add(self.cam_layer)
  47. self.overlay_layer = cocos.layer.ScrollableLayer()
  48. self.add(self.overlay_layer, z=1)
  49. @property
  50. def cam_position(self):
  51. return self.cam.position
  52. @cam_position.setter
  53. def cam_position(self, new_position):
  54. self.cam.position = new_position
  55. def zoom(self, delta):
  56. scale_request_idx_new = getattr(self.cam, 'scale_request_idx', 3) + delta
  57. if 0 <= scale_request_idx_new < len(self.cam_motion.scale_levels):
  58. self.cam.scale_request_idx = scale_request_idx_new
  59. camera = RTSCamera()