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.
- checksums.yaml +7 -0
- data/.bundle/config +2 -0
- data/.github/workflows/release-gem.yml +62 -0
- data/.github/workflows/test.yml +23 -0
- data/.github/workflows/utils.rb +56 -0
- data/.gitignore +11 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +284 -0
- data/LICENSE +21 -0
- data/Podfile +31 -0
- data/Podfile.lock +59 -0
- data/README.md +21 -0
- data/Rakefile +100 -0
- data/RubySolitaire/Assets.xcassets/AccentColor.colorset/Contents.json +11 -0
- data/RubySolitaire/Assets.xcassets/AppIcon.appiconset/Contents.json +98 -0
- data/RubySolitaire/Assets.xcassets/Contents.json +6 -0
- data/RubySolitaire/BridgingHeader.h +10 -0
- data/RubySolitaire/GameView.swift +47 -0
- data/RubySolitaire/Preview Content/Preview Assets.xcassets/Contents.json +6 -0
- data/RubySolitaire/RubySolitaireApp.swift +10 -0
- data/RubySolitaireTests/RubySolitaireTests.swift +28 -0
- data/RubySolitaireUITests/RubySolitaireUITests.swift +35 -0
- data/RubySolitaireUITests/RubySolitaireUITestsLaunchTests.swift +25 -0
- data/VERSION +1 -0
- data/data/button.mp3 +0 -0
- data/data/card.png +0 -0
- data/data/deal1.mp3 +0 -0
- data/data/deal2.mp3 +0 -0
- data/data/deal3.mp3 +0 -0
- data/data/flip.mp3 +0 -0
- data/data/noop.mp3 +0 -0
- data/lib/rubysketch/solitaire/background.rb +34 -0
- data/lib/rubysketch/solitaire/card.rb +256 -0
- data/lib/rubysketch/solitaire/common/animation.rb +116 -0
- data/lib/rubysketch/solitaire/common/button.rb +67 -0
- data/lib/rubysketch/solitaire/common/dialog.rb +103 -0
- data/lib/rubysketch/solitaire/common/history.rb +94 -0
- data/lib/rubysketch/solitaire/common/particle.rb +71 -0
- data/lib/rubysketch/solitaire/common/scene.rb +128 -0
- data/lib/rubysketch/solitaire/common/score.rb +37 -0
- data/lib/rubysketch/solitaire/common/settings.rb +31 -0
- data/lib/rubysketch/solitaire/common/shake.rb +48 -0
- data/lib/rubysketch/solitaire/common/sound.rb +6 -0
- data/lib/rubysketch/solitaire/common/timer.rb +35 -0
- data/lib/rubysketch/solitaire/common/transitions.rb +149 -0
- data/lib/rubysketch/solitaire/common/utils.rb +89 -0
- data/lib/rubysketch/solitaire/extension.rb +25 -0
- data/lib/rubysketch/solitaire/klondike.rb +676 -0
- data/lib/rubysketch/solitaire/places.rb +177 -0
- data/lib/rubysketch/solitaire/start.rb +19 -0
- data/lib/rubysketch/solitaire.rb +80 -0
- data/main.rb +1 -0
- data/project.yml +91 -0
- data/solitaire.gemspec +28 -0
- 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
|