conjuration 0.1.2 → 0.2.0
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.
- checksums.yaml +4 -4
- data/README.md +4 -0
- data/examples/tictactoe/Gemfile +3 -0
- data/examples/tictactoe/Gemfile.lock +22 -0
- data/examples/tictactoe/README.md +3 -0
- data/examples/tictactoe/main.rb +5 -0
- data/examples/tictactoe/src/game.rb +10 -0
- data/examples/tictactoe/src/game_objects/slot.rb +43 -0
- data/examples/tictactoe/src/scenes/main_scene.rb +52 -0
- data/examples/tictactoe/src/scenes/winner_scene.rb +11 -0
- data/lib/conjuration/concerns/attributes.rb +25 -23
- data/lib/conjuration/game.rb +29 -0
- data/lib/conjuration/game_object.rb +6 -6
- data/lib/conjuration/managers/input_manager.rb +1 -1
- data/lib/conjuration/managers/scene_manager.rb +2 -2
- data/lib/conjuration/scene.rb +3 -3
- data/lib/conjuration/ui/button.rb +38 -0
- data/lib/conjuration/ui/text.rb +16 -0
- data/lib/conjuration/version.rb +1 -1
- data/lib/conjuration.rb +3 -0
- metadata +11 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9730a469c206b387fd96012ddb7a885a4a3d19e991aeb3c5cc2cf0afca81560a
|
4
|
+
data.tar.gz: 356d4cb07b20f5378d4c161c9212a20dc5eaf42e84b22e49f79cebf2d1a7520b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9f2ec5ffb69518a3b2461cbdb4a7c5158f058daa292c5416ebf1857482aad1ccdd65f196177fa3c0694974ccd2f4a0beef8a8d5f495ec330787eb5d74983c619
|
7
|
+
data.tar.gz: a0f10f06c9f2c1a8812efad61a6c214e48866554ad6255d6a38af4ff7d87324f6d9f134c600a4bac3903c6bae3917931c05dd88288dd804b4ba72245507047ed
|
data/README.md
CHANGED
@@ -73,6 +73,10 @@ You should setup your project with the following file structure:
|
|
73
73
|
|
74
74
|
This is where you store your game assets. This can include images, sounds, and other resources.
|
75
75
|
|
76
|
+
## Examples
|
77
|
+
|
78
|
+
- [Tic Tac Toe](/examples/tic_tac_toe)
|
79
|
+
|
76
80
|
## Contributing
|
77
81
|
|
78
82
|
Bug reports and pull requests are welcome on GitHub at https://github.com/Nitemaeric/conjuration.
|
@@ -0,0 +1,22 @@
|
|
1
|
+
PATH
|
2
|
+
remote: ../..
|
3
|
+
specs:
|
4
|
+
conjuration (0.1.3)
|
5
|
+
gosu (~> 1.4.6)
|
6
|
+
zeitwerk (~> 2.6.14)
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: https://rubygems.org/
|
10
|
+
specs:
|
11
|
+
gosu (1.4.6)
|
12
|
+
zeitwerk (2.6.14)
|
13
|
+
|
14
|
+
PLATFORMS
|
15
|
+
arm64-darwin-23
|
16
|
+
ruby
|
17
|
+
|
18
|
+
DEPENDENCIES
|
19
|
+
conjuration!
|
20
|
+
|
21
|
+
BUNDLED WITH
|
22
|
+
2.5.10
|
@@ -0,0 +1,43 @@
|
|
1
|
+
class Slot < Conjuration::GameObject
|
2
|
+
attribute :mark
|
3
|
+
|
4
|
+
PLAYER_X_COLOR = Gosu::Color::RED
|
5
|
+
PLAYER_O_COLOR = Gosu::Color::GREEN
|
6
|
+
|
7
|
+
def initialize(x:, y:)
|
8
|
+
super(x:, y:, width: 200, height: 200)
|
9
|
+
end
|
10
|
+
|
11
|
+
def draw(window, scene)
|
12
|
+
window.draw_rect(x, y, width, height, Gosu::Color::BLACK)
|
13
|
+
window.draw_rect(x+2, y+2, width-4, height-4, Gosu::Color::WHITE)
|
14
|
+
|
15
|
+
if mark == "X"
|
16
|
+
window.rotate(45, x+width/2, y+height/2) do
|
17
|
+
window.draw_rect(x, y + height / 2 - 5, width, 10, PLAYER_X_COLOR)
|
18
|
+
window.draw_rect(x + width / 2 - 5, y, 10, height, PLAYER_X_COLOR)
|
19
|
+
end
|
20
|
+
elsif mark == "O"
|
21
|
+
window.draw_circle(x+width/2, y+height/2, width/2 - 30, PLAYER_O_COLOR, 0, 10)
|
22
|
+
else
|
23
|
+
if hovering?
|
24
|
+
if scene.current_player == "X"
|
25
|
+
window.rotate(45, x+width/2, y+height/2) do
|
26
|
+
window.draw_rect(x, y + height / 2 - 5, width, 10, PLAYER_X_COLOR)
|
27
|
+
window.draw_rect(x + width / 2 - 5, y, 10, height, PLAYER_X_COLOR)
|
28
|
+
end
|
29
|
+
elsif scene.current_player == "O"
|
30
|
+
window.draw_circle(x+width/2, y+height/2, width/2 - 30, PLAYER_O_COLOR, 0, 10)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def on_click(scene, key)
|
37
|
+
return if mark
|
38
|
+
|
39
|
+
self.mark = scene.current_player
|
40
|
+
|
41
|
+
scene.change_player
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require_relative "../game_objects/slot"
|
2
|
+
require_relative "./winner_scene"
|
3
|
+
|
4
|
+
class MainScene < Conjuration::Scene
|
5
|
+
attribute :current_player, default: "X"
|
6
|
+
|
7
|
+
def initialize(window, options = {})
|
8
|
+
super(window, options)
|
9
|
+
|
10
|
+
starting_x = 600
|
11
|
+
starting_y = 400
|
12
|
+
|
13
|
+
@slots = []
|
14
|
+
|
15
|
+
(0..2).each do |grid_y|
|
16
|
+
@slots << []
|
17
|
+
|
18
|
+
(0..2).each do |grid_x|
|
19
|
+
@slots[grid_y] << Slot.create(x: starting_x + grid_x * 200, y: starting_y + grid_y * 200, scene: self)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def change_player
|
25
|
+
self.current_player = current_player == "X" ? "O" : "X"
|
26
|
+
end
|
27
|
+
|
28
|
+
def check_winner
|
29
|
+
# Check horizontal wins
|
30
|
+
return @slots[0][0].mark if @slots[0][0].mark == @slots[0][1].mark && @slots[0][1].mark == @slots[0][2].mark
|
31
|
+
return @slots[1][0].mark if @slots[1][0].mark == @slots[1][1].mark && @slots[1][1].mark == @slots[1][2].mark
|
32
|
+
return @slots[2][0].mark if @slots[2][0].mark == @slots[2][1].mark && @slots[2][1].mark == @slots[2][2].mark
|
33
|
+
|
34
|
+
# Check vertical wins
|
35
|
+
return @slots[0][0].mark if @slots[0][0].mark == @slots[1][0].mark && @slots[1][0].mark == @slots[2][0].mark
|
36
|
+
return @slots[0][1].mark if @slots[0][1].mark == @slots[1][1].mark && @slots[1][1].mark == @slots[2][1].mark
|
37
|
+
return @slots[0][2].mark if @slots[0][2].mark == @slots[1][2].mark && @slots[1][2].mark == @slots[2][2].mark
|
38
|
+
|
39
|
+
# Check diagonal wins
|
40
|
+
return @slots[0][0].mark if @slots[0][0].mark == @slots[1][1].mark && @slots[1][1].mark == @slots[2][2].mark
|
41
|
+
return @slots[0][2].mark if @slots[0][2].mark == @slots[1][1].mark && @slots[1][1].mark == @slots[2][0].mark
|
42
|
+
end
|
43
|
+
|
44
|
+
def button_up(window, id)
|
45
|
+
super
|
46
|
+
|
47
|
+
if @winner = check_winner
|
48
|
+
window.scene_manager.add_scene(:winner, WinnerScene)
|
49
|
+
window.scene_manager.set_scene(:winner, winner: @winner)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class WinnerScene < Conjuration::Scene
|
2
|
+
def initialize(window, winner:)
|
3
|
+
super
|
4
|
+
|
5
|
+
Conjuration::Text.create(x: 600, y: 400, text: "#{winner} wins!", color: Gosu::Color::WHITE, scene: self)
|
6
|
+
|
7
|
+
Conjuration::Button.create(x: 600, y: 600, text: "Close", scene: self) do |scene|
|
8
|
+
scene.window.close
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -22,37 +22,39 @@
|
|
22
22
|
# person.age = 30
|
23
23
|
# person.inspect # => "<Person name: \"Alice\", age: 30>"
|
24
24
|
#
|
25
|
-
module
|
26
|
-
|
27
|
-
|
28
|
-
|
25
|
+
module Conjuration
|
26
|
+
module Attributes
|
27
|
+
def self.included(base)
|
28
|
+
base.extend(ClassMethods)
|
29
|
+
end
|
29
30
|
|
30
|
-
|
31
|
-
|
31
|
+
def initialize(...)
|
32
|
+
super()
|
32
33
|
|
33
|
-
|
34
|
-
|
34
|
+
@attributes = {}
|
35
|
+
end
|
35
36
|
|
36
|
-
|
37
|
-
|
38
|
-
|
37
|
+
def inspect
|
38
|
+
"<#{self.class} #{@attributes.map { |attribute_name, value| "#{attribute_name}: #{value.inspect}" }.join(", ")}>"
|
39
|
+
end
|
39
40
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
41
|
+
module ClassMethods
|
42
|
+
def attribute(attribute_name, default: nil)
|
43
|
+
define_method(attribute_name) do
|
44
|
+
@attributes[attribute_name] ||= default
|
45
|
+
end
|
45
46
|
|
46
|
-
|
47
|
-
|
47
|
+
define_method("#{attribute_name}=") do |value|
|
48
|
+
@attributes[attribute_name] = value
|
49
|
+
end
|
48
50
|
end
|
49
|
-
end
|
50
51
|
|
51
|
-
|
52
|
-
|
52
|
+
def boolean_attribute(attribute_name)
|
53
|
+
attribute(attribute_name)
|
53
54
|
|
54
|
-
|
55
|
-
|
55
|
+
define_method("#{attribute_name}?") do
|
56
|
+
!!@attributes[attribute_name]
|
57
|
+
end
|
56
58
|
end
|
57
59
|
end
|
58
60
|
end
|
data/lib/conjuration/game.rb
CHANGED
@@ -33,5 +33,34 @@ module Conjuration
|
|
33
33
|
def button_up(id)
|
34
34
|
@scene_manager.button_up(self, @input_manager.map_button(id))
|
35
35
|
end
|
36
|
+
|
37
|
+
def draw_circle(x, y, r, c, z = 0, thickness = 1, sides = nil, mode = :default)
|
38
|
+
# Unless specified, calculate a nice-looking "minimum" number of sides
|
39
|
+
# sides = (r + Math::sqrt(r * 0.1) * 4).floor if sides.nil?
|
40
|
+
sides = (2.0 * r * Math::PI).floor if sides.nil?
|
41
|
+
|
42
|
+
# Calculate the inner and outer offsets from the "true" circle
|
43
|
+
offs = thickness * 0.5
|
44
|
+
r_in = r - offs
|
45
|
+
r_out = r + offs
|
46
|
+
|
47
|
+
# Calculate the angular increment
|
48
|
+
ai = 360.0 / sides.to_f
|
49
|
+
|
50
|
+
translate(x, y) {
|
51
|
+
ang = 0
|
52
|
+
while ang <= 359.9 do
|
53
|
+
draw_quad(
|
54
|
+
Gosu.offset_x(ang, r_in), Gosu.offset_y(ang, r_in), c,
|
55
|
+
Gosu.offset_x(ang, r_out), Gosu.offset_y(ang, r_out), c,
|
56
|
+
Gosu.offset_x(ang + ai, r_in), Gosu.offset_y(ang + ai, r_in), c,
|
57
|
+
Gosu.offset_x(ang + ai, r_out), Gosu.offset_y(ang + ai, r_out), c,
|
58
|
+
z, mode
|
59
|
+
)
|
60
|
+
ang += ai
|
61
|
+
end
|
62
|
+
}
|
63
|
+
|
64
|
+
end
|
36
65
|
end
|
37
66
|
end
|
@@ -77,18 +77,18 @@ module Conjuration
|
|
77
77
|
# Clicking
|
78
78
|
# ==========
|
79
79
|
|
80
|
-
def mouse_down(
|
81
|
-
on_mouse_down(
|
80
|
+
def mouse_down(scene, key)
|
81
|
+
on_mouse_down(scene, key)
|
82
82
|
|
83
|
-
return unless !clicking[key] &&
|
83
|
+
return unless !clicking[key] && scene.window.input_manager.button_down?(key) && in_bounds?(scene.window)
|
84
84
|
|
85
85
|
clicking[key] = true
|
86
86
|
end
|
87
87
|
|
88
|
-
def mouse_up(
|
89
|
-
on_mouse_up(
|
88
|
+
def mouse_up(scene, key)
|
89
|
+
on_mouse_up(scene, key)
|
90
90
|
|
91
|
-
on_click(
|
91
|
+
on_click(scene, key) if clicking[key] && !scene.window.input_manager.button_down?(key) && in_bounds?(scene.window)
|
92
92
|
|
93
93
|
clicking[key] = false
|
94
94
|
end
|
@@ -15,7 +15,7 @@ module Conjuration
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def button_down?(action)
|
18
|
-
action_map[action]
|
18
|
+
action_map[action]&.any? { |key_id| Gosu.button_down?(key_id) } || false
|
19
19
|
end
|
20
20
|
|
21
21
|
# Returns a hash of actions mapped to key bindings.
|
@@ -11,8 +11,8 @@ module Conjuration
|
|
11
11
|
@scenes[key] = scene_class
|
12
12
|
end
|
13
13
|
|
14
|
-
def set_scene(
|
15
|
-
@current_scene = @scenes[key].new(@window, options)
|
14
|
+
def set_scene(key, **options)
|
15
|
+
@current_scene = @scenes[key].new(@window, **options)
|
16
16
|
end
|
17
17
|
|
18
18
|
attr_reader :current_scene
|
data/lib/conjuration/scene.rb
CHANGED
@@ -34,15 +34,15 @@ module Conjuration
|
|
34
34
|
def draw(context)
|
35
35
|
@background_image&.draw(0, 0, 0, context.width.to_f / @background_image.width,
|
36
36
|
context.height.to_f / @background_image.height)
|
37
|
-
@game_objects.each { |game_object| game_object.draw(context) }
|
37
|
+
@game_objects.each { |game_object| game_object.draw(context, self) }
|
38
38
|
end
|
39
39
|
|
40
40
|
def button_down(context, key)
|
41
|
-
@game_objects.each { |game_object| game_object.mouse_down(
|
41
|
+
@game_objects.each { |game_object| game_object.mouse_down(self, key) }
|
42
42
|
end
|
43
43
|
|
44
44
|
def button_up(context, key)
|
45
|
-
@game_objects.each { |game_object| game_object.mouse_up(
|
45
|
+
@game_objects.each { |game_object| game_object.mouse_up(self, key) }
|
46
46
|
end
|
47
47
|
end
|
48
48
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Conjuration
|
2
|
+
class Button < Conjuration::GameObject
|
3
|
+
def initialize(
|
4
|
+
x:,
|
5
|
+
y:,
|
6
|
+
width: 200,
|
7
|
+
height: 40,
|
8
|
+
text:,
|
9
|
+
font_size: 20,
|
10
|
+
color: Gosu::Color::BLACK,
|
11
|
+
background_color: Gosu::Color::WHITE,
|
12
|
+
hover: {
|
13
|
+
color: Gosu::Color::BLACK,
|
14
|
+
background_color: Gosu::Color::GRAY,
|
15
|
+
},
|
16
|
+
&action
|
17
|
+
)
|
18
|
+
super(x:, y:, width:, height:)
|
19
|
+
|
20
|
+
@text = text
|
21
|
+
@font = Gosu::Font.new(font_size)
|
22
|
+
@color = color
|
23
|
+
@background_color = background_color
|
24
|
+
@hover = hover
|
25
|
+
@action = action
|
26
|
+
end
|
27
|
+
|
28
|
+
def draw(window, scene)
|
29
|
+
window.draw_rect(x, y, width, height, hovering? ? @hover[:background_color] : @background_color)
|
30
|
+
|
31
|
+
@font.draw_text(@text, x + width/2 - @font.text_width(@text)/2, y + height/2 - @font.height/2, 1, 1, 1, hovering? ? @hover[:color] : @color)
|
32
|
+
end
|
33
|
+
|
34
|
+
def on_click(scene, key)
|
35
|
+
@action.call(scene) if key == InputManager::LEFT_CLICK
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Conjuration
|
2
|
+
class Text < Conjuration::GameObject
|
3
|
+
def initialize(x:, y:, text:, font_size: 20, color: Gosu::Color::BLACK)
|
4
|
+
@font = Gosu::Font.new(font_size)
|
5
|
+
|
6
|
+
super(x:, y:, width: @font.text_width(text), height: @font.height)
|
7
|
+
|
8
|
+
@text = text
|
9
|
+
@color = color
|
10
|
+
end
|
11
|
+
|
12
|
+
def draw(window, scene)
|
13
|
+
@font.draw_text(@text, x, y, 1, 1, 1, @color)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/conjuration/version.rb
CHANGED
data/lib/conjuration.rb
CHANGED
@@ -4,6 +4,9 @@ require "gosu"
|
|
4
4
|
require "zeitwerk"
|
5
5
|
|
6
6
|
loader = Zeitwerk::Loader.for_gem
|
7
|
+
loader.collapse("#{__dir__}/conjuration/concerns")
|
8
|
+
loader.collapse("#{__dir__}/conjuration/managers")
|
9
|
+
loader.collapse("#{__dir__}/conjuration/ui")
|
7
10
|
loader.setup
|
8
11
|
|
9
12
|
module Conjuration
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: conjuration
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Dye
|
@@ -52,6 +52,14 @@ files:
|
|
52
52
|
- LICENSE.txt
|
53
53
|
- README.md
|
54
54
|
- Rakefile
|
55
|
+
- examples/tictactoe/Gemfile
|
56
|
+
- examples/tictactoe/Gemfile.lock
|
57
|
+
- examples/tictactoe/README.md
|
58
|
+
- examples/tictactoe/main.rb
|
59
|
+
- examples/tictactoe/src/game.rb
|
60
|
+
- examples/tictactoe/src/game_objects/slot.rb
|
61
|
+
- examples/tictactoe/src/scenes/main_scene.rb
|
62
|
+
- examples/tictactoe/src/scenes/winner_scene.rb
|
55
63
|
- lib/conjuration.rb
|
56
64
|
- lib/conjuration/concerns/attributes.rb
|
57
65
|
- lib/conjuration/game.rb
|
@@ -61,6 +69,8 @@ files:
|
|
61
69
|
- lib/conjuration/managers/input_manager.rb
|
62
70
|
- lib/conjuration/managers/scene_manager.rb
|
63
71
|
- lib/conjuration/scene.rb
|
72
|
+
- lib/conjuration/ui/button.rb
|
73
|
+
- lib/conjuration/ui/text.rb
|
64
74
|
- lib/conjuration/version.rb
|
65
75
|
homepage: https://github.com/nitemaeric/conjuration
|
66
76
|
licenses:
|