SlideLaser.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472
  1. //
  2. // Sliding laser.
  3. // The idea here is to have a player slide a laser below a enemy or enemy weapon. When the laser
  4. // stops sliding a laser is shot upwards and it should destroy the threat.
  5. //
  6. // Going on a break.. Maybe I will expand and make it more playable later.
  7. //
  8. //
  9. #include "raylib.h"
  10. #include <math.h>
  11. #define MAX_SLIDEBOMBS 10
  12. #define MAX_CEILTURRETS 10
  13. #define MAX_BULLETS 64
  14. #define MAX_EFFECT 1000
  15. int myMap[10][11] = { {1,1,1,1,1,1,1,1,1,1,1},
  16. {1,1,1,1,1,1,1,1,1,1,1},
  17. {1,1,1,1,1,1,1,1,1,1,1},
  18. {1,1,1,1,1,1,1,1,1,1,1},
  19. {1,1,1,0,0,0,0,1,1,1,1},
  20. {1,1,1,0,0,0,0,1,0,0,1},
  21. {1,1,1,0,0,0,0,1,0,0,1},
  22. {1,1,1,0,0,0,0,1,0,0,1},
  23. {1,0,0,0,0,0,0,0,0,0,1},
  24. {1,1,1,1,1,1,1,1,1,1,1}
  25. };
  26. int mapWidth = 11;
  27. int mapHeight = 10;
  28. float tileWidth;
  29. float tileHeight;
  30. typedef struct player{
  31. bool active;
  32. Vector2 position;
  33. int direction; // -1 left, 2 - right
  34. int w;
  35. int h;
  36. int numslidelasers;
  37. }player;
  38. static player myplayer = {0};
  39. static struct effect2{
  40. bool active;
  41. Vector2 position;
  42. int startdelay;
  43. int radius;
  44. int countdown;
  45. }effect2;
  46. static struct effect2 arr_effect2[MAX_EFFECT];
  47. static struct effect{
  48. bool active;
  49. Vector2 position;
  50. Vector2 inc;
  51. Vector2 incmod;
  52. int w;
  53. int h;
  54. int countdown;
  55. }effect;
  56. static struct effect arr_effect[MAX_EFFECT];
  57. // design.
  58. // shoot x amount of rays into any direction to see if player is there.
  59. // if player is there than the bullet is shot.
  60. static struct bullet{
  61. bool active;
  62. Vector2 position;
  63. Vector2 inc;
  64. int radius;
  65. }bullet;
  66. static struct bullet arr_bullet[MAX_BULLETS];
  67. static struct ceilturret{
  68. bool active;
  69. Vector2 position;
  70. int w;
  71. int h;
  72. int shootdelay;
  73. }aiceilturret;
  74. static struct ceilturret arr_ceilturret[MAX_CEILTURRETS];
  75. static struct slidelaser{
  76. bool active;
  77. int state;
  78. Vector2 position;
  79. Vector2 inc;
  80. Vector2 incdec;
  81. int ceilingloc;
  82. int w;
  83. int h;
  84. }slidelaser;
  85. static struct slidelaser arr_slidelaser[MAX_SLIDEBOMBS];
  86. //Unit collide with solid blocks true/false
  87. bool recttilecollide(int x, int y, int w, int h, int offsetx,int offsety);
  88. // Our rectsoverlap function. Returns true/false.
  89. static bool rectsoverlap(int x1,int y1,int w1,int h1,int x2,int y2,int w2,int h2);
  90. void createeffect(int x, int y);
  91. int screenWidth;
  92. int screenHeight;
  93. int main(void)
  94. {
  95. // Initialization
  96. //--------------------------------------------------------------------------------------
  97. screenWidth = 800;
  98. screenHeight = 600;
  99. tileWidth = ceil((float)(float)screenWidth/(float)mapWidth);
  100. tileHeight = ceil((float)screenHeight/(float)mapHeight);
  101. InitWindow(screenWidth, screenHeight, "raylib example.");
  102. SetTargetFPS(60); // Set our game to run at 60 frames-per-second
  103. //--------------------------------------------------------------------------------------
  104. arr_slidelaser[0].active = false;
  105. arr_slidelaser[0].state = 0;
  106. arr_slidelaser[0].position = (Vector2){160,530};
  107. arr_slidelaser[0].w = 16;
  108. arr_slidelaser[0].h = 10;
  109. arr_slidelaser[0].inc.x = 3;
  110. arr_slidelaser[0].incdec.x = 0.02;
  111. myplayer.active = true;
  112. myplayer.w = 16;
  113. myplayer.h = 24;
  114. myplayer.position = (Vector2){100,516};
  115. myplayer.direction = 2;
  116. arr_ceilturret[0].active = true;
  117. arr_ceilturret[0].position.x=tileWidth*5;
  118. arr_ceilturret[0].position.y=tileHeight*4;
  119. arr_ceilturret[0].w = tileWidth/2;
  120. arr_ceilturret[0].h = tileHeight/2;
  121. // Main game loop
  122. while (!WindowShouldClose()) // Detect window close button or ESC key
  123. {
  124. // Update
  125. //----------------------------------------------------------------------------------
  126. // update the effect 2
  127. for(int i=0;i<MAX_EFFECT;i++){
  128. if(arr_effect2[i].active==false)continue;
  129. arr_effect2[i].countdown--;
  130. if(arr_effect2[i].countdown<0){
  131. arr_effect2[i].active=false;
  132. }
  133. }
  134. // update the effect
  135. for(int i=0;i<MAX_EFFECT;i++){
  136. if(arr_effect[i].active==true){
  137. // When exit the effect and disable
  138. Vector2 oldpos = arr_effect[i].position;
  139. arr_effect[i].countdown--;
  140. if(arr_effect[i].countdown<0)arr_effect[i].active=false;
  141. arr_effect[i].inc.y += arr_effect[i].incmod.y;
  142. if(arr_effect[i].inc.x<0){
  143. arr_effect[i].inc.x-=arr_effect[i].incmod.x;
  144. }else{
  145. arr_effect[i].inc.x+=arr_effect[i].incmod.x;;
  146. }
  147. arr_effect[i].position.x += arr_effect[i].inc.x;
  148. arr_effect[i].position.y += arr_effect[i].inc.y;
  149. if(recttilecollide(arr_effect[i].position.x,arr_effect[i].position.y,1,32,0,-1)){
  150. arr_effect[i].inc.y=-arr_effect[i].inc.y/4;
  151. }
  152. if(recttilecollide(arr_effect[i].position.x,arr_effect[i].position.y,1,6,0,0)){
  153. arr_effect[i].inc.x/=2;
  154. arr_effect[i].position = oldpos;
  155. }
  156. }
  157. }
  158. //Update the bullets
  159. for(int i=0;i<MAX_BULLETS;i++){
  160. if(arr_bullet[i].active==false)continue;
  161. for(int speed=0;speed<8;speed++){
  162. arr_bullet[i].position.x+=arr_bullet[i].inc.x;
  163. arr_bullet[i].position.y+=arr_bullet[i].inc.y;
  164. if(recttilecollide(arr_bullet[i].position.x,arr_bullet[i].position.y,6,6,0,0)){
  165. arr_bullet[i].active=false;
  166. }
  167. }
  168. }
  169. // update the turrets
  170. for(int i=0;i<MAX_CEILTURRETS;i++){
  171. if(arr_ceilturret[i].active==false)continue;
  172. arr_ceilturret[i].shootdelay-=1;
  173. if(arr_ceilturret[i].shootdelay>0)continue;
  174. int touch;//if collided with map count
  175. for(int a=0;a<10;a++){
  176. float angle=(float)GetRandomValue(0,6200)/100;
  177. Vector2 position = arr_ceilturret[i].position;
  178. for(int b=0;b<screenHeight;b++){
  179. position.x += cos(angle)*2;
  180. position.y += sin(angle)*2;
  181. if(recttilecollide(position.x,position.y,6,6,0,0))b=999999;
  182. if(rectsoverlap(position.x,position.y,6,6,myplayer.position.x,myplayer.position.y,myplayer.w,myplayer.h)){
  183. for(int free=0;free<MAX_BULLETS;free++){
  184. if(arr_ceilturret[i].shootdelay<0 && arr_bullet[free].active==false){
  185. arr_bullet[free].active=true;
  186. arr_bullet[free].radius = 6;
  187. arr_bullet[free].position = arr_ceilturret[i].position;
  188. arr_bullet[free].position.x+=GetRandomValue(0,10);
  189. arr_bullet[free].inc.x = cos(angle)*1;
  190. arr_bullet[free].inc.y = sin(angle)*1;
  191. arr_ceilturret[i].shootdelay = 20;
  192. }
  193. }
  194. }
  195. }
  196. }
  197. }
  198. // Update the slidelasers
  199. for(int i=0;i<MAX_SLIDEBOMBS;i++){
  200. if(arr_slidelaser[i].active==false)continue;
  201. if(arr_slidelaser[i].state==0){
  202. if(arr_slidelaser[i].inc.x>0){
  203. arr_slidelaser[i].inc.x-=arr_slidelaser[i].incdec.x;
  204. }else{
  205. arr_slidelaser[i].inc.x+=arr_slidelaser[i].incdec.x;
  206. }
  207. if((arr_slidelaser[i].inc.x>-0.2 && arr_slidelaser[i].inc.x<0.2) || recttilecollide(arr_slidelaser[i].position.x,arr_slidelaser[i].position.y,arr_slidelaser[i].w,arr_slidelaser[i].h,0,0)){
  208. arr_slidelaser[i].state = 1;
  209. arr_slidelaser[i].inc.x = 0;
  210. // find ceiling(top of the laser beam;)
  211. int ceilingloc;
  212. for(int y=arr_slidelaser[i].position.y;y>0;y--){
  213. if(recttilecollide(arr_slidelaser[i].position.x+4,y,1,1,0,0)){
  214. ceilingloc=y+1;
  215. break;
  216. }
  217. }
  218. arr_slidelaser[i].ceilingloc = ceilingloc;
  219. }
  220. arr_slidelaser[i].position.x+=arr_slidelaser[i].inc.x;
  221. }
  222. // If the laser cuts into the first! ceiling turret then remove it.
  223. if(arr_slidelaser[i].state==1){
  224. if(arr_slidelaser[i].active==true){
  225. if(rectsoverlap(arr_slidelaser[i].position.x,0,arr_slidelaser[i].w,10,arr_ceilturret[0].position.x-arr_ceilturret[0].w,0,arr_ceilturret[0].w*2,10)){
  226. if(arr_ceilturret[0].active)createeffect(arr_ceilturret[i].position.x,arr_ceilturret[i].position.y+tileHeight/4);
  227. arr_ceilturret[0].active=false;
  228. }
  229. }
  230. }
  231. }
  232. // Update the player..
  233. if(myplayer.active==true){
  234. Vector2 oldpos = myplayer.position;
  235. int fast=1;
  236. if(IsKeyDown(KEY_LEFT_SHIFT)){
  237. fast++;
  238. }
  239. if(IsKeyDown(KEY_RIGHT)){
  240. myplayer.position.x += fast;
  241. myplayer.direction = 2;
  242. }
  243. if(IsKeyDown(KEY_LEFT)){
  244. myplayer.position.x -= fast;
  245. myplayer.direction = 1;
  246. }
  247. if(recttilecollide(myplayer.position.x,myplayer.position.y,myplayer.w,myplayer.h,0,0)){
  248. myplayer.position = oldpos;
  249. }
  250. if(IsKeyPressed(KEY_Z)){ // Slide the laser weapon
  251. if(myplayer.numslidelasers<3){
  252. int cl=myplayer.numslidelasers; // current sliding laser number
  253. arr_slidelaser[cl].active = true;
  254. arr_slidelaser[cl].w = 16;
  255. arr_slidelaser[cl].h = 10;
  256. arr_slidelaser[cl].incdec.x = 0.02;
  257. arr_slidelaser[cl].state = 0;
  258. arr_slidelaser[cl].position.x = myplayer.position.x;
  259. arr_slidelaser[cl].position.y = myplayer.position.y+arr_slidelaser[0].h+4;
  260. if(myplayer.direction==1){
  261. arr_slidelaser[cl].inc.x = -1.5*fast;
  262. }else{
  263. arr_slidelaser[cl].inc.x = 1.5*fast;
  264. }
  265. myplayer.numslidelasers++;
  266. }
  267. }
  268. }
  269. //----------------------------------------------------------------------------------
  270. // Draw
  271. //----------------------------------------------------------------------------------
  272. BeginDrawing();
  273. ClearBackground(LIGHTGRAY);
  274. // Draw the turrets
  275. for(int i=0;i<MAX_CEILTURRETS;i++){
  276. if(arr_ceilturret[i].active==false)continue;
  277. DrawEllipse(arr_ceilturret[i].position.x,arr_ceilturret[i].position.y,arr_ceilturret[i].w,arr_ceilturret[i].h,WHITE);
  278. DrawEllipse(arr_ceilturret[i].position.x+4,arr_ceilturret[i].position.y,arr_ceilturret[i].w-4,arr_ceilturret[i].h,BLACK);
  279. DrawEllipse(arr_ceilturret[i].position.x+2,arr_ceilturret[i].position.y+2,arr_ceilturret[i].w-5,arr_ceilturret[i].h-4,YELLOW);
  280. }
  281. // Draw map
  282. for (int y = 0; y< mapHeight ; y++)
  283. {
  284. for (int x = 0; x< mapWidth ; x++)
  285. {
  286. if (myMap[y][x] == 1)
  287. {
  288. DrawRectangle(x*tileWidth,y*tileHeight,tileWidth,tileHeight,(Color){60,50,250,255});
  289. }
  290. }
  291. }
  292. // draw the player
  293. if(myplayer.active==true){
  294. DrawRectangle(myplayer.position.x,myplayer.position.y,myplayer.w,myplayer.h,GREEN);
  295. }
  296. // Draw the slidelasers
  297. for(int i=0;i<MAX_SLIDEBOMBS;i++){
  298. if(arr_slidelaser[i].active==false)continue;
  299. DrawRectangle(arr_slidelaser[i].position.x,arr_slidelaser[i].position.y,arr_slidelaser[i].w,arr_slidelaser[i].h,GRAY);
  300. if(arr_slidelaser[i].state==1){
  301. DrawRectangle(arr_slidelaser[i].position.x+3,arr_slidelaser[i].ceilingloc,arr_slidelaser[i].w-6,arr_slidelaser[i].position.y-arr_slidelaser[i].ceilingloc,YELLOW);
  302. }
  303. }
  304. // Draw the bullets
  305. for(int i=0;i<MAX_BULLETS;i++){
  306. if(arr_bullet[i].active==false)continue;
  307. DrawCircle(arr_bullet[i].position.x,arr_bullet[i].position.y,6,RED);
  308. }
  309. // draw the effect
  310. for(int i=0;i<MAX_EFFECT;i++){
  311. if(arr_effect[i].active==false)continue;
  312. DrawRectangle(arr_effect[i].position.x,arr_effect[i].position.y,arr_effect[i].w,arr_effect[i].h,RED);
  313. }
  314. // draw the effect2
  315. for(int i=0;i<MAX_EFFECT;i++){
  316. if(arr_effect2[i].active==false)continue;
  317. arr_effect2[i].startdelay--;
  318. if(arr_effect2[i].startdelay>0)continue;
  319. DrawCircle(arr_effect2[i].position.x,arr_effect2[i].position.y,arr_effect2[i].radius,WHITE);
  320. }
  321. // some screen info
  322. DrawText("Cursor Left and Right. Left Shift = Run. Z key is slide laser weapon.",2,2,22,WHITE);
  323. DrawText(FormatText("SlideLasers : %02i",3-myplayer.numslidelasers),2,screenHeight-32,26,WHITE);
  324. //DrawText(FormatText("SlideLasers : %f",PI*2.0f),312,screenHeight-32,26,WHITE);
  325. EndDrawing();
  326. //------------------------------- --------------------------------------------------
  327. }
  328. // De-Initialization
  329. //--------------------------------------------------------------------------------------
  330. CloseWindow(); // Close window and OpenGL context
  331. //--------------------------------------------------------------------------------------
  332. return 0;
  333. }
  334. void createeffect(int posx, int posy){
  335. //int posx = GetRandomValue(0,screenWidth);
  336. //int posy = GetRandomValue(0,screenHeight);
  337. for(int i=0;i<5;i++){
  338. if(arr_effect2[i].active==true)continue;
  339. arr_effect2[i].active = true;
  340. arr_effect2[i].position.x = posx+GetRandomValue(-32,32);
  341. arr_effect2[i].position.y = posy+GetRandomValue(-32,32);
  342. arr_effect2[i].startdelay = GetRandomValue(0,60);
  343. arr_effect2[i].countdown = 10+arr_effect2[i].startdelay;
  344. arr_effect2[i].radius = GetRandomValue(tileWidth/4,tileWidth);
  345. }
  346. int i=0;
  347. int cnt=0;
  348. while(cnt<32){
  349. i++;
  350. if(i>MAX_EFFECT){
  351. continue;
  352. cnt=51;
  353. }
  354. if(arr_effect[i].active==true){
  355. continue;
  356. }
  357. arr_effect[i].active = true;
  358. arr_effect[i].position.x = posx;
  359. arr_effect[i].position.y = posy;
  360. arr_effect[i].w = 16;
  361. arr_effect[i].h = 16;
  362. arr_effect[i].inc.x = GetRandomValue(-1,1);
  363. arr_effect[i].inc.y = GetRandomValue(-5,-2);
  364. arr_effect[i].incmod.x = (float)(GetRandomValue(0,100)/3500.0f);
  365. arr_effect[i].incmod.y = (float)(GetRandomValue(0,100)/1000.0f);//+0.1f;
  366. if(GetRandomValue(0,8)==1){
  367. arr_effect[i].incmod.x*=5;
  368. arr_effect[i].inc.y*=1.5;
  369. }
  370. if(GetRandomValue(0,8)==1){
  371. arr_effect[i].incmod.x*=5;
  372. arr_effect[i].inc.y/=2;
  373. }
  374. arr_effect[i].countdown = GetRandomValue(30,70);
  375. cnt++;
  376. }
  377. }
  378. //Unit collide with solid blocks true/false
  379. bool recttilecollide(int x, int y,int w, int h, int offsetx,int offsety){
  380. int cx = (x+offsetx)/tileWidth;
  381. int cy = (y+offsety)/tileHeight;
  382. for(int y2=cy-1; y2<cy+2;y2++){//Note that the - and + are to be set differently with differently sized players
  383. for(int x2=cx-1; x2<cx+2;x2++){
  384. if(x2>=0 && x2<mapWidth && y2>=0 && y2<mapHeight){
  385. if(myMap[y2][x2] == 1){
  386. int x3 = (x2)*tileWidth;
  387. int y3 = (y2)*tileHeight;
  388. if(rectsoverlap(x+offsetx,y+offsety,w,h,x3,y3,tileWidth,tileHeight)){
  389. return true;
  390. }
  391. }
  392. }
  393. }}
  394. return false;
  395. }
  396. // Rectangles overlap
  397. bool rectsoverlap(int x1,int y1,int w1,int h1,int x2,int y2,int w2,int h2){
  398. if(x1 >= (x2 + w2) || (x1 + w1) <= x2) return false;
  399. if(y1 >= (y2 + h2) || (y1 + h1) <= y2) return false;
  400. return true;
  401. }