now its a different game
After Width: | Height: | Size: 2.3 KiB |
BIN
res/bg/wall1.png
Before Width: | Height: | Size: 5.4 KiB |
After Width: | Height: | Size: 4.9 KiB |
Before Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 5.2 KiB |
After Width: | Height: | Size: 4.7 KiB |
After Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 5.8 KiB |
After Width: | Height: | Size: 5.8 KiB |
After Width: | Height: | Size: 5.8 KiB |
After Width: | Height: | Size: 5.8 KiB |
Before Width: | Height: | Size: 4.9 KiB |
Before Width: | Height: | Size: 4.9 KiB |
Before Width: | Height: | Size: 4.8 KiB |
Before Width: | Height: | Size: 4.8 KiB |
Before Width: | Height: | Size: 4.9 KiB |
Before Width: | Height: | Size: 4.9 KiB |
Before Width: | Height: | Size: 4.8 KiB |
Before Width: | Height: | Size: 4.8 KiB |
Before Width: | Height: | Size: 4.8 KiB |
Before Width: | Height: | Size: 4.8 KiB |
BIN
res/font.png
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 4.6 KiB |
After Width: | Height: | Size: 5.6 KiB |
|
@ -8,40 +8,20 @@ IMAGE frame "chrome/frame.png" FAST
|
|||
|
||||
// background
|
||||
|
||||
IMAGE wall1 "bg/wall1.png" FAST
|
||||
|
||||
|
||||
// foreground
|
||||
|
||||
IMAGE rock1Bottom "fg/rock1bottom.png" FAST
|
||||
IMAGE rock1Top "fg/rock1top.png" FAST
|
||||
|
||||
IMAGE obstacle1LeftBottom "fg/obstacle1leftbottom.png" FAST
|
||||
IMAGE obstacle1RightBottom "fg/obstacle1rightbottom.png" FAST
|
||||
IMAGE obstacle1MiddleBottom "fg/obstacle1middlebottom.png" FAST
|
||||
|
||||
IMAGE obstacle1LeftTop "fg/obstacle1lefttop.png" FAST
|
||||
IMAGE obstacle1RightTop "fg/obstacle1righttop.png" FAST
|
||||
IMAGE obstacle1MiddleTop "fg/obstacle1middletop.png" FAST
|
||||
|
||||
IMAGE rock2Bottom "fg/rock2bottom.png" FAST
|
||||
IMAGE rock2Top "fg/rock2top.png" FAST
|
||||
|
||||
IMAGE bg1 "bg/1.png" FAST
|
||||
|
||||
// player and enemies
|
||||
|
||||
SPRITE nitori "player/nitori.png" 4 4 FAST
|
||||
SPRITE fairy1 "enemies/fairy1.png" 5 4 FAST
|
||||
SPRITE sunny "player/sunny.png" 6 5 FAST 10
|
||||
SPRITE hitbox "player/hitbox.png" 1 1 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
|
||||
SPRITE fairyRed "enemies/fairyred.png" 4 4 FAST 10
|
||||
SPRITE fairyBlue "enemies/fairyblue.png" 4 4 FAST 10
|
||||
SPRITE fairyYellow "enemies/fairyyellow.png" 4 4 FAST 10
|
||||
SPRITE fairyGreen "enemies/fairygreen.png" 4 4 FAST 10
|
||||
|
||||
SPRITE smallBullet "bullets/small.png" 1 1 FAST 5
|
||||
SPRITE bigBullet "bullets/big.png" 2 2 FAST 5
|
||||
SPRITE hugeBullet "bullets/huge.png" 4 4 FAST 5
|
||||
|
||||
SPRITE playerBullet "bullets/player.png" 4 3 FAST 5
|
|
@ -2,48 +2,46 @@
|
|||
|
||||
#define BG_I 512
|
||||
|
||||
#define BG_W GAME_W_T + 8
|
||||
#define BG_H GAME_H_T
|
||||
#define BG_W 38
|
||||
#define BG_H 32
|
||||
|
||||
|
||||
// draw
|
||||
|
||||
|
||||
static void drawBg(){
|
||||
for(u16 x = 0; x < BG_W; x++) for(u16 y = 0; y < BG_H; y++){
|
||||
if(x % 8 == 0 && y % 8 == 0)
|
||||
VDP_drawImageEx(BG_A, &wall1, TILE_ATTR_FULL(PAL2, 0, 0, 0, BG_I), x, y, 0, DMA);
|
||||
if(x % 8 == 0 && y % 8 == 0){
|
||||
VDP_drawImageEx(BG_B, &bg1, TILE_ATTR_FULL(PAL1, 0, 0, 0, BG_I + 1), x - 4, y, 0, DMA);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// update
|
||||
|
||||
#define BG_SPEED FIX16(0.5)
|
||||
#define BG_SPEED_NORM FIX16(0.354)
|
||||
#define BG_SPEED FIX16(2)
|
||||
#define BG_SPEED_NORM FIX16(0.5 * NORM)
|
||||
|
||||
#define BG_SIZE 64
|
||||
#define BG_LIMIT FIX16(-256)
|
||||
|
||||
#define BG_SIZE_F FIX16(BG_SIZE)
|
||||
|
||||
s16 bgPosX[GAME_H_T];
|
||||
fix16 bgPosXF[GAME_H_T];
|
||||
s16 bgPos;
|
||||
fix16 bgPosF;
|
||||
|
||||
static void scrollBg(){
|
||||
for(u8 y = 0; y < GAME_H_T; y++){
|
||||
if(y > 2) bgPosXF[y] = fix16Sub(bgPosXF[y], BG_SPEED);
|
||||
if(bgPosXF[y] <= -BG_SIZE_F) bgPosXF[y] = fix16Add(bgPosXF[y], BG_SIZE_F);
|
||||
bgPosX[y] = fix16ToInt(bgPosXF[y]);
|
||||
}
|
||||
bgPosF = fix16Sub(bgPosF, BG_SPEED);
|
||||
if(bgPosF <= BG_LIMIT) bgPosF = fix16Sub(bgPosF, BG_LIMIT);
|
||||
bgPos = fix16ToInt(bgPosF);
|
||||
}
|
||||
|
||||
// loop
|
||||
|
||||
void loadBg(){
|
||||
VDP_setScrollingMode(HSCROLL_TILE, VSCROLL_PLANE);
|
||||
drawBg();
|
||||
}
|
||||
|
||||
void updateBg(){
|
||||
VDP_setHorizontalScrollTile(BG_A, 0, bgPosX, GAME_H_T, DMA);
|
||||
VDP_setVerticalScroll(BG_B, bgPos);
|
||||
scrollBg();
|
||||
}
|
|
@ -2,9 +2,13 @@
|
|||
|
||||
#define BULLET_OFF 4
|
||||
#define BULLET_OFF_BIG 8
|
||||
#define BULLET_OFF_HUGE 16
|
||||
#define BULLET_OFF_P_X 16
|
||||
#define BULLET_OFF_P_Y 12
|
||||
|
||||
#define BULLET_DIST FIX32(4)
|
||||
#define BULLET_DIST_BIG FIX32(8)
|
||||
#define BULLET_DIST_HUGE FIX32(16)
|
||||
|
||||
|
||||
// lifecycle
|
||||
|
@ -16,13 +20,14 @@ void spawnBullet(struct bulletSpawner spawner, void(*updater)){
|
|||
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].dist = fix16ToFix32(spawner.huge ? BULLET_DIST_HUGE : (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;
|
||||
bullets[i].huge = spawner.huge;
|
||||
for(u8 j = 0; j < COUNT_INT; j++){
|
||||
bullets[i].bools[j] = spawner.bools[j];
|
||||
bullets[i].ints[j] = spawner.ints[j];
|
||||
|
@ -31,17 +36,18 @@ void spawnBullet(struct bulletSpawner spawner, void(*updater)){
|
|||
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;
|
||||
if(bullets[i].vel.y < 0 && !bullets[i].player && bullets[i].pos.y < player.pos.y) bullets[i].vel.y = -bullets[i].vel.y;
|
||||
} 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)),
|
||||
fix16ToInt(fix16Sub(bullets[i].pos.x, FIX16(spawner.player ? BULLET_OFF_P_X : (spawner.huge ? BULLET_OFF_HUGE : (spawner.big ? BULLET_OFF_BIG : BULLET_OFF))))),
|
||||
fix16ToInt(fix16Sub(bullets[i].pos.y, FIX16(spawner.player ? BULLET_OFF_P_Y : (spawner.huge ? BULLET_OFF_HUGE : (spawner.big ? BULLET_OFF_BIG : BULLET_OFF))))),
|
||||
TILE_ATTR(PAL1, 0, 0, 0));
|
||||
// SPR_setDepth(bullets[i].image, 4);
|
||||
if(spawner.light) SPR_setAnim(bullets[i].image, 1);
|
||||
SPR_setDepth(bullets[i].image, spawner.top ? 3 : 4);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -62,19 +68,23 @@ void updateBulletVel(s16 i){
|
|||
|
||||
// collision
|
||||
|
||||
#define BULLET_LIMIT FIX16(-BULLET_OFF)
|
||||
#define BULLET_LIMIT FIX16(0 - 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_BIG FIX16(0 - 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)
|
||||
|
||||
#define BULLET_LIMIT_HUGE FIX16(0 - BULLET_OFF_HUGE)
|
||||
#define BULLET_LIMIT_W_HUGE FIX16(GAME_W + BULLET_OFF_HUGE)
|
||||
#define BULLET_LIMIT_H_HUGE FIX16(GAME_H + BULLET_OFF_HUGE)
|
||||
|
||||
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)){
|
||||
if(bullets[i].pos.x < (bullets[i].huge ? BULLET_LIMIT_HUGE : (bullets[i].big ? BULLET_LIMIT_BIG : BULLET_LIMIT)) ||
|
||||
bullets[i].pos.x > (bullets[i].huge ? BULLET_LIMIT_W_HUGE : (bullets[i].big ? BULLET_LIMIT_W_BIG : BULLET_LIMIT_W)) ||
|
||||
bullets[i].pos.y < (bullets[i].huge ? BULLET_LIMIT_HUGE : (bullets[i].big ? BULLET_LIMIT_BIG : BULLET_LIMIT)) ||
|
||||
bullets[i].pos.y > (bullets[i].huge ? BULLET_LIMIT_H_HUGE : (bullets[i].big ? BULLET_LIMIT_H_BIG : BULLET_LIMIT_H))){
|
||||
killBullet(i);
|
||||
}
|
||||
}
|
||||
|
@ -89,8 +99,8 @@ static void updateBullet(s16 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)));
|
||||
fix16ToInt(fix16Sub(bullets[i].pos.x, FIX16(bullets[i].player ? BULLET_OFF_P_X : (bullets[i].huge ? BULLET_OFF_HUGE : (bullets[i].big ? BULLET_OFF_BIG : BULLET_OFF))))),
|
||||
fix16ToInt(fix16Sub(bullets[i].pos.y, FIX16(bullets[i].player ? BULLET_OFF_P_Y : (bullets[i].huge ? BULLET_OFF_HUGE : (bullets[i].big ? BULLET_OFF_BIG : BULLET_OFF))))));
|
||||
bullets[i].clock++;
|
||||
}
|
||||
|
||||
|
|
46
src/chrome.h
|
@ -5,25 +5,21 @@
|
|||
// frame
|
||||
|
||||
static void loadFrame(){
|
||||
VDP_loadTileSet(frame.tileset, CHROME_I, DMA);
|
||||
VDP_fillTileMapRect(BG_A, TILE_ATTR_FULL(PAL2, 1, 0, 0, CHROME_I), 0, 0, GAME_W_T, 3);
|
||||
// VDP_loadTileSet(frame.tileset, CHROME_I, DMA);
|
||||
// VDP_fillTileMapRect(BG_A, TILE_ATTR_FULL(PAL2, 1, 0, 0, CHROME_I), 0, 0, GAME_W_T, 4);
|
||||
}
|
||||
|
||||
// score
|
||||
|
||||
#define SCORE_X 4
|
||||
#define SCORE_Y 2
|
||||
#define SCORE_LENGTH 8
|
||||
#define SCORE_X 1
|
||||
#define SCORE_Y 1
|
||||
#define SCORE_LENGTH 9
|
||||
|
||||
u32 lastScore;
|
||||
char scoreStr[SCORE_LENGTH];
|
||||
|
||||
static void loadScore(){
|
||||
VDP_drawText("HI", 1, 1);
|
||||
VDP_drawText("00000000", SCORE_X, 1);
|
||||
VDP_drawText("sc", 1, 2);
|
||||
intToStr(score, scoreStr, SCORE_LENGTH);
|
||||
VDP_drawText(scoreStr, SCORE_X, SCORE_Y);
|
||||
VDP_drawText("00000000", SCORE_X, SCORE_Y);
|
||||
}
|
||||
|
||||
// static void updateScore(){
|
||||
|
@ -36,37 +32,35 @@ static void loadScore(){
|
|||
// }
|
||||
|
||||
|
||||
// zone
|
||||
// time
|
||||
|
||||
#define ZONE_X 28
|
||||
#define ZONE_Y 1
|
||||
#define ZONE_LABEL_X 23
|
||||
#define TIME_Y 1
|
||||
#define TIME_X 27
|
||||
|
||||
static void loadZone(){
|
||||
VDP_drawText("ZONE", ZONE_LABEL_X, ZONE_Y);
|
||||
VDP_drawText("001", ZONE_X, ZONE_Y);
|
||||
static void loadTime(){
|
||||
VDP_drawText("1:58", TIME_X, TIME_Y);
|
||||
}
|
||||
|
||||
|
||||
// heat
|
||||
|
||||
#define HEAT_X 28
|
||||
#define HEAT_Y 2
|
||||
#define HEAT_LABEL_X 23
|
||||
#define RANK_X 28
|
||||
#define RANK_Y 2
|
||||
#define RANK_LABEL_X 25
|
||||
|
||||
static void loadHeat(){
|
||||
VDP_drawText("heat", HEAT_LABEL_X, HEAT_Y);
|
||||
VDP_drawText("100", HEAT_X, HEAT_Y);
|
||||
static void loadRank(){
|
||||
// VDP_drawText("RANK 1", RANK_LABEL_X, RANK_Y);
|
||||
// VDP_drawText("100", RANK_X, HEAT_Y);
|
||||
}
|
||||
|
||||
|
||||
// loop
|
||||
|
||||
void loadChrome(){
|
||||
loadFrame();
|
||||
// loadFrame();
|
||||
loadScore();
|
||||
loadZone();
|
||||
loadHeat();
|
||||
loadTime();
|
||||
// loadRank();
|
||||
}
|
||||
|
||||
void updateChrome(){
|
||||
|
|
|
@ -68,7 +68,7 @@ static void updateEnemy(s16 i){
|
|||
killEnemy(i);
|
||||
enemies[i].suicide(i);
|
||||
} else {
|
||||
if(!enemies[i].seen && enemies[i].pos.x <= fix16Add(FIX16(GAME_W), enemies[i].off.x)){
|
||||
if(!enemies[i].seen && enemies[i].pos.y >= fix16Sub(0, enemies[i].off.y)){
|
||||
enemies[i].seen = TRUE;
|
||||
SPR_setVisibility(enemies[i].image, VISIBLE);
|
||||
}
|
||||
|
|
159
src/foreground.h
|
@ -1,159 +0,0 @@
|
|||
// foreground
|
||||
|
||||
#define FG_I 576
|
||||
#define FG_W 64
|
||||
#define OBSTACLE_COUNT 24
|
||||
|
||||
#define FG_SPEED FIX16(1.75)
|
||||
#define FG_SPEED_NORM FIX16(1.75 * 0.707)
|
||||
|
||||
struct obstacle {
|
||||
bool active, top;
|
||||
Vect2D_f16 pos, size;
|
||||
s16 startX;
|
||||
};
|
||||
struct obstacle obstacles[OBSTACLE_COUNT];
|
||||
|
||||
s16 currentFg;
|
||||
SpriteDefinition* currentTopImage;
|
||||
SpriteDefinition* currentBottomImage;
|
||||
|
||||
// draw
|
||||
|
||||
#define CEIL_Y 3
|
||||
#define FLOOR_Y 24
|
||||
|
||||
static void drawFg(){
|
||||
switch(currentFg){
|
||||
case 0:
|
||||
VDP_loadTileSet(rock1Top.tileset, FG_I, DMA);
|
||||
VDP_loadTileSet(rock1Bottom.tileset, FG_I + 16, DMA);
|
||||
break;
|
||||
case 1:
|
||||
VDP_loadTileSet(rock2Top.tileset, FG_I, DMA);
|
||||
VDP_loadTileSet(rock2Bottom.tileset, FG_I + 16, DMA);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
for(u16 x = 0; x < FG_W; x++){
|
||||
if(x % 4 == 0){
|
||||
for(s16 i = 0; i < 4; i++){
|
||||
for(s16 j = 0; j < 4; j++){
|
||||
VDP_setTileMapXY(BG_B, TILE_ATTR_FULL(PAL2, 1, 0, 0, FG_I + i + 4 * j), x + i, CEIL_Y + j);
|
||||
VDP_setTileMapXY(BG_B, TILE_ATTR_FULL(PAL2, 1, 0, 0, FG_I + 16 + i + 4 * j), x + i, FLOOR_Y + j);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// obstacle
|
||||
|
||||
#define OBS_CEIL_Y 3
|
||||
#define OBS_FLOOR_Y 20
|
||||
#define OBS_X 32
|
||||
|
||||
#define OBS_TOP_Y FIX16(56)
|
||||
#define OBS_BOTTOM_Y FIX16(160)
|
||||
|
||||
s16 fgPos, obsX;
|
||||
|
||||
#define OBS_I FG_I + 32
|
||||
|
||||
SpriteDefinition* obstacleImage;
|
||||
s16 obstacleI;
|
||||
|
||||
static void spawnObstacle(bool top, s16 offset, u8 type){
|
||||
s16 i = -1;
|
||||
for(s16 j = 0; j < OBSTACLE_COUNT; j++) if(!obstacles[j].active && i == -1) i = j;
|
||||
if(i > -1){
|
||||
// obsX = OBS_X;
|
||||
obsX = OBS_X + (fgPos != 0 ? (-fgPos / 8) : 0);
|
||||
obstacles[i].active = TRUE;
|
||||
obstacles[i].top = top;
|
||||
obstacles[i].pos.x = FIX16(256);
|
||||
obstacles[i].pos.y = top ? OBS_TOP_Y : OBS_BOTTOM_Y;
|
||||
obstacles[i].size.x = FIX16(32);
|
||||
obstacles[i].size.y = FIX16(32);
|
||||
if(offset){
|
||||
obstacles[i].pos.x = fix16Sub(obstacles[i].pos.x, FIX16(offset));
|
||||
obsX -= offset / 8;
|
||||
}
|
||||
obstacles[i].startX = obsX;
|
||||
switch(type){
|
||||
case 0: obstacleImage = top ? &obstacle1LeftTop : &obstacle1LeftBottom; break;
|
||||
case 1: obstacleImage = top ? &obstacle1MiddleTop : &obstacle1MiddleBottom; break;
|
||||
case 2: obstacleImage = top ? &obstacle1RightTop : &obstacle1RightBottom; break;
|
||||
}
|
||||
obstacleI = type * 32;
|
||||
if(top) obstacleI += 128;
|
||||
VDP_drawImageEx(BG_B, obstacleImage,
|
||||
TILE_ATTR_FULL(PAL2, 1, 0, 0, OBS_I + obstacleI),
|
||||
obsX, top ? OBS_CEIL_Y : OBS_FLOOR_Y, 0, DMA);
|
||||
}
|
||||
}
|
||||
|
||||
#define OBSTACLE_MOD FIX16(8)
|
||||
#define OBSTACLE_LIMIT_X FIX16(-64)
|
||||
|
||||
static void killObstacle(s16 i){
|
||||
obstacles[i].active = FALSE;
|
||||
VDP_clearTileMapRect(BG_B, obstacles[i].startX, obstacles[i].top ? OBS_CEIL_Y + 4 : OBS_FLOOR_Y, 4, 4);
|
||||
for(s16 h = 0; h < 4; h++){
|
||||
for(s16 j = 0; j < 4; j++){
|
||||
if(obstacles[i].top) VDP_setTileMapXY(BG_B, TILE_ATTR_FULL(PAL2, 1, 0, 0, FG_I + h + 4 * j), obstacles[i].startX + h, CEIL_Y + j);
|
||||
else VDP_setTileMapXY(BG_B, TILE_ATTR_FULL(PAL2, 1, 0, 0, FG_I + 16 + h + 4 * j), obstacles[i].startX + h, FLOOR_Y + j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void collideObstacle(s16 i){
|
||||
collideObstacleWithPlayer(i);
|
||||
}
|
||||
|
||||
static void updateObstacle(s16 i){
|
||||
obstacles[i].pos.x = fix16Sub(obstacles[i].pos.x, FG_SPEED);
|
||||
obstacles[i].pos.x <= OBSTACLE_LIMIT_X ? killObstacle(i) : collideObstacle(i);
|
||||
}
|
||||
|
||||
|
||||
// update
|
||||
|
||||
#define FG_SIZE 32
|
||||
#define FG_LIMIT FIX16(-512)
|
||||
|
||||
#define FG_SIZE_F 40
|
||||
|
||||
s16 fgPosX[GAME_H_T];
|
||||
fix16 fgPosXF[GAME_H_T];
|
||||
|
||||
static void scrollFg(){
|
||||
for(u8 y = 0; y < GAME_H_T; y++){
|
||||
if(y > 2){
|
||||
fgPosXF[y] = fix16Sub(fgPosXF[y], FG_SPEED);
|
||||
if(fgPosXF[y] <= FG_LIMIT) fgPosXF[y] = 0;
|
||||
fgPosX[y] = fix16ToInt(fgPosXF[y]);
|
||||
}
|
||||
}
|
||||
fgPos = fgPosX[3];
|
||||
}
|
||||
|
||||
void nextFg(){
|
||||
VDP_clearTileMapRect(BG_B, 0, OBS_CEIL_Y + 4, FG_W, 17);
|
||||
currentFg++;
|
||||
drawFg();
|
||||
}
|
||||
|
||||
|
||||
// loop
|
||||
|
||||
void loadFg(){
|
||||
drawFg();
|
||||
}
|
||||
|
||||
void updateFg(){
|
||||
VDP_setHorizontalScrollTile(BG_B, 0, fgPosX, GAME_H_T, DMA);
|
||||
scrollFg();
|
||||
for(s16 i = 0; i < OBSTACLE_COUNT; i++) if(obstacles[i].active) updateObstacle(i);
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
// globals
|
||||
|
||||
#define NORM 0.707
|
||||
|
||||
#define GAME_W_T 32
|
||||
#define GAME_H_T 28
|
||||
|
||||
|
|
10
src/main.c
|
@ -8,7 +8,7 @@
|
|||
#include "controls.h"
|
||||
#include "start.h"
|
||||
#include "background.h"
|
||||
#include "foreground.h"
|
||||
// #include "foreground.h"
|
||||
#include "bullets.h"
|
||||
#include "player.h"
|
||||
#include "enemies.h"
|
||||
|
@ -22,18 +22,15 @@ static void loadInternals(){
|
|||
JOY_init();
|
||||
JOY_setEventHandler(&updateControls);
|
||||
SPR_init(127, 0, 0);
|
||||
VDP_setPalette(PAL1, nitori.palette -> data);
|
||||
VDP_setPalette(PAL2, wall1.palette -> data);
|
||||
VDP_setPalette(PAL3, font.palette -> data);
|
||||
VDP_loadFont(font.tileset, DMA);
|
||||
VDP_setTextPalette(3);
|
||||
VDP_setPalette(PAL1, fairyYellow.palette -> data);
|
||||
VDP_setTextPalette(1);
|
||||
}
|
||||
|
||||
void loadGame(){
|
||||
started = TRUE;
|
||||
loadBg();
|
||||
loadChrome();
|
||||
loadFg();
|
||||
loadPlayer();
|
||||
}
|
||||
|
||||
|
@ -43,7 +40,6 @@ static void updateGame(){
|
|||
updateStage();
|
||||
updateBullets();
|
||||
updateBg();
|
||||
updateFg();
|
||||
updateChrome();
|
||||
clock++;
|
||||
if(clock >= CLOCK_LIMIT) clock -= CLOCK_LIMIT;
|
||||
|
|
79
src/player.h
|
@ -1,10 +1,13 @@
|
|||
// player
|
||||
|
||||
#define PLAYER_OFF FIX16(16)
|
||||
#define PLAYER_INIT_X FIX16(32)
|
||||
#define PLAYER_INIT_Y FIX16(124)
|
||||
#define PLAYER_OFF_X FIX16(24)
|
||||
#define PLAYER_OFF_Y FIX16(20)
|
||||
#define PLAYER_INIT_X FIX16(GAME_W / 2)
|
||||
#define PLAYER_INIT_Y FIX16(GAME_H - 40)
|
||||
|
||||
#define SHOT_INTERVAL 15
|
||||
#define HITBOX_OFF FIX16(4)
|
||||
|
||||
#define SHOT_INTERVAL 12
|
||||
|
||||
|
||||
// spawn
|
||||
|
@ -13,60 +16,43 @@ 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)),
|
||||
player.image = SPR_addSprite(&sunny,
|
||||
fix16ToInt(fix16Sub(player.pos.x, PLAYER_OFF_X)),
|
||||
fix16ToInt(fix16Sub(player.pos.y, PLAYER_OFF_Y)),
|
||||
TILE_ATTR(PAL1, 0, 0, 0));
|
||||
player.hitboxImage = SPR_addSprite(&hitbox,
|
||||
fix16ToInt(fix16Sub(player.pos.x, HITBOX_OFF)),
|
||||
fix16ToInt(fix16Sub(player.pos.y, HITBOX_OFF)),
|
||||
TILE_ATTR(PAL1, 0, 0, 0));
|
||||
SPR_setDepth(player.image, 6);
|
||||
SPR_setDepth(player.hitboxImage, 1);
|
||||
}
|
||||
|
||||
#define PLAYER_SPEED FIX16(2.5)
|
||||
#define PLAYER_SPEED_NORM FIX16(1.768)
|
||||
#define PLAYER_SPEED FIX16(3)
|
||||
#define PLAYER_SPEED_NORM FIX16(3 * NORM)
|
||||
|
||||
// collision
|
||||
|
||||
#define PLAYER_LIMIT_X FIX16(16)
|
||||
#define PLAYER_LIMIT_W FIX16(240)
|
||||
#define PLAYER_LIMIT_Y FIX16(16)
|
||||
#define PLAYER_LIMIT_H FIX16(208)
|
||||
|
||||
#define PLAYER_LIMIT_Y_HORI FIX16(72)
|
||||
#define PLAYER_LIMIT_H_HORI FIX16(176)
|
||||
#define PLAYER_LIMIT_X FIX16(0)
|
||||
#define PLAYER_LIMIT_W FIX16(GAME_W)
|
||||
#define PLAYER_LIMIT_Y FIX16(0)
|
||||
#define PLAYER_LIMIT_H FIX16(GAME_H)
|
||||
|
||||
static void checkPlayerBounds(){
|
||||
if(player.pos.x < PLAYER_LIMIT_X) player.pos.x = PLAYER_LIMIT_X;
|
||||
else if(player.pos.x > PLAYER_LIMIT_W) player.pos.x = PLAYER_LIMIT_W;
|
||||
if(player.pos.y < PLAYER_LIMIT_Y_HORI) player.pos.y = PLAYER_LIMIT_Y_HORI;
|
||||
else if(player.pos.y > PLAYER_LIMIT_H_HORI) player.pos.y = PLAYER_LIMIT_H_HORI;
|
||||
}
|
||||
|
||||
void collideObstacleWithPlayer(s16 i){
|
||||
if(
|
||||
obstacles[i].pos.x < fix16Add(player.pos.x, PLAYER_OFF) &&
|
||||
fix16Add(obstacles[i].pos.x, obstacles[i].size.x) > fix16Sub(player.pos.x, PLAYER_OFF) &&
|
||||
obstacles[i].pos.y < fix16Add(player.pos.y, PLAYER_OFF) &&
|
||||
fix16Add(obstacles[i].pos.y, obstacles[i].size.y) > fix16Sub(player.pos.y, PLAYER_OFF)
|
||||
){
|
||||
if(obstacles[i].pos.x > player.pos.x) player.pos.x = fix16Sub(fix16Sub(obstacles[i].pos.x, FG_SPEED), PLAYER_OFF);
|
||||
// else if(fix16Add(obstacles[i].pos.x, obstacles[i].size.x) > fix16Sub(player.pos.x, PLAYER_OFF)) player.pos.x = fix16Add(fix16Add(obstacles[i].pos.x, obstacles[i].size.x), PLAYER_OFF);
|
||||
else if(obstacles[i].pos.y > player.pos.y) player.pos.y = fix16Sub(obstacles[i].pos.y, PLAYER_OFF);
|
||||
else if(fix16Add(obstacles[i].pos.y, obstacles[i].size.y) > fix16Sub(player.pos.y, PLAYER_OFF)) player.pos.y = fix16Add(fix16Add(obstacles[i].pos.y, obstacles[i].size.y), PLAYER_OFF);
|
||||
checkPlayerBounds();
|
||||
}
|
||||
if(player.pos.y < PLAYER_LIMIT_Y) player.pos.y = PLAYER_LIMIT_Y;
|
||||
else if(player.pos.y > PLAYER_LIMIT_H) player.pos.y = PLAYER_LIMIT_H;
|
||||
}
|
||||
|
||||
// movement
|
||||
|
||||
|
||||
s16 playerFrame;
|
||||
|
||||
static void movePlayer(){
|
||||
playerFrame = 0;
|
||||
if(ctrl.left || ctrl.right || ctrl.up || ctrl.down){
|
||||
if(ctrl.left || ctrl.right){
|
||||
if(ctrl.up || ctrl.down){
|
||||
player.vel.x = ctrl.left ? -PLAYER_SPEED_NORM : PLAYER_SPEED_NORM;
|
||||
player.vel.y = ctrl.up ? -PLAYER_SPEED_NORM : PLAYER_SPEED_NORM;
|
||||
playerFrame = ctrl.up ? 2 : 1;
|
||||
} else {
|
||||
player.vel.x = ctrl.left ? -PLAYER_SPEED : PLAYER_SPEED;
|
||||
player.vel.y = 0;
|
||||
|
@ -74,17 +60,14 @@ static void movePlayer(){
|
|||
} else if(ctrl.up){
|
||||
player.vel.x = 0;
|
||||
player.vel.y = -PLAYER_SPEED;
|
||||
playerFrame = 2;
|
||||
} else if(ctrl.down){
|
||||
player.vel.x = 0;
|
||||
player.vel.y = PLAYER_SPEED;
|
||||
playerFrame = 1;
|
||||
}
|
||||
if(player.vel.x != 0) player.pos.x = fix16Add(player.pos.x, player.vel.x);
|
||||
if(player.vel.y != 0) player.pos.y = fix16Add(player.pos.y, player.vel.y);
|
||||
checkPlayerBounds();
|
||||
}
|
||||
SPR_setFrame(player.image, playerFrame);
|
||||
}
|
||||
|
||||
|
||||
|
@ -93,13 +76,14 @@ static void movePlayer(){
|
|||
// shoot
|
||||
|
||||
#define PLAYER_BULLET_SPEED FIX16(16)
|
||||
#define PLAYER_BULLET_ANGLE 0
|
||||
#define PLAYER_BULLET_ANGLE 768
|
||||
#define PLAYER_BULLET_OFF FIX16(8)
|
||||
|
||||
static void spawnPlayerBullet(){
|
||||
struct bulletSpawner spawner = {
|
||||
.x = player.pos.x,
|
||||
.y = player.pos.y,
|
||||
.image = &smallWhiteBullet,
|
||||
.y = fix16Sub(player.pos.y, PLAYER_BULLET_OFF),
|
||||
.image = &playerBullet,
|
||||
.speed = PLAYER_BULLET_SPEED,
|
||||
.angle = PLAYER_BULLET_ANGLE,
|
||||
.player = TRUE
|
||||
|
@ -126,8 +110,11 @@ void updatePlayer(){
|
|||
movePlayer();
|
||||
shotPlayer();
|
||||
SPR_setPosition(player.image,
|
||||
fix16ToInt(fix16Sub(player.pos.x, PLAYER_OFF)),
|
||||
fix16ToInt(fix16Sub(player.pos.y, PLAYER_OFF)));
|
||||
fix16ToInt(fix16Sub(player.pos.x, PLAYER_OFF_X)),
|
||||
fix16ToInt(fix16Sub(player.pos.y, PLAYER_OFF_Y)));
|
||||
SPR_setPosition(player.hitboxImage,
|
||||
fix16ToInt(fix16Sub(player.pos.x, HITBOX_OFF)),
|
||||
fix16ToInt(fix16Sub(player.pos.y, HITBOX_OFF)));
|
||||
player.clock++;
|
||||
if(player.clock >= CLOCK_LIMIT) player.clock -= CLOCK_LIMIT;
|
||||
}
|
403
src/stage.h
|
@ -1,94 +1,379 @@
|
|||
// stage
|
||||
|
||||
#define SPAWN_MID 124
|
||||
/*
|
||||
|
||||
sine from left
|
||||
sine from right
|
||||
big middle
|
||||
sine from left, big right
|
||||
sine from right, big left
|
||||
big middle
|
||||
swarm
|
||||
big from left and right
|
||||
swarm, big right
|
||||
swarm, big left
|
||||
|
||||
midboss
|
||||
|
||||
big from left and right
|
||||
big from right and left
|
||||
big from left, small formation
|
||||
big from right, small formation
|
||||
big from left, small formation
|
||||
big from right, small formation
|
||||
|
||||
midboss
|
||||
|
||||
final boss at 30 seconds left
|
||||
|
||||
*/
|
||||
|
||||
#define SPAWN_MID 128
|
||||
|
||||
|
||||
// groups
|
||||
|
||||
static void groupOne(s16 off, bool firesAll){
|
||||
static void waveSine(bool right){
|
||||
struct enemySpawner spawner = {
|
||||
.angle = 512,
|
||||
.speed = FIX16(1),
|
||||
.x = GAME_W + 20,
|
||||
.y = SPAWN_MID + off,
|
||||
.image = &fairy1,
|
||||
.offX = 20,
|
||||
.angle = 256,
|
||||
.speed = FIX16(0.8),
|
||||
.x = GAME_W / 5 * (right ? 3 : 2),
|
||||
.y = -16,
|
||||
.image = right ? &fairyRed : &fairyBlue,
|
||||
.offX = 16,
|
||||
.offY = 16
|
||||
};
|
||||
spawner.fixes[0] = FIX16(spawner.y);
|
||||
spawner.fixes[1] = FIX16(8);
|
||||
spawner.fixes[2] = FIX16(8);
|
||||
spawner.fixes[3] = FIX16(0.25);
|
||||
spawner.fixes[0] = FIX16(spawner.x);
|
||||
spawner.fixes[1] = FIX16(32);
|
||||
spawner.fixes[2] = FIX16(64);
|
||||
spawner.fixes[3] = FIX16(0.08);
|
||||
spawner.bools[0] = right;
|
||||
void updater(s16 i){
|
||||
enemies[i].pos.y = fix16Sub(enemies[i].fixes[0], fix16Mul(sinFix16(enemies[i].fixes[1]), enemies[i].fixes[2]));
|
||||
enemies[i].fixes[1] = fix16Add(enemies[i].fixes[1], enemies[i].fixes[3]);
|
||||
if(enemies[i].clock == 30 && enemies[i].bools[0]){
|
||||
enemies[i].pos.x = fix16Sub(enemies[i].fixes[0], fix16Mul(sinFix16(enemies[i].fixes[1]), enemies[i].fixes[2]));
|
||||
enemies[i].fixes[1] = enemies[i].bools[0] ? fix16Add(enemies[i].fixes[1], enemies[i].fixes[3]) : fix16Sub(enemies[i].fixes[1], enemies[i].fixes[3]);
|
||||
}
|
||||
spawnEnemy(spawner, updater, EMPTY);
|
||||
}
|
||||
|
||||
static void waveBig1(){
|
||||
struct enemySpawner spawner = {
|
||||
.angle = 256,
|
||||
.speed = FIX16(0.6),
|
||||
.x = GAME_W / 2,
|
||||
.y = -16,
|
||||
.image = &fairyGreen,
|
||||
.offX = 16,
|
||||
.offY = 16
|
||||
};
|
||||
void updater(s16 i){
|
||||
if(enemies[i].clock == 60){
|
||||
struct bulletSpawner spawner = {
|
||||
.x = enemies[i].pos.x,
|
||||
.y = enemies[i].pos.y,
|
||||
.image = &bigBullet,
|
||||
.angle = 128,
|
||||
.speed = FIX16(1.5),
|
||||
.big = TRUE
|
||||
};
|
||||
for(u8 j = 0; j < 5; j++){
|
||||
spawnBullet(spawner, EMPTY);
|
||||
spawner.angle += 64;
|
||||
}
|
||||
}
|
||||
}
|
||||
spawnEnemy(spawner, updater, EMPTY);
|
||||
}
|
||||
|
||||
static void waveBig2(bool left){
|
||||
struct enemySpawner spawner = {
|
||||
.angle = 256,
|
||||
.speed = FIX16(0.6),
|
||||
.x = left ? GAME_W / 5 - 16 : GAME_W / 5 * 4 + 16,
|
||||
.y = -16,
|
||||
.image = left ? &fairyGreen : &fairyYellow,
|
||||
.offX = 16,
|
||||
.offY = 16
|
||||
};
|
||||
spawner.bools[0] = left;
|
||||
void updater(s16 i){
|
||||
if(enemies[i].clock >= 60 && enemies[i].clock < 180 && enemies[i].clock % 15 == 0){
|
||||
if(enemies[i].clock == 60){
|
||||
velPos.x = player.pos.x;
|
||||
velPos.y = player.pos.y;
|
||||
}
|
||||
struct bulletSpawner spawner = {
|
||||
.x = enemies[i].pos.x,
|
||||
.y = enemies[i].pos.y,
|
||||
.speed = FIX16(1.5),
|
||||
.image = &smallBullet,
|
||||
.light = enemies[i].clock % 30 == 0,
|
||||
.top = TRUE
|
||||
};
|
||||
spawner.vel = hone(enemies[i].pos, velPos, spawner.speed, 48);
|
||||
spawnBullet(spawner, EMPTY);
|
||||
} else if(enemies[i].bools[0] && enemies[i].clock == 61){
|
||||
struct bulletSpawner spawner = {
|
||||
.x = enemies[i].pos.x,
|
||||
.y = enemies[i].pos.y,
|
||||
.image = &bigBullet,
|
||||
.angle = 64,
|
||||
.speed = FIX16(1.25),
|
||||
.big = TRUE
|
||||
};
|
||||
for(u8 j = 0; j < 4; j++){
|
||||
spawnBullet(spawner, EMPTY);
|
||||
spawner.angle += 64;
|
||||
}
|
||||
}
|
||||
}
|
||||
spawnEnemy(spawner, updater, EMPTY);
|
||||
}
|
||||
|
||||
static void waveBig3(){
|
||||
struct enemySpawner spawner = {
|
||||
.angle = 256,
|
||||
.speed = FIX16(0.6),
|
||||
.x = GAME_W / 2,
|
||||
.y = -16,
|
||||
.image = &fairyGreen,
|
||||
.offX = 16,
|
||||
.offY = 16
|
||||
};
|
||||
void updater(s16 i){
|
||||
if(enemies[i].clock >= 30 && enemies[i].clock <= 90 && enemies[i].clock % 30 == 0){
|
||||
struct bulletSpawner spawner = {
|
||||
.x = enemies[i].pos.x,
|
||||
.y = enemies[i].pos.y,
|
||||
.image = &smallRedBullet,
|
||||
.angle = 512,
|
||||
.speed = FIX16(1.5)
|
||||
};
|
||||
spawner.vel = hone(enemies[i].pos, player.pos, spawner.speed, 0);
|
||||
if(enemies[i].clock == 60){
|
||||
spawner.image = &smallBullet;
|
||||
spawner.angle = 96;
|
||||
} else {
|
||||
spawner.image = &bigBullet;
|
||||
spawner.big = TRUE;
|
||||
spawner.angle = 128;
|
||||
}
|
||||
for(u8 j = 0; j < (enemies[i].clock == 60 ? 6 : 5); j++){
|
||||
spawnBullet(spawner, EMPTY);
|
||||
spawner.angle += 64;
|
||||
}
|
||||
}
|
||||
}
|
||||
spawnEnemy(spawner, updater, EMPTY);
|
||||
}
|
||||
|
||||
static void waveSwarm(bool right, bool color){
|
||||
struct enemySpawner spawner = {
|
||||
.angle = 256,
|
||||
.speed = FIX16(1.25),
|
||||
.x = random() % (GAME_W / 2 - 64),
|
||||
.y = -16,
|
||||
.image = color ? &fairyRed : &fairyBlue,
|
||||
.offX = 16,
|
||||
.offY = 16
|
||||
};
|
||||
spawner.x += right ? (GAME_W / 2) : 64;
|
||||
spawnEnemy(spawner, EMPTY, EMPTY);
|
||||
}
|
||||
|
||||
static void waveBig4(bool right, bool second){
|
||||
struct enemySpawner spawner = {
|
||||
.angle = 256,
|
||||
.speed = FIX16(0.6),
|
||||
.x = right ? (GAME_W / 4 * 3 + 24) : (GAME_W / 4 - 24),
|
||||
.y = -16,
|
||||
.image = right ? &fairyYellow : &fairyGreen,
|
||||
.offX = 16,
|
||||
.offY = 16
|
||||
};
|
||||
spawner.bools[0] = right;
|
||||
spawner.bools[1] = second;
|
||||
void updater(s16 i){
|
||||
if(enemies[i].clock == 40){
|
||||
struct bulletSpawner spawner = {
|
||||
.x = enemies[i].pos.x,
|
||||
.y = enemies[i].pos.y,
|
||||
.image = &bigBullet,
|
||||
.big = TRUE,
|
||||
.speed = FIX16(1.25),
|
||||
.angle = 32,
|
||||
.light = enemies[i].bools[0]
|
||||
};
|
||||
if(enemies[i].bools[0]) spawner.angle = 512 - spawner.angle;
|
||||
for(u8 j = 0; j < 5; j++){
|
||||
spawnBullet(spawner, EMPTY);
|
||||
spawner.angle += enemies[i].bools[0] ? -64 : 64;
|
||||
}
|
||||
} else if(enemies[i].clock >= 60 && enemies[i].clock < 150 && enemies[i].clock % 10 == 0 && enemies[i].bools[1]){
|
||||
struct bulletSpawner spawner = {
|
||||
.x = enemies[i].pos.x,
|
||||
.y = enemies[i].pos.y,
|
||||
.image = &smallBullet,
|
||||
.speed = FIX16(2),
|
||||
.light = !enemies[i].bools[0]
|
||||
};
|
||||
if(enemies[i].clock == 60){
|
||||
velPos = hone(enemies[i].pos, player.pos, spawner.speed, 0);
|
||||
enemies[i].fixes[0] = velPos.x;
|
||||
enemies[i].fixes[1] = velPos.y;
|
||||
}
|
||||
spawner.vel.x = enemies[i].fixes[0];
|
||||
spawner.vel.y = enemies[i].fixes[1];
|
||||
// spawner.vel = velPos;
|
||||
spawnBullet(spawner, EMPTY);
|
||||
}
|
||||
}
|
||||
for(u8 j = 0; j < 3; j++){
|
||||
spawner.bools[0] = j == 2 || firesAll;
|
||||
spawnEnemy(spawner, updater, EMPTY);
|
||||
spawner.x += 44;
|
||||
}
|
||||
spawnEnemy(spawner, updater, EMPTY);
|
||||
}
|
||||
|
||||
// bosses
|
||||
|
||||
static void waveMidboss1(){
|
||||
struct enemySpawner spawner = {
|
||||
.angle = 256,
|
||||
.speed = FIX16(1),
|
||||
.x = GAME_W / 2,
|
||||
.y = -16,
|
||||
.image = &fairyGreen,
|
||||
.offX = 16,
|
||||
.offY = 16
|
||||
};
|
||||
void updater(s16 i){
|
||||
if(enemies[i].bools[0]){
|
||||
|
||||
// ring
|
||||
if(enemies[i].clock % 90 == 0){
|
||||
struct bulletSpawner spawner = {
|
||||
.x = enemies[i].pos.x,
|
||||
.y = enemies[i].pos.y,
|
||||
.image = &bigBullet,
|
||||
.big = TRUE,
|
||||
.speed = FIX16(1),
|
||||
.angle = 80 + random() % 32,
|
||||
.light = TRUE
|
||||
};
|
||||
for(u8 j = 3; j < 15; j++){
|
||||
if(j % 3 < 2) spawnBullet(spawner, EMPTY);
|
||||
spawner.angle += 32;
|
||||
}
|
||||
}
|
||||
|
||||
// puke
|
||||
else if(enemies[i].clock % 20 == 0){
|
||||
struct bulletSpawner spawner = {
|
||||
.x = FIX16(enemies[i].clock % 180 < 90 ? 32 : GAME_W - 32),
|
||||
.y = FIX16(40),
|
||||
.image = &bigBullet,
|
||||
.big = TRUE,
|
||||
.speed = FIX16(1.75)
|
||||
};
|
||||
velPos.x = spawner.x;
|
||||
velPos.y = spawner.y;
|
||||
spawner.vel = hone(velPos, player.pos, spawner.speed, 32);
|
||||
spawnBullet(spawner, EMPTY);
|
||||
}
|
||||
|
||||
|
||||
} else if(!enemies[i].bools[0] && enemies[i].clock > 0 && enemies[i].clock % 30 == 0) {
|
||||
enemies[i].speed = fix16Sub(enemies[i].speed, FIX16(0.25));
|
||||
if(enemies[i].speed <= 0){
|
||||
enemies[i].speed = 0;
|
||||
enemies[i].bools[0] = TRUE;
|
||||
enemies[i].clock = -1;
|
||||
}
|
||||
updateEnemyVel(i);
|
||||
}
|
||||
}
|
||||
spawnEnemy(spawner, updater, EMPTY);
|
||||
}
|
||||
|
||||
// loop
|
||||
|
||||
#define OBS_INTERVAL 15
|
||||
|
||||
s16 stageClock,
|
||||
nextClock,
|
||||
currentWave;
|
||||
nextClock;
|
||||
|
||||
s16 currentWave = 42;
|
||||
|
||||
|
||||
static void updateWaves(){
|
||||
if(stageClock == nextClock){
|
||||
switch(currentWave){
|
||||
case 0:
|
||||
for(s16 i = 0; i < 6; i++)
|
||||
for(s16 j = 0; j < 2; j++) spawnObstacle(j == 0 ? TRUE : FALSE, 256 - i * 32, i == 5 ? 2 : 1);
|
||||
groupOne(0, FALSE);
|
||||
nextClock += 180;
|
||||
break;
|
||||
case 1:
|
||||
for(s16 i = 0; i < 6; i++)
|
||||
spawnObstacle(FALSE, 0 - i * 32, i == 0 ? 0 : (i == 5 ? 2 : 1));
|
||||
groupOne(-24, FALSE);
|
||||
nextClock += 180;
|
||||
break;
|
||||
case 2:
|
||||
for(s16 i = 0; i < 6; i++)
|
||||
spawnObstacle(TRUE, 0 - i * 32, i == 0 ? 0 : (i == 5 ? 2 : 1));
|
||||
groupOne(24, FALSE);
|
||||
nextClock += 180;
|
||||
break;
|
||||
case 3:
|
||||
groupOne(0, FALSE);
|
||||
nextClock += 180;
|
||||
break;
|
||||
case 4:
|
||||
nextFg();
|
||||
break;
|
||||
|
||||
|
||||
// sine from left
|
||||
if(currentWave < 6){
|
||||
waveSine(FALSE);
|
||||
nextClock += currentWave == 5 ? 90 : 40;
|
||||
}
|
||||
|
||||
// sine from right
|
||||
else if(currentWave < 12){
|
||||
waveSine(TRUE);
|
||||
nextClock += currentWave == 11 ? 90 : 40;
|
||||
}
|
||||
|
||||
// big middle
|
||||
else if(currentWave == 12){
|
||||
waveBig1();
|
||||
nextClock += 120;
|
||||
}
|
||||
|
||||
// sine from left, big right
|
||||
else if(currentWave < 18){
|
||||
waveSine(FALSE);
|
||||
if(currentWave == 14) waveBig2(FALSE);
|
||||
nextClock += currentWave == 17 ? 90 : 40;
|
||||
}
|
||||
|
||||
// sine from right, big left
|
||||
else if(currentWave < 24){
|
||||
waveSine(TRUE);
|
||||
if(currentWave == 20) waveBig2(TRUE);
|
||||
nextClock += currentWave == 23 ? 90 : 40;
|
||||
}
|
||||
|
||||
// big middle
|
||||
else if(currentWave == 24){
|
||||
waveBig3();
|
||||
nextClock += 180;
|
||||
}
|
||||
|
||||
// swarm (8)
|
||||
else if(currentWave < 32){
|
||||
waveSwarm(currentWave % 2 == 0, currentWave % 4 < 2);
|
||||
nextClock += 30;
|
||||
}
|
||||
|
||||
// big left and right
|
||||
else if(currentWave < 34){
|
||||
waveBig4(currentWave == 32, FALSE);
|
||||
nextClock += currentWave == 32 ? 60 : 120;
|
||||
}
|
||||
|
||||
// swarm (4), big right
|
||||
else if(currentWave < 38){
|
||||
waveSwarm(FALSE, currentWave % 2 < 1);
|
||||
if(currentWave == 35) waveBig4(TRUE, TRUE);
|
||||
nextClock += currentWave == 37 ? 60 : 30;
|
||||
}
|
||||
|
||||
// swarm (4), big left
|
||||
else if(currentWave < 42){
|
||||
waveSwarm(TRUE, currentWave % 2 < 1);
|
||||
if(currentWave == 39) waveBig4(FALSE, TRUE);
|
||||
nextClock += currentWave == 41 ? 60 : 30;
|
||||
}
|
||||
|
||||
else if(currentWave == 42){
|
||||
waveMidboss1();
|
||||
}
|
||||
|
||||
currentWave++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// case 0: groupOne(-32, FALSE); break;
|
||||
// case 180: groupOne(32, FALSE); break;
|
||||
// case 360: groupOne(0, TRUE); break;
|
||||
|
||||
|
||||
void updateStage(){
|
||||
updateWaves();
|
||||
stageClock++;
|
||||
|
|
|
@ -9,19 +9,18 @@ struct bulletSpawner {
|
|||
Vect2D_f16 vel;
|
||||
s16 angle;
|
||||
SpriteDefinition* image;
|
||||
bool big, player;
|
||||
bool big, player, huge, light, top;
|
||||
bool bools[COUNT_INT];
|
||||
s16 ints[COUNT_INT];
|
||||
fix16 fixes[COUNT_INT];
|
||||
};
|
||||
struct bullet {
|
||||
bool active, player;
|
||||
bool active, player, dead, big, huge;
|
||||
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];
|
||||
|
@ -35,6 +34,7 @@ struct bullet bullets[BULLET_COUNT];
|
|||
struct playerStruct {
|
||||
Vect2D_f16 pos, vel;
|
||||
Sprite* image;
|
||||
Sprite* hitboxImage;
|
||||
s16 clock, invincibleClock, shotClock;
|
||||
};
|
||||
struct playerStruct player;
|
||||
|
|