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

📄 swegame.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 ".\swegame.h"

SWEGame::SWEGame(void)
{
	m_pPoly = NULL;
	selectedSurfaceType = SURFACE_NONE;
	selectedIndex = 0;
	selectedSurface = NULL;
	mouseX = 0;
	mouseY = 0;
}

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

int SWEGame::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;
	}

	Vertex vList[4] = {{-12,-12},{12,-12},{12,12},{-12,12}};
	if((m_pPoly = new BPolygon(0, 0, 4, vList, 0xff0000)) == NULL) {
		REPORT_ERROR("Not enough memory");
		return 0;
	}

	mouseX = SCREEN_WIDTH>>1;
	mouseY = SCREEN_HEIGHT>>1;

	if((selectedSurface = new BDirectDrawSurface(dd.CreateOffScreenSurface(SLICE_WIDTH, SLICE_HEIGHT, 0))) == NULL) {
		REPORT_ERROR("Not enough memory");
		return 0;
	}
	if(!selectedSurface->Fill(0x00ffff)) {
		DXTRACE_MSG("Failed to fill selectedSurface");
	}

	if(!pddsBack->Fill(0x0045ff)) {
		DXTRACE_MSG("Failed to fill back surface");
	}

	sprintf(printBuffer, "Usage: arrow keys: move, S:save world.");

	return 1;
}

int SWEGame::ShutDown(void)
{
	bitmap.UnLoad();

	if(m_pPoly != NULL) {
		delete m_pPoly;
		m_pPoly = NULL;
	}
	if(selectedSurface != NULL) {
		delete selectedSurface;
		selectedSurface = NULL;
	}
	if(!BGame::ShutDown())
		return 0;

	return 1;
}

bool SWEGame::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;
	}

	mouseX += di.GetMouseDX();
	if(mouseX < 0)
		mouseX = 0;
	else if(mouseX > SCREEN_WIDTH)
		mouseX = SCREEN_WIDTH;

	mouseY += di.GetMouseDY();
	if(mouseY < 0)
		mouseY = 0;
	else if(mouseY > SCREEN_HEIGHT + SLICE_HEIGHT)
		mouseY = SCREEN_HEIGHT + SLICE_HEIGHT;

	POINT pt = {0, 0};
	ClientToScreen(this->m_hwndMain, &pt);
	SetCursorPos(pt.x + mouseX, pt.y + mouseY);

	if(di.KeyDown(DIK_LEFT)) {
		mapLevel1.MoveTo(mapLevel1.GetX()-5, 0);
	}
	if(di.KeyDown(DIK_RIGHT)) {
		mapLevel1.MoveTo(mapLevel1.GetX()+5, 0);
	}
	if(di.KeyDown(DIK_S)) {
		if(!mapLevel1.Save("data/newLevel.map")) {
			REPORT_ERROR("Failed to save map file: data/newLevel.map");
		}
		if(!spriteManager.Save("data/newLevel.def")) {
			REPORT_ERROR("Failed to save monster define file: data/newLevel.def");
		}
	}
	if(di.MouseDown(MOUSE_LEFT_BUTTON)) {
		if(mouseY >= 600 && mouseY < 625) {	//selected a slice
			int index = mouseX / 25;
			if(index >= SLICE_KINDS) {
				return true;
			}
			if(!selectedSurface->Fill(0)) {
				DXTRACE_MSG("Failed to fill selectedSurface");
			}
			if(!selectedSurface->Draw(mapLevel1.GetSurface(index), 0, 0, 1, false)) {
				DXTRACE_MSG("Failed to draw map to selectedSurface");
			}
			selectedSurfaceType = SURFACE_MAP;
			selectedIndex = index;

			m_pPoly->MoveTo(index*25+12, 612);
		}
		else if(mouseY >= 625 && mouseY<= 650) { //selected a sprite
			int index = mouseX / 25;
			if(index >= SPRITE_KINDS) {
				return true;
			}
			if(!selectedSurface->Fill(0)) {
				DXTRACE_MSG("Failed to fill selectedSurface");
			}
			if(!selectedSurface->Draw(spriteFactory.GetSurface(index), 0, 0)) {
				DXTRACE_MSG("Failed to draw sprite to selectedSurface");
			}
			selectedSurfaceType = SURFACE_SPRITE;
			selectedIndex = index;

			m_pPoly->MoveTo(index*25+12, 637);
		}
		else {	//make a sprite/slice
			int row, col;
			row = (mapLevel1.GetY() + mouseY) / SLICE_HEIGHT;
			col = (mapLevel1.GetX() + mouseX) / SLICE_WIDTH;
			if(selectedSurfaceType == SURFACE_MAP) {
				mapLevel1.Set(row, col, selectedIndex);
			}
			else if(selectedSurfaceType == SURFACE_SPRITE) {
				if(!spriteManager.Add(row, col, selectedIndex)) {
					DXTRACE_MSG("Failed to add sprite to spriteManager, please check the parameters");
				}
			}
		}
	}
	else if(di.MouseDown(MOUSE_RIGHT_BUTTON)) {
		selectedSurfaceType = SURFACE_NONE;
		if(!selectedSurface->Fill(0x000080)) {
			DXTRACE_MSG("Failed to fill selectedSurface");
		}
	}

	return true;
}

bool SWEGame::RunGameLogic(void)
{
	return true;
}

bool SWEGame::DrawScreen(void)
{
	//surface restore
	if(pddsPrimary->IsLost()) {
		dd.Restore();
	}
	//draw operations: Fill back, then map, sprites, mario, and last, infomations
	if(!pddsBack->Fill(0x0045ff)) {
		DXTRACE_MSG("Failed to fill back surface!");
	}
	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(!mapLevel1.DrawSlices(pddsBack, 0, 600, 0.5)) {
		DXTRACE_MSG("Failed to draw map slices!");
	}
	if(!spriteFactory.DrawSprites(pddsBack, 0, 625, 0.5)) {
		DXTRACE_MSG("Failed to draw sprite slices!");
	}
	if(selectedSurfaceType != SURFACE_NONE) {
		if(!m_pPoly->Draw(pddsBack)) {
			DXTRACE_MSG("Failed to draw polygon!");
		}
	}
	if(mouseY < SCREEN_HEIGHT) {
		if(!pddsBack->Draw(selectedSurface, mouseX - (SLICE_WIDTH>>1), mouseY - (SLICE_HEIGHT>>1))) {
			DXTRACE_MSG("Failed to draw selected slice!");
		}
	}
	if(!pddsBack->DrawTextGDI(printBuffer, 0, 0, 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;
}

⌨️ 快捷键说明

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