-
Notifications
You must be signed in to change notification settings - Fork 0
/
Bomb.m
307 lines (288 loc) · 11.4 KB
/
Bomb.m
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
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
classdef Bomb < BoardPiece
%The Bomb class is a subclass of BoardPiece. It has four inputs, a
%position, board, myOwner (a Player object), and a myRange (a property of
%the Player object). It calls the BoardPiece constructor, then creates its
%own additional properties of Range, Owner, Time, and StartTime in the
%constructor. It has an explode function that works with its getObstacles
%function, which destroys the bomb and surrounding objects around it within
%it's Range. It also checks if the bomb hits a player, with the
%checkPlayerSafety method. The Bomb class has a method called update, which
%when called calls its Time property and subtracts one. If the Time = 0, it
%calls the die method, which overloads the BoardPiece die and calls the
%explode method instead. Lastly, it has a static method getSym, which
%returns "BO".
properties
Range;
Owner;
Time;
StartTime;
end
methods
function newBomb = Bomb(position,board,myOwner,myRange)
newBomb = newBomb@BoardPiece(position,board);
newBomb.StartTime = clock;
if nargin > 2
newBomb.Range = myRange;
newBomb.Owner = myOwner;
newBomb.Time = 3; % Blow up after 3 seconds
end
end
function explode(b)
b.MyBoard.addPiece(EmptySpace(b.Position,b.MyBoard));
b.MyBoard.Bombs(1) = [];
b.Owner.BombCount = b.Owner.BombCount + 1;
obstacles = b.getObstacles();
e_c = imread('explosion_center.png','Back',[0 .6 .3]);
e_h = imread('explosion_hor.png','Back',[0 .6 .3]);
e_v = imread('explosion_ver.png','Back',[0 .6 .3]);
e_h_l = imread('explosion_hor_left.png','Back',[0 .6 .3]);
e_h_r = imread('explosion_hor_right.png','Back',[0 .6 .3]);
e_v_b = imread('explosion_ver_bottom.png','Back',[0 .6 .3]);
e_v_t = imread('explosion_ver_top.png','Back',[0 .6 .3]);
exp_hor = flipdim(e_h,2);
exp_ver = flipdim(e_v,2);
exp_hor_lef = flipdim(e_h_l,2);
exp_hor_rig = flipdim(e_h_r,2);
exp_ver_bot = flipdim(e_v_b,2);
exp_ver_top = flipdim(e_v_t,2);
hold on
%n s e w
x = b.Position(1); y = b.Position(2); z = b.Range;
imagesc([x+.5 x-.5],[16-(y+.5) 16-(y-.5)],e_c);
%North
pc = obstacles{1};
if isa(pc,'FilledSpace')
pc = b.MyBoard.MyBoardPieces{x,y+1};
end
pos = pc.Position;
if pos(2) == y
%do nothing
else
dist = y-pos(2);
if dist == 1
imagesc([x+.5 x-.5],[16-(y-1+.5) 16-(y-1-.5)],exp_ver_bot);
elseif dist > 1
i = 1;
while i < dist
imagesc([x+.5 x-.5],[16-(y-i+.5) 16-(y-i-.5)],exp_ver);
i = i+1;
end
imagesc([x+.5 x-.5],[16-(y-i+.5) 16-(y-i-.5)],exp_ver_bot);
end
end
%South
pc = obstacles{2};
if isa(pc,'FilledSpace')
pc = b.MyBoard.MyBoardPieces{x,y-1};
end
pos = pc.Position;
if pos(2) == y
%do nothing
else
dist = pos(2)-y;
if dist == 1
imagesc([x+.5 x-.5],[16-(y+1+.5) 16-(y+1-.5)],exp_ver_top);
elseif dist > 1
i = 1;
while i < dist
imagesc([x+.5 x-.5],[16-(y+i+.5) 16-(y+i-.5)],exp_ver);
i = i+1;
end
imagesc([x+.5 x-.5],[16-(y+i+.5) 16-(y+i-.5)],exp_ver_top);
end
end
%East
pc = obstacles{3};
if isa(pc,'FilledSpace')
pc = b.MyBoard.MyBoardPieces{x-1,y};
end
pos = pc.Position;
if pos(1) == x
%do nothing
else
dist = pos(1)-x;
if dist == 1
imagesc([x+1+.5 x+1-.5],[16-(y+.5) 16-(y-.5)],exp_hor_rig);
elseif dist > 1
i = 1;
while i < dist
imagesc([x+i+.5 x+i-.5],[16-(y+.5) 16-(y-.5)],exp_hor);
i = i+1;
end
imagesc([x+i+.5 x+i-.5],[16-(y+.5) 16-(y-.5)],exp_hor_rig);
end
end
%West
pc = obstacles{4};
if isa(pc,'FilledSpace')
pc = b.MyBoard.MyBoardPieces{x+1,y};
end
pos = pc.Position;
if pos(1) == x
%do nothing
else
dist = x-pos(1);
if dist == 1
imagesc([x-1+.5 x-1-.5],[16-(y+.5) 16-(y-.5)],exp_hor_lef);
elseif dist > 1
i = 1;
while i < dist
imagesc([x-i+.5 x-i-.5],[16-(y+.5) 16-(y-.5)],exp_hor);
i = i+1;
end
imagesc([x-i+.5 x-i-.5],[16-(y+.5) 16-(y-.5)],exp_hor_lef);
end
end
hold off
p1 = b.Owner.MyGame.PlayerList{1};
p2 = b.Owner.MyGame.PlayerList{2};
if ~b.checkPlayerSafety(p1,obstacles)
p1.IsAlive = false;
end
if ~b.checkPlayerSafety(p2,obstacles)
p2.IsAlive = false;
end
for i = 1:4
if obstacles{i} ~= b
obstacles{i}.die();
end
end
end
function obstacles = getObstacles(b)
noNorthObstacle = true;
noSouthObstacle = true;
noWestObstacle = true;
noEastObstacle = true;
i = 0;
n = 0;
s = 0;
w = 0;
e = 0;
obstacles = cell(1,4);
while (i<b.Range)
if noNorthObstacle
n = n+1;
obstacles{1} = b.MyBoard.MyBoardPieces{b.Position(1),max(b.Position(2)-n,1)};
if ~strcmp(obstacles{1}.getSym,'ES')
noNorthObstacle = false;
end
end
if noSouthObstacle
s = s+1;
obstacles{2} = b.MyBoard.MyBoardPieces{b.Position(1),min(b.Position(2)+s,15)};
if ~strcmp(obstacles{2}.getSym,'ES')
noSouthObstacle = false;
end
end
if noEastObstacle
e = e+1;
obstacles{3} = b.MyBoard.MyBoardPieces{min(b.Position(1)+e,15),b.Position(2)};
if ~strcmp(obstacles{3}.getSym,'ES')
noEastObstacle = false;
end
end
if noWestObstacle
w = w+1;
obstacles{4} = b.MyBoard.MyBoardPieces{max(b.Position(1)-w,1),b.Position(2)};
if ~strcmp(obstacles{4}.getSym,'ES')
noWestObstacle = false;
end
end
i = i+1;
end
end
function safe = checkPlayerSafety(b,p,obstacles)
safe = true;
pos = Player.nearby(p.Position);
danger = false; %Is player 1 within range of bomb
hitbox = 0; %which part of the player was hit
direction = 'D'; % Direction of bomb blast towards player
% D is a null value
for j = 1:4
if (abs(pos{j}(1) - b.Position(1))<=b.Range && ...
pos{j}(2) == b.Position(2))
%Player is east or west of bomb
danger = true;
hitbox = j;
if (pos{j}(1) - b.Position(1))>0
direction = 'E';
elseif (pos{j}(1) - b.Position(1))<0
direction = 'W';
elseif (pos{j}(1) - b.Position(1))==0
safe = false;
end
elseif (abs(pos{j}(2) - b.Position(2))<=b.Range && ...
pos{j}(1) == b.Position(1))
%Player is north or south of bomb
hitbox = j;
danger = true;
if (pos{j}(2) - b.Position(2))>0
direction = 'S';
elseif (pos{j}(2) - b.Position(2))<0
direction = 'N';
elseif (pos{j}(1) - b.Position(1))==0
safe = false;
end
end
end
if danger
%Check if there is something between bomb blast and player
placehit = pos{hitbox};
pos1 = Correction(placehit(2));
pos2 = Correction(placehit(2));
switch direction
case 'N'
obstype = obstacles{1}.getSym;
if (strcmp(obstype,'FS')||strcmp(obstype,'BR'))
if ~(obstacles{1}.Position>=[pos1 pos2])
safe = false;
end
elseif (strcmp(obstype,'ES'))
safe = false;
end
case 'S'
obstype = obstacles{2}.getSym;
if (strcmp(obstype,'FS')||strcmp(obstype,'BR'))
if ~(obstacles{2}.Position<=[pos1 pos2])
safe = false;
end
elseif (strcmp(obstype,'ES'))
safe = false;
end
case 'E'
obstype = obstacles{3}.getSym;
if (strcmp(obstype,'FS')||strcmp(obstype,'BR'))
if ~(obstacles{3}.Position>=[pos1 pos2])
safe = false;
end
elseif (strcmp(obstype,'ES'))
safe = false;
end
case 'W'
obstype = obstacles{4}.getSym;
if (strcmp(obstype,'FS')||strcmp(obstype,'BR'))
if ~(obstacles{4}.Position<=[pos1 pos2])
safe = false;
end
elseif (strcmp(obstype,'ES'))
safe = false;
end
end
end
end
function die(thisBomb)
thisBomb.explode();
end
function update(thisBomb)
thisBomb.Time = thisBomb.Time - 1;
if thisBomb.Time == 0
thisBomb.explode();
end
end
end
methods (Static)
function symbol = getSym()
symbol = 'BO';
end
end
end