Advertisement
Redxone

[SDL2] WIP Spaceship Shmup!

Feb 16th, 2018
190
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.49 KB | None | 0 0
  1. // See the game here: https://imgur.com/a/wt4lO
  2.  
  3.  
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <stdbool.h>
  7. #include <math.h>
  8. #include <string.h>
  9.  
  10. #include <SDL2/SDL.h>
  11. #include <SDL2/SDL_image.h>
  12.  
  13. #define WINDOW_WIDTH 320
  14. #define WINDOW_HEIGHT 480
  15. #define FRAMERATE 60
  16.  
  17.  
  18. enum {
  19.     BT_FORWARD = 0x01,
  20.     BT_BACK    = 0x02,
  21.     BT_LEFT    = 0x04,
  22.     BT_RIGHT   = 0x08,
  23.     BT_FIRE    = 0x10,
  24. };
  25.  
  26. typedef struct
  27. {
  28.     int FORWARD;
  29.     int BACK;
  30.     int LEFT;
  31.     int RIGHT;
  32.     int SHOOT;
  33.  
  34. } InputButtons;
  35.  
  36. typedef enum {
  37.     GAME_RUNNING,
  38.     GAME_PAUSED,
  39. } States;
  40.  
  41. typedef struct
  42. {
  43.    SDL_Surface* surface;
  44.    SDL_Texture* texture;
  45.    SDL_Rect unit;
  46.    char* name;
  47. } Image;
  48.  
  49. typedef struct
  50. {
  51.     Image* sprite;
  52.     int width;
  53.     int height;
  54.     float xpos;
  55.     float ypos;
  56.     float speed;
  57.     float friction;
  58.     float xvel;
  59.     float yvel;
  60.     int image_index;
  61. } Player;
  62.  
  63. typedef struct
  64. {
  65.   Image* img;
  66.   SDL_Rect cam;
  67. } Background;
  68.  
  69. // Globals
  70.     static int GameState = GAME_RUNNING;
  71.     static uint8_t active_buttons = 0;
  72.     static Player* plr;
  73.     static InputButtons boundkeys;
  74.     static Background* levelbg;
  75.     static SDL_Window* win;
  76.     static SDL_Renderer* renderer;
  77.     static bool running = true;
  78.  
  79. // Declarations
  80.  
  81. Image* loadImage(SDL_Renderer*, char*, int, int);
  82. void freeImage(Image*);
  83. void drawImage(SDL_Renderer*, Image*);
  84. void drawSprite(SDL_Renderer*, Image*, int, int, int, int);
  85. void WindowHandler(SDL_Event* );
  86. void ButtonHandler(InputButtons*, SDL_Event* , uint8_t* );
  87. SDL_Keycode getKey(SDL_Event* );
  88. void Update();
  89. void Initalize();
  90.  
  91. int random_range(int, int);
  92.  
  93. // Game Loop
  94.  
  95. int main(int argc, char** argv)
  96. {
  97.  
  98.     if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) != 0)
  99.     {
  100.         printf("Video initialization failed :> %s\n",SDL_GetError());
  101.         return 1; // Return error code.
  102.     }
  103.  
  104.     // Create SDL window.
  105.     win = SDL_CreateWindow("My SDL Game",SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED,WINDOW_WIDTH,WINDOW_HEIGHT,0);
  106.     renderer = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
  107.     SDL_SetRenderDrawColor(renderer,0x00, 0x30, 0x30, 0xFF);
  108.  
  109.     // Init Objects
  110.     Initalize();
  111.  
  112.     Image* object = loadImage(renderer, "turrets.png", 0, 0);
  113.     object->unit.w = 30;
  114.     object->unit.h = 15;
  115.     object->unit.x = 536;
  116.     object->unit.y = 300;
  117.  
  118.     SDL_Event events;
  119.     uint32_t ticks_prev;
  120.     ticks_prev = SDL_GetTicks();
  121.  
  122.     while(running)
  123.     {
  124.         ticks_prev = SDL_GetTicks();
  125.  
  126.         // Handle events;
  127.         while(SDL_PollEvent(&events) != 0)
  128.         {
  129.             WindowHandler(&events);
  130.             ButtonHandler(&boundkeys, &events, &active_buttons);
  131.             if(getKey(&events) == SDLK_p)
  132.             {
  133.                 switch(GameState)
  134.                 {
  135.                     case GAME_PAUSED:  GameState = GAME_RUNNING; break;
  136.                     case GAME_RUNNING: GameState = GAME_PAUSED;  break;
  137.                 }
  138.             }
  139.         }
  140.         // Update objects/player.
  141.         if(GameState == GAME_RUNNING)
  142.         {
  143.             Update();
  144.         }
  145.          // Draw things
  146.         SDL_RenderClear(renderer);
  147.         SDL_RenderCopy(renderer, levelbg->img->texture, &levelbg->cam, &levelbg->img->unit);
  148.         drawSprite(renderer, plr->sprite,plr->width, plr->height, plr->image_index, 0);
  149.         drawSprite(renderer, object, 30, 15, 0, 0);
  150.  
  151.         SDL_RenderPresent(renderer);
  152.  
  153.         char* title = malloc(50 * sizeof(char));
  154.         float frametime = 1000 / ( FRAMERATE+( (float) SDL_GetTicks() - (float) ticks_prev ) );
  155.         sprintf(title, "My SDL Game; FPS: %f", 1000/frametime);
  156.         SDL_SetWindowTitle(win, title);
  157.  
  158.         SDL_Delay(frametime);
  159.     }
  160.  
  161.     // Wait then close window.
  162.     freeImage(plr->sprite);
  163.     free(plr);
  164.     SDL_DestroyWindow(win);
  165.     SDL_Quit();
  166.     return 0;
  167. }
  168.  
  169. // Game functions
  170. void Initalize()
  171. {
  172.     // Load Resources / Allocate objects.
  173.     boundkeys.FORWARD = SDLK_w;
  174.     boundkeys.BACK    = SDLK_s;
  175.     boundkeys.LEFT    = SDLK_a;
  176.     boundkeys.RIGHT   = SDLK_d;
  177.     boundkeys.SHOOT   = SDL_BUTTON_LEFT;
  178.  
  179.     levelbg = malloc(sizeof(Background));
  180.     levelbg->img = loadImage(renderer, "background.jpg", 0, 0);
  181.     levelbg->cam.x = 0;
  182.     levelbg->cam.y = 850;
  183.     levelbg->cam.w = WINDOW_WIDTH;
  184.     levelbg->cam.h = WINDOW_HEIGHT;
  185.     levelbg->img->unit.w = WINDOW_WIDTH;
  186.     levelbg->img->unit.h = WINDOW_HEIGHT;
  187.  
  188.     plr = malloc(sizeof(Player));
  189.     plr->sprite = loadImage(renderer, "ships.png", 0, 0);
  190.     plr->width  = 48;
  191.     plr->height = 45;
  192.     plr->speed  = 8;
  193.     plr->image_index = 2;
  194.     plr->friction = 3.8;
  195.     plr->sprite->unit.w = plr->width;
  196.     plr->sprite->unit.h = plr->height;
  197.     plr->xpos = (WINDOW_WIDTH - plr->width)/2;
  198.     plr->ypos = ((WINDOW_HEIGHT - plr->height)/2);
  199. }
  200.  
  201.  
  202. void Update()
  203. {
  204.     if(active_buttons & BT_FORWARD) plr->yvel -= plr->speed/plr->friction;
  205.     if(active_buttons & BT_BACK) plr->yvel += plr->speed/plr->friction;
  206.     if(active_buttons & BT_LEFT) plr->xvel -= plr->speed/plr->friction;
  207.     if(active_buttons & BT_RIGHT) plr->xvel += plr->speed/plr->friction;
  208.             //Move player.
  209.     if(plr->xvel >  plr->speed) plr->xvel = plr->speed;
  210.     if(plr->xvel < -plr->speed) plr->xvel = -plr->speed;
  211.     if(plr->yvel >  plr->speed) plr->yvel = plr->speed;
  212.     if(plr->yvel < -plr->speed) plr->yvel = -plr->speed;
  213.     if(!(active_buttons & BT_FORWARD) && !(active_buttons & BT_BACK)) plr->yvel /= plr->friction;
  214.     if(!(active_buttons & BT_LEFT) && !(active_buttons & BT_RIGHT))   plr->xvel /= plr->friction;
  215.          // Update Player
  216.     plr->xpos += plr->xvel;
  217.     plr->ypos += plr->yvel;
  218.     plr->sprite->unit.x = plr->xpos;
  219.     plr->sprite->unit.y = plr->ypos;
  220.          // Momentum based sprite.
  221.     if(plr->xvel > 0) plr->image_index = 3;
  222.     if(plr->xvel >= plr->speed) plr->image_index = 4;
  223.     if(plr->xvel < 0) plr->image_index = 1;
  224.     if(plr->xvel <= -plr->speed) plr->image_index = 0;
  225.     if(abs(plr->xvel) <= 0.5) plr->image_index = 2;
  226.          //Scroll background
  227.     levelbg->cam.y -= 2;
  228. }
  229.  
  230.  
  231. void WindowHandler(SDL_Event* ev)
  232. {
  233.     if(ev->type == SDL_WINDOWEVENT)
  234.     {
  235.         switch(ev->window.event)
  236.         {
  237.             case SDL_WINDOWEVENT_CLOSE:
  238.                 running = false;
  239.             break;
  240.             default:
  241.             break;
  242.         }
  243.     }
  244. }
  245.  
  246. void ButtonHandler(InputButtons* input, SDL_Event* ev, uint8_t* abuttons)
  247. {
  248.     if(ev->type == SDL_KEYDOWN)
  249.     {
  250.         int key = ev->key.keysym.sym;
  251.         if(key == input->FORWARD)  *abuttons |= BT_FORWARD;
  252.         if(key == input->BACK)     *abuttons |= BT_BACK;
  253.         if(key == input->LEFT)     *abuttons |= BT_LEFT;
  254.         if(key == input->RIGHT)    *abuttons |= BT_RIGHT;
  255.     }
  256.     else if(ev->type == SDL_KEYUP)
  257.     {
  258.         int key = ev->key.keysym.sym;
  259.         if(key == input->FORWARD)  *abuttons &= ~BT_FORWARD;
  260.         if(key == input->BACK)     *abuttons &= ~BT_BACK;
  261.         if(key == input->LEFT)     *abuttons &= ~BT_LEFT;
  262.         if(key == input->RIGHT)    *abuttons &= ~BT_RIGHT;
  263.     }
  264. }
  265.  
  266. SDL_Keycode getKey(SDL_Event* e)
  267. {
  268.     if(e->type == SDL_KEYDOWN)
  269.     {
  270.         return e->key.keysym.sym;
  271.     }
  272. }
  273.  
  274.  
  275.  
  276. // Utilities
  277.  
  278. Image* loadImage(SDL_Renderer* r, char* file, int x, int y)
  279. {
  280.     SDL_Surface* imgsurf = IMG_Load(file);
  281.     if(!imgsurf)
  282.     {
  283.         printf("Failed to load resource: %s \n", file);
  284.         return NULL;
  285.     }
  286.     SDL_Texture* imgtex = SDL_CreateTextureFromSurface(r,imgsurf);
  287.     SDL_Rect imgunit = { x, y, imgsurf->w, imgsurf->h};
  288.  
  289.     Image* img = NULL;
  290.     img = malloc(sizeof(Image));
  291.     img->name = file;
  292.     img->surface = imgsurf;
  293.     img->texture = imgtex;
  294.     img->unit = imgunit;
  295.  
  296.     printf("Resource loaded: %s; at: Image->%p\n     X->%i, Y->%i\n     W->%i, H->%i",file,img,img->unit.x,img->unit.y,img->unit.w,img->unit.h);
  297.  
  298.     //SDL_DestroyTexture(imgtex);
  299.     //SDL_FreeSurface(imgsurf);
  300.  
  301.     return img;
  302. }
  303.  
  304. void drawImage(SDL_Renderer* r, Image* img)
  305. {
  306.     SDL_RenderCopy(r, img->texture, NULL, &img->unit);
  307. }
  308.  
  309. void drawSprite(SDL_Renderer* r, Image* img, int width, int height, int col, int row)
  310. {
  311.     SDL_Rect spr = {col*width, row*height, col+width, row+height};
  312.     SDL_RenderCopy(r, img->texture, &spr, &img->unit);
  313. }
  314.  
  315. void freeImage(Image* img)
  316. {
  317.     SDL_DestroyTexture(img->texture);
  318.     SDL_FreeSurface(img->surface);
  319.     free(img);
  320. }
  321.  
  322. int random_range(int rmin, int rmax)
  323. {
  324.     return rand() % rmin + rmax;
  325. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement