功能实现

  1. 部分卡牌数值
  2. 无法出牌时的提示

卡牌数值的绑定

这里先做一部分卡牌的数值,就是那些没有特殊功能的卡牌

自定义一个cardManage类来进行卡牌的管理

#pragma once
#include "Player.h"
class cardManage {
public:
    int playerCardLength = 77, enemyCardLength = 63;
    Card playerCards[77], enemyCards[63];                                        //卡牌数组
    Texture tCard1[3][77], tEnemyCard[63];                                        //卡牌纹理数组
    void initCards();                                                            //初始化卡牌数据
    int useCard(Player*, Card*, Player*);                                        //使用卡牌
    void getCard(Player*, Card[], int, int, int);                                //抽牌 玩家,卡组 抽牌数 卡组数量 抽牌种类
    bool cardUsable(Player, Card);                                                //手牌是否可用

};

为了方便管理以及提高代码可读性,我把之前在Game.cpp里加载卡牌的部分重新写在了cardManage.cpp里

数值的绑定就比较枯燥了,有规律的就批量赋值,没有规律的就只能一张一张来了

void cardManage::initCards() {
    //加载卡牌图片
    for (int i = 0; i < 77; i++) {
        if (i < 8) {
            playerCards[i].cardType = playerCards[i].equip;
        } else if (i < 14) {
            playerCards[i].cardType = playerCards[i].attack;
        } else if (i < 26) {
            playerCards[i].cardType = playerCards[i].mp;
        } else if (i < 45) {
            playerCards[i].cardType = playerCards[i].movePower;
            playerCards[i].cost = 1;
        } else if (i < 72) {
            playerCards[i].cardType = playerCards[i].magic;
            playerCards[i].cost = 1;
        } else if (i < 77) {
            playerCards[i].cardType = playerCards[i].fightBack;
        }
    }
    playerCards[8].damage = 6;
    playerCards[8].getMp = 6;
    playerCards[9].damage = 5;
    playerCards[10].damage = 5;
    playerCards[11].damage = 5;
    playerCards[12].damage = 12;
    playerCards[12].destory = true;
    playerCards[13].damage = 5;
    playerCards[14].destory = true;
    playerCards[14].getMp = 25;
    playerCards[15].getMp = 8;
    playerCards[16].getMp = 5;
    playerCards[16].getHp = 5;
    playerCards[17].getMp = 5;
    playerCards[17].getHp = 5;
    //中间就省略了
    for (int i = 0; i < 63; i++) {
        if (i < 10) {
            enemyCards[i].cardType = enemyCards[i].equip;
        } else if (i < 24) {
            playerCards[i].cardType = enemyCards[i].attack;
        } else if (i < 25) {
            enemyCards[i].cardType = enemyCards[i].mp;
        } else if (i < 60) {
            enemyCards[i].cardType = enemyCards[i].movePower;
        } else if (i < 61) {
            enemyCards[i].cardType = enemyCards[i].fightBack;
        } else if (i < 63) {
            enemyCards[i].cardType = enemyCards[i].magic;
        }
    }
}

抽牌也是和之前写的大同小异

void cardManage::getCard(Player* player, Card cards[], int getNum, int cardLength, int cardType) {
    if (player->handCardNums == player->handMaxNum) {                                //手牌已达上限
        return;
    } else if (getNum + player->handCardNums > player->handMaxNum) {                //抽牌后会达到上限
        getNum = player->handMaxNum - player->handCardNums;
    }
    srand((unsigned)time(NULL));                                                    //随机
    if (player->handCardNums <= player->handMaxNum) {
        for (; getNum != 0;) {
            int num = rand() % cardLength;
            for (int i = 0; i < player->handMaxNum; i++) {
                if (player->handCards[i] == &player->nullCard) {
                    if (cards[num].cardState == cards[num].cardPool) {                //如果卡牌在卡池里就抽牌
                        if (cardType < 6) {                                            //卡牌种类 大于等于6为特殊牌(暂定)
                            if (cards[num].cardType == cardType) {                    //如果是对应种类
                                cards[num].cardState = cards[num].handPool;            //卡牌移到手牌区
                                player->handCardNums += 1;                            //手牌数加一
                                player->handCards[i] = &cards[num];                    //手牌数组赋值
                                getNum--;
                            }
                        }
                    }
                }
            }
        }
    }
}

卡牌的使用

