用事件做一个简单的方块移动即碰撞小程序
Attention:
我们这次用:
render = SDL_CreateRenderer(window, -1,SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
来初始化渲染器
不知道有没有发现上次程序运行后GPU占用会达到70%以上
真正的游戏当然不能是这样
所以我们加上了后面两个参数
第一个是开启硬件加速,第二个控制屏幕帧率不超过电脑默认刷新率
这样就不会给显卡造成如此大的压力,可以自己试试
在上篇中我们讲了事件,但只涉及到了SDL_QUIT事件,即关闭事件
这次我们讲讲键盘事件
event 中的type属性中的SDL_keydown用于检测键盘是否按下
用event.key.keysym.sym获取键盘按下的字符
key:指的是事件的类型
keysym:是键盘按下或释放的键,即键盘按下或者释放都会返回字符,如果想只按下时返回字符需要搭配
if (event.type == SDL_KEYDOWN) 判断是否按下一个按键
sym:获取字符
代码运行效果:
WASD控制运动方向,边界时反向
在上次的代码基础上,只改动了event事件循环的一些内容,如下
char c = 0;
SDL_Rect rect;
rect.x = 100;
rect.y = 100;
rect.w = 50;
rect.h = 50;
/*LOAD_Image();
Put_Image();*/
SDL_SetRenderDrawColor(render, 0, 255, 255, 255);
SDL_RenderFillRect(render, &rect);
SDL_RenderPresent(render);
bool quit = false;
SDL_Event event;
while (!quit)
{
SDL_SetRenderDrawColor(render, 0, 0, 0, 255);
SDL_RenderClear(render);
while (SDL_PollEvent(&event) != 0)
{
//SDL_Delay(5);
//SDL_RenderPresent(render);
if (event.type == SDL_KEYDOWN)
{
c = event.key.keysym.sym;
}
if (event.type == SDL_QUIT)
{
quit = true;
cout << "quit\n";
}
}
if (c == 'w')
{
if (rect.y == 0)
{
c = 's';
continue;
}
rect.y-=4;
//cout << "w\n";
}
if (c == 'a')
{
if (rect.x == 0)
{
c = 'd';
continue;
}
rect.x-=4;
//cout << "a\n";
}
if (c == 's')
{
if (rect.y == 428)
{
c = 'w';
continue;
}
rect.y+=4;
cout << "s\n";
}
if (c == 'd')
{
if (rect.x == 588)
{
c = 'a';
continue;
}
rect.x+=4;
//cout << "d\n";
}
SDL_SetRenderDrawColor(render, 0, 255, 255, 255);
SDL_RenderFillRect(render, &rect);
SDL_RenderPresent(render);
cout << c << endl;
}
解释:
SDL_rect 是一个结构表示一块区域,参数依次为坐标x,y和宽高
SDL_SetRenderDrawColor(render, 0, 255, 255, 255);
用于设置绘图颜色,设置为蓝色
SDL_RenderFillRect(render, &rect);
用于在render上画一个区域是rect的矩形
每次循环通过清空屏幕重新绘图来实现动画效果
清空屏幕
SDL_SetRenderDrawColor(render, 0, 0, 0, 255);
SDL_RenderClear(render);
绘制矩形
SDL_SetRenderDrawColor(render, 0, 255, 255, 255);
SDL_RenderFillRect(render, &rect);
SDL_RenderPresent(render);
注意
if (c == 'w')
{
if (rect.y == 0)
{
c = 's';
continue;
}
rect.y-=4;
//cout << "w\n";
}
这一类代码用于判断是否运动到边界,如果到边界则反向
整体代码如下:
#define SDL_MAIN_HANDLED
#include "SDL.h"
#include "SDL_image.h"
#include<iostream>
#include<conio.h>
using namespace std;
const int Window_WIDTH = 640;
const int Window_HEIGHT = 480;
SDL_Window* window = NULL;
SDL_Renderer* render = NULL;
SDL_Texture* tex = NULL;
SDL_Renderer* render2 = NULL;
SDL_Rect srcrect;
bool Init()
{
srcrect.x = 0;
srcrect.y = 0;
srcrect.w = 32;
srcrect.h = 32;
window = SDL_CreateWindow("my first SDL",
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, Window_WIDTH, Window_HEIGHT,
SDL_WINDOW_SHOWN);
if (window == NULL)
{
cout << "creat window error\n";
return false;
}
//render = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED );
render = SDL_CreateRenderer(window, -1,SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if (render == NULL)
{
cout << "creat render error\n";
return false;
}
return true;
}
bool LOAD_Image()
{
if (IMG_Init(IMG_INIT_PNG | IMG_INIT_JPG) == -1) cout << "png error\n";
tex = IMG_LoadTexture(render,"bg1.png");
if (tex == NULL)
{
cout << "creat surface tex error\n";
return false;
}
return true;
}
bool Put_Image()
{
//SDL_RenderCopy(render, tex, NULL, &srcrect);
SDL_RenderPresent(render);
return true;
}
void Quit()
{
SDL_DestroyWindow(window);
SDL_DestroyRenderer(render);
SDL_DestroyTexture(tex);
SDL_Quit();
}
void clear()
{
SDL_RenderClear(render);
SDL_SetRenderDrawColor(render, 0, 0, 0, 255);
SDL_RenderPresent(render);
}
int main(int argc, char *args[])
{
if (Init())
{
char c = 'w';
SDL_Rect rect;
rect.x = 100;
rect.y = 100;
rect.w = 50;
rect.h = 50;
/*LOAD_Image();
Put_Image();*/
SDL_SetRenderDrawColor(render, 0, 255, 255, 255);
SDL_RenderFillRect(render, &rect);
SDL_RenderPresent(render);
bool quit = false;
SDL_Event event;
while (!quit)
{
SDL_SetRenderDrawColor(render, 0, 0, 0, 255);
SDL_RenderClear(render);
while (SDL_PollEvent(&event) != 0)
{
//SDL_Delay(5);
//SDL_RenderPresent(render);
if (event.type == SDL_KEYDOWN)
{
c = event.key.keysym.sym;
}
if (event.type == SDL_QUIT)
{
quit = true;
cout << "quit\n";
}
}
if (c == 'w')
{
if (rect.y == 0)
{
c = 's';
continue;
}
rect.y-=4;
//cout << "w\n";
}
if (c == 'a')
{
if (rect.x == 0)
{
c = 'd';
continue;
}
rect.x-=4;
//cout << "a\n";
}
if (c == 's')
{
if (rect.y == 428)
{
c = 'w';
continue;
}
rect.y+=4;
cout << "s\n";
}
if (c == 'd')
{
if (rect.x == 588)
{
c = 'a';
continue;
}
rect.x+=4;
//cout << "d\n";
}
SDL_SetRenderDrawColor(render, 0, 255, 255, 255);
SDL_RenderFillRect(render, &rect);
SDL_RenderPresent(render);
cout << c << endl;
}
//Put_Image();
Quit();
}
system("pause");
return 0;
}