bullets are go
							
								
								
									
										
											BIN
										
									
								
								res/bullets/bigblue.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 3 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								res/bullets/biggreen.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 3 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								res/bullets/bigpink.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 3 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								res/bullets/bigred.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 3 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								res/bullets/bigwhite.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 2.9 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								res/bullets/bigyellow.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 3 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								res/bullets/smallblue.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 2.8 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								res/bullets/smallgreen.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 2.8 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								res/bullets/smallpink.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 2.8 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								res/bullets/smallred.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 2.8 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								res/bullets/smallwhite.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 2.8 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								res/bullets/smallyellow.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 2.8 KiB  | 
| 
						 | 
				
			
			@ -5,3 +5,16 @@ IMAGE bgCeil1 "bg/ceil1.png" FAST
 | 
			
		|||
IMAGE bgFloor1 "bg/floor1.png" FAST
 | 
			
		||||
 | 
			
		||||
SPRITE nitori "player/nitori.png" 4 4 FAST
 | 
			
		||||
 | 
			
		||||
SPRITE smallRedBullet "bullets/smallred.png" 1 1 FAST 5
 | 
			
		||||
SPRITE smallBlueBullet "bullets/smallblue.png" 1 1 FAST 5
 | 
			
		||||
SPRITE smallGreenBullet "bullets/smallgreen.png" 1 1 FAST 5
 | 
			
		||||
SPRITE smallPinkBullet "bullets/smallpink.png" 1 1 FAST 5
 | 
			
		||||
SPRITE smallYellowBullet "bullets/smallyellow.png" 1 1 FAST 5
 | 
			
		||||
SPRITE smallWhiteBullet "bullets/smallwhite.png" 1 1 FAST 5
 | 
			
		||||
SPRITE bigRedBullet "bullets/bigred.png" 2 2 FAST 5
 | 
			
		||||
SPRITE bigBlueBullet "bullets/bigblue.png" 2 2 FAST 5
 | 
			
		||||
SPRITE bigGreenBullet "bullets/biggreen.png" 2 2 FAST 5
 | 
			
		||||
SPRITE bigPinkBullet "bullets/bigpink.png" 2 2 FAST 5
 | 
			
		||||
SPRITE bigYellowBullet "bullets/bigyellow.png" 2 2 FAST 5
 | 
			
		||||
SPRITE bigWhiteBullet "bullets/bigwhite.png" 2 2 FAST 5
 | 
			
		||||
							
								
								
									
										124
									
								
								src/bullets.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
				
			
			@ -0,0 +1,124 @@
 | 
			
		|||
// bullets
 | 
			
		||||
 | 
			
		||||
#define BULLET_COUNT 64
 | 
			
		||||
 | 
			
		||||
struct bullet {
 | 
			
		||||
	bool active, player;
 | 
			
		||||
	fix16 speed;
 | 
			
		||||
	fix32 dist;
 | 
			
		||||
	Vect2D_f16 pos, vel;
 | 
			
		||||
	s16 angle, clock;
 | 
			
		||||
	Sprite* image;
 | 
			
		||||
	bool dead, big;
 | 
			
		||||
	void (*updater)(s16);
 | 
			
		||||
	bool bools[COUNT_INT];
 | 
			
		||||
	s16 ints[COUNT_INT];
 | 
			
		||||
	fix16 fixes[COUNT_INT];
 | 
			
		||||
};
 | 
			
		||||
struct bullet bullets[BULLET_COUNT];
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// lifecycle
 | 
			
		||||
 | 
			
		||||
#define BULLET_OFF 4
 | 
			
		||||
#define BULLET_OFF_BIG 8
 | 
			
		||||
 | 
			
		||||
#define BULLET_DIST FIX32(4)
 | 
			
		||||
#define BULLET_DIST_BIG FIX32(8)
 | 
			
		||||
 | 
			
		||||
