ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

按键操作

2022-01-05 21:06:11  阅读:252  来源: 互联网

标签:SURFACE PRESS KEY 按键 SDL 操作 NULL gKeyPressSurfaces


按键操作

先来讲点题外话,为啥我会喜欢SDL呢?我之前从事的编程是嵌入式开发,我喜欢嵌入式,但是人生苦短,学学其他东西也是好的。我讨厌Python,因此没有过于学习pyqt库,不知道为啥,就是觉得啥东西都不是自己写的,代码量一写大一点,就觉得不是自己的东西,格外不踏实。在者这门语言执行效率太低下了,一边有C语言的影子,还有c++的影子,却又是脚本语言。我是新手菜鸡,或许我的感觉是很不对的,但是没人纠正我之前我就这样认为吧。
好,回归主题,SDL的开发其实和嵌入式开发很像,更多类似于对库进行开发。事件类似于嵌入式的信号输入,刷新渲染层类似于像电机发送处理好的命令,窗口运行的视觉效果就像嵌入式代码烧进板子里产品运行效果,无现象就失败了,有现象也不一定成功了,或许一个极端条件直接就无了。
这种感觉很强烈,说不清楚。应该没有哪个闲人会像我一样做着嵌入式跑来学SDL吧!好了,如果看不懂这段直接飘过,进入下面正题。

用户按键很重要,特别是游戏,我的小miku还等着按键交互呢

还是先看代码,看代码是最快的学习方式,前提是你能看懂的话,看不懂还是好好学语法,学基础,多抱着基础书籍啃啃,总会好起来的。
也别慌,我会使用中文注释对代码进行讲解,以中文注释的方式呈现(非中文注释的地方要么简单,要么已经讲过),并在文末附上我对这份代码的划重点“欸欸欸~~~敲黑板了,必考的喔”(还是想念高三的时光啊!)

/*This source code copyrighted by Lazy Foo' Productions (2004-2020)
and may not be redistributed without written permission.*/
//注意,此份代码只是用C语言,因此做出过修改,不会影响大局
//Using SDL, standard IO, and strings
#include <SDL.h>
#include <stdio.h>
#include <string.h>
//为了C语言和c++部分数据类型命名的统一,自己书写的一个头文件
#include "struct_type.h"

//Screen dimension constants
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;

//将事件封装为一个枚举类型,命名很重要
enum KeyPressSurfaces
{
	KEY_PRESS_SURFACE_DEFAULT,
	KEY_PRESS_SURFACE_UP,
	KEY_PRESS_SURFACE_DOWN,
	KEY_PRESS_SURFACE_LEFT,
	KEY_PRESS_SURFACE_RIGHT,
	KEY_PRESS_SURFACE_TOTAL
};

//Starts up SDL and creates window
bool init();

//Loads media
bool loadMedia();

//Frees media and shuts down SDL
void close();

//将图片的装载处理为一个单独模块,模块化的编程很重要
SDL_Surface* loadSurface(char path[]);

//The window we'll be rendering to
SDL_Window* gWindow = NULL;

//The surface contained by the window
SDL_Surface* gScreenSurface = NULL;

//不同按键对应的图片资源
SDL_Surface* gKeyPressSurfaces[KEY_PRESS_SURFACE_TOTAL];

//Current displayed image
SDL_Surface* gCurrentSurface = NULL;

