問題1://播放背景BGM,Debug下運行沒有聲音,直接運行exe能聽到聲音
void PlayBgm()
{
TCHAR szBuffer[256] = {0};
TCHAR Buffer[256] = {0};
WCHAR VolumCmd[256];
WCHAR volume[256];
//先關閉failure.mp3
wsprintf(szBuffer,L"failure.mp3");
wsprintf(Buffer,L"close \"%s\"",szBuffer);
mciSendString(Buffer,0,0,0);
//再載入bgm
wsprintf(szBuffer,L"The Dawn.mp3");
wsprintf(Buffer,L"open \"%s\"",szBuffer);
mciSendString(Buffer,NULL,0,NULL); //打開設備
wsprintf(Buffer,L"play \"%s\" repeat",szBuffer);
mciSendString(Buffer,NULL,0,NULL); //播放
wsprintf(VolumCmd,L"status \"%s\" volume",szBuffer);
mciSendString(VolumCmd,volume, sizeof(volume), 0 );
int v0 = _wtoi(volume);
wsprintf(VolumCmd,L"setaudio \"%s\" volume to %i",szBuffer,500);//修改音量
mciSendString(VolumCmd,0,0,0);
}
從網上下載的vs可運行的貪吃蛇代碼,想試著修改BGM,但是修改紅色部分的歌曲名之后,運行exe檔案就沒有聲音了,修改回去,又會有聲音,想要修改的mp3檔案已放入debug中。求大神幫忙看看是怎么回事。
問題二:試著新建了一個控制臺應用程式,但是把代碼粘過去之后(把相應的圖示檔案,位圖檔案,mp3檔案也都拷進了對應檔案),運行一直出錯:
錯誤 2 error LNK2019: 無法決議的外部符號 _main,該符號在函式 ___tmainCRTStartup 中被參考 F:\ruanjian2\vs2013\files\lianxi\lianxi\MSVCRTD.lib(crtexe.obj) lianxi
上網查之后,加了個void main(){}
然后就只出現黑框(正真的控制臺了吧)
求大佬能指點一下
代碼放上來就超字數了,怎么辦啊QAQ
uj5u.com熱心網友回復:
#pragma oncestruct Occupy
{
int x;
int y;
int iDirection;//方向,0為上,1為下,2為左,3為右
};
class CSnake
{
public:
CSnake(void);
~CSnake(void);
public:
//處理下一次移動后的各個節點的位置
void MoveBody(int dir);
//處理吃到糖果后的變化,實際上不太需要這個函式,這里為了直觀,保留之
void EatCandy();
//一般成員變數定為私有,這里為了方便,設定為public
public:
//頭的位置
Occupy head;
//身體的位置,默認最多300個,不夠再改
Occupy body[300];
//身體的總節數
int iSumPanel;
};
CSnake::CSnake(void)//建構式
{
//初始化
head.x = 360;
head.y = 360;
head.iDirection = 3;
iSumPanel = 1;
}
CSnake::~CSnake(void)
{
}
void CSnake::MoveBody(int dir)
{
//這里額外記錄一個節點,用于吃到candy時的備用
if (iSumPanel == 0)
body[0] = head;
//若存在身體
else
{
//身體長度大于0的話,禁止直接反向運動
if (head.iDirection == 0 && dir == 1)
return;
if (head.iDirection == 1 && dir == 0)
return;
if (head.iDirection == 2 && dir == 3)
return;
if (head.iDirection == 3 && dir == 2)
return;
//這里額外記錄一個節點,吃到candy時可直接使用該節點
for (int i = iSumPanel; i>0; i--)
{
body[i] = body[i - 1];
}
body[0].iDirection = head.iDirection;
body[0].x = head.x;
body[0].y = head.y;
}
switch (dir)
{
case 0:
head.y -= 40;
head.iDirection = 0;
break;
case 1:
head.y += 40;
head.iDirection = 1;
break;
case 2:
head.x -= 40;
head.iDirection = 2;
break;
case 3:
head.x += 40;
head.iDirection = 3;
break;
default:
break;
}
return;
}
void CSnake::EatCandy()
{
iSumPanel++;
}
//Snake.h頭檔案
uj5u.com熱心網友回復:
#include <windows.h>#include <tchar.h>//使用swprintf_s函式所需的頭檔案
#include "Snake.h"
#include "time.h"
#include "mmsystem.h"
#include "iostream"
using namespace std;
//-----------------------------------【庫檔案包含部分】---------------------------------------
#pragma comment (lib,"User32.lib")
#pragma comment (lib,"Gdi32.lib")
#pragma comment(lib,"winmm.lib") //呼叫PlaySound函式所需庫檔案
#pragma comment(lib,"Msimg32.lib") //添加使用TransparentBlt函式所需的庫檔案
//-----------------------------------【宏定義部分】--------------------------------------------
#define WINDOW_WIDTH 815 //為視窗寬度定義的宏,以方便在此處修改視窗寬度
#define WINDOW_HEIGHT 640 //為視窗高度定義的宏,以方便在此處修改視窗高度
#define WINDOW_TITLE L"貪吃蛇" //為視窗標題定義的宏
CSnake snake;
HDC g_hdc = NULL, g_mdc = NULL, g_bufdc = NULL; //全域設備環境句柄與兩個全域記憶體DC句柄
HBITMAP g_hHead = NULL, g_hBody = NULL, g_hCandy = NULL, g_hFailure = NULL;
HBITMAP g_hBackGround = NULL; //定義位圖句柄陣列用于存盤四張方向圖,以及定義存盤背景圖的句柄
DWORD g_tPre = 0, g_tNow = 0; //宣告l兩個函式來記錄時間,g_tPre記錄上一次繪圖的時間,g_tNow記錄此次準備繪圖的時間
int candy_x, candy_y;
int g_iDirection = 0;//g_iDirection為蛇移動方向,這里我們中以0,1,2,3代表上,下,左,右方向上的移動
int g_iIntervalTime = 200;
bool g_bChangeDirection = 0;
bool g_bExistCandy = 0;
bool g_bKeyDown = 0;//判斷當前是否兩個方向鍵一起按下,這樣可以防止蛇斜方向運動
bool g_bFailure = 0;
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);//視窗程序函式
BOOL Game_Init(HWND hwnd); //在此函式中進行資源的初始化
VOID Game_Paint(HWND hwnd); //在此函式中進行繪圖代碼的書寫
BOOL Game_CleanUp(HWND hwnd); //在此函式中進行資源的清理
void SetCandy(); //將新的candy放置在蛇未占據的地方
void ReplayGame(); //重新開始游戲
//-----------------------------------【WinMain( )函式】--------------------------------------
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
//【1】開始設計一個完整的視窗類
WNDCLASSEX wndClass = { 0 }; //用WINDCLASSEX定義了一個視窗類
wndClass.cbSize = sizeof(WNDCLASSEX); //設定結構體的位元組數大小
wndClass.style = CS_HREDRAW | CS_VREDRAW; //設定視窗的樣式
wndClass.lpfnWndProc = WndProc; //設定指向視窗程序函式的指標
wndClass.cbClsExtra = 0; //視窗類的附加記憶體,取0就可以了
wndClass.cbWndExtra = 0; //視窗的附加記憶體,依然取0就行了
wndClass.hInstance = hInstance; //指定包含視窗程序的程式的實體句柄。
wndClass.hIcon = (HICON)::LoadImage(NULL, L"icon.ico", IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_LOADFROMFILE); //本地加載自定義ico圖示
wndClass.hCursor = LoadCursor(NULL, IDC_ARROW); //指定視窗類的游標句柄。
wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); //為hbrBackground成員指定一個白色畫刷句柄
wndClass.lpszMenuName = NULL; //用一個以空終止的字串,指定選單資源的名字。
wndClass.lpszClassName = L"tanchishe"; //用一個以空終止的字串,指定視窗類的名字。
//【2】注冊視窗類
if (!RegisterClassEx(&wndClass)) //設計完視窗后,需要對視窗類進行注冊,這樣才能創建該型別的視窗
return -1;
//【3】正式創建視窗
HWND hwnd = CreateWindow(L"tanchishe", WINDOW_TITLE, //喜聞樂見的創建視窗函式CreateWindow
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, WINDOW_WIDTH,
WINDOW_HEIGHT, NULL, NULL, hInstance, NULL);
//【4】視窗的移動、顯示與更新
MoveWindow(hwnd, 20, 20, WINDOW_WIDTH, WINDOW_HEIGHT, true); //調整視窗顯示時的位置,使視窗左上角位于(250,80)處
ShowWindow(hwnd, nShowCmd); //呼叫ShowWindow函式來顯示視窗
UpdateWindow(hwnd); //對視窗進行更新,就像我們買了新房子要裝修一樣
//游戲資源的初始化,若初始化失敗,彈出一個訊息框,并回傳FALSE
if (!Game_Init(hwnd))
{
MessageBox(hwnd, L"資源初始化失敗", L"訊息視窗", 0); //使用MessageBox函式,創建一個訊息視窗
return FALSE;
}
//【5】訊息回圈程序
MSG msg = { 0 }; //定義并初始化msg
while (msg.message != WM_QUIT) //使用while回圈,如果訊息不是WM_QUIT訊息,就繼續回圈
{
if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) //查看應用程式訊息佇列,有訊息時將佇列中的訊息派發出去。
{
TranslateMessage(&msg); //將虛擬鍵訊息轉換為字符訊息
DispatchMessage(&msg); //分發一個訊息給視窗程式。
}
else
{
g_tNow = GetTickCount(); //獲取當前系統時間
if (g_tNow - g_tPre >= g_iIntervalTime) //當此次回圈運行與上次繪圖時間相差0.4秒時再進行重繪操作
if (!g_bFailure)
Game_Paint(hwnd);
}
}
//【6】視窗類的注銷
UnregisterClass(L"ForTheDreamOfGameDevelop", wndClass.hInstance); //程式準備結束,注銷視窗類
return 0;
}
//-----------------------------------【WndProc( )函式】--------------------------------------
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) //switch陳述句開始
{
case WM_KEYDOWN: //按下鍵盤訊息
//判斷按鍵的虛擬鍵碼
if (g_bKeyDown)
break;
switch (wParam)
{
case VK_ESCAPE: //按下【Esc】鍵
DestroyWindow(hwnd); // 銷毀視窗, 并發送一條WM_DESTROY訊息
PostQuitMessage(0); //結束程式
break;
case VK_UP: //按下【↑】鍵
snake.MoveBody(0);
g_bKeyDown = 1;
break;
case VK_DOWN: //按下【↓】鍵
snake.MoveBody(1);
g_bKeyDown = 1;
break;
case VK_LEFT: //按下【←】鍵
snake.MoveBody(2);
g_bKeyDown = 1;
break;
case VK_RIGHT: //按下【→】鍵
snake.MoveBody(3);
g_bKeyDown = 1;
break;
case VK_SPACE: //按下【空格】鍵
if (g_bFailure)
ReplayGame(); //重新開始游戲
break;
}
g_bChangeDirection = 1;//已改變方向
//g_bKeyDown = 1;
break; //跳出該switch陳述句
case WM_DESTROY: //若是視窗銷毀訊息
Game_CleanUp(hwnd); //呼叫自定義的資源清理函式Game_CleanUp()進行退出前的資源清理
PostQuitMessage(0); //向系統表明有個執行緒有終止請求。用來回應WM_DESTROY訊息
break; //跳出該switch陳述句
default: //若上述case條件都不符合,則執行該default陳述句
return DefWindowProc(hwnd, message, wParam, lParam); //呼叫預設的視窗程序
}
return 0; //正常退出
}
//-----------------------------------【Game_Init( )函式】--------------------------------------
// 描述:初始化函式,進行一些簡單的初始化
//------------------------------------------------------------------------------------------------
BOOL Game_Init(HWND hwnd)
{
srand((unsigned)time(NULL));
HBITMAP bmp;
g_hdc = GetDC(hwnd);
g_mdc = CreateCompatibleDC(g_hdc); //創建一個和hdc兼容的記憶體DC
g_bufdc = CreateCompatibleDC(g_hdc);//再創建一個和hdc兼容的緩沖DC
bmp = CreateCompatibleBitmap(g_hdc, WINDOW_WIDTH, WINDOW_HEIGHT);
SelectObject(g_mdc, bmp);
//加載各張跑動圖及背景圖,這里以0,1,2,3來代表人物的上,下,左,右移動
g_hHead = (HBITMAP)LoadImage(NULL, L"head.bmp", IMAGE_BITMAP, 40, 80, LR_LOADFROMFILE);
g_hBody = (HBITMAP)LoadImage(NULL, L"body.bmp", IMAGE_BITMAP, 40, 80, LR_LOADFROMFILE);
g_hCandy = (HBITMAP)LoadImage(NULL, L"candy.bmp", IMAGE_BITMAP, 40, 80, LR_LOADFROMFILE);
g_hFailure = (HBITMAP)LoadImage(NULL, L"failure.bmp", IMAGE_BITMAP, 1086, 396, LR_LOADFROMFILE);
g_hBackGround = (HBITMAP)LoadImage(NULL, L"bk.bmp", IMAGE_BITMAP, WINDOW_WIDTH, WINDOW_HEIGHT, LR_LOADFROMFILE);
//設定字體
HFONT hFont;
hFont = CreateFont(25, 0, 0, 0, 700, 0, 0, 0, GB2312_CHARSET, 0, 0, 0, 0, TEXT("鐘齊段寧行書"));
SelectObject(g_mdc, hFont);
SetBkMode(g_mdc, TRANSPARENT);
Game_Paint(hwnd);
return TRUE;
}
//-----------------------------------【Game_Paint( )函式】--------------------------------------
// 描述:繪制函式,在此函式中進行繪制操作
//--------------------------------------------------------------------------------------------------
VOID Game_Paint(HWND hwnd)
{
//先在mdc中貼上背景圖
SelectObject(g_bufdc, g_hBackGround);
BitBlt(g_mdc, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, g_bufdc, 0, 0, SRCCOPY);
//若最近沒有按下方向鍵的話,將自動運動
if (!g_bChangeDirection)
{
switch (snake.head.iDirection)
{
case 0:
snake.MoveBody(0);
break;
case 1:
snake.MoveBody(1);
break;
case 2:
snake.MoveBody(2);
break;
case 3:
snake.MoveBody(3);
break;
default:
break;
}
}
g_bChangeDirection = 0;
//這里首先判斷蛇頭有沒有碰到其他物體
if (snake.head.x<-20 || snake.head.x>780 || snake.head.y<-20 || snake.head.y>580)//撞墻
g_bFailure = 1;
else
{
for (int i = 0; i<snake.iSumPanel; i++)
{
if (snake.head.x == snake.body[i].x&&snake.head.y == snake.body[i].y)//撞自己
g_bFailure = 1;
}
}
if (g_bFailure)
{
//繪制失敗文字
SelectObject(g_bufdc, g_hFailure);
BitBlt(g_mdc, 130, 200, 543, 396, g_bufdc, 543, 0, SRCAND);
BitBlt(g_mdc, 130, 200, 543, 396, g_bufdc, 0, 0, SRCPAINT);
WCHAR str[100];
swprintf_s(str, L"您的分數為:%d", snake.iSumPanel - 1);
SetTextColor(g_mdc, RGB(0, 0, 255));
TextOut(g_mdc, 0, 0, str, wcslen(str));
swprintf_s(str, L"請按空格鍵繼續");
SetTextColor(g_mdc, RGB(0, 0, 255));
TextOut(g_mdc, 325, 630, str, wcslen(str));
BitBlt(g_hdc, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, g_mdc, 0, 0, SRCCOPY);
return;
}
//繪制糖果
if (!g_bExistCandy)
SetCandy();
SelectObject(g_bufdc, g_hCandy);
BitBlt(g_mdc, candy_x, candy_y, 40, 40, g_bufdc, 0, 40, SRCAND);
BitBlt(g_mdc, candy_x, candy_y, 40, 40, g_bufdc, 0, 0, SRCPAINT);
//當蛇頭遇到糖果時
if (snake.head.x == candy_x&&snake.head.y == candy_y)
{
snake.EatCandy();
g_bExistCandy = 0;
}
//繪制蛇頭
SelectObject(g_bufdc, g_hHead);
BitBlt(g_mdc, snake.head.x, snake.head.y, 40, 40, g_bufdc, 0, 40, SRCAND);
BitBlt(g_mdc, snake.head.x, snake.head.y, 40, 40, g_bufdc, 0, 0, SRCPAINT);
//繪制蛇身
if (snake.iSumPanel>0)
{
SelectObject(g_bufdc, g_hBody);
for (int i = 0; i<snake.iSumPanel; i++)
{
BitBlt(g_mdc, snake.body[i].x, snake.body[i].y, 40, 40, g_bufdc, 0, 40, SRCAND);
BitBlt(g_mdc, snake.body[i].x, snake.body[i].y, 40, 40, g_bufdc, 0, 0, SRCPAINT);
}
}
//將最后的畫面顯示在視窗中
BitBlt(g_hdc, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, g_mdc, 0, 0, SRCCOPY);
g_bKeyDown = 0;
g_tPre = GetTickCount(); //記錄此次繪圖時間
}
//-----------------------------------【Game_CleanUp( )函式】--------------------------------
// 描述:資源清理函式,在此函式中進行程式退出前資源的清理作業
//---------------------------------------------------------------------------------------------------
BOOL Game_CleanUp(HWND hwnd)
{
//釋放資源物件
DeleteObject(g_hBackGround);
DeleteObject(g_hHead);
DeleteObject(g_hBody);
DeleteObject(g_hCandy);
DeleteDC(g_bufdc);
DeleteDC(g_mdc);
ReleaseDC(hwnd, g_hdc);
return TRUE;
}
//-----------------------------------【其他函式】--------------------------------
void SetCandy()
{
//隨機放置糖果的位置
a: candy_x = 40 * (rand() % 20);
candy_y = 40 * (rand() % 15);
if (candy_x == snake.head.x&&candy_y == snake.head.y)//若新糖果與蛇頭重合
goto a;
for (int i = 0; i<snake.iSumPanel; i++)
if (candy_x == snake.body[i].x&&candy_y == snake.body[i].y)//若新糖果與蛇身重合
goto a;
g_bExistCandy = 1;
return;
}
//重新開始游戲
void ReplayGame()
{
g_bFailure = 0;
snake.iSumPanel = 1;
snake.head.x = 360;
snake.head.y = 360;
}
uj5u.com熱心網友回復:
第二個問題已解決,求大佬幫忙看看第一個問題,如何修改bgm
uj5u.com熱心網友回復:
1.猜測可能你的mp3格式與原來不匹配2.是vs視窗程式與控制臺程式的編譯沖突
VS2005中的設定
1.選單中選擇Project->Properties, 彈出Property Pages視窗
2.在左邊欄中依次選擇:ConfigurationProperties->C/C++->Preprocessor,然后在右邊欄的PreprocessorDefinitions對應的項中洗掉_WINDOWS,添加_CONSOLE
3.在左邊欄中依次選擇:ConfigurationProperties->Linker->System,然后在右邊欄的SubSystem對應的項改為console(/SUBSYSTEM:CONSOLE)
uj5u.com熱心網友回復:
mp3檔案應該不分類吧
uj5u.com熱心網友回復:
這里說的格式不是指mp3格式,是你播放程式對mp3有沒有什么t特別 要求。如果對mp3格式熟悉,可以另找個普通mp3檔案來剖析比較下。uj5u.com熱心網友回復:
想要修改的mp3檔案已放入debug中要放入 Release 中
uj5u.com熱心網友回復:
// mp3,在debug下無聲,直接運行有聲,顯然你的mp3路徑錯了// 默認,debug時,你沒有指明路徑的話,會呼叫源代碼同一目錄的檔案,而不是debug輸出目錄的檔案。
uj5u.com熱心網友回復:
// 你可以在debug時輸出 GetCurrentDirectory(),就可以看到會呼叫哪個目錄下的檔案了。uj5u.com熱心網友回復:
《Visual C++ 游戲開發經典案例詳解》轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/73878.html
標籤:硬件/系統
上一篇:各位大神求指導!用MFC做一個界面,下位機每隔一秒通過串口傳資料到上位機,現在能接收到資料,要想根據這些資料實時的畫矩形,是如何呼叫onpaint函式啊
