Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <math.h>
- #include <stdbool.h>
- #include "SDL/SDL.h"
- #include "SDL/SDL_image.h"
- #include "SDL/SDL_ttf.h"
- #define SCREEN_WIDTH 640
- #define SCREEN_HEIGHT 480
- #define MAX_MAP_X 400
- #define MAX_MAP_Y 300
- #define TILE_SIZE 42
- #define SCROLL_SPEED 8
- #define GRAVITY_SPEED 0.8
- #define MAX_FALL_SPEED 20
- #define PLAYER_SPEED 4
- #define TRANS_R 127
- #define TRANS_G 0
- #define TRANS_B 127
- #define MAX_MESSAGE_LENGTH 100
- #define BLANK_TILE 0
- #define MAX_TILES 10
- #define Bullet_No 6 // Maximum no of alive bullet
- typedef struct
- {
- char *filename;
- int startX, startY;
- int maxX, maxY;
- int tile[MAX_MAP_Y][MAX_MAP_X];
- SDL_Surface *background;
- } Map;
- typedef struct
- {
- int left, right, up, down, jump, fire;
- } Input;
- typedef struct
- {
- int w, h, onGround;
- int thinkTime;
- float x, y, dirX, dirY;
- } Entity;
- struct Projectile {
- bool alive;
- SDL_Rect b;
- char w,h;
- } bullet[Bullet_No];
- SDL_Surface *screen, *playerImage, *spriteImage, *mapImages[MAX_TILES];
- Entity *self, player;
- Input input;
- Map map;
- void checkToMap(Entity *e)
- {
- int i, x1, x2, y1, y2;
- /* Remove the user from the ground */
- e->onGround = 0;
- /* Test the horizontal movement first */
- i = e->h > TILE_SIZE ? TILE_SIZE : e->h;
- for (;;)
- {
- x1 = (e->x + e->dirX) / TILE_SIZE;
- x2 = (e->x + e->dirX + e->w - 1) / TILE_SIZE;
- y1 = (e->y) / TILE_SIZE;
- y2 = (e->y + i - 1) / TILE_SIZE;
- if (x1 >= 0 && x2 < MAX_MAP_X && y1 >= 0 && y2 < MAX_MAP_Y)
- {
- if (e->dirX > 0)
- {
- /* Trying to move right */
- if ((map.tile[y1][x2] != BLANK_TILE) || (map.tile[y2][x2] != BLANK_TILE))
- {
- /* Place the player as close to the solid tile as possible */
- e->x = x2 * TILE_SIZE;
- e->x -= e->w + 1;
- e->dirX = 0;
- }
- }
- else if (e->dirX < 0)
- {
- /* Trying to move left */
- if ((map.tile[y1][x1] != BLANK_TILE) || (map.tile[y2][x1] != BLANK_TILE))
- {
- /* Place the player as close to the solid tile as possible */
- e->x = (x1 + 1) * TILE_SIZE;
- e->dirX = 0;
- }
- }
- }
- /* Exit this loop if we have tested all of the body */
- if (i == e->h)
- {
- break;
- }
- /* Test the next block */
- i += TILE_SIZE;
- if (i > e->h)
- {
- i = e->h;
- }
- }
- /* Now test the vertical movement */
- i = e->w > TILE_SIZE ? TILE_SIZE : e->w;
- for (;;)
- {
- x1 = (e->x) / TILE_SIZE;
- x2 = (e->x + i) / TILE_SIZE;
- y1 = (e->y + e->dirY) / TILE_SIZE;
- y2 = (e->y + e->dirY + e->h) / TILE_SIZE;
- if (x1 >= 0 && x2 < MAX_MAP_X && y1 >= 0 && y2 < MAX_MAP_Y)
- {
- if (e->dirY > 0)
- {
- /* Trying to move down */
- if ((map.tile[y2][x1] != BLANK_TILE) || (map.tile[y2][x2] != BLANK_TILE))
- {
- /* Place the player as close to the solid tile as possible */
- e->y = y2 * TILE_SIZE;
- e->y -= e->h;
- e->dirY = 0;
- e->onGround = 1;
- }
- }
- else if (e->dirY < 0)
- {
- /* Trying to move up */
- if ((map.tile[y1][x1] != BLANK_TILE) || (map.tile[y1][x2] != BLANK_TILE))
- {
- /* Place the player as close to the solid tile as possible */
- e->y = (y1 + 1) * TILE_SIZE;
- e->dirY = 0;
- }
- }
- }
- if (i == e->w)
- {
- break;
- }
- i += TILE_SIZE;
- if (i > e->w)
- {
- i = e->w;
- }
- }
- /* Now apply the movement */
- e->x += e->dirX;
- e->y += e->dirY;
- if (e->x < 0)
- {
- e->x = 0;
- }
- else if (e->x + e->w >= map.maxX)
- {
- e->x = map.maxX - e->w - 1;
- }
- if (e->y > map.maxY)
- {
- e->thinkTime = 60;
- }
- }
- SDL_Surface *loadImage(char *name)
- {
- /* Load the image using SDL Image */
- SDL_Surface *temp = IMG_Load(name);
- SDL_Surface *image;
- if (temp == NULL)
- {
- printf("Failed to load image %s\n", name);
- return NULL;
- }
- /* Make the background transparent */
- SDL_SetColorKey(temp, (SDL_SRCCOLORKEY|SDL_RLEACCEL), SDL_MapRGB(temp->format, TRANS_R, TRANS_G, TRANS_B));
- /* Convert the image to the screen's native format */
- image = SDL_DisplayFormat(temp);
- SDL_FreeSurface(temp);
- if (image == NULL)
- {
- printf("Failed to convert image %s to native format\n", name);
- return NULL;
- }
- /* Return the processed image */
- return image;
- }
- void drawImage(SDL_Surface *image, int x, int y)
- {
- SDL_Rect dest;
- /* Set the blitting rectangle to the size of the src image */
- dest.x = x;
- dest.y = y;
- dest.w = image->w;
- dest.h = image->h;
- /* Blit the entire image onto the screen at coordinates x and y */
- SDL_BlitSurface(image, NULL, screen, &dest);
- }
- void init(char *title)
- {
- /* Initialise SDL Video and Audio */
- if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO) < 0)
- {
- printf("Could not initialize SDL: %s\n", SDL_GetError());
- exit(1);
- }
- /* Open a screen */
- screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 0, SDL_HWPALETTE|SDL_DOUBLEBUF);
- if (screen == NULL)
- {
- printf("Couldn't set screen mode to %d x %d: %s\n", SCREEN_WIDTH, SCREEN_HEIGHT, SDL_GetError());
- exit(1);
- }
- /* Set the screen title */
- SDL_WM_SetCaption(title, NULL);
- /* Hide the mouse cursor */
- SDL_ShowCursor(SDL_DISABLE);
- }
- void getInput()
- {
- SDL_Event event;
- /* Loop through waiting messages and process them */
- while (SDL_PollEvent(&event))
- {
- switch (event.type)
- {
- /*
- ** Closing the Window or pressing Escape will exit the program
- ** The arrow keys will scroll the map around
- */
- case SDL_QUIT:
- exit(0);
- break;
- case SDL_KEYDOWN:
- switch (event.key.keysym.sym)
- {
- case SDLK_ESCAPE:
- exit(0);
- break;
- case SDLK_SPACE:
- input.jump = 1;
- for(int i=0;i<Bullet_No;i++) if(!bullet[i].alive) {
- bullet[i].alive = 1;
- bullet[i].b.x = player.x + 60 ;
- bullet[i].b.y = player.y + 30 ;
- break; // break this for( ) loop
- }
- for(int i=0;i<Bullet_No;i++) if(bullet[i].alive) {
- bullet[i].b.x += 5;
- bullet[i].b.w = bullet[i].w;
- bullet[i].b.h = bullet[i].h;
- SDL_FillRect(screen , &bullet[i].b , 0xFFFF66);
- // Bullet Destroy condition
- if(bullet[i].b.x > 380) bullet[i].alive = 0;
- }
- break;
- case SDLK_LEFT:
- input.left = 1;
- break;
- case SDLK_RIGHT:
- input.right = 1;
- break;
- default:
- break;
- }
- break;
- case SDL_KEYUP:
- switch (event.key.keysym.sym)
- {
- case SDLK_LEFT:
- input.left = 0;
- break;
- case SDLK_RIGHT:
- input.right = 0;
- break;
- default:
- break;
- }
- break;
- }
- }
- }
- void loadMap(char *name)
- {
- int x, y;
- FILE *fp;
- fp = fopen(name, "rb");
- /* If we can't open the map then exit */
- if (fp == NULL)
- {
- printf("Failed to open map %s\n", name);
- exit(1);
- }
- /* Read the data from the file into the map */
- map.maxX = map.maxY = 0;
- for (y=0;y<MAX_MAP_Y;y++)
- {
- for (x=0;x<MAX_MAP_X;x++)
- {
- fscanf(fp, "%d", &map.tile[y][x]);
- if (map.tile[y][x] > 0)
- {
- if (x > map.maxX)
- {
- map.maxX = x;
- }
- if (y > map.maxY)
- {
- map.maxY = y;
- }
- }
- }
- }
- /* Set the maximum scroll position of the map */
- map.maxX = (map.maxX + 1) * TILE_SIZE;
- map.maxY = (map.maxY + 1) * TILE_SIZE;
- printf("%d %d\n", map.maxX, map.maxY);
- /* Set the start coordinates */
- map.startX = map.startY = 0;
- /* Set the filename */
- map.filename = name;
- /* Close the file afterwards */
- fclose(fp);
- }
- void loadMapTiles()
- {
- int i;
- char filename[40];
- FILE *fp;
- for (i=0;i<MAX_TILES;i++)
- {
- sprintf(filename, "gfx/map/%d.png", i);
- fp = fopen(filename, "rb");
- if (fp == NULL)
- {
- continue;
- }
- fclose(fp);
- mapImages[i] = loadImage(filename);
- if (mapImages[i] == NULL)
- {
- exit(1);
- }
- }
- }
- void freeMapTiles()
- {
- int i;
- for (i=0;i<MAX_TILES;i++)
- {
- if (mapImages[i] != NULL)
- {
- SDL_FreeSurface(mapImages[i]);
- }
- }
- }
- void drawMap()
- {
- int x, y, mapX, x1, x2, mapY, y1, y2;
- mapX = map.startX / TILE_SIZE;
- x1 = (map.startX % TILE_SIZE) * -1;
- x2 = x1 + SCREEN_WIDTH + (x1 == 0 ? 0 : TILE_SIZE);
- mapY = map.startY / TILE_SIZE;
- y1 = (map.startY % TILE_SIZE) * -1;
- y2 = y1 + SCREEN_HEIGHT + (y1 == 0 ? 0 : TILE_SIZE);
- /* Draw the background */
- drawImage(map.background, 0, 0);
- /* Draw the map starting at the startX and startY */
- for (y=y1;y<y2;y+=TILE_SIZE)
- {
- mapX = map.startX / TILE_SIZE;
- for (x=x1;x<x2;x+=TILE_SIZE)
- {
- if (map.tile[mapY][mapX] != 0)
- {
- drawImage(mapImages[map.tile[mapY][mapX]], x, y);
- }
- mapX++;
- }
- mapY++;
- }
- }
- void centerEntityOnMap(Entity *e)
- {
- map.startX = e->x - (SCREEN_WIDTH / 2);
- if (map.startX < 0)
- {
- map.startX = 0;
- }
- else if (map.startX + SCREEN_WIDTH >= map.maxX)
- {
- map.startX = map.maxX - SCREEN_WIDTH;
- }
- map.startY = e->y - (SCREEN_HEIGHT / 2);
- if (map.startY < 0)
- {
- map.startY = 0;
- }
- else if (map.startY + SCREEN_HEIGHT >= map.maxY)
- {
- map.startY = map.maxY - SCREEN_HEIGHT;
- }
- }
- void initPlayer()
- {
- player.x = player.y = 0;
- player.dirX = player.dirY = 0;
- player.w = playerImage->w;
- player.h = playerImage->h;
- player.thinkTime = 0;
- }
- void doPlayer()
- {
- if (player.thinkTime == 0)
- {
- player.dirX = 0;
- /* Gravity always pulls the player down */
- player.dirY += GRAVITY_SPEED;
- if (player.dirY >= MAX_FALL_SPEED)
- {
- player.dirY = MAX_FALL_SPEED;
- }
- if (input.left == 1)
- {
- player.dirX -= PLAYER_SPEED;
- }
- else if (input.right == 1)
- {
- player.dirX += PLAYER_SPEED;
- }
- if (input.jump == 1)
- {
- if (player.onGround == 1)
- {
- player.dirY = -13;
- }
- input.jump = 0;
- }
- if (input.fire == 1 )
- {
- }
- checkToMap(&player);
- centerEntityOnMap(&player);
- }
- if (player.thinkTime > 0)
- {
- player.thinkTime--;
- if (player.thinkTime == 0)
- {
- initPlayer();
- }
- }
- }
- void drawPlayer()
- {
- if (player.thinkTime == 0)
- {
- drawImage(playerImage, player.x - map.startX, player.y - map.startY);
- }
- }
- void draw()
- {
- /* Draw the map */
- drawMap();
- /* Draw the player */
- drawPlayer();
- /* Swap the buffers */
- SDL_Flip(screen);
- /* Sleep briefly */
- SDL_Delay(1);
- }
- void delay(unsigned int frameLimit)
- {
- unsigned int ticks = SDL_GetTicks();
- if (frameLimit < ticks)
- {
- return;
- }
- if (frameLimit > ticks + 16)
- {
- SDL_Delay(16);
- }
- else
- {
- SDL_Delay(frameLimit - ticks);
- }
- }
- void cleanup()
- {
- /* Free the map tiles */
- freeMapTiles();
- /* Free the background image */
- if (map.background != NULL)
- {
- SDL_FreeSurface(map.background);
- }
- /* Free the player image */
- if (playerImage != NULL)
- {
- SDL_FreeSurface(playerImage);
- }
- /* Shut down SDL */
- SDL_Quit();
- }
- int main(int argc, char *argv[])
- {
- unsigned int frameLimit = SDL_GetTicks() + 16;
- int go;
- /* Start up SDL */
- init("Krumm's Adventures");
- /* Call the cleanup function when the program exits */
- atexit(cleanup);
- go = 1;
- // Initialize the bullet
- for(int i=0;i<Bullet_No;i++) {
- bullet[i].alive = 0;
- bullet[i].w = bullet[i].h = 5 ; // Bullet Size Configuration
- }
- /* Load the map tiles */
- loadMapTiles();
- /* Load the player image */
- playerImage = loadImage("gfx/krumm.png");
- /* If we get back a NULL image, just exit */
- if (playerImage == NULL)
- {
- exit(1);
- }
- /* Load the background image */
- map.background = loadImage("gfx/background.png");
- /* If we get back a NULL image, just exit */
- if (map.background == NULL)
- {
- exit(1);
- }
- /* Load the map */
- loadMap("data/maps/map01.dat");
- /* Initialise the player */
- initPlayer();
- /* Loop indefinitely for messages */
- while (go == 1)
- {
- getInput();
- /* Do the player */
- doPlayer();
- /* Draw the map */
- draw();
- /* Sleep briefly to stop sucking up all the CPU time */
- delay(frameLimit);
- frameLimit = SDL_GetTicks() + 16;
- }
- /* Exit the program */
- exit(0);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement