fantasy 0.1.13 → 0.1.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +22 -1
  3. data/.yardopts +4 -0
  4. data/CHANGELOG.md +6 -0
  5. data/Gemfile +1 -1
  6. data/Gemfile.lock +55 -0
  7. data/README.md +14 -6
  8. data/docs/Actor.html +2737 -0
  9. data/docs/Background.html +961 -0
  10. data/docs/Camera.html +791 -0
  11. data/docs/Clock.html +753 -0
  12. data/docs/Color.html +776 -0
  13. data/docs/Coordinates.html +730 -0
  14. data/docs/Cursor.html +752 -0
  15. data/docs/Disk.html +236 -0
  16. data/docs/Draggable.html +198 -0
  17. data/docs/Fantasy.html +121 -0
  18. data/docs/Game.html +904 -0
  19. data/docs/Global.html +2791 -0
  20. data/docs/Gravitier.html +179 -0
  21. data/docs/HudImage.html +979 -0
  22. data/docs/HudText.html +1151 -0
  23. data/docs/Image.html +506 -0
  24. data/docs/Jumper.html +189 -0
  25. data/docs/Mouse.html +226 -0
  26. data/docs/MoveByCursor.html +374 -0
  27. data/docs/MoveByDirection.html +179 -0
  28. data/docs/Mover.html +305 -0
  29. data/docs/Music.html +524 -0
  30. data/docs/Shape.html +1057 -0
  31. data/docs/Sound.html +374 -0
  32. data/docs/Tilemap.html +491 -0
  33. data/docs/Tween.html +186 -0
  34. data/docs/UserInputs.html +879 -0
  35. data/docs/Utils.html +345 -0
  36. data/docs/_index.html +346 -0
  37. data/docs/class_list.html +51 -0
  38. data/docs/css/common.css +1 -0
  39. data/docs/css/full_list.css +58 -0
  40. data/docs/css/style.css +497 -0
  41. data/docs/file.CHANGELOG.html +121 -0
  42. data/docs/file.README.html +599 -0
  43. data/docs/file_list.html +61 -0
  44. data/docs/frames.html +17 -0
  45. data/docs/index.html +599 -0
  46. data/docs/js/app.js +314 -0
  47. data/docs/js/full_list.js +216 -0
  48. data/docs/js/jquery.js +4 -0
  49. data/docs/method_list.html +1931 -0
  50. data/docs/top-level-namespace.html +978 -0
  51. data/lib/fantasy/actor.rb +455 -123
  52. data/lib/fantasy/background.rb +109 -13
  53. data/lib/fantasy/base.rb +113 -1
  54. data/lib/fantasy/camera.rb +95 -11
  55. data/lib/fantasy/clock.rb +4 -2
  56. data/lib/fantasy/color.rb +158 -153
  57. data/lib/fantasy/coordinates.rb +5 -9
  58. data/lib/fantasy/cursor.rb +2 -1
  59. data/lib/fantasy/disk.rb +12 -8
  60. data/lib/fantasy/draggable.rb +22 -1
  61. data/lib/fantasy/global.rb +59 -31
  62. data/lib/fantasy/hud_image.rb +5 -3
  63. data/lib/fantasy/hud_text.rb +6 -2
  64. data/lib/fantasy/image.rb +12 -4
  65. data/lib/fantasy/includes/gravitier.rb +2 -0
  66. data/lib/fantasy/includes/jumper.rb +3 -2
  67. data/lib/fantasy/includes/log.rb +12 -0
  68. data/lib/fantasy/includes/move_by_cursors.rb +24 -15
  69. data/lib/fantasy/includes/move_by_direction.rb +2 -0
  70. data/lib/fantasy/includes/mover.rb +3 -0
  71. data/lib/fantasy/includes/user_inputs.rb +6 -0
  72. data/lib/fantasy/loop.rb +41 -44
  73. data/lib/fantasy/mouse.rb +2 -0
  74. data/lib/fantasy/music.rb +4 -2
  75. data/lib/fantasy/shape.rb +11 -2
  76. data/lib/fantasy/sound.rb +3 -1
  77. data/lib/fantasy/tilemap.rb +19 -13
  78. data/lib/fantasy/tween.rb +3 -1
  79. data/lib/fantasy/utils.rb +7 -13
  80. data/lib/fantasy/version.rb +1 -1
  81. data/lib/fantasy.rb +2 -0
  82. metadata +90 -4
  83. data/fantasy.gemspec +0 -40
  84. data/fonts/VT323-Regular.ttf +0 -0
