前几天为了忽悠一个大一小弟弟答应他给他写个打砖块。。。用了SDL,顺便试了一下beta版本的SDL1.3。。。发现用3D api作底层的SDL1.3的新加入的2D绘图接口的绘图速度跟以前相比真是逆天了。。。(相较之用DX由底层堆起来的2D程序绘制效率都逊色了。。。)果断弃SDL1.2用1.3。
然后这几天折腾好LINUX MINT 12,发现源里的SDL是1.2。。。 于是,下载,编译。
然后去源里扒SDL_ttf与SDL_image,还要靠这俩绘制文本哪。。。
然后,发现了个大问题:源里这俩库是依赖与SDL库的。装这俩前提是装SDL1.2。
于是去网上下了SDL_ttf,SDL_image的源码包,编译,安装,其间还特别留意了它们所使用的SDL的路径是我编译的版本。。。
然后。。。所有使用SDL相关的小游戏都不能运行了。 初始化失败,然后提示段错误。
而我写的那玩意儿即使编译通过也会直接初始化失败,错在 SDL_CreateRender函数失败,错误提示找不到显示设备(具体怎么提示的我也忘了)。总之是非常奇怪的错误。
后来卸掉编译安装的SDL_ttf与SDL_image,原来的SDL游戏都能用了。
然后,通过链接自行编译的SDL_1.3,还有源里的SDL_ttf和SDL_image,我在win里写的东西终于成功编译运行了。。。
gcc -o blockRevolutionNew testSDL1.c -I/usr/local/include/SDL -I/usr/include/SDL -Wl,-rpath,/usr/local/lib -L/usr/local/lib -lSDL -L/usr/lib -lSDL_image -lSDL_ttf -std=c99
回头查看了一下SDL_image的编译指令,发现了某些参数:
-g -O2 -D_REENTRANT -I/usr/local/include/SDL -o .libs/showimage showimage.o -Wl,-rpath -Wl,/usr/local/lib ./.libs/libSDL_image.so -L/usr/local/lib /usr/local/lib/libSDL.so
我这个菜鸟也看不太懂,只是发现它生成的文件是调试版本,链接的是我编译的SDL的链接库,而且其中还强制指向动态链接库的位置为我编译的SDL的位置。
顺便,把写得死烂的代码贴上(到处都是全局变量,各种混乱我自重,而且小球与挡板碰撞检测的代码逻辑有问题,总之雷雷更健康)
#include "SDL.h" #include "SDL_render.h" #include <stdio.h> #include <stdlib.h> #include <SDL_image.h> #include <SDL_ttf.h> #include <time.h> //time library of c //define width and height of the window #define WIDTH 800 #define HEIGHT 600 #define BLOCKNUM 36 #define BOARDY 420 #define BALLY 300 #define SPEED 1 #define BOARDSPEED 3 #define BLOCKSPERLINE 6 //the amount of blocks per line //SDL_Surface* screen; SDL_Event MyEvent; SDL_Window* win = NULL; SDL_Renderer* renderer = NULL; SDL_Texture* bgTex = NULL; //texture of background image SDL_Texture* boardTex = NULL; //texture of board SDL_Texture* ballTex = NULL; //texture of ball SDL_Texture* scoreTex = NULL; //height and width of the board int boardWidth = 0; int boardHeight = 0; //height and of the ball int ballWidth = 0; int ballHeight = 0; //score int score = 0; //lives int lives = 5; // rects... SDL_Rect boardRect; SDL_Rect ballRect; SDL_Rect scoreRect; //font TTF_Font* font; //declarations of functions that will be defined int WindowInit(); int GameMain(); int LoadBitmap(); int GameQuit(); int UpdateBall(); int UpdateBoard(); void GameInit(); int UpdateBlocks(); int DrawScore(); //struct of a brick struct MyBrick{ Uint8 r; Uint8 g; Uint8 b; Uint8 a; int unhit; int x; int y; }; //bricks struct MyBrick blocks[BLOCKNUM]; int blockStep = ( WIDTH - 40 ) / BLOCKSPERLINE; int blockWidth = 0; int blockHeight = 0; int boardMoved = 0; int main(int argc, char *argv[]) { if(!WindowInit()) exit(1); printf("SDL initialized.\n"); if(!LoadBitmap()) exit(1); GameInit(); if(!(GameMain())) exit(1); printf("Quiting SDL.\n"); /* Shutdown all subsystems */ GameQuit(); SDL_Quit(); printf("Quiting....\n"); exit(0); } //Initialization int WindowInit() { //set position, size and window tittle win = SDL_CreateWindow("BlocksRevolution -- By: Adolfans", 100, 100, WIDTH, HEIGHT, 0); if(!win) return 0; renderer = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED); if(!renderer) { printf("%s\n",SDL_GetError()); return 0; } if(TTF_Init()==-1) { printf("TTF_Init: %s\n", TTF_GetError()); exit(2); } //msyh.ttf font=TTF_OpenFont("Ubuntu-BI.ttf", 64); if(!font) printf("TTF_OpenFont: %s\n", TTF_GetError()); // handle error return 1; } //game main loop int GameMain() { //static time_t timeNow = time(0); //static int timeNow = SDL_GetTicks(); static clock_t timeNow; timeNow = clock(); while(1) { SDL_PollEvent( &MyEvent ); // if clicked quit, quit game main loop if( MyEvent.type == SDL_QUIT) return 1; // if( SDL_GetTicks() - timeNow >= 1) if( clock() - timeNow >= (10/SPEED) ) { // timeNow = SDL_GetTicks(); timeNow = clock(); if( MyEvent.type == SDL_KEYDOWN ) { boardMoved = 0; //printf("some key is pressed"); if(MyEvent.key.keysym.sym == SDLK_LEFT) {/* boardRect.x--;*/ boardMoved = -1; //UpdateBoard(-1); }else if(MyEvent.key.keysym.sym == SDLK_RIGHT) { /* boardRect.x++;*/ boardMoved = 1; //UpdateBoard(1); } if(MyEvent.key.keysym.sym == SDLK_ESCAPE) { return 1; } UpdateBoard(); } UpdateBall(); boardMoved = 0; } SDL_RenderClear(renderer); SDL_RenderCopy(renderer, bgTex, NULL, NULL); SDL_RenderCopy(renderer, boardTex, NULL, &boardRect); SDL_RenderCopy(renderer, ballTex, NULL, &ballRect); UpdateBlocks(); DrawScore(); SDL_RenderPresent(renderer); } return 1; } int LoadBitmap() { //SDL_SetAlpha( image, SDL_SRCALPHA, 0); SDL_Surface* image; image = IMG_Load("c.png"); if (image == NULL) { fprintf( stderr, "Couldn't load %s: %s\n", "c.png", SDL_GetError() ); return 0; } bgTex = SDL_CreateTextureFromSurface( renderer, image ); SDL_FreeSurface( image ); image = IMG_Load("board.png"); boardWidth = image->w; boardHeight = image->h; boardTex = SDL_CreateTextureFromSurface( renderer, image ); SDL_FreeSurface( image ); image = 0; image = IMG_Load("BALL.png"); ballWidth = image->w; ballHeight = image->h; ballTex = SDL_CreateTextureFromSurface( renderer, image ); SDL_FreeSurface( image ); return 1; } void GameInit() { //initialize game data blockWidth = blockStep - 2; //init rects boardRect.y = BOARDY; boardRect.x = WIDTH/2 - boardWidth/2; boardRect.h = boardHeight; boardRect.w = boardWidth; ballRect.y = BALLY - ballHeight/2; ballRect.x = WIDTH/2 - ballWidth/2; ballRect.h = ballHeight; ballRect.w = ballWidth; //initialize blocks, set it to 0 means it is not hit memset( blocks, 0, sizeof(blocks) ); blockHeight = 50; //Initialize color of the blocks for( int i = 0; i < BLOCKNUM; i++ ) { blocks[i].r = rand()%255; blocks[i].g = rand()%255; blocks[i].b = rand()%255; blocks[i].a = rand()%255; blocks[i].x = 20 + i%6*blockStep; blocks[i].y = 20 + i/6*(blockHeight+2); } } int GameQuit() { /* Free the allocated BMP surface */ //SDL_FreeSurface(image); SDL_DestroyTexture( bgTex ); SDL_DestroyTexture( boardTex ); SDL_DestroyTexture( ballTex ); // SDL_DestroyTexture( scoreTex ); SDL_DestroyRenderer( renderer ); SDL_DestroyWindow( win ); return 1; } int UpdateBlocks() { static SDL_Rect rectTmp; rectTmp.w = blockWidth; rectTmp.h = blockHeight; for( int i = 0; i < BLOCKNUM; i++ ) { if( blocks[i].unhit == 0 ) { rectTmp.x = blocks[i].x; rectTmp.y = blocks[i].y; SDL_SetTextureColorMod( boardTex, blocks[i].r, blocks[i].g, blocks[i].b ); SDL_RenderCopy(renderer, boardTex, NULL,&rectTmp); } } return 1; } int UpdateBall() { static int leftBorder = 0; static int rightBorder ; rightBorder = WIDTH - ballWidth; static int topBorder = 0; static int bottomBorder; bottomBorder = HEIGHT - ballHeight; static int criticalBorder; criticalBorder = boardRect.y; //velocity of that ball static int ballVelX = 1; static int ballVelY = 3; //position of the ball // static int ballX = WIDTH/2; // static int ballY = BALLY; //update // ballX += ballVelX; // ballY += ballVelY; ballRect.x += ballVelX; ballRect.y += ballVelY; if( ballRect.x <= leftBorder || ballRect.x >= rightBorder ) ballVelX = -ballVelX; else if( ballRect.y <= topBorder || ballRect.y >= bottomBorder ) ballVelY = -ballVelY; if( ballRect.y >= bottomBorder ) lives--; //hit on the board /* if( ballRect.y + ballRect.h >= criticalBorder && \ ballRect.x >= boardRect.x && \ ballRect.x <= boardRect.x + boardRect.w) ballVelY = -ballVelY; */ if( ballVelY > 0 && \ ballRect.x <= boardRect.x + boardRect.w && \ ballRect.y + ballRect.h >= criticalBorder && \ ballRect.y + ballRect.h < criticalBorder + boardHeight && \ ballRect.x >= boardRect.x ) { ballVelY = -ballVelY; if( boardMoved < 0 ) { ballVelX -= rand()%2; }else if( boardMoved > 0 ) { ballVelX += rand()%2; } } for( int i = 0; i < BLOCKNUM; i++ ) { /* if( ballRect.x + ballWidth > blocks[i].x && \ ballRect.x + ballWidth < blocks[i].x + blockWidth && \ ballRect.y + ballHeight > blocks[i].y && \ ballRect.y + ballWidth < blocks[i].y + blockHeight) { if }*/ //if( ballRect.x + ballWidth >= blocks[i].x && ballRect.x < blocks[i].x) //×ó if( blocks[i].unhit==1 ) continue; int a = blocks[i].x - ballWidth; int b = blocks[i].y - ballHeight; int a2 = blocks[i].x + blockWidth; int b2 = blocks[i].y + blockHeight; if( ballRect.x >= a && ballRect.x <= a2 && \ ballRect.y >= b && ballRect.y <= b2) { if( (ballRect.x - a < ballRect.x - a && ballRect.x - a < b2 - ballRect.y) ||\ (a2-ballRect.x < ballRect.x - a && a2-ballRect.x < b2 - ballRect.y)) ballVelX = -ballVelX; else ballVelY = -ballVelY; blocks[i].unhit=1; score++; } } return 1; } int UpdateBoard( ) { static int leftBorder = 0; static int rightBorder; rightBorder = WIDTH - boardWidth; if( boardMoved < 0 ) { if( boardRect.x-1 < leftBorder ) return 1; else boardRect.x-=BOARDSPEED; }else { if( boardRect.x+1 > rightBorder ) return 1; else boardRect.x+=BOARDSPEED; } return 1; } int DrawScore() { SDL_Color color={0,0,0}; SDL_Surface *text_surface; char scoreText[100]; sprintf( scoreText, "score: %d lives: %d", score, lives ); if(!(text_surface=TTF_RenderText_Blended(font,scoreText,color))) { printf("text_surface drawing error"); //handle error here, perhaps print TTF_GetError at least return 0; } scoreRect.w = text_surface->w; scoreRect.h = text_surface->h; scoreRect.x = WIDTH/2 - text_surface->w/2; scoreRect.y = HEIGHT - 70; scoreTex = SDL_CreateTextureFromSurface( renderer, text_surface ); //perhaps we can reuse it, but I assume not for simplicity. SDL_FreeSurface(text_surface); SDL_RenderCopy(renderer, scoreTex, NULL, &scoreRect); SDL_DestroyTexture( scoreTex ); return 1; }
另外发现:NEHE的opengl教程,用SDL1.3编译可能会出一些问题,其中有一个检测键盘输入的API名字被改了。。。
=================================================================
今天过生日,发现这个博客快被荒废了,于是偶尔来写点东西,虽然是意义不大的东西啦。。。点进来的各位见笑了。