前几天为了忽悠一个大一小弟弟答应他给他写个打砖块。。。用了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名字被改了。。。

 =================================================================

今天过生日,发现这个博客快被荒废了,于是偶尔来写点东西,虽然是意义不大的东西啦。。。点进来的各位见笑了。

posted on 2011-12-13 21:04  Snafloda  阅读(1066)  评论(0编辑  收藏  举报