Как известно, написание игры на SDL без каких-либо надстроек — очень муторное дело.
Есть несколько решений этого:
- Написание библиотеки, облегчающей жизнь.
- Бросаем SDL и переходим на какую-нибудь другую библиотеку.
Мы выберем более трудный путь — №1.
Наша библиотека будет включать:
- Создание Core-структуры, которая включает в себя работу с окном, рендером, и.т.д.
- Облегчённая работа со спрайтами — текстура, поворот, обрез текстуры.
- Рисование текста.
Итак, начнём! Создаём header и source файлы:
- ITopping.h
- ITopping.cpp
(Нашу библиотеку мы назовём ITopping)
Инициализируем файл заголовка и создаём Core-структуру (окно+рендер):
ITopping.h
#ifndef ITOPPING_H_
#define ITOPPING_H_
#include <iostream>
#include <fstream>
#include <vector>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <SDL2/SDL_mixer.h>
#include <SDL2/SDL_ttf.h>
typedef struct{
SDL_Window* window;
SDL_Renderer* render;
} ITCore;
//...
#endif /* ITOPPING_H_ */
Соответственно, создаём функцию инициализации Core-структуры:
ITopping.h
ITCore initCore(char* title,int screenx,int screeny,bool isResizable,int w,int h,bool isAcceleratedRender);
ITopping.cpp
ITCore initCore(char* title,int screenx,int screeny,bool isResizable,int w,int h,bool isAcceleratedRender)
{
ITCore core;
if(isResizable == true) core.window = SDL_CreateWindow(title,screenx,screeny,w,h,SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
if(isResizable == false) core.window = SDL_CreateWindow(title,screenx,screeny,w,h,SDL_WINDOW_SHOWN);
if(isAcceleratedRender == true) core.render = SDL_CreateRenderer(core.window,-1,SDL_RENDERER_ACCELERATED);
if(isAcceleratedRender == false) core.render = SDL_CreateRenderer(core.window,-1,SDL_RENDERER_SOFTWARE);
return(core);
}
Теперь к спрайтам:
Спрайт — это объект, имеющий изображение, координаты и (иногда) угол.
ITopping.h
ITSprite initSprite(ITCore* core,char* texturepath,int imagew,int imageh,int initx,int inity,bool isCropped,SDL_Rect crop);
ITopping.cpp
ITSprite initSprite(ITCore* core,char* texturepath,int imagew,int imageh,int initx,int inity,bool isCropped,SDL_Rect crop)
{
ITSprite spr;
spr.texture = IMG_LoadTexture(core->render,texturepath);
spr.rect.x = initx;
spr.rect.y = inity;
spr.rect.w = imagew;
spr.rect.h = imageh;
if(isCropped == true)
{
spr.crop = crop;
}
return spr;
}
Поворот спрайта:
Наш спрайт будет иметь значение угла, соответственно поворот — это сложение введёных градусов с углом спрайта по модулю 360:
ITopping.h
void turnSprite(ITSprite* spr,int angle);
ITopping.cpp
void turnSprite(ITSprite* spr,int angle)
{
spr->angle = ((spr->angle + angle) % 360);
}
Наконец, отрисовка спрайта:
ITopping.h
void drawSprite(ITCore* core,ITSprite* spr,bool isCropped);
ITopping.cpp
void drawSprite(ITCore* core,ITSprite* spr,bool isCropped)
{
if(isCropped) SDL_RenderCopyEx(core->render,spr->texture,&(spr->crop),&(spr->rect),spr->angle,NULL,SDL_FLIP_NONE);
else SDL_RenderCopyEx(core->render,spr->texture,NULL,&(spr->rect),spr->angle,NULL,SDL_FLIP_NONE);
}
Рендер текста:
Рендерим текст в поверхность, конвертируем поверхность в текстуру, выводим на экран с поворотом/без поворота.
ITopping.h
void drawText(ITCore* core,const char* text,const char* fontpath,int basesize,SDL_Color color,int x,int y,bool isRotated,int angle);
ITopping.cpp
void drawText(ITCore* core,const char* text,const char* fontpath,int basesize,SDL_Color color,int x,int y,bool isRotated,int angle)
{
TTF_Font* font = TTF_OpenFont(fontpath,basesize);
SDL_Surface* textSurface = TTF_RenderText_Solid(font, text, color);
SDL_Texture* textTexture = SDL_CreateTextureFromSurface(core->render,textSurface);
SDL_Rect textrect;
textrect.w = textSurface->w;
textrect.h = textSurface->h;
textrect.x = x;
textrect.y = y;
if(isRotated == false) SDL_RenderCopy(core->render,textTexture,NULL,&textrect);
else SDL_RenderCopyEx(core->render,textTexture,NULL,&textrect,angle,NULL,SDL_FLIP_NONE);
}
Код на GitHub'е: https://github.com/Fedorsturov/itopping
Спасибо за внимание!
Автор: fedor2612