功能实现
- 对话框绘制
- 敌人的出牌
对话框
在战斗界面按下右上角返回按钮时我们增加一个对话框用来提示进一步操作,避免误触导致gg
在Game.cpp中写绘制对话框的函数
void Game::drawPlayer() {
window.draw(sPlayUI);
humanPlayer.drawState(&window);
window.draw(turnEnd);
window.draw(disCardBtn);
}
然后设置一个默认为false的变量showBackDialog,在需要对话框出现的地方进行判断
void Game::drawFight() { //战斗场景
window.clear(); //清屏
window.draw(sGameFightBK); //绘制背景图
backToMenuBtn.setPosition(windowWidth * 0.9f, windowHeight * 0.05f); //按百分比绘制 不要写到别的函数里去
window.draw(backToMenuBtn);
drawPlayer();
drawEnemy();
//绘制
drawCard();
if (showBackDialog) {
drawDialog();
}
window.display(); //展示屏幕
}
在交互函数中修改
switch (backToMenuBtn.checkMouse(mousePosition, event)) {
case 1:
break;
case 3:
releaseSd.play(); //释放按钮的声音
showBackDialog = true; //显示对话框
break;
}
if (showBackDialog) {
switch (yesBtn.checkMouse(mousePosition, event)) {
case 3:
gameSceneState = SCENE_START; //切换场景
loadMusic(); //加载音乐
showBackDialog = false; //不显示对话框
yesBtn.setState(0); //设定按钮为普通状态
break;
}
switch (noBtn.checkMouse(mousePosition, event)) {
case 3:
showBackDialog = false;
break;
}
}
下面是效果
敌人的出牌
首先在Enemy类中定义一些必要的属性
void getCard(Card[], int, int); //抽牌
void showCard(RenderWindow*); //把敌人用过的卡牌展示在屏幕上
Card cardShow; //展示的卡牌
Vector2f cardPosition; //敌人卡牌的绘制位置
Clock useCardTimer; //出牌定时器
在抽牌时启动计时器,让敌人的每张出牌之间有一定的间隔
void Enemy::getCard(Card cards[], int getNum, int length) {
Player::getCard(cards, getNum, length);
cardShow = nullCard; //回合开始时出牌为null
useCardTimer.restart(); //启动计时器
}
然后是绘制卡牌
void Enemy::showCard(RenderWindow* window) {
if (handCardNums >= 0) {
if (useCardTimer.getElapsedTime().asMilliseconds() > 1200) { //大于1200 ms
for (int i = 0; i < handMaxNum; i++) {
if (handCards[i]->cardState != handCards[i]->null) { //如果手牌不为空
cardShow = *handCards[i]; //展示该卡牌
useCardTimer.restart(); //重启计时器
disCard(handCards[i]); //弃牌
handCards[i] = &nullCard; //手牌数组位置为null
return; //退出循环
}
}
} else {
if (cardShow.cardState != null) { //展示的卡牌状态不为null
window->draw(cardShow); //绘制卡牌
}
}
}
}
然后按回合按钮时转到敌人回合
void Game::fightInput(Vector2i mousePosition, Event event) {
switch (turnEnd.checkMouse(mousePosition, event, 0, 0)) {
case 1:
hoverSd.play();
break;
case 3:
releaseSd.play();
enemyCarpente.getCard(cards, enemyCarpente.getCardNum, sizeof(cards) / sizeof(cards[0]));
break;
}
}
最后进行出牌的 绘制
void Game::drawEnemy() {
window.draw(enemyCarpente.shape);
window.draw(sEnemyUI);
enemyCarpente.drawState(&window);
enemyCarpente.showCard(&window); //出牌
}
效果如下
卡牌交互Bug修复
由于修改了手牌数组运作的相关方法,之前卡牌交互的部分出现了bug:有时候不能正确判断最右边的手牌是视觉上的最右边的手牌
在交互函数中修改
int cardPos = 0; //当前卡牌是手牌中的第几张
for (int i = 0; i < humanPlayer.handMaxNum; i++) {
if (humanPlayer.handCards[i]->cardState != humanPlayer.handCards[i]->null) {
cardPos++;
if (cardPos != humanPlayer.handCardNums) { //如果不是最后一张手牌(在最上面)
cardOffset.x = 80;
cardOffset.y = 0;
} else {
cardOffset.x = 0;
cardOffset.y = 0;
}
}
}
窗口的优化
之前的游戏窗口大小是可以被改变的,我们在创建窗口时增加窗口样式来限制窗口大小
Uint32 windowStyle = sf::Style::Close | sf::Style::Titlebar;
window.create(sf::VideoMode(windowWidth, windowHeight), "月圆之夜", windowStyle);
这样窗口大小就不会被改变了