void spawnBullet(struct bulletSpawner spawner, void(*updater)){
 | 
			
		||||
	s16 i = -1;
 | 
			
		||||
	for(s16 j = 0; j < BULLET_COUNT; j++) if(!bullets[j].active && i == -1) i = j;
 | 
			
		||||
	if(i > -1 && (spawner.player || (player.invincibleClock < INVINCIBLE_LIMIT))){
 | 
			
		||||
		bullets[i].active = TRUE;
 | 
			
		||||
		bullets[i].pos.x = spawner.x;
 | 
			
		||||
		bullets[i].pos.y = spawner.y;
 | 
			
		||||
		bullets[i].dist = fix16ToFix32(spawner.big ? BULLET_DIST_BIG : BULLET_DIST);
 | 
			
		||||
		bullets[i].speed = spawner.speed;
 | 
			
		||||
		bullets[i].angle = spawner.angle;
 | 
			
		||||
		bullets[i].player = spawner.player;
 | 
			
		||||
		bullets[i].clock = 0;
 | 
			
		||||
		bullets[i].dead = FALSE;
 | 
			
		||||
		bullets[i].big = spawner.big;
 | 
			
		||||
		for(u8 j = 0; j < COUNT_INT; j++){
 | 
			
		||||
			bullets[i].bools[j] = spawner.bools[j];
 | 
			
		||||
			bullets[i].ints[j] = spawner.ints[j];
 | 
			
		||||
			bullets[i].fixes[j] = spawner.fixes[j];
 | 
			
		||||
		}
 | 
			
		||||
		if(spawner.vel.x && spawner.vel.y){
 | 
			
		||||
			bullets[i].vel.x = spawner.vel.x;
 | 
			
		||||
			bullets[i].vel.y = spawner.vel.y;
 | 
			
		||||
			if(bullets[i].vel.x > 0 && !bullets[i].player) bullets[i].vel.x = -bullets[i].vel.x;
 | 
			
		||||
		} else {
 | 
			
		||||
			bullets[i].vel.x = fix16Mul(cosFix16(spawner.angle), spawner.speed);
 | 
			
		||||
			bullets[i].vel.y = fix16Mul(sinFix16(spawner.angle), spawner.speed);
 | 
			
		||||
		}
 | 
			
		||||
		bullets[i].updater = updater;
 | 
			
		||||
		bullets[i].image = SPR_addSprite(spawner.image,
 | 
			
		||||
			fix16ToInt(fix16Sub(bullets[i].pos.x, spawner.big ? BULLET_OFF_BIG : BULLET_OFF)),
 | 
			
		||||
			fix16ToInt(fix16Sub(bullets[i].pos.y,spawner.big ? BULLET_OFF_BIG : BULLET_OFF)),
 | 
			
		||||
			TILE_ATTR(PAL1, 0, 0, 0));
 | 
			
		||||
		// SPR_setDepth(bullets[i].image, 4);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void killBullet(s16 i){
 | 
			
		||||
	bullets[i].active = FALSE;
 | 
			
		||||
	SPR_releaseSprite(bullets[i].image);
 | 
			
		||||
	if(bullets[i].dead){
 | 
			
		||||
		// spawnExplosion(bullets[i].pos.x, bullets[i].pos.y, 0);
 | 
			
		||||
		bullets[i].dead = FALSE;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void updateBulletVel(s16 i){
 | 
			
		||||
	bullets[i].vel.x = fix16Mul(cosFix16(bullets[i].angle), bullets[i].speed);
 | 
			
		||||
	bullets[i].vel.y = fix16Mul(sinFix16(bullets[i].angle), bullets[i].speed);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// collision
 | 
			
		||||
 | 
			
		||||
#define BULLET_LIMIT FIX16(-BULLET_OFF)
 | 
			
		||||
#define BULLET_LIMIT_W FIX16(GAME_W + BULLET_OFF)
 | 
			
		||||
#define BULLET_LIMIT_H FIX16(GAME_H + BULLET_OFF)
 | 
			
		||||
 | 
			
		||||
#define BULLET_LIMIT_BIG FIX16(-BULLET_OFF_BIG)
 | 
			
		||||
#define BULLET_LIMIT_W_BIG FIX16(GAME_W + BULLET_OFF_BIG)
 | 
			
		||||
#define BULLET_LIMIT_H_BIG FIX16(GAME_H + BULLET_OFF_BIG)
 | 
			
		||||
 | 
			
		||||
static void collideBullet(s16 i){
 | 
			
		||||
	if(bullets[i].pos.x < (bullets[i].big ? BULLET_LIMIT_BIG : BULLET_LIMIT) ||
 | 
			
		||||
		bullets[i].pos.x > (bullets[i].big ? BULLET_LIMIT_W_BIG : BULLET_LIMIT_W) ||
 | 
			
		||||
		bullets[i].pos.y < (bullets[i].big ? BULLET_LIMIT_BIG : BULLET_LIMIT) ||
 | 
			
		||||
		bullets[i].pos.y > (bullets[i].big ? BULLET_LIMIT_H_BIG : BULLET_LIMIT_H)){
 | 
			
		||||
		killBullet(i);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// loop
 | 
			
		||||
 | 
			
		||||
static void updateBullet(s16 i){
 | 
			
		||||
	bullets[i].pos.x = fix16Add(bullets[i].pos.x, bullets[i].vel.x);
 | 
			
		||||
	bullets[i].pos.y = fix16Add(bullets[i].pos.y, bullets[i].vel.y);
 | 
			
		||||
	bullets[i].updater(i);
 | 
			
		||||
	collideBullet(i);
 | 
			
		||||
	SPR_setPosition(
 | 
			
		||||
		bullets[i].image,
 | 
			
		||||
		fix16ToInt(fix16Sub(bullets[i].pos.x, bullets[i].big ? BULLET_OFF_BIG : BULLET_OFF)),
 | 
			
		||||
		fix16ToInt(fix16Sub(bullets[i].pos.y, bullets[i].big ? BULLET_OFF_BIG : BULLET_OFF)));
 | 
			
		||||
	bullets[i].clock++;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void updateBullets(){
 | 
			
		||||
	if(killBullets){
 | 
			
		||||
		for(s16 i = 0; i < BULLET_COUNT; i++) if(bullets[i].active){
 | 
			
		||||
			if(i % 4 == 0) bullets[i].dead = TRUE;
 | 
			
		||||
			killBullet(i);
 | 
			
		||||
		}
 | 
			
		||||
		killBullets = FALSE;
 | 
			
		||||
	} else {
 | 
			
		||||
		for(s16 i = 0; i < BULLET_COUNT; i++) if(bullets[i].active) updateBullet(i);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										19
									
								
								src/global.h
									
										
									
									
									
								
							
							
						
						| 
						 | 
				
			
			@ -19,8 +19,27 @@
 | 
			
		|||
#define GAME_Y 0
 | 
			
		||||
 | 
			
		||||
#define CLOCK_LIMIT 32000
 | 
			
		||||
#define COUNT_INT 8
 | 
			
		||||
 | 
			
		||||
bool killBullets;
 | 
			
		||||
 | 
			
		||||
s16 clock;
 | 
			
		||||
 | 
			
		||||
u32 score,
 | 
			
		||||
	highScore;
 | 
			
		||||
 | 
			
		||||
void EMPTY(s16 i){}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// structs
 | 
			
		||||
 | 
			
		||||
struct bulletSpawner {
 | 
			
		||||
	fix16 x, y, speed;
 | 
			
		||||
	Vect2D_f16 vel;
 | 
			
		||||
	s16 angle;
 | 
			
		||||
	Sprite* image;
 | 
			
		||||
	bool big, player;
 | 
			
		||||
	bool bools[COUNT_INT];
 | 
			
		||||
	s16 ints[COUNT_INT];
 | 
			
		||||
	fix16 fixes[COUNT_INT];
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -7,6 +7,7 @@
 | 
			
		|||
#include "controls.h"
 | 
			
		||||
#include "background.h"
 | 
			
		||||
#include "player.h"
 | 
			
		||||
#include "bullets.h"
 | 
			
		||||
#include "chrome.h"
 | 
			
		||||
 | 
			
		||||
// game loop
 | 
			
		||||
| 
						 | 
				
			
			@ -30,6 +31,7 @@ static void loadGame(){
 | 
			
		|||
 | 
			
		||||
static void updateGame(){
 | 
			
		||||
	updatePlayer();
 | 
			
		||||
	updateBullets();
 | 
			
		||||
	updateBg();
 | 
			
		||||
	updateChrome();
 | 
			
		||||
	clock++;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										39
									
								
								src/player.h
									
										
									
									
									
								
							
							
						
						| 
						 | 
				
			
			@ -4,10 +4,13 @@
 | 
			
		|||
#define PLAYER_INIT_X FIX16(40)
 | 
			
		||||
#define PLAYER_INIT_Y FIX16(GAME_H / 2)
 | 
			
		||||
 | 
			
		||||
#define INVINCIBLE_LIMIT 60 * 4
 | 
			
		||||
#define SHOT_INTERVAL 15
 | 
			
		||||
 | 
			
		||||
struct playerStruct {
 | 
			
		||||
	Vect2D_f16 pos, vel;
 | 
			
		||||
	Sprite* image;
 | 
			
		||||
	s16 clock;
 | 
			
		||||
	s16 clock, invincibleClock, shotClock;
 | 
			
		||||
};
 | 
			
		||||
struct playerStruct player;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -17,6 +20,7 @@ struct playerStruct player;
 | 
			
		|||
static void spawnPlayer(){
 | 
			
		||||
	player.pos.x = PLAYER_INIT_X;
 | 
			
		||||
	player.pos.y = PLAYER_INIT_Y;
 | 
			
		||||
	player.shotClock = SHOT_INTERVAL;
 | 
			
		||||
	player.image = SPR_addSprite(&nitori,
 | 
			
		||||
		fix16ToInt(fix16Sub(player.pos.x, PLAYER_OFF)),
 | 
			
		||||
		fix16ToInt(fix16Sub(player.pos.y, PLAYER_OFF)),
 | 
			
		||||
| 
						 | 
				
			
			@ -40,8 +44,8 @@ static void checkPlayerBounds(){
 | 
			
		|||
 | 
			
		||||
// movement
 | 
			
		||||
 | 
			
		||||
#define PLAYER_SPEED FIX16(2.25)
 | 
			
		||||
#define PLAYER_SPEED_NORM FIX16(2.25 * 0.707)
 | 
			
		||||
#define PLAYER_SPEED FIX16(2.5)
 | 
			
		||||
#define PLAYER_SPEED_NORM FIX16(2.5 * 0.707)
 | 
			
		||||
 | 
			
		||||
s16 playerFrame;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -74,6 +78,34 @@ static void movePlayer(){
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// shooting
 | 
			
		||||
 | 
			
		||||
// shoot
 | 
			
		||||
 | 
			
		||||
#define PLAYER_BULLET_SPEED FIX16(16)
 | 
			
		||||
#define PLAYER_BULLET_ANGLE 0
 | 
			
		||||
 | 
			
		||||
static void spawnPlayerBullet(){
 | 
			
		||||
	struct bulletSpawner spawner = {
 | 
			
		||||
		.x = player.pos.x,
 | 
			
		||||
		.y = player.pos.y,
 | 
			
		||||
		.image = &smallWhiteBullet,
 | 
			
		||||
		.speed = PLAYER_BULLET_SPEED,
 | 
			
		||||
		.angle = PLAYER_BULLET_ANGLE,
 | 
			
		||||
		.player = TRUE
 | 
			
		||||
	};
 | 
			
		||||
	spawnBullet(spawner, EMPTY);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void shotPlayer(){
 | 
			
		||||
	if(player.shotClock >= SHOT_INTERVAL && ctrl.a) player.shotClock = 0;
 | 
			
		||||
	if(player.shotClock == 0) spawnPlayerBullet();
 | 
			
		||||
	player.shotClock++;
 | 
			
		||||
	if(player.shotClock >= CLOCK_LIMIT) player.shotClock = SHOT_INTERVAL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// loop
 | 
			
		||||
 | 
			
		||||
void loadPlayer(){
 | 
			
		||||
| 
						 | 
				
			
			@ -82,6 +114,7 @@ void loadPlayer(){
 | 
			
		|||
 | 
			
		||||
void updatePlayer(){
 | 
			
		||||
	movePlayer();
 | 
			
		||||
	shotPlayer();
 | 
			
		||||
	SPR_setPosition(player.image,
 | 
			
		||||
		fix16ToInt(fix16Sub(player.pos.x, PLAYER_OFF)),
 | 
			
		||||
		fix16ToInt(fix16Sub(player.pos.y, PLAYER_OFF)));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||