2 * nInvaders - a space invaders clone for ncurses
3 * Copyright (C) 2002-2003 Dettus
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 * homepage: http://ninvaders.sourceforge.net
20 * mailto: ninvaders-devel@lists.sourceforge.net
27 #include "nInvaders.h"
30 * initialize aliens attributes
36 // three different types of aliens [5], [10]
37 int level
[ALIENS_MAX_NUMBER_Y
][ALIENS_MAX_NUMBER_X
]={
38 {1,1,1,1,1,1,1,1,1,1},
39 {2,2,2,2,2,2,2,2,2,2},
40 {2,2,2,2,2,2,2,2,2,2},
41 {3,3,3,3,3,3,3,3,3,3},
45 aliensClear(aliens
.posX
, aliens
.posY
, aliens
.right
, aliens
.bottom
); // clear old position of aliens
47 // reset alien position
55 // copy level-array to enemy-array
56 for (i
=0;i
<ALIENS_MAX_NUMBER_X
;i
++) {
57 for (j
=0;j
<ALIENS_MAX_NUMBER_Y
;j
++) {
58 alienBlock
[j
][i
]=level
[j
][i
];
63 for (i
= 0; i
< ALIENS_MAX_MISSILES
; i
++) {
64 if (alienshotx
[i
] != 0) {
65 aliensMissileClear(alienshotx
[i
],alienshoty
[i
]); // clear old position
67 alienshotx
[i
] = 0; // start with zero values
68 alienshoty
[i
] = 0; // start with zero values
70 alienshotnum
= 1; // one missile at the same time
71 alienshotx
[0] = 5; // x position of first alienshot
72 alienshoty
[0] = 1; // y position of first alienshot
77 * initialize bunkers attributes
83 // set position of bunker sprites. user graphical char bunkerd for better visual overview
84 // and set according to this the bunker-array
85 char bunkerd
[BUNKERHEIGHT
][BUNKERWIDTH
+1] = {
87 " ##### ##### ##### ##### ",
88 " ####### ####### ####### ####### ",
89 " ## ## ## ## ## ## ## ## "
91 // 12345678901234567890123456789012345678901234567890123456789012345678901234567890
94 // copy graphical "bunkerd" to binary "bunker"
95 for (a
= 0; a
< BUNKERWIDTH
; a
++) {
96 for (b
= 0; b
< BUNKERHEIGHT
; b
++) {
97 if (bunkerd
[b
][a
] == '#')
104 // display bunkers sprite
105 bunkersDisplay(&bunker
[0][0]);
109 * move aliens and test if they've reached the
110 * bottom of the windows or the bunkers.
116 int fReachedPlayer
=0; // return value
119 aliensClear(aliens
.posX
, aliens
.posY
, aliens
.right
, aliens
.bottom
); // clear old position of aliens
121 aliens
.posX
= aliens
.posX
+ aliens
.speed
; // move aliens left/ right
123 // when aliens reached left or right screen-border
124 if (aliens
.posX
== (BUNKERWIDTH
+ BUNKERX
- 5 - aliens
.right
) || aliens
.posX
== (BUNKERX
+ aliens
.left
)) {
126 aliens
.posY
++; // move aliens downwards
128 // aliens reached player
129 if (aliens
.posY
== SCREENHEIGHT
- 2 - aliens
.bottom
) {
130 fReachedPlayer
= 1; // set return value
133 // aliens reached bunkers //funzt nicht ganz: todo
134 if (aliens
.posY
== BUNKERY
- aliens
.bottom
) {
136 for(cx
=0;cx
<BUNKERWIDTH
;cx
++) {
137 for(cy
=0;cy
<BUNKERHEIGHT
;cy
++) {
141 bunkersClear(); // clear bunkers sprites
144 aliens
.speed
= aliens
.speed
* (-1); // change direction of aliens' movements
147 aliensDisplay(aliens
.posX
, aliens
.posY
, aliens
.right
, aliens
.bottom
); // display aliens at new position
149 return fReachedPlayer
; // return if aliens reached player
154 * display alien animation, display remaining parts of aliens and bunker
161 // calculate left, right, bottom, lowest_ship
170 for (row
=0;row
<ALIENS_MAX_NUMBER_Y
*2;row
++) {
172 for (k
=0;k
<ALIENS_MAX_NUMBER_X
;k
++) {
173 if (alienBlock
[c
][k
] != 0) {
176 if (aliens
.left
==1 || -k
>aliens
.left
) {aliens
.left
=-k
;}
177 if (aliens
.right
==-1 || k
>aliens
.right
) {aliens
.right
=k
;}
178 if (aliens
.bottom
==-1 || c
>aliens
.bottom
) {aliens
.bottom
=c
;}
185 aliens
.bottom
=aliens
.bottom
*2; // every 2nd row is an empty row
186 aliens
.left
=aliens
.left
*3; // alien sprite is 3 chars wide
187 aliens
.right
=aliens
.right
*3; // alien sprite is 3 chars wide
189 // display remaining aliens with animation
190 aliensRefresh(level
, &alienBlock
[0][0]);
196 * move aliens' missiles and do player/bunker hit testing
197 * a zero value in alienshotx indicates that the appropriate missile is loaded, but not fired
199 int aliensMissileMove()
202 int fPlayerWasHit
= 0;
204 static int alienshot_counter
= 0;
207 // calculate threshold when next missile should be fired
208 // it is done here to save calculation time in for-instruction
209 shootThreshold
= (skill_level
* 8) * (shipnum
+ 2);
210 alienshot_counter
= alienshot_counter
+ 10 ;
212 // loop all possible missiles
213 for (i
= 0; i
< ALIENS_MAX_MISSILES
; i
++) {
215 // if the current missile is flying we should do movements
216 if (alienshotx
[i
] != 0) {
218 aliensMissileClear(alienshotx
[i
],alienshoty
[i
]); // clear old position
220 // if missile hit the bunkers
221 if (bunkersHitCheck(alienshotx
[i
], alienshoty
[i
]) == 1) {
222 alienshotx
[i
] = 0; // value of zero reloads missile
225 alienshoty
[i
]++; // move missile downwards
227 // check if player was hit by an alien missile
228 if (playerHitCheck(alienshotx
[i
], alienshoty
[i
]) == 1) {
229 alienshotx
[i
] = 0; // value of zero reloads missile
234 } else { // missile not launched yet
236 // start new missile if counter says so
237 if (alienshot_counter
> shootThreshold
&& shipnum
> 0) {// only shot if there's an alien left
238 alienshot_counter
= 0; // reset counter
239 tmp
= random() % ALIENS_MAX_NUMBER_X
; // randomly select one of the ...
240 while (lowest_ship
[tmp
] == -1) { // ...aliens at the bottom of ...
241 tmp
= random() % ALIENS_MAX_NUMBER_X
; // ...a column to launch missile
243 alienshoty
[i
]=aliens
.posY
+lowest_ship
[tmp
]; // set y position of missile
244 alienshotx
[i
]=aliens
.posX
+tmp
*3; // set x position of missile
248 // display missiles if still running or just launched; could have been modified in the above code
249 if (alienshotx
[i
] != 0) {
250 // if missile is out of battlefield
251 if (alienshoty
[i
] == SCREENHEIGHT
- 1) {
252 alienshotx
[i
] = 0; // reload missile
254 aliensMissileDisplay(alienshotx
[i
], alienshoty
[i
]); // display Missile at new position
261 return fPlayerWasHit
;
267 * check if missile hit an alien
269 int aliensHitCheck(int shotx
, int shoty
)
273 // if missile is within alien-rectangle
274 if (shotx
>= aliens
.posX
&& shotx
<= aliens
.posX
+ ALIENS_MAX_NUMBER_X
* 3 - 1
275 && shoty
>= aliens
.posY
&& shoty
<= aliens
.posY
+ (ALIENS_MAX_NUMBER_Y
- 1) * 2) {
276 // calculate the ship that was hit
277 shipx
= (shotx
- aliens
.posX
) / 3;
278 shipy
= (shoty
- aliens
.posY
) / 2;
279 // if there is still a ship at this position
280 alienType
= alienBlock
[shipy
][shipx
];
281 if (alienType
!= 0) {
282 alienBlock
[shipy
][shipx
] = 0; // delete alien ship
285 return alienType
; // returns 0 if no alien was hit, else returns type-code of alien
289 * check if missile hit an element of bunker
291 int bunkersHitCheck(int shotx
, int shoty
)
294 int fBunkerWasHit
= 0;
295 // if missile is within bunker-rectangle
296 if (shotx
>= BUNKERX
&& shotx
< BUNKERX
+ BUNKERWIDTH
297 && shoty
>= BUNKERY
&& shoty
< BUNKERY
+ BUNKERHEIGHT
) {
298 // calculate the element of the bunker that was hit
299 adjy
= shoty
- BUNKERY
;
300 adjx
= shotx
- BUNKERX
;
301 // if there is still an element
302 if(bunker
[adjy
][adjx
] == 1){
303 bunker
[adjy
][adjx
] = 0; // delete element
304 fBunkerWasHit
= 1; // bunker was hit!
307 return fBunkerWasHit
;
This page took 0.411324 seconds and 4 git commands to generate.