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

📄 sgame.cpp

📁 用VC++及DirectX实现的SuperMario小游戏
💻 CPP
字号:
/*
Author: Bear

This source is free to anybody.
If you have any problem with this or some advice to me, please:
    mailto: heyang22118952.student@sina.com
        or  yang45249.student@sina.com
or you can contact me through my QQ:     261570581

Welcome to discuss game programming techniques with me :)
And I like to play games!
*/
#include ".\sgame.h"

SGame::SGame(void)
{
	score = 0;
	life = 3;
	restarting = false;
	gameOver = false;
	mario = NULL;
}

SGame::~SGame(void)
{
	if(!ShutDown()) {
		DXTRACE_MSG("Can not shutdown");
	}
}

int SGame::Initialize(HINSTANCE hInstance, HWND hwndMain, bool windowMode, int screenWidth, int screenHeight, int screenBpp)
{
	if(!BGame::Initialize(hInstance, hwndMain, windowMode, screenWidth, screenHeight, screenBpp)) {
		REPORT_ERROR("Failed to initialize directx");
		return 0;
	}

	//load bitmap
	if(!bitmap.Load("data/sprites.bmp")) {
		REPORT_ERROR("Failed to load bitmap file: data/sprites.bmp");
		return 0;
	}
	//init off screen surface
	if(!mapLevel1.Load(&dd, &bitmap, "Data/Level1.map")) {
		REPORT_ERROR("Read map file 'Data/Level1.map' error, may be not a correct map file");
		return 0;
	}
	//load sprites
	if(!spriteFactory.Load(&dd, &bitmap, "data/sprites.dat")) {
		REPORT_ERROR("Failed to load sprite file: Data/sprites.dat");
		return 0;
	}
	if(!spriteManager.Load(&spriteFactory, "data/monstersLevel1.def")) {
		REPORT_ERROR("Failed to load monster define file: Data/monstersLevel1.def");
		return 0;
	}
	mario = (SMario*)spriteFactory.Create("mario", 300, 400);
	if(mario == NULL) {
		DXTRACE_MSG("Error Creating mario");
		return 0;
	}

	//if(!waveFile.Load("sp066.wav")) {
	//	DXTRACE_MSG("Error loading wav file: sp066.wav");
	//	return 0;
	//}
	//if(!pdsbSample->LoadWaveFile(&waveFile)) {
	//	DXTRACE_MSG("Error loading wav file: sp066.wav");
	//	return 0;
	//}
	//waveFile.UnLoad();
	////test play sound
	//if(!pdsbSample->Play(true)) {
	//	DXTRACE_MSG("Error Playing wav file: sp066.wav");
	//	return 0;
	//}

	return 1;
}

int SGame::ShutDown(void)
{
	//pdsbSample->Stop();
	//if(pdsbSample != NULL) {
	//	delete pdsbSample;
	//	pdsbSample = NULL;
	//}
	bitmap.UnLoad();
	if(mario != NULL) {
		delete mario;
		mario = NULL;
	}

	if(!BGame::ShutDown()) {
		DXTRACE_MSG("SGame::ShutDown(): call BGame::ShutDown() failed");
		return 0;
	}

	return 1;
}

bool SGame::ProcessInput(void)
{
	//directinput test
	if(!di.GetDeviceState()) {	//first get status of input devices, to call status functions, this must be done!
		DXTRACE_MSG("SGame::ProcessInput(): call DirectInput::GetDeviceState() failed");
		return false;
	}
	if(di.KeyDown(DIK_ESCAPE)) {
		PostMessage(m_hwndMain, WM_QUIT, 0, 0);
		wndClosed = true;
		return false;
	}
	if(gameOver) {
		if(di.KeyDown(DIK_R)) {
			if(!ReStartGame()) {
				DXTRACE_MSG("SGame::ProcessInput(): call ReStartGame() failed");
				return false;
			}
		}
	}
	if(di.KeyDown(DIK_LEFT)) {
		mario->SetSpeedX(-5);
	}
	if(di.KeyDown(DIK_RIGHT)) {
		mario->SetSpeedX(5);
	}
	if(!di.KeyDown(DIK_LEFT) && !di.KeyDown(DIK_RIGHT)) {
		mario->SetSpeedX(0);
	}
	if(di.KeyDown(DIK_SPACE)) {
		mario->Jump();
	}

	return true;
}

