Advertisement
Guest User

Untitled

a guest
May 14th, 2013
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 12.37 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <math.h>
  5. #include <stdbool.h>
  6. #include "SDL/SDL.h"
  7. #include "SDL/SDL_image.h"
  8. #include "SDL/SDL_ttf.h"
  9.  
  10. #define SCREEN_WIDTH 640
  11. #define SCREEN_HEIGHT 480
  12. #define MAX_MAP_X 400
  13. #define MAX_MAP_Y 300
  14. #define TILE_SIZE 42
  15. #define SCROLL_SPEED 8
  16. #define GRAVITY_SPEED 0.8
  17. #define MAX_FALL_SPEED 20
  18. #define PLAYER_SPEED 4
  19. #define TRANS_R 127
  20. #define TRANS_G 0
  21. #define TRANS_B 127
  22. #define MAX_MESSAGE_LENGTH 100
  23. #define BLANK_TILE 0
  24. #define MAX_TILES 10
  25. #define Bullet_No 6 // Maximum no of alive bullet
  26.  
  27. typedef struct
  28. {
  29.     char *filename;
  30.     int startX, startY;
  31.     int maxX, maxY;
  32.     int tile[MAX_MAP_Y][MAX_MAP_X];
  33.     SDL_Surface *background;
  34. } Map;
  35.  
  36. typedef struct
  37. {
  38.     int left, right, up, down, jump, fire;
  39. } Input;
  40.  
  41. typedef struct
  42. {
  43.     int w, h, onGround;
  44.     int thinkTime;
  45.     float x, y, dirX, dirY;
  46. } Entity;
  47.  
  48. struct Projectile {
  49.     bool alive;
  50.     SDL_Rect b;
  51.     char w,h;
  52. } bullet[Bullet_No];
  53.  
  54. SDL_Surface *screen, *playerImage, *spriteImage, *mapImages[MAX_TILES];
  55. Entity *self, player;
  56. Input input;
  57. Map map;
  58.  
  59. void checkToMap(Entity *e)
  60. {
  61.     int i, x1, x2, y1, y2;
  62.  
  63.     /* Remove the user from the ground */
  64.  
  65.     e->onGround = 0;
  66.  
  67.     /* Test the horizontal movement first */
  68.  
  69.     i = e->h > TILE_SIZE ? TILE_SIZE : e->h;
  70.  
  71.     for (;;)
  72.     {
  73.         x1 = (e->x + e->dirX) / TILE_SIZE;
  74.         x2 = (e->x + e->dirX + e->w - 1) / TILE_SIZE;
  75.  
  76.         y1 = (e->y) / TILE_SIZE;
  77.         y2 = (e->y + i - 1) / TILE_SIZE;
  78.  
  79.         if (x1 >= 0 && x2 < MAX_MAP_X && y1 >= 0 && y2 < MAX_MAP_Y)
  80.         {
  81.             if (e->dirX > 0)
  82.             {
  83.                 /* Trying to move right */
  84.  
  85.                 if ((map.tile[y1][x2] != BLANK_TILE) || (map.tile[y2][x2] != BLANK_TILE))
  86.                 {
  87.                     /* Place the player as close to the solid tile as possible */
  88.  
  89.                     e->x = x2 * TILE_SIZE;
  90.  
  91.                     e->x -= e->w + 1;
  92.  
  93.                     e->dirX = 0;
  94.                 }
  95.             }
  96.  
  97.             else if (e->dirX < 0)
  98.             {
  99.                 /* Trying to move left */
  100.  
  101.                 if ((map.tile[y1][x1] != BLANK_TILE) || (map.tile[y2][x1] != BLANK_TILE))
  102.                 {
  103.                     /* Place the player as close to the solid tile as possible */
  104.  
  105.                     e->x = (x1 + 1) * TILE_SIZE;
  106.  
  107.                     e->dirX = 0;
  108.                 }
  109.             }
  110.         }
  111.  
  112.         /* Exit this loop if we have tested all of the body */
  113.  
  114.         if (i == e->h)
  115.         {
  116.             break;
  117.         }
  118.  
  119.         /* Test the next block */
  120.  
  121.         i += TILE_SIZE;
  122.  
  123.         if (i > e->h)
  124.         {
  125.             i = e->h;
  126.         }
  127.     }
  128.  
  129.     /* Now test the vertical movement */
  130.  
  131.     i = e->w > TILE_SIZE ? TILE_SIZE : e->w;
  132.  
  133.     for (;;)
  134.     {
  135.         x1 = (e->x) / TILE_SIZE;
  136.         x2 = (e->x + i) / TILE_SIZE;
  137.  
  138.         y1 = (e->y + e->dirY) / TILE_SIZE;
  139.         y2 = (e->y + e->dirY + e->h) / TILE_SIZE;
  140.  
  141.         if (x1 >= 0 && x2 < MAX_MAP_X && y1 >= 0 && y2 < MAX_MAP_Y)
  142.         {
  143.             if (e->dirY > 0)
  144.             {
  145.                 /* Trying to move down */
  146.  
  147.                 if ((map.tile[y2][x1] != BLANK_TILE) || (map.tile[y2][x2] != BLANK_TILE))
  148.                 {
  149.                     /* Place the player as close to the solid tile as possible */
  150.  
  151.                     e->y = y2 * TILE_SIZE;
  152.                     e->y -= e->h;
  153.  
  154.                     e->dirY = 0;
  155.  
  156.                     e->onGround = 1;
  157.                 }
  158.             }
  159.  
  160.             else if (e->dirY < 0)
  161.             {
  162.                 /* Trying to move up */
  163.  
  164.                 if ((map.tile[y1][x1] != BLANK_TILE) || (map.tile[y1][x2] != BLANK_TILE))
  165.                 {
  166.                     /* Place the player as close to the solid tile as possible */
  167.  
  168.                     e->y = (y1 + 1) * TILE_SIZE;
  169.  
  170.                     e->dirY = 0;
  171.                 }
  172.             }
  173.         }
  174.  
  175.         if (i == e->w)
  176.         {
  177.             break;
  178.         }
  179.  
  180.         i += TILE_SIZE;
  181.  
  182.         if (i > e->w)
  183.         {
  184.             i = e->w;
  185.         }
  186.     }
  187.  
  188.     /* Now apply the movement */
  189.  
  190.     e->x += e->dirX;
  191.     e->y += e->dirY;
  192.  
  193.     if (e->x < 0)
  194.     {
  195.         e->x = 0;
  196.     }
  197.  
  198.     else if (e->x + e->w >= map.maxX)
  199.     {
  200.         e->x = map.maxX - e->w - 1;
  201.     }
  202.  
  203.     if (e->y > map.maxY)
  204.     {
  205.         e->thinkTime = 60;
  206.     }
  207. }
  208.  
  209. SDL_Surface *loadImage(char *name)
  210. {
  211.     /* Load the image using SDL Image */
  212.  
  213.     SDL_Surface *temp = IMG_Load(name);
  214.     SDL_Surface *image;
  215.  
  216.     if (temp == NULL)
  217.     {
  218.         printf("Failed to load image %s\n", name);
  219.  
  220.         return NULL;
  221.     }
  222.  
  223.     /* Make the background transparent */
  224.  
  225.     SDL_SetColorKey(temp, (SDL_SRCCOLORKEY|SDL_RLEACCEL), SDL_MapRGB(temp->format, TRANS_R, TRANS_G, TRANS_B));
  226.  
  227.     /* Convert the image to the screen's native format */
  228.  
  229.     image = SDL_DisplayFormat(temp);
  230.  
  231.     SDL_FreeSurface(temp);
  232.  
  233.     if (image == NULL)
  234.     {
  235.         printf("Failed to convert image %s to native format\n", name);
  236.  
  237.         return NULL;
  238.     }
  239.  
  240.     /* Return the processed image */
  241.  
  242.     return image;
  243. }
  244.  
  245. void drawImage(SDL_Surface *image, int x, int y)
  246. {
  247.     SDL_Rect dest;
  248.  
  249.     /* Set the blitting rectangle to the size of the src image */
  250.  
  251.     dest.x = x;
  252.     dest.y = y;
  253.     dest.w = image->w;
  254.     dest.h = image->h;
  255.  
  256.     /* Blit the entire image onto the screen at coordinates x and y */
  257.  
  258.     SDL_BlitSurface(image, NULL, screen, &dest);
  259. }
  260.  
  261. void init(char *title)
  262. {
  263.     /* Initialise SDL Video and Audio */
  264.  
  265.     if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO) < 0)
  266.     {
  267.         printf("Could not initialize SDL: %s\n", SDL_GetError());
  268.  
  269.         exit(1);
  270.     }
  271.  
  272.     /* Open a screen */
  273.  
  274.     screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 0, SDL_HWPALETTE|SDL_DOUBLEBUF);
  275.  
  276.     if (screen == NULL)
  277.     {
  278.         printf("Couldn't set screen mode to %d x %d: %s\n", SCREEN_WIDTH, SCREEN_HEIGHT, SDL_GetError());
  279.  
  280.         exit(1);
  281.     }
  282.  
  283.     /* Set the screen title */
  284.  
  285.     SDL_WM_SetCaption(title, NULL);
  286.  
  287.     /* Hide the mouse cursor */
  288.  
  289.     SDL_ShowCursor(SDL_DISABLE);
  290. }
  291.  
  292. void getInput()
  293. {
  294.     SDL_Event event;
  295.  
  296.     /* Loop through waiting messages and process them */
  297.  
  298.     while (SDL_PollEvent(&event))
  299.     {
  300.         switch (event.type)
  301.         {
  302.             /*
  303.             ** Closing the Window or pressing Escape will exit the program
  304.             ** The arrow keys will scroll the map around
  305.             */
  306.  
  307.             case SDL_QUIT:
  308.                 exit(0);
  309.             break;
  310.  
  311.             case SDL_KEYDOWN:
  312.                 switch (event.key.keysym.sym)
  313.                 {
  314.                     case SDLK_ESCAPE:
  315.                         exit(0);
  316.                     break;
  317.  
  318.                     case SDLK_SPACE:
  319.                         input.jump = 1;
  320.                         for(int i=0;i<Bullet_No;i++) if(!bullet[i].alive) {
  321.                             bullet[i].alive = 1;
  322.                             bullet[i].b.x = player.x + 60 ;
  323.                             bullet[i].b.y = player.y + 30 ;
  324.                             break; // break this for( ) loop
  325.                         }
  326.                         for(int i=0;i<Bullet_No;i++) if(bullet[i].alive) {
  327.                             bullet[i].b.x += 5;
  328.                             bullet[i].b.w = bullet[i].w;
  329.                             bullet[i].b.h = bullet[i].h;
  330.                             SDL_FillRect(screen , &bullet[i].b , 0xFFFF66);
  331.                             // Bullet Destroy condition
  332.                             if(bullet[i].b.x > 380) bullet[i].alive = 0;
  333.                         }
  334.                     break;
  335.  
  336.                     case SDLK_LEFT:
  337.                         input.left = 1;
  338.                     break;
  339.  
  340.                     case SDLK_RIGHT:
  341.                         input.right = 1;
  342.                     break;
  343.  
  344.                     default:
  345.                     break;
  346.                 }
  347.             break;
  348.  
  349.             case SDL_KEYUP:
  350.                 switch (event.key.keysym.sym)
  351.                 {
  352.                     case SDLK_LEFT:
  353.                         input.left = 0;
  354.                     break;
  355.  
  356.                     case SDLK_RIGHT:
  357.                         input.right = 0;
  358.                     break;
  359.  
  360.                     default:
  361.                     break;
  362.                 }
  363.             break;
  364.         }
  365.     }
  366. }
  367.  
  368. void loadMap(char *name)
  369. {
  370.     int x, y;
  371.     FILE *fp;
  372.  
  373.     fp = fopen(name, "rb");
  374.  
  375.     /* If we can't open the map then exit */
  376.  
  377.     if (fp == NULL)
  378.     {
  379.         printf("Failed to open map %s\n", name);
  380.  
  381.         exit(1);
  382.     }
  383.  
  384.     /* Read the data from the file into the map */
  385.  
  386.     map.maxX = map.maxY = 0;
  387.  
  388.     for (y=0;y<MAX_MAP_Y;y++)
  389.     {
  390.         for (x=0;x<MAX_MAP_X;x++)
  391.         {
  392.             fscanf(fp, "%d", &map.tile[y][x]);
  393.  
  394.             if (map.tile[y][x] > 0)
  395.             {
  396.                 if (x > map.maxX)
  397.                 {
  398.                     map.maxX = x;
  399.                 }
  400.  
  401.                 if (y > map.maxY)
  402.                 {
  403.                     map.maxY = y;
  404.                 }
  405.             }
  406.         }
  407.     }
  408.  
  409.     /* Set the maximum scroll position of the map */
  410.  
  411.     map.maxX = (map.maxX + 1) * TILE_SIZE;
  412.     map.maxY = (map.maxY + 1) * TILE_SIZE;
  413.  
  414.     printf("%d %d\n", map.maxX, map.maxY);
  415.  
  416.     /* Set the start coordinates */
  417.  
  418.     map.startX = map.startY = 0;
  419.  
  420.     /* Set the filename */
  421.  
  422.     map.filename = name;
  423.  
  424.     /* Close the file afterwards */
  425.  
  426.     fclose(fp);
  427. }
  428.  
  429. void loadMapTiles()
  430. {
  431.     int i;
  432.     char filename[40];
  433.     FILE *fp;
  434.  
  435.     for (i=0;i<MAX_TILES;i++)
  436.     {
  437.         sprintf(filename, "gfx/map/%d.png", i);
  438.  
  439.         fp = fopen(filename, "rb");
  440.  
  441.         if (fp == NULL)
  442.         {
  443.             continue;
  444.         }
  445.  
  446.         fclose(fp);
  447.  
  448.         mapImages[i] = loadImage(filename);
  449.  
  450.         if (mapImages[i] == NULL)
  451.         {
  452.             exit(1);
  453.         }
  454.     }
  455. }
  456.  
  457. void freeMapTiles()
  458. {
  459.     int i;
  460.  
  461.     for (i=0;i<MAX_TILES;i++)
  462.     {
  463.         if (mapImages[i] != NULL)
  464.         {
  465.             SDL_FreeSurface(mapImages[i]);
  466.         }
  467.     }
  468. }
  469.  
  470. void drawMap()
  471. {
  472.     int x, y, mapX, x1, x2, mapY, y1, y2;
  473.  
  474.     mapX = map.startX / TILE_SIZE;
  475.     x1 = (map.startX % TILE_SIZE) * -1;
  476.     x2 = x1 + SCREEN_WIDTH + (x1 == 0 ? 0 : TILE_SIZE);
  477.  
  478.     mapY = map.startY / TILE_SIZE;
  479.     y1 = (map.startY % TILE_SIZE) * -1;
  480.     y2 = y1 + SCREEN_HEIGHT + (y1 == 0 ? 0 : TILE_SIZE);
  481.  
  482.     /* Draw the background */
  483.  
  484.     drawImage(map.background, 0, 0);
  485.  
  486.     /* Draw the map starting at the startX and startY */
  487.  
  488.     for (y=y1;y<y2;y+=TILE_SIZE)
  489.     {
  490.         mapX = map.startX / TILE_SIZE;
  491.  
  492.         for (x=x1;x<x2;x+=TILE_SIZE)
  493.         {
  494.             if (map.tile[mapY][mapX] != 0)
  495.             {
  496.                 drawImage(mapImages[map.tile[mapY][mapX]], x, y);
  497.             }
  498.  
  499.             mapX++;
  500.         }
  501.  
  502.         mapY++;
  503.     }
  504. }
  505.  
  506. void centerEntityOnMap(Entity *e)
  507. {
  508.     map.startX = e->x - (SCREEN_WIDTH / 2);
  509.  
  510.     if (map.startX < 0)
  511.     {
  512.         map.startX = 0;
  513.     }
  514.  
  515.     else if (map.startX + SCREEN_WIDTH >= map.maxX)
  516.     {
  517.         map.startX = map.maxX - SCREEN_WIDTH;
  518.     }
  519.  
  520.     map.startY = e->y - (SCREEN_HEIGHT / 2);
  521.  
  522.     if (map.startY < 0)
  523.     {
  524.         map.startY = 0;
  525.     }
  526.  
  527.     else if (map.startY + SCREEN_HEIGHT >= map.maxY)
  528.     {
  529.         map.startY = map.maxY - SCREEN_HEIGHT;
  530.     }
  531. }
  532.  
  533. void initPlayer()
  534. {
  535.     player.x = player.y = 0;
  536.     player.dirX = player.dirY = 0;
  537.  
  538.     player.w = playerImage->w;
  539.     player.h = playerImage->h;
  540.  
  541.     player.thinkTime = 0;
  542. }
  543.  
  544. void doPlayer()
  545. {
  546.     if (player.thinkTime == 0)
  547.     {
  548.         player.dirX = 0;
  549.  
  550.         /* Gravity always pulls the player down */
  551.  
  552.         player.dirY += GRAVITY_SPEED;
  553.  
  554.         if (player.dirY >= MAX_FALL_SPEED)
  555.         {
  556.             player.dirY = MAX_FALL_SPEED;
  557.         }
  558.  
  559.         if (input.left == 1)
  560.         {
  561.             player.dirX -= PLAYER_SPEED;
  562.         }
  563.  
  564.         else if (input.right == 1)
  565.         {
  566.             player.dirX += PLAYER_SPEED;
  567.         }
  568.  
  569.         if (input.jump == 1)
  570.         {
  571.             if (player.onGround == 1)
  572.             {
  573.                 player.dirY = -13;
  574.             }
  575.  
  576.             input.jump = 0;
  577.         }
  578.  
  579.         if (input.fire == 1 )
  580.         {
  581.  
  582.         }
  583.  
  584.         checkToMap(&player);
  585.  
  586.         centerEntityOnMap(&player);
  587.     }
  588.  
  589.     if (player.thinkTime > 0)
  590.     {
  591.         player.thinkTime--;
  592.  
  593.         if (player.thinkTime == 0)
  594.         {
  595.             initPlayer();
  596.         }
  597.     }
  598. }
  599.  
  600. void drawPlayer()
  601. {
  602.     if (player.thinkTime == 0)
  603.     {
  604.         drawImage(playerImage, player.x - map.startX, player.y - map.startY);
  605.     }
  606. }
  607.  
  608. void draw()
  609. {
  610.  
  611.     /* Draw the map */
  612.  
  613.     drawMap();
  614.  
  615.     /* Draw the player */
  616.  
  617.     drawPlayer();
  618.  
  619.     /* Swap the buffers */
  620.  
  621.     SDL_Flip(screen);
  622.  
  623.     /* Sleep briefly */
  624.  
  625.     SDL_Delay(1);
  626. }
  627.  
  628. void delay(unsigned int frameLimit)
  629. {
  630.     unsigned int ticks = SDL_GetTicks();
  631.  
  632.     if (frameLimit < ticks)
  633.     {
  634.         return;
  635.     }
  636.  
  637.     if (frameLimit > ticks + 16)
  638.     {
  639.         SDL_Delay(16);
  640.     }
  641.  
  642.     else
  643.     {
  644.         SDL_Delay(frameLimit - ticks);
  645.     }
  646. }
  647.  
  648. void cleanup()
  649. {
  650.     /* Free the map tiles */
  651.  
  652.     freeMapTiles();
  653.  
  654.     /* Free the background image */
  655.  
  656.     if (map.background != NULL)
  657.     {
  658.         SDL_FreeSurface(map.background);
  659.     }
  660.  
  661.     /* Free the player image */
  662.  
  663.     if (playerImage != NULL)
  664.     {
  665.         SDL_FreeSurface(playerImage);
  666.     }
  667.  
  668.     /* Shut down SDL */
  669.  
  670.     SDL_Quit();
  671. }
  672.  
  673. int main(int argc, char *argv[])
  674. {
  675.     unsigned int frameLimit = SDL_GetTicks() + 16;
  676.     int go;
  677.  
  678.     /* Start up SDL */
  679.  
  680.     init("Krumm's Adventures");
  681.  
  682.     /* Call the cleanup function when the program exits */
  683.  
  684.     atexit(cleanup);
  685.  
  686.     go = 1;
  687.  
  688.     // Initialize the bullet
  689.     for(int i=0;i<Bullet_No;i++) {
  690.         bullet[i].alive = 0;
  691.         bullet[i].w = bullet[i].h = 5 ; // Bullet Size Configuration
  692.     }
  693.  
  694.  
  695.     /* Load the map tiles */
  696.  
  697.     loadMapTiles();
  698.  
  699.     /* Load the player image */
  700.  
  701.     playerImage = loadImage("gfx/krumm.png");
  702.  
  703.     /* If we get back a NULL image, just exit */
  704.  
  705.     if (playerImage == NULL)
  706.     {
  707.         exit(1);
  708.     }
  709.  
  710.     /* Load the background image */
  711.  
  712.     map.background = loadImage("gfx/background.png");
  713.  
  714.     /* If we get back a NULL image, just exit */
  715.  
  716.     if (map.background == NULL)
  717.     {
  718.         exit(1);
  719.     }
  720.  
  721.     /* Load the map */
  722.  
  723.     loadMap("data/maps/map01.dat");
  724.  
  725.     /* Initialise the player */
  726.  
  727.     initPlayer();
  728.  
  729.     /* Loop indefinitely for messages */
  730.  
  731.     while (go == 1)
  732.     {
  733.         getInput();
  734.  
  735.         /* Do the player */
  736.  
  737.         doPlayer();
  738.  
  739.         /* Draw the map */
  740.  
  741.         draw();
  742.  
  743.         /* Sleep briefly to stop sucking up all the CPU time */
  744.  
  745.         delay(frameLimit);
  746.  
  747.         frameLimit = SDL_GetTicks() + 16;
  748.  
  749.     }
  750.  
  751.     /* Exit the program */
  752.  
  753.     exit(0);
  754. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement