-
Notifications
You must be signed in to change notification settings - Fork 2
/
spaceinvaders.rb
202 lines (164 loc) · 3.83 KB
/
spaceinvaders.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
# Space Invaders
# a super mega massive awesome space invaders clone LOL !!!!111eleven
#
# code (cc) oneup <hello@geeq.at>
# graphics (cc) kingpepe
require "activesupport"
require "kyoto_reconstruction"
def game
$game
end
class Spaceinvaders < Game
attr_accessor :player
include Collideable
include Timer
resolution [640, 480]
def setup
$game = self
@x, @y = 0, 0
@player = PlayerShip.new
@objects << @player
row = 0
EnemyShip.rows.times do |row|
x = 10 # fixme: calculate from EnemyShip.rows
EnemyShip.cols.times do
enemy = EnemyShip.new(x, row)
@objects << enemy
x += (enemy.width + 10)
end
row += 1
end
every(2.seconds) do
row = 0
x = 10 # fixme: calculate from EnemyShip.rows
EnemyShip.cols.times do
enemy = EnemyShip.new(x, row)
@objects << enemy
x += (enemy.width + 10)
end
row += 1
end
end
def font
"puit/font/Busk_3x3pixel_fin".ttf
end
def draw
super
font.draw("YOU WON", width-120, 10) if $game.count(EnemyShip) == 0
font.draw("YOU LOST", width-120, 10) if $game.count(PlayerShip) == 0
end
end
# now: other ships :)
class EnemyShip < Gameobject
# set :rows, 6
# set :cols, 24
def self.rows
6
end
def self.cols
$game.width / ("spaceinvaders/Space Invader1".img.width+10)
end
def points
(1 + EnemyShip.rows - @row) * 10
end
def initialize x, row
set_sprite "spaceinvaders/Space Invader#{row+1}"
@row = row
@velocity = 0.2
@x, @y = x, 10 + (@row+1)*(sprite.height+10)
end
def change_direction_and_go_to_next_row
@velocity = -@velocity
@velocity *= 1.2
@y += sprite.height + 10
end
def update
@x += @velocity
if right > $game.width or left < 0 # one space invader touched the right or left border!!!
for ship in $game.all(EnemyShip)
ship.change_direction_and_go_to_next_row
end
end
# kill player?
if $game.player.collides_with? self
$game.player.die
end
# shoot
if probability(0.0005)
shot = Shot.new @x, @y+sprite.height, +4, PlayerShip
$game.objects << shot
end
end
def die
$game.player.score += self.points
super
end
end
class Shot < Gameobject
def initialize x, y, vel_y, target
@x, @y, @vel_y = x, y, vel_y
@target = target
set_sprite "spaceinvaders/Shot1"
end
def update
@y += @vel_y
$game.all(@target).each do |object|
if self.collides_with? object
object.die
die
end
end
die unless $game.collides_with? self
end
end
class PlayerShip < Gameobject
attr_accessor :score
@@speed = 5
def initialize
set_sprite("spaceinvaders/Shooter")
@x = 0
@y = $game.height - sprite.height - 10 # 10 pixels free to bottom
@vel_x = 0
@vel_y = 0
@score = 0
@lives = 3
set_keys("left".key => :move_left,
"left".gamepad => :move_left,
"right".key => :move_right,
"right".gamepad => :move_right,
"space".key => :shoot)
end
def update
@x += @vel_x
@y += @vel_y
@x = (0..$game.width).limit @x
@y = (0..$game.height).limit @y
end
def draw
super
font.draw("#{@score} points #{@lives} lives", 10, 10, 0)
end
def font
$game.font
end
def shoot pressed
if pressed
shot = Shot.new @x, @y - self.height, -6, EnemyShip
$game.objects << shot
end
end
def move_left pressed
@vel_x = -@@speed if pressed
@vel_x = 0 if not pressed and not is_pressed? :move_right
end
def move_right pressed
@vel_x = @@speed if pressed
@vel_x = 0 if not pressed and not is_pressed? :move_left
end
def die
@lives -= 1
if @lives == 0
super # really die
end
end
end