rubysketch-solitaire 0.1.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.
Files changed (55) hide show
  1. checksums.yaml +7 -0
  2. data/.bundle/config +2 -0
  3. data/.github/workflows/release-gem.yml +62 -0
  4. data/.github/workflows/test.yml +23 -0
  5. data/.github/workflows/utils.rb +56 -0
  6. data/.gitignore +11 -0
  7. data/Gemfile +5 -0
  8. data/Gemfile.lock +284 -0
  9. data/LICENSE +21 -0
  10. data/Podfile +31 -0
  11. data/Podfile.lock +59 -0
  12. data/README.md +21 -0
  13. data/Rakefile +100 -0
  14. data/RubySolitaire/Assets.xcassets/AccentColor.colorset/Contents.json +11 -0
  15. data/RubySolitaire/Assets.xcassets/AppIcon.appiconset/Contents.json +98 -0
  16. data/RubySolitaire/Assets.xcassets/Contents.json +6 -0
  17. data/RubySolitaire/BridgingHeader.h +10 -0
  18. data/RubySolitaire/GameView.swift +47 -0
  19. data/RubySolitaire/Preview Content/Preview Assets.xcassets/Contents.json +6 -0
  20. data/RubySolitaire/RubySolitaireApp.swift +10 -0
  21. data/RubySolitaireTests/RubySolitaireTests.swift +28 -0
  22. data/RubySolitaireUITests/RubySolitaireUITests.swift +35 -0
  23. data/RubySolitaireUITests/RubySolitaireUITestsLaunchTests.swift +25 -0
  24. data/VERSION +1 -0
  25. data/data/button.mp3 +0 -0
  26. data/data/card.png +0 -0
  27. data/data/deal1.mp3 +0 -0
  28. data/data/deal2.mp3 +0 -0
  29. data/data/deal3.mp3 +0 -0
  30. data/data/flip.mp3 +0 -0
  31. data/data/noop.mp3 +0 -0
  32. data/lib/rubysketch/solitaire/background.rb +34 -0
  33. data/lib/rubysketch/solitaire/card.rb +256 -0
  34. data/lib/rubysketch/solitaire/common/animation.rb +116 -0
  35. data/lib/rubysketch/solitaire/common/button.rb +67 -0
  36. data/lib/rubysketch/solitaire/common/dialog.rb +103 -0
  37. data/lib/rubysketch/solitaire/common/history.rb +94 -0
  38. data/lib/rubysketch/solitaire/common/particle.rb +71 -0
  39. data/lib/rubysketch/solitaire/common/scene.rb +128 -0
  40. data/lib/rubysketch/solitaire/common/score.rb +37 -0
  41. data/lib/rubysketch/solitaire/common/settings.rb +31 -0
  42. data/lib/rubysketch/solitaire/common/shake.rb +48 -0
  43. data/lib/rubysketch/solitaire/common/sound.rb +6 -0
  44. data/lib/rubysketch/solitaire/common/timer.rb +35 -0
  45. data/lib/rubysketch/solitaire/common/transitions.rb +149 -0
  46. data/lib/rubysketch/solitaire/common/utils.rb +89 -0
  47. data/lib/rubysketch/solitaire/extension.rb +25 -0
  48. data/lib/rubysketch/solitaire/klondike.rb +676 -0
  49. data/lib/rubysketch/solitaire/places.rb +177 -0
  50. data/lib/rubysketch/solitaire/start.rb +19 -0
  51. data/lib/rubysketch/solitaire.rb +80 -0
  52. data/main.rb +1 -0
  53. data/project.yml +91 -0
  54. data/solitaire.gemspec +28 -0
  55. metadata +137 -0
