【教程】SDL2.0实现触控方法,让屏幕跟随你的手指动起来
c4droid吧
全部回复
仅看楼主
level 12
Naurex👀 楼主
好久没有发帖了,看到有好多同学想要SDL2.0实现触控的教程,今天我就发一个SDL2.0实现触控教程给大家。SDL2.0刚刚出来,几乎没有任何教程,我是看SDL2.0的API来写的,如果有什么出错的地方大家可以纠正。
好了,让我们开始吧。
2013年11月01日 13点11分 1
level 12
Naurex👀 楼主
首先我们来分析一下SDL2.0头文件里的events.h,这家伙里面装的全是Event的事件类型,比如判断按键被是否按下我们可以这样判断,if(event.type==SDL_KEYDOWN),而SDL_KEYDOWN就在里面被定义。
2013年11月01日 14点11分 2
level 12
Naurex👀 楼主
我们很快就可以找到有关触控的3个类型,它们分别是:
/* Touch events */
SDL_FINGERDOWN ,
SDL_FINGERUP,
SDL_FINGERMOTION,
而SDL1.2是没有这三个类型的,很容易知道这三个是关于触控事件的type。
顾名思义,我们看名字就可以联想这三个分别使用的地方了吧?
SDL_FINGERDOWN //这个是当屏幕被触控时
SDL_FINGERUP //把手指抬起,没有触控发生时
SDL_FINGERMOTION //这个就是你的手指在屏幕上移动时I
2013年11月01日 14点11分 3
level 12
Naurex👀 楼主
下课了,回宿舍再继续给大家更[太开心]
2013年11月01日 14点11分 4
敢问楼主哪个学校吧。。。?
2014年06月03日 14点06分
level 12
Naurex👀 楼主
2013年11月01日 14点11分 5
2013年11月01日 15点11分
[真棒][真棒][真棒]赞I
2013年11月01日 15点11分
@lunhui000 粗不鸟你许褚小二逼你想哪谢娜在哪那在哪在哪那自己这机子你
2015年10月19日 15点10分
level 12
用不了SDL2的孩子哭了T^T
2013年11月01日 14点11分 6
有系统限制的吗?我是4.1系统的
2013年11月01日 15点11分
@Naurex👀 似乎是3.0才可用,我个倒霉的2.3T^TI
2013年11月02日 02点11分
@51popo 额?我也是听别人说的,没查过,反正我新版的C4都装不了,只能用SDL1.2......你的都可以写代码了?就算返回-1也至少说明可以运行啊,确定路径什么的都对?回去我也要再试试I
2013年11月02日 05点11分
@51popo 哇,发现我安装了4.09的c4后可以用sdl2了!开心^-^I
2013年11月03日 10点11分
level 12
Naurex👀 楼主
好了,知道这三个类型了,那我们怎么去获取坐标位置呢?
让我们继续往下看,可以找到
/**
* \brief Touch finger event structure (event.tfinger.*)
*/
typedef struct SDL_TouchFingerEvent
{
Uint32 type; /**< ::SDL_FINGERMOTION or ::SDL_FINGERDOWN or ::SDL_FINGERUP */
Uint32 timestamp;
SDL_TouchID touchId; /**< The touch device id */
SDL_FingerID fingerId;
float x; /**< Normalized in the range 0...1 */
float y; /**< Normalized in the range 0...1 */
float dx; /**< Normalized in the range 0...1 */
float dy; /**< Normalized in the range 0...1 */
float pressure; /**< Normalized in the range 0...1 */
} SDL_TouchFingerEvent;
其他的我们不用管,只需知道
float x,
float y,
这两个就是触控位置的x,y坐标轴,再看最上面的那行注释中的括号(event.tfinger.*)
现在就可以知道使用方法了。
现在定义一个event
SDL_Event event;
float x,y;//用于获取坐标
while(SDL_PollEvent(&event))//当有事件发生
{
if(event.type==SDL_FINGERDOWN)
//如果事件的类型为屏幕被点击
{
x=event.tfinger.x;
y=event.tfinger.y;
//获取坐标
}
}I
2013年11月01日 14点11分 8
level 12
Naurex👀 楼主
PS: 这里有个问题必须要注意,很严重的一个问题。 SDL2.0触屏的x,y是使用float浮点形,X与Y是不会大于1,取值范围在0<X(Y)<1之间,这个比较奇葩,所以我们不能直接使用为int,后果就是编译器直接显示为0。当然,要是不喜欢小数点,我们也可以给x,y同时乘以100或者更大,这样我们就可以使用int了。
int x,y;
x=event.tfinger.x*100;
y=event.tfinger.y*100;I
2013年11月01日 14点11分 9
x,y应该是指占屏幕长和高的百分比吧,可以定义两个int,一个width和一个hight,然后用 SDL_GetWindowSize(window,&width,&hight);来获得当前屏幕的宽度和高度,x*width和y*hight才是我们触摸的点的坐标。
2013年11月18日 16点11分
回复 shaonialife :欢迎纠正,当时应该说成百分比来更好点,太匆忙了
2013年11月18日 16点11分
2017年11月24日 16点11分
level 12
Naurex👀 楼主
好了,现在我们了解了获取坐标x,y那我们怎么去获取滑动方向呢?
我们在上面还发现两个float浮点型,
float dx,
float dy,
就是利用这两个获取方向,要注意,这两个的值很小很小
2013年11月01日 14点11分 10
level 12
Naurex👀 楼主
dx,dy又如何去使用呢?
当我们把手指放在屏幕上时,就以我们手指的位置为坐标原点,dx,dy的值都为0。
当我们手指向左滑动,dx值会变为负数,向右滑值为正数,同理可以知道dy。
PS:还是值得注意,dx,dy的值也是小于1的,在-1<0<1直接,不能直接使用int
2013年11月01日 14点11分 11
这里讲错了,向右移动是正数,向左移动是负数,跟我们数学的坐标轴一样
2013年11月01日 16点11分
回复 傻傻_痴痴 :我肿么了我,没有错到,顿时觉得自己方向感好差。。。
2013年11月01日 16点11分
2013年11月03日 00点11分
dx,dy 怎么获得啊?
2014年03月22日 15点03分
level 12
Naurex👀 楼主
好了,讲解完毕,接下来我们来写一个程序,把触屏的坐标放到屏幕上,程序运行结果如下图:
2013年11月01日 14点11分 12
level 12
Naurex👀 楼主
2013年11月01日 14点11分 13
傻傻_痴痴:经童鞋反馈此代码导致卡死,请调转到45楼看优化后的代码,此链接失效
2013年11月15日 11点11分
level 8
very good, thanks!
2013年11月01日 15点11分 14
[哈哈]
2013年11月01日 15点11分
level 12
Naurex👀 楼主
#include "SDL2/SDL.h"
#include "SDL2/SDL_ttf.h"
#include<stdio.h>
#include<string.h>
#define W 480
#define H 800
TTF_Font *font = NULL; //定义一个字体
SDL_Color color = { 178, 34, 34 };// 设置字体颜色
void setFont()
{
TTF_Init();// 启动font
font = TTF_OpenFont("/system/fonts/DroidSansFallback.ttf", 50);// 打开系统自带字体并设置大小为30
}
int main(int argc, char *argv[])
{
float x = 0, y = 0;// 用于获取触控位置的坐标
char ch[50];
//用于储存x,y为字符串输出
SDL_Rect image;
//设置一个矩形用于显示surface表面大小,如果不使用image的话图像拉伸得无法想象
image.x = 0;
image.y = 100;
image.h = 150;
image.w = 500;
SDL_Event event; //定义一个事件
SDL_Surface *sur1 = NULL; //定义刷屏表面
SDL_Surface *sur2 = NULL; //定义一个Surface表面用于显示字体
SDL_Window *w = NULL;// 创建一个窗口指针
SDL_Renderer *ren = NULL;// 创建一个渲染器指针
w = SDL_CreateWindow("Touch Test", 0, 0, W, H, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL);// 配置窗口参数并创建
ren = SDL_CreateRenderer(w, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE);// 为创建的窗口配置渲染器I
2013年11月01日 15点11分 15
level 12
Naurex👀 楼主
SDL_Texture *tex1 = NULL;
SDL_Texture *tex2 = NULL;//在SDL2.0中得把Surface表面传递给Texture来实现硬件加速,再把图形显示在屏幕上
sur1 = SDL_CreateRGBSurface(0, W, H, 32, 0, 0, 0, 0); //用于画一个矩形来刷屏
SDL_FillRect(sur1, NULL, 0xffacca);
//在sur1上画一个矩形
tex1 = SDL_CreateTextureFromSurface(ren, sur1); //把sur1传递给tex1
setFont();I
2013年11月01日 15点11分 16
level 12
Naurex👀 楼主
while (1)
{
while (SDL_PollEvent(&event))
{
if (event.type == SDL_FINGERDOWN || event.type == SDL_FINGERMOTION)
//当事件为触屏
{
x = event.tfinger.x;
y = event.tfinger.y;
//获取x,y的坐标
}
}
sprintf(ch, "X: %f Y: %f",100*x,100*y); //把坐标位置储存到ch字符串中,这里乘以100为了显示更方便直观
sur2 = TTF_RenderUTF8_Solid(font, ch, color); //让字符串生成surface表面并且传递给sur2
tex2 = SDL_CreateTextureFromSurface(ren, sur2);
SDL_RenderCopy(ren, tex1, NULL, NULL); //SDL2.0中是使用SDL_RenderCopy直接把Texture复制到窗口,而不是使用SDL_BlitSutface
SDL_RenderCopy(ren, tex2, NULL, &image);
SDL_RenderPresent(ren); //刷新屏幕
}
SDL_DestroyTexture(tex1);
SDL_DestroyTexture(tex2);
//释放Textrue
SDL_DestroyRenderer(ren);
SDL_DestroyWindow(w);
//释放渲染器和窗口并退出
}I
2013年11月01日 15点11分 17
level 12
Naurex👀 楼主
下面是以上程序的源码下载,永久地址
ht哎tp:呀/呀/pan.呀baidu.co呀m/share/link?shareid=呀3841893038&uk=2905224086
2013年11月01日 15点11分 18
经童鞋反馈此代码导致卡死,请调转到45楼看优化后的代码,此链接失效
2013年11月15日 11点11分
level 12
Naurex👀 楼主
2013年11月01日 15点11分 19
傻傻_痴痴:经童鞋反馈此代码导致卡死,请调转到45楼看优化后的代码,此链接失效
2013年11月15日 11点11分
level 12
Naurex👀 楼主
教程完毕,有什么不懂的在下面回复我,我可以回答的会尽量回答[太开心]
2013年11月01日 15点11分 20
level 10
真的很强大[真棒]可是为什么当点击屏幕到一定次数之后坐标就会显示不出来了,如果返回,c4droid会关闭??怎么回事呢[乖]I
2013年11月01日 16点11分 21
你是说我上面的程序吗?没有这种情况的呀?我点了很多次,滑动了很多次也没有问题,点击返回SDL2.0是没有确认选项,直接返回代码
2013年11月01日 16点11分
1 2 3 4 5 尾页