📄 sgame.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 + -