SDL2 教程(三):keyboardevent

用事件做一个简单的方块移动即碰撞小程序


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;
}

猜你喜欢

转载自blog.csdn.net/qq_40953281/article/details/80088942