bool init()
{
	//Initialization flag
	bool success = true;

	//Initialize SDL
	if (SDL_Init(SDL_INIT_VIDEO) < 0)
	{
		printf("SDL could not initialize! SDL Error: %s\n", SDL_GetError());
		success = false;
	}
	else
	{
		//Create window
		gWindow = SDL_CreateWindow("SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
		if (gWindow == NULL)
		{
			printf("Window could not be created! SDL Error: %s\n", SDL_GetError());
			success = false;
		}
		else
		{
			//Get window surface
			gScreenSurface = SDL_GetWindowSurface(gWindow);
		}
	}

	return success;
}

bool loadMedia()
{
	//Loading success flag
	bool success = true;

	//Load default surface
	gKeyPressSurfaces[KEY_PRESS_SURFACE_DEFAULT] = loadSurface("C:\\Users\\Lixin\\Desktop\\down.bmp");
	if (gKeyPressSurfaces[KEY_PRESS_SURFACE_DEFAULT] == NULL)
	{
		printf("Failed to load default image!\n");
		success = false;
	}

	//Load up surface
	gKeyPressSurfaces[KEY_PRESS_SURFACE_UP] = loadSurface("C:\\Users\\Lixin\\Desktop\\down.bmp");
	if (gKeyPressSurfaces[KEY_PRESS_SURFACE_UP] == NULL)
	{
		printf("Failed to load up image!\n");
		success = false;
	}

	//Load down surface
	gKeyPressSurfaces[KEY_PRESS_SURFACE_DOWN] = loadSurface("C:\\Users\\Lixin\\Desktop\\down.bmp");
	if (gKeyPressSurfaces[KEY_PRESS_SURFACE_DOWN] == NULL)
	{
		printf("Failed to load down image!\n");
		success = false;
	}

	//Load left surface
	gKeyPressSurfaces[KEY_PRESS_SURFACE_LEFT] = loadSurface("C:\\Users\\Lixin\\Desktop\\left.bmp");
	if (gKeyPressSurfaces[KEY_PRESS_SURFACE_LEFT] == NULL)
	{
		printf("Failed to load left image!\n");
		success = false;
	}

	//Load right surface
	gKeyPressSurfaces[KEY_PRESS_SURFACE_RIGHT] = loadSurface("C:\\Users\\Lixin\\Desktop\\down.bmp");
	if (gKeyPressSurfaces[KEY_PRESS_SURFACE_RIGHT] == NULL)
	{
		printf("Failed to load right image!\n");
		success = false;
	}

	return success;
}

void close()
{
	//Deallocate surfaces
	for (int i = 0; i < KEY_PRESS_SURFACE_TOTAL; ++i)
	{
		SDL_FreeSurface(gKeyPressSurfaces[i]);
		gKeyPressSurfaces[i] = NULL;
	}

	//Destroy window
	SDL_DestroyWindow(gWindow);
	gWindow = NULL;

	//Quit SDL subsystems
	SDL_Quit();
}

SDL_Surface* loadSurface(char path[])
{
	//Load image at specified path
	SDL_Surface* loadedSurface = SDL_LoadBMP(path);
	if (loadedSurface == NULL)
	{
		printf("Unable to load image %s! SDL Error: %s\n", path, SDL_GetError());
	}

	return loadedSurface;
}


int main(int argc, char* args[])
{
	//Start up SDL and create window
	if (!init())
	{
		printf("Failed to initialize!\n");
	}
	else
	{
		//Load media
		if (!loadMedia())
		{
			printf("Failed to load media!\n");
		}
		else
		{
			//Main loop flag
			bool quit = false;

			//Event handler
			SDL_Event e;

			//Set default current surface
			gCurrentSurface = gKeyPressSurfaces[KEY_PRESS_SURFACE_DEFAULT];

			//While application is running
			while (!quit)
			{
				//Handle events on queue
				while (SDL_PollEvent(&e) != 0)
				{
					//User requests quit
					if (e.type == SDL_QUIT)
					{
						quit = true;
					}
					//用户按键事件处理,本节课学习的重点,其他的可以不理解,但是它不行
                    //类似于SDL_KEYDOWN,SDLK_UP,全是已经定义好了的宏定义或者枚举类型,直接F12查看即可,注意这里为枚举的一个函数
					else if (e.type == SDL_KEYDOWN)
					{
						//Select surfaces based on key press
						switch (e.key.keysym.sym)
						{
						case SDLK_UP:
							gCurrentSurface = gKeyPressSurfaces[KEY_PRESS_SURFACE_UP];
							break;

						case SDLK_DOWN:
							gCurrentSurface = gKeyPressSurfaces[KEY_PRESS_SURFACE_DOWN];
							break;

						case SDLK_LEFT:
							gCurrentSurface = gKeyPressSurfaces[KEY_PRESS_SURFACE_LEFT];
							break;

						case SDLK_RIGHT:
							gCurrentSurface = gKeyPressSurfaces[KEY_PRESS_SURFACE_RIGHT];
							break;

						default:
							gCurrentSurface = gKeyPressSurfaces[KEY_PRESS_SURFACE_DEFAULT];
							break;
						}
					}
				}

				//Apply the current image
				SDL_BlitSurface(gCurrentSurface, NULL, gScreenSurface, NULL);

				//Update the surface
				SDL_UpdateWindowSurface(gWindow);
			}
		}
	}

	//Free resources and close SDL
	close();

	return 0;
}

下面我要解释的不多,主要就是夸夸我本人:

  1. 重点按键操作,这个看了应该是不难的,但是是不是看见这份代码开始有点慌了,显得好臃肿,很想重构他?没错,模块化编程在我现在看来模块的不仅是功能函数模块化,还应该是多文件书写代码。明明不同类别模块的东西,非得挤在一个文件里面,很想多文件分开;同时,明明功能接近但是却重复造轮子的代码,如bool loadMedia()函数,就应该重构统一为一个函数,这是我的一个编程思想,需要改进结构的话肯定得下死手。
  2. 对于C语言和c++在书写方式上是很多不同的,目前我只会一点点c++的语法,但是我很想只用C语言写完这个教程,因为C语言是最好的编程语言!!!因此,我会对接下来大佬开源的代码进行C语言化,尽量不影响其原汁原味的特性
  3. 对于struct_type.h文件,暂时不加说明,到后面会统一公布,会在本教程书写完毕后,再在开头补充如何使用他。说白了其中就是一点宏定义以及枚举定义之类的。为了增加代码的兼容性,同时为了方便以后代码的使用,才单独进行封装。

似乎离翻译汉化的道路越来越远,算了算了,写成个人学习汉化教程吧,因为我英语虽然不好,但意会这些外国文献倒是够了,翻译太耗时间了,而且确实没有必要处处都看,我给你们只挑选重点,你好我也好。

标签:SURFACE,PRESS,KEY,按键,SDL,操作,NULL,gKeyPressSurfaces
来源: https://www.cnblogs.com/LOVE-LIXINTAO/p/15768807.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有