ruby2d-camera 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: fb4d1852c5d26e98334d2d1dff3f480c0ee51b0f3a0e0acfcd55f21bbb494d9b
4
+ data.tar.gz: c4829a8ece2fcc5b342e82ea1b21e4af317e59691a376ec61724a52ee233cfd2
5
+ SHA512:
6
+ metadata.gz: ef598ebfb03a65bb732ffd2c257ff8e685f44f5838b92c2d866d0492a678b66c39649caf9703262669f7bdef7d514492bada4de1d146ebb84b310a90abd4b109
7
+ data.tar.gz: 5c65aab04d7c23de753f603114bd96e9352e8bf6fbe9f26fd37d5346d111322c6fd08b31a736aa1a0ceff414941b1068fe1a7a6aaf55e0ea9205376bff42d324
data/.gitignore ADDED
@@ -0,0 +1,8 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
data/.rubocop.yml ADDED
@@ -0,0 +1,13 @@
1
+ AllCops:
2
+ TargetRubyVersion: 3.0
3
+
4
+ Style/StringLiterals:
5
+ Enabled: true
6
+ EnforcedStyle: single_quotes
7
+
8
+ Style/StringLiteralsInInterpolation:
9
+ Enabled: true
10
+ EnforcedStyle: single_quotes
11
+
12
+ Layout/LineLength:
13
+ Max: 120
data/.solargraph.yml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ include:
3
+ - "**/*.rb"
4
+ exclude:
5
+ - spec/**/*
6
+ - test/**/*
7
+ - vendor/**/*
8
+ - ".bundle/**/*"
9
+ require: []
10
+ domains: []
11
+ reporters:
12
+ - rubocop
13
+ require_paths: []
14
+ plugins: []
15
+ max_files: 5000
data/CHANGELOG.mdown ADDED
@@ -0,0 +1,11 @@
1
+ ###### [major.minor.bugfix] - year-month-day
2
+
3
+ ![Fixed](https://img.shields.io/badge/-Fixed-blue)
4
+ ![Added](https://img.shields.io/badge/-Added-brightgreen)
5
+ ![Changed](https://img.shields.io/badge/-Changed-yellow)
6
+ ![Deprecated](https://img.shields.io/badge/-Deprecated-orange)
7
+ ![Removed](https://img.shields.io/badge/-Removed-red)
8
+
9
+ ## [1.0.0](https://github.com/realtradam/ruby2d-camera/releases/tag/1.0.0) - 2021-08-08
10
+ ![Added](https://img.shields.io/badge/-Added-brightgreen)
11
+ - Initial release
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ # Specify your gem's dependencies in ruby2d-camera.gemspec
6
+ gemspec
7
+
8
+ gem "rake", "~> 13.0"
9
+
10
+ gem "rubocop", "~> 1.7"
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2021 realtradam
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.mdown ADDED
@@ -0,0 +1,39 @@
1
+ ![ruby2d-camera logo](https://naked.catgirls.rodeo/images/ruby2d-camera.png)
2
+
3
+ [![MIT License](https://img.shields.io/github/license/realtradam/FelFlame?label=license&style=flat)](https://github.com/realtradam/FelFlame/blob/master/LICENSE)
4
+ [![Ko-Fi](https://img.shields.io/static/v1?message=Buy%20me%20a%20coffee&logo=kofi&labelColor=ff5e5b&color=434B57&logoColor=white&label=%20)](https://ko-fi.com/tradam)
5
+
6
+ # Ruby2D Camera Gem
7
+
8
+ With this gem you can easily add camera functionality into your games built with Ruby2D. Install it using `gem install ruby2d-camera` and then add it into your project with `require ruby2d/camera` at the top of your code, just below the line `require ruby2d`.
9
+
10
+ `ruby run.rb` to run the demo.
11
+
12
+ ## How to use the camera:
13
+
14
+ Create your object as if you would create it in Ruby2D except you need to prefix it with `Camera::`. For example to create a square you do `Camera::Square.new`. Any objects you create this way can be controlled and manipulated the same way that you control and manipulate them in Ruby2D with a few small additions. Any objects that do not have an x/y variable to move it now do have this, so that you may move the objects in the camera. Text objects also have a boolean that you can change named `center` which allows you to set the origin to be the horizontal center of the text rather then the edge.
15
+
16
+ ### To manipulate the camera there are 4 variables:
17
+
18
+ - `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)
19
+ - `Camera.x` and `Camera.y` Default: 0. This is the position the camera is centered on in the "world"
20
+ - `Camera.angle` Default: 0. This is the angle of how much the camera is rotated(in degrees). It ranges from 0-360. Giving values outside of this range will automagically convert them to fit within the 0-360 range.
21
+
22
+ ## How it works:
23
+
24
+ A single `Camera` module exists which keeps track of objects created with it. When you create an object with the camera it creates a special object that inherits the original object from Ruby2D and then adds additional functions. The Camera module then uses these functions to draw the various objects on the screen each frame, using the parameters you gave it.
25
+
26
+ ## Demo:
27
+
28
+ Under the `example` directory you can find a (poorly coded) demo using this gem. Simply `ruby run.rb` in the example directory to start the demo.
29
+
30
+ ### Controls:
31
+
32
+ WASD to move character
33
+ Q/E to rotate camera
34
+ Hold R to reset the rotation
35
+ Space to enter doors
36
+
37
+ ## Known Issues:
38
+
39
+ Unfortunately text cannot be resized due to current limitations of Ruby2D, this will fixed when possible. This means zooming with text will look strange, centering the text somewhat alleviates this issue.
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rubocop/rake_task"
5
+
6
+ RuboCop::RakeTask.new
7
+
8
+ task default: :rubocop
data/bin/console ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "ruby2d/camera"
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require "irb"
15
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,107 @@
1
+ # frozen_string_literal: true
2
+
3
+ # require_relative "camera/version"
4
+ # require_relative "camera/triangle"
5
+ require 'ruby2d'
6
+ Dir[File.join(__dir__, 'camera', '*.rb')].sort.each { |file| require file }
7
+
8
+ # Handles rendering objects relative
9
+ # to a camera location
10
+ module Ruby2D
11
+ module Camera
12
+ class << self
13
+ private
14
+
15
+ # Contains all objects that are tracked
16
+ def objects
17
+ @objects ||= []
18
+ end
19
+ end
20
+
21
+ def self.debug_x
22
+ @debug_x ||= 0
23
+ end
24
+
25
+ def self.debug_x=(debug_x)
26
+ @debug_x = debug_x
27
+ end
28
+
29
+ def self.debug_y
30
+ @debug_y ||= 0
31
+ end
32
+
33
+ def self.debug_y=(debug_y)
34
+ @debug_y = debug_y
35
+ end
36
+
37
+ # Adding objects so they are
38
+ # tracked by the Camera
39
+ def self.<<(item)
40
+ objects.push(item) unless objects.include?(item)
41
+ objects.sort_by! do |n|
42
+ n.z
43
+ end
44
+ end
45
+
46
+ def self.remove(item)
47
+ objects.delete(item) if objects.include?(item)
48
+ end
49
+
50
+ # Redraw all objects that
51
+ # are tracked by the Camera
52
+ def self._redraw(auto_purge: false)
53
+ objects.each(&:_draw)
54
+ end
55
+
56
+ # Variables changing Camera properties
57
+ def self._x(x)
58
+ @x += x
59
+ end
60
+
61
+ def self._y(y)
62
+ @y += y
63
+ end
64
+
65
+ def self.x
66
+ @x ||= 0
67
+ end
68
+
69
+ def self.x=(x)
70
+ @x = x
71
+ end
72
+
73
+ def self.y
74
+ @y ||= 0
75
+ end
76
+
77
+ def self.y=(y)
78
+ @y = y
79
+ end
80
+
81
+ def self.zoom
82
+ @zoom ||= 1.0
83
+ end
84
+
85
+ def self.zoom=(zoom)
86
+ @zoom = zoom
87
+ end
88
+
89
+ def self.angle
90
+ @angle ||= 0
91
+ end
92
+
93
+ def self.angle=(angle)
94
+ angle %= 360
95
+ @angle = angle
96
+ end
97
+ end
98
+ end
99
+
100
+ module Ruby2D
101
+ class Window
102
+ def update(&aproc)
103
+ @update_proc = (aproc << proc { Ruby2D::Camera._redraw })
104
+ true
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ruby2D
4
+ module Camera
5
+ # Wraps existing variables as well as adding new methods
6
+ # so that it can be handled by the Camera Module
7
+ class Circle < Ruby2D::Circle
8
+ # Recalculates real coordiantes
9
+ # Use after changing variables
10
+ def _draw
11
+ return if @hide
12
+
13
+ angle = Camera.angle * (Math::PI / 180)
14
+ half_width = Window.width * 0.5
15
+ half_height = Window.height * 0.5
16
+ temp_radius = @radius * Camera.zoom
17
+ temp_x = (((@x - Ruby2D::Camera.x + radius) * Math.cos(angle)) - ((@y - Ruby2D::Camera.y + radius) * Math.sin(angle))) * Ruby2D::Camera.zoom + half_width
18
+ temp_y = (((@x - Ruby2D::Camera.x + radius) * Math.sin(angle)) + ((@y - Ruby2D::Camera.y + radius) * Math.cos(angle))) * Ruby2D::Camera.zoom + half_height
19
+ Ruby2D::Circle.draw(x: temp_x, y: temp_y,
20
+ radius: temp_radius,
21
+ sectors: sectors,
22
+ color: [color.r, color.g, color.b, color.a])
23
+ end
24
+
25
+ def initialize(opts = {})
26
+ super(opts)
27
+ Ruby2D::Camera << self
28
+ Window.remove(self)
29
+ end
30
+
31
+ def remove
32
+ @hide = true
33
+ end
34
+
35
+ def add
36
+ @hide = false
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Camera
4
+ # Wraps existing variables as well as adding new methods
5
+ # so that it can be handled by the Camera Module
6
+ class Image < Ruby2D::Image
7
+ # Recalculates real coordiantes
8
+ # Use after changing variables
9
+ def _draw
10
+ return if @hide
11
+
12
+ temp_angle = Camera.angle * (Math::PI / 180)
13
+ half_width = Window.width * 0.5
14
+ half_height = Window.height * 0.5
15
+ offset_x = @x + (@width / 2)
16
+ offset_y = @y + (@height / 2)
17
+ temp_x = (((offset_x - Camera.x) * Math.cos(temp_angle)) - ((offset_y - Camera.y) * Math.sin(temp_angle))) \
18
+ * Camera.zoom + half_width - (width * Camera.zoom / 2)
19
+ temp_y = (((offset_x - Camera.x) * Math.sin(temp_angle)) + ((offset_y - Camera.y) * Math.cos(temp_angle))) \
20
+ * Camera.zoom + half_height - (height * Camera.zoom / 2)
21
+ temp_rotate = rotate + Camera.angle
22
+ temp_width = width * Camera.zoom
23
+ temp_height = height * Camera.zoom
24
+ draw(x: temp_x, y: temp_y,
25
+ width: temp_width,
26
+ height: temp_height,
27
+ rotate: temp_rotate,
28
+ color: [color.r, color.g, color.b, color.a])
29
+ end
30
+
31
+ def initialize(path, opts = {})
32
+ super(path, opts)
33
+ Ruby2D::Camera << self
34
+ Window.remove(self)
35
+ end
36
+
37
+ def remove
38
+ @hide = true
39
+ end
40
+
41
+ def add
42
+ @hide = false
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ruby2D
4
+ module Camera
5
+ # Wraps existing variables as well as adding new methods
6
+ # so that it can be handled by the Camera Module
7
+ class Line < Ruby2D::Line
8
+ # Recalculates real coordiantes
9
+ # Use after changing variables
10
+ def _draw
11
+ return if @hide
12
+
13
+ angle = Camera.angle * (Math::PI / 180)
14
+ half_width = Window.width * 0.5
15
+ half_height = Window.height * 0.5
16
+ temp_x1 = (((x + @x1 - Camera.x) * Math.cos(angle)) - ((y + @y1 - Camera.y) * Math.sin(angle))) * Camera.zoom + half_width
17
+ temp_y1 = (((x + @x1 - Camera.x) * Math.sin(angle)) + ((y + @y1 - Camera.y) * Math.cos(angle))) * Camera.zoom + half_height
18
+ temp_x2 = (((x + @x2 - Camera.x) * Math.cos(angle)) - ((y + @y2 - Camera.y) * Math.sin(angle))) * Camera.zoom + half_width
19
+ temp_y2 = (((x + @x2 - Camera.x) * Math.sin(angle)) + ((y + @y2 - Camera.y) * Math.cos(angle))) * Camera.zoom + half_height
20
+ temp_width = width * Camera.zoom
21
+ Ruby2D::Line.draw(x1: temp_x1, y1: temp_y1,
22
+ x2: temp_x2, y2: temp_y2,
23
+ width: temp_width,
24
+ color: [
25
+ [color.r, color.g, color.b, color.a],
26
+ [color.r, color.g, color.b, color.a],
27
+ [color.r, color.g, color.b, color.a],
28
+ [color.r, color.g, color.b, color.a]
29
+ ],
30
+ z: z)
31
+ end
32
+
33
+ def initialize(opts = {})
34
+ super(opts)
35
+ Ruby2D::Camera << self
36
+ Window.remove(self)
37
+ end
38
+
39
+ def remove
40
+ @hide = true
41
+ end
42
+
43
+ def add
44
+ @hide = false
45
+ end
46
+
47
+ # Methods for moving the shape
48
+ def x
49
+ @x ||= 0
50
+ end
51
+
52
+ attr_writer :x, :y
53
+
54
+ def y
55
+ @y ||= 0
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ruby2D
4
+ module Camera
5
+ # Wraps existing variables as well as adding new methods
6
+ # so that it can be handled by the Camera Module
7
+ class Quad < Ruby2D::Quad
8
+ # Recalculates real coordiantes
9
+ # Use after changing variables
10
+ def _draw
11
+ return if @hide
12
+
13
+ angle = Camera.angle * (Math::PI / 180)
14
+ half_width = Window.width * 0.5
15
+ half_height = Window.height * 0.5
16
+ temp_x1 = (((x + x1 - Camera.x) * Math.cos(angle)) - ((y + y1 - Camera.y) * Math.sin(angle))) * Camera.zoom + half_width
17
+ temp_y1 = (((x + x1 - Camera.x) * Math.sin(angle)) + ((y + y1 - Camera.y) * Math.cos(angle))) * Camera.zoom + half_height
18
+ temp_x2 = (((x + x2 - Camera.x) * Math.cos(angle)) - ((y + y2 - Camera.y) * Math.sin(angle))) * Camera.zoom + half_width
19
+ temp_y2 = (((x + x2 - Camera.x) * Math.sin(angle)) + ((y + y2 - Camera.y) * Math.cos(angle))) * Camera.zoom + half_height
20
+ temp_x3 = (((x + x3 - Camera.x) * Math.cos(angle)) - ((y + y3 - Camera.y) * Math.sin(angle))) * Camera.zoom + half_width
21
+ temp_y3 = (((x + x3 - Camera.x) * Math.sin(angle)) + ((y + y3 - Camera.y) * Math.cos(angle))) * Camera.zoom + half_height
22
+ temp_x4 = (((x + x4 - Camera.x) * Math.cos(angle)) - ((y + y4 - Camera.y) * Math.sin(angle))) * Camera.zoom + half_width
23
+ temp_y4 = (((x + x4 - Camera.x) * Math.sin(angle)) + ((y + y4 - Camera.y) * Math.cos(angle))) * Camera.zoom + half_height
24
+ Ruby2D::Quad.draw(x1: temp_x1, y1: temp_y1,
25
+ x2: temp_x2, y2: temp_y2,
26
+ x3: temp_x3, y3: temp_y3,
27
+ x4: temp_x4, y4: temp_y4,
28
+ color: [
29
+ [c1.r, c1.g, c1.b, c1.a],
30
+ [c2.r, c2.g, c2.b, c2.a],
31
+ [c3.r, c3.g, c3.b, c3.a],
32
+ [c4.r, c4.g, c4.b, c4.a]
33
+ ],
34
+ z: z)
35
+ end
36
+
37
+ def initialize(opts = {})
38
+ super(opts)
39
+ Ruby2D::Camera << self
40
+ Window.remove(self)
41
+ end
42
+
43
+ def remove
44
+ @hide = true
45
+ end
46
+
47
+ def add
48
+ @hide = false
49
+ end
50
+
51
+ # Methods for moving the shape
52
+ def x
53
+ @x ||= 0
54
+ end
55
+
56
+ attr_writer :x, :y
57
+
58
+ def y
59
+ @y ||= 0
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ruby2D
4
+ module Camera
5
+ # Wraps existing variables as well as adding new methods
6
+ # so that it can be handled by the Camera Module
7
+ class Rectangle < Ruby2D::Rectangle
8
+ # Recalculates real coordiantes
9
+ # Use after changing variables
10
+ def _draw
11
+ return if @hide
12
+
13
+ angle = Camera.angle * (Math::PI / 180)
14
+ half_width = Window.width * 0.5
15
+ half_height = Window.height * 0.5
16
+ temp_x1 = (((x + x1 - Camera.x) * Math.cos(angle)) - ((y + y1 - Camera.y) * Math.sin(angle))) * Camera.zoom + half_width
17
+ temp_y1 = (((x + x1 - Camera.x) * Math.sin(angle)) + ((y + y1 - Camera.y) * Math.cos(angle))) * Camera.zoom + half_height
18
+ temp_x2 = (((x + x2 - Camera.x) * Math.cos(angle)) - ((y + y2 - Camera.y) * Math.sin(angle))) * Camera.zoom + half_width
19
+ temp_y2 = (((x + x2 - Camera.x) * Math.sin(angle)) + ((y + y2 - Camera.y) * Math.cos(angle))) * Camera.zoom + half_height
20
+ temp_x3 = (((x + x3 - Camera.x) * Math.cos(angle)) - ((y + y3 - Camera.y) * Math.sin(angle))) * Camera.zoom + half_width
21
+ temp_y3 = (((x + x3 - Camera.x) * Math.sin(angle)) + ((y + y3 - Camera.y) * Math.cos(angle))) * Camera.zoom + half_height
22
+ temp_x4 = (((x + x4 - Camera.x) * Math.cos(angle)) - ((y + y4 - Camera.y) * Math.sin(angle))) * Camera.zoom + half_width
23
+ temp_y4 = (((x + x4 - Camera.x) * Math.sin(angle)) + ((y + y4 - Camera.y) * Math.cos(angle))) * Camera.zoom + half_height
24
+ Ruby2D::Quad.draw(x1: temp_x1, y1: temp_y1,
25
+ x2: temp_x2, y2: temp_y2,
26
+ x3: temp_x3, y3: temp_y3,
27
+ x4: temp_x4, y4: temp_y4,
28
+ color: [
29
+ [c1.r, c1.g, c1.b, c1.a],
30
+ [c2.r, c2.g, c2.b, c2.a],
31
+ [c3.r, c3.g, c3.b, c3.a],
32
+ [c4.r, c4.g, c4.b, c4.a]
33
+ ],
34
+ z: z)
35
+ end
36
+
37
+ def initialize(opts = {})
38
+ super(opts)
39
+ Ruby2D::Camera << self
40
+ Window.remove(self)
41
+ @x1 -= @x
42
+ @x2 -= @x
43
+ @x3 -= @x
44
+ @x4 -= @x
45
+ @y1 -= @y
46
+ @y2 -= @y
47
+ @y3 -= @y
48
+ @y4 -= @y
49
+ end
50
+
51
+ def remove
52
+ @hide = true
53
+ end
54
+
55
+ def add
56
+ @hide = false
57
+ end
58
+
59
+ # Methods for moving the shape
60
+ def x
61
+ @x ||= 0
62
+ end
63
+
64
+ attr_writer :x, :y
65
+
66
+ def y
67
+ @y ||= 0
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ruby2D
4
+ module Camera
5
+ # Wraps existing variables as well as adding new methods
6
+ # so that it can be handled by the Camera Module
7
+ class Sprite < Ruby2D::Sprite
8
+ # Recalculates real coordiantes
9
+ # Use after changing variables
10
+ def _draw
11
+ return if @hide
12
+
13
+ angle = Camera.angle * (Math::PI / 180)
14
+ half_width = Window.width * 0.5
15
+ half_height = Window.height * 0.5
16
+ offset_x = @x + (width / 2)
17
+ offset_y = @y + (height / 2)
18
+ temp_x = (((offset_x - Camera.x) * Math.cos(angle)) - ((offset_y - Camera.y) * Math.sin(angle))) \
19
+ * Camera.zoom + half_width - (width * Camera.zoom / 2)
20
+ temp_y = (((offset_x - Camera.x) * Math.sin(angle)) + ((offset_y - Camera.y) * Math.cos(angle))) \
21
+ * Camera.zoom + half_height - (height * Camera.zoom / 2)
22
+ temp_rotate = rotate + Camera.angle
23
+ temp_width = width * Camera.zoom
24
+ temp_height = height * Camera.zoom
25
+ case @flip
26
+ when :both
27
+ temp_x += temp_height
28
+ temp_y += temp_width
29
+ temp_width = -temp_width
30
+ temp_height = -temp_height
31
+ puts 'both'
32
+ when :horizontal
33
+ temp_y += temp_width
34
+ temp_height = -temp_height
35
+ when :vertical
36
+ temp_width = -temp_width
37
+ temp_x += temp_height
38
+ end
39
+ draw(x: temp_x, y: temp_y,
40
+ width: temp_width,
41
+ height: temp_height,
42
+ rotate: temp_rotate)
43
+ update
44
+ end
45
+
46
+ def initialize(path, opts = {})
47
+ super(path, opts)
48
+ Ruby2D::Camera << self
49
+ Window.remove(self)
50
+ end
51
+
52
+ def remove
53
+ @hide = true
54
+ end
55
+
56
+ def add
57
+ @hide = false
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ruby2D
4
+ module Camera
5
+ # Wraps existing variables as well as adding new methods
6
+ # so that it can be handled by the Camera Module
7
+ class Square < Ruby2D::Square
8
+ # Recalculates real coordiantes
9
+ # Use after changing variables
10
+ def _draw
11
+ return if @hide
12
+
13
+ angle = Camera.angle * (Math::PI / 180)
14
+ half_width = Window.width * 0.5
15
+ half_height = Window.height * 0.5
16
+ temp_x1 = (((x + x1 - Camera.x) * Math.cos(angle)) - ((y + y1 - Camera.y) * Math.sin(angle))) * Camera.zoom + half_width
17
+ temp_y1 = (((x + x1 - Camera.x) * Math.sin(angle)) + ((y + y1 - Camera.y) * Math.cos(angle))) * Camera.zoom + half_height
18
+ temp_x2 = (((x + x2 - Camera.x) * Math.cos(angle)) - ((y + y2 - Camera.y) * Math.sin(angle))) * Camera.zoom + half_width
19
+ temp_y2 = (((x + x2 - Camera.x) * Math.sin(angle)) + ((y + y2 - Camera.y) * Math.cos(angle))) * Camera.zoom + half_height
20
+ temp_x3 = (((x + x3 - Camera.x) * Math.cos(angle)) - ((y + y3 - Camera.y) * Math.sin(angle))) * Camera.zoom + half_width
21
+ temp_y3 = (((x + x3 - Camera.x) * Math.sin(angle)) + ((y + y3 - Camera.y) * Math.cos(angle))) * Camera.zoom + half_height
22
+ temp_x4 = (((x + x4 - Camera.x) * Math.cos(angle)) - ((y + y4 - Camera.y) * Math.sin(angle))) * Camera.zoom + half_width
23
+ temp_y4 = (((x + x4 - Camera.x) * Math.sin(angle)) + ((y + y4 - Camera.y) * Math.cos(angle))) * Camera.zoom + half_height
24
+ Ruby2D::Quad.draw(x1: temp_x1, y1: temp_y1,
25
+ x2: temp_x2, y2: temp_y2,
26
+ x3: temp_x3, y3: temp_y3,
27
+ x4: temp_x4, y4: temp_y4,
28
+ color: [
29
+ [c1.r, c1.g, c1.b, c1.a],
30
+ [c2.r, c2.g, c2.b, c2.a],
31
+ [c3.r, c3.g, c3.b, c3.a],
32
+ [c4.r, c4.g, c4.b, c4.a]
33
+ ],
34
+ z: z)
35
+ end
36
+
37
+ def initialize(opts = {})
38
+ super(opts)
39
+ Ruby2D::Camera << self
40
+ Window.remove(self)
41
+ @x1 -= @x
42
+ @x2 -= @x
43
+ @x3 -= @x
44
+ @x4 -= @x
45
+ @y1 -= @y
46
+ @y2 -= @y
47
+ @y3 -= @y
48
+ @y4 -= @y
49
+ end
50
+
51
+ def remove
52
+ @hide = true
53
+ end
54
+
55
+ def add
56
+ @hide = false
57
+ end
58
+
59
+ # Methods for moving the shape
60
+ def x
61
+ @x ||= 0
62
+ end
63
+
64
+ attr_writer :x, :y
65
+
66
+ def y
67
+ @y ||= 0
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ruby2D
4
+ module Camera
5
+ # Wraps existing variables as well as adding new methods
6
+ # so that it can be handled by the Camera Module
7
+ # TODO: note that text could not be resized at the current iteration
8
+ # of Ruby2D so the math needs to be changed compensate for this.
9
+ # When Ruby2D gets updated to allow text resizing the math will need
10
+ # to be corrected again(see image_wrapper.rb for reference, that has
11
+ # math that allows for resizing)
12
+ class Text < Ruby2D::Text
13
+ # Recalculates real coordiantes
14
+ # Use after changing variables
15
+ def _draw
16
+ return if @hide
17
+
18
+ angle = Camera.angle * (Math::PI / 180)
19
+ half_width = Window.width * 0.5
20
+ half_height = Window.height * 0.5
21
+ if center
22
+ offset_y = y + (Camera.zoom / 2)
23
+ offset_x = x + (Camera.zoom / 2)
24
+ else
25
+ offset_x = x + (width / Camera.zoom / 2)
26
+ offset_y = y + (height / Camera.zoom / 2)
27
+ end
28
+ temp_x = (((offset_x - Camera.x) * Math.cos(angle)) - ((offset_y - Camera.y) * Math.sin(angle))) \
29
+ * Camera.zoom + half_width - (width / 2)
30
+ temp_y = (((offset_x - Camera.x) * Math.sin(angle)) + ((offset_y - Camera.y) * Math.cos(angle))) \
31
+ * Camera.zoom + half_height - (height / 2)
32
+ temp_rotate = rotate + Camera.angle
33
+ # Workaround for resizing text
34
+ # TODO: resizing doesnt work at all even with workaround
35
+ temp_size = size # * Camera.zoom
36
+ self.size *= Camera.zoom
37
+ draw(x: temp_x, y: temp_y,
38
+ rotate: temp_rotate,
39
+ color: [color.r, color.g, color.b, color.a])
40
+ self.size = temp_size
41
+ end
42
+
43
+ def initialize(text, opts = {})
44
+ super(text, opts)
45
+ Ruby2D::Camera << self
46
+ Window.remove(self)
47
+ end
48
+
49
+ def remove
50
+ @hide = true
51
+ end
52
+
53
+ def add
54
+ @hide = false
55
+ end
56
+
57
+ attr_accessor :center
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ruby2D
4
+ module Camera
5
+ class Triangle < Ruby2D::Triangle
6
+ # Recalculates real coordiantes
7
+ # Use after changing variables
8
+ def _draw
9
+ return if @hide
10
+
11
+ angle = Ruby2D::Camera.angle * (Math::PI / 180)
12
+ half_width = Window.width * 0.5
13
+ half_height = Window.height * 0.5
14
+ temp_x1 = (((x + @x1 - Ruby2D::Camera.x) * Math.cos(angle)) - ((y + @y1 - Ruby2D::Camera.y) * Math.sin(angle))) * Ruby2D::Camera.zoom + half_width
15
+ temp_y1 = (((x + @x1 - Ruby2D::Camera.x) * Math.sin(angle)) + ((y + @y1 - Ruby2D::Camera.y) * Math.cos(angle))) * Ruby2D::Camera.zoom + half_height
16
+ temp_x2 = (((x + @x2 - Ruby2D::Camera.x) * Math.cos(angle)) - ((y + @y2 - Ruby2D::Camera.y) * Math.sin(angle))) * Ruby2D::Camera.zoom + half_width
17
+ temp_y2 = (((x + @x2 - Ruby2D::Camera.x) * Math.sin(angle)) + ((y + @y2 - Ruby2D::Camera.y) * Math.cos(angle))) * Ruby2D::Camera.zoom + half_height
18
+ temp_x3 = (((x + @x3 - Ruby2D::Camera.x) * Math.cos(angle)) - ((y + @y3 - Ruby2D::Camera.y) * Math.sin(angle))) * Ruby2D::Camera.zoom + half_width
19
+ temp_y3 = (((x + @x3 - Ruby2D::Camera.x) * Math.sin(angle)) + ((y + @y3 - Ruby2D::Camera.y) * Math.cos(angle))) * Ruby2D::Camera.zoom + half_height
20
+ Ruby2D::Triangle.draw(x1: temp_x1, y1: temp_y1,
21
+ x2: temp_x2, y2: temp_y2,
22
+ x3: temp_x3, y3: temp_y3,
23
+ color: [
24
+ [c1.r, c1.g, c1.b, c1.a],
25
+ [c2.r, c2.g, c2.b, c2.a],
26
+ [c3.r, c3.g, c3.b, c3.a]
27
+ ],
28
+ z: z)
29
+ end
30
+
31
+ def initialize(opts = {})
32
+ super(opts)
33
+ Ruby2D::Camera << self
34
+ Window.remove(self)
35
+ add
36
+ end
37
+
38
+ def remove
39
+ @hide = true
40
+ end
41
+
42
+ def add
43
+ @hide = false
44
+ end
45
+
46
+ # Methods for moving the shape
47
+ def x
48
+ @x ||= 0
49
+ end
50
+
51
+ attr_writer :x, :y
52
+
53
+ def y
54
+ @y ||= 0
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ruby2d
4
+ module Camera
5
+ VERSION = '1.0.0'
6
+ end
7
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/ruby2d/camera/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "ruby2d-camera"
7
+ spec.version = Ruby2d::Camera::VERSION
8
+ spec.authors = ["Tradam"]
9
+ spec.email = ["ruby2d-camera@tradam.dev"]
10
+
11
+ spec.summary = "A library for camera movement in the Ruby2D gem"
12
+ #spec.description = "TODO: Write a longer description or delete this line."
13
+ spec.homepage = "https://github.com/realtradam/ruby2d-camera"
14
+ spec.license = "MIT"
15
+ spec.required_ruby_version = ">= 2.4.0"
16
+
17
+ #spec.metadata["allowed_push_host"] = "TODO: Set to 'https://mygemserver.com'"
18
+
19
+ spec.metadata["homepage_uri"] = spec.homepage
20
+ spec.metadata["source_code_uri"] = "https://github.com/realtradam/ruby2d-camera"
21
+ #spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
22
+
23
+ # Specify which files should be added to the gem when it is released.
24
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
25
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
26
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features|assets|example)/}) }
27
+ end
28
+ spec.bindir = "exe"
29
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
30
+ spec.require_paths = ["lib"]
31
+
32
+ # Uncomment to register a new dependency of your gem
33
+ # spec.add_dependency "example-gem", "~> 1.0"
34
+ spec.add_dependency "ruby2d", "~> 0.10"
35
+
36
+ # For more information and examples about making a new gem, checkout our
37
+ # guide at: https://bundler.io/guides/creating_gem.html
38
+ end
data/run.rb ADDED
@@ -0,0 +1,248 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ruby2d'
4
+ require 'ruby2d/camera'
5
+ require_relative 'house'
6
+ require_relative 'room'
7
+
8
+ Window.set(icon: './assets/blobcoolthink.png',
9
+ width: 1280,
10
+ height: 720,
11
+ background: 'blue')
12
+
13
+
14
+ @player = Camera::Sprite.new('./assets/sprites/mainblob-128.png',
15
+ x: 1920 / 1.1,
16
+ y: 1080 / 1.1,
17
+ width: 50,
18
+ height: 50,
19
+ clip_width: 128,
20
+ loop: true,
21
+ time: 1,
22
+ z: 99,
23
+ animations: {
24
+ walk: 0...60,
25
+ stand: 60...61
26
+ })
27
+ @shadow = Camera::Image.new(
28
+ 'assets/blobshadow.png',
29
+ width: 52,
30
+ height: 10,
31
+ z: 4
32
+ )
33
+ #Camera << @shadow
34
+ @player.play animation: :walk, loop: true
35
+ #Camera << @player
36
+
37
+ # UI
38
+ Rectangle.new(
39
+ width: 350,
40
+ height: 135,
41
+ color: 'navy',
42
+ z: 100
43
+ )
44
+ @ui_pos_cam = Text.new(
45
+ 'pos: 0,0',
46
+ x: 10,
47
+ y: 10,
48
+ color: 'teal',
49
+ z: 101
50
+ )
51
+ @ui_pos_ply = Text.new(
52
+ 'pos: 0,0',
53
+ x: 10,
54
+ y: 40,
55
+ color: 'teal',
56
+ z: 101
57
+ )
58
+ @ui_zoom = Text.new(
59
+ 'zoom: 0',
60
+ x: 10,
61
+ y: 70,
62
+ color: 'lime',
63
+ z: 101
64
+ )
65
+ @ui_rotation = Text.new(
66
+ 'rotation: 0',
67
+ x: 10,
68
+ y: 100,
69
+ color: 'lime',
70
+ z: 101
71
+ )
72
+ Rectangle.new(
73
+ x: (Window.width - 120),
74
+ width: 120,
75
+ height: 45,
76
+ color: 'navy',
77
+ z: 100
78
+ )
79
+ @ui_fps = Text.new(
80
+ 'fps: 60.00',
81
+ x: (Window.width - 110),
82
+ y: 10,
83
+ color: 'teal',
84
+ z: 101
85
+ )
86
+
87
+
88
+
89
+ # How fast the player can move
90
+ @speed = 5
91
+
92
+ # Initializing
93
+ @player_movement_x = 0
94
+ @player_movement_y = 0
95
+ @pressed_space = false
96
+ @scene_transition_into = false
97
+ @scene_transition_out = false
98
+ @indoors = false
99
+ @house = nil
100
+ @room = nil
101
+
102
+ on :key do |event|
103
+ if event.key == 'w'
104
+ @player_movement_y -= @speed unless @scene_transition_into || @scene_transition_out
105
+ end
106
+ if event.key == 's'
107
+ @player_movement_y += @speed unless @scene_transition_into || @scene_transition_out
108
+ end
109
+ if event.key == 'd'
110
+ @player_movement_x += @speed unless @scene_transition_into || @scene_transition_out
111
+ end
112
+ if event.key == 'a'
113
+ @player_movement_x -= @speed unless @scene_transition_into || @scene_transition_out
114
+ end
115
+ if event.key == 'space'
116
+ @pressed_space = true unless @scene_transition_into || @scene_transition_out
117
+ end
118
+ if event.key == 'q'
119
+ Camera.angle += 1 unless @scene_transition_into || @scene_transition_out
120
+ end
121
+ if event.key == 'e'
122
+ Camera.angle -= 1 unless @scene_transition_into || @scene_transition_out
123
+ end
124
+ if event.key == 'r'
125
+ unless @scene_transition_into || @scene_transition_out || Camera.angle.zero?
126
+ if Camera.angle <= 180
127
+ if Camera.angle > 10
128
+ Camera.angle -= 10
129
+ else
130
+ Camera.angle -=1
131
+ end
132
+ elsif
133
+ if Camera.angle < 350
134
+ Camera.angle += 10
135
+ else
136
+ Camera.angle += 1
137
+ end
138
+ end
139
+ end
140
+ end
141
+ end
142
+
143
+ update do
144
+ if (@player.x > 2371 && @player_movement_x.positive?) || (@player.x.negative? && @player_movement_x.negative?)
145
+ @player_movement_x = 0
146
+ end
147
+ if (@player.y > 1608 && @player_movement_y.positive?) || (@player.y.negative? && @player_movement_y.negative?)
148
+ @player_movement_y = 0
149
+ end
150
+ if !@player_movement_y.zero? == !@player_movement_x.zero?
151
+ @player_movement_x /= 1.4141
152
+ @player_movement_y /= 1.4141
153
+ end
154
+ @player.x += @player_movement_x
155
+ @player.y += @player_movement_y
156
+ if @player_movement_x.negative?
157
+ @player.play animation: :walk, loop: true
158
+ elsif @player_movement_x.positive? || !@player_movement_y.zero?
159
+ @player.play animation: :walk, loop: true, flip: :vertical
160
+ else
161
+ @player.play animation: :stand
162
+ end
163
+
164
+ if !@scene_transition_into && !@scene_transition_out
165
+ 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
166
+ Camera.x += (@player.x + (@player.width / 2) - Camera.x) * 0.025
167
+ Camera.y += (@player.y + (@player.height / 2) - Camera.y) * 0.025
168
+ elsif @scene_transition_into
169
+ if Camera.zoom < 250
170
+ Camera.zoom *= 1.05
171
+ Camera.angle += 5
172
+ else
173
+ @scene_transition_into = false
174
+ @scene_transition_out = true
175
+ if @room.nil?
176
+ @house.remove
177
+ @house = nil
178
+ @indoors = true
179
+ else
180
+ @room.remove
181
+ @room = nil
182
+ @indoors = false
183
+ end
184
+ #Camera.remove @background
185
+ @background.remove
186
+ @background = nil
187
+ end
188
+ Camera.x += (@player.x + (@player.width / 2) - Camera.x) * 0.25
189
+ Camera.y += (@player.y + (@player.height / 2) - Camera.y) * 0.25
190
+ elsif @scene_transition_out
191
+ if !((Camera.zoom <= (@zoom_transition * 1.001)) && (Camera.angle == @angle_transition))
192
+ Camera.zoom /= 1.05
193
+ Camera.angle -= 5
194
+ else
195
+ @scene_transition_out = false
196
+ end
197
+ end
198
+
199
+ if @house.nil? && !@indoors
200
+ @house = House.new(750, 300)
201
+ @background = Camera::Image.new(
202
+ 'assets/background.png',
203
+ x: 100, y: 100,
204
+ z: -1
205
+ )
206
+ #Camera << @background
207
+ elsif @room.nil? && @indoors
208
+ @room = Room.new(750,300)
209
+ @background = Camera::Rectangle.new(
210
+ color: 'black',
211
+ x: 0,
212
+ y: 0,
213
+ width: 1920,
214
+ height: 1080,
215
+ z: -1
216
+ )
217
+ end
218
+ @shadow.x = @player.x - 2
219
+ @shadow.y = @player.y + 42
220
+
221
+ #Camera.remove @house_text
222
+ @house_text&.remove
223
+ if @indoors
224
+ @house_text = @room.visted_by?(@player)
225
+ else
226
+ @house_text = @house.visted_by?(@player)
227
+ end
228
+ unless @house_text.nil?
229
+ #Camera << @house_text
230
+ @house_text.center = true
231
+ end
232
+ if !@house_text.nil? && @pressed_space && !@scene_transition_into && !@scene_transition_out
233
+ @scene_transition_into = true
234
+ @angle_transition = Camera.angle
235
+ @zoom_transition = Camera.zoom
236
+ end
237
+ @ui_pos_cam.text = "Camera Position: #{Camera.x.round(1)}, #{Camera.y.round(1)}"
238
+ @ui_pos_ply.text = "Player Position: #{@player.x.round(1)}, #{@player.y.round(1)}"
239
+ @ui_zoom.text = "Zoom: #{Camera.zoom.round(3)}"
240
+ @ui_fps.text = "FPS: #{Window.fps.round(2)}"
241
+ @ui_rotation.text = "Angle: #{Camera.angle}"
242
+ @player_movement_x = 0
243
+ @player_movement_y = 0
244
+ @pressed_space = false
245
+
246
+ #Camera.redraw
247
+ end
248
+ show
metadata ADDED
@@ -0,0 +1,82 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ruby2d-camera
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Tradam
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2021-08-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: ruby2d
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.10'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.10'
27
+ description:
28
+ email:
29
+ - ruby2d-camera@tradam.dev
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - ".gitignore"
35
+ - ".rubocop.yml"
36
+ - ".solargraph.yml"
37
+ - CHANGELOG.mdown
38
+ - Gemfile
39
+ - LICENSE.txt
40
+ - README.mdown
41
+ - Rakefile
42
+ - bin/console
43
+ - bin/setup
44
+ - lib/ruby2d/camera.rb
45
+ - lib/ruby2d/camera/circle.rb
46
+ - lib/ruby2d/camera/image.rb
47
+ - lib/ruby2d/camera/line.rb
48
+ - lib/ruby2d/camera/quad.rb
49
+ - lib/ruby2d/camera/rectangle.rb
50
+ - lib/ruby2d/camera/sprite.rb
51
+ - lib/ruby2d/camera/square.rb
52
+ - lib/ruby2d/camera/text.rb
53
+ - lib/ruby2d/camera/triangle.rb
54
+ - lib/ruby2d/camera/version.rb
55
+ - ruby2d-camera.gemspec
56
+ - run.rb
57
+ homepage: https://github.com/realtradam/ruby2d-camera
58
+ licenses:
59
+ - MIT
60
+ metadata:
61
+ homepage_uri: https://github.com/realtradam/ruby2d-camera
62
+ source_code_uri: https://github.com/realtradam/ruby2d-camera
63
+ post_install_message:
64
+ rdoc_options: []
65
+ require_paths:
66
+ - lib
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: 2.4.0
72
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ requirements: []
78
+ rubygems_version: 3.2.22
79
+ signing_key:
80
+ specification_version: 4
81
+ summary: A library for camera movement in the Ruby2D gem
82
+ test_files: []