Battlecity 0.0.1 → 0.0.2

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.
@@ -0,0 +1,45 @@
1
+ require 'singleton'
2
+ require_relative 'game_state'
3
+ require_relative 'play_state'
4
+
5
+ # class MenuState
6
+ class MenuState < GameState
7
+ include Singleton
8
+ attr_accessor :multiplayer
9
+
10
+ def initialize
11
+ @message = Gosu::Image.from_text($window, "Battle\ncity", $window.mediamanager.font, 45)
12
+ @choice = Sprite.new(:player1_1right, true)
13
+ @multiplayer = false
14
+ end
15
+
16
+ def enter
17
+ # play some music
18
+ end
19
+
20
+ def leave
21
+ # play some music
22
+ end
23
+
24
+ def update(_keymap)
25
+ @pl1 = Gosu::Image.from_text($window, '1 Player', $window.mediamanager.font, 16)
26
+ @pl2 = Gosu::Image.from_text($window, '2 Players', $window.mediamanager.font, 16)
27
+ @choice.update
28
+ end
29
+
30
+ def draw
31
+ @message.draw($window.width / 2 - @message.width / 2, $window.height / 2 - @message.height / 2 - 50, 10)
32
+ @pl1.draw($window.width / 2 - @pl1.width / 2, $window.height / 2 - @pl1.height / 2 + 30, 10)
33
+ @pl2.draw($window.width / 2 - @pl1.width / 2, $window.height / 2 - @pl2.height / 2 + 50, 10)
34
+ @choice.draw($window.width / 2 - @pl1.width / 2 - 30, $window.height / 2 - @pl1.height / 2 + 30, 10) unless @multiplayer
35
+ @choice.draw($window.width / 2 - @pl1.width / 2 - 30, $window.height / 2 - @pl2.height / 2 + 50, 10) if @multiplayer
36
+ end
37
+
38
+ def button_down(id)
39
+ $window.close if id == Gosu::KbEscape
40
+ if id == Gosu::KbLeftShift || id == Gosu::KbRightShift
41
+ @multiplayer ^= true # prevraceni hodnoty bool
42
+ end
43
+ GameState.switch(PlayState.new(@multiplayer)) if id == Gosu::KbReturn || id == Gosu::KbEnter
44
+ end
45
+ end
@@ -0,0 +1,31 @@
1
+ require_relative '../misc/map'
2
+
3
+ # class PlayState
4
+ class PlayState < GameState
5
+ def initialize(two_players = false)
6
+ @game_over = Gosu::Image.from_text($window, "Game\nover", $window.mediamanager.font, 40)
7
+ @map = Map.new(two_players, 1)
8
+ @upgrade_prob = 0.0001
9
+ end
10
+
11
+ def button_down(id)
12
+ GameState.switch(MenuState.instance) if id == Gosu::KbEscape
13
+ end
14
+
15
+ def update(keymap)
16
+ return if @map.game_over?
17
+ if rand < @upgrade_prob
18
+ @map.upgrade_create
19
+ @upgrade_prob = 0.0001
20
+ else
21
+ @upgrade_prob += 0.00001 if @map.upgrades_size == 0
22
+ end
23
+ @map.update(keymap)
24
+ end
25
+
26
+ def draw
27
+ @game_over.draw($window.width / 2 - @game_over.width / 2, $window.height / 2 - @game_over.height / 2 - 10,
28
+ 11, 1, 1, 0xffff0000) if @map.game_over?
29
+ @map.draw
30
+ end
31
+ end
data/lib/main.rb ADDED
@@ -0,0 +1,14 @@
1
+ require 'gosu'
2
+ require_relative 'gamestates/game_state'
3
+ require_relative 'gamestates/menu_state'
4
+ require_relative 'misc/game_window'
5
+
6
+ module Game
7
+ def self.media_path(file)
8
+ File.join(File.dirname(File.dirname(__FILE__)), 'media', file)
9
+ end
10
+ end
11
+
12
+ $window = GameWindow.new
13
+ GameState.switch(MenuState.instance)
14
+ $window.show
data/lib/misc/ai.rb ADDED
@@ -0,0 +1,37 @@
1
+ # class AI
2
+ class AI
3
+ def initialize(enemy, map)
4
+ @enemy = enemy
5
+ @map = map
6
+ @stuck_restore = 0
7
+ @x_prev = enemy.x
8
+ @y_prev = enemy.y
9
+ end
10
+
11
+ def step
12
+ # puts @stuck_restore
13
+ change_direction if rand < 0.01 || rand < @stuck_restore
14
+ move
15
+ @map.add_bullet(@enemy.shoot) if rand < 0.01
16
+ @map.add_bullet(@enemy.shoot) if @enemy.y == 13 * 16
17
+ end
18
+
19
+ def move
20
+ @enemy.move
21
+ if @x_prev == @enemy.x && @y_prev == @enemy.y
22
+ @stuck_restore += 0.01
23
+ else
24
+ @stuck_restore = 0
25
+ end
26
+ @x_prev = @enemy.x
27
+ @y_prev = @enemy.y
28
+ end
29
+
30
+ def change_direction # left right down up
31
+ directions = [:left, :down] if @enemy.x > @map.eagle.x
32
+ directions = [:right, :down] if @enemy.x < @map.eagle.x
33
+ directions = [:right, :down, :left] if @enemy.x == @map.eagle.x
34
+ directions = [:up, :right, :down, :left] if @stuck_restore > 0.1
35
+ @enemy.direction = directions[rand(directions.length)]
36
+ end
37
+ end
@@ -0,0 +1,45 @@
1
+ require 'gosu'
2
+ require_relative 'mediamanager'
3
+
4
+ # class GameWindow
5
+ class GameWindow < Gosu::Window
6
+ attr_accessor :state
7
+ attr_accessor :mediamanager
8
+ def initialize
9
+ super(256, 224, true)
10
+ self.caption = 'Battle city'
11
+ @unitsize = 8
12
+ @mediamanager = MediaManager.new(self)
13
+ end
14
+
15
+ def update
16
+ @state.update(keymap)
17
+ end
18
+
19
+ def draw
20
+ @state.draw
21
+ end
22
+
23
+ def needs_redraw?
24
+ @state.needs_redraw?
25
+ end
26
+
27
+ def button_down(id)
28
+ @state.button_down(id)
29
+ end
30
+
31
+ def keymap
32
+ keys = []
33
+ keys.push(:p1up) if Gosu::button_down?(Gosu::KbUp)
34
+ keys.push(:p1down) if Gosu::button_down?(Gosu::KbDown)
35
+ keys.push(:p1left) if Gosu::button_down?(Gosu::KbLeft)
36
+ keys.push(:p1right) if Gosu::button_down?(Gosu::KbRight)
37
+ keys.push(:p2up) if Gosu::button_down?(Gosu::KbW)
38
+ keys.push(:p2down) if Gosu::button_down?(Gosu::KbS)
39
+ keys.push(:p2left) if Gosu::button_down?(Gosu::KbA)
40
+ keys.push(:p2right) if Gosu::button_down?(Gosu::KbD)
41
+ keys.push(:p1shoot) if Gosu::button_down?(Gosu::KbRightControl)
42
+ keys.push(:p2shoot) if Gosu::button_down?(Gosu::KbLeftControl)
43
+ keys
44
+ end
45
+ end
data/lib/misc/level.rb ADDED
@@ -0,0 +1,139 @@
1
+ require_relative '../entities/stone'
2
+ require_relative '../entities/water'
3
+ require_relative '../entities/bush'
4
+ require_relative '../entities/brick'
5
+ require_relative '../entities/player'
6
+ require_relative '../entities/eagle'
7
+ require_relative '../entities/enemy'
8
+ require_relative '../entities/upgrade'
9
+
10
+ # class Level
11
+ class Level
12
+ COEF = 16
13
+ attr_reader :env_objects
14
+ def initialize(level = 1)
15
+ @env_objects = []
16
+ @enemyspawn = 0
17
+ case level
18
+ when 1
19
+ level1
20
+ end
21
+ end
22
+
23
+ def spawn1
24
+ [5 * COEF, 13 * COEF]
25
+ end
26
+
27
+ def spawn2
28
+ [9 * COEF, 13 * COEF]
29
+ end
30
+
31
+ def eagle
32
+ [7 * COEF, 13 * COEF]
33
+ end
34
+
35
+ def enemy_spawn
36
+ @enemyspawn = (@enemyspawn + 1) % 3
37
+ [[0, 7 * COEF, 15 * COEF][@enemyspawn], 0]
38
+ end
39
+
40
+ def level1
41
+ @env_objects.push(Bush.new(0 * COEF, 4 * COEF))
42
+ @env_objects.push(Bush.new(0 * COEF, 5 * COEF))
43
+ @env_objects.push(Stone.new(0 * COEF, 8 * COEF))
44
+ @env_objects.push(Brick.new(1 * COEF, 1 * COEF))
45
+ @env_objects.push(Brick.new(1 * COEF, 2 * COEF))
46
+ @env_objects.push(Bush.new(1 * COEF, 5 * COEF))
47
+ @env_objects.push(Brick.new(1 * COEF, 6 * COEF))
48
+ @env_objects.push(Brick.new(1 * COEF, 8 * COEF))
49
+ @env_objects.push(Brick.new(1 * COEF, 9 * COEF))
50
+ @env_objects.push(Brick.new(1 * COEF, 10 * COEF))
51
+ @env_objects.push(Brick.new(1 * COEF, 11 * COEF))
52
+ @env_objects.push(Brick.new(1 * COEF, 12 * COEF))
53
+ @env_objects.push(Brick.new(1 * COEF, 13 * COEF))
54
+ @env_objects.push(Brick.new(2 * COEF, 6 * COEF))
55
+ @env_objects.push(Stone.new(3 * COEF, 0 * COEF))
56
+ @env_objects.push(Stone.new(3 * COEF, 1 * COEF))
57
+ @env_objects.push(Brick.new(3 * COEF, 3 * COEF))
58
+ @env_objects.push(Brick.new(3 * COEF, 4 * COEF))
59
+ @env_objects.push(Brick.new(3 * COEF, 6 * COEF))
60
+ @env_objects.push(Stone.new(3 * COEF, 7 * COEF))
61
+ @env_objects.push(Stone.new(3 * COEF, 8 * COEF))
62
+ @env_objects.push(Brick.new(3 * COEF, 9 * COEF))
63
+ @env_objects.push(Brick.new(3 * COEF, 10 * COEF))
64
+ @env_objects.push(Brick.new(3 * COEF, 12 * COEF))
65
+ @env_objects.push(Stone.new(3 * COEF, 13 * COEF))
66
+ @env_objects.push(Water.new(4 * COEF, 6 * COEF))
67
+ @env_objects.push(Water.new(4 * COEF, 7 * COEF))
68
+ @env_objects.push(Bush.new(5 * COEF, 6 * COEF))
69
+ @env_objects.push(Bush.new(5 * COEF, 7 * COEF))
70
+ @env_objects.push(Stone.new(5 * COEF, 9 * COEF))
71
+ @env_objects.push(Brick.new(6 * COEF, 5 * COEF))
72
+ @env_objects.push(Bush.new(6 * COEF, 6 * COEF))
73
+ @env_objects.push(Brick.new(6 * COEF, 7 * COEF))
74
+ @env_objects.push(Brick.new(6 * COEF, 8 * COEF))
75
+ @env_objects.push(Brick.new(6 * COEF, 9 * COEF))
76
+ @env_objects.push(Brick.new(6 * COEF, 10 * COEF))
77
+ @env_objects.push(Brick.new(6 * COEF, 12 * COEF))
78
+ @env_objects.push(Brick.new(6 * COEF, 13 * COEF))
79
+ @env_objects.push(Brick.new(7 * COEF, 2 * COEF))
80
+ @env_objects.push(Stone.new(7 * COEF, 4 * COEF))
81
+ @env_objects.push(Bush.new(7 * COEF, 6 * COEF))
82
+ @env_objects.push(Brick.new(7 * COEF, 8 * COEF))
83
+ @env_objects.push(Brick.new(7 * COEF, 9 * COEF))
84
+ @env_objects.push(Brick.new(7 * COEF, 10 * COEF))
85
+ @env_objects.push(Brick.new(7 * COEF, 12 * COEF))
86
+ @env_objects.push(Stone.new(8 * COEF, 0 * COEF))
87
+ @env_objects.push(Brick.new(8 * COEF, 1 * COEF))
88
+ @env_objects.push(Brick.new(8 * COEF, 2 * COEF))
89
+ @env_objects.push(Stone.new(8 * COEF, 6 * COEF))
90
+ @env_objects.push(Brick.new(8 * COEF, 7 * COEF))
91
+ @env_objects.push(Brick.new(8 * COEF, 8 * COEF))
92
+ @env_objects.push(Brick.new(8 * COEF, 9 * COEF))
93
+ @env_objects.push(Brick.new(8 * COEF, 10 * COEF))
94
+ @env_objects.push(Brick.new(8 * COEF, 12 * COEF))
95
+ @env_objects.push(Brick.new(8 * COEF, 13 * COEF))
96
+ @env_objects.push(Stone.new(9 * COEF, 5 * COEF))
97
+ @env_objects.push(Brick.new(10 * COEF, 1 * COEF))
98
+ @env_objects.push(Brick.new(10 * COEF, 2 * COEF))
99
+ @env_objects.push(Stone.new(10 * COEF, 3 * COEF))
100
+ @env_objects.push(Brick.new(10 * COEF, 4 * COEF))
101
+ @env_objects.push(Brick.new(10 * COEF, 7 * COEF))
102
+ @env_objects.push(Brick.new(10 * COEF, 9 * COEF))
103
+ @env_objects.push(Brick.new(10 * COEF, 11 * COEF))
104
+ @env_objects.push(Brick.new(11 * COEF, 1 * COEF))
105
+ @env_objects.push(Brick.new(11 * COEF, 2 * COEF))
106
+ @env_objects.push(Stone.new(11 * COEF, 3 * COEF))
107
+ @env_objects.push(Brick.new(11 * COEF, 4 * COEF))
108
+ @env_objects.push(Brick.new(11 * COEF, 7 * COEF))
109
+ @env_objects.push(Water.new(11 * COEF, 8 * COEF))
110
+ @env_objects.push(Brick.new(11 * COEF, 9 * COEF))
111
+ @env_objects.push(Water.new(11 * COEF, 10 * COEF))
112
+ @env_objects.push(Brick.new(11 * COEF, 11 * COEF))
113
+ @env_objects.push(Brick.new(11 * COEF, 12 * COEF))
114
+ @env_objects.push(Brick.new(11 * COEF, 13 * COEF))
115
+ @env_objects.push(Stone.new(12 * COEF, 2 * COEF))
116
+ @env_objects.push(Bush.new(12 * COEF, 4 * COEF))
117
+ @env_objects.push(Bush.new(12 * COEF, 5 * COEF))
118
+ @env_objects.push(Bush.new(12 * COEF, 6 * COEF))
119
+ @env_objects.push(Bush.new(12 * COEF, 7 * COEF))
120
+ @env_objects.push(Stone.new(12 * COEF, 10 * COEF))
121
+ @env_objects.push(Brick.new(12 * COEF, 13 * COEF))
122
+ @env_objects.push(Brick.new(13 * COEF, 1 * COEF))
123
+ @env_objects.push(Brick.new(13 * COEF, 2 * COEF))
124
+ @env_objects.push(Brick.new(13 * COEF, 4 * COEF))
125
+ @env_objects.push(Brick.new(13 * COEF, 6 * COEF))
126
+ @env_objects.push(Brick.new(13 * COEF, 7 * COEF))
127
+ @env_objects.push(Brick.new(13 * COEF, 8 * COEF))
128
+ @env_objects.push(Brick.new(13 * COEF, 9 * COEF))
129
+ @env_objects.push(Brick.new(13 * COEF, 10 * COEF))
130
+ @env_objects.push(Brick.new(13 * COEF, 12 * COEF))
131
+ @env_objects.push(Brick.new(13 * COEF, 13 * COEF))
132
+ @env_objects.push(Stone.new(14 * COEF, 5 * COEF))
133
+ @env_objects.push(Stone.new(14 * COEF, 9 * COEF))
134
+ @env_objects.push(Stone.new(14 * COEF, 13 * COEF))
135
+ @env_objects.push(Stone.new(15 * COEF, 3 * COEF))
136
+ @env_objects.push(Stone.new(15 * COEF, 7 * COEF))
137
+ @env_objects.push(Stone.new(15 * COEF, 11 * COEF))
138
+ end
139
+ end
data/lib/misc/map.rb ADDED
@@ -0,0 +1,95 @@
1
+ require_relative 'level'
2
+
3
+ # class Map
4
+ class Map
5
+ attr_reader :eagle
6
+ def initialize(two_players = false, level = 1)
7
+ @level = Level.new(level)
8
+ @env_objects = @level.env_objects
9
+ @explosions = []
10
+ @bullets = []
11
+ @upgrades = []
12
+ @enemies = [Enemy.new(0, 0, self), Enemy.new(7 * 16, 0, self), Enemy.new(15 * 16, 0, self)]
13
+ @pl1 = Player.new(@level.spawn1[0], @level.spawn1[1], self)
14
+ @pl2 = two_players ? Player.new(@level.spawn2[0], @level.spawn2[1], self, true) : nil
15
+ @eagle = Eagle.new(@level.eagle[0], @level.eagle[1])
16
+ @timer = 0
17
+ end
18
+
19
+ def objects
20
+ obj = @env_objects
21
+ obj += [@pl1] unless @pl1.done?
22
+ obj += [@pl2] if @pl2 && !@pl2.done?
23
+ obj += [@eagle]
24
+ obj += @upgrades
25
+ obj += @explosions
26
+ obj += @bullets
27
+ obj += @enemies
28
+ obj
29
+ end
30
+
31
+ def draw
32
+ objects.map(&:draw)
33
+ end
34
+
35
+ def update(keymap)
36
+ add_object(@pl1.input(keymap), @bullets) unless @pl1.done?
37
+ add_object(@pl2.input(keymap), @bullets) if @pl2 && !@pl2.done?
38
+ @enemies.map(&:ai) if @timer == 0
39
+ objects.map(&:update)
40
+ reject_objects
41
+ objects.map { |x| add_object(x.collision_detect(objects), @explosions) }
42
+ @timer -= 1 if @timer > 0
43
+ add_enemy if @enemies.length < 3
44
+ end
45
+
46
+ def add_object(o, list)
47
+ return if list.include?(o) || o.nil?
48
+ list.push(o)
49
+ end
50
+
51
+ def add_explosion(x, y)
52
+ add_object(Explosion.new(x, y), @explosions)
53
+ end
54
+
55
+ def add_enemy
56
+ spawn = @level.enemy_spawn
57
+ add_object(Enemy.new(spawn[0],spawn[1], self, rand(5) + 1), @enemies)
58
+ end
59
+
60
+ def add_bullet(bullet)
61
+ return if bullet.nil?
62
+ add_object(bullet, @bullets)
63
+ end
64
+
65
+ def reject_objects
66
+ @explosions.reject!(&:done?)
67
+ @bullets.reject!(&:done?)
68
+ @env_objects.reject!(&:done?)
69
+ @enemies.reject!(&:done?)
70
+ @upgrades.reject!(&:done?)
71
+ end
72
+
73
+ def game_over?
74
+ over = @eagle.dead?
75
+ over |= @pl1.done? if @pl2.nil?
76
+ over |= @pl1.done? && @pl2.done? if @pl2
77
+ over
78
+ end
79
+
80
+ def upgrade_create
81
+ @upgrades.push(Upgrade.new(rand(240), rand(208), [:powerup_timer, :powerup_star, :powerup_granade][rand(3)]))
82
+ end
83
+
84
+ def upgrade_timer
85
+ @timer = 600
86
+ end
87
+
88
+ def upgrade_granade
89
+ @enemies.each { |e| e.hitted(nil) }
90
+ end
91
+
92
+ def upgrades_size
93
+ @upgrades.length
94
+ end
95
+ end
@@ -0,0 +1,105 @@
1
+ def media_path(file)
2
+ File.join(File.dirname(File.dirname(
3
+ __FILE__)), '../media', file)
4
+ end
5
+
6
+ # class MediaManager
7
+ class MediaManager
8
+ SPRITE = media_path('sprites_transparent.png')
9
+
10
+ def initialize(window)
11
+ @spritehash = {}
12
+ animations = Gosu::Image.load_tiles(window, SPRITE, 16, 16, false)
13
+ @spritehash[:player1_1up] = animations[0..1]
14
+ @spritehash[:player1_1left] = animations[2..3]
15
+ @spritehash[:player1_1down] = animations[4..5]
16
+ @spritehash[:player1_1right] = animations[6..7]
17
+ @spritehash[:enemy1up] = animations[8..9]
18
+ @spritehash[:enemy1left] = animations[10..11]
19
+ @spritehash[:enemy1down] = animations[12..13]
20
+ @spritehash[:enemy1right] = animations[14..15]
21
+ @spritehash[:brickwall] = animations[16]
22
+ @spritehash[:brickwallright] = animations[17]
23
+ @spritehash[:brickdown] = animations[18]
24
+ @spritehash[:brickleft] = animations[19]
25
+ @spritehash[:brickup] = animations[20]
26
+ # 21 22 tma
27
+ @spritehash[:player1_2up] = animations[25..26]
28
+ @spritehash[:player1_2left] = animations[27..28]
29
+ @spritehash[:player1_2down] = animations[29..30]
30
+ @spritehash[:player1_2right] = animations[31..32]
31
+ @spritehash[:enemy2up] = animations[33..34]
32
+ @spritehash[:enemy2left] = animations[35..36]
33
+ @spritehash[:enemy2down] = animations[37..38]
34
+ @spritehash[:enemy2right] = animations[39..40]
35
+ @spritehash[:stonewall] = animations[41]
36
+ @spritehash[:stonewallright] = animations[42]
37
+ @spritehash[:stonedown] = animations[43]
38
+ @spritehash[:stoneleft] = animations[44]
39
+ @spritehash[:stoneup] = animations[45]
40
+ # 46 47 tma
41
+ @spritehash[:player1_3up] = animations[50..51]
42
+ @spritehash[:player1_3left] = animations[52..53]
43
+ @spritehash[:player1_3down] = animations[54..55]
44
+ @spritehash[:player1_3right] = animations[56..57]
45
+ @spritehash[:enemy3up] = animations[58..59]
46
+ @spritehash[:enemy3left] = animations[60..61]
47
+ @spritehash[:enemy3down] = animations[62..63]
48
+ @spritehash[:enemy3right] = animations[64..65]
49
+ # @spritehash[:water] = animations[62]
50
+ @spritehash[:bush] = animations[67]
51
+ @spritehash[:movingtitle] = animations[68]
52
+ @spritehash[:eagle] = animations[69]
53
+ @spritehash[:eagledead] = animations[70]
54
+ # 67 68 tma
55
+ @spritehash[:player1_4up] = animations[75..76]
56
+ @spritehash[:player1_4left] = animations[77..78]
57
+ @spritehash[:player1_4down] = animations[79..80]
58
+ @spritehash[:player1_4right] = animations[81..82]
59
+ @spritehash[:enemy4up] = animations[83..84]
60
+ @spritehash[:enemy4left] = animations[85..86]
61
+ @spritehash[:enemy4down] = animations[87..88]
62
+ @spritehash[:enemy4right] = animations[89..90]
63
+ @spritehash[:enemy5up] = animations[133..134]
64
+ @spritehash[:enemy5left] = animations[135..136]
65
+ @spritehash[:enemy5down] = animations[137..138]
66
+ @spritehash[:enemy5right] = animations[139..140]
67
+ @spritehash[:water] = animations[91..92]
68
+ # 87 - 91 tma
69
+ @spritehash[:newtank] = animations[166..169]
70
+ @spritehash[:powerup_timer] = [animations[192]] + [animations[21]]
71
+ @spritehash[:powerup_star] = [animations[194]] + [animations[21]]
72
+ @spritehash[:powerup_granade] = [animations[195]] + [animations[21]]
73
+
74
+ @spritehash[:player2_1up] = animations[200..201]
75
+ @spritehash[:player2_1left] = animations[202..203]
76
+ @spritehash[:player2_1down] = animations[204..205]
77
+ @spritehash[:player2_1right] = animations[206..207]
78
+ @spritehash[:player2_2up] = animations[225..226]
79
+ @spritehash[:player2_2left] = animations[227..228]
80
+ @spritehash[:player2_2down] = animations[229..230]
81
+ @spritehash[:player2_2right] = animations[231..232]
82
+ @spritehash[:player2_3up] = animations[250..251]
83
+ @spritehash[:player2_3left] = animations[252..253]
84
+ @spritehash[:player2_3down] = animations[254..255]
85
+ @spritehash[:player2_3right] = animations[256..257]
86
+ @spritehash[:player2_4up] = animations[275..276]
87
+ @spritehash[:player2_4left] = animations[277..278]
88
+ @spritehash[:player2_4down] = animations[279..280]
89
+ @spritehash[:player2_4right] = animations[281..282]
90
+ @spritehash[:explosion_small] = animations[216..218]
91
+ animations = Gosu::Image.load_tiles(window, SPRITE, 8, 16, false)
92
+ @spritehash[:bullet_up] = animations[340]
93
+ @spritehash[:bullet_left] = animations[341]
94
+ @spritehash[:bullet_down] = animations[342]
95
+ @spritehash[:bullet_right] = animations[343]
96
+ end
97
+
98
+ def get_sprites(symbol)
99
+ @spritehash[symbol]
100
+ end
101
+
102
+ def font
103
+ media_path('emulogic.ttf')
104
+ end
105
+ end
@@ -0,0 +1,53 @@
1
+ require 'gosu'
2
+
3
+ def media_path(file)
4
+ File.join(File.dirname(File.dirname(
5
+ __FILE__)), 'media', file)
6
+ end
7
+
8
+ # class Sprite
9
+ class Sprite
10
+ attr_writer :done
11
+ attr_writer :repeat
12
+ attr_writer :pause
13
+
14
+ def initialize(symbol, repeat = false, frame_delay = 400, lifecycle = false)
15
+ @frame_delay = frame_delay
16
+ @animation = $window.mediamanager.get_sprites(symbol)
17
+ @animate = @animation.kind_of?(Array)
18
+ @current_frame = 0
19
+ @repeat = repeat
20
+ @lifecycle = lifecycle
21
+ @pause = false
22
+ end
23
+
24
+ def update
25
+ return unless @animate
26
+ return if @pause
27
+ @current_frame = (@current_frame + 1) % @animation.size if frame_expired?
28
+ end
29
+
30
+ def draw(x, y, layout)
31
+ return if done?
32
+ image = current_frame
33
+ image.draw(x, y, layout, 1, 1)
34
+ end
35
+
36
+ def done?
37
+ return false if !@animate || @repeat
38
+ @done ||= @current_frame == @animation.size - 1 if @lifecycle
39
+ end
40
+
41
+ private
42
+
43
+ def current_frame
44
+ return @animation unless @animate
45
+ @animation[@current_frame % @animation.size]
46
+ end
47
+
48
+ def frame_expired?
49
+ now = Gosu.milliseconds
50
+ @last_frame ||= now
51
+ @last_frame = now if (now - @last_frame) > @frame_delay
52
+ end
53
+ end
Binary file
data/media/sprites.png ADDED
Binary file
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: Battlecity
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tomáš Šabata
@@ -55,24 +55,46 @@ dependencies:
55
55
  description: Gem contains Battlecity remake
56
56
  email:
57
57
  - speedex505@gmail.com
58
- executables: []
58
+ executables:
59
+ - battlecity
59
60
  extensions: []
60
61
  extra_rdoc_files: []
61
62
  files:
62
63
  - ".gitignore"
63
- - ".idea/.name"
64
- - ".idea/Battlecity.iml"
65
- - ".idea/misc.xml"
66
- - ".idea/modules.xml"
67
- - ".idea/vcs.xml"
68
- - ".idea/workspace.xml"
69
64
  - Battlecity.gemspec
70
65
  - Gemfile
71
66
  - LICENSE.txt
72
67
  - README.md
73
68
  - Rakefile
69
+ - bin/battlecity
74
70
  - lib/Battlecity.rb
75
71
  - lib/Battlecity/version.rb
72
+ - lib/entities/brick.rb
73
+ - lib/entities/bullet.rb
74
+ - lib/entities/bush.rb
75
+ - lib/entities/collider.rb
76
+ - lib/entities/eagle.rb
77
+ - lib/entities/enemy.rb
78
+ - lib/entities/explosion.rb
79
+ - lib/entities/gameobject.rb
80
+ - lib/entities/player.rb
81
+ - lib/entities/stone.rb
82
+ - lib/entities/tank.rb
83
+ - lib/entities/upgrade.rb
84
+ - lib/entities/water.rb
85
+ - lib/gamestates/game_state.rb
86
+ - lib/gamestates/menu_state.rb
87
+ - lib/gamestates/play_state.rb
88
+ - lib/main.rb
89
+ - lib/misc/ai.rb
90
+ - lib/misc/game_window.rb
91
+ - lib/misc/level.rb
92
+ - lib/misc/map.rb
93
+ - lib/misc/mediamanager.rb
94
+ - lib/misc/sprite.rb
95
+ - media/emulogic.ttf
96
+ - media/sprites.png
97
+ - media/sprites_transparent.png
76
98
  homepage: ''
77
99
  licenses:
78
100
  - MIT
data/.idea/.name DELETED
@@ -1 +0,0 @@
1
- Battlecity