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

📄 game.cpp

📁 LBreakout a breakout-style arcade game for Linux Requirements: X11, SDL[1.0 or better] Inst
💻 CPP
字号:
/***************************************************************************                          game.cpp  -  description                             -------------------    begin                : Tue Feb 29 2000    copyright            : (C) 2000 by Michael Speck    email                :  ***************************************************************************//*************************************************************************** *                                                                         * *   This program is free software; you can redistribute it and/or modify  * *   it under the terms of the GNU General Public License as published by  * *   the Free Software Foundation; either version 2 of the License, or     * *   (at your option) any later version.                                   * *                                                                         * ***************************************************************************/#include <sys/timeb.h>#include <stdlib.h>#include <string.h>#include "game.h"#include "breakout.h"#include "menumanager.h"#include "level.h"#ifdef SOUNDextern SndSrv sndsrv;#endifextern Sdl sdl;extern int fast_quit;extern DrawRgn dr_src, dr_dst;Game::Game(){	//video mode#ifdef SOUND		Sdl_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER | SDL_INIT_JOYSTICK );#else		Sdl_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_JOYSTICK);#endif	if (Sdl_SetVideoMode(450, 325, 16, SDL_HWSURFACE))		exit(1);	printf( "1\n" );	SDL_WM_SetCaption("LBreakout", 0);	printf( "2\n" );			//load title	title = SSur_Load("title.bmp", SDL_HWSURFACE);	printf( "3\n" );		SDL_SetColorKey(title, 0, 0);	printf( "4\n" );		if (title == 0) {		title = SSur_Create(sdl.scr->w, sdl.scr->h, SDL_HWSURFACE);		DR_SETFULLDST(title);		SSur_Fill(0x0);	}	f_copy = SFnt_Load("font_s.sdlfnt");	f_copy->algn = TA_X_RIGHT | TA_Y_BOTTOM;	SFnt_Write(f_copy, title, title->w-3, title->h-1, "(C) 2000 Michael Speck", 0);	f_copy->algn = TA_X_LEFT | TA_Y_BOTTOM;	SFnt_Write(f_copy, title, 0, title->h-1, "http://lgames.sourceforge.net", 0);    SFnt_Free(f_copy);	printf( "5\n" );    //load logo    logo = SSur_Load("logo.bmp", SDL_HWSURFACE);//  SDL_SetAlpha(logo, SDL_SRCALPHA, 16);    if (logo == 0)    	exit(1);    logo_x = (sdl.scr->w - logo->w) / 2;    logo_y = 40;    		//load fonts	f_menu_w = SFnt_LoadFixed("f_yellow.bmp", 32, 96, 10);	f_menu_w->algn = TA_X_CENTER | TA_Y_CENTER;	f_menu_b = SFnt_LoadFixed("f_white.bmp", 32, 96, 10);	f_menu_b->algn = TA_X_CENTER | TA_Y_CENTER;	f_hiscore = SFnt_LoadFixed("f_yellow.bmp", 32, 96, 10);	f_hiscore->algn = TA_X_LEFT | TA_Y_TOP;	f_enlgt_hiscore = SFnt_LoadFixed("f_white.bmp", 32, 96, 10);	f_enlgt_hiscore->algn = TA_X_LEFT | TA_Y_TOP;		//restricted keys	memset(val_ctrl_keys, 0, sizeof(val_ctrl_keys));	for (int i = 32; i < 128; i++)		val_ctrl_keys[i] = 1;	val_ctrl_keys[SDLK_RETURN] = 0;	val_ctrl_keys[SDLK_ESCAPE] = 0;	val_ctrl_keys[SDLK_q] = 0;	val_ctrl_keys[SDLK_r] = 0;	val_ctrl_keys[SDLK_f] = 0;	val_ctrl_keys[SDLK_p] = 0;	val_ctrl_keys[SDLK_UP] = 1;	val_ctrl_keys[SDLK_DOWN] = 1;	val_ctrl_keys[SDLK_RIGHT] = 1;	val_ctrl_keys[SDLK_LEFT] = 1;	//breakout	breakout = new BreakOut();			//create menumanager	char    *str_gfx[] = {	    "Off",	    "Low",	    "High"	};	char    *str_ctrls[] = {	    "Only Keyboard",	    "Only Mouse",	    "Keyboard&Mouse"	};	char    *str_diff[] = {	    "Easy",	    "Medium",	    "Hard"	};	mm = new MenuManager(title, sdl.scr->w / 2, 240, f_menu_w, f_menu_b, 9, val_ctrl_keys);	//create menus	Menu *menu[9];	menu[0] = new Menu("main", 4);	menu[1] = new Menu("newgame", 4);	menu[2] = new Menu("options", 6);	menu[3] = new Menu("graphics", 8);	menu[4] = new Menu("audio", 4);	menu[5] = new Menu("controls", 8);	menu[6] = new Menu("game", 10);	menu[7] = new Menu("level", 4);	menu[8] = new Menu("mouse", 5);    menu[0]->InsertItem(0, new MenuItem("New Game", AT_NEWGAME ));    menu[0]->InsertItem(1, new MenuItem());    menu[0]->InsertItem(2, new MenuItem());    menu[0]->InsertItem(3, new MenuItem("Quit", AT_QUIT));    menu[1]->InsertItem(0, new MenuItem("New Game", AT_NEWGAME));    menu[1]->InsertItem(1, new MenuItem("Name", breakout->Setup()->name, 10));    menu[1]->InsertItem(2, new MenuItem());    menu[1]->InsertItem(3, new MenuItem("Back", menu[0]));    menu[2]->InsertItem(0, new MenuItem("Game", menu[6]));    menu[2]->InsertItem(1, new MenuItem("Controls", menu[5]));    menu[2]->InsertItem(2, new MenuItem("Graphics", menu[3]));#ifdef SOUND    menu[2]->InsertItem(3, new MenuItem("Audio", menu[4]));#else    menu[2]->InsertItem(3, new MenuItem("Audio"));#endif    menu[2]->InsertItem(4, new MenuItem());    menu[2]->InsertItem(5, new MenuItem("Back", menu[0]));    menu[3]->InsertItem(0, new MenuItem("Transparency:", &breakout->Setup()->trp, "Off", "On"));    menu[3]->InsertItem(1, new MenuItem("Animations:", &breakout->Setup()->anim, str_gfx, 3));    menu[3]->InsertItem(2, new MenuItem("Bonus Information:", &breakout->Setup()->no_exdisp, "On", "Off"));	menu[3]->InsertItem(3, new MenuItem());    menu[3]->InsertItem(4, new MenuItem("Background:", &breakout->Setup()->bkgnd, "Off", "On"));    menu[3]->InsertItem(5, new MenuItem("Display:", &breakout->Setup()->fullscreen, "Window", "Fullscreen"));	menu[3]->InsertItem(6, new MenuItem());    menu[3]->InsertItem(7, new MenuItem("Back", menu[2]));    menu[4]->InsertItem(0, new MenuItem("Sound:", &breakout->Setup()->snd_on, "Off", "On"));    menu[4]->InsertItem(1, new MenuItem("Volume:", &breakout->Setup()->snd_vol, 1, 8));    menu[4]->InsertItem(2, new MenuItem());    menu[4]->InsertItem(3, new MenuItem("Back", menu[2]));	menu[5]->InsertItem(0, new MenuItem("Left", &breakout->Setup()->k_left, 0));	menu[5]->InsertItem(1, new MenuItem("Right", &breakout->Setup()->k_right, 0));	menu[5]->InsertItem(2, new MenuItem("Fire", &breakout->Setup()->k_fire, 0));	menu[5]->InsertItem(3, new MenuItem());    menu[5]->InsertItem(4, new MenuItem("Mouse", menu[8]));	menu[5]->InsertItem(5, new MenuItem("Use:", &breakout->Setup()->control, str_ctrls, 3));	menu[5]->InsertItem(6, new MenuItem());	menu[5]->InsertItem(7, new MenuItem("Back", menu[2]));    menu[6]->InsertItem(0, new MenuItem("Difficulty:", &breakout->Setup()->diff, str_diff, 3));    menu[6]->InsertItem(1, new MenuItem("Starting Level:", &breakout->Setup()->startlevel, 0, LEVEL_NUM-1, 5));    menu[6]->InsertItem(2, new MenuItem("Paddle:", &breakout->Setup()->convex, "Flat Surface", "Convex Surface"));    menu[6]->InsertItem(3, new MenuItem("Ball's Starting Angle:", &breakout->Setup()->rnd_start, "50 Degree", "Random"));	menu[6]->InsertItem(4, new MenuItem());    menu[6]->InsertItem(5, new MenuItem("", &breakout->Setup()->lvls_frm_file, "Play Original Levels", "Play Own Levels"));	menu[6]->InsertItem(6, new MenuItem("Level File", menu[7]));	menu[6]->InsertItem(7, new MenuItem("(not selected)"));	menu[6]->InsertItem(8, new MenuItem());	menu[6]->InsertItem(9, new MenuItem("Back", menu[2]));    menu[7]->InsertItem(0, new MenuItem("Path", breakout->Setup()->lvl_path, 31));    menu[7]->InsertItem(1, new MenuItem("File", breakout->Setup()->lvl_file, 19));	menu[7]->InsertItem(2, new MenuItem());	menu[7]->InsertItem(3, new MenuItem("Back", menu[6]));    menu[8]->InsertItem(0, new MenuItem("Warp Mouse:", &breakout->Setup()->warp, "Off", "On"));    menu[8]->InsertItem(1, new MenuItem("Invert Mouse:", &breakout->Setup()->invert, "Off", "On"));    menu[8]->InsertItem(2, new MenuItem("Motion Modifier:", &breakout->Setup()->motion_mod, 40, 100, 10));	menu[8]->InsertItem(3, new MenuItem());	menu[8]->InsertItem(4, new MenuItem("Back", menu[5]));    //add to manager    mm->InsertMenu(0, menu[0]);    mm->InsertMenu(1, menu[1]);    mm->InsertMenu(2, menu[2]);    mm->InsertMenu(3, menu[3]);    mm->InsertMenu(4, menu[4]);    mm->InsertMenu(5, menu[5]);    mm->InsertMenu(6, menu[6]);    mm->InsertMenu(7, menu[7]);    mm->InsertMenu(8, menu[8]);    mm->Activate();    level_sw = menu[6]->Item(5);    level_menu = menu[7]->Item(3);    level_menu->SetUsed(1); level_sw->SetUsed(1);    CheckLevelFile();    //randomize    timeb t;    ftime(&t);    srand((unsigned int)t.time);	#ifdef SOUND		//load waves    snd_menu = Wave_Load("click.wav");#endif	}Game::~Game(){	if (breakout) delete breakout;	if (title) SDL_FreeSurface(title);	if (logo) SDL_FreeSurface(logo);	if (mm) delete mm;	if (f_menu_w) SFnt_Free(f_menu_w);	if (f_menu_b) SFnt_Free(f_menu_b);	if (f_hiscore) SFnt_Free(f_hiscore);	if (f_enlgt_hiscore) SFnt_Free(f_enlgt_hiscore);#ifdef SOUND	if (snd_menu) Wave_Free(snd_menu);#endif	    Sdl_Quit();}void Game::Run(){#ifdef SOUND    sndsrv.spec.freq = 22050;    sndsrv.spec.format = AUDIO_U8;    sndsrv.spec.samples = 128;    sndsrv.spec.channels = 1;	SndSrv_Open(snd_menu->spec);#endif		mm->Prepare();	DR_SETFULLDST(sdl.scr);	DR_SETFULLSRC(title);	SSur_Blit();	DR_SETDST(sdl.scr, logo_x, logo_y, logo->w, logo->h);	DR_SETSRC(logo, 0, 0);	SSur_Blit();		SDL_UNDIM();	mm->CurMenu()->Show(1);	//loop	SDL_Event	event;	int			go_on = 1;	int         rank;	int         ret;	while (go_on && !fast_quit) {	    ret = MR_CONTINUE;		if (SDL_PollEvent(&event)) {		    switch (event.type) {				case SDL_MOUSEMOTION:				    mm->CurMenu()->MouseMotion(event.motion.x, event.motion.y);				    break;				case SDL_MOUSEBUTTONUP:#ifdef SOUND    				SndSrv_Play(snd_menu, 0);#endif				    ret = mm->ButtonEvent(event.button);				    break;		        case SDL_KEYUP:#ifdef SOUND    				SndSrv_Play(snd_menu, 0);#endif    				if (event.key.keysym.sym == SDLK_ESCAPE) {    				    go_on = 0;    				    break;    				}    				ret = mm->KeyEvent(&event.key);                break;				case SDL_QUIT:				    fast_quit = 1;				    break;				default:				    break;			}	   			switch (ret) {				case MR_CONTINUE:   					break;				case AT_HISCORE:   					SDL_DIM();    				ShowHiScore(0);                  	DR_SETFULLDST(sdl.scr);                  	DR_SETFULLSRC(title);                  	SSur_Blit();                    DR_SETDST(sdl.scr, logo_x, logo_y, logo->w, logo->h);                    DR_SETSRC(logo, 0, 0);                    SSur_Blit();   					SDL_UNDIM();    				mm->CurMenu()->Show(1);	    			break;		    	case AT_QUIT:					go_on = 0;    				break;    			case AT_NEWGAME:	    			SDL_DIM();		    		rank = breakout->Run(); //game					if (!fast_quit) {  					    if (rank != 0)    					    ShowHiScore(rank);                       	DR_SETFULLDST(sdl.scr);                       	DR_SETFULLSRC(title);                       	SSur_Blit();                        DR_SETDST(sdl.scr, logo_x, logo_y, logo->w, logo->h);                        DR_SETSRC(logo, 0, 0);                        SSur_Blit();         			    SDL_UNDIM();					    mm->CurMenu()->ClearState();  					    mm->SetCurMenu(0);    				    mm->CurMenu()->Prepare(0);					    mm->CurMenu()->Show(1);   					}    		        break;   			}				}			        			if (fast_quit) break;		CheckLevelFile();			 	//compute 	    mm->CurMenu()->Compute(); 	    mm->CurMenu()->Update(1);	 	SDL_Delay(8);	#ifdef SOUND		SndSrv_SetActive(breakout->Setup()->snd_on); 		SndSrv_SetVolume(breakout->Setup()->snd_vol);#endif	}    SDL_DIM();#ifdef SOUND	SndSrv_Close();#endif}void Game::ShowHiScore(int r){	int i;	int a_y = 100;	int off = 50;	int entry_h = f_hiscore->lh + 2;	char buffer[12];	HiScoreEntry	entry;	SFnt			*font;		for (int page = 0; page<2; page++) {    DR_SETFULLDST(sdl.scr);    DR_SETFULLSRC(title);    SSur_Blit();	SDL_UNDIM();	    f_hiscore->algn = TA_X_CENTER | TA_Y_CENTER;    const char* txt;    if (0==page) txt="Highest Scores";    else txt="Highest Levels";    SFnt_Write(f_hiscore, sdl.scr, sdl.scr->w / 2, 50, const_cast<char*>(txt), 0);    f_hiscore->algn = 0;    for (i = 0; i < 10; i++) {        if ((0==page && r%10 == i+1)            || (1==page && r/10 == i+1))            font = f_enlgt_hiscore;        else            font = f_hiscore;        entry = breakout->GetHiScore()->Entry(i,page);        font->algn = TA_X_LEFT | TA_Y_TOP;        SFnt_Write(font, sdl.scr, off, a_y + i * entry_h, entry.name, 0);        font->algn = TA_X_CENTER | TA_Y_TOP;        sprintf(buffer, "%i", entry.level);        SFnt_Write(font, sdl.scr, sdl.scr->w / 2, a_y + i * entry_h, buffer, 0);        font->algn = TA_X_RIGHT | TA_Y_TOP;        sprintf(buffer, "%i", entry.score);        SFnt_Write(font, sdl.scr, sdl.scr->w - off, a_y + i * entry_h, buffer, 0);    }    Sdl_FullUpdate();    Sdl_WaitForClick();    			SDL_DIM();	}}void Game::CheckLevelFile(){     // strange and bad code, I know... //    if (!level_sw->Used() && !level_menu->Used()) return;    level_menu->Used();    int rep = mm->GetMenu(6) == mm->CurMenu() ? 1 : 0;    if (!breakout->Setup()->lvls_frm_file) {        mm->GetMenu(6)->Item(7)->SetString("(not selected)", rep);        mm->GetMenu(6)->Item(1)->SetRange(0, LEVEL_NUM - 1, 5, rep);        return;    }    char str[256];    FILE *f;    if ((f = breakout->Levels_OpenFile(str)) == 0) {        mm->GetMenu(6)->Item(7)->SetString("(not found)", rep);        mm->GetMenu(6)->Item(1)->SetRange(0, LEVEL_NUM - 1, 5, rep);        return;    }    else        mm->GetMenu(6)->Item(7)->SetString("(found)", rep);    int lev_num = 0;    char *cur_pos;    // load file into mem //    fseek(f, 0, SEEK_END);    int fsize = ftell(f);    char *fbuf = new char[fsize];    fseek(f, 0, SEEK_SET);    fread(fbuf, fsize, 1, f);    cur_pos = fbuf;    fclose(f);    // count    while (cur_pos < fbuf + fsize) {        if (!strncmp(cur_pos, "[LEV", 4))            lev_num++;        cur_pos = breakout->NextLine(0, cur_pos, fbuf + fsize);    }    if (lev_num > 0)        mm->GetMenu(6)->Item(1)->SetRange(0, lev_num - 1, 5, rep);    delete fbuf;}

⌨️ 快捷键说明

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