@@ -1,9 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Represents on static image that will be rendered on every frame.
4
+ # Replicable (by default).
5
+ # The position is relative to `Camera.main`.
6
+ # ```
7
+ # on_game do
8
+ # background = Background.new(image_name: "beach")
9
+ # # background.replicable = false # if you don't want the image to replicate
10
+ # background.scale = 6
11
+ # end
12
+ # ```
1
13
  class Background
2
- attr_accessor :scale, :color, :visible, :position, :layer, :replicable
3
14
 
15
+ # In which layer the image of the Background is rendered.
16
+ # Smaller numbers are rendered behind higher numbers.
17
+ #
18
+ # Default `-100`.
19
+ #
20
+ # @example Set layer
21
+ # background = Background.new("image")
22
+ # background.layer = -50
23
+ attr_accessor :layer
24
+
25
+
26
+ # Coordinates object where x and y represent the position of the Background in the World
27
+ # (no necessarily in the Screen).
28
+ #
29
+ # Default `Coordinates.zero`.
30
+ #
31
+ # @example Setting position
32
+ # background = Background.new("image")
33
+ # background.position = Coordinates.new(10, 20)
34
+ # background.position.x # => 10
35
+ #
36
+ # @example Modify position
37
+ # background.position.x += 1
38
+ # background.position.x # => 11
39
+ attr_accessor :position
40
+
41
+ # [Boolean] When `true` the image will replicate itself to cover all the screen. Default `true`.
42
+ #
43
+ # Default `true`.
44
+ #
45
+ # @example Setting replicable
46
+ # background = Background.new("image")
47
+ # background.replicable = false
48
+ attr_accessor :replicable
49
+
50
+ # The value to scale the image of the Background when drawn.
51
+ # If the value is `2` the image will rendered at double of size.
52
+ # If the value is `0.5` the image will rendered at half of size.
53
+ #
54
+ # @note this value affects the attributes `width` and `height`
55
+ #
56
+ # Default `1`.
57
+ #
58
+ # @example Set scale
59
+ # background = Background.new("image")
60
+ # background.scale = 6
61
+ attr_accessor :scale
62
+
63
+ # When `false` the Background won't be rendered in the next frame.
64
+ #
65
+ # Default `true`.
66
+ #
67
+ # @example Set visible
68
+ # background = Background.new("image")
69
+ # background.visible = false
70
+ attr_accessor :visible
71
+
72
+ # Generates an Background with all the below default values:
73
+ # - **position**: `Coordinates.zero`.
74
+ # - **scale**: `1`.
75
+ # - **draggable_on_debug**: `true`.
76
+ # - **layer**: `-100`.
77
+ # - **image**: The Image generated by `image_name`
78
+ # - **name**: Same as `image_name`
79
+ # - **visible**: `true`
80
+ # - **replicable**: `true`
81
+ #
82
+ # @param image_name [string] the name of the image file from `./images/*`
83
+ # @return [Background] the Background
84
+ # @example Instantiate a new Background
85
+ # background = Background.new("background")
4
86
  def initialize(image_name:)
5
87
  @image = Image.new(image_name)
6
- @name = image_name
7
88
  @position = Coordinates.zero
8
89
  @scale = 1
9
90
  @visible = true
@@ -15,18 +96,19 @@ class Background
15
96
  Global.backgrounds.push(self)
16
97
  end
17
98
 
99
+ # @return [Fixnum] the Background width in pixels
18
100
  def width
19
- @image.width() * @scale
101
+ @image.width * @scale
20
102
  end
21
103
 
104
+ # @return [Fixnum] the Background height in pixels
22
105
  def height
23
- @image.height() * @scale
106
+ @image.height * @scale
24
107
  end
25
108
 
26
- def position_in_camera
27
- @position - Global.camera.position
28
- end
109
+ # rubocop:disable Style/GuardClause
29
110
 
111
+ # @!visibility private
30
112
  def draw
31
113
  if @visible
32
114
  if @replicable
@@ -36,18 +118,31 @@ class Background
36
118
  end
37
119
  end
38
120
  end
121
+ # rubocop:enable Style/GuardClause
39
122
 
