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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1a2cd4153fd1fe67cf858245a3337a12f28e3bf0383a14c4ca5a98021eb446e6
4
- data.tar.gz: 0b1975cf3fb9baf67802f204faaef6a91e71a2d080064eb922d22cee2ffc78ec
3
+ metadata.gz: 9730a469c206b387fd96012ddb7a885a4a3d19e991aeb3c5cc2cf0afca81560a
4
+ data.tar.gz: 356d4cb07b20f5378d4c161c9212a20dc5eaf42e84b22e49f79cebf2d1a7520b
5
5
  SHA512:
6
- metadata.gz: f655cf37edfa05b1ab4b6256a19486b31c3a406ae68c8447f02683b1b946fc13a34266c88017f6c5c332b4603187b2346e58e5988ffde8f41f8009aef4064446
7
- data.tar.gz: cecba3e7696c57a11662dce317652bae03b6be7c0addd4d71ac0a2c11a1875de083709305eba38df6a22e3343f4a09fa4a44fa40841e3c0679e4668a2e823364
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,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "conjuration", path: "../.."
@@ -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,3 @@
1
+ # Tic Tac Toe - Conjuration Example
2
+
3
+ This is a simple example of a Tic Tac Toe game built with Conjuration.
@@ -0,0 +1,5 @@
1
+ require "conjuration"
2
+
3
+ require "./src/game"
4
+
5
+ Game.new.show
@@ -0,0 +1,10 @@
1
+ require_relative "./scenes/main_scene"
2
+
3
+ class Game < Conjuration::Game
4
+ def initialize
5
+ super(title: "Tic Tac Toe")
6
+
7
+ scene_manager.add_scene(:main, MainScene)
8
+ scene_manager.set_scene(:main)
9
+ end
10
+ end
@@ -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 Attributes
26
- def self.included(base)
27
- base.extend(ClassMethods)
28
- end
25
+ module Conjuration
26
+ module Attributes
27
+ def self.included(base)
28
+ base.extend(ClassMethods)
29
+ end
29
30
 
30
- def initialize(...)
31
- super()
31
+ def initialize(...)
32
+ super()
32
33
 
33
- @attributes = {}
34
- end
34
+ @attributes = {}
35
+ end
35
36
 
36
- def inspect
37
- "<#{self.class} #{@attributes.map { |attribute_name, value| "#{attribute_name}: #{value.inspect}" }.join(", ")}>"
38
- end
37
+ def inspect
38
+ "<#{self.class} #{@attributes.map { |attribute_name, value| "#{attribute_name}: #{value.inspect}" }.join(", ")}>"
39
+ end
39
40
 
40
- module ClassMethods
41
- def attribute(attribute_name)
42
- define_method(attribute_name) do
43
- @attributes[attribute_name]
44
- end
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
- define_method("#{attribute_name}=") do |value|
47
- @attributes[attribute_name] = value
47
+ define_method("#{attribute_name}=") do |value|
48
+ @attributes[attribute_name] = value
49
+ end
48
50
  end
49
- end
50
51
 
51
- def boolean_attribute(attribute_name)
52
- attribute(attribute_name)
52
+ def boolean_attribute(attribute_name)
53
+ attribute(attribute_name)
53
54
 
54
- define_method("#{attribute_name}?") do
55
- !!@attributes[attribute_name]
55
+ define_method("#{attribute_name}?") do
56
+ !!@attributes[attribute_name]
57
+ end
56
58
  end
57
59
  end
58
60
  end
@@ -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(context, key)
81
- on_mouse_down(context, key)
80
+ def mouse_down(scene, key)
81
+ on_mouse_down(scene, key)
82
82
 
83
- return unless !clicking[key] && context.input_manager.button_down?(key) && in_bounds?(context)
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(context, key)
89
- on_mouse_up(context, key)
88
+ def mouse_up(scene, key)
89
+ on_mouse_up(scene, key)
90
90
 
91
- on_click(context, key) if clicking[key] && !context.input_manager.button_down?(key) && in_bounds?(context)
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].any? { |key_id| Gosu.button_down?(key_id) }
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(_scene_class, options = {})
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
@@ -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(context, key) }
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(context, key) }
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Conjuration
4
- VERSION = "0.1.2"
4
+ VERSION = "0.2.0"
5
5
  end
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.1.2
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: