Browse Source

add Camera2D node.

SakiKawasaki 5 years ago
parent
commit
d00f40c162

+ 1 - 0
README.md

@@ -95,6 +95,7 @@
    -  [YSort](https://ethosa.github.io/nodesnim/nodesnim/nodes2d/ysort.html)
    -  [CollisionShape2D](https://ethosa.github.io/nodesnim/nodesnim/nodes2d/collision_shape2d.html)
    -  [KinematicBody2D](https://ethosa.github.io/nodesnim/nodesnim/nodes2d/kinematic_body2d.html)
+   -  [Camera2D](https://ethosa.github.io/nodesnim/nodesnim/nodes2d/camera2d.html)
 
 </details>
 

+ 3 - 2
src/nodesnim.nim

@@ -65,7 +65,8 @@ import
   nodesnim/nodes2d/animated_sprite,
   nodesnim/nodes2d/ysort,
   nodesnim/nodes2d/collision_shape2d,
-  nodesnim/nodes2d/kinematic_body2d
+  nodesnim/nodes2d/kinematic_body2d,
+  nodesnim/nodes2d/camera2d
 
 export
   # Third party
@@ -82,4 +83,4 @@ export
   rich_label, rich_edit_text, scroll, progress_bar, vprogress_bar, slider, vslider, popup,
   texture_button, texture_progress_bar, counter, switch,
   # 2D nodes
-  node2d, sprite, animated_sprite, ysort, collision_shape2d, kinematic_body2d
+  node2d, sprite, animated_sprite, ysort, collision_shape2d, kinematic_body2d, camera2d

+ 1 - 0
src/nodesnim/core/enums.nim

@@ -19,6 +19,7 @@ type
     AUDIO_STREAM_PLAYER_NODE,
     COLLISION_SHAPE_2D_NODE,
     YSORT_NODE,
+    CAMERA_2D_NODE,
     SPRITE_NODE,
     ANIMATED_SPRITE_NODE,
     NODE2D_NODE,

+ 0 - 4
src/nodesnim/nodes/scene.nim

@@ -37,10 +37,6 @@ method drawScene*(scene: ScenePtr, w, h: GLfloat, paused: bool) {.base.} =
       continue
     if child.visible:
       child.calcGlobalPosition()
-      if child.global_position.x > w or child.global_position.y > h:
-        continue
-      elif child.global_position.x < 0 - child.rect_size.x or child.global_position.y < 0 - child.rect_size.y:
-        continue
       if not child.is_ready:
         child.on_ready(child)
         child.is_ready = true

+ 91 - 0
src/nodesnim/nodes2d/camera2d.nim

@@ -0,0 +1,91 @@
+# author: Ethosa
+import
+  ../thirdparty/opengl,
+
+  ../core/vector2,
+  ../core/rect2,
+  ../core/anchor,
+  ../core/input,
+  ../core/enums,
+
+  ../nodes/node,
+  node2d
+
+
+type
+  Camera2DObj* = object of Node2DObj
+    current*: bool
+    target*: NodePtr
+    limit*: AnchorRef
+  Camera2DPtr* = ptr Camera2DObj
+
+
+var nodes: seq[Camera2DPtr] = @[]
+
+
+proc Camera2D*(name: string, variable: var Camera2DObj): Camera2DPtr =
+  ## Creates a new Camera2D pointer.
+  ##
+  ## Arguments:
+  ## - `name` is a node name.
+  ## - `variable` is a Camera2DObj variable.
+  runnableExamples:
+    var
+      node_obj: Camera2DObj
+      node = Camera2D("Camera2D", node_obj)
+  nodepattern(Camera2DObj)
+  node2dpattern()
+  variable.limit = Anchor(-100000, -100000, 100000, 100000)
+  variable.current = false
+  variable.kind = CAMERA_2D_NODE
+  nodes.add(result)
+
+proc Camera2D*(obj: var Camera2DObj): Camera2DPtr {.inline.} =
+  ## Creates a new Camera2D pointer with deffault node name "Camera2D".
+  ##
+  ## Arguments:
+  ## - `variable` is a Camera2DObj variable.
+  runnableExamples:
+    var
+      node_obj: Camera2DObj
+      node = Camera2D(node_obj)
+  Camera2D("Camera2D", obj)
+
+
+method draw*(self: Camera2DPtr, w, h: GLfloat) =
+  ## this method uses in the `window.nim`.
+  {.warning[LockLevel]: off.}
+  self.position = self.timed_position
+
+  if self.centered:
+    self.position = self.timed_position - self.rect_size*2
+  else:
+    self.position = self.timed_position
+
+  if self.target != nil and self.current:
+    var root = self.getRootNode()
+    let
+      x = self.target.position.x
+      y = self.target.position.y
+
+    root.position.x = if x+w/2 < self.limit.x1: root.position.x elif x-w/2 > self.limit.x2: root.position.x else: -(x - w/2)
+    root.position.y = if y+h/2 < self.limit.y1: root.position.y elif y-h/2 > self.limit.y2: root.position.y else: -(y - h/2)
+
+
+method setCurrent*(self: Camera2DPtr) {.base.} =
+  ## Changes the current camera. It also automatically disable other cameras.
+  for c in nodes:
+    c.current = false
+  self.current = true
+
+method setLimit*(self: Camera2DPtr, x1, y1, x2, y2: float) {.base.} =
+  ## Change camera limit.
+  self.limit = Anchor(x1, y1, x2, y2)
+
+method setLimit*(self: Camera2DPtr, limit: AnchorRef) {.base.} =
+  ## Changes camera limit.
+  self.limit = limit
+
+method setTarget*(self: Camera2DPtr, target: NodePtr) {.base.} =
+  ## Changes camera target node.
+  self.target = target

+ 2 - 2
src/nodesnim/nodes2d/kinematic_body2d.nim

@@ -113,10 +113,10 @@ method moveAndCollide*(self: KinematicBody2DPtr, vel: Vector2Ref) {.base.} =
   ##
   ## Arguments:
   ## - `vel` is a velocity vector.
+  self.move(vel)
+  self.calcGlobalPosition()
   if self.has_collision:
     var scene = self.getRootNode()
-    self.move(vel)
-    self.calcGlobalPosition()
     self.collision_node.calcGlobalPosition()
 
     for node in scene.getChildIter():

+ 5 - 3
src/nodesnim/window.nim

@@ -20,9 +20,11 @@ var
   cmdLine {.importc: "cmdLine".}: array[0..255, cstring]
   cmdCount {.importc: "cmdCount".}: cint
 
-when defined(debug):
-  debug("Try to load OpenGL ...")
-loadExtensions()  # Load OpenGL extensions.
+
+when not defined(ios) or not defined(android):
+  when defined(debug):
+    debug("Try to load OpenGL ...")
+  loadExtensions()  # Load OpenGL extensions.
 
 when defined(debug):
   debug("Try to load freeGLUT ...")

+ 1 - 0
tests/README.md

@@ -36,3 +36,4 @@
 34. [Use Switch node.](https://github.com/Ethosa/nodesnim/blob/master/tests/test34.nim)
 35. [Event handlers with macros.](https://github.com/Ethosa/nodesnim/blob/master/tests/test35.nim)
 36. [Rotation.](https://github.com/Ethosa/nodesnim/blob/master/tests/test36.nim)
+37. [Use Camera2D node.](https://github.com/Ethosa/nodesnim/blob/master/tests/test37.nim)

+ 56 - 0
tests/test37.nim

@@ -0,0 +1,56 @@
+# --- Test 37. use Camera2D node. --- #
+import nodesnim
+
+
+Window("hello world")
+
+
+var
+  mainobj: SceneObj
+  main = Scene("Main", mainobj)
+
+  body_obj: KinematicBody2DObj
+  body = KinematicBody2D(body_obj)
+
+  sprite_obj: SpriteObj
+  sprite = Sprite(sprite_obj)
+
+  sprite1_obj: SpriteObj
+  sprite1 = Sprite(sprite1_obj)
+
+  cameraobj: Camera2DObj
+  camera = Camera2D(cameraobj)
+
+  img = load("assets/anim/2.jpg")
+  img1 = load("assets/anim/4.jpg")
+
+sprite.setTexture(img)
+sprite1.setTexture(img1)
+body.addChild(sprite)
+body.addChild(camera)
+
+sprite1.move(0, 400)
+camera.setTarget(body)
+camera.setLimit(-400, -256, 400, 256)
+camera.setCurrent()
+
+
+
+Input.addButtonAction("left", BUTTON_LEFT)
+body.on_process =
+  proc(self: NodePtr) =
+    if Input.isActionPressed("left"):
+      let
+        mouse_pos = body.getGlobalMousePosition()
+        distance = body.global_position.distance(mouse_pos)
+        direction = body.global_position.directionTo(mouse_pos)
+        speed = 4f
+      if distance >= 5:
+        body.moveAndCollide(direction*speed)
+
+
+main.addChild(body)
+main.addChild(sprite1)
+addScene(main)
+setMainScene("Main")
+windowLaunch()