int cardManage::useCard(Player* player1, Card* card, Player* player2) {
    if (!cardUsable(*player1, *card)) {
        return card->cardType;
    } else {
        player1->handCardNums--;                //手牌数减一
        card->cardState = card->disCardPool;    //移到弃牌区
        player1->mp += card->getMp;                //获得蓝量
        player1->movePower += card->getMovePower;    //获得行动力
        switch (card->cardType) {                //减去对应的消耗
            case card->magic:
                player1->mp -= card->cost;
                break;
            case card->movePower:
                player1->movePower -= card->cost;
                break;
            default:
                break;
        }
        if (player1->hp += card->getHp > player1->fullHp) {
            player1->hp = player1->fullHp;
        } else {
            player1->hp += card->getHp;                //获得血量
        }

        player1->hp += card->superHp;            //获得血量上限
        player1->fullHp += card->superHp;

        player2->reduceGetCardNum += card->reduceEnemyGetNum;        //减少抽牌数
        if (card->destory) {
            card->cardState = card->noPool;            //被移除
        }
        if (card->removeGame) {
            card->cardState = card->null;        //从游戏移去
        }
        if (card->getCardNum >= 1) {
            if (player1->humanPlayer) {
                getCard(player1, playerCards, card->getCardNum, playerCardLength, card->getCardType);
            } else {
                getCard(player1, enemyCards, card->getCardNum, enemyCardLength, card->getCardType);
            }
        }
        return -1;
    }
}

Game中调用

switch (humanPlayer.handCards[i]->checkMouse(mousePosition, event, cardOffset.x, cardOffset.y)) {        
    case 3:
        pressSd.stop();
        releaseSd.play();
        if (enemyCarpente.checkMouse(mousePosition)) {
        switch (cardManage.useCard(&humanPlayer, humanPlayer.handCards[i], &enemyCarpente)) {        //是否可出牌
            case 2:
                cout << "mp need";
                break;
            case 3:
                cout << "move need";
                break;
            case -1:
                attackSd.play();                                                    //播放攻击音乐
                humanPlayer.handCards[i] = &humanPlayer.nullCard;                    //设定使用后的手牌为null
                break;
        }
    } else {
        if (humanPlayer.handCards[i]->mouseContainf(disCardBtn.getPosition(), 30, -30)) {
            humanPlayer.disCard(humanPlayer.handCards[i]);
            humanPlayer.handCards[i] = &humanPlayer.nullCard;                    //设定使用后的手牌为null
        } else
            humanPlayer.handCards[i]->setState(humanPlayer.handCards[i]->NORMAL);        //释放后设定为普通状态
    }
    disCardBtn.setState(disCardBtn.NORMAL);
    humanPlayer.cardSelect = -1;                                //没有在与卡牌进行交互
    humanPlayer.handCards[i]->hoverSd = true;                    //释放卡牌,音效可播放
    humanPlayer.handCards[i]->pressSd = true;
    break;
}

差不多这个样子,行动力或蓝量不足就无法出对应的牌

出牌mp不足的提示

自定义一个hintText类,来进行各种提示文本的管理

hintText.h

#pragma once
#include <string>
#include "SFML/Graphics/RenderWindow.hpp"
#include <SFML\Graphics\Text.hpp>
#include <SFML\Graphics\Color.hpp>
using namespace sf;
using namespace std;
class hintText {
public:
    hintText();
    Color color;
    Font textFont;
    Text hint;
    Clock clock;
    bool isShow = false;            //是否正在绘制
    void setText(int);
    void showHint(RenderWindow*);
};

hintText.cpp

#include "hintText.h"
#include <iostream>
hintText::hintText() {
    textFont.loadFromFile("./data/font/simsun.ttc");
}
void hintText::setText(int type) {                //根据传入参数不同输出不同的文本
    hint.setFont(textFont);
    hint.setCharacterSize(40);
    switch (type) {
        case 0:
            hint.setString(L"魔力不足!");
            break;
        case 1:
            hint.setString(L"行动力不足!");
            break;
    }
    hint.setPosition(750, 400);
    color.r = 0;
    color.g = 0;
    color.b = 0;
    color.a = 255;
    hint.setFillColor(color);
    isShow = true;
    clock.restart();
}
void hintText::showHint(RenderWindow* window) {                        //慢慢变透明
    if (isShow) {
        if (clock.getElapsedTime().asMilliseconds() > 500) {
            color.a = 255 - (clock.getElapsedTime().asMilliseconds() - 500) / 10;
            hint.setFillColor(color);
        }
        if (clock.getElapsedTime().asMilliseconds() < 3050) {
            window->draw(hint);
        } else {
            isShow = false;
        }
    }
}

Game.cpp中调用

//fightInput中
switch (cardManage.useCard(&humanPlayer, humanPlayer.handCards[i], &enemyCarpente)) {        //是否可出牌
    case 2:
        hint.setText(0);
        break;
    case 3:
        hint.setText(1);
        break;
    case -1:
        attackSd.play();                                                    //播放攻击音乐
        humanPlayer.handCards[i] = &humanPlayer.nullCard;                    //设定使用后的手牌为null
        break;
}
void Game::drawDialog() {
    ///
    hint.showHint(&window);
}

大概效果,有一个缓慢消失的动画

Last modification:February 12th, 2021 at 06:15 am