fantasy 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.rubocop.yml +13 -0
- data/CHANGELOG.md +5 -0
- data/Gemfile +12 -0
- data/LICENSE.txt +21 -0
- data/README.md +163 -0
- data/Rakefile +16 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/fantasy.gemspec +40 -0
- data/fonts/OFL.txt +93 -0
- data/fonts/VT323-Regular.ttf +0 -0
- data/lib/fantasy/actor.rb +141 -0
- data/lib/fantasy/base.rb +59 -0
- data/lib/fantasy/camera.rb +7 -0
- data/lib/fantasy/clock.rb +39 -0
- data/lib/fantasy/color.rb +5 -0
- data/lib/fantasy/coordinates.rb +31 -0
- data/lib/fantasy/draggable.rb +27 -0
- data/lib/fantasy/global.rb +106 -0
- data/lib/fantasy/hud_image.rb +46 -0
- data/lib/fantasy/hud_text.rb +57 -0
- data/lib/fantasy/loop.rb +55 -0
- data/lib/fantasy/sound.rb +21 -0
- data/lib/fantasy/utils.rb +27 -0
- data/lib/fantasy/version.rb +5 -0
- data/lib/fantasy.rb +17 -0
- metadata +101 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 98740063fd63398988bf5b11e625a75e2526f617ab22e9aa1ff483a65c0f91cb
|
4
|
+
data.tar.gz: b4eecd987e01f24f2a1d3aef7627c195992ec0ffa0c4b124fb6ca577896a2a58
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ab99759553de96490612fbf1c6089db1113ec26969876b88d9215fbb1317a7ee08dfef98cd376c7843750013ed3981b10fc0beba0e816a6c5c7358511166b023
|
7
|
+
data.tar.gz: 69c41125931104d3440c02bfe1073b6d37f27d2efebbe3fdd331165c014739bf81f92d80c83c46f636d0eda77d583a802a7f377c943ce8964a8bf9d7567f7d4d
|
data/.rubocop.yml
ADDED
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2022 Fernando Guillen
|
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.md
ADDED
@@ -0,0 +1,163 @@
|
|
1
|
+
# Ruby in Fantasy
|
2
|
+
|
3
|
+
An upper layer over Gosu library to offer a more friendly API for an easy and lean game development.
|
4
|
+
|
5
|
+
Specially intended to use Ruby as a learning language to introduce children into programming.
|
6
|
+
|
7
|
+
**Attention**: This project is in early development phase, right now it is just an experiment
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
Add this line to your application's Gemfile:
|
12
|
+
|
13
|
+
```ruby
|
14
|
+
gem "fantasy"
|
15
|
+
```
|
16
|
+
|
17
|
+
And then execute:
|
18
|
+
|
19
|
+
$ bundle install
|
20
|
+
|
21
|
+
Or install it yourself as:
|
22
|
+
|
23
|
+
$ gem install fantasy
|
24
|
+
|
25
|
+
## Features
|
26
|
+
|
27
|
+
### Actor
|
28
|
+
|
29
|
+
Managing game elements which have (optionally) image, movement and collision
|
30
|
+
|
31
|
+
- Easy to set an `image`
|
32
|
+
- Managing movement through `direction` and `speed`
|
33
|
+
- Built-in movement control through cursors
|
34
|
+
- Collision detection, OnCollision callback
|
35
|
+
- Jump (TODO)
|
36
|
+
- Gravity (TODO)
|
37
|
+
- Animations (TODO)
|
38
|
+
- Possibility to extend Actor class or instantiate it directly for simple characters
|
39
|
+
|
40
|
+
### Clock
|
41
|
+
|
42
|
+
Create new execution threads to program delayed behaviors, repetitive actions, animations, ...
|
43
|
+
|
44
|
+
- Run now
|
45
|
+
- Run after a delay
|
46
|
+
- Repeat
|
47
|
+
- Stop
|
48
|
+
- Callback when finished (TODO)
|
49
|
+
|
50
|
+
### Animations
|
51
|
+
|
52
|
+
Add animations to an Actor and activate them when special state triggered
|
53
|
+
|
54
|
+
- Set frames (TODO)
|
55
|
+
- Duration in seconds (TODO)
|
56
|
+
- Run once (TODO)
|
57
|
+
- Run on loop (TODO)
|
58
|
+
- Stop (TODO)
|
59
|
+
- Callback when finished (TODO)
|
60
|
+
|
61
|
+
### UI
|
62
|
+
|
63
|
+
#### Button (TODO)
|
64
|
+
|
65
|
+
Easy to set up a graphical component that responds to mouse hover and click events.
|
66
|
+
|
67
|
+
- Set image (TODO)
|
68
|
+
- Set image when hover (TODO)
|
69
|
+
- Set image when clicked (TODO)
|
70
|
+
- OnClicked callback (TODO)
|
71
|
+
|
72
|
+
#### HUD Elements
|
73
|
+
|
74
|
+
For easy creation of head-up display components.
|
75
|
+
|
76
|
+
- Text Element
|
77
|
+
- Image Element
|
78
|
+
- Auto update text (observer variable changes) (TODO)
|
79
|
+
|
80
|
+
### Debug Mode
|
81
|
+
|
82
|
+
When active different attributes from all the Actors and HUD elements will be visible in the screen.
|
83
|
+
|
84
|
+
- Position
|
85
|
+
- Collider
|
86
|
+
|
87
|
+
On top, when debug mode is active, the Actors and HUD elements become draggable.
|
88
|
+
The new position won't be persistent but it will be helpful to identify which should be the desired position.
|
89
|
+
|
90
|
+
### Camera
|
91
|
+
|
92
|
+
Setting up a camera component that we can easily move around and all the active
|
93
|
+
Actors in the game will be rendered in the relative position to this camera.
|
94
|
+
|
95
|
+
- Allow camera move
|
96
|
+
- Easy to follow one actor
|
97
|
+
|
98
|
+
### Colors palette (TODO)
|
99
|
+
|
100
|
+
- Not deal with RGB or anything, just a list of colors (TODO)
|
101
|
+
|
102
|
+
### Game Scene transitions
|
103
|
+
|
104
|
+
Easy to configure 3 basic game states:
|
105
|
+
|
106
|
+
- Initial screen
|
107
|
+
- Game
|
108
|
+
- Game over screen
|
109
|
+
|
110
|
+
Each state should be independent and unique Actors and other elements can be created and configured for each state
|
111
|
+
|
112
|
+
Built-in mechanism to move from one state to another.
|
113
|
+
|
114
|
+
### Pause Game (TODO)
|
115
|
+
|
116
|
+
- Pause game, pause Actors, animations, clocks, ... (TODO)
|
117
|
+
|
118
|
+
### Core run
|
119
|
+
|
120
|
+
Move the core functions to the top level hierarchy so I don't need to create a `Game::Window` class
|
121
|
+
|
122
|
+
### Sound
|
123
|
+
|
124
|
+
Direct and easy way to play a sound
|
125
|
+
|
126
|
+
### Data Persistance (TODO)
|
127
|
+
|
128
|
+
Simple mechanismo to save data in disk. For user preferences, game progress, high scores and others
|
129
|
+
|
130
|
+
### User Inputs
|
131
|
+
|
132
|
+
Easy access to keyboard and mouse inputs on any part of the code. Specially in the Actors.
|
133
|
+
|
134
|
+
- Allow "on_space_bar" and each Actor (TODO)
|
135
|
+
- Allow multiple "on_space_bar" (TODO)
|
136
|
+
- Remove "on_space_bar" when changing scene (TODO)
|
137
|
+
|
138
|
+
## API
|
139
|
+
|
140
|
+
|
141
|
+
|
142
|
+
## Credits for assets
|
143
|
+
|
144
|
+
- Sprites: www.kenney.nl
|
145
|
+
- Font: VT323 Project Authors (peter.hull@oikoi.com)
|
146
|
+
|
147
|
+
## Bugs
|
148
|
+
|
149
|
+
- When dragging in debug mode new elements are being added to the drag (TODO)
|
150
|
+
|
151
|
+
## Development
|
152
|
+
|
153
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
154
|
+
|
155
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
156
|
+
|
157
|
+
## Contributing
|
158
|
+
|
159
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/fguillen/fantasy.
|
160
|
+
|
161
|
+
## License
|
162
|
+
|
163
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "bundler/gem_tasks"
|
4
|
+
require "rake/testtask"
|
5
|
+
|
6
|
+
Rake::TestTask.new(:test) do |t|
|
7
|
+
t.libs << "test"
|
8
|
+
t.libs << "lib"
|
9
|
+
t.test_files = FileList["test/**/*_test.rb"]
|
10
|
+
end
|
11
|
+
|
12
|
+
require "rubocop/rake_task"
|
13
|
+
|
14
|
+
RuboCop::RakeTask.new
|
15
|
+
|
16
|
+
task default: %i[test 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 "fantasy"
|
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
data/fantasy.gemspec
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "lib/fantasy/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "fantasy"
|
7
|
+
spec.version = Fantasy::VERSION
|
8
|
+
spec.authors = ["Fernando Guillen"]
|
9
|
+
spec.email = ["fguillen.mail@gmail.com"]
|
10
|
+
|
11
|
+
spec.summary = "Simple toolbox library and lean API to build great mini games"
|
12
|
+
spec.description = "Simple toolbox library and lean API to build great mini games"
|
13
|
+
spec.homepage = "https://github.com/fguillen/fantasy"
|
14
|
+
spec.license = "MIT"
|
15
|
+
spec.required_ruby_version = ">= 3.0.0"
|
16
|
+
|
17
|
+
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
18
|
+
|
19
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
20
|
+
spec.metadata["source_code_uri"] = "https://github.com/fguillen/fantasy"
|
21
|
+
spec.metadata["changelog_uri"] = "https://github.com/fguillen/fantasy/blob/main/CHANGELOG.md"
|
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 do |f|
|
27
|
+
(f == __FILE__) || f.match(%r{\A(?:(?:test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
|
28
|
+
end
|
29
|
+
end
|
30
|
+
spec.bindir = "exe"
|
31
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
32
|
+
spec.require_paths = ["lib"]
|
33
|
+
|
34
|
+
# Uncomment to register a new dependency of your gem
|
35
|
+
spec.add_dependency "gosu", "~> 1.4.1"
|
36
|
+
spec.add_dependency "vector2d", "~> 2.2.3"
|
37
|
+
|
38
|
+
# For more information and examples about making a new gem, checkout our
|
39
|
+
# guide at: https://bundler.io/guides/creating_gem.html
|
40
|
+
end
|
data/fonts/OFL.txt
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
Copyright 2011, The VT323 Project Authors (peter.hull@oikoi.com)
|
2
|
+
|
3
|
+
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
4
|
+
This license is copied below, and is also available with a FAQ at:
|
5
|
+
http://scripts.sil.org/OFL
|
6
|
+
|
7
|
+
|
8
|
+
-----------------------------------------------------------
|
9
|
+
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
10
|
+
-----------------------------------------------------------
|
11
|
+
|
12
|
+
PREAMBLE
|
13
|
+
The goals of the Open Font License (OFL) are to stimulate worldwide
|
14
|
+
development of collaborative font projects, to support the font creation
|
15
|
+
efforts of academic and linguistic communities, and to provide a free and
|
16
|
+
open framework in which fonts may be shared and improved in partnership
|
17
|
+
with others.
|
18
|
+
|
19
|
+
The OFL allows the licensed fonts to be used, studied, modified and
|
20
|
+
redistributed freely as long as they are not sold by themselves. The
|
21
|
+
fonts, including any derivative works, can be bundled, embedded,
|
22
|
+
redistributed and/or sold with any software provided that any reserved
|
23
|
+
names are not used by derivative works. The fonts and derivatives,
|
24
|
+
however, cannot be released under any other type of license. The
|
25
|
+
requirement for fonts to remain under this license does not apply
|
26
|
+
to any document created using the fonts or their derivatives.
|
27
|
+
|
28
|
+
DEFINITIONS
|
29
|
+
"Font Software" refers to the set of files released by the Copyright
|
30
|
+
Holder(s) under this license and clearly marked as such. This may
|
31
|
+
include source files, build scripts and documentation.
|
32
|
+
|
33
|
+
"Reserved Font Name" refers to any names specified as such after the
|
34
|
+
copyright statement(s).
|
35
|
+
|
36
|
+
"Original Version" refers to the collection of Font Software components as
|
37
|
+
distributed by the Copyright Holder(s).
|
38
|
+
|
39
|
+
"Modified Version" refers to any derivative made by adding to, deleting,
|
40
|
+
or substituting -- in part or in whole -- any of the components of the
|
41
|
+
Original Version, by changing formats or by porting the Font Software to a
|
42
|
+
new environment.
|
43
|
+
|
44
|
+
"Author" refers to any designer, engineer, programmer, technical
|
45
|
+
writer or other person who contributed to the Font Software.
|
46
|
+
|
47
|
+
PERMISSION & CONDITIONS
|
48
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
49
|
+
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
50
|
+
redistribute, and sell modified and unmodified copies of the Font
|
51
|
+
Software, subject to the following conditions:
|
52
|
+
|
53
|
+
1) Neither the Font Software nor any of its individual components,
|
54
|
+
in Original or Modified Versions, may be sold by itself.
|
55
|
+
|
56
|
+
2) Original or Modified Versions of the Font Software may be bundled,
|
57
|
+
redistributed and/or sold with any software, provided that each copy
|
58
|
+
contains the above copyright notice and this license. These can be
|
59
|
+
included either as stand-alone text files, human-readable headers or
|
60
|
+
in the appropriate machine-readable metadata fields within text or
|
61
|
+
binary files as long as those fields can be easily viewed by the user.
|
62
|
+
|
63
|
+
3) No Modified Version of the Font Software may use the Reserved Font
|
64
|
+
Name(s) unless explicit written permission is granted by the corresponding
|
65
|
+
Copyright Holder. This restriction only applies to the primary font name as
|
66
|
+
presented to the users.
|
67
|
+
|
68
|
+
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
69
|
+
Software shall not be used to promote, endorse or advertise any
|
70
|
+
Modified Version, except to acknowledge the contribution(s) of the
|
71
|
+
Copyright Holder(s) and the Author(s) or with their explicit written
|
72
|
+
permission.
|
73
|
+
|
74
|
+
5) The Font Software, modified or unmodified, in part or in whole,
|
75
|
+
must be distributed entirely under this license, and must not be
|
76
|
+
distributed under any other license. The requirement for fonts to
|
77
|
+
remain under this license does not apply to any document created
|
78
|
+
using the Font Software.
|
79
|
+
|
80
|
+
TERMINATION
|
81
|
+
This license becomes null and void if any of the above conditions are
|
82
|
+
not met.
|
83
|
+
|
84
|
+
DISCLAIMER
|
85
|
+
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
86
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
87
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
88
|
+
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
89
|
+
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
90
|
+
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
91
|
+
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
92
|
+
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
93
|
+
OTHER DEALINGS IN THE FONT SOFTWARE.
|
Binary file
|
@@ -0,0 +1,141 @@
|
|
1
|
+
class Actor
|
2
|
+
attr_reader :image, :moving_with_cursors
|
3
|
+
attr_accessor :position, :direction, :speed, :solid, :scale, :name, :layer
|
4
|
+
|
5
|
+
def initialize(image_name)
|
6
|
+
@image = Gosu::Image.new("#{__dir__}/../images/#{image_name}.png", { retro: true })
|
7
|
+
@name = image_name
|
8
|
+
@position = Coordinates.new(0, 0)
|
9
|
+
@direction = Coordinates.new(0, 0)
|
10
|
+
@speed = 0
|
11
|
+
@scale = 1
|
12
|
+
@on_after_move_callback = nil
|
13
|
+
@moving_with_cursors = false
|
14
|
+
@solid = false
|
15
|
+
@draggable_on_debug = true
|
16
|
+
@dragging = false
|
17
|
+
@dragging_offset = nil
|
18
|
+
@layer = 0
|
19
|
+
|
20
|
+
@on_collision_callback = nil
|
21
|
+
|
22
|
+
Global.actors << self
|
23
|
+
end
|
24
|
+
|
25
|
+
def image=(image_name)
|
26
|
+
@image = Gosu::Image.new("#{__dir__}/../images/#{image_name}.png", { retro: true })
|
27
|
+
end
|
28
|
+
|
29
|
+
def width
|
30
|
+
@image.width() * @scale
|
31
|
+
end
|
32
|
+
|
33
|
+
def height
|
34
|
+
@image.height() * @scale
|
35
|
+
end
|
36
|
+
|
37
|
+
def move_with_cursors
|
38
|
+
@moving_with_cursors = true
|
39
|
+
end
|
40
|
+
|
41
|
+
def direction=(value)
|
42
|
+
@direction = value
|
43
|
+
@direction = @direction.normalize
|
44
|
+
end
|
45
|
+
|
46
|
+
def draw
|
47
|
+
@image.draw(position_in_camera.x, position_in_camera.y, 0, @scale, @scale)
|
48
|
+
|
49
|
+
draw_debug if Global.debug
|
50
|
+
end
|
51
|
+
|
52
|
+
def draw_debug
|
53
|
+
Utils.draw_frame(position_in_camera.x, position_in_camera.y, width, height, 1, Gosu::Color::RED) if solid
|
54
|
+
Global.pixel_font.draw_text("#{@position.x.floor},#{@position.y.floor}", position_in_camera.x, position_in_camera.y - 20, 1)
|
55
|
+
end
|
56
|
+
|
57
|
+
def position_in_camera
|
58
|
+
@position - Global.camera.position
|
59
|
+
end
|
60
|
+
|
61
|
+
def move
|
62
|
+
mouse_position = Global.mouse_position + Global.camera.position
|
63
|
+
|
64
|
+
if @draggable_on_debug && Global.debug && !@dragging && Gosu.button_down?(Gosu::MS_LEFT) && Utils.collision_at?(self, mouse_position.x, mouse_position.y)
|
65
|
+
@dragging = true
|
66
|
+
@dragging_offset = mouse_position - @position
|
67
|
+
end
|
68
|
+
|
69
|
+
if @dragging && !Gosu.button_down?(Gosu::MS_LEFT)
|
70
|
+
@dragging = false
|
71
|
+
end
|
72
|
+
|
73
|
+
if @dragging
|
74
|
+
@position = mouse_position - @dragging_offset
|
75
|
+
else
|
76
|
+
calculate_direction_by_cursors if @moving_with_cursors
|
77
|
+
|
78
|
+
if @direction != Coordinates.zero && !@speed.zero?
|
79
|
+
@last_position = @position
|
80
|
+
@position = @position + (@direction * @speed * Global.frame_time)
|
81
|
+
|
82
|
+
if solid?
|
83
|
+
actual_collisions = collisions
|
84
|
+
actual_collisions.each do |actor|
|
85
|
+
collision_with(actor)
|
86
|
+
actor.collision_with(self)
|
87
|
+
end
|
88
|
+
|
89
|
+
@position = @last_position if actual_collisions.any?
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
@on_after_move_callback.call unless @on_after_move_callback.nil?
|
95
|
+
end
|
96
|
+
|
97
|
+
def solid?
|
98
|
+
@solid
|
99
|
+
end
|
100
|
+
|
101
|
+
def on_after_move(&block)
|
102
|
+
@on_after_move_callback = block
|
103
|
+
end
|
104
|
+
|
105
|
+
def on_collision(&block)
|
106
|
+
@on_collision_callback = block
|
107
|
+
end
|
108
|
+
|
109
|
+
def on_destroy(&block)
|
110
|
+
@on_destroy_callback = block
|
111
|
+
end
|
112
|
+
|
113
|
+
def collision_with(actor)
|
114
|
+
@on_collision_callback.call(actor) unless @on_collision_callback.nil?
|
115
|
+
end
|
116
|
+
|
117
|
+
def calculate_direction_by_cursors
|
118
|
+
if Gosu.button_down?(Gosu::KB_DOWN)
|
119
|
+
@direction = Coordinates.down
|
120
|
+
elsif Gosu.button_down?(Gosu::KB_UP)
|
121
|
+
@direction = Coordinates.up
|
122
|
+
elsif Gosu.button_down?(Gosu::KB_RIGHT)
|
123
|
+
@direction = Coordinates.right
|
124
|
+
elsif Gosu.button_down?(Gosu::KB_LEFT)
|
125
|
+
@direction = Coordinates.left
|
126
|
+
else
|
127
|
+
@direction = Coordinates.zero
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def collisions
|
132
|
+
Global.actors.reject { |e| e == self }.select { |e| e.solid? }.select do |actor|
|
133
|
+
Utils.collision? self, actor
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def destroy
|
138
|
+
@on_destroy_callback.call unless @on_destroy_callback.nil?
|
139
|
+
Global.actors.delete(self)
|
140
|
+
end
|
141
|
+
end
|
data/lib/fantasy/base.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
Global.setup_proc = nil
|
2
|
+
Global.loop_proc = nil
|
3
|
+
|
4
|
+
def on_presentation(&block)
|
5
|
+
Global.presentation_proc = block
|
6
|
+
end
|
7
|
+
|
8
|
+
def on_game(&block)
|
9
|
+
Global.game_proc = block
|
10
|
+
end
|
11
|
+
|
12
|
+
def on_end(&block)
|
13
|
+
Global.end_proc = block
|
14
|
+
end
|
15
|
+
|
16
|
+
def on_setup(&block)
|
17
|
+
Global.setup_proc = block
|
18
|
+
end
|
19
|
+
|
20
|
+
def on_loop(&block)
|
21
|
+
Global.loop_proc = block
|
22
|
+
end
|
23
|
+
|
24
|
+
def on_button(&block)
|
25
|
+
Global.button_proc = block
|
26
|
+
end
|
27
|
+
|
28
|
+
def on_space_bar(&block)
|
29
|
+
Global.space_bar_proc = block
|
30
|
+
end
|
31
|
+
|
32
|
+
def on_cursor_up(&block)
|
33
|
+
Global.cursor_up_proc = block
|
34
|
+
end
|
35
|
+
|
36
|
+
def on_cursor_down(&block)
|
37
|
+
Global.cursor_down_proc = block
|
38
|
+
end
|
39
|
+
|
40
|
+
def on_cursor_left(&block)
|
41
|
+
Global.cursor_left_proc = block
|
42
|
+
end
|
43
|
+
|
44
|
+
def on_cursor_right(&block)
|
45
|
+
Global.cursor_right_proc = block
|
46
|
+
end
|
47
|
+
|
48
|
+
def on_mouse_button_left(&block)
|
49
|
+
Global.mouse_button_left_proc = block
|
50
|
+
end
|
51
|
+
|
52
|
+
def on_mouse_button_right(&block)
|
53
|
+
Global.mouse_button_right_proc = block
|
54
|
+
end
|
55
|
+
|
56
|
+
def start!
|
57
|
+
Global.game = Game.new
|
58
|
+
Global.game.show
|
59
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
class Clock
|
2
|
+
def initialize(&block)
|
3
|
+
@block = block
|
4
|
+
@thread = nil
|
5
|
+
|
6
|
+
Global.clocks << self
|
7
|
+
end
|
8
|
+
|
9
|
+
def run_now
|
10
|
+
@thread =
|
11
|
+
Thread.new do
|
12
|
+
@block.call
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def run_on(seconds:)
|
17
|
+
@thread =
|
18
|
+
Thread.new do
|
19
|
+
sleep(seconds)
|
20
|
+
@block.call
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def repeat(seconds: 1, times: Float::INFINITY)
|
25
|
+
times_executed = 0
|
26
|
+
@thread =
|
27
|
+
Thread.new do
|
28
|
+
while(times_executed < times)
|
29
|
+
@block.call
|
30
|
+
times_executed += 1;
|
31
|
+
sleep(seconds)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def stop
|
37
|
+
Thread.kill(@thread)
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require "vector2d"
|
2
|
+
|
3
|
+
class Coordinates < Vector2d
|
4
|
+
def self.zero
|
5
|
+
Coordinates.new(0, 0)
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.up
|
9
|
+
Coordinates.new(0, -1)
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.down
|
13
|
+
Coordinates.new(0, 1)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.left
|
17
|
+
Coordinates.new(-1, 0)
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.right
|
21
|
+
Coordinates.new(1, 0)
|
22
|
+
end
|
23
|
+
|
24
|
+
def x=(value)
|
25
|
+
@x = value
|
26
|
+
end
|
27
|
+
|
28
|
+
def y=(value)
|
29
|
+
@y = value
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Draggable
|
2
|
+
def drag
|
3
|
+
puts "XXX: dragging 1 #{name}"
|
4
|
+
mouse_position = Global.mouse_position
|
5
|
+
|
6
|
+
puts "@draggable_on_debug: #{@draggable_on_debug}"
|
7
|
+
puts "@dragging: #{@dragging}"
|
8
|
+
puts "Gosu.button_down?(Gosu::MS_LEFT): #{Gosu.button_down?(Gosu::MS_LEFT)}"
|
9
|
+
puts "collision: #{Utils.collision_at?(self, mouse_position.x, mouse_position.y)}"
|
10
|
+
|
11
|
+
if @draggable_on_debug && !@dragging && Gosu.button_down?(Gosu::MS_LEFT) && Utils.collision_at?(self, mouse_position.x, mouse_position.y)
|
12
|
+
puts "XXX: dragging start #{name}"
|
13
|
+
@dragging = true
|
14
|
+
@dragging_offset = mouse_position - @position
|
15
|
+
end
|
16
|
+
|
17
|
+
if @dragging && !Gosu.button_down?(Gosu::MS_LEFT)
|
18
|
+
puts "XXX: dragging end #{name}"
|
19
|
+
@dragging = false
|
20
|
+
end
|
21
|
+
|
22
|
+
if @dragging
|
23
|
+
puts "XXX: dragging 3 #{name}"
|
24
|
+
@position = mouse_position - @dragging_offset
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require "ostruct"
|
2
|
+
|
3
|
+
module Global
|
4
|
+
class << self
|
5
|
+
attr_accessor :actors, :hud_texts, :hud_images, :clocks
|
6
|
+
attr_accessor :debug
|
7
|
+
attr_accessor :setup_proc, :loop_proc, :button_proc
|
8
|
+
attr_accessor :presentation_proc, :game_proc, :end_proc
|
9
|
+
|
10
|
+
attr_accessor :space_bar_proc
|
11
|
+
attr_accessor :cursor_up_proc, :cursor_down_proc, :cursor_left_proc, :cursor_right_proc
|
12
|
+
attr_accessor :mouse_button_left_proc, :mouse_button_right_proc
|
13
|
+
|
14
|
+
attr_accessor :background
|
15
|
+
|
16
|
+
attr_accessor :game
|
17
|
+
attr_reader :frame_time # delta_time
|
18
|
+
attr_reader :pixel_font
|
19
|
+
attr_reader :references
|
20
|
+
attr_reader :camera
|
21
|
+
attr_reader :game_state
|
22
|
+
|
23
|
+
def initialize
|
24
|
+
puts "Global.initialize"
|
25
|
+
@actors = []
|
26
|
+
@hud_texts = []
|
27
|
+
@hud_images = []
|
28
|
+
@clocks = []
|
29
|
+
@last_frame_at = Time.now
|
30
|
+
@debug = false
|
31
|
+
@pixel_font = Gosu::Font.new(20, { name: "#{__dir__}/../fonts/VT323-Regular.ttf" } )
|
32
|
+
@d_key_pressed = false
|
33
|
+
@references = OpenStruct.new
|
34
|
+
@camera = Camera.new(position: Coordinates.zero)
|
35
|
+
@game_state = Global.presentation_proc.nil? ? "game" : "presentation"
|
36
|
+
|
37
|
+
@presentation_proc = Global.default_on_presentation if @presentation_proc.nil?
|
38
|
+
@game_proc = Global.default_on_game if @game_proc.nil?
|
39
|
+
@end_proc = Global.default_on_end if @end_proc.nil?
|
40
|
+
@paused = false
|
41
|
+
end
|
42
|
+
|
43
|
+
def update
|
44
|
+
@frame_time = Time.now - @last_frame_at
|
45
|
+
@last_frame_at = Time.now
|
46
|
+
|
47
|
+
if Gosu.button_down?(Gosu::KB_D) && !@d_key_pressed
|
48
|
+
@debug = !@debug
|
49
|
+
@d_key_pressed = true
|
50
|
+
end
|
51
|
+
|
52
|
+
if !Gosu.button_down?(Gosu::KB_D) && @d_key_pressed
|
53
|
+
@d_key_pressed = false
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def add_reference(name:, object:)
|
58
|
+
@references[name] = object
|
59
|
+
end
|
60
|
+
|
61
|
+
def default_on_presentation
|
62
|
+
Global.go_to_game
|
63
|
+
end
|
64
|
+
|
65
|
+
def default_on_game
|
66
|
+
raise "You have to define a 'on_game' block"
|
67
|
+
end
|
68
|
+
|
69
|
+
def default_on_end
|
70
|
+
Global.go_to_presentation
|
71
|
+
end
|
72
|
+
|
73
|
+
def go_to_presentation
|
74
|
+
puts "Game stage 'presentation'"
|
75
|
+
|
76
|
+
clear_state_elements
|
77
|
+
presentation_proc.call
|
78
|
+
end
|
79
|
+
|
80
|
+
def go_to_game
|
81
|
+
puts "Game stage 'game'"
|
82
|
+
|
83
|
+
clear_state_elements
|
84
|
+
game_proc.call
|
85
|
+
end
|
86
|
+
|
87
|
+
def go_to_end
|
88
|
+
puts "Game stage 'end'"
|
89
|
+
|
90
|
+
clear_state_elements
|
91
|
+
end_proc.call
|
92
|
+
end
|
93
|
+
|
94
|
+
def clear_state_elements
|
95
|
+
@actors.clear
|
96
|
+
@hud_texts.clear
|
97
|
+
@hud_images.clear
|
98
|
+
@clocks.each(&:stop)
|
99
|
+
@background = Color.new(r: 0, g: 0, b: 0)
|
100
|
+
end
|
101
|
+
|
102
|
+
def mouse_position
|
103
|
+
Coordinates.new(Global.game.mouse_x, Global.game.mouse_y)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
class HudImage
|
2
|
+
include Draggable
|
3
|
+
|
4
|
+
attr_accessor :name, :scale, :color, :visible, :position, :layer
|
5
|
+
|
6
|
+
def initialize(position:, image_name: )
|
7
|
+
@image = Gosu::Image.new("#{__dir__}/../images/#{image_name}.png", { retro: true })
|
8
|
+
@name = image_name
|
9
|
+
@position = position
|
10
|
+
@scale = 1
|
11
|
+
@visible = true
|
12
|
+
@draggable_on_debug = true
|
13
|
+
@dragging = false
|
14
|
+
@layer = 100
|
15
|
+
|
16
|
+
Global.hud_images.push(self)
|
17
|
+
end
|
18
|
+
|
19
|
+
def width
|
20
|
+
@image.width() * @scale
|
21
|
+
end
|
22
|
+
|
23
|
+
def height
|
24
|
+
@image.height() * @scale
|
25
|
+
end
|
26
|
+
|
27
|
+
def move
|
28
|
+
drag if Global.debug
|
29
|
+
end
|
30
|
+
|
31
|
+
def draw
|
32
|
+
if visible
|
33
|
+
@image.draw(@position.x, @position.y, 0, @scale, @scale)
|
34
|
+
end
|
35
|
+
|
36
|
+
draw_debug if Global.debug
|
37
|
+
end
|
38
|
+
|
39
|
+
def draw_debug
|
40
|
+
Global.pixel_font.draw_text("#{@position.x.floor},#{@position.y.floor}", @position.x, @position.y - 20, 1)
|
41
|
+
end
|
42
|
+
|
43
|
+
def destroy
|
44
|
+
Global.hud_images.delete(self)
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
class HudText
|
2
|
+
attr_accessor :text, :size, :color, :visible, :layer, :in_world
|
3
|
+
|
4
|
+
def initialize(position:, text: "")
|
5
|
+
@position = position
|
6
|
+
@text = text
|
7
|
+
@size = "medium"
|
8
|
+
@color = Gosu::Color::WHITE
|
9
|
+
@visible = true
|
10
|
+
@layer = 100
|
11
|
+
@in_world = false
|
12
|
+
|
13
|
+
Global.hud_texts.push(self)
|
14
|
+
end
|
15
|
+
|
16
|
+
def move; end
|
17
|
+
|
18
|
+
def draw
|
19
|
+
if visible
|
20
|
+
Global.pixel_font.draw_markup(text, screen_position.x + scale, screen_position.y - 20 + scale, 1, scale, scale, Gosu::Color::BLACK)
|
21
|
+
Global.pixel_font.draw_markup(text, screen_position.x, screen_position.y - 20, 1, scale, scale, color)
|
22
|
+
end
|
23
|
+
|
24
|
+
draw_debug if Global.debug
|
25
|
+
end
|
26
|
+
|
27
|
+
def scale
|
28
|
+
case @size
|
29
|
+
when "small"
|
30
|
+
1
|
31
|
+
when "medium"
|
32
|
+
2
|
33
|
+
when "big"
|
34
|
+
3
|
35
|
+
when "huge"
|
36
|
+
4
|
37
|
+
else
|
38
|
+
raise "HudText.size not valid '#{@size}'. Valid sizes: 'small, medium, big, huge'"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def screen_position
|
43
|
+
if @in_world
|
44
|
+
@position - Global.camera.position
|
45
|
+
else
|
46
|
+
@position
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def destroy
|
51
|
+
Global.hud_texts.delete(self)
|
52
|
+
end
|
53
|
+
|
54
|
+
def draw_debug
|
55
|
+
Global.pixel_font.draw_text("#{@position.x.floor},#{@position.y.floor}", @position.x, @position.y, 1)
|
56
|
+
end
|
57
|
+
end
|
data/lib/fantasy/loop.rb
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
class Game < Gosu::Window
|
2
|
+
def initialize
|
3
|
+
# TODO: require SCREEN_WIDTH and SCREEN_HEIGHT
|
4
|
+
super(SCREEN_WIDTH, SCREEN_HEIGHT)
|
5
|
+
Global.initialize
|
6
|
+
|
7
|
+
Global.presentation_proc.call()
|
8
|
+
end
|
9
|
+
|
10
|
+
def button_down(button_id)
|
11
|
+
case button_id
|
12
|
+
when Gosu::KB_DOWN then Global.cursor_down_proc.call unless Global.cursor_down_proc.nil?
|
13
|
+
when Gosu::KB_UP then Global.cursor_up_proc.call unless Global.cursor_up_proc.nil?
|
14
|
+
when Gosu::KB_LEFT then Global.cursor_left_proc.call unless Global.cursor_left_proc.nil?
|
15
|
+
when Gosu::KB_RIGHT then Global.cursor_right_proc.call unless Global.cursor_right_proc.nil?
|
16
|
+
when Gosu::MS_LEFT then Global.mouse_button_left_proc.call unless Global.mouse_button_left_proc.nil?
|
17
|
+
when Gosu::MS_RIGHT then Global.mouse_button_right_proc.call unless Global.mouse_button_right_proc.nil?
|
18
|
+
when Gosu::KB_SPACE then Global.space_bar_proc.call unless Global.space_bar_proc.nil?
|
19
|
+
end
|
20
|
+
|
21
|
+
Global.button_proc.call(button_id) unless Global.button_proc.nil?
|
22
|
+
|
23
|
+
super
|
24
|
+
end
|
25
|
+
|
26
|
+
def update
|
27
|
+
Global.update
|
28
|
+
|
29
|
+
Global.actors.each do |e|
|
30
|
+
e.move
|
31
|
+
end
|
32
|
+
|
33
|
+
Global.hud_texts.each do |e|
|
34
|
+
e.move
|
35
|
+
end
|
36
|
+
|
37
|
+
Global.hud_images.each do |e|
|
38
|
+
e.move
|
39
|
+
end
|
40
|
+
|
41
|
+
Global.loop_proc.call() unless Global.loop_proc.nil?
|
42
|
+
end
|
43
|
+
|
44
|
+
def draw
|
45
|
+
Gosu.draw_rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, Global.background)
|
46
|
+
|
47
|
+
(
|
48
|
+
Global.actors +
|
49
|
+
Global.hud_texts +
|
50
|
+
Global.hud_images
|
51
|
+
).sort_by(&:layer).each do |e|
|
52
|
+
e.draw
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Sound
|
2
|
+
class << self
|
3
|
+
@@sounds = {}
|
4
|
+
|
5
|
+
def play(sound_name)
|
6
|
+
locate_sound(sound_name).play
|
7
|
+
end
|
8
|
+
|
9
|
+
def locate_sound(sound_name)
|
10
|
+
return @@sounds[sound_name] if @@sounds[sound_name]
|
11
|
+
|
12
|
+
puts "Initialize Sound: '#{sound_name}'"
|
13
|
+
|
14
|
+
base_path = "#{__dir__}/../sounds"
|
15
|
+
file_name = Dir.entries(base_path).find { |e| e.start_with?(sound_name) }
|
16
|
+
@@sounds[sound_name] = Gosu::Sample.new("#{base_path}/#{file_name}")
|
17
|
+
|
18
|
+
return @@sounds[sound_name]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Utils
|
2
|
+
# https://developer.mozilla.org/en-US/docs/Games/Techniques/2D_collision_detection
|
3
|
+
def self.collision?(actor_1, actor_2)
|
4
|
+
(
|
5
|
+
actor_1.position.x < (actor_2.position.x + actor_2.width) &&
|
6
|
+
(actor_1.position.x + actor_1.width) > actor_2.position.x &&
|
7
|
+
actor_1.position.y < (actor_2.position.y + actor_2.height) &&
|
8
|
+
actor_1.position.y + actor_1.height > actor_2.position.y
|
9
|
+
)
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.collision_at?(actor, x, y)
|
13
|
+
(
|
14
|
+
actor.position.x < x &&
|
15
|
+
(actor.position.x + actor.width) > x &&
|
16
|
+
actor.position.y < y &&
|
17
|
+
actor.position.y + actor.height > y
|
18
|
+
)
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.draw_frame(x, y, width, height, stroke, color)
|
22
|
+
Gosu.draw_rect(x, y, width, stroke, color)
|
23
|
+
Gosu.draw_rect(x + (width - stroke), y, stroke, height, color)
|
24
|
+
Gosu.draw_rect(x, y + (height - stroke), width, stroke, color)
|
25
|
+
Gosu.draw_rect(x, y, stroke, height, color)
|
26
|
+
end
|
27
|
+
end
|
data/lib/fantasy.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "gosu"
|
3
|
+
|
4
|
+
require_relative "fantasy/version"
|
5
|
+
require_relative "fantasy/draggable"
|
6
|
+
require_relative "fantasy/color"
|
7
|
+
require_relative "fantasy/actor"
|
8
|
+
require_relative "fantasy/coordinates"
|
9
|
+
require_relative "fantasy/utils"
|
10
|
+
require_relative "fantasy/global"
|
11
|
+
require_relative "fantasy/clock"
|
12
|
+
require_relative "fantasy/loop"
|
13
|
+
require_relative "fantasy/hud_text"
|
14
|
+
require_relative "fantasy/hud_image"
|
15
|
+
require_relative "fantasy/sound"
|
16
|
+
require_relative "fantasy/camera"
|
17
|
+
require_relative "fantasy/base"
|
metadata
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fantasy
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Fernando Guillen
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2022-03-11 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: gosu
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.4.1
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.4.1
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: vector2d
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 2.2.3
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 2.2.3
|
41
|
+
description: Simple toolbox library and lean API to build great mini games
|
42
|
+
email:
|
43
|
+
- fguillen.mail@gmail.com
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- ".rubocop.yml"
|
49
|
+
- CHANGELOG.md
|
50
|
+
- Gemfile
|
51
|
+
- LICENSE.txt
|
52
|
+
- README.md
|
53
|
+
- Rakefile
|
54
|
+
- bin/console
|
55
|
+
- bin/setup
|
56
|
+
- fantasy.gemspec
|
57
|
+
- fonts/OFL.txt
|
58
|
+
- fonts/VT323-Regular.ttf
|
59
|
+
- lib/fantasy.rb
|
60
|
+
- lib/fantasy/actor.rb
|
61
|
+
- lib/fantasy/base.rb
|
62
|
+
- lib/fantasy/camera.rb
|
63
|
+
- lib/fantasy/clock.rb
|
64
|
+
- lib/fantasy/color.rb
|
65
|
+
- lib/fantasy/coordinates.rb
|
66
|
+
- lib/fantasy/draggable.rb
|
67
|
+
- lib/fantasy/global.rb
|
68
|
+
- lib/fantasy/hud_image.rb
|
69
|
+
- lib/fantasy/hud_text.rb
|
70
|
+
- lib/fantasy/loop.rb
|
71
|
+
- lib/fantasy/sound.rb
|
72
|
+
- lib/fantasy/utils.rb
|
73
|
+
- lib/fantasy/version.rb
|
74
|
+
homepage: https://github.com/fguillen/fantasy
|
75
|
+
licenses:
|
76
|
+
- MIT
|
77
|
+
metadata:
|
78
|
+
allowed_push_host: https://rubygems.org
|
79
|
+
homepage_uri: https://github.com/fguillen/fantasy
|
80
|
+
source_code_uri: https://github.com/fguillen/fantasy
|
81
|
+
changelog_uri: https://github.com/fguillen/fantasy/blob/main/CHANGELOG.md
|
82
|
+
post_install_message:
|
83
|
+
rdoc_options: []
|
84
|
+
require_paths:
|
85
|
+
- lib
|
86
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: 3.0.0
|
91
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
requirements: []
|
97
|
+
rubygems_version: 3.2.22
|
98
|
+
signing_key:
|
99
|
+
specification_version: 4
|
100
|
+
summary: Simple toolbox library and lean API to build great mini games
|
101
|
+
test_files: []
|