⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tetris_cpp.cpp

📁 使用SDL库,做的俄罗斯方框,支持调速度,多彩方块
💻 CPP
字号:
//============================================================================// Name        : tetris_cpp.cpp// Author      : gogo649// Version     :// Copyright   : Your copyright notice// Description : tetris in C, SDL SDL_image SDL_mixer//============================================================================//俄罗斯方块程序#include <SDL/SDL.h>#include <iostream>#include <SDL/SDL_image.h>#include <SDL/SDL_mixer.h>using namespace std;#define HW 512#define HH 720#define BLOCK_W 30  //象素值#define BLOCK_H 30#define GAME_W 10  //BLOCK值#define GAME_H 24#define MAXUPDATES 8*GAME_W+4*4#define FPS 40#define MAXINT 999999999#define FONT_WIDTH 16#define FONT_HIGHT 16SDL_Surface *screen,			*back,			*block,			*block_2,			*block_3,			*block_4,			*block_5,			*block_6,			*frame,			*font,			*up,			*bottom;int gamestate[GAME_W + 2][GAME_H + 1] = { };int score;typedef struct {	int coor[4][2]; //相对坐标	int rotate_next;} shape;typedef struct {	int x, y; //block坐标	int type; //形状	int color;	SDL_Surface *img;} object;enum {	BOTTOM_WAV, EXPLODE_WAV, EXCELLENT_WAV, NUM_WAVES};Mix_Chunk *sounds[NUM_WAVES];object current, next;//速度int speed = 10;SDL_Rect src[MAXUPDATES];SDL_Rect dst[MAXUPDATES];int numupdates;typedef struct {	SDL_Rect *src, *dst;	SDL_Surface *img;} Blit;Blit blits[MAXUPDATES];shape SP[19] = { { 0, 0, 1, 0, 0, 1, 0, 2, 1 },		{ -1, 0, -1, 1, 0, 1, 1, 1, 2 }, { 0, 2, 1, 2, 1, 1, 1, 0, 3 }, { -1,				1, 0, 1, 1, 1, 1, 2, 0 },		{ 0, 0, 0, 1, 0, 2, 1, 2, 5 }, { -1, 1, 0, 1, 1, 1, 1, 0, 6 }, { 0, 0,				1, 0, 1, 1, 1, 2, 7 }, { 0, 2, 0, 1, 1, 1, 2, 1, 4 },		{ 0, 0, -1, 0, 1, 0, 0, 1, 9 }, { 0, 0, 0, 1, 0, 2, 1, 1, 10 }, { -1,				1, 0, 1, 1, 1, 0, 0, 11 }, { 0, 0, 0, 1, 0, 2, -1, 1, 8 },		{ 0, 0, -1, 0, 0, 1, 1, 1, 13 }, { 0, 1, 0, 2, 1, 1, 1, 0, 12 },		{ 0, 0, 0, 1, 1, 0, -1, 1, 15 }, { 0, 0, 0, 1, 1, 1, 1, 2, 14 },		{ 0, 0, 0, 1, 0, 2, 0, 3, 17 }, { -1, 1, 0, 1, 1, 1, 2, 1, 16 },		{ 0, 0, 0, 1, 1, 1, 1, 0, 18 } };void drawobject(object sprite) {	Blit *update;	for (int i = 0; i < 4; i++) {		update = &blits[numupdates++];		update->img = sprite.img;		update->src->x = update->src->y = 0;		update->src->w = BLOCK_W;		update->src->h = BLOCK_H;		update->dst->x = (sprite.x + SP[sprite.type].coor[i][0]) * BLOCK_W				- frame->w;		update->dst->y = (sprite.y - SP[sprite.type].coor[i][1]) * BLOCK_H				- frame->h;		update->dst->w = BLOCK_W;		update->dst->h = BLOCK_H;	}}void eraseobject(object sprite) {	Blit *update;	for (int i = 0; i < 4; i++) {		update = &blits[numupdates++];		update->img = back;		update->src->x = (sprite.x + SP[sprite.type].coor[i][0]) * BLOCK_W				- frame->w;		update->src->y = (sprite.y - SP[sprite.type].coor[i][1]) * BLOCK_H				- frame->h;		update->src->w = BLOCK_W;		update->src->h = BLOCK_H;		update->dst->x = (sprite.x + SP[sprite.type].coor[i][0]) * BLOCK_W				- frame->w;		update->dst->y = (sprite.y - SP[sprite.type].coor[i][1]) * BLOCK_H				- frame->h;		update->dst->w = BLOCK_W;		update->dst->h = BLOCK_H;	}}void updatescene() {	for (int i = 0; i < numupdates; i++)		SDL_BlitSurface(blits[i].img, blits[i].src, screen, blits[i].dst);	SDL_UpdateRects(screen, numupdates, dst);	numupdates = 0;}void Rotate() {	int i, x, y;	int type = SP[current.type].rotate_next;	for (i = 0; i < 4; i++) {		x = current.x + SP[type].coor[i][0];		y = current.y + SP[type].coor[i][1];		if (gamestate[x][y] != 0)			break;	}	if (i == 4)		current.type = type;	else		return;}void drawframe() {	int i = 0, j = 0, flag = 0;	int down[4];	for (i = 0; i < 4; i++)		down[j++] = current.x + SP[current.type].coor[i][0];	SDL_Rect dst;	dst.w = frame->w;	dst.h = frame->h;	for (i = 0; i < HH; i += frame->h) {		dst.x = 0;		dst.y = i;		SDL_BlitSurface(frame, NULL, screen, &dst);		SDL_UpdateRects(screen, 1, &dst);		dst.x = frame->w + GAME_W * BLOCK_W;		SDL_BlitSurface(frame, NULL, screen, &dst);		SDL_UpdateRects(screen, 1, &dst);	}	for (i = 0; i < frame->w + GAME_W * BLOCK_W; i += frame->w) {		dst.y = HH - frame->h;		dst.x = i;		flag = 0;		for (j = 0; j < 4; j++) {			if (dst.x == (down[j] * BLOCK_H) - frame->w) {				SDL_BlitSurface(bottom, NULL, screen, &dst);				SDL_UpdateRects(screen, 1, &dst);				i += frame->w;				dst.x = i;				SDL_BlitSurface(bottom, NULL, screen, &dst);				flag = 1;			}		}		if (!flag)			SDL_BlitSurface(frame, NULL, screen, &dst);		SDL_UpdateRects(screen, 1, &dst);	}}void init() {	int i;	if (SDL_Init(SDL_INIT_AUDIO| SDL_INIT_VIDEO) < 0)		fprintf(stderr, "init error\n");	if ((screen = SDL_SetVideoMode(HW, HH, 32, SDL_HWSURFACE| SDL_DOUBLEBUF))			== NULL)		fprintf(stderr, "set video mode error\n");	srand(time(NULL));	atexit(SDL_Quit);	SDL_WM_SetCaption("tetris", "");	for (i = 0; i < MAXUPDATES; i++) //更新矩阵进行锁定	{		blits[i].src = &src[i];		blits[i].dst = &dst[i];	}	for (i = 0; i < GAME_W + 2; i++)		//设置底线		gamestate[i][GAME_H] = 1;	for (i = 0; i < GAME_H; i++)		gamestate[0][i] = gamestate[GAME_W + 1][i] = 1;	next.x = 13;	next.y = 10;	if (Mix_OpenAudio(22050, AUDIO_U16, 1, 512) < 0) {		fprintf(stderr,		"Warning: Couldn't set 22050 Hz 16-bit audio\n- Reason: %s\n",				SDL_GetError());	}}SDL_Surface* LoadIMG(const char *name) {	SDL_Surface *tmp, *ok;	if ((tmp = IMG_Load(name)) == NULL) {		fprintf(stderr, "load %s error\n", name);		return NULL;	}	ok = SDL_DisplayFormat(tmp);	SDL_FreeSurface(tmp);	SDL_SetColorKey(ok, SDL_SRCCOLORKEY| SDL_RLEACCEL, *(Uint32 *) ok->pixels);	return ok;}void showstring(int x, int y, const char *string) {	int length = strlen(string), i;	SDL_Rect src, dst;	dst.y = y;	src.w = FONT_WIDTH;	src.h = FONT_HIGHT;	for (i = 0; i < length; i++) {		dst.x = x + i * FONT_WIDTH;		if (string[i] >= 'a' && string[i] <= 'o') {			src.x = (string[i] - 'a' + 1) * FONT_WIDTH;			src.y = 2 * FONT_HIGHT;		} else {			src.x = (string[i] - 'p') * FONT_WIDTH;			src.y = 3 * FONT_HIGHT;		}		SDL_BlitSurface(font, &src, screen, &dst);		SDL_UpdateRects(screen, 1, &dst);	}}void LoadData() {	back = LoadIMG("C:\\tetris\\back.jpg");	block = LoadIMG("C:\\tetris\\element.png");	block_2 = LoadIMG("C:\\tetris\\element_2.png");	block_3 = LoadIMG("C:\\tetris\\element_3.png");	block_4 = LoadIMG("C:\\tetris\\element_4.png");	block_5 = LoadIMG("C:\\tetris\\element_5.png");	block_6 = LoadIMG("C:\\tetris\\element_6.png");	frame = LoadIMG("C:\\tetris\\frame.png");	font = LoadIMG("C:\\tetris\\glassfont1.png");	up = LoadIMG("C:\\tetris\\up.png");	bottom = LoadIMG("C:\\tetris\\bottom.png");//	sounds[BOTTOM_WAV] = Mix_LoadWAV("bottom.wav");//	sounds[EXPLODE_WAV] = Mix_LoadWAV("explosion.wav");//	sounds[EXCELLENT_WAV] = Mix_LoadWAV("excellent.wav");}int moveable(int faceing) {	int x, y, i;	switch (faceing) {	case -1:		for (i = 0; i < 4; i++) {			x = current.x + SP[current.type].coor[i][0] - 1;			y = current.y - SP[current.type].coor[i][1];			if (gamestate[x][y] != 0)				break;		}		if (i == 4)			return 1;		else			return 0;	case 0:		for (i = 0; i < 4; i++) {			x = current.x + SP[current.type].coor[i][0];			y = current.y - SP[current.type].coor[i][1] + 1;			if (gamestate[x][y] != 0)				break;		}		if (i == 4)			return 1;		else			return 0;	case 1:		for (i = 0; i < 4; i++) {			x = current.x + SP[current.type].coor[i][0] + 1;			y = current.y - SP[current.type].coor[i][1];			if (gamestate[x][y] != 0)				break;		}		if (i == 4)			return 1;		else			return 0;	default:		return 0;	}}int atbottom() {	if (moveable(0))		return 0;	else		return 1;}int over() {	int y,  i;	for (i = 0; i < 4; i++) {		y = current.y - SP[current.type].coor[i][1];		if (y < 4)			break;	}	if (i == 4)		return 0;	else		return 1;}void FreeData() {	SDL_FreeSurface(block);	SDL_FreeSurface(block_2);	SDL_FreeSurface(block_3);	SDL_FreeSurface(block_4);	SDL_FreeSurface(block_5);	SDL_FreeSurface(block_6);	SDL_FreeSurface(back);	SDL_FreeSurface(frame);	SDL_FreeSurface(font);	SDL_FreeSurface(up);	SDL_FreeSurface(bottom);	Mix_CloseAudio();}void drawupline() {//	SDL_Rect src, dst;//	dst.y = 4 * BLOCK_H;//	dst.x = 2 * frame->w + (GAME_W - 2) * BLOCK_W;//	dst.w = up->w;//	dst.h = up->h;//	src.x = src.y = 0;//	src.h = up->h;//	src.w = 2 * BLOCK_W;//	SDL_BlitSurface(up, &src, screen, &dst);//	SDL_UpdateRects(screen, 1, &dst);}SDL_Surface* ch_block_col(int color){	switch (color) {		case 1:			return block;			break;		case 2:			return block_2;			break;		case 3:			return block_3;			break;		case 4:			return block_4;			break;		case 5:			return block_5;			break;		case 6:			return block_6;			break;		default:			return block;			break;	}}void creatblock() {	int type = rand() % 19;	int color = rand() % 6 +1;	next.type = type;	next.color = color;	next.img = ch_block_col(color);	current.x = GAME_W / 2;	current.y = 2;}void moveblock(int faceing) {	int can = moveable(faceing);	if (can) {		switch (faceing) {		case -1:			current.x--;			break;		case 0:			current.y++;			break;		case 1:			current.x++;			break;		};	}}void wait() {	Uint32 this_tick;	static Uint32 next_tick = 0;	this_tick = SDL_GetTicks();	if (next_tick > this_tick)		SDL_Delay(next_tick - this_tick);	next_tick = this_tick + 1000 / FPS;}void addscore(int num) {	switch (num) //消掉的行数	{	case 1:		score += 100;		break;	case 2:		score += 300;		break;	case 3:		score += 700;		break;	case 4:		score += 1500;		break;	default:		break;	};	if (num >= 3)		Mix_PlayChannel(EXCELLENT_WAV, sounds[EXCELLENT_WAV], 0);	else		Mix_PlayChannel(EXPLODE_WAV, sounds[EXPLODE_WAV], 0);}void shownum(int x, int y, int num_char, int num) {	int a, i = num_char - 1;	int S[10] = { };	while (num != 0) {		a = num % 10;		S[i--] = a;		num /= 10;	}	SDL_Rect src, dst;	for (i = 0; i < num_char; i++) {		src.x = S[i] * FONT_WIDTH;		src.y = 1 * FONT_HIGHT;		src.w = FONT_WIDTH;		src.h = FONT_HIGHT;		dst.x = x + i * FONT_WIDTH;		dst.y = y;		dst.w = FONT_WIDTH;		dst.h = FONT_HIGHT;		SDL_BlitSurface(back, &dst, screen, &dst);		SDL_BlitSurface(font, &src, screen, &dst);		SDL_UpdateRects(screen, 1, &dst);	}}void eraseline(int line) {	int i, j;	for (j = line - 1; j > 0; j--)		for (i = 1; i < GAME_W + 1; i++)			gamestate[i][j + 1] = gamestate[i][j];}void collision() {	int num = 0, i, j;	for (j = GAME_H - 1; j > 0; j--) {		for (i = 1; i < GAME_W + 1; i++) {			if (gamestate[i][j] == 0)				break;		}		if (i == GAME_W + 1) {			num++;			eraseline(j++);		}	}	if (num != 0)		addscore(num);}void rungame() {	SDL_Event event;	int point = 0;	Uint8 *key;	int run = 1, i, j, x, y, w = 0, s = 0;	int up = 0, left = 0, right = 0, tr = 10, tl = 10;	numupdates = 0;	score = 0;	drawframe();	creatblock();	current.type = next.type;	current.color = next.color;	current.img = next.img;	creatblock();	drawobject(next);	x = frame->w * 4 + GAME_W * BLOCK_W;	y = BLOCK_H * (GAME_H - 8);	showstring(x, y, "speed");	y = BLOCK_H * (GAME_H - 7);	shownum(x, y, 1, 11 - speed);	x = frame->w * 4 + GAME_W * BLOCK_W;	y = BLOCK_H * (GAME_H - 3);	showstring(x, y, "score");	x = frame->w * 4 + GAME_W * BLOCK_W;	y = 6 * BLOCK_H;	showstring(x, y, "next");	x = 2 * frame->w + GAME_W * BLOCK_W;	y = 4 * BLOCK_H;	showstring(x, y, "upper line");	x = frame->w * 4 + GAME_W * BLOCK_W;	y = BLOCK_H * (GAME_H - 2);	shownum(x, y, 6, score);	while (run) {		wait();		eraseobject(current);		drawframe();		drawupline();		point++;		if (point % (speed * (FPS / 10)) == 0)			moveblock(0);		if (point > MAXINT)			point -= MAXINT;		while (SDL_PollEvent(&event)) {			switch (event.type) {			case SDL_QUIT:				return;			};		}		key = SDL_GetKeyState(NULL);		if (!w && key[SDLK_w])			speed--;		if (speed < 1)			speed = 1;		w = key[SDLK_w];		if (!s && key[SDLK_s])			speed++;		if (speed > 10)			speed = 10;		s = key[SDLK_s];		//		if (key[SDLK_LEFT])			tl--;		else			tl = 10;		if (tl <= 0 && key[SDLK_LEFT])			moveblock(-1);		if (tl > 0 && !left && key[SDLK_LEFT])			moveblock(-1);		left = key[SDLK_LEFT];		//		if (key[SDLK_RIGHT])			tr--;		else			tr = 10;		if (tr <= 0 && key[SDLK_RIGHT])			moveblock(1);		if (tr > 0 && !right && key[SDLK_RIGHT])			moveblock(1);		right = key[SDLK_RIGHT];		//		if (key[SDLK_SPACE])			moveblock(0);		//		if (!up && key[SDLK_UP])			Rotate();		up = key[SDLK_UP];		//		drawobject(current);		updatescene();		speed -= score / 10000;		if (speed < 1)			speed = 1;		else if (speed > 10)			speed = 10;		shownum(frame->w * 4 + GAME_W * BLOCK_W, BLOCK_H * (GAME_H - 7), 2, 11				- speed);		if (atbottom()) {			if (over() )				return;			Mix_PlayChannel(BOTTOM_WAV, sounds[BOTTOM_WAV], 0);			eraseobject(next);			 for (i = 0; i < 4; i++) {				x = current.x + SP[current.type].coor[i][0];				y = current.y - SP[current.type].coor[i][1];				gamestate[x][y] = current.color;			}			collision();			shownum(frame->w * 4 + GAME_W * BLOCK_W, BLOCK_H * (GAME_H - 2), 6,					score);			eraseobject(current);			updatescene();			SDL_Rect dst;			for (j = GAME_H - 1; j > 0; j--)				for (i = 1; i < GAME_W + 1; i++) {					dst.x = i * BLOCK_W - frame->w;					dst.y = j * BLOCK_H - frame->h;					if (gamestate[i][j]) {						//什么颜色的方块落下还是什么颜色 gamestate[][]保存颜色状态						SDL_BlitSurface(ch_block_col(gamestate[i][j]), NULL, screen, &dst);					} else {						SDL_BlitSurface(back, &dst, screen, &dst);					}					SDL_UpdateRects(screen, 1, &dst);				}			//当前 = 下一个			{			current.type = next.type;			current.img = next.img;			current.color = next.color;			}			creatblock();			drawobject(next);		}		updatescene();	}}int main(int argc, char *argv[]) {		init();		LoadData();		SDL_BlitSurface(back, NULL, screen, NULL);		SDL_Flip(screen);		numupdates = 0;		rungame();		FreeData();}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -