??[導讀]本系列博文內容鏈接如下:
【C++】做一個飛機空戰(zhàn)小游戲(一)——使用getch()函數(shù)獲得鍵盤碼值
【C++】做一個飛機空戰(zhàn)小游戲(二)——利用getch()函數(shù)實現(xiàn)鍵盤控制單個字符移動
【C++】做一個飛機空戰(zhàn)小游戲(三)——getch()函數(shù)控制任意造型飛機圖標移動【C++】做一個飛機空戰(zhàn)小游戲(四)——給游戲添加背景音樂(多線程技巧應用)
【C++】做一個飛機空戰(zhàn)小游戲(五)——getch()控制兩個飛機圖標移動(控制光標位置)
【C++】做一個飛機空戰(zhàn)小游戲(六)——給兩架飛機設置不同顏色(cout輸出彩色字符、結構體使用技巧)
【C++】做一個飛機空戰(zhàn)小游戲(七)——兩組按鍵同時檢測平滑移動(GetAsyncKeyState()函數(shù)應用)
【C++】做一個飛機空戰(zhàn)小游戲(八)——生成敵方炮彈(rand()函數(shù)應用)
【C++】做一個飛機空戰(zhàn)小游戲(九)——發(fā)射子彈的編程技巧
【C++】做一個飛機空戰(zhàn)小游戲(十)——子彈擊落炮彈、炮彈與飛機相撞?
目錄
一、線程
(一)什么是線程
(二)為什么本游戲要用到多線程
(三)創(chuàng)建線程的步驟
1、引入頭文件
2、編寫線程函數(shù)
3、聲明線程號
4、創(chuàng)建線程
5、創(chuàng)建線程的完整代碼
二、播放音樂
(一)播放音樂的相關頭文件和函數(shù)
1、引入頭文件
2、播放音樂相關函數(shù)
(1)打開音頻文件
(2)播放音頻文件
(3)關閉音頻文件?
(二)播放音頻文件的設置
1、打開項目選項對話框
?2、設置鏈接
三、將循環(huán)播放音頻線程集成到主程序中
(一)自定義函數(shù)
(二)將循環(huán)播放音頻進程相關函數(shù)聲明和所引入的頭文件集成control_plane.h中
(三)將循環(huán)播放音頻進程相關函數(shù)定義集成到control_plane.cpp文件中
(四)將循環(huán)播放音頻進程集成到主函數(shù)中
本系列文章前三節(jié)介紹了如何用getch()函數(shù)控制飛機的圖標移動,并使用了模塊化的設計,為后邊的設計打下了一個比較好的基礎。
今天介紹如何給游戲添加背景音樂。
一、線程
(一)什么是線程
關于線程的概念,以及進程和線程的關系,網上有好多資料,本文不再贅述.本文只介紹一下小編對兩者的理解。
一個具有獨立完整功能的程序或軟件就是一個進程,這個程序里可以有多個線程并行運行,互不干擾,但是各個線程之間可以傳遞信息。線程,就是線性的過程,各個程序語句只能依次執(zhí)行,執(zhí)行完了前邊的才能執(zhí)行后邊的,這個線程中的每條語句都會順序執(zhí)行一次。
如果把火車站售票看成是一個進程,那么售票廳里開設的多個售票窗口就是多個線程,在每個窗口購票的人需要排隊依次購票,排在前邊的購完票了,后邊的才能購票。而兩個窗口,也就是兩個線程之間相互沒有影響,這個隊伍中的每名購票者速度的快慢,只會對這個窗口排隊購票的進度有影響,而不會對另外窗口的購票產生影響。
(二)為什么本游戲要用到多線程
本游戲目前設計了三個模塊:檢測鍵盤指令并控制飛機移動模塊,背景音樂循環(huán)播放模塊,敵方炮彈循環(huán)掉落模塊。
這三個模塊都需要循環(huán)進行,在程序里都需要用到while(1)循環(huán)。如果三個模塊放到同一個while(1)循環(huán)里,那么就會相互影響進程,游戲的流暢度大大降低。如果在同一個線程里放3個不同的while(1)循環(huán),那么后邊連個while(1)循環(huán)就根本沒有執(zhí)行的就會了。
所以把三個模塊放到3個不同的線程里,才會保證程序的正常運行。
(三)創(chuàng)建線程的步驟
1、引入頭文件
#include <pthread.h>
2、編寫線程函數(shù)
void* thread_name(void* arg)?
{?
? //此處為函數(shù)的具體內容
}?
3、聲明線程號
pthread_t tid;//pthread_t為線程類型,tid為線程id變量名
4、創(chuàng)建線程
pthread_create(&tid, NULL, thread_name, NULL);//創(chuàng)建線程
5、創(chuàng)建線程的完整代碼
#include <pthread.h>//導入線程頭文件庫
using namespace std;
//定義線程函數(shù)
void* thread_name(void* arg) //
{
//此處為函數(shù)的具體內容,本例要填入播放音頻的代碼
}
//主函數(shù)
int main()
{
pthread_t tid; //聲明線程id
pthread_create(&tid, NULL, thread_name, NULL);//創(chuàng)建線程
return 0;
}
二、播放音樂
(一)播放音樂的相關頭文件和函數(shù)
1、引入頭文件
#include <mmsystem.h> //導入聲音頭文件庫
#pragma comment(lib,"winmm.lib")//導入聲音的鏈接庫
#define _CRT_SECURE_NO_WARNINGS
2、播放音樂相關函數(shù)
(1)打開音頻文件
mciSendString(TEXT("open hero.mp3 alias s1"),NULL,0,NULL);
代碼中hero.mp3為音頻名稱,s1為導入程序后的變量名。
(2)播放音頻文件
mciSendString(TEXT("play s1"),NULL,0,NULL);
代碼中s1為打開音頻文件時,導入程序后的變量名。
(3)關閉音頻文件?
mciSendString(TEXT("close S1"),NULL,0,NULL);?
代碼中s1為打開音頻文件時,導入程序后的變量名。
(二)播放音頻文件的設置
本文是以Dev-C編程環(huán)境為例,需要進行如下配置:
1、打開項目選項對話框
操作:菜單"項目"-->"項目屬性"子菜單
?2、設置鏈接
操作:單擊"參數(shù)"標簽-->"鏈接"欄目中填入"-lwinmm",然后點"確定"。
三、將循環(huán)播放音頻線程集成到主程序中
(一)自定義函數(shù)
下圖為自定義的與播放音頻相關的3個函數(shù):
play_bgmusic()的作用是播放項目所在路徑內名為"hero.mp3"的一首音頻,播放完畢后關閉音頻;
thread_bgmusic()是實現(xiàn)循環(huán)播放音頻的線程函數(shù),其返回值為指針類型;
bgmusic()是最終的創(chuàng)建循環(huán)播放音頻進程的函數(shù),在主函數(shù)中只需調用這個函數(shù)即可。
//********************************************************************************
//以下三個函數(shù)為播放背景音樂功能
//********************************************************************************
//播放一遍背景音樂
void play_bgmusic() {
mciSendString(TEXT("open hero.mp3 alias s1"),NULL,0,NULL);
mciSendString(TEXT("play s1"),NULL,0,NULL);
Sleep(153*1000);//153*1000意思是153秒,是整首音樂的時長
mciSendString(TEXT("close S1"),NULL,0,NULL);
}
//循環(huán)播放音樂線程函數(shù)
void* thread_bgmusic(void* arg) //
{
while(1)
{
play_bgmusic();
}
}
//創(chuàng)建音樂播放線程,開始播放音樂
void bgmusic()
{
pthread_t tid;
pthread_create(&tid, NULL, thread_bgmusic, NULL);
}
(二)將循環(huán)播放音頻進程相關函數(shù)聲明和所引入的頭文件集成control_plane.h中
#ifndef CONTROL_PLANE_H
#define CONTROL_PLANE
#include <iostream>
#include <string>
#include<stdlib.h>
#include<windows.h>
#include <pthread.h>//導入線程頭文件庫
#include <mmsystem.h> //導入聲音頭文件庫
#pragma comment(lib,"winmm.lib")//導入聲音的鏈接庫
#define _CRT_SECURE_NO_WARNINGS
using namespace std;
#define t_b 0 //圖形顯示區(qū)域上側邊界
#define l_b 0 //圖形顯示區(qū)域左側邊界
#define r_b 100 //圖形顯示區(qū)域右側邊界
#define b_b 20 //圖形顯示區(qū)域下側邊界
//定義飛機造型
const string icon_plane[]={" ■ ","■ ■ ■","■■■■■","■ ■ ■"," ■ "," ■■■ "};
//定義圖標坐標結構體
typedef struct{
int x;
int y;
} location;
//定義移動方向命令枚舉類型
typedef enum {up_cmd,down_cmd,left_cmd,right_cmd} direction_cmd;
extern location plocation; //聲明飛機坐標
static direction_cmd dir_cmd; //聲明存放按鍵碼值的兩個變量
//聲明刷新飛機位置函數(shù)
void show_plane(location plct);
//獲取鍵盤指令
direction_cmd key(void);
//計算出接收指令后的飛機坐標
location plane_locate(location plct,direction_cmd dircmd);
void init(void);
void* thread_bgmusic(void* arg);
void play_bgmusic();
void bgmusic();
#endif
(三)將循環(huán)播放音頻進程相關函數(shù)定義集成到control_plane.cpp文件中
#include <iostream>
#include "conio.h"
#include <string>
#include "control_plane.h"
using namespace std;
//初始化函數(shù)
void init(void)
{
plocation.x=r_b/2; //初始化飛機圖標的x坐標為屏幕橫軸最大值的一半
plocation.y=b_b; //初始化飛機圖標的y坐標為屏幕縱軸最大值
}
//********************************************************************************
//以下三個函數(shù)為播放背景音樂功能
//********************************************************************************
//播放一遍背景音樂
void play_bgmusic() {
mciSendString(TEXT("open hero.mp3 alias s1"),NULL,0,NULL);
mciSendString(TEXT("play s1"),NULL,0,NULL);
Sleep(153*1000);//153*1000意思是153秒,是整首音樂的時長
mciSendString(TEXT("close S1"),NULL,0,NULL);
}
//循環(huán)播放音樂線程函數(shù)
void* thread_bgmusic(void* arg) //
{
while(1)
{
play_bgmusic();
}
}
//創(chuàng)建音樂播放線程,開始循環(huán)播放音樂
void bgmusic()
{
pthread_t tid;
pthread_create(&tid, NULL, thread_bgmusic, NULL);
}
//飛機圖標刷新函數(shù)
void show_plane(location plct) //預先定義字符定位顯示函數(shù),x是列坐標,y是行坐標,原點(x=0,y=0)位于屏幕左上角
{
int x,y;
int i,j;
int rows=sizeof(icon_plane)/sizeof(icon_plane[0]);
x=plct.x;
y=plct.y;
for(j=0;j<y;j++) //圖標上側輸出y個換行符
{
cout<<endl;
}
for(i=0;i<rows;i++) //圖標每行前輸出x個空格
{
for(j=0;j<x;j++)
{
cout<<" ";
}
cout<<icon_plane[i]<<endl;
}
}
//獲取鍵盤指令函數(shù)
direction_cmd key(void)
{
int key_value1,key_value2; //聲明兩個變量,存放鍵值
key_value1=getch(); //先獲取第一個碼值
if(key_value1==224) //如果第一個碼值為224,則進行第二個碼值的判斷
{
key_value2=getch(); //先獲取第二個碼值
switch(key_value2)
{
case 72: //向上方向鍵
return up_cmd;
case 80: //向下方向鍵
return down_cmd;
case 75: //向左方向鍵
return left_cmd;
case 77: //向右方向鍵
return right_cmd;
}
}
}
//計算獲得移動指令后飛機的坐標
location plane_locate(location plct,direction_cmd dircmd)
{
int x,y;
x=plct.x;
y=plct.y;
switch(dircmd)
{
case up_cmd:
y--; //字符上移一行,行值y減1
if(y<t_b) //限定y值最小值為0
{
y=t_b;
}
break;
case down_cmd:
y++; //字符下移一行,行值y加1
if(y>b_b) //限定y高度
{
y=b_b;
}
break;
case left_cmd:
x--; //字符左移一列,列值x減1
if(x<l_b)
{
x=l_b; //限定x最小值為0;
}
break;
case right_cmd:
x++; //字符右移一列,列值x加1
if(x>r_b)
{
x=r_b; //限定x寬度
}
break;
}
plct.x=x;
plct.y=y;
return plct;
}
(四)將循環(huán)播放音頻進程集成到主函數(shù)中
在游戲中插入背景音樂,代碼如下:
#include "control_plane.h"
using namespace std;
location plocation;
int main(int argc, char** argv) {
init(); //初始化
bgmusic();//播放背景音樂
while(1) //循環(huán)等待鍵盤指令
{
system("cls"); //清屏
show_plane(plocation); //刷新飛機圖標
dir_cmd=key(); //獲取按鍵指令
//計算收到鍵盤指令后的飛機坐標
plocation=plane_locate(plocation,dir_cmd);
}
return 0;
}
參考博文:
dev c++播放音樂MP3_c++播放mp3_輕覽月的博客-CSDN博客文章來源:http://www.zghlxwxcb.cn/news/detail-625540.html
(未完待續(xù))文章來源地址http://www.zghlxwxcb.cn/news/detail-625540.html
到了這里,關于【C++】做一個飛機空戰(zhàn)小游戲(四)——給游戲添加背景音樂(多線程技巧應用)的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!