40
- def draw_normal
41
- @image.draw(x: position_in_camera.x, y: position_in_camera.y, scale: @scale)
123
+ # Destroy this Background and it will not longer be rendered
124
+ #
125
+ # @example Destroy a Background
126
+ # background = Background.new("background")
127
+ # background.destroy
128
+ def destroy
129
+ Global.backgrounds.delete(self)
130
+ end
131
+
132
+ private
133
+
134
+ def position_in_camera
135
+ @position - Camera.main.position
42
136
  end
43
137
 
44
138
  # Camera relative Tiles
139
+ # rubocop:disable Metrics/AbcSize
45
140
  def draw_replicable
46
141
  tiles_delta_x = (position_in_camera.x % width) - width
47
142
  tiles_delta_y = (position_in_camera.y % height) - height
48
143
 
49
- tiles_needed_horizontal = ((SCREEN_WIDTH - (tiles_delta_x + width)) / width.to_f).ceil + 1
50
- tiles_needed_vertical = ((SCREEN_HEIGHT - (tiles_delta_y + height)) / height.to_f).ceil + 1
144
+ tiles_needed_horizontal = ((Global.screen_width - (tiles_delta_x + width)) / width.to_f).ceil + 1
145
+ tiles_needed_vertical = ((Global.screen_height - (tiles_delta_y + height)) / height.to_f).ceil + 1
51
146
 
52
147
  tiles_needed_horizontal.times do |index_horizontal|
53
148
  tiles_needed_vertical.times do |index_vertical|
@@ -55,8 +150,9 @@ class Background
55
150
  end
56
151
  end
57
152
  end
153
+ # rubocop:enable Metrics/AbcSize
58
154
 
59
- def destroy
60
- Global.backgrounds.delete(self)
155
+ def draw_normal
156
+ @image.draw(x: position_in_camera.x, y: position_in_camera.y, scale: @scale)
61
157
  end
62
158
  end
data/lib/fantasy/base.rb CHANGED
@@ -1,60 +1,172 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Here there are all the methods that can be used in the root level
4
+
1
5
  Global.setup_proc = nil
2
6
  Global.loop_proc = nil
3
7
 
8
+ # Defines the presentation Scene
9
+ #
10
+ # ```
11
+ # on_presentation do
12
+ # HudText.new(position: Coordinates.new(10, 100), text: "Press space to start")
13
+ #
14
+ # on_space_bar do
15
+ # Global.go_to_game
16
+ # end
17
+ # end
18
+ # ```
4
19
  def on_presentation(&block)
5
20
  Global.presentation_proc = block
6
21
  end
7
22
 
23
+ # Defines the game Scene
24
+ #
25
+ # ```
26
+ # on_game do
27
+ # # [...]
28
+ # if player.dead
29
+ # Global.go_to_end
30
+ # end
31
+ # end
32
+ # ```
8
33
  def on_game(&block)
9
34
  Global.game_proc = block
10
35
  end
11
36
 
37
+ # Defines the end Scene
38
+ #
39
+ # ```
40
+ # on_end do
41
+ # HudText.new(position: Coordinates.new(10, 100), text: "You are dead. Press space to re-tart")
42
+ #
43
+ # on_space_bar do
44
+ # Global.go_to_presentation
45
+ # end
46
+ # end
47
+ # ```
12
48
  def on_end(&block)
13
49
  Global.end_proc = block
14
50
  end
15
51
 
52
+ # @!visibility private
16
53
  def on_setup(&block)
17
54
  Global.setup_proc = block
18
55
  end
19
56
 
57
+ # Executes on every frame. To be used inside one of the scene blocks (`on_presentation`, `on_game`, `on_end`)
58
+ # ```
59
+ # on_game do
60
+ # on_loop do
61
+ # Global.references.time = Time.at(Global.seconds_in_scene).utc.strftime("%M:%S")
62
+ # end
63
+ # end
64
+ # ```
20
65
  def on_loop(&block)
21
66
  Global.loop_proc = block
22
67
  end
23
68
 
69
+ # @!visibility private
24
70
  def on_button(&block)
25
71
  Global.button_proc = block
26
72
  end
27
73
 
74
+ # Triggered any time space bar key is pressed. To be used inside one of the scene blocks (`on_presentation`, `on_game`, `on_end`)
75
+ # ```
76
+ # on_game do
77
+ # on_space_bar do
78
+ # shoot_gun # for example
79
+ # end
80
+ # end
81
+ # ```
28
82
  def on_space_bar(&block)
