summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorrealtradam <[email protected]>2021-04-25 18:12:58 -0400
committerrealtradam <[email protected]>2021-04-25 18:12:58 -0400
commita3e96f57e36bfd96b753aab3a7fbe28be9bdfcf8 (patch)
tree49ad332d3da404c6c45202fd18d282a062473acd
parent505a4735d519253c5f173f47fbe9691bc5d9ce93 (diff)
downloadruby2d-camera-a3e96f57e36bfd96b753aab3a7fbe28be9bdfcf8.tar.gz
ruby2d-camera-a3e96f57e36bfd96b753aab3a7fbe28be9bdfcf8.zip
.
-rw-r--r--README.md33
-rw-r--r--assets/houseshadow.pngbin10856 -> 0 bytes
-rw-r--r--assets/legacy_player.png (renamed from assets/player.png)bin1044 -> 1044 bytes
-rw-r--r--assets/sprites/peepocomfy-100.pngbin4321 -> 0 bytes
-rw-r--r--assets/stand.pngbin7792 -> 0 bytes
-rw-r--r--house.rb4
-rw-r--r--lib/camera/wrappers/text_wrapper.rb28
-rw-r--r--room.rb85
-rw-r--r--run.rb89
9 files changed, 151 insertions, 88 deletions
diff --git a/README.md b/README.md
index 2069ab1..f6984c2 100644
--- a/README.md
+++ b/README.md
@@ -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
deleted file mode 100644
index d860b9b..0000000
--- a/assets/houseshadow.png
+++ /dev/null
Binary files differ
diff --git a/assets/player.png b/assets/legacy_player.png
index 485e972..485e972 100644
--- a/assets/player.png
+++ b/assets/legacy_player.png
Binary files differ
diff --git a/assets/sprites/peepocomfy-100.png b/assets/sprites/peepocomfy-100.png
deleted file mode 100644
index 6d8812d..0000000
--- a/assets/sprites/peepocomfy-100.png
+++ /dev/null
Binary files differ
diff --git a/assets/stand.png b/assets/stand.png
deleted file mode 100644
index 2c7038d..0000000
--- a/assets/stand.png
+++ /dev/null
Binary files differ
diff --git a/house.rb b/house.rb
index 850bea8..1da0d58 100644
--- a/house.rb
+++ b/house.rb
@@ -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
diff --git a/room.rb b/room.rb
index 5811dc8..0366b36 100644
--- a/room.rb
+++ b/room.rb
@@ -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)
diff --git a/run.rb b/run.rb
index 3899c83..5197978 100644
--- a/run.rb
+++ b/run.rb
@@ -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