@@ -0,0 +1,35 @@
1
+ $timers = {}
2
+
3
+ def startTimer(name = unique, seconds, &block)
4
+ $timers[name] = [now + seconds, block]
5
+ name
6
+ end
7
+
8
+ def startInterval(name = unique, seconds, now: false, &block)
9
+ block.call if now
10
+ startTimer name, seconds do
11
+ block.call
12
+ startInterval name, seconds, &block
13
+ end
14
+ end
15
+
16
+ def stopTimer(name)
17
+ $timers.delete name
18
+ end
19
+
20
+ def getTimer(name)
21
+ $timers[name]
22
+ end
23
+
24
+ def delay(&block)
25
+ startTimer 0, &block
26
+ end
27
+
28
+ def fireTimers()
29
+ now_ = now
30
+ blocks = []
31
+ $timers.delete_if do |_, (time, block)|
32
+ (now_ >= time).tap { blocks.push block if _1 }
33
+ end
34
+ blocks.each { _1.call }
35
+ end
@@ -0,0 +1,149 @@
1
+ using RubySketch
2
+
3
+
4
+ class TransitionEffect < Scene
5
+
6
+ def initialize(
7
+ nextScene, sec: 1,
8
+ secOut: nil, secIn: nil,
9
+ easeOut: :expoOut, easeIn: :expoIn,
10
+ &block)
11
+
12
+ super()
13
+ @nextScene, @easeOut, @easeIn = nextScene, easeOut, easeIn
14
+ @secOut = secOut || sec / 2.0
15
+ @secIn = secIn || sec / 2.0
16
+ @phase = :out
17
+ end
18
+
19
+ attr_reader :phase
20
+
21
+ def effect(t)
22
+ end
23
+
24
+ def activated()
25
+ super
26
+ start do
27
+ case @phase
28
+ when :out
29
+ pa = parent
30
+ pa.remove self
31
+ @phase = :in
32
+ @nextScene.add self
33
+ pa.transition @nextScene
34
+ when :in
35
+ parent.remove self
36
+ end
37
+ end
38
+ end
39
+
40
+ private
41
+
42
+ def start(&block)
43
+ sec = out? ? @secOut : @secIn
44
+ ease = out? ? @easeOut : @easeIn
45
+ animate sec, ease: ease do |t, finished|
46
+ effect (out? ? t : 1.0 - t)
47
+ block.call if finished
48
+ end
49
+ end
50
+
51
+ def out?()
52
+ @phase == :out
53
+ end
54
+
55
+ end# TransitionEffect
56
+
57
+
58
+ class Fade < TransitionEffect
59
+
60
+ def initialize(*args, rgb: 0, **kwargs, &block)
61
+ super(*args, easeIn: :expoOut, **kwargs)
62
+ @rgb, @alpha = rgb, 0
63
+ end
64
+
65
+ def effect(t)
66
+ @alpha = 255 * t
67
+ end
68
+
69
+ def draw()
70
+ super
71
+ fill *@rgb, @alpha
72
+ noStroke
73
+ rect 0, 0, width, height
74
+ end
75
+
76
+ end# Fade
77
+
78
+
79
+ class Curtain < TransitionEffect
80
+
81
+ def initialize(*args, rgb: 0, **kwargs, &block)
82
+ super(*args, easeIn: :expoOut, **kwargs)
83
+ @rgb = rgb
84
+ @y = @h = 0
85
+ end
86
+
87
+ def effect(t)
88
+ @y, @h =
89
+ case phase
90
+ when :out then [height * (1.0 - t), height]
91
+ when :in then [0, height * t]
92
+ end
93
+ end
94
+
95
+ def draw()
96
+ super
97
+ fill *@rgb
98
+ noStroke
99
+ rect 0, @y, width, @h
100
+ end
101
+
102
+ end# Fade
103
+
104
+
105
+ class Pixelate < TransitionEffect
106
+
107
+ def initialize(*args, **kwargs, &block)
108
+ super *args, sec: 1, easeOut: :cubicOut, easeIn: :cubicIn, **kwargs, &block
109
+ end
110
+
111
+ def activated()
112
+ super
113
+ filter pixelate
114
+ end
115
+
116
+ def deactivated()
117
+ super
118
+ filter nil
119
+ end
120
+
121
+ def effect(t)
122
+ pixelate.set :resolution, width, height
123
+ pixelate.set :pixelateSize, map(t, 0.0, 1.0, 1, 32)
124
+ end
125
+
126
+ private
127
+
128
+ def pixelate()
129
+ @checker ||= createShader nil, <<~END
130
+ uniform sampler2D texMap;
131
+ uniform vec3 texMax;
132
+ uniform vec2 resolution;
133
+ uniform float pixelateSize;
134
+ varying vec4 vertTexCoord;
135
+ varying vec4 vertColor;
136
+ void main() {
137
+ vec2 r = resolution;
138
+ float ps = pixelateSize;
139
+ vec2 coord = (floor(vertTexCoord.xy * r / ps) + 0.5) * ps / r;
140
+ if (coord.x >= texMax.x) coord.x = texMax.x - 1. / r.x;
141
+ if (coord.y >= texMax.y) coord.y = texMax.y - 1. / r.y;
142
+
143
+ vec4 col = texture2D(texMap, coord);
144
+ gl_FragColor = vec4(col.rgb, 1.) * vertColor;
145
+ }
146
+ END
147
+ end
148
+
149
+ end# Pixelate
@@ -0,0 +1,89 @@
1
+ def now()
2
+ Time.now.to_f
3
+ end
4
+
5
+ def unique()
6
+ Object.new.object_id
7
+ end
8
+
9
+ def dataPath(path)
10
+ File.expand_path "../../../../data/#{path}", __dir__
11
+ end
12
+
13
+
14
+ module Processing
15
+ class Vector
16
+ def xy()
17
+ self.class.new x, y
18
+ end
19
+ end
20
+ end
21
+
22
+
23
+ module CanDisable
24
+
25
+ def initialize(*a, **k, &b)
26
+ super
27
+ @enabled = true
28
+ end
29
+
30
+ def enable(state = true)
31
+ return if state == @enabled
32
+ @enabled = state
33
+ @enabled ? enabled : disabled
34
+ end
35
+
36
+ def disable(&block)
37
+ old = enabled?
38
+ enable false
39
+ if block
40
+ begin
41
+ block.call
42
+ ensure
43
+ enable old
44
+ end
45
+ end
46
+ end
47
+
48
+ def enabled?()
49
+ @enabled
50
+ end
51
+
52
+ def disabled?()
53
+ !enabled?
54
+ end
55
+
56
+ def enabled()
57
+ end
58
+
59
+ def disabled()
60
+ end
61
+
62
+ end# CanDisable
63
+
64
+
65
+ module HasSprite
66
+
67
+ extend Forwardable
68
+
69
+ def_delegators :sprite,
70
+ :pos, :pos=, :x, :x=, :y, :y=, :z, :z=, :center, :center=,
71
+ :left, :left=, :top, :top=, :right, :right=, :bottom, :bottom=,
72
+ :size, :width, :width=, :height, :height=, :depth, :w, :w=, :h, :h=, :d,
73
+ :angle, :angle=
74
+
75
+ alias l left
76
+ alias l= left=
77
+ alias t top
78
+ alias t= top=
79
+ alias r right
80
+ alias r= right=
81
+ alias b bottom
82
+ alias b= bottom=
83
+
84
+ def hit?(x, y)
85
+ s = sprite
86
+ s.x <= x && x < (s.x + s.w) && s.y <= y && y < (s.y + s.h)
87
+ end
88
+
89
+ end# HasSprite
@@ -0,0 +1,25 @@
1
+ module RubySketch
2
+
3
+ module Solitaire
4
+
5
+ module Extension
6
+
7
+ module_function
8
+
9
+ def name()
10
+ super.split('::')[-2]
11
+ end
12
+
13
+ def version()
14
+ File.read(root_dir 'VERSION')[/[\d\.]+/]
15
+ end
16
+
17
+ def root_dir(path = '')
18
+ File.expand_path "../../../#{path}", __dir__
19
+ end
20
+
21
+ end# Extension
22
+
23
+ end# Solitaire
24
+
25
+ end# RubySketch