conjuration 0.1.2 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|