chingu 0.8rc1 → 0.8rc2
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +3 -3
- data/chingu.gemspec +201 -198
- data/examples/example21.yml +39 -39
- data/examples/example26_splash_screen.rb +48 -0
- data/examples/example3_parallax.rb +6 -10
- data/examples/game1.rb +4 -3
- data/examples/game_of_life.rb +11 -9
- data/examples/{example24_input_codes.rb → tool1_input_codes.rb} +1 -1
- data/lib/chingu.rb +1 -1
- data/lib/chingu/assets.rb +58 -0
- data/lib/chingu/basic_game_object.rb +15 -3
- data/lib/chingu/classic_game_object.rb +267 -0
- data/lib/chingu/game_object.rb +6 -234
- data/lib/chingu/game_states/debug.rb +1 -1
- data/lib/chingu/game_states/pause.rb +1 -1
- data/lib/chingu/helpers/rotation_center.rb +1 -2
- data/lib/chingu/inflector.rb +7 -0
- data/lib/chingu/named_resource.rb +258 -254
- data/lib/chingu/parallax.rb +6 -4
- data/lib/chingu/text.rb +4 -2
- data/lib/chingu/traits/sprite.rb +22 -19
- data/lib/chingu/window.rb +17 -0
- data/spec/chingu/game_object_spec.rb +69 -1
- data/spec/chingu/parallax_spec.rb +34 -0
- metadata +25 -21
- data/.gitignore +0 -6
data/examples/example21.yml
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
- CogWheel:
|
3
3
|
:x: 1088.0
|
4
4
|
:y: 352.0
|
5
|
-
:angle:
|
5
|
+
:angle: 238.31818883902704
|
6
6
|
:zorder: 95
|
7
7
|
:factor_x: 1.68525252525252
|
8
8
|
:factor_y: 1.68525252525252
|
@@ -930,7 +930,7 @@
|
|
930
930
|
- CogWheel:
|
931
931
|
:x: 1792.0
|
932
932
|
:y: 320.0
|
933
|
-
:angle:
|
933
|
+
:angle: 205.68237008923398
|
934
934
|
:zorder: 95
|
935
935
|
:factor_x: 1.68525252525252
|
936
936
|
:factor_y: 1.68525252525252
|
@@ -946,7 +946,7 @@
|
|
946
946
|
- CogWheel:
|
947
947
|
:x: 2464.0
|
948
948
|
:y: 288.0
|
949
|
-
:angle:
|
949
|
+
:angle: 350.97150938554654
|
950
950
|
:zorder: 95
|
951
951
|
:factor_x: 1.68525252525252
|
952
952
|
:factor_y: 1.68525252525252
|
@@ -954,7 +954,7 @@
|
|
954
954
|
- CogWheel:
|
955
955
|
:x: 2460.0
|
956
956
|
:y: 960.0
|
957
|
-
:angle:
|
957
|
+
:angle: 207.68237008923398
|
958
958
|
:zorder: 95
|
959
959
|
:factor_x: 1.68525252525252
|
960
960
|
:factor_y: 1.68525252525252
|
@@ -1066,7 +1066,7 @@
|
|
1066
1066
|
- Saw:
|
1067
1067
|
:x: 2304.0
|
1068
1068
|
:y: 42980.3876971599
|
1069
|
-
:angle:
|
1069
|
+
:angle: 41.72555205053806
|
1070
1070
|
:zorder: 100
|
1071
1071
|
:factor_x: 0.317794486215539
|
1072
1072
|
:factor_y: 0.320401002506266
|
@@ -1074,7 +1074,7 @@
|
|
1074
1074
|
- Saw:
|
1075
1075
|
:x: 2016.0
|
1076
1076
|
:y: 32178.4911927486
|
1077
|
-
:angle:
|
1077
|
+
:angle: 72.34574735821182
|
1078
1078
|
:zorder: 100
|
1079
1079
|
:factor_x: 0.398395989974937
|
1080
1080
|
:factor_y: 0.401002506265664
|
@@ -1082,7 +1082,7 @@
|
|
1082
1082
|
- Saw:
|
1083
1083
|
:x: 1696.0
|
1084
1084
|
:y: 14501.1166797636
|
1085
|
-
:angle:
|
1085
|
+
:angle: 226.82001857098814
|
1086
1086
|
:zorder: 100
|
1087
1087
|
:factor_x: 0.958395989974934
|
1088
1088
|
:factor_y: 0.961002506265664
|
@@ -1090,7 +1090,7 @@
|
|
1090
1090
|
- Saw:
|
1091
1091
|
:x: 1056.0
|
1092
1092
|
:y: 24038.686890917
|
1093
|
-
:angle:
|
1093
|
+
:angle: 62.16252750703487
|
1094
1094
|
:zorder: 100
|
1095
1095
|
:factor_x: 0.637794486215539
|
1096
1096
|
:factor_y: 0.640401002506266
|
@@ -1098,7 +1098,7 @@
|
|
1098
1098
|
- Saw:
|
1099
1099
|
:x: 1344.0
|
1100
1100
|
:y: 24038.686890917
|
1101
|
-
:angle:
|
1101
|
+
:angle: 65.16252750703583
|
1102
1102
|
:zorder: 100
|
1103
1103
|
:factor_x: 0.637794486215539
|
1104
1104
|
:factor_y: 0.640401002506266
|
@@ -1354,7 +1354,7 @@
|
|
1354
1354
|
- Saw:
|
1355
1355
|
:x: 2176.0
|
1356
1356
|
:y: 42820.3876971599
|
1357
|
-
:angle:
|
1357
|
+
:angle: 44.725552050538056
|
1358
1358
|
:zorder: 100
|
1359
1359
|
:factor_x: 0.317794486215539
|
1360
1360
|
:factor_y: 0.320401002506266
|
@@ -1362,7 +1362,7 @@
|
|
1362
1362
|
- Saw:
|
1363
1363
|
:x: 1280.0
|
1364
1364
|
:y: 30827.366022672
|
1365
|
-
:angle:
|
1365
|
+
:angle: 300.0776055490816
|
1366
1366
|
:zorder: 100
|
1367
1367
|
:factor_x: 0.47739348370927
|
1368
1368
|
:factor_y: 0.48
|
@@ -1370,7 +1370,7 @@
|
|
1370
1370
|
- Saw:
|
1371
1371
|
:x: 1055.0
|
1372
1372
|
:y: 91497.8070513121
|
1373
|
-
:angle:
|
1373
|
+
:angle: 344.02733176191106
|
1374
1374
|
:zorder: 100
|
1375
1375
|
:factor_x: 0.156390977443606
|
1376
1376
|
:factor_y: 0.158997493734336
|
@@ -1378,7 +1378,7 @@
|
|
1378
1378
|
- Saw:
|
1379
1379
|
:x: 960.0
|
1380
1380
|
:y: 91561.8070513122
|
1381
|
-
:angle:
|
1381
|
+
:angle: 347.02733176190907
|
1382
1382
|
:zorder: 100
|
1383
1383
|
:factor_x: 0.156390977443606
|
1384
1384
|
:factor_y: 0.158997493734336
|
@@ -1386,7 +1386,7 @@
|
|
1386
1386
|
- Saw:
|
1387
1387
|
:x: 1120.0
|
1388
1388
|
:y: 91561.8070513122
|
1389
|
-
:angle:
|
1389
|
+
:angle: 347.02733176190907
|
1390
1390
|
:zorder: 100
|
1391
1391
|
:factor_x: 0.156390977443606
|
1392
1392
|
:factor_y: 0.158997493734336
|
@@ -1394,7 +1394,7 @@
|
|
1394
1394
|
- Saw:
|
1395
1395
|
:x: 864.0
|
1396
1396
|
:y: 91497.8070513121
|
1397
|
-
:angle:
|
1397
|
+
:angle: 350.02733176190907
|
1398
1398
|
:zorder: 100
|
1399
1399
|
:factor_x: 0.156390977443606
|
1400
1400
|
:factor_y: 0.158997493734336
|
@@ -1402,7 +1402,7 @@
|
|
1402
1402
|
- Saw:
|
1403
1403
|
:x: 1247.0
|
1404
1404
|
:y: 27759.2193277261
|
1405
|
-
:angle:
|
1405
|
+
:angle: 320.6743989618843
|
1406
1406
|
:zorder: 100
|
1407
1407
|
:factor_x: 0.477192982456137
|
1408
1408
|
:factor_y: 0.479799498746867
|
@@ -1410,7 +1410,7 @@
|
|
1410
1410
|
- Saw:
|
1411
1411
|
:x: 1088.0
|
1412
1412
|
:y: 54684.0355932234
|
1413
|
-
:angle:
|
1413
|
+
:angle: 146.99443884993184
|
1414
1414
|
:zorder: 100
|
1415
1415
|
:factor_x: 0.236591478696738
|
1416
1416
|
:factor_y: 0.239197994987469
|
@@ -1418,7 +1418,7 @@
|
|
1418
1418
|
- Saw:
|
1419
1419
|
:x: 960.0
|
1420
1420
|
:y: 54684.0355932234
|
1421
|
-
:angle:
|
1421
|
+
:angle: 149.99443884993195
|
1422
1422
|
:zorder: 100
|
1423
1423
|
:factor_x: 0.236591478696738
|
1424
1424
|
:factor_y: 0.239197994987469
|
@@ -1537,24 +1537,24 @@
|
|
1537
1537
|
:alpha: 255
|
1538
1538
|
- Saw:
|
1539
1539
|
:x: 2272.0
|
1540
|
-
:y:
|
1541
|
-
:angle:
|
1540
|
+
:y: 1362.6472068444905
|
1541
|
+
:angle: 237.91947659816137
|
1542
1542
|
:zorder: 100
|
1543
1543
|
:factor_x: 0.398395989974937
|
1544
1544
|
:factor_y: 0.401002506265664
|
1545
1545
|
:alpha: 255
|
1546
1546
|
- Saw:
|
1547
1547
|
:x: 1792.0
|
1548
|
-
:y:
|
1549
|
-
:angle:
|
1548
|
+
:y: 1415.2943760984278
|
1549
|
+
:angle: 203.02724077304177
|
1550
1550
|
:zorder: 100
|
1551
1551
|
:factor_x: 0.79859649122807
|
1552
1552
|
:factor_y: 0.801203007518797
|
1553
1553
|
:alpha: 255
|
1554
1554
|
- Saw:
|
1555
1555
|
:x: 2112.0
|
1556
|
-
:y:
|
1557
|
-
:angle:
|
1556
|
+
:y: 1330.7449409780638
|
1557
|
+
:angle: 199.5458246302823
|
1558
1558
|
:zorder: 100
|
1559
1559
|
:factor_x: 0.237794486215539
|
1560
1560
|
:factor_y: 0.240401002506266
|
@@ -1562,63 +1562,63 @@
|
|
1562
1562
|
- Saw:
|
1563
1563
|
:x: 1504.0
|
1564
1564
|
:y: 1551.27092138629
|
1565
|
-
:angle:
|
1565
|
+
:angle: 210.11538461603345
|
1566
1566
|
:zorder: 100
|
1567
1567
|
:factor_x: 0.23719298245614
|
1568
1568
|
:factor_y: 0.239799498746867
|
1569
1569
|
:alpha: 255
|
1570
1570
|
- Saw:
|
1571
1571
|
:x: 1344.0
|
1572
|
-
:y:
|
1573
|
-
:angle:
|
1572
|
+
:y: 1420.697802197812
|
1573
|
+
:angle: 213.11538461603647
|
1574
1574
|
:zorder: 100
|
1575
1575
|
:factor_x: 0.23719298245614
|
1576
1576
|
:factor_y: 0.239799498746867
|
1577
1577
|
:alpha: 255
|
1578
1578
|
- Saw:
|
1579
1579
|
:x: 1152.0
|
1580
|
-
:y:
|
1581
|
-
:angle:
|
1580
|
+
:y: 1400.550295858002
|
1581
|
+
:angle: 216.11538461603348
|
1582
1582
|
:zorder: 100
|
1583
1583
|
:factor_x: 0.23719298245614
|
1584
1584
|
:factor_y: 0.239799498746867
|
1585
1585
|
:alpha: 255
|
1586
1586
|
- Saw:
|
1587
1587
|
:x: 992.0
|
1588
|
-
:y:
|
1589
|
-
:angle:
|
1588
|
+
:y: 1373.3390804597661
|
1589
|
+
:angle: 223.96232061665756
|
1590
1590
|
:zorder: 100
|
1591
1591
|
:factor_x: 0.156992481203007
|
1592
1592
|
:factor_y: 0.159598997493734
|
1593
1593
|
:alpha: 255
|
1594
1594
|
- Saw:
|
1595
1595
|
:x: 800.0
|
1596
|
-
:y:
|
1597
|
-
:angle:
|
1596
|
+
:y: 1373.3390804597661
|
1597
|
+
:angle: 226.96232061665756
|
1598
1598
|
:zorder: 100
|
1599
1599
|
:factor_x: 0.156992481203007
|
1600
1600
|
:factor_y: 0.159598997493734
|
1601
1601
|
:alpha: 255
|
1602
1602
|
- Saw:
|
1603
1603
|
:x: 1248.0
|
1604
|
-
:y:
|
1605
|
-
:angle:
|
1604
|
+
:y: 1452.2977917981073
|
1605
|
+
:angle: 77.7519563145171
|
1606
1606
|
:zorder: 100
|
1607
1607
|
:factor_x: 0.317794486215539
|
1608
1608
|
:factor_y: 0.320401002506266
|
1609
1609
|
:alpha: 255
|
1610
1610
|
- Saw:
|
1611
1611
|
:x: 928.0
|
1612
|
-
:y:
|
1613
|
-
:angle:
|
1612
|
+
:y: 1341.641762452114
|
1613
|
+
:angle: 229.9623206166576
|
1614
1614
|
:zorder: 100
|
1615
1615
|
:factor_x: 0.156992481203007
|
1616
1616
|
:factor_y: 0.159598997493734
|
1617
1617
|
:alpha: 255
|
1618
1618
|
- Saw:
|
1619
1619
|
:x: 672.0
|
1620
|
-
:y:
|
1621
|
-
:angle:
|
1620
|
+
:y: 1318.3473818646446
|
1621
|
+
:angle: 226.96232061665756
|
1622
1622
|
:zorder: 100
|
1623
1623
|
:factor_x: 0.156992481203007
|
1624
1624
|
:factor_y: 0.159598997493734
|
@@ -0,0 +1,48 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'rubygems' rescue nil
|
3
|
+
$LOAD_PATH.unshift File.join(File.expand_path(__FILE__), "..", "..", "lib")
|
4
|
+
require 'chingu'
|
5
|
+
include Gosu
|
6
|
+
|
7
|
+
#
|
8
|
+
# Creates a window, then lets the user change to another one. Use this to change resolution or change to/from
|
9
|
+
# full-screen mode
|
10
|
+
#
|
11
|
+
class SplashScreen < Chingu::Window
|
12
|
+
def initialize
|
13
|
+
super(400,200,false)
|
14
|
+
self.input = { :escape => :close, :return => :load } # exits example on Escape
|
15
|
+
|
16
|
+
Chingu::GameObject.create(:x => 200, :y => 100, :image => Image["spaceship.png"])
|
17
|
+
Chingu::Text.create("Press <return> to load game", :y => 100)
|
18
|
+
end
|
19
|
+
|
20
|
+
def update
|
21
|
+
super
|
22
|
+
self.caption = "FPS: #{self.fps} milliseconds_since_last_tick: #{self.milliseconds_since_last_tick}"
|
23
|
+
end
|
24
|
+
|
25
|
+
def load
|
26
|
+
# MUST close current window before we open the new one!
|
27
|
+
close
|
28
|
+
MainGame.new.show
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class MainGame < Chingu::Window
|
33
|
+
def initialize
|
34
|
+
super(640,480,false)
|
35
|
+
self.input = { :escape => :close } # exits example on Escape
|
36
|
+
|
37
|
+
Chingu::GameObject.create(:x => 200, :y => 200, :image => Image["spaceship.png"])
|
38
|
+
Chingu::Text.create("Main game loaded", :y => 100)
|
39
|
+
end
|
40
|
+
|
41
|
+
def update
|
42
|
+
super
|
43
|
+
self.caption = "FPS: #{self.fps} milliseconds_since_last_tick: #{self.milliseconds_since_last_tick}"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
SplashScreen.new.show
|
@@ -18,21 +18,18 @@ end
|
|
18
18
|
|
19
19
|
class Scroller < Chingu::GameState
|
20
20
|
|
21
|
-
def initialize(options)
|
22
|
-
super
|
21
|
+
def initialize(options = {})
|
22
|
+
super(options)
|
23
23
|
@text_color = Color.new(0xFF000000)
|
24
|
-
end
|
25
|
-
|
26
|
-
def setup
|
27
24
|
self.input = { :holding_left => :camera_left,
|
28
25
|
:holding_right => :camera_right,
|
29
26
|
:holding_up => :camera_up,
|
30
27
|
:holding_down => :camera_down,
|
31
28
|
:space => :next_game_state,
|
32
29
|
:escape => :exit
|
33
|
-
}
|
30
|
+
}
|
34
31
|
end
|
35
|
-
|
32
|
+
|
36
33
|
def next_game_state
|
37
34
|
if current_game_state.class == Wood
|
38
35
|
switch_game_state(Jungle)
|
@@ -63,9 +60,8 @@ class Scroller < Chingu::GameState
|
|
63
60
|
end
|
64
61
|
|
65
62
|
class Wood < Scroller
|
66
|
-
def
|
67
|
-
|
68
|
-
@parallax = Chingu::Parallax.create(:x => 0, :y => 0, :rotation_center => :top_left)
|
63
|
+
def setup
|
64
|
+
@parallax = Chingu::Parallax.create(:x => 150, :y => 150, :rotation_center => :top_left)
|
69
65
|
@parallax << { :image => "wood.png", :repeat_x => true, :repeat_y => true}
|
70
66
|
Chingu::Text.create("82x64 image with repeat_x and repeat_y set to TRUE", :x => 0, :y => 0, :size => 30, :color => @text_color)
|
71
67
|
end
|
data/examples/game1.rb
CHANGED
@@ -31,9 +31,9 @@ class Level < Chingu::GameState
|
|
31
31
|
def initialize(options = {})
|
32
32
|
super
|
33
33
|
|
34
|
-
@parallax = Parallax.create(:rotation_center => :top_left)
|
35
|
-
@parallax << { :image => "city2.png", :damping => 2}
|
36
|
-
@parallax << { :image => "city1.png", :damping => 1}
|
34
|
+
@parallax = Parallax.create(:rotation_center => :top_left, :zorder => 200)
|
35
|
+
@parallax << { :image => "city2.png", :damping => 2, :zorder => 200}
|
36
|
+
@parallax << { :image => "city1.png", :damping => 1, :zorder => 200}
|
37
37
|
@player = Player.create(:x => 30, :y => 10)
|
38
38
|
|
39
39
|
@bg1 = Color.new(0xFFCE28FF)
|
@@ -109,6 +109,7 @@ class Level < Chingu::GameState
|
|
109
109
|
|
110
110
|
def draw
|
111
111
|
fill_gradient(:from => @bg2, :to => @bg1)
|
112
|
+
@parallax.draw
|
112
113
|
super
|
113
114
|
end
|
114
115
|
end
|
data/examples/game_of_life.rb
CHANGED
@@ -16,8 +16,8 @@ class Main < Chingu::Window
|
|
16
16
|
push_game_state(GameOfLife)
|
17
17
|
end
|
18
18
|
def draw
|
19
|
-
super
|
20
19
|
fill_rect([0,0,640,480], 0xffffffff, -2)
|
20
|
+
super
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
@@ -85,14 +85,7 @@ class GameOfLife < Chingu::GameState
|
|
85
85
|
|
86
86
|
def update
|
87
87
|
super
|
88
|
-
|
89
|
-
if @painting
|
90
|
-
draw_pattern_at_mouse(@pattern, true)
|
91
|
-
@painting = false if @running # Only put out pattern Once if game is running
|
92
|
-
else
|
93
|
-
draw_pattern_at_mouse(@pattern)
|
94
|
-
end
|
95
|
-
|
88
|
+
|
96
89
|
update_grid if @running
|
97
90
|
|
98
91
|
$window.caption = "Conway Generation #{@@tick}. Start/Stop with 'Space'. Run 1 generation with 'N'. Reset with 'Z'."
|
@@ -100,7 +93,16 @@ class GameOfLife < Chingu::GameState
|
|
100
93
|
|
101
94
|
def draw
|
102
95
|
super
|
96
|
+
|
103
97
|
draw_grid
|
98
|
+
|
99
|
+
if @painting
|
100
|
+
draw_pattern_at_mouse(@pattern, true)
|
101
|
+
@painting = false if @running # Only put out pattern Once if game is running
|
102
|
+
else
|
103
|
+
draw_pattern_at_mouse(@pattern)
|
104
|
+
end
|
105
|
+
|
104
106
|
end
|
105
107
|
|
106
108
|
private
|
@@ -18,7 +18,7 @@ class Game < Chingu::Window
|
|
18
18
|
@gosu_inputs = input_names.inject({}) {|hash, name| hash[Gosu.const_get name] = name; hash }
|
19
19
|
|
20
20
|
# Get all possible key codes.
|
21
|
-
@key_codes = (Gosu::KbRangeBegin..Gosu::KbRangeEnd).to_a
|
21
|
+
@key_codes = (Gosu::KbRangeBegin..Gosu::KbRangeEnd).to_a + (Gosu::GpRangeBegin..Gosu::GpRangeEnd).to_a + (Gosu::MsRangeBegin..Gosu::MsRangeEnd).to_a
|
22
22
|
end
|
23
23
|
|
24
24
|
def update
|
data/lib/chingu.rb
CHANGED
data/lib/chingu/assets.rb
CHANGED
@@ -39,6 +39,64 @@ module Gosu
|
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
|
+
class Font
|
43
|
+
# Font is a special case, since it has both a name and a size.
|
44
|
+
include Chingu::NamedResource
|
45
|
+
|
46
|
+
# Load a font with the given name and size.
|
47
|
+
# @param [String] name Name of the font (or path to TTF font)
|
48
|
+
# @param [Number] size Size of the font.
|
49
|
+
def self.autoload(name, size)
|
50
|
+
font_name = if path = find_file(name)
|
51
|
+
path # Use the full path, found in the autoload dirs.
|
52
|
+
else
|
53
|
+
name # Font not found in the path. Assume it is an OS font.
|
54
|
+
end
|
55
|
+
|
56
|
+
return Gosu::Font.new($window, font_name, size)
|
57
|
+
end
|
58
|
+
|
59
|
+
# @overload self.[](name, size)
|
60
|
+
# Get a font with the given name and size.
|
61
|
+
# @param [String] name Name of the font (or path to TTF font)
|
62
|
+
# @param [Number] size Size of the font.
|
63
|
+
#
|
64
|
+
# @overload self.[](size)
|
65
|
+
# Get a font of a given size using the Gosu.default_font_name.
|
66
|
+
# @param [Number] size Size of the font.
|
67
|
+
def self.[]( *args )
|
68
|
+
case args.size
|
69
|
+
when 1
|
70
|
+
name = Gosu.default_font_name
|
71
|
+
size = args[0]
|
72
|
+
when 2
|
73
|
+
name, size = args
|
74
|
+
else
|
75
|
+
raise ArgumentError, "wrong number of arguments (#{args.size} for 1 or 2)"
|
76
|
+
end
|
77
|
+
|
78
|
+
result = @resources[[name, size]]
|
79
|
+
|
80
|
+
if result.nil?
|
81
|
+
result = autoload(name, size)
|
82
|
+
if result
|
83
|
+
self[name, size] = result
|
84
|
+
result.name = name
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
return result
|
89
|
+
end
|
90
|
+
|
91
|
+
# Save a font with the given name and size.
|
92
|
+
# @param [String] name Name of the font (or path to TTF font)
|
93
|
+
# @param [Number] size Size of the font.
|
94
|
+
# @param [Gosu::Font] font Font object to save.
|
95
|
+
def self.[]=( name, size, font )
|
96
|
+
@resources[[name, size]] = font
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
42
100
|
class Song
|
43
101
|
include Chingu::NamedResource
|
44
102
|
|