SDL2基本操作
- 头文件
- 主函数
- 初始化
- 创建窗口
- 窗口暂停以及事件讲解
- 销毁窗口(释放指针)并退出
- 加载bmp图片
- 新加载图片的方法(使用渲染、纹理)
- 加载其他格式的图片
头文件
#include "SDL.h"
#include "SDL_image.h"
主函数
int main(int argc,char* argv[]) //一定要写成这种含参数形式
{
}
初始化
使用SDL_Init(参数),参数表示整个游戏可以播放动画和声音等,可以只填一个,但是一定要有参数。
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO);
创建窗口
采用SDL_Window类型的指针来创建,使用SDL_CreateWindow(const char *title, int x, int y, int w,int h, Uint32 flags)函数来创建窗口。
函数参数意义依次为:
- 窗口标题
- 窗口显示在屏幕的位置(x,y),x和y可以让系统来设置,可以写成SDL_WINDOWPOS_UNDEFINED和SDL_WINDOWPOS_UNDEFINED
- 窗口的大小(w,h)
- 以什么样的方式显示窗口,如SDL_WINDOW_SHOWN(直接显示),SDL_WINDOW_FULLSCREEN(全屏显示)
代码如下:
SDL_Window* window = SDL_CreateWindow("Asuna",100,100,800,600,SDL_WINDOW_SHOWN);
窗口暂停以及事件讲解
代码如下:
//方法1
SDL_Delay(3000); //窗口停留3000秒
//方法2
system("pause");//一直暂停窗口,知道输入其他键才消失
//方法3,使用事件弄一个循环
SDL_Event event;
bool quit=false;
while (quit==false)
{ /*用SDL_PollEvent(&event)来检测是否有事件,用SDL_Event的实例属性event.type来获取事件。*/while (SDL_PollEvent(&event)) //当触发事件时候执行该循环,没有事件的时候就暂停,这样做的目的是可以减少使用更多的内存和cpu消耗{if (event.type==SDL_QUIT) //窗口操作的事件,当点击窗口右上角关闭按钮的时候就执行if{quit=true;//使用exit(0)是退出程序,这样有个缺点,就是可能有之前创建的内存没有释放}else if (event.type==SDL_MOUSEBUTTONDOWN) //鼠标事件,当在窗口内点击鼠标的时候触发。{if (event.button.button==SDL_BUTTON_LEFT) //点击鼠标左键的时候执行该代码{}else if(event.button.button==SDL_BUTTON_RIGHT) //点击鼠标右键的时候执行该代码{}}else if (event.type == SDL_KEYDOWN) //键盘事件,当输入任意键时触发。{if (event.key.keysym.sym==SDLK_UP) //如果按下的键是上就执行代码,左侧用来接收用户按下的键{} }}
}
销毁窗口(释放指针)并退出
程序最后需要执行的代码。代码如下:
SDL_DestroyWindow(window); //销毁窗口
SDL_Quit(); //以最安全的方式退出
加载bmp图片
加载图片相当于在窗口表面覆盖上一张贴图,SDL2默认支持加载bmp格式的图片,注意图片的大小要比窗口小。步骤如下:
1.使用SDL_Surface类型的指针通过SDL_GetWindowSurface()函数获得到窗口的表面。
2.再创建一个SDL_Surface类型的指针接收SDL_LoadBMP()函数加载的图片。
3.贴图之前要清除原来的图,不然之前的图还会呈现在窗口内
4.使用SDL_BlitSurface()函数把图片贴到窗口表面。
第一个参数是图片。
第二个参数是以一个点切割图片,取右下角图片。参数形式和参数四一样(NULL默认不切割)
第三个参数是窗口。
第四个参数表示把图片贴到窗口的哪个位置(NULL为贴到左上角),使用结构体SDL_RECT类型,创建一个实例,该结构体有两个属性x,y代表贴的位置,然后对其赋值,再将实例作为实参传给第四个参数(需要指针,所以需要加&取地址)。代码如下:
SDL_Rect rect;rect.x = 100;rect.y = 100;
5.刷新窗口
加载图片详细代码如下:
SDL_Surface* surface = SDL_GetWindowSurface(window);//记住最后需要释放,使用SDL_FreeSurface()函数。SDL_Surface* image = SDL_LoadBMP("1.bmp");//此处为相对路径,也就是放在和代码同一个文件夹中SDL_FillRect(surface, NULL, 0);//清除原来的图,但是程序大的话鼠标会闪屏,第一个参数表示在哪画一个矩形(NULL表示整个屏幕),第二个参数表示要填充的地方,第三个参数表示颜色SDL_BlitSurface(image,NULL,surface,&rect);//贴完之后刷新窗口SDL_UpdateWindowSurface(window);
当程序大或者电脑差的时候,用这种方法会发生鼠标指针一闪一闪的问题,原因是每次更新屏幕时都是通过SDL_FillRect()在屏幕上画了一个很大的矩形,然后把原来的屏幕覆盖掉了。为了解决这个问题,引入了render(渲染)来更新屏幕。
新加载图片的方法(使用渲染、纹理)
1.先对窗口进行渲染(使用renderer),得到rend,以后都用rend代替窗口。
2.再把图片转换成纹理才能贴到rend上
3.创建一个矩形,也就是要贴的大小位置等
4.每次贴之前先清空rend
5.把img贴到rend上
6.显示贴完之后的rend
SDL_Window* window = SDL_CreateWindow("Asuna", 100, 100, 800, 600, SDL_WINDOW_SHOWN);
//1.渲染,以后用rend来代表window
SDL_Renderer* rend = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
SDL_Surface* image = SDL_LoadBMP("1.bmp");
//2.要先把surface转换成纹理(材质)才能贴到rend上
SDL_Texture* img = SDL_CreateTextureFromSurface(rend, image);
//3.创建矩形
SDL_Rect rect;
rect.x = 100;
rect.y = 100;
rect.h = image->h;
rect.w = image->w;
//4.每次贴之前先清空rend
SDL_RenderClear(rend);
//5.把img贴到rend上
SDL_RenderCopy(rend, img, NULL, &rect);//第三个参数同样是对图片进行分割
//6.显示贴完之后的rend
SDL_RenderPresent(rend);
加载其他格式的图片
使用来自SDL_image.h库的IMG_Load()函数,其他和加载bmp格式的图片一样,改一下获取图片的函数就可以了。
SDL_Surface* image1 = IMG_Load("yui.png");
通用模板代码如下:
#include <iostream>
#include "SDL.h"
#include "SDL_image.h"
using namespace std;int main(int argc, char* argv[])
{SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO);SDL_Window* window = SDL_CreateWindow("Asuna", 100, 100, 800, 600, SDL_WINDOW_SHOWN);//渲染之后,用rend来代表windowSDL_Renderer* rend = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);SDL_RenderClear(rend); //清空掉窗口SDL_Surface* image = SDL_LoadBMP("1.bmp");//此处为相对路径,也就是放在和代码同一个文件夹中//要先把surface转换成纹理(材质)才能贴到rend上SDL_Texture* img = SDL_CreateTextureFromSurface(rend, image);SDL_Rect rect;rect.x = 100;rect.y = 100;rect.h = image->h;rect.w = image->w;SDL_Event event;bool quit = false;while (quit == false){ /*用SDL_PollEvent(&event)来检测是否有事件,用SDL_Event的实例属性event.type来获取事件。*/while (SDL_PollEvent(&event)) //当触发事件时候执行该循环,没有事件的时候就暂停,这样做的目的是可以减少使用更多的内存和cpu消耗{if (event.type == SDL_QUIT) //窗口操作的事件,当点击窗口右上角关闭按钮的时候就执行if{quit = true;//使用exit(0)是退出程序,这样有个缺点,就是可能有之前创建的内存没有释放}else if (event.type == SDL_MOUSEMOTION){//每次贴之前先清空rendSDL_RenderClear(rend);//把img贴到rend上SDL_RenderCopy(rend, img, NULL, &rect);}}SDL_Delay(5); //闪屏速度,越低越快。可以降低cpu使用率//显示贴完之后的rendSDL_RenderPresent(rend);}SDL_DestroyWindow(window); //销毁窗口SDL_Quit(); //以最安全的方式退出return 0;
}