bool SGame::RunGameLogic(void)
{
	if(gameOver) {
		return true;
	}
	if(restarting) {
		static int count = 0;
		count++;
		if(count == 60) {
			count = 0;
			restarting = false;
			if(!ReStart()) {
				DXTRACE_MSG("SGame::RunGameLogic(): call ReStart() failed");
				return false;
			}
		}
		return true;
	}
	//do all animations
	mario->Anim();
	spriteManager.Anim();
	//move map according to mario's position
	mapLevel1.MoveTo(mario->GetX() - mario->GetScreenX(), 0);
	//hit test
	SSprite* aSprite;
	bool hitWall = false;
	for(int i=0; i<spriteManager.GetCount(); i++) {	//for all sprites, test if it has hit mario
		aSprite = spriteManager.GetSprite(i);
		if(aSprite == NULL) {
			DXTRACE_MSG("SGame::RunGameLogic(): call SpriteManager::GetSprite() failed");
			return false;
		}
		if(mario->HitTest(aSprite)) {
			//do different game logic according to the hit sprite's type
			switch(aSprite->GetType()) {
				case SPRITE_TYPE_MARIO:	//this can not happen
					assert(false);
					break;
				case SPRITE_TYPE_WALL:
				case SPRITE_TYPE_PIPE:	
					//when the sprite is a wall or a pipe, mario should be bounded back.
					mario->MoveBack();
					if((mario->GetX() + SLICE_WIDTH) <= aSprite->GetX() || (aSprite->GetX() + SLICE_WIDTH) <= mario->GetX()) { //hit right or left
					}
					else {
						if(mario->IsJumping()) {	//jumping, hit top
							mario->StopJump();
						}
						else if(!mario->IsLanded()) {	//dropping, hit bottom
							mario->Land(aSprite->GetY());
							mario->Move();
						}
					}
					hitWall = true;
					break;
				case SPRITE_TYPE_FUNGUS:
				case SPRITE_TYPE_TORTOISE:
					//when the sprite is a fungus or a tortoise, mario may beat it or be beaten.
					if(abs(mario->GetX()-aSprite->GetX()) < abs(mario->GetY()-aSprite->GetY()) && !mario->IsLanded() && !mario->IsJumping()) { //beat a monster, give him some courage.
						score += 20;
						if(!spriteManager.Delete(aSprite)) {
							DXTRACE_MSG("SGame::RunGameLogic(): call SpriteManager::Delete() failed");
							return false;
						}
					}
					else {	// be beaten, die
						life--;
						if(life <= 0) {
							GameOver();
						}
						else {
							restarting = true;;
						}
					}
					break;
				case SPRITE_TYPE_COIN:
					//mario get a coin, encourage him
					score += 10;
					spriteManager.Delete(aSprite);
					break;
				case SPRITE_TYPE_FLOUR:
					//mario get an extra life
					life++;
					if(!spriteManager.Delete(aSprite)) {
						DXTRACE_MSG("SGame::RunGameLogic(): call SpriteManager::Delete() failed");
						return false;
					}
					break;
				case SPRITE_TYPE_FLAG:
					//goto next level
					score += 100;
					break;
				default:
					DXTRACE_MSG("Bad sprite type!");
					assert(false);
					break;
			}
		}
	}

	//mario should drop to the ground if it is flying
	if(!hitWall && mario->GetY() != 400 && !mario->IsJumping()) {
		mario->Drop();
	}

	return true;
}

bool SGame::DrawScreen(void)
{
	//surface restore
	if(pddsPrimary->IsLost()) {
		dd.Restore();
	}
	//draw operations: Fill back, then map, sprites, mario, and last, infomations
	if(!mapLevel1.Draw(pddsBack)) {
		DXTRACE_MSG("Failed to draw map!");
	}
	if(!spriteManager.Draw(pddsBack, mapLevel1.GetX(), mapLevel1.GetY())) {
		DXTRACE_MSG("Failed to draw sprites!");
	}
	if(!mario->Draw(pddsBack, mapLevel1.GetX(), mapLevel1.GetY())) {
		DXTRACE_MSG("Failed to draw mario!");
	}
	sprintf(buf, "Score: %d   Life: %d", score, life);
	if(!pddsBack->DrawTextGDI(buf, 0, 0, 0x00ff00)) {
		DXTRACE_MSG("Failed to draw text!");
	}
	if(restarting) {
		sprintf(buf, "Mario dead, restarting...");
		if(!pddsBack->DrawTextGDI(buf, pddsBack->GetWidth()/2, pddsBack->GetHeight()/2, 0x00ff00)) {
			DXTRACE_MSG("Failed to draw text!");
		}
	}
	if(gameOver) {
		sprintf(buf, "G A M E   O V E R");
		if(!pddsBack->DrawTextGDI(buf, pddsBack->GetWidth()/2, pddsBack->GetHeight()/2, 0x00ff00)) {
			DXTRACE_MSG("Failed to draw text!");
		}
	}
	//flip
	if(dd.IsFullScreen()) {	//if it's full screen mode, just call Flip() mathod of primary surface
		pddsPrimary->Flip();
	}
	else {	//if it's windowed mode, we can not flip, must get client rect and blit back surface to primary
		RECT rcClient;
		GetClientRect(m_hwndMain, &rcClient);
		POINT pt = {0, 0};
		ClientToScreen(m_hwndMain, &pt);
		rcClient.left += pt.x;
		rcClient.top += pt.y;
		rcClient.right += pt.x;
		rcClient.bottom += pt.y;

		if(!pddsPrimary->Draw(pddsBack, rcClient.left, rcClient.top, 1, false)) {
			DXTRACE_MSG("Failed to draw back surface to primary!");
		}
	}

	return true;
}

void SGame::GameOver() {
	gameOver = true;
}
//reset all
int SGame::ReStartGame() {
	//reset global variables
	score = 0;
	life = 3;
	restarting = false;
	gameOver = false;
	//load sprites
	if(mario != NULL) {
		delete mario;
		mario = NULL;
	}
	mario = (SMario*)spriteFactory.Create("mario", 300, 400);
	if(mario == NULL) {
		DXTRACE_MSG("Error Creating mario");
		return 0;
	}
	if(!spriteManager.Load(&spriteFactory, "data/monstersLevel1.def")) {
		REPORT_ERROR("RestartGame: Failed to load monsters!");
		return 0;
	}

	return 1;
}
//reset mario position to restart level
int SGame::ReStart() {
	if(mario != NULL) {
		delete mario;
		mario = NULL;
	}
	mario = (SMario*)spriteFactory.Create("mario", 300, 400);
	if(mario == NULL) {
		DXTRACE_MSG("Error Creating mario");
		return 0;
	}

	return 1;
}

⌨️ 快捷键说明

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