29
83
  Global.space_bar_proc = block
30
84
  end
31
85
 
86
+ # Triggered any time cursor up key is pressed. To be used inside one of the scene blocks (`on_presentation`, `on_game`, `on_end`)
87
+ # ```
88
+ # on_game do
89
+ # on_cursor_up do
90
+ # look_ups # for example
91
+ # end
92
+ # end
93
+ # ```
32
94
  def on_cursor_up(&block)
33
95
  Global.cursor_up_proc = block
34
96
  end
35
97
 
98
+ # Triggered any time cursor down key is pressed. To be used inside one of the scene blocks (`on_presentation`, `on_game`, `on_end`)
99
+ # ```
100
+ # on_game do
101
+ # on_cursor_down do
102
+ # look_down # for example
103
+ # end
104
+ # end
105
+ # ```
36
106
  def on_cursor_down(&block)
37
107
  Global.cursor_down_proc = block
38
108
  end
39
109
 
110
+ # Triggered any time cursor left key is pressed. To be used inside one of the scene blocks (`on_presentation`, `on_game`, `on_end`)
111
+ # ```
112
+ # on_game do
113
+ # on_cursor_left do
114
+ # look_left # for example
115
+ # end
116
+ # end
117
+ # ```
40
118
  def on_cursor_left(&block)
41
119
  Global.cursor_left_proc = block
42
120
  end
43
121
 
122
+ # Triggered any time cursor right key is pressed. To be used inside one of the scene blocks (`on_presentation`, `on_game`, `on_end`)
123
+ # ```
124
+ # on_game do
125
+ # on_cursor_right do
126
+ # look_right # for example
127
+ # end
128
+ # end
129
+ # ```
44
130
  def on_cursor_right(&block)
45
131
  Global.cursor_right_proc = block
46
132
  end
47
133
 
134
+ # Triggered any time mouse left button is pressed. To be used inside one of the scene blocks (`on_presentation`, `on_game`, `on_end`)
135
+ # ```
136
+ # on_game do
137
+ # on_mouse_button_left do
138
+ # show_menu # for example
139
+ # end
140
+ # end
141
+ # ```
48
142
  def on_mouse_button_left(&block)
49
143
  Global.mouse_button_left_proc = block
50
144
  end
51
145
 
146
+ # Triggered any time mouse right button is pressed. To be used inside one of the scene blocks (`on_presentation`, `on_game`, `on_end`)
147
+ # ```
148
+ # on_game do
149
+ # on_mouse_button_right do
150
+ # show_menu # for example
151
+ # end
152
+ # end
153
+ # ```
52
154
  def on_mouse_button_right(&block)
53
155
  Global.mouse_button_right_proc = block
54
156
  end
55
157
 
158
+ # Starts the game. This method has to be called when all the desired scene blocks (`on_presentation`, `on_game`, `on_end`) have been declared.
159
+ # ```
160
+ # on_game do
161
+ # # do game stuff
162
+ # end
163
+ #
164
+ # start!
165
+ # ```
56
166
  def start!
167
+ raise "'SCREEN_WIDTH' and 'SCREEN_HEIGHT' both have to be set at the beginning of the program" unless defined?(SCREEN_WIDTH) && defined?(SCREEN_HEIGHT)
168
+
57
169
  Global.setup
58
- Global.game = Game.new
170
+ Global.game = Game.new(SCREEN_WIDTH, SCREEN_HEIGHT)
59
171
  Global.game.show
60
172
  end
@@ -1,31 +1,115 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Represents Coordinates of the camera and it affects the screen position of all Actors and Backgrounds.
4
+ # There is only one active Camera and it is acceded by `Camera.main`. This Camera is initialized automatically
5
+ # and it is already accessible. It can also be changed by another `Camera` instance.`
6
+ #
7
+ # @example Set the camera position
8
+ # Camera.main.position = Coordinates.new(0, 100)
9
+ #
10
+ # @example Camera follows player vertically
11
+ # on_game do
12
+ # player = Actor.new("image")
13
+ #
14
+ # on_loop do
15
+ # Camera.main.position.y = player.position.y - (SCREEN_HEIGHT / 2)
16
+ # end
17
+ # end
18
+ #
19
+ # @example Switching between cameras
20
+ # camera_1 = Camera.new
21
+ # camera_2 = Camera.new(position: Coordinates.new(0, 10))
22
+ # Camera.main = camera_1
23
+ # Camera.main = camera_2
1
24
  class Camera
