From 7666fc9be0357bff0b9798aacbf6a3f6b59846d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miloslav=20=C4=8C=C3=AD=C5=BE?= Date: Mon, 21 Oct 2019 19:58:11 +0200 Subject: [PATCH] Start explosions --- assets.h | 23 ++++++- assets/effect_explosion.png | Bin 0 -> 981 bytes main.c | 120 +++++++++++++++++++++++++++--------- raycastlib.h | 16 +++-- settings.h | 9 ++- 5 files changed, 132 insertions(+), 36 deletions(-) create mode 100644 assets/effect_explosion.png diff --git a/assets.h b/assets.h index a99b505..558ea07 100644 --- a/assets.h +++ b/assets.h @@ -498,7 +498,28 @@ SFG_PROGRAM_MEMORY uint8_t SFG_monsterSprites[][SFG_TEXTURE_STORE_SIZE] = SFG_PROGRAM_MEMORY uint8_t SFG_effects[][SFG_TEXTURE_STORE_SIZE] = { - { // 0, fireball + { // 0, explostion +175,103,95,183,191,7,111,255,31,254,173,87,15,102,23,190,0,0,0,0,0,0,0,0,16,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,1,16,0,0,16,0,0,0,0,0,0,0,0,0,16,0,1,17,0,1,16,0,0,1,16, +0,17,0,0,0,17,0,17,17,16,17,0,0,1,17,0,0,17,17,16,0,1,18,34,50,17,17,0,1,17,17, +0,0,1,23,17,17,187,34,35,241,33,16,1,17,33,16,0,0,1,23,113,18,43,33,19,65,17,16, +17,18,49,16,0,0,1,17,115,146,34,17,115,65,17,17,17,51,17,0,0,0,0,17,19,57,42,17, +35,102,17,19,114,52,16,0,0,0,0,17,34,58,161,23,42,194,35,34,34,68,16,0,0,1,16,1, +34,35,33,18,157,194,50,35,51,65,17,17,0,0,17,18,34,18,19,217,38,85,109,212,68, +34,17,0,0,0,0,18,33,17,51,54,120,85,102,51,68,18,32,0,0,0,1,34,23,34,51,68,133, +85,86,51,65,50,35,16,0,1,17,18,33,68,54,72,85,85,86,99,67,18,33,17,16,17,17,19, +54,104,181,85,85,85,85,91,134,67,51,19,51,0,17,18,33,20,54,104,85,85,88,225,102, +99,35,51,48,0,0,17,33,19,36,69,85,85,88,22,98,41,35,48,0,0,0,0,19,51,52,88,83, +70,88,102,119,50,32,0,0,0,0,17,17,51,51,69,35,68,136,102,114,34,17,0,0,0,1,16,1, +18,52,66,116,68,104,129,18,34,17,16,0,0,0,0,17,114,51,55,68,68,54,102,114,35,16, +17,0,0,0,1,17,115,19,51,52,65,19,145,18,147,48,0,0,0,0,1,17,33,44,50,51,67,34, +169,51,35,49,0,0,0,0,17,18,34,49,50,35,202,34,42,35,114,51,0,0,0,1,17,50,49,17, +17,51,146,34,34,17,23,35,16,0,0,1,19,49,17,17,17,57,34,33,177,17,19,35,16,0,0, +17,17,17,16,1,1,19,17,1,16,1,19,50,48,0,0,17,17,0,0,17,1,19,17,0,16,0,17,17,49, +0,0,0,0,0,0,16,0,17,16,0,17,0,0,17,17,0,0,0,0,0,0,0,0,17,16,0,1,0,0,0,0,0,0,0,0, +0,0,0,0,1,0,0,0,0,0,0,0,0 + }, + { // 1, fireball 175,103,183,7,191,111,254,31,95,180,173,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,17,17,0,0,0,0,0, diff --git a/assets/effect_explosion.png b/assets/effect_explosion.png new file mode 100644 index 0000000000000000000000000000000000000000..3556569673e3b44bdac888d256fc21f88ebe9970 GIT binary patch literal 981 zcmV;`11kK9P)e zSad^gZEa<4bO1wgWnpw>WFU8GbZ8()Nlj2!fese{00TWqL_t(o!>yO0lA}NnhQFjD zR*poRK(364$OA+~oEQ;-SaBkc5HXK{$Ri+5A`nPK9sm&$x#9#8i9}r0o)`v($-r*1 zH&v+w7`p%d`|s|_qJf{{=uH=MDRwJp#mIe>uC+-fUC-49JOh z#sGZzbYCtcBoj`bV93wFeycyOp@hMC0^IU@FeV5W_$_|`Kv51rj5FKO(b=DH&yu}t z=MKvYZy6c`=EbWVJKt}iD5-W3UMweT58a6a+5s?IhP6`q$0i>eIg~Uz52XgMNuhDR z$)D&02?U3CYNaSuXT-_3Aksi=iW3cxSPg&;GaivIy=rgb{&sM9AJTB_qTJ+&Gl*=B zI6EoY=;y3E(Ynz);v8$h1&}GqENAO#0;o=skd%rDfxa)!(46!)0AUIu^;B6tBSO2* z9kthWOHdayCzFD<2Owx^cg-kPA=}dY4H0-sE{eM6YGC0i2OYR&y3acRHY$&BN(JHXJ?+~|7qQ3r zS<`RQ)Kiy-{b=@ChoMP2<*_jQwhcZn>ej&7R0BNGhR6_AYc zU+o}_Oxn{)0CqJ1h>L_!Wo4JqN->I3%5?yJCGhQ1bi zmDE35+P8t~kd%hp1Ed4t&X7-M!PM-w429=h8#h!}ATB8l`eTc(v?Dgn%_+sD*ZDpl zkecqd$$5DzMnK3a_>)rYEYV#wh@f~U!~!AI*ly=hm>P98|+kLBIuYf|l8M6!3zT8_$& zSdHgK_Nuj`;@LCeYBKr+*f5T|XGFpk#0>;Fb*2aykK|zE%n}1|Ex%BPrX9~6u?)q& zQghFNW{+*NONGA?O`UShb=*Z_J5e4n7xEs6(+}n~;Lh*8BP!2yy92Abed}&2I>+r$+Jevw+R)lkoANd#jfStv+{+`E9^iQmRi*lKmHb_8(00000NkvXXu0mjf Dubs3H literal 0 HcmV?d00001 diff --git a/main.c b/main.c index ef03d5c..91b414a 100755 --- a/main.c +++ b/main.c @@ -303,7 +303,9 @@ typedef struct typedef struct { uint8_t type; - uint8_t framesToLive; + uint8_t doubleFramesToLive; /**< This number times two (because 256 could be + too little at high FPS) says after how many + frames the projectile is destroyed. */ uint16_t position[3]; /**< Current position, stored as u16 to save space, as that is exactly enough to store position on 64x64 map. */ @@ -312,6 +314,16 @@ typedef struct #define SFG_MAX_PROJECTILES 12 +#define SFG_PROJECTILE_EXPLOSION 0 +#define SFG_PROJECTILE_FIREBALL 1 + +#define SFG_EXPLOSION_DURATION_DOUBLE_FRAMES \ + (SFG_EXPLOSION_DURATION / SFG_MS_PER_FRAME) + +#if SFG_EXPLOSION_DURATION_DOUBLE_FRAMES == 0 + #define SFG_EXPLOSION_DURATION_FRAMES 1 +#endif + /* GLOBAL VARIABLES =============================================================================== @@ -1136,6 +1148,27 @@ uint8_t SFG_createProjectile(SFG_ProjectileRecord projectile) return 1; } +void SFG_createExplosion(RCL_Unit x, RCL_Unit y, RCL_Unit z) +{ + SFG_LOG("creating explostion"); + + SFG_ProjectileRecord explostion; + + explostion.type = SFG_PROJECTILE_EXPLOSION; + + explostion.position[0] = x; + explostion.position[1] = y; + explostion.position[2] = z; + + explostion.direction[0] = 0; + explostion.direction[1] = 0; + explostion.direction[2] = 0; + + explostion.doubleFramesToLive = SFG_EXPLOSION_DURATION_DOUBLE_FRAMES; + + SFG_createProjectile(explostion); +} + /** Performs one game step (logic, physics), happening SFG_MS_PER_FRAME after previous frame. @@ -1166,12 +1199,11 @@ void SFG_gameStep() SFG_ProjectileRecord p; -p.type = 0; -p.framesToLive = 255; +p.type = SFG_PROJECTILE_FIREBALL; +p.doubleFramesToLive = 255; p.position[0] = SFG_player.camera.position.x; p.position[1] = SFG_player.camera.position.y; -p.position[2] = SFG_player.camera.height; - +p.position[2] = SFG_player.camera.height - 256; RCL_Vector2D dir = RCL_angleToDirection(SFG_player.camera.direction); @@ -1179,7 +1211,8 @@ p.direction[0] = (dir.x * SFG_ROCKER_MOVE_UNITS_PER_FRAME) / RCL_UNITS_PER_SQUAR p.direction[1] = (dir.y * SFG_ROCKER_MOVE_UNITS_PER_FRAME) / RCL_UNITS_PER_SQUARE; p.direction[2] = 0; -printf("%d\n",SFG_createProjectile(p)); +SFG_createProjectile(p); + } if (SFG_keyIsDown(SFG_KEY_A)) @@ -1367,6 +1400,10 @@ printf("%d\n",SFG_createProjectile(p)); // update projectiles: + uint8_t substractFrames = + (SFG_gameFrame - SFG_currentLevel.frameStart) & 0x01 ? 1 : 0; + // ^ only substract frames to live every other frame + for (int8_t i = 0; i < SFG_currentLevel.projectileRecordCount; ++i) { SFG_ProjectileRecord *p = &(SFG_currentLevel.projectileRecords[i]); @@ -1389,6 +1426,17 @@ printf("%d\n",SFG_createProjectile(p)); } } + if (p->doubleFramesToLive == 0) + { + collides = 1; + } + else if (SFG_floorHeightAt( + pos[0] / RCL_UNITS_PER_SQUARE,pos[1] / RCL_UNITS_PER_SQUARE) + >= pos[2]) + { + collides = 1; + } + if (collides) { SFG_LOG("projectile collides"); @@ -1402,6 +1450,9 @@ printf("%d\n",SFG_createProjectile(p)); SFG_currentLevel.projectileRecordCount--; i--; + + if (p->type == SFG_PROJECTILE_FIREBALL) + SFG_createExplosion(p->position[0],p->position[1],p->position[2]); } else { @@ -1409,6 +1460,8 @@ printf("%d\n",SFG_createProjectile(p)); p->position[1] = pos[1]; p->position[2] = pos[2]; } + + p->doubleFramesToLive -= substractFrames; } // handle door: @@ -1731,28 +1784,6 @@ void SFG_draw() // draw sprites: - - // projecile sprites: - - for (uint8_t i = 0; i < SFG_currentLevel.projectileRecordCount; ++i) - { - SFG_ProjectileRecord *proj = &(SFG_currentLevel.projectileRecords[i]); - - RCL_Vector2D worldPosition; - - worldPosition.x = proj->position[0]; - worldPosition.y = proj->position[1]; - - RCL_PixelInfo p = - RCL_mapToScreen(worldPosition,proj->position[2],SFG_player.camera); - - if (p.depth > 0) - SFG_drawScaledSprite(SFG_effects[0], - p.position.x * SFG_RAYCASTING_SUBSAMPLE,p.position.y, - RCL_perspectiveScale(SFG_GAME_RESOLUTION_Y,p.depth), - p.depth / (RCL_UNITS_PER_SQUARE * 2),p.depth); - } - // monster sprites: for (uint8_t i = 0; i < SFG_currentLevel.monsterRecordCount; ++i) { @@ -1809,6 +1840,39 @@ void SFG_draw() p.depth / (RCL_UNITS_PER_SQUARE * 2),p.depth); } + // projecile sprites: + + for (uint8_t i = 0; i < SFG_currentLevel.projectileRecordCount; ++i) + { + SFG_ProjectileRecord *proj = &(SFG_currentLevel.projectileRecords[i]); + + RCL_Vector2D worldPosition; + + worldPosition.x = proj->position[0]; + worldPosition.y = proj->position[1]; + + RCL_PixelInfo p = + RCL_mapToScreen(worldPosition,proj->position[2],SFG_player.camera); + + const uint8_t *s = + SFG_effects[proj->type == SFG_PROJECTILE_FIREBALL ? 1 : 0]; + + int16_t spriteSize = SFG_GAME_RESOLUTION_Y / 2; + + if (proj->type == SFG_PROJECTILE_EXPLOSION) + { + spriteSize = + (SFG_GAME_RESOLUTION_Y * (SFG_EXPLOSION_DURATION_DOUBLE_FRAMES - proj->doubleFramesToLive) ) / + SFG_EXPLOSION_DURATION_DOUBLE_FRAMES; + } + + if (p.depth > 0) + SFG_drawScaledSprite(s, + p.position.x * SFG_RAYCASTING_SUBSAMPLE,p.position.y, + RCL_perspectiveScale(spriteSize,p.depth), + p.depth / (RCL_UNITS_PER_SQUARE * 2),p.depth); + } + #if SFG_HEADBOB_ENABLED // substract head bob after rendering SFG_player.camera.height -= headBobOffset; diff --git a/raycastlib.h b/raycastlib.h index 26f5cbc..cd1d928 100644 --- a/raycastlib.h +++ b/raycastlib.h @@ -26,7 +26,7 @@ author: Miloslav "drummyfish" Ciz license: CC0 1.0 - version: 0.90 + version: 0.901 */ #include @@ -855,8 +855,11 @@ void RCL_castRayMultiHit(RCL_Ray ray, RCL_ArrayFunction arrayFunc, divided by leg B (length along the same axis). */ h.distance = - ((h.position.x - ray.start.x) * RCL_UNITS_PER_SQUARE * rayDirXRecip) - / RECIP_SCALE; + (((h.position.x - ray.start.x) / 4) * + RCL_UNITS_PER_SQUARE * rayDirXRecip) + / (RECIP_SCALE / 4); + + // ^ / 4 is here to prevent overflow #endif } else @@ -877,8 +880,11 @@ void RCL_castRayMultiHit(RCL_Ray ray, RCL_ArrayFunction arrayFunc, #if RCL_RECTILINEAR h.distance = - ((h.position.y - ray.start.y) * RCL_UNITS_PER_SQUARE * rayDirYRecip) - / RECIP_SCALE; + (((h.position.y - ray.start.y) / 4) * + RCL_UNITS_PER_SQUARE * rayDirYRecip) + / (RECIP_SCALE / 4); + + // ^ / 4 is here to prevent overflow #endif } diff --git a/settings.h b/settings.h index fe40179..9dca7ed 100644 --- a/settings.h +++ b/settings.h @@ -32,14 +32,14 @@ game to run at smaller resolution (with bigger pixels), do his using SFG_RESOLUTION_SCALEDOWN; */ -#define SFG_SCREEN_RESOLUTION_X 800 +#define SFG_SCREEN_RESOLUTION_X 1024 /** Height of the screen in pixels. Set this to ACTUAL resolution. If you want the game to run at smaller resolution (with bigger pixels), do his using SFG_RESOLUTION_SCALEDOWN; */ -#define SFG_SCREEN_RESOLUTION_Y 600 +#define SFG_SCREEN_RESOLUTION_Y 768 /** How many times the screen resolution will be divided (how many times a game @@ -125,4 +125,9 @@ */ #define SFG_CAMERA_MAX_SHEAR 1024 +/** + Duration in ms of the explosion animation. +*/ +#define SFG_EXPLOSION_DURATION 70 + #endif // guard