基于SDL实现图片的移动和风车的转动
所需准备的东西如下:
1.本程序所需的库支持
其中调用了SDL SDL_image SDL_gfx tslib 等 库
包含有的文件有SDL的头文件 ,交叉编译的可执行文件a 、一些链接库文件
libSDL-1.2.so.0.11.3 、libSDL-1.2.so.0、libSDL.so、---------------〉 SDL的一些链接库
libSDL_gfx.so、libSDL_gfx.so.13、libSDL_gfx.so.13.9.0、libSDL_gfx.so.13.9.1、 ----------〉SDL_gfx 的一些链接库
libSDL_image-1.2.so.0、libSDL_image-1.2.so.0.8.0、libSDL_image.so、 ---------------〉 SDL_image的一些链接库
libts-0.0.so.0、libts-0.0.so.0.1.1、libts.so、 ---------------〉 触摸屏的一些链接库
2.本程序所需的图片
背景图片:bg.bmp 移动图片:player.bmp
3.本程序所需的代码及头文件
main.c ts.c ts.h tslib.h move.h movebutton.h judge.h
代码如下:
1.-------------------------main.c
#include "SDL.h"
#include "stdio.h"
#include"judge.h"
#include"movebutton.h"
#include<stdlib.h>
static void sig(int argv) {
exit(0);
}
int main() {
//声明和初始化
SDL_Surface * screen;
SDL_Surface * image;
SDL_Surface * PlayerImage;
XTsEvent event;
Uint32 BeginTicks;
//声明要传输的精灵图片的区域部分
SDL_Rect PRect, BRect; //PRect对应精灵的移动的小图位置(实现动画),BRect对应精灵在屏幕的位置。
unsigned char PlayerStarts = 0;
unsigned char PlayerIndex = 0;
int flag=1;
//初始化SDL
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) == -1) {
fprintf(stderr, "初始化SDL %s\n", SDL_GetError());
return -1;
}
TsInit();
signal(SIGINT, sig);
//初始化成功设置退出要调用的函数SDL_Quit
atexit(SDL_Quit);
screen = SDL_SetVideoMode(640, 480, 16, SDL_SWSURFACE);
if (screen == NULL) {
fprintf(stderr, "不能设置 640x480x8 video mode %s\n",SDL_GetError());
return -1;
}
SDL_WM_SetCaption("图片移动", NULL);
//读取背景图片信息,
image = SDL_LoadBMP("./bg.bmp");
if (image == NULL) {
fprintf(stderr, "不能下载图片, %s\n", SDL_GetError());
return -1;
}
//读取picture
PlayerImage = SDL_LoadBMP("./picture.bmp"); //请在终端里运行该程序
if (PlayerImage == NULL) {
fprintf(stderr, "不能下载图片, %s\n", SDL_GetError());
return -1;
}
//读取第一个像素
Uint8 key = *((Uint8 *)PlayerImage->pixels);
//设置色键
SDL_SetColorKey(PlayerImage, SDL_SRCCOLORKEY, key);
if (SDL_BlitSurface(image, NULL, screen, NULL) < 0) {
//解释一下NULL,第一个是按照image的尺寸显示,第二个是默认显示
fprintf(stderr, "BlitSurface error: %s\n", SDL_GetError());
return -1;
}
PRect.x = 0; //初始化动画显示的图片。
PRect.y = 0;
PRect.w = 32;
PRect.h = 48;
BRect.x = 220; //初始化精灵的位置。
BRect.y = 200;
BRect.w = 32;
BRect.h = 48;
if (SDL_BlitSurface(PlayerImage, &PRect, screen, &BRect) < 0) {
fprintf(stderr, "BlitSurface error: %s\n", SDL_GetError());
return -1;
}
//更新显示图片
SDL_UpdateRect(screen, 0, 0, image->w, image->h);
BeginTicks = SDL_GetTicks();
// 真的时候监听板子上的触摸事件
while (1) {
//消息循环
TsEvent(&event);
//if (TsEvent(&event))
// {
switch (event.type) {
case TSDOWN:
movebutton(screen);
SDL_UpdateRect(screen, 0, 0, 0, 0);
break;
case TSUP:
movebutton(screen);
SDL_UpdateRect(screen, 0, 0, 0, 0);
break;
}
judge(screen, &event, 0, &BeginTicks, &BRect, PRect, &PlayerIndex,
&PlayerStarts);
// }
if (SDL_BlitSurface(image, NULL, screen, NULL) < 0) {
//NULL,第一个是按照image的尺寸显示,第二个是默认显示
fprintf(stderr, "BlitSurface error: %s\n", SDL_GetError());
return -1;
}
if (SDL_BlitSurface(PlayerImage, &PRect, screen, &BRect) < 0) {
fprintf(stderr, "BlitSurface error: %s\n", SDL_GetError());
return -1;
}
movebutton(screen);
}
//退出了程序释放图片资源
//SDL_FreeSurface(image);
// SDL_FreeSurface(PlayerImage);
return 0;
}
2-----------------------ts.c
#include"ts.h"
struct tsdev *ts;
int TsInit()
{
char *tsdevice=NULL;
if( (tsdevice = getenv("TSLIB_TSDEVICE")) != NULL ) {
ts = ts_open(tsdevice,0);
}else {
ts = ts_open("/dev/input/event0", 0);
}
if (!ts) {
perror("ts_open");
return -1;
}
if (ts_config(ts)) {
perror("ts_config");
exit(1);
}
return 0;
}
int TsEvent(XTsEvent *event)
{
//当按下时候记录坐标
static int x1=-1;
static int y1=-1;
int ret;
struct ts_sample samp;
while(1){
ret = ts_read(ts, &samp, 1);
if (ret < 0) {
perror("ts_read");
event->type=-1;
return -1;
}
if(samp.pressure == 1)
{
if(x1 ==-1 || y1 ==-1)
{
x1=samp.x;
y1=samp.y;
event->x=samp.x;
event->y=samp.y;
event->type=TSDOWN;
return 1;
}
if(samp.x == x1 && samp.y == y1)
{
continue ;
}
event->x=samp.x;
event->y=samp.y;
event->type=TSMOTION;
return 1;
}
if(samp.pressure == 0) {
x1=-1;
y1=-1;
event->x=samp.x;
event->y=samp.y;
event->type=TSUP;
return 1;
}
event->type=-1;
return -1;
}
}
void Tsclose()
{
ts_close(ts);
}
----------------------3. ts.h
#ifndef __TS_TEST_H
#define __TS_TEST_H
#include "tslib.h"
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/fcntl.h>
#include <sys/ioctl.h>
//type
typedef enum{ TSDOWN=0,TSUP,TSMOTION} TSEVENT;
typedef struct
{
TSEVENT type;
int x;
int y;
}XTsEvent;
int TsInit();
int TsEvent(XTsEvent *event);
void Tsclose();
#endif
----------------------4 tslib.h
#ifndef _TSLIB_H_
#define _TSLIB_H_
/*
* tslib/src/tslib.h
*
* Copyright (C) 2001 Russell King.
*
* This file is placed under the LGPL.
*
* $Id: tslib.h,v 1.4 2005/02/26 01:47:23 kergoth Exp $
*
* Touch screen library interface definitions.
*/
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#include <stdarg.h>
#include <sys/time.h>
#ifdef WIN32
#define TSIMPORT __declspec(dllimport)
#define TSEXPORT __declspec(dllexport)
#define TSLOCAL
#else
#define TSIMPORT
#ifdef GCC_HASCLASSVISIBILITY
#define TSEXPORT __attribute__ ((visibility("default")))
#define TSLOCAL __attribute__ ((visibility("hidden")))
#else
#define TSEXPORT
#define TSLOCAL
#endif
#endif
#ifdef TSLIB_INTERNAL
#define TSAPI TSEXPORT
#else
#define TSAPI TSIMPORT
#endif // TSLIB_INTERNAL
struct tsdev;
struct ts_sample {
int x;
int y;
unsigned int pressure;
struct timevaltv;
};
/*
* Close the touchscreen device, free all resources.
*/
TSAPI int ts_close(struct tsdev *);
/*
* Configure the touchscreen device.
*/
TSAPI int ts_config(struct tsdev *);
/*
* Change this hook to point to your custom error handling function.
*/
extern TSAPI int (*ts_error_fn)(const char *fmt, va_list ap);
/*
* Returns the file descriptor in use for the touchscreen device.
*/
TSAPI int ts_fd(struct tsdev *);
/*
* Load a filter/scaling module
*/
TSAPI int ts_load_module(struct tsdev *, const char *mod, const char *params);
/*
* Open the touchscreen device.
*/
TSAPI struct tsdev *ts_open(const char *dev_name, int nonblock);
/*
* Return a scaled touchscreen sample.
*/
TSAPI int ts_read(struct tsdev *, struct ts_sample *, int);
/*
* Returns a raw, unscaled sample from the touchscreen.
*/
TSAPI int ts_read_raw(struct tsdev *, struct ts_sample *, int);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _TSLIB_H_ */
----------------------5 move.h
#ifndef _MOVE_H_
#define _MOVE_H_
#include "SDL.h"
//
int move(SDL_Surface *screen,int i,Uint32 *BeginTicks,SDL_Rect *BRect,SDL_Rect PRect,unsigned char *PlayerIndex )
{
Uint32 EndTicks;
EndTicks = SDL_GetTicks();
if ((EndTicks - *BeginTicks) > 50) {//到了50MS
*BeginTicks = EndTicks;
SDL_FillRect(screen, BRect, 0); //清除以前的图片。
if (i) {
switch (i) {
case 1: //向上移动。
if (((*BRect).y - 5) > 0) { //要移动的位置是否到顶
(*BRect).y -= 5;//坐标减去5
}
else {
(*BRect).y = 0; //设置位置在顶部。
}
PRect.x = (*PlayerIndex)* 32; //使用序号计算该显示那个动画图片
PRect.y = 144; //向上的图组
(*PlayerIndex)++; //动画序号加1
if ((*PlayerIndex) > 2) (*PlayerIndex) = 0; //循环显示动画
break;
case 2:
if (((*BRect).y + (*BRect).h + 5) < screen->h) {
(*BRect).y += 5;
}
else {
(*BRect).y = screen->h - (*BRect).h;
}
PRect.x = (*PlayerIndex) * 32;
PRect.y = 0;
(*PlayerIndex)++;
if ((*PlayerIndex) > 2) (*PlayerIndex) = 0;//循环显示动画
break;
case 3:
if (((*BRect).x - 5) > 0) {
(*BRect).x -= 5;
}
else {
(*BRect).x = 0;
}
PRect.x = (*PlayerIndex) * 32;
PRect.y = 48;
(*PlayerIndex)++;
if ((*PlayerIndex) > 2) (*PlayerIndex) = 0;
break;
case 4:
if (((*BRect).x + (*BRect).w + 5) < screen->w) {
(*BRect).x += 5;
}
else {
(*BRect).x = screen->w - (*BRect).w;
}
PRect.x = (*PlayerIndex)* 32;
PRect.y = 96;
(*PlayerIndex) ++;
if ((*PlayerIndex) > 2) (*PlayerIndex) = 0;
break;
}
}
}
}
#endif
----------------------6 movebutton.h
#ifndef _MOVEBUTTON_H_
#define _MOVEBUTTON_H_
int movebutton(SDL_Surface *screen) {
filledTrigonColor(screen, 510, 280, 550,280,530, 250, 0xff8f66);
filledTrigonColor(screen, 510,400, 550,400,530, 430, 0xff8f66);
filledTrigonColor(screen, 470, 320, 470,360,440, 340, 0xff8f66);
filledTrigonColor(screen, 590, 320, 590,360,620, 340, 0xff8f66);
filledCircleColor (screen, 530, 340, 40, 0xff8f66);
stringColor(screen, 520, 340, "Quit", 0xFFFFFFFF);
boxColor(screen, 490, 180,600, 220,0xff8f66);
stringColor(screen, 500, 200, " draw Trigon", 0xFFFFFFFF);
SDL_Flip(screen);
return 0;
}
#endif
//临时
----------------------7 judge.h
#ifndef _JUDGE_H_
#define _JUDGE_H_
#include"move.h"
#include"ts.h"
int judge(SDL_Surface *screen, XTsEvent * event,unsigned char i,Uint32 *BeginTicks,SDL_Rect *BRect,SDL_Rect PRect,unsigned char * PlayerIndex,unsigned char *PlayerStarts) {
// 向上移动图片
if ((*event).x<=550&&(*event).x>=510)
if ((*event).y>=250 && (*event).y<=280)
if ((*event).type==TSDOWN||(*event).type==TSUP) {
move(screen,1,BeginTicks,BRect,PRect,PlayerIndex);
*PlayerStarts = 1;//向上移动。
*PlayerIndex = 0;//动画序号清零
}
// 向下移动图片
if ((*event).x<=550 && (*event).x>=510)
if ((*event).y>=400 && (*event).y<=430)
if ((*event).type==TSDOWN||(*event).type==TSUP) {
move(screen,2,BeginTicks,BRect,PRect,PlayerIndex);
*PlayerStarts = 2; //向下移动。
*PlayerIndex = 0;//动画序号清零
}
// 向左移动图片
if ((*event).x<=470 && (*event).x>=440)
if ((*event).y>=320 && (*event).y<=360)
if ((*event).type==TSDOWN||(*event).type==TSUP) {
move(screen,3,BeginTicks,BRect,PRect,PlayerIndex);
*PlayerStarts = 3; //向左移动
*PlayerIndex = 0;//动画序号清零
}
// 退出
if ((*event).x<=620 && (*event).x>=590)
if ((*event).y>=320 && (*event).y<=360)
if ((*event).type==TSDOWN||(*event).type==TSUP) {
move(screen,4,BeginTicks,BRect,PRect,PlayerIndex);
*PlayerStarts = 4; //向右移动
*PlayerIndex = 0;//动画序号清零
}
if ((*event).x<=570 && (*event).x>=490)
if ((*event).y>=300 && (*event).y<=380)
if ((*event).type==TSDOWN||(*event).type==TSUP) {
SDL_Quit();
}
// 画风车
if ((*event).x<=600 && (*event).x>=490)
if ((*event).y>=180 && (*event).y<=220)
if ((*event).type==TSDOWN||(*event).type==TSUP)
{
filledTrigonColor(screen, 300, 200, 300,240,340, 240,0xff0623);
SDL_UpdateRect(screen, 0, 0,0,0);
SDL_Delay(500);
filledTrigonColor(screen, 300, 280, 340,280,340, 240,0xfbff89);
SDL_UpdateRect(screen, 0, 0,0,0);
SDL_Delay(500);
filledTrigonColor(screen, 380, 280, 380,240,340, 240,0x741dff);
SDL_UpdateRect(screen, 0, 0,0,0);
SDL_Delay(500);
filledTrigonColor(screen, 380, 200, 340,200,340, 240,0x5bff20);
SDL_UpdateRect(screen, 0, 0,0,0);
SDL_Delay(1000);
filledTrigonColor(screen, 320, 220, 340,220,340, 240,0x66b120);
SDL_UpdateRect(screen, 0, 0,0,0);
SDL_Delay(1000);
filledTrigonColor(screen, 320, 240, 320,260,340, 240,0xb12ab1);
SDL_UpdateRect(screen, 0, 0,0,0);
SDL_Delay(1000);
filledTrigonColor(screen, 340, 260, 360,260,340, 240,0x16b133);
SDL_UpdateRect(screen, 0, 0,0,0);
SDL_Delay(1000);
filledTrigonColor(screen, 360, 240, 360,220,340, 240,0xff8f66);
SDL_UpdateRect(screen, 0, 0,0,0);
SDL_Delay(1000);
}
return 0;
}
#endif
四、本程序所需的命令
1、配置需要的库的命令
1. SDL-1.2.14
cd SDL-1.2.14
./configure --prefix=/opt/arm --disable-video-nanox -disable-video-qtopia --disable-static --enable-shared --disable-video-photon --disable-video-ggi --disable-video-svga --disable-video-aalib --disable-video-dummy --disable-video-dga --disable-arts --disable-esd --disable-alsa --disable-video-x11 --disable-nasm --disable-joystick --disable-input-tslib -enable-video-fbcon --host=arm-linux
make&&make install
2. SDL_image-1.2.10
cd SDL_image-1.2.10
./configure --prefix=/opt/arm --host=arm-linux --disable-static --enable-shared --with-sdl-prefix=/opt/arm CPPFLAGS=-I/opt/arm/include/SDL LDFLAGS=-L/opt/arm/lib
make&&make install
3. SDL_gfx-2.0.22
cd SDL_gfx-2.0.22
./configure --prefix=/opt/arm --disable-static --enable-shared --with-sdl-prefix=/opt/arm CPPFLAGS=-I/opt/arm/include/SDL LDFLAGS=-L/opt/arm/lib --host=arm-linux --enable-mmx=no
make&&make install
2、交叉编译命令
1. 交叉编译命令:
arm-linux-gcc main.c ts.c -o a -L/opt/arm/lib -I/opt/arm/include/SDL -lSDL -lSDL_image -lSDL_gfx -lts
2.将所需的链接库拷贝到6410的开发板上
挂载命令:
mountnfs 192.168.1.15:/opt/arm /mnt/nfs/
cd /mnt/nfs
cp a /mnt/yaffs/Qtopia/lib
cp *.bmp /mnt/yaffs/Qtopia/lib
cp *.so.* /mnt/yaffs/Qtopia/lib
或者将第二步改为将所需的链接库和SDL头文件复制到自己的U盘的一个文件里,直接挂载U盘到6410 arm板上
命令如下 :
mount /dec/sda1 /mnt/nfs
cd /mnt/nfs
cp a /mnt/yaffs/Qtopia/lib
cp *.bmp /mnt/yaffs/Qtopia/lib
cp *.so.* /mnt/yaffs/Qtopia/lib
./a(交叉编译后的可执行文件)
3.运行结果如下
至此,本篇已结束,如有不对的地方,欢迎您的建议与指正。同时期待您的关注,感谢您的阅读,谢谢!
如有侵权,请联系小编,小编对此深感抱歉,届时小编会删除文章,立即停止侵权行为,请您多多包涵。
既然都看到这里,领两个红包在走吧!
以下两个红包每天都可以领取
1.支付宝搜索 522398497,或扫码支付宝红包海报。
支付宝扫一扫,每天领取大红包
2.微信红包,微信扫一扫即可领取红包
微信扫一扫,每天领取微信红包
小礼物走一走,来简书关注我