2
- include MoveByCursor
3
25
 
4
- attr_accessor :position, :direction, :speed
26
+ # Coordinates object where x and y represent the position of the Camera in the World (no necessarily in the Screen).
27
+ #
28
+ # Default `Coordinates.zero`.
29
+ #
30
+ # @return [Coordinates] the actual position
31
+ #
32
+ # @example Setting position
33
+ # Camera.main.position = Coordinates.new(10, 20)
34
+ # Camera.main.position.x # => 10
35
+ #
36
+ # @example Modify position
37
+ # Camera.main.position.x += 1
38
+ # Camera.main.position.x # => 11
39
+ attr_accessor :position
40
+
41
+ # Controls the direction in which the Camera will move in the next frame.
42
+ #
43
+ # Default `Coordinates.zero`.
44
+ #
45
+ # @return [Coordinates] the actual direction
46
+ #
47
+ # @note The the pixels per second is represented by the `@speed` attribute
48
+ #
49
+ # @example Set direction
50
+ # Camera.main.direction = Coordinates.right
51
+ attr_accessor :direction
52
+
53
+ # Controls the pixels per second which the Camera will move in the next frame.
54
+ #
55
+ # Default `0`.
56
+ #
57
+ # @return [Float] the actual speed
58
+ #
59
+ # @note The the direction is represented by the `@direction` attribute
60
+ #
61
+ # @example Set speed
62
+ # Camera.main.speed = 10
63
+ attr_accessor :speed
5
64
 
65
+ # Generates a Camera with all the default attribute values
66
+ # @example Generate an Camera
67
+ # camera = Camera.new
68
+ # camera.position # => Coordinates.zero
69
+ # camera.direction # => Coordinates.zero
70
+ # camera.speed # => 0
71
+ #
72
+ # @param position [Coordinates] the initial position of the camera. Default `Coordinates.zero`
73
+ # @return [Camera] the Camera
6
74
  def initialize(position: Coordinates.zero)
7
75
  @position = position
8
76
  @direction = Coordinates.zero
9
77
  @speed = 0
10
- @moving_with_cursors = false
11
78
  @on_after_move_callback = nil
12
79
  end
13
80
 
14
- def move_with_cursors
15
- @moving_with_cursors = true
16
- end
17
-
81
+ # @!visibility private
18
82
  def move
19
- calculate_direction_by_cursors if @moving_with_cursors
20
-
21
83
  if @direction != Coordinates.zero && !@speed.zero?
22
- @position = @position + (@direction * @speed * Global.frame_time)
84
+ @position += (@direction * @speed * Global.frame_time)
23
85
  end
24
86
 
25
- @on_after_move_callback.call unless @on_after_move_callback.nil?
87
+ @on_after_move_callback&.call
26
88
  end
27
89
 
90
+ # Triggered on every frame after the move has been executed
91
+ # @example Avoid Camera to move over limits
92
+ # Camera.main.on_after_move do
93
+ # if Camera.main.position.x > 100
94
+ # Camera.main.position.x = 100
95
+ # end
96
+ # end
28
97
  def on_after_move(&block)
29
98
  @on_after_move_callback = block
30
99
  end
100
+
101
+ class << self
102
+ # @return [Camera] The active Camera
103
+ attr_accessor :main
104
+
105
+ # @!visibility private
106
+ def initialize
107
+ reset
108
+ end
109
+
110
+ # @!visibility private
111
+ def reset
112
+ @main = Camera.new
113
+ end
114
+ end
31
115
  end
data/lib/fantasy/clock.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Clock
2
4
  attr_accessor :persistent
3
5
  attr_reader :thread
@@ -29,9 +31,9 @@ class Clock
29
31
  times_executed = 0
30
32
  @thread =
31
33
  Thread.new do
32
- while(times_executed < times)
34
+ while times_executed < times
33
35
  @block.call
34
- times_executed += 1;
36
+ times_executed += 1
35
37
 
36
38
  seconds_to_sleep = seconds.is_a?(Range) ? rand(seconds) : seconds
37
39
  sleep(seconds_to_sleep)