diff options
| author | realtradam <[email protected]> | 2021-04-25 18:12:58 -0400 |
|---|---|---|
| committer | realtradam <[email protected]> | 2021-04-25 18:12:58 -0400 |
| commit | a3e96f57e36bfd96b753aab3a7fbe28be9bdfcf8 (patch) | |
| tree | 49ad332d3da404c6c45202fd18d282a062473acd | |
| parent | 505a4735d519253c5f173f47fbe9691bc5d9ce93 (diff) | |
| download | ruby2d-camera-old-a3e96f57e36bfd96b753aab3a7fbe28be9bdfcf8.tar.gz ruby2d-camera-old-a3e96f57e36bfd96b753aab3a7fbe28be9bdfcf8.zip | |
.
| -rw-r--r-- | README.md | 33 | ||||
| -rw-r--r-- | assets/houseshadow.png | bin | 10856 -> 0 bytes | |||
| -rw-r--r-- | assets/legacy_player.png (renamed from assets/player.png) | bin | 1044 -> 1044 bytes | |||
| -rw-r--r-- | assets/sprites/peepocomfy-100.png | bin | 4321 -> 0 bytes | |||
| -rw-r--r-- | assets/stand.png | bin | 7792 -> 0 bytes | |||
| -rw-r--r-- | house.rb | 4 | ||||
| -rw-r--r-- | lib/camera/wrappers/text_wrapper.rb | 28 | ||||
| -rw-r--r-- | room.rb | 85 | ||||
| -rw-r--r-- | run.rb | 89 |
9 files changed, 151 insertions, 88 deletions
@@ -1,27 +1,32 @@ # Ruby2D Camera Demo -`ruby run.rb` to run the demo +`ruby run.rb` to run the demo. ---- - -Controls: +## Controls: WASD to move character -IJKL to move camera -Q/E to rotate camera -R to reset the rotation +Q/E to rotate camera +Hold R to reset the rotation +Space to enter doors + +## How it works: + +A single `Camera` module exists which keeps track of objects that you add to it. When you add an object to the camera it creates a wrapper for the object and 'monkey patches' it onto the object to work with the camera. ---- +Feel free to use any part of this code in your own projects, no credit required(but is appreciated [^; ) -I wanted to make a proof of concept to see how feasible it is to implement a camera system in Ruby2D. Turns out it is very feasible :D +## How to use the camera in your own code: -How it works: +Copy the `lib/camera/` directory into your ruby project and then in your code simply ```require_relative 'camera/camera'``` at the top. In your `Update do` loop you must add ```Camera.redraw``` at the bottom(this is so that the camera applies any changes you tell it to do). Your camera is now ready to use! -A single `Camera` module exists which keeps track of objects that you add to it. When you add an object to the camera (currently only triangles) it creates a wrapper for the object and modifys it to work with the camera. +To add an object to the camera simply do ```Camera << @your_object``` and the camera will do its magic on your object. Only the various shape/image/text/line/sprite/etc. from Ruby2D are supported. +Whenever an object is wrapped by the camera it gets `x` and `y` methods if it does not already have them which you can use to move the object around in the camera. The text object also gets a `center` method which you can set to true if you wish the origin of text to be its center. Otherwise the origin of all objects is the top left corner. Other then these methods mentioned, object behave as expected within the context of the camera. -If you want to use this little demo in your own projects feel free to do so! All you need is the camera.rb file and then just `require` or `require_relative` it into your project. -See the code as an example for how it is used. +When unloading an object, make sure to also remove it from the Camera or else it will attempt to update it when it is Nil. To do this use the following: `Camera.remove(@your_object)` -Credit is appreciated but not required :) +To manipulate the camera there are 4 variables you can use: +- `Camera.zoom` Default: 1. This is a multiplier for how much you want the camera to be zoomed in(e.g 2 is 2x zoom, 0.5 is 0.5x zoom) +- `Camera.x` and `Camera.y` Default: 0. This are the position of the camera in the "world" +- `Camera.angle` Default: 0. This is the angle of how much the camera is rotated(in degrees). It ranges from 0-359. Giving values outside of this range will automagically convert them to fit within the 0-359 range. diff --git a/assets/houseshadow.png b/assets/houseshadow.png Binary files differdeleted file mode 100644 index d860b9b..0000000 --- a/assets/houseshadow.png +++ /dev/null diff --git a/assets/player.png b/assets/legacy_player.png Binary files differindex 485e972..485e972 100644 --- a/assets/player.png +++ b/assets/legacy_player.png diff --git a/assets/sprites/peepocomfy-100.png b/assets/sprites/peepocomfy-100.png Binary files differdeleted file mode 100644 index 6d8812d..0000000 --- a/assets/sprites/peepocomfy-100.png +++ /dev/null diff --git a/assets/stand.png b/assets/stand.png Binary files differdeleted file mode 100644 index 2c7038d..0000000 --- a/assets/stand.png +++ /dev/null @@ -90,8 +90,8 @@ class House y = @y + 160 if character.x >= x && character.x <= (x + (character.width * 2)) && character.y > y && character.y <= (y + (character.height * 2)) Text.new('Press Space To Enter House', - x: x - 10, - y: y + 20, + x: x + 70, + y: y + 30, color: 'white', z: 98, size: 25.0) diff --git a/lib/camera/wrappers/text_wrapper.rb b/lib/camera/wrappers/text_wrapper.rb index 56b35ed..ad96881 100644 --- a/lib/camera/wrappers/text_wrapper.rb +++ b/lib/camera/wrappers/text_wrapper.rb @@ -3,19 +3,31 @@ module Camera # Wraps existing variables as well as adding new methods # so that it can be handled by the Camera Module + # TODO: note that text could not be resized at the current iteration + # of Ruby2D so the math needs to be changed compensate for this. + # When Ruby2D gets updated to allow text resizing the math will need + # to be corrected again(see image_wrapper.rb for reference, that has + # math that allows for resizing) module TextWrapped + @center = false + # Recalculates real coordiantes # Use after changing variables def redraw angle = Camera.angle * (Math::PI / 180) half_width = Window.width * 0.5 half_height = Window.height * 0.5 - offset_x = x + (width / 2) - offset_y = y + (height / 2) + if center + offset_y = y + (Camera.zoom / 2) + offset_x = x + (Camera.zoom / 2) + else + offset_x = x + (width / Camera.zoom / 2) + offset_y = y + (height / Camera.zoom / 2) + end @x = (((offset_x - Camera.x) * Math.cos(angle)) - ((offset_y - Camera.y) * Math.sin(angle))) \ - * Camera.zoom + half_width - (width * Camera.zoom / 2) + * Camera.zoom + half_width - (width / 2) @y = (((offset_x - Camera.x) * Math.sin(angle)) + ((offset_y - Camera.y) * Math.cos(angle))) \ - * Camera.zoom + half_height - (height * Camera.zoom / 2) + * Camera.zoom + half_height - (height / 2) @rotate = rotate + Camera.angle @size = size * Camera.zoom end @@ -60,5 +72,13 @@ module Camera def size=(size) @virtual_size = size end + + def center + @center + end + + def center=(center) + @center = center + end end end @@ -2,81 +2,106 @@ # Is a house class Room - def debug - @debug - end def initialize(x, y) @objects = [] @x = x @y = y + roomy = 155 @objects.push Square.new(x: 125 + x, y: 230 + y, size: 50, - color: 'blue') + color: 'blue', + z: 3) @objects.push Circle.new(x: 125 + x, y: 205 + y, radius: 25, - color: 'blue') + sectors: 64, + color: 'blue', + z: 3) @objects.push Quad.new(x1: 50 + x, - y1: 130 + y, + y1: 130 + y + roomy, x2: 125 + x, - y2: 180 + y, + y2: 180 + y + roomy, x3: 325 + x, - y3: 180 + y, + y3: 180 + y + roomy, x4: 250 + x, - y4: 130 + y, + y4: 130 + y + roomy, color: 'aqua', z: 1) @objects.push Quad.new(x1: 50 + x, - y1: 45 + y, + y1: 45 + y + roomy, x2: 50 + x, - y2: 125 + y, + y2: 125 + y + roomy, x3: 250 + x, - y3: 125 + y, + y3: 125 + y + roomy, x4: 250 + x, - y4: 45 + y, + y4: 45 + y + roomy, color: 'orange', z: 1) @objects.push Quad.new(x1: 255 + x, - y1: 45 + y, - x2: 255 + x, - y2: 125 + y, - x3: 330 + x, - y3: 175 + y, - x4: 330 + x, - y4: 95 + y, - color: 'olive', - z: 1) + y1: 45 + y + roomy, + x2: 255 + x, + y2: 125 + y + roomy, + x3: 330 + x, + y3: 175 + y + roomy, + x4: 330 + x, + y4: 95 + y + roomy, + color: 'olive', + z: 1) @objects.push Sprite.new('./assets/sprites/blobdance-128.png', x: 250 + x, - y: 135 + y, + y: 135 + y + roomy, width: 40, height: 40, clip_width: 128, loop: true, time: 24, - z: 2) + z: 5) @objects.last.play + @objects.push Image.new( + 'assets/blobshadow.png', + x: 250 + x - 2 - 5, + y: 135 + y + roomy + 42 - 15, + width: 52, + height: 10, + z: 4 + ) @objects.push Sprite.new('./assets/sprites/dance2-112.png', x: 95 + x, - y: 115 + y, + y: 115 + y + roomy, width: 40, height: 40, clip_width: 112, loop: true, time: 13, - z: 2) + z: 5) @objects.last.play + @objects.push Image.new( + 'assets/blobshadow.png', + x: 95 + x - 2 - 5, + y: 115 + y + roomy + 42 - 10, + width: 52, + height: 10, + z: 4 + ) @objects.push Sprite.new('./assets/sprites/dancer-128.png', x: 175 + x, - y: 120 + y, + y: 120 + y + roomy, width: 45, height: 45, clip_width: 128, loop: true, time: 60, - z: 2) + z: 5) @objects.last.play + @objects.push Image.new( + 'assets/blobshadow.png', + x: 175 + x - 2 - 5, + y: 120 + y + roomy + 42 - 5, + width: 52, + height: 10, + z: 4 + ) @objects.each do |item| Camera << item end @@ -94,8 +119,8 @@ class Room y = @y + 160 if character.x >= x && character.x <= (x + (character.width * 2)) && character.y > y && character.y <= (y + (character.height * 2)) Text.new('Press Space To Exit House', - x: x - 10, - y: y + 20, + x: x + 70, + y: y + 30, color: 'white', z: 98, size: 25.0) @@ -28,11 +28,13 @@ Window.set(icon: './assets/blobcoolthink.png', 'assets/blobshadow.png', width: 52, height: 10, - z: 1 + z: 4 ) Camera << @shadow @player.play animation: :walk, loop: true Camera << @player + +# UI Rectangle.new( width: 350, height: 135, @@ -88,8 +90,8 @@ Rectangle.new( @speed = 5 # Initializing -player_movement_x = 0 -player_movement_y = 0 +@player_movement_x = 0 +@player_movement_y = 0 @pressed_space = false @scene_transition_into = false @scene_transition_out = false @@ -99,62 +101,68 @@ player_movement_y = 0 on :key do |event| if event.key == 'w' - player_movement_y -= @speed unless @scene_transition_into || @scene_transition_out + @player_movement_y -= @speed unless @scene_transition_into || @scene_transition_out end if event.key == 's' - player_movement_y += @speed unless @scene_transition_into || @scene_transition_out + @player_movement_y += @speed unless @scene_transition_into || @scene_transition_out end if event.key == 'd' - player_movement_x += @speed unless @scene_transition_into || @scene_transition_out + @player_movement_x += @speed unless @scene_transition_into || @scene_transition_out end if event.key == 'a' - player_movement_x -= @speed unless @scene_transition_into || @scene_transition_out + @player_movement_x -= @speed unless @scene_transition_into || @scene_transition_out end if event.key == 'space' @pressed_space = true unless @scene_transition_into || @scene_transition_out end if event.key == 'q' - Camera.angle += 1 + Camera.angle += 1 unless @scene_transition_into || @scene_transition_out end if event.key == 'e' - Camera.angle -= 1 - end - if event.key == 'z' - Camera.zoom *= 1.015 - end - if event.key == 'x' - Camera.zoom *= 0.985 + Camera.angle -= 1 unless @scene_transition_into || @scene_transition_out + end + if event.key == 'r' + unless @scene_transition_into || @scene_transition_out || Camera.angle.zero? + if Camera.angle <= 180 + if Camera.angle > 10 + Camera.angle -= 10 + else + Camera.angle -=1 + end + elsif + if Camera.angle < 350 + Camera.angle += 10 + else + Camera.angle += 1 + end + end + end end end -=begin -Camera << Text.new('rotate me to see how if it works', - x: 500, - y: 500, - z: 99) -=end + update do - if (@player.x > 2371 && player_movement_x.positive?) || (@player.x.negative? && player_movement_x.negative?) - player_movement_x = 0 + if (@player.x > 2371 && @player_movement_x.positive?) || (@player.x.negative? && @player_movement_x.negative?) + @player_movement_x = 0 end - if (@player.y > 1608 && player_movement_y.positive?) || (@player.y.negative? && player_movement_y.negative?) - player_movement_y = 0 + if (@player.y > 1608 && @player_movement_y.positive?) || (@player.y.negative? && @player_movement_y.negative?) + @player_movement_y = 0 end - if !player_movement_y.zero? == !player_movement_x.zero? - player_movement_x /= 1.4141 - player_movement_y /= 1.4141 + if !@player_movement_y.zero? == !@player_movement_x.zero? + @player_movement_x /= 1.4141 + @player_movement_y /= 1.4141 end - @player.x += player_movement_x - @player.y += player_movement_y - if player_movement_x.negative? + @player.x += @player_movement_x + @player.y += @player_movement_y + if @player_movement_x.negative? @player.play animation: :walk, loop: true - elsif player_movement_x.positive? || !player_movement_y.zero? + elsif @player_movement_x.positive? || !@player_movement_y.zero? @player.play animation: :walk, loop: true, flip: :vertical else @player.play animation: :stand end if !@scene_transition_into && !@scene_transition_out - Camera.zoom = (-[Math.sqrt(((@player.x + (@player.width / 2) - Camera.x)**2) + ((@player.y + (@player.width / 2) - Camera.y)**2)), 350].min * 0.004) + 2 + Camera.zoom += ((-[Math.sqrt(((@player.x + (@player.width / 2) - Camera.x)**2) + ((@player.y + (@player.width / 2) - Camera.y)**2)), 350].min * 0.004) + 2 - Camera.zoom) * 0.25 Camera.x += (@player.x + (@player.width / 2) - Camera.x) * 0.025 Camera.y += (@player.y + (@player.height / 2)- Camera.y) * 0.025 elsif @scene_transition_into @@ -180,7 +188,7 @@ update do Camera.x += (@player.x + (@player.width / 2) - Camera.x) * 0.25 Camera.y += (@player.y + (@player.height / 2) - Camera.y) * 0.25 elsif @scene_transition_out - if !(Camera.zoom <= 2.1 && Camera.angle.zero?) + if !((Camera.zoom <= (@zoom_transition * 1.001)) && (Camera.angle == @angle_transition)) Camera.zoom /= 1.05 Camera.angle -= 5 else @@ -217,17 +225,22 @@ update do else @house_text = @house.visted_by?(@player) end - Camera << @house_text unless @house_text.nil? - if !@house_text.nil? && @pressed_space + unless @house_text.nil? + Camera << @house_text + @house_text.center = true + end + if !@house_text.nil? && @pressed_space && !@scene_transition_into && !@scene_transition_out @scene_transition_into = true + @angle_transition = Camera.angle + @zoom_transition = Camera.zoom end @ui_pos_cam.text = "Camera Position: #{Camera.x.round(1)}, #{Camera.y.round(1)}" @ui_pos_ply.text = "Player Position: #{@player.x.round(1)}, #{@player.y.round(1)}" @ui_zoom.text = "Zoom: #{Camera.zoom.round(3)}" @ui_fps.text = "FPS: #{Window.fps.round(2)}" @ui_rotation.text = "Angle: #{Camera.angle}" - player_movement_x = 0 - player_movement_y = 0 + @player_movement_x = 0 + @player_movement_y = 0 @pressed_space = false Camera.redraw |
