iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 20
3

引言

今天我們要正式來製作2D遊戲,
這次筆者在製作前會先列出規格表給大家看看,
讓大家了解最後會做出甚麼樣的成品~

我們要製作的是一款類似於魔塔(參考這個)
的小小RPG。題外話,很推薦大家玩玩看這個骨董級遊戲,雖然非常陽春,但好玩程度超乎想像~

但我們可能在功能方面就不像魔塔那麼多了,但至少會做到尋找鑰匙、開門的遊戲要素。


規格表

以下是遊戲的各種設定,之後程式碼會按照這個標準來撰寫:
所有音效請下載.wav檔案,沒有.wav的話須先轉成.wav

項目 內容
標題 "Dungeon Adventure" (有點中二XD)
遊戲視窗大小 高:寬 = 40:60
遊戲地圖大小 高:寬 = 30:59
遊戲確認音效 魔王魂システム49
遊戲BGM 魔王魂8bit 27

大致是這樣,其他規格會視情況在各篇中補充。


視窗設定

我們先打開昨天的專案(這裡),
將專案回復成這樣:
https://ithelp.ithome.com.tw/upload/images/20191004/201114291E52WPIL5w.png

我們第一步要先處理遊戲開啟的視窗設定標題高寬將如規格表所示。

  1. 新增SystemSetting.c以及SystemSetting.h:
/* File: SystemSetting.h */

#ifndef __SYSTEMSETTING_H__
#define __SYSTEMSETTING_H__



#endif
/* File: SystemSetting.c */

#include "SystemSetting.h"
  1. 將main.c上頭的兩個include移到SystemSetting.h,並引入SystemSetting.h:
/* File: main.c */

// ------------新增部分-------------------
#include "SystemSetting.h"
// --------------------------------------

int main(int argc, char *argv[])
{
    

    return 0;
}
/* File: SystemSetting.h */

#ifndef __SYSTEMSETTING_H__
#define __SYSTEMSETTING_H__

// ------------新增部分-------------------
#include <stdio.h>
#include <string.h>  // 等等會用到字串操作,預先引入
#include <windows.h>
// --------------------------------------

#endif
  1. 複製製作3D模擬器時的寫的清空畫面函數,selfCls(連結),一樣會用到滴:
/* File: SystemSetting.h */

#ifndef __SYSTEMSETTING_H__
#define __SYSTEMSETTING_H__

#include <stdio.h>
#include <string.h>  // 等等會用到字串操作,預先引入
#include <windows.h>

// ------------新增部分-------------------
HANDLE handler;  // 控制視窗的變數,視為視窗的控制把手
COORD xyPoint;  // Windows用的x, y座標型態
CONSOLE_CURSOR_INFO cursorInfo;  // 有關光標的資訊構成的結構

void selfCls();  // 自行撰寫的清空螢幕
// --------------------------------------

#endif
/* File: SystemSetting.c */

#include "SystemSetting.h"

// ------------新增部分-------------------
void selfCls()  // 此清空螢幕原理是直接將光標帶到第一個位置,再直接更新畫面
{
    handler = GetStdHandle(STD_OUTPUT_HANDLE);  // 取得標準輸出的handle
    xyPoint.X = 0;  // 希望x, y座標都能到0的位置
    xyPoint.Y = 0;
    SetConsoleCursorPosition(handler, xyPoint);  // 將座標設置到該位置
    cursorInfo.bVisible = FALSE;  // 光標設為不可見
    cursorInfo.dwSize = 1;  // 光標大小用不到,先設為1
    SetConsoleCursorInfo(handler, &cursorInfo);  // 設置光標資訊
}
// --------------------------------------
  1. 新增兩個函數,可以設定視窗高寬標題,並新增三個macro定義
/* File: SystemSetting.h */

#ifndef __SYSTEMSETTING_H__
#define __SYSTEMSETTING_H__

#include <stdio.h>
#include <string.h>
#include <windows.h>

// ------------新增部分-------------------
// 視窗常數定義
#define GAME_WIDTH 60  // 等等設定時將直接使用這些常數傳入,
#define GAME_HEIGHT 40 // 未來要修改時只要更改這邊的數值就行。
#define GAME_TITLE "Dungeon Adventure"
// --------------------------------------

HANDLE handler;  // 控制視窗的變數,視為視窗的控制把手
COORD xyPoint;  // Windows用的x, y座標型態
CONSOLE_CURSOR_INFO cursorInfo;  // 有關光標的資訊構成的結構

void selfCls();  // 自行撰寫的清空螢幕

// ------------新增部分-------------------
void setGameWindow(int c, int l);
void setGameTitle(char *name);
// --------------------------------------

#endif

/* File: SystemSetting.c */

// 寫在selfCls函數定義下

void setGameWindow(int c, int l)
{
    char commandBuffer[64] = "mode con:cols=";
    char numberStr[4] = "";

    sprintf(numberStr, "%d", c);
    strcat(commandBuffer, numberStr);

    strcat(commandBuffer, " lines=");

    sprintf(numberStr, "%d", l);
    strcat(commandBuffer, numberStr);

    system(commandBuffer);

    SetWindowPos(GetConsoleWindow(), HWND_TOPMOST, 500, 100, 0, 0, SWP_NOSIZE);
}


void setGameTitle(char *name)
{
    char commandBuffer[64] = "TITLE ";

    strcat(commandBuffer, name);

    system(commandBuffer);
}

播放BGM

昨天設定好環境,今天我們可以直接讓遊戲播放開頭BGM!
我會使用這個BGM,大家可以先下載來轉成.wav檔:魔王魂8bit 27

大家拿到BGM音檔後,將其放到昨天新增的musics資料夾:
https://ithelp.ithome.com.tw/upload/images/20191004/20111429ARUPfT8xxL.png

我們統一取名為bgm.wav,方便等等直接取用:
https://ithelp.ithome.com.tw/upload/images/20191004/20111429pdmbifRxxu.png

以下是程式碼:

  1. 先在SystemSetting.h檔設定一些定義:
/* File: SystemSetting.h */

#ifndef __SYSTEMSETTING_H__
#define __SYSTEMSETTING_H__

#include <stdio.h>
#include <string.h>
#include <windows.h>

// 視窗常數定義
#define GAME_WIDTH 60  // 等等設定時將直接使用這些常數傳入,
#define GAME_HEIGHT 40 // 未來要修改時只要更改這邊的數值就行。
#define GAME_TITLE "Dungeon Adventure"

// ------------新增部分-------------------
// 音樂定義
#define BGM "musics/bgm.wav"  // 紀錄bgm音檔位置
#define MUSIC_STOP NULL       // 停止音樂用

// 播放模式定義
#define BGM_MODE 0  // 無限循環播放的模式
#define SE_MODE 1   // 音效模式,播完就沒了
// --------------------------------------

HANDLE handler;  // 控制視窗的變數,視為視窗的控制把手
COORD xyPoint;  // Windows用的x, y座標型態
CONSOLE_CURSOR_INFO cursorInfo;  // 有關光標的資訊構成的結構

void selfCls();  // 自行撰寫的清空螢幕

void setGameWindow(int c, int l);
void setGameTitle(char *name);

#endif
  1. 宣告「播放音樂函數playMusic」,傳入音樂檔路徑以及播放模式:
/* File: SystemSetting.h */

// 寫在setGameTitle下

void playMusic(char *musicPath, int mode);  // 路徑與模式將會在呼叫時填入剛剛所定義的macro

  1. 定義playMusic於SystemSetting.c
/* File: SystemSetting.c */

// 寫在setGameTitle下

void playMusic(char *musicPath, int mode)
{
    if(mode == BGM_MODE)  // 若模式為BGM_MODE,PlaySound的第三參數將改為SND_ASYNC並多了SND_LOOP,
    {                     // 表示播放為非同步,播放的瞬間就return,不等音樂播完;LOOP就是無限播放。
        PlaySound(musicPath, NULL, SND_ASYNC|SND_FILENAME|SND_LOOP);
    }
    else if(mode == SE_MODE)
    {
        PlaySound(musicPath, NULL, SND_SYNC|SND_FILENAME);
    }
    else  // 不屬於兩種模式任一,則直接return。
    {
        return;
    }
}

主函式呼叫

回到main.c檔,我們直接來呼叫視窗設定BGM播放

#include "SystemSetting.h"  // 設定標題、視窗、音效、錯誤處理、遊戲初始化等

int main(int argc, char *argv[])
{
    playMusic(BGM, BGM_MODE);  // 以BGM模式播放BGM
    setGameTitle(GAME_TITLE);  // 遊戲標題設為GAME_TITLE
    setGameWindow(GAME_WIDTH, GAME_HEIGHT);  // 遊戲視窗長寬設為GAME_WIDTH, GAME_HEIGHT
    // (BGM, BGM_MODE, GAME_TITLE, GAME_WIDTH, GAME_HEIGHT 定義在SystemSetting.h中)
    
    system("pause");  // 程式暫停,按任意鍵繼續

    return 0;
}

執行

執行看看吧,看看標題、高寬、以及BGM有沒有順利播放:
https://ithelp.ithome.com.tw/upload/images/20191004/2011142989PNAshDnM.jpg


上一篇
[11屆鐵人賽Day19] 進入2D世界—聲音播放:PlaySound
下一篇
[11屆鐵人賽Day21] 2D遊戲—開頭畫面設計(讀檔應用)
系列文
若沒有遊戲引擎、合作夥伴...做得出遊戲嗎? 不試試看不知道吧? [使用C語言]30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言