Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * spacexplore.c -- прототип игры управления звездолетом
- *
- * Copyright (c) 2019, Nikita Semenov <ndsemeno@petrsu.ru>
- *
- * This code is licensed under a MIT-style license.
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <time.h>
- #include <SDL.h>
- #include <SDL_ttf.h>
- /* Скорости корабля */
- #define VXD 6
- #define VYD 6
- typedef struct _gamescreen { // экран
- SDL_Surface* sprite;
- } gamescreen;
- typedef struct _gamebackground { // фон
- SDL_Surface* sprite;
- } gamebackground;
- typedef struct _spaceship { // корабль
- SDL_Surface* sprite;
- int x;
- int y;
- int vx;
- int vy;
- } spaceship;
- typedef struct _obstacle { // астероиды
- int vx[8];
- int vy[8];
- int x[8];
- int y[8];
- int if_exist[8];
- int n_existing;
- } obstacle;
- typedef struct _gameresources { // ресурсы
- SDL_Surface* asteroid;
- SDL_Surface* bitcoin;
- int x;
- int y;
- int if_exist;
- int bitcoin_count;
- int flag;
- } gameresources;
- typedef struct _game { // состояние игры
- gamescreen* screen;
- spaceship* ship;
- gameresources* resources;
- gamebackground* background;
- obstacle* obstacles;
- TTF_Font* font;
- int timer;
- } game;
- game* init();
- void run(game* g);
- void draw(game* g);
- void show_counter(game* g, const int counter, const int mode);
- void show_mission_status(game* g);
- void spawn_asteroids(game* g);
- int main()
- {
- game* g = init(); // инициализируем игру
- run(g); // запускаем цикл обработки
- return 0;
- }
- game* init()
- {
- /* Создаем структуру представления состояния игры */
- game* g;
- g = (game*)malloc(sizeof(game));
- if (g == NULL) {
- fprintf(stderr, "Not enough memory!");
- exit(EXIT_FAILURE);
- }
- /* Инициализируем библиотеку SDL, используем только видеоподсистему */
- if (SDL_Init(SDL_INIT_VIDEO) < 0) {
- fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError());
- exit(EXIT_FAILURE);
- }
- /* Регистрируем обработчик завершения программы */
- atexit(SDL_Quit);
- /* Инициализируем библиотеку SDL_ttf и загружаем шрифт */
- TTF_Init();
- g->font = TTF_OpenFont("AbrilFatface-Regular.ttf", 44);
- /* Выделяем память для структуры представления экрана */
- g->screen = (gamescreen*)malloc(sizeof(gamescreen));
- if (g->screen == NULL) {
- fprintf(stderr, "Not enough memory!");
- exit(EXIT_FAILURE);
- }
- /* Инициализируем видеорежим */
- g->screen->sprite = SDL_SetVideoMode(1024, 768, 0, SDL_HWSURFACE | SDL_DOUBLEBUF);
- if (g->screen->sprite == NULL) {
- fprintf(stderr, "Couldn't set video mode: %s\n", SDL_GetError());
- exit(EXIT_FAILURE);
- }
- /* Инициализируем фон*/
- g->background = (gamebackground*)malloc(sizeof(gamebackground));
- if (g->background == NULL) {
- fprintf(stderr, "Not enough memory!");
- exit(EXIT_FAILURE);
- }
- g->background->sprite = SDL_LoadBMP("kosmos.bmp");
- if (g->background->sprite == NULL) {
- fprintf(stderr, "Couldn't load a bitmap: %s\n", SDL_GetError());
- exit(EXIT_FAILURE);
- }
- /* Инициализируем ресурсы */
- g->resources = (gameresources*)malloc(sizeof(gameresources));
- if (g->resources == NULL) {
- fprintf(stderr, "Not enough memory!");
- exit(EXIT_FAILURE);
- }
- g->resources->bitcoin = SDL_LoadBMP("bitcoin.bmp");
- if (g->resources->bitcoin == NULL) {
- fprintf(stderr, "Couldn't load a bitmap: %s\n", SDL_GetError());
- exit(EXIT_FAILURE);
- }
- g->resources->asteroid = SDL_LoadBMP("asteroid.bmp");
- if (g->resources->asteroid == NULL) {
- fprintf(stderr, "Couldn't load a bitmap: %s\n", SDL_GetError());
- exit(EXIT_FAILURE);
- }
- /* Инициализируем астероиды */
- g->obstacles = (obstacle*)malloc(sizeof(obstacle));
- if (g->obstacles == NULL) {
- fprintf(stderr, "Not enough memory!");
- exit(EXIT_FAILURE);
- }
- /* Выделяем память для структуры представления корабля */
- g->ship = (spaceship*)malloc(sizeof(spaceship));
- if (g->ship == NULL) {
- fprintf(stderr, "Not enough memory!");
- exit(EXIT_FAILURE);
- }
- g->ship->sprite = SDL_LoadBMP("ship.bmp");
- if (g->ship->sprite == NULL) {
- fprintf(stderr, "Couldn't load a bitmap: %s\n", SDL_GetError());
- exit(EXIT_FAILURE);
- }
- /* Задаем начальное положение кораблю */
- g->ship->x = g->screen->sprite->w / 2 - g->ship->sprite->w / 2;
- g->ship->y = g->screen->sprite->h - g->ship->sprite->h;
- /* Задание начальных значений для счетчиков и флагов */
- g->resources->bitcoin_count = -1;
- g->resources->if_exist = 0;
- g->resources->flag = 0;
- g->timer = 0;
- /* Устанавливаем заголовок окна */
- SDL_WM_SetCaption("Space explore", NULL);
- return g;
- }
- void run(game* g)
- {
- int done = 0; // Флажок выхода
- unsigned int start_time = SDL_GetTicks();
- /* Продолжаем выполнение, пока не поднят флажок */
- while (!done) {
- /* Структура описания события */
- SDL_Event event;
- /* Извлекаем и обрабатываем все доступные события */
- while (SDL_PollEvent(&event)) {
- switch (event.type) {
- /* Если клавишу нажали */
- case SDL_KEYDOWN:
- switch (event.key.keysym.sym) {
- case SDLK_LEFT:
- g->ship->vx += -VXD;
- break;
- case SDLK_RIGHT:
- g->ship->vx += VXD;
- break;
- case SDLK_UP:
- g->ship->vy += -VYD;
- break;
- case SDLK_DOWN:
- g->ship->vy += VYD;
- break;
- case SDLK_ESCAPE:
- done = 1;
- break;
- }
- break;
- /* Если клавишу отпустили */
- case SDL_KEYUP:
- switch (event.key.keysym.sym) {
- case SDLK_LEFT:
- g->ship->vx += VXD;
- break;
- case SDLK_RIGHT:
- g->ship->vx += -VXD;
- break;
- case SDLK_UP:
- g->ship->vy += VYD;
- break;
- case SDLK_DOWN:
- g->ship->vy += -VYD;
- break;
- default:
- break;
- }
- break;
- /* Если закрыли окно */
- case SDL_QUIT:
- done = 1;
- break;
- default:
- break;
- }
- }
- /* Верхняя граница корабля */
- if (g->ship->x + g->ship->vx >= 0 && g->ship->x + g->ship->vx <= g->screen->sprite->w - g->ship->sprite->w)
- g->ship->x += g->ship->vx;
- /* Нижняя граница корабля */
- if (g->ship->y + g->ship->vy >= g->screen->sprite->h / 3 && g->ship->y + g->ship->vy <= g->screen->sprite->h)
- g->ship->y += g->ship->vy;
- /* Проверка взятия ресурса */
- if (g->resources->if_exist == 1)
- if (g->ship->x <= g->resources->x + g->resources->bitcoin->w && g->ship->x + g->ship->sprite->w >= g->resources->x)
- if (g->ship->y <= g->resources->y + g->resources->bitcoin->h && g->ship->y + g->ship->sprite->h >= g->resources->y)
- g->resources->if_exist = 0;
- /* Получаем значение времени прошедшего с начала игры */
- unsigned int current_time = SDL_GetTicks();
- g->timer = (current_time - start_time) / 1000;
- if (g->timer <= 60) {
- draw(g);
- }
- else {
- show_mission_status(g);
- SDL_Delay(2500);
- done = 1;
- }
- SDL_Delay(10);
- }
- }
- void draw(game* g)
- {
- /* Прямоугольники, определяющие зону отображения */
- SDL_Rect src, dest;
- /* Отображаем фон */
- src.x = 0;
- src.y = 0;
- src.w = g->background->sprite->w;
- src.h = g->background->sprite->h;
- dest.x = 0;
- dest.y = 0;
- dest.w = g->background->sprite->w;
- dest.h = g->background->sprite->h;
- SDL_BlitSurface(g->background->sprite, &src, g->screen->sprite, &dest);
- /* Отображаем счетчики */
- show_counter(g, g->resources->bitcoin_count, 1);
- show_counter(g, g->timer, 2);
- /* Отображаем корабль */
- src.x = 0;
- src.y = 0;
- src.w = g->ship->sprite->w;
- src.h = g->ship->sprite->h;
- dest.x = g->ship->x;
- dest.y = g->ship->y;
- dest.w = g->ship->sprite->w;
- dest.h = g->ship->sprite->h;
- SDL_SetColorKey(g->ship->sprite, SDL_SRCCOLORKEY, 0x000000); // Удаляем черные пиксели
- SDL_BlitSurface(g->ship->sprite, &src, g->screen->sprite, &dest);
- /* Отображение ресурса */
- if (g->resources->if_exist == 0) {
- srand(time(NULL));
- while (g->resources->flag == 0) {
- g->resources->x = rand() % (g->screen->sprite->w - g->resources->bitcoin->w);
- g->resources->y = rand() % (g->screen->sprite->h * 2 / 3 - g->resources->bitcoin->h) + g->screen->sprite->h / 3;
- if (g->ship->x <= g->resources->x + g->resources->bitcoin->w && g->ship->x + g->ship->sprite->w >= g->resources->x) {
- if (g->ship->y <= g->resources->y + g->resources->bitcoin->h && g->ship->y + g->ship->sprite->h >= g->resources->y) {
- ;
- }
- else {
- g->resources->flag = 1;
- }
- }
- }
- g->resources->flag = 0;
- g->resources->if_exist = 1;
- g->resources->bitcoin_count++;
- }
- src.x = 0;
- src.y = 0;
- src.w = g->resources->bitcoin->w;
- src.h = g->resources->bitcoin->h;
- dest.x = g->resources->x;
- dest.y = g->resources->y;
- dest.w = g->resources->bitcoin->w;
- dest.h = g->resources->bitcoin->h;
- SDL_SetColorKey(g->resources->bitcoin, SDL_SRCCOLORKEY, 0x000000);
- SDL_BlitSurface(g->resources->bitcoin, &src, g->screen->sprite, &dest);
- spawn_asteroids(g);
- /* Отрисовываем обновленный экран */
- SDL_Flip(g->screen->sprite);
- }
- void show_counter(game* g, const int counter, const int mode)
- {
- char text[5] = "";
- /* Переводим int счетчик в char */
- if (sprintf(text, "%d", counter) == 0) {
- ;
- }
- SDL_Surface* fontSurface;
- SDL_Color fColor = { 0xff, 0x00, 0x00, 0xff };
- SDL_Color bColor = { 0x00, 0x00, 0x00, 0xff };
- fontSurface = TTF_RenderUTF8_Shaded(g->font, text, fColor, bColor);
- int w, h;
- TTF_SizeUTF8(g->font, text, &w, &h);
- SDL_Rect fontRect;
- if (mode == 1) {
- fontRect.x = 0;
- } else {
- fontRect.x = g->screen->sprite->w - w;
- }
- fontRect.y = 0;
- SDL_SetColorKey(fontSurface, SDL_SRCCOLORKEY, 0x000000);
- SDL_BlitSurface(fontSurface, NULL, g->screen->sprite, &fontRect);
- }
- void show_mission_status(game* g)
- {
- char text[] = "Mission complete!";
- SDL_Surface* status;
- SDL_Color fColor = { 0x00, 0xff, 0x00, 0xff };
- SDL_Color bColor = { 0x00, 0x00, 0x00, 0xff };
- status = TTF_RenderUTF8_Shaded(g->font, text, fColor, bColor);
- int w, h;
- TTF_SizeUTF8(g->font, text, &w, &h);
- SDL_Rect statusRect;
- statusRect.x = g->screen->sprite->w / 2 - w / 2;
- statusRect.y = g->screen->sprite->h / 2 - h / 2;
- SDL_SetColorKey(status, SDL_SRCCOLORKEY, 0x000000);
- SDL_BlitSurface(status, NULL, g->screen->sprite, &statusRect);
- SDL_Flip(g->screen->sprite);
- }
- void spawn_asteroids(game* g)
- {
- SDL_Rect src, dest;
- for (int i = 0; i < 8; i++) {
- /* Проверка на существование астероида в плоскости
- * и последующее задание ему случайной координаты x
- */
- if (g->obstacles->if_exist[i] == 0) {
- srand(time(NULL));
- g->obstacles->if_exist[i] = 1;
- g->obstacles->x[i] = rand() % (g->screen->sprite->w - g->resources->asteroid->w);
- g->obstacles->y[i] = 0 - g->resources->asteroid->h;
- g->obstacles->vx[i] = rand() % (12) - 6;
- g->obstacles->vy[i] = rand() % (3);
- }
- else {
- /* Обработка ситуации выхода астероида за границы */
- if (g->obstacles->y[i] > g->screen->sprite->h || g->obstacles->x[i] < 0 - g->resources->asteroid->w
- || g->obstacles->x[i] > g->screen->sprite->w) {
- g->obstacles->if_exist[i] = 0;
- }
- else {
- g->obstacles->x[i] += g->obstacles->vx[i];
- g->obstacles->y[i] += g->obstacles->yx[i];
- }
- src.x = 0;
- src.y = 0;
- src.w = g->resources->asteroid->w;
- src.h = g->resources->asteroid->h;
- dest.x = g->obstacles->x[i];
- dest.y = g->obstacles->y[i];
- dest.w = g->resources->asteroid->w;
- dest.h = g->resources->asteroid->h;
- SDL_SetColorKey(g->resources->asteroid, SDL_SRCCOLORKEY, 0x000000);
- SDL_BlitSurface(g->resources->asteroid, &src, g->screen->sprite, &dest);
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement