iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 26
1

引言

昨天我們做出了可以跟怪物戰鬥的系統了,
但是...

有人發現嗎XD 打怪不會掉寶(or 錢、經驗)

所以我們今天要來讓打怪後可以掉,並且在商店買東西!

所以敵人規格表也多了一項:

敵人 生命 攻擊 防禦 掉錢
1 35 18 1 1
2 45 20 2 2
3 35 38 3 3
4 60 32 8 5
5 50 42 6 6

而為了做出商店,這邊筆者也列出商店規格表:

商店選項
1 生命值 + 100
2 攻擊力 + 2
3 防禦值 + 4
4 什麼都不做

商店所需花費是逐漸提高的,以下是花費成長曲線:

消費次數 花費
1 10
2 20
3 40
4 80
5+ 以此類推
其實就是每買一次價錢乘二(黑店XD

怪物掉錢

想要實作讓怪物掉錢的話,我們要先在Monster結構中加入每種怪的掉錢量—drop:

/* File: PlayGround.h */

typedef struct monster
{
    char skin;
    int hp;
    int atk;
    int def;
    
// ------------新增部分-------------------
    int drop;  // 紀錄怪會掉的錢
// --------------------------------------
    
}Monster;

然後在initMonster函數中加入各種怪的掉錢量:

/* File: PlayGround.c */

void initMonster()
{
    m1.skin = '1';
    m1.atk = 18;
    m1.def = 1;
    m1.hp = 35;

    m2.skin = '2';
    m2.atk = 20;
    m2.def = 2;
    m2.hp = 45;

    m3.skin = '3';
    m3.atk = 38;
    m3.def = 3;
    m3.hp = 35;

    m4.skin = '4';
    m4.atk = 32;
    m4.def = 8;
    m4.hp = 60;

    m5.skin = '5';
    m5.atk = 42;
    m5.def = 6;
    m5.hp = 50;

// ------------新增部分-------------------
    m1.drop = 1;  // 每一種怪掉的錢數量都不同
    m2.drop = 2;
    m3.drop = 3;
    m4.drop = 5;
    m5.drop = 6;
// --------------------------------------
    
}

最後,只要玩家打敗怪物,就必須把怪物掉的錢加到玩家身上

/* File: PlayGround.c */

int atkMonster(char monsterSkin)
{
    int monsterCurrentHp;
    int playerCurrentHp;

    playerCurrentHp = p.hp;

    Monster *monsterChooser;

    if(monsterSkin == '1')
    {
        monsterChooser = &m1;
    }
    else if(monsterSkin == '2')
    {
        monsterChooser = &m2;
    }
    else if(monsterSkin == '3')
    {
        monsterChooser = &m3;
    }
    else if(monsterSkin == '4')
    {
        monsterChooser = &m4;
    }
    else if(monsterSkin == '5')
    {
        monsterChooser = &m5;
    }
    else
    {
        monsterChooser = &m1;
    }

    if(monsterChooser->def >= p.atk) return 0;  // 一定輸
    if(p.def >= monsterChooser->atk)
    {
        printf("本次玩家毫髮無傷!\n");
        
    // ------------新增部分-------------------
        p.money += monsterChooser->drop;  // 怪掉錢
    // --------------------------------------

        return 1;  // 一定贏
    }

    monsterCurrentHp = monsterChooser->hp;

    while((playerCurrentHp > 0) && (monsterCurrentHp > 0))
    {
        monsterCurrentHp -= (p.atk - monsterChooser->def);  // 怪被玩家打
        if(monsterCurrentHp <= 0) break;
        playerCurrentHp -= (monsterChooser->atk - p.def);  // 玩家被怪打
    }

    if(playerCurrentHp <= 0) return 0;  // 玩家和怪如果一起死,算輸
    if(monsterCurrentHp <= 0)           // 玩家沒死,怪死,就贏了
    {
        printf("本次玩家所受傷害: %d\n", p.hp - playerCurrentHp);
        if(((double)(p.hp - playerCurrentHp)) / ((double)(p.hp)) > 0.9)
        {
            printf("差點死掉(汗\n");
        }
        else if(((double)(p.hp - playerCurrentHp)) / ((double)(p.hp)) > 0.5)
        {
            printf("滿痛的...\n");
        }
        else if(((double)(p.hp - playerCurrentHp)) / ((double)(p.hp)) > 0.3)
        {
            printf("有點痛...\n");
        }

        p.hp = playerCurrentHp;  // 贏了的話,血量要真的算給玩家
        
    // ------------新增部分-------------------
        p.money += monsterChooser->drop;  // 怪掉錢
    // --------------------------------------

        return 1;
    }
}

商店

有了錢的來源,我們可以設計一個商店讓玩家購買數值,首先在地圖中新增商店skin,"T":
https://ithelp.ithome.com.tw/upload/images/20191010/201114295RiOWpPx8U.png
https://ithelp.ithome.com.tw/upload/images/20191010/20111429sTFA4iWL3W.jpg

然後在movePlayer中新增商店的判斷式:

/* File: PlayGround.c */

// 在movePlayer函數中新增一判斷式

if(game_map[y][x] == 'T')
{
    switch(shopping())  // shopping函數定義在底下
    {
        case 1:
            p.money -= shopPrice;
            p.hp += 100;
            shopPrice *= 2;  // 直接漲價,不囉嗦
            break;
        case 2:
            p.money -= shopPrice;
            p.atk += 2;
            shopPrice *= 2;  // 直接漲價,不囉嗦
            break;
        case 3:
            p.money -= shopPrice;
            p.def += 4;
            shopPrice *= 2;  // 直接漲價,不囉嗦
            break;
        default:
            break;
    }
}

這段程式碼大意是,呼叫等等要定義的shopping函數,這個函數會回傳玩家選擇哪個商品,
然後底下用switch切換不同處理,每次購物完都會漲價一倍。

再來就是定義shopping函數:

/* File: PlayGround.h */

// 新增shopping宣告

int shopping();
/* File: PlayGround.c */

// 在.c檔中新增shopping定義

int shopping()  // shopping函數最後會回傳一整數,表示玩家選擇的商品
{
    if(p.money < shopPrice) return 0;  // 錢不夠就不進商店囉

    printf("只要花費%d金幣,就能獲得一種能力!\n(按下F1, F2, F3或Esc決定)", shopPrice);
    printf("<F1> 生命值 + 100\n");
    printf("<F2> 攻擊力 + 2\n");
    printf("<F3> 防禦值 + 4\n");
    printf("<Esc> 不想花錢@@\n");  // 以上五行是給玩家的提示訊息
    while(1)  // 直到玩家按下**以下按鍵其中一個**前都不斷循環
    {
        if(GetAsyncKeyState(VK_F1) != 0)  // 買生命值的話,回傳1
        {
            printf("購買生命值,謝謝惠顧!\n");
            playMusic(SYSTEM_OK, SE_MODE);
            waitForUser(800);
            return 1;
        }
        else if(GetAsyncKeyState(VK_F2) != 0)  // 買攻擊力的話,回傳2
        {
            printf("購買攻擊力,謝謝惠顧!\n");
            playMusic(SYSTEM_OK, SE_MODE);
            waitForUser(800);
            return 2;
        }
        else if(GetAsyncKeyState(VK_F3) != 0)  // 買防禦值的話,回傳3
        {
            printf("購買防禦值,謝謝惠顧!\n");
            playMusic(SYSTEM_OK, SE_MODE);
            waitForUser(800);
            return 3;
        }
        else if(GetAsyncKeyState(VK_ESCAPE) != 0)  // 什麼都不買的話,回傳0
        {
            printf("歡迎下次光臨!\n");
            playMusic(SYSTEM_OK, SE_MODE);
            waitForUser(800);
            return 0;
        }
    }
}

執行

這樣商店就完成囉! 程式的步驟大概是:

  1. 玩家觸碰到"T",此時movePlayer中的判斷式觸發,呼叫shopping函數。
  2. shopping函數顯示提示訊息給玩家,等待玩家輸入選擇。
  3. 玩家的選擇由shopping函數回傳,movePlayer的判斷式處理數值加減,並告知玩家。

那麼就來執行看看吧:
https://ithelp.ithome.com.tw/upload/images/20191010/201114298xW9WFXpSM.png
新增商店"T"。

https://ithelp.ithome.com.tw/upload/images/20191010/20111429mZsZawmTcb.png
先去打怪賺錢,目前賺了12塊!

https://ithelp.ithome.com.tw/upload/images/20191010/20111429NQXvN8JmDN.png
前往商店,顯示出選項,這時我選了「防禦」的話...

https://ithelp.ithome.com.tw/upload/images/20191010/20111429ICHrhfn6pa.png
會顯示「購買了防禦值」!

https://ithelp.ithome.com.tw/upload/images/20191010/20111429muyXYRfnjs.png
購買後,money剩下2塊,再次觸碰商店也沒有反應了,因為錢不夠~


這就是我們設計的商店啦~
是不是不難呢?


上一篇
[11屆鐵人賽Day25] 2D遊戲—戰鬥設定
下一篇
[11屆鐵人賽Day27] 2D遊戲—查看怪物資訊
系列文
若沒有遊戲引擎、合作夥伴...做得出遊戲嗎? 不試試看不知道吧? [使用C語言]30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言