prkwars 0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 1f148993f8f36cbef84d775439462a7ac06cc4c1
4
+ data.tar.gz: bd0bffc487588e44e113f51bd91536a257dd0af2
5
+ SHA512:
6
+ metadata.gz: 8861ae042979ea10ef8bb8b6f5471ac7e55c328416e81091600566043095364b44bfa1f27ef1da6925c33ed47b8369e143d7267702e318866b03506ca5eedb76
7
+ data.tar.gz: 221db7ba52d96a1a4e4e11c8d035069fcca794b5fbc56fb078d8d727d35d36038dbf100f38c091e5657a089fd44e2a168671fdf0b3f153cb144b7679d50cdd9b
data/bin/prkwars ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'prkwars'
4
+
5
+ Game.new.show
@@ -0,0 +1,30 @@
1
+ require_relative './modules.rb'
2
+ require 'chingu'
3
+
4
+ # Class representing a bullet shot by the player. Destroys itself
5
+ # if is present out of bounds.
6
+ class Bullet < Chingu::GameObject
7
+ trait :velocity
8
+ trait :bounding_box
9
+ trait :collision_detection
10
+ include GamespacePersistence
11
+
12
+ def initialize(gamespace, options = {})
13
+ super(options)
14
+ @image = Image['media/bullet.png']
15
+ @gamespace = gamespace
16
+
17
+ cache_bounding_box
18
+ end
19
+
20
+ def update
21
+ return if in_bounds(self, @gamespace)
22
+
23
+ 2.times do
24
+ ExplosionParticle.create(@gamespace,
25
+ x: @x, y: @y,
26
+ zorder: ZOrder::GAMEOBJECT)
27
+ destroy!
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,20 @@
1
+ require_relative './modules'
2
+ require 'chingu'
3
+
4
+ # A bullet shot by the Turret enemy unit. Destroys itself if out of bounds.
5
+ class BulletTurret < Chingu::GameObject
6
+ trait :velocity
7
+ trait :bounding_box
8
+ trait :collision_detection
9
+ include GamespacePersistence
10
+
11
+ def initialize(gamespace, options = {})
12
+ super(options)
13
+ @image = Image['media/bullet_turret.png']
14
+ @gamespace = gamespace
15
+ end
16
+
17
+ def update
18
+ destroy! unless in_bounds(self, @gamespace)
19
+ end
20
+ end
@@ -0,0 +1,16 @@
1
+ require 'chingu'
2
+
3
+ # A generic Enemy class inheriting from Chingu::Gameobject. Any enemy
4
+ # unit inherits from this class. The class contains a method
5
+ # which returns all the descendants - useful for checking all possible
6
+ # collisions.
7
+ class Enemy < Chingu::GameObject
8
+ attr_accessor :hp
9
+ trait :bounding_box
10
+ trait :collision_detection
11
+ trait :timer
12
+
13
+ def self.descendants
14
+ ObjectSpace.each_object(::Class).select { |klass| klass < self }
15
+ end
16
+ end
@@ -0,0 +1,48 @@
1
+ require_relative './modules'
2
+ require 'chingu'
3
+
4
+ # Class used for holding behaviour of particles during explosions of various
5
+ # entitites.
6
+ class ExplosionParticle < Chingu::GameObject
7
+ trait :velocity
8
+ trait :effect # fade
9
+ trait :bounding_box
10
+ include GamespacePersistence
11
+
12
+ def initialize(gamespace, options = {})
13
+ super(options)
14
+
15
+ @gamespace = gamespace
16
+ @fade_rate = -3
17
+ @mode = :default
18
+ @image = Image['media/myparticle.png']
19
+ @velocity_x = rand(-7..7)
20
+ @velocity_y = rand(-7..7)
21
+ @angle = Math.atan2(@velocity_x, @velocity_y) / Math::PI * 180 + 90
22
+ end
23
+
24
+ def update
25
+ velocity_correct! unless bounding_box.collide_rect?(@gamespace.bounding_box)
26
+ destroy! if color.alpha.zero?
27
+ end
28
+
29
+ private
30
+
31
+ # Method correcting the velocity if hitting a wall.
32
+ def velocity_correct!
33
+ if hitting_side
34
+ @velocity_x = -@velocity_x
35
+ else
36
+ @velocity_y = -@velocity_y
37
+ end
38
+ end
39
+
40
+ def hitting_side
41
+ if bounding_box.left < @gamespace.bounding_box.left ||
42
+ bounding_box.right > @gamespace.bounding_box.right
43
+ true
44
+ else
45
+ false
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,16 @@
1
+ require_relative './play'
2
+ require 'chingu'
3
+ include Gosu
4
+
5
+ # Game class which is reponsible for the whole game logic - generation
6
+ # of the game space, generation of enemies and checking collisions between
7
+ # them, destroying objects or reducing their HP if necessary.
8
+ class Game < Chingu::Window
9
+ attr_reader :player, :gamespace
10
+
11
+ def initialize
12
+ super(1280, 720)
13
+ # push_game_state(Play)
14
+ push_game_state(Splash)
15
+ end
16
+ end
@@ -0,0 +1,18 @@
1
+ require 'chingu'
2
+
3
+ # Class representing the game over state shown when the player loses the game.
4
+ class GameOver < Chingu::GameState
5
+ def initialize(score, options = {})
6
+ super(options)
7
+
8
+ self.input = { space: :play, esc: :exit }
9
+
10
+ Chingu::Text.create("Final score: #{score}", x: 20, y: 20, size: 30)
11
+ Chingu::Text.create('Press <space> to play again, <esc> to exit.',
12
+ x: 20, y: 60)
13
+ end
14
+
15
+ def play
16
+ switch_game_state(Play.new)
17
+ end
18
+ end
@@ -0,0 +1,47 @@
1
+ require 'chingu'
2
+
3
+ # Class representing the space where the game is being played. Class is
4
+ # essentially an encapsulation for the big rectangle where the game can be
5
+ # played. Also holds possible spawn points for enemy entities.
6
+ class GameSpace < Chingu::GameObject
7
+ trait :collision_detection
8
+ trait :bounding_box
9
+
10
+ attr_accessor :player
11
+ attr_reader :spawn_points
12
+
13
+ def initialize(options = {})
14
+ super(options)
15
+
16
+ @image = Image['media/background.png']
17
+ setup_spawn_points
18
+ end
19
+
20
+ def enemy_spawn_point(player_x, player_y)
21
+ sample_points = points_far_enough(player_x, player_y)
22
+
23
+ sample_points.sample
24
+ end
25
+
26
+ private
27
+
28
+ def setup_spawn_points
29
+ @spawn_points = [[60, 60], [1200, 60], [60, 640], [1200, 640], [800, 640],
30
+ [800, 60], [800, 640], [250, 400], [500, 600],
31
+ [120, 640], [340, 520], [380, 640], [960, 80],
32
+ [1100, 420]]
33
+ end
34
+
35
+ def points_far_enough(player_x, player_y)
36
+ points = []
37
+
38
+ @spawn_points.each do |point|
39
+ dist = Math.sqrt((player_x - point[0]) * (player_x - point[0]) +
40
+ (player_y - point[1]) * (player_y - point[1]))
41
+
42
+ points.push(point) if dist > 130
43
+ end
44
+
45
+ points
46
+ end
47
+ end
@@ -0,0 +1,32 @@
1
+ require 'chingu'
2
+
3
+ module ZOrder
4
+ GAMEOBJECT = 2
5
+ end
6
+
7
+ module Constants
8
+ PLAYER_VELOCITY = 6
9
+ BULLET_VELOCITY = 12
10
+ end
11
+
12
+ # Module used by classes as a mixin for collision checking with the gamespace
13
+ # so that they do not get out of bounds.
14
+ module GamespacePersistence
15
+ def in_bounds(entity, gamespace)
16
+ return true if gamespace.bounding_box.contain?(entity.bounding_box)
17
+ false
18
+ end
19
+
20
+ def correct_coords(entity, gamespace)
21
+ if entity.bounding_box.top < gamespace.bounding_box.top # ceiling
22
+ entity.y += gamespace.bounding_box.top - entity.bounding_box.top
23
+ elsif entity.bounding_box.bottom > gamespace.bounding_box.bottom # floor
24
+ entity.y -= entity.bounding_box.bottom - gamespace.bounding_box.bottom
25
+ end
26
+ if entity.bounding_box.left < gamespace.bounding_box.left # left side
27
+ entity.x += gamespace.bounding_box.left - entity.bounding_box.left
28
+ elsif entity.bounding_box.right > gamespace.bounding_box.right # right side
29
+ entity.x -= entity.bounding_box.right - gamespace.bounding_box.right
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,195 @@
1
+ require 'chingu'
2
+
3
+ # Class holding the gamestate of the gameplay itself.
4
+ class Play < Chingu::GameState
5
+ trait :timer
6
+
7
+ attr_reader :player, :gamespace
8
+
9
+ PLAYER_START_X = 800
10
+ PLAYER_START_Y = 640
11
+
12
+ include GamespacePersistence
13
+
14
+ def initialize(options = {})
15
+ super(options)
16
+
17
+ self.input = { esc: :exit, p: :pause }
18
+
19
+ @gamespace = GameSpace.create(x: 1280 / 2, y: 720 / 2)
20
+ @player = Player.create(@gamespace,
21
+ zorder: ZOrder::GAMEOBJECT,
22
+ x: PLAYER_START_X, y: PLAYER_START_Y)
23
+ @gamespace.player = @player
24
+
25
+ setup_enemy_generation
26
+ setup_score_calculation
27
+ setup_display_messages
28
+ end
29
+
30
+ def pause
31
+ switch_game_state(Splash)
32
+ end
33
+
34
+ def update
35
+ super
36
+ collide_enemies_bullets
37
+ collide_enemies_player
38
+
39
+ generate_random_enemy
40
+ end
41
+
42
+ def draw
43
+ super
44
+ end
45
+
46
+ private
47
+
48
+ def setup_score_calculation
49
+ @score = 0
50
+ @multiplier = 1
51
+ @score_this_life = 0
52
+ @next_multiplier = 2000
53
+ end
54
+
55
+ def update_score
56
+ @score += 100 * @multiplier
57
+ @score_this_life += 100 * @multiplier
58
+
59
+ @message_score.text = "Score: #{@score}"
60
+
61
+ return if @score_this_life != @next_multiplier
62
+
63
+ @multiplier += 1
64
+ PopupText.create("#{@multiplier}x Multiplier", @player.x, @player.y - 10)
65
+ @next_multiplier *= 2
66
+ end
67
+
68
+ def collide_enemies_bullets
69
+ Enemy.descendants.each do |enemy|
70
+ enemy.each_bounding_box_collision(Bullet) do |nmy, bullet|
71
+ 10.times do
72
+ ExplosionParticle.create(@gamespace,
73
+ x: bullet.x, y: bullet.y,
74
+ zorder: ZOrder::GAMEOBJECT)
75
+ end
76
+ bullet.destroy!
77
+ nmy.take_damage
78
+ next unless nmy.hp.zero?
79
+ Warp.create(zorder: ZOrder::GAMEOBJECT, x: nmy.x, y: nmy.y)
80
+ PopupText.create((100 * @multiplier).to_s, nmy.x, nmy.y)
81
+ nmy.destroy
82
+ update_score
83
+ end
84
+ end
85
+ end
86
+
87
+ def collide_enemies_player
88
+ Enemy.descendants.each do |enemy|
89
+ @player.each_bounding_box_collision(enemy) do
90
+ handle_player_death
91
+ return true # no need to check collisions of turret bullets
92
+ end
93
+ end
94
+
95
+ @player.each_bounding_box_collision(BulletTurret) do
96
+ handle_player_death
97
+ end
98
+ end
99
+
100
+ def generate_random_enemy
101
+ @framecounter_turret += 1
102
+ generate_random_turret
103
+
104
+ @framecounter_stalker += 1
105
+ generate_random_stalker
106
+ end
107
+
108
+ def generate_random_turret
109
+ return if @framecounter_turret != @nextgen_turret
110
+
111
+ x, y = generate_random_position
112
+ turret = Turret.create(@gamespace, zorder: ZOrder::GAMEOBJECT, x: x, y: y)
113
+
114
+ correct_coords(turret, @gamespace)
115
+
116
+ create_warp(x, y)
117
+
118
+ @framecounter_turret = 0
119
+ @nextgen_turret = rand(80..150)
120
+ end
121
+
122
+ def generate_random_stalker
123
+ return if @framecounter_stalker != @nextgen_stalker
124
+
125
+ x, y = generate_random_position
126
+ Stalker.create(@gamespace, zorder: ZOrder::GAMEOBJECT, x: x, y: y)
127
+ create_warp(x, y)
128
+
129
+ @framecounter_stalker = 0
130
+ @nextgen_stalker = rand(20..50)
131
+ end
132
+
133
+ def create_warp(x, y)
134
+ Warp.create(zorder: ZOrder::GAMEOBJECT, x: x, y: y)
135
+ end
136
+
137
+ def generate_random_position
138
+ x, y = @gamespace.enemy_spawn_point(@player.x, @player.y)
139
+
140
+ x += rand(-30..30)
141
+ y += rand(-30..30)
142
+
143
+ [x, y]
144
+ end
145
+
146
+ def handle_game_over
147
+ switch_game_state(GameOver.new(@score))
148
+ end
149
+
150
+ def handle_player_death
151
+ kill_everything
152
+ @player.lives -= 1
153
+ handle_game_over if @player.lives.zero?
154
+
155
+ 500.times do
156
+ ExplosionParticle.create(@gamespace,
157
+ x: @player.x, y: @player.y,
158
+ zorder: ZOrder::GAMEOBJECT)
159
+ end
160
+
161
+ setup_enemy_generation
162
+ @message_lives.text = "Lives: #{@player.lives}"
163
+ @score_this_life = 0
164
+ @next_multiplier = 2000
165
+ @multiplier = 1
166
+ PopupText.create("#{@multiplier}x Multiplier", @player.x, @player.y - 10)
167
+ @player.x = PLAYER_START_X
168
+ @player.y = PLAYER_START_Y
169
+ end
170
+
171
+ def kill_everything
172
+ Enemy.descendants.each do |enemy|
173
+ ObjectSpace.each_object(enemy, &:destroy!)
174
+ end
175
+
176
+ ObjectSpace.each_object(BulletTurret, &:destroy!)
177
+
178
+ ObjectSpace.each_object(Bullet, &:destroy!)
179
+ end
180
+
181
+ def setup_enemy_generation
182
+ @framecounter_turret = 0
183
+ @nextgen_turret = rand(150..300)
184
+ @framecounter_stalker = 0
185
+ @nextgen_stalker = rand(110..180)
186
+ end
187
+
188
+ def setup_display_messages
189
+ @message_lives = Chingu::Text.create("Lives: #{@player.lives}",
190
+ x: 1020, y: 5, size: 30)
191
+
192
+ @message_score = Chingu::Text.create("Score: #{@score}",
193
+ x: 100, y: 5, size: 30)
194
+ end
195
+ end
@@ -0,0 +1,128 @@
1
+ require_relative './modules'
2
+ require 'chingu'
3
+
4
+ # Class holding all the logic related to the player - input controller
5
+ # and any manipulation of player's sprite.
6
+ class Player < Chingu::GameObject
7
+ trait :bounding_box
8
+ trait :collision_detection
9
+
10
+ attr_accessor :lives
11
+ attr_reader :invulnerable
12
+
13
+ include GamespacePersistence
14
+ STARTING_LIVES = 3
15
+ SHOOT_GAP = 8
16
+ STARTING_BOMBS = 3
17
+ INVUL_FRAMES = 30
18
+
19
+ def initialize(gamespace, options = {})
20
+ super(options)
21
+
22
+ @image = Image['./media/player_ship.png']
23
+ self.input = { holding_w: :move_up, holding_a: :move_left,
24
+ holding_d: :move_right, holding_s: :move_down,
25
+ holding_left: :shoot_left, holding_right: :shoot_right,
26
+ holding_up: :shoot_up, holding_down: :shoot_down }
27
+ init_vector_variables
28
+
29
+ @gamespace = gamespace
30
+ @lives = STARTING_LIVES
31
+ @bombs = STARTING_BOMBS
32
+ end
33
+
34
+ def move_up
35
+ @y -= Constants::PLAYER_VELOCITY
36
+ @y_change = -Constants::PLAYER_VELOCITY
37
+ end
38
+
39
+ def move_down
40
+ @y += Constants::PLAYER_VELOCITY
41
+ @y_change = Constants::PLAYER_VELOCITY
42
+ end
43
+
44
+ def move_left
45
+ @x -= Constants::PLAYER_VELOCITY
46
+ @x_change = -Constants::PLAYER_VELOCITY
47
+ end
48
+
49
+ def move_right
50
+ @x += Constants::PLAYER_VELOCITY
51
+ @x_change = Constants::PLAYER_VELOCITY
52
+ end
53
+
54
+ def shoot_left
55
+ @shoot_vec_x = -Constants::BULLET_VELOCITY
56
+ end
57
+
58
+ def shoot_right
59
+ @shoot_vec_x = Constants::BULLET_VELOCITY
60
+ end
61
+
62
+ def shoot_up
63
+ @shoot_vec_y = -Constants::BULLET_VELOCITY
64
+ end
65
+
66
+ def shoot_down
67
+ @shoot_vec_y = Constants::BULLET_VELOCITY
68
+ end
69
+
70
+ def update
71
+ rotate_player
72
+ correct_coords(self, @gamespace) unless in_bounds(self, @gamespace)
73
+ @shoot_timer += 1
74
+ return unless @shoot_timer == SHOOT_GAP
75
+
76
+ shoot_bullet
77
+ @shoot_timer = 0
78
+ end
79
+
80
+ private
81
+
82
+ def init_vector_variables
83
+ @x_change = 0 # Used for rotating the triangular sprite
84
+ @y_change = 0
85
+ @shoot_timer = 0
86
+ @shoot_vec_x = 0 # Used for deciding the shooting direction
87
+ @shoot_vec_y = 0
88
+ end
89
+
90
+ def rotate_player
91
+ return unless @x_change != 0 || @y_change != 0
92
+
93
+ rot_to = Math.atan2(@y_change, @x_change) / Math::PI * 180 + 90
94
+
95
+ self.angle = rot_to
96
+
97
+ @x_change = 0
98
+ @y_change = 0
99
+ end
100
+
101
+ def shoot_bullet
102
+ return unless @shoot_vec_x != 0 || @shoot_vec_y != 0
103
+
104
+ bullet_angle = Math.atan2(@shoot_vec_y, @shoot_vec_x) / Math::PI * 180 - 180
105
+
106
+ norm_x = -@shoot_vec_y
107
+ norm_y = @shoot_vec_x
108
+
109
+ dist_norm = Math.sqrt(norm_x * norm_x + norm_y * norm_y)
110
+
111
+ unit_x = norm_x / dist_norm
112
+ unit_y = norm_y / dist_norm
113
+
114
+ Bullet.create(@gamespace,
115
+ zorder: ZOrder::GAMEOBJECT, x: @x + unit_x * 7,
116
+ y: @y + unit_y * 7,
117
+ velocity_x: @shoot_vec_x, velocity_y: @shoot_vec_y,
118
+ angle: bullet_angle)
119
+
120
+ Bullet.create(@gamespace,
121
+ zorder: ZOrder::GAMEOBJECT, x: @x - unit_x * 7,
122
+ y: @y - unit_y * 7,
123
+ velocity_x: @shoot_vec_x, velocity_y: @shoot_vec_y,
124
+ angle: bullet_angle)
125
+ @shoot_vec_x = 0
126
+ @shoot_vec_y = 0
127
+ end
128
+ end
@@ -0,0 +1,23 @@
1
+ require 'chingu'
2
+ include Gosu
3
+
4
+ # Class used for messages that pop up on the screen whenever something
5
+ # relevant happens - e.g. score goes up.
6
+ class PopupText < Chingu::GameObject
7
+ trait :effect # fade
8
+ trait :velocity # move up slowly
9
+
10
+ def initialize(message, x, y, options = {})
11
+ super(options)
12
+
13
+ @velocity_x = 0
14
+ @velocity_y = -2
15
+ @msg = Chingu::Text.create(message, x: x, y: y, size: 30)
16
+ end
17
+
18
+ def update
19
+ @msg.y -= 1
20
+ @msg.color.alpha -= 4
21
+ @msg.destroy! if color.alpha.zero?
22
+ end
23
+ end
@@ -0,0 +1,22 @@
1
+ require 'chingu'
2
+
3
+ # Class representing the game state right after turning the game on.
4
+ class Splash < Chingu::GameState
5
+ def setup
6
+ self.input = { space: :play, esc: :exit }
7
+ Chingu::Text.create('PRK WARS',
8
+ x: 20, y: 20, size: 60, color: Gosu::Color::RED)
9
+ Chingu::Text.create('A simple Grid Wars/Geometry Wars clone',
10
+ x: 20, y: 90, size: 30)
11
+ Chingu::Text.create('Press <space> to play the game, <esc> to exit.',
12
+ x: 20, y: 130, size: 30)
13
+ Chingu::Text.create('Controls: WASD: movement, arrow keys: shooting'\
14
+ ' direction.',
15
+ x: 20, y: 170, size: 30)
16
+ end
17
+
18
+ def play
19
+ transitional_game_state(Chingu::GameStates::FadeTo, speed: 10)
20
+ switch_game_state(Play.new)
21
+ end
22
+ end
@@ -0,0 +1,39 @@
1
+ require_relative './enemy'
2
+ require 'chingu'
3
+
4
+ # Class representing the Stalker enemy unit which is mobile but unable to
5
+ # shoot and endlessly moves towards the player unit.
6
+ class Stalker < Enemy
7
+ trait :velocity
8
+ include GamespacePersistence
9
+ VELOCITY = 2
10
+ HP = 1
11
+
12
+ def initialize(gamespace, options = {})
13
+ super(options)
14
+
15
+ @image = Image['./media/stalker.png']
16
+
17
+ @gamespace = gamespace
18
+ @hp = HP
19
+ end
20
+
21
+ def update
22
+ dist_x = @gamespace.player.x - @x
23
+ dist_y = @gamespace.player.y - @y
24
+
25
+ rot_to = Math.atan2(dist_y, dist_x) / Math::PI * 180 + 90
26
+
27
+ dist = Math.sqrt(dist_x * dist_x + dist_y * dist_y)
28
+
29
+ ticks = dist / VELOCITY
30
+
31
+ @velocity_x = dist_x / ticks
32
+ @velocity_y = dist_y / ticks
33
+ @angle = rot_to
34
+ end
35
+
36
+ def take_damage
37
+ @hp -= 1
38
+ end
39
+ end
@@ -0,0 +1,54 @@
1
+ require_relative './modules'
2
+ require_relative './enemy'
3
+ require_relative './bullet_turret'
4
+ require 'chingu'
5
+
6
+ # Class representing the Turret enemy unit which is stationary and endlessly
7
+ # shoots bullets in the direction of the player.
8
+ class Turret < Enemy
9
+ SHOOT_GAP = 40
10
+ VELOCITY = 3
11
+ HP = 3
12
+
13
+ def initialize(gamespace, options = {})
14
+ super(options)
15
+
16
+ @animation = Chingu::Animation.new(file: 'media/turrets.png', size: 32)
17
+
18
+ @gamespace = gamespace
19
+ @hp = HP
20
+ @shoot_timer = 0
21
+ @image = @animation[@hp - 1]
22
+ end
23
+
24
+ def update
25
+ @shoot_timer += 1
26
+ return unless @shoot_timer == SHOOT_GAP
27
+
28
+ shoot_bullet
29
+ @shoot_timer = 0
30
+ end
31
+
32
+ def take_damage
33
+ @hp -= 1
34
+ @image = @animation[@hp - 1]
35
+ end
36
+
37
+ private
38
+
39
+ def shoot_bullet
40
+ dist_x = @gamespace.player.x - @x
41
+ dist_y = @gamespace.player.y - @y
42
+
43
+ bullet_angle = Math.atan2(dist_y, dist_x) / Math::PI * 180 + 90
44
+
45
+ dist = Math.sqrt(dist_x * dist_x + dist_y * dist_y)
46
+
47
+ ticks = dist / VELOCITY
48
+
49
+ BulletTurret.create(@gamespace,
50
+ zorder: ZOrder::GAMEOBJECT, x: @x,
51
+ y: @y, velocity_x: dist_x / ticks,
52
+ velocity_y: dist_y / ticks, angle: bullet_angle)
53
+ end
54
+ end
@@ -0,0 +1,18 @@
1
+ require 'chingu'
2
+
3
+ # Class holding the warp effect used whenever an enemy game object
4
+ # spawns somewhere.
5
+ class Warp < Chingu::GameObject
6
+ trait :effect # fade
7
+
8
+ def initialize(options = {})
9
+ super(options)
10
+
11
+ @fade_rate = -8
12
+ @image = Image['media/warp.png']
13
+ end
14
+
15
+ def update
16
+ destroy! if color.alpha.zero?
17
+ end
18
+ end
data/lib/prkwars.rb ADDED
@@ -0,0 +1,5 @@
1
+ PRKWARS_ROOT = File.dirname(File.expand_path(__FILE__))
2
+
3
+ Dir[File.join(PRKWARS_ROOT, '/prkwars/*.rb')].each { |f| require f }
4
+
5
+ #Game.new.show
Binary file
data/media/bullet.png ADDED
Binary file
Binary file
Binary file
Binary file
Binary file
data/media/stalker.png ADDED
Binary file
data/media/turrets.png ADDED
Binary file
data/media/warp.png ADDED
Binary file
metadata ADDED
@@ -0,0 +1,71 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: prkwars
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Marek Pikna
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-02-16 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: A simple Grid Wars clone made as a project for the Ruby class taught
14
+ at FIT CTU.
15
+ email: mar.pikna@gmail.com
16
+ executables:
17
+ - prkwars
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - bin/prkwars
22
+ - lib/prkwars.rb
23
+ - lib/prkwars/bullet.rb
24
+ - lib/prkwars/bullet_turret.rb
25
+ - lib/prkwars/enemy.rb
26
+ - lib/prkwars/explosionparticle.rb
27
+ - lib/prkwars/game.rb
28
+ - lib/prkwars/gameover.rb
29
+ - lib/prkwars/gamespace.rb
30
+ - lib/prkwars/modules.rb
31
+ - lib/prkwars/play.rb
32
+ - lib/prkwars/player.rb
33
+ - lib/prkwars/popuptext.rb
34
+ - lib/prkwars/splash.rb
35
+ - lib/prkwars/stalker.rb
36
+ - lib/prkwars/turret.rb
37
+ - lib/prkwars/warp.rb
38
+ - media/background.png
39
+ - media/bullet.png
40
+ - media/bullet_turret.png
41
+ - media/gamespace.png
42
+ - media/myparticle.png
43
+ - media/player_ship.png
44
+ - media/stalker.png
45
+ - media/turrets.png
46
+ - media/warp.png
47
+ homepage: http://rubygems.org/gems/prkwars
48
+ licenses:
49
+ - MIT
50
+ metadata: {}
51
+ post_install_message:
52
+ rdoc_options: []
53
+ require_paths:
54
+ - lib
55
+ required_ruby_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ required_rubygems_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: '0'
65
+ requirements: []
66
+ rubyforge_project:
67
+ rubygems_version: 2.6.13
68
+ signing_key:
69
+ specification_version: 4
70
+ summary: Prk wars - a Grid Wars clone
71
+ test_files: []