Извините, если код неаккуратный, я работаю с QT только последние пару недель. Во время учебы я работаю над небольшой игрой, и сейчас я работаю над тем, когда игрок покупает предмет из магазина, он помещает его в сумку для персонажа.
Проблема в том, что когда я покупаю товар один раз, он работает нормально. Но если я удаляю элемент после покупки, затем выкупаю тот же элемент снова, он помещает два одинаковых элемента в массив, даже если я приобрел один.
У меня есть 3 файла, использованных для этого. Inventory.cpp
, GameScreen.cpp
, Shops.cpp
.
GameScreen.cpp
- это основной файл. Здесь я просто все инициализирую.
void GameScreen::initGame(QString &characterName, QString &characterProfession){
//PASS CHARACTERNAME AND CHARACTERPROFESSION INTO INVENTORY
inv.initCharacter(characterName, characterProfession);
//INIT BAG
inv.initBag();
//INIT MONEY
inv.initMoney();
//SHOPS INITS
mos.initShop();
mos.passMoneyToShop(inv.gold, inv.silver, inv.copper);
}
Откроется окно магазина. Подключение предмета является частью моей проблемы.
void GameScreen::on_mapOneShopB_clicked()
{
mos.setModal(true);
//SEND THE ITEM INTO BAG
connect(&mos, SIGNAL(getItemFromMapOneShop(const QString&)), &inv, SLOT(bagAddElement(const QString&)));
mos.show();
mos.exec();
}
Переезд в Shops.cpp
. Я использую полиморфизм в этом файле, и именно поэтому вы видите MapOneShop::
вместо Shops::
. Извините за путаницу. Но, двигаясь дальше, я нажимаю кнопку, и она вычитает цену предмета из моего количества золота.
void MapOneShop::on_buyB_clicked()
{
//ONLY WORKS IF I HIT THE ITEM NAME COLUMN THEN HIT BUY
gold -= itemPrice[ui->treeWidget->currentColumn()];
//UPDATE INFORMATION
updateInformationVAndMoneyAfterBuy();
}
Затем он переходит в updateInformationVAndMoneyAfterBuy();
, который проверяет, что я потратил деньги, и, если я это сделаю, выдаст нужный мне предмет. Я просто излучаю обратно в GameScreen.cpp
внутри void GameScreen::on_mapOneShopB_clicked()
и передаю их в Inventory.cpp
.
void MapOneShop::updateInformationVAndMoneyAfterBuy()
{
//UPDATE INFORMATIONV FIRST TO CHECK MONEY CHANGES
if(goldCheck != gold)
{
emit getUpdatedMoneyFromShop(gold, silver, copper);
//ITEM NAME IS WHERE I STORE THE NAMES OF THE ITEMS
emit getItemFromMapOneShop(this->itemName[ui->treeWidget->currentColumn()]);
}
}
Теперь перехожу в Inventory.cpp
. Когда элемент передается в bagAddElement
после удаления, а затем выкупа, я получаю два одинаковых элемента, даже если нужно передать только 1. Для этого я использую динамический массив c. Ниже я также покажу функции void Inventory::on_deleteB_clicked
, void Inventory::bagDeleteAt
, а также void Inventory::bagLWPrint
. Значение items
- это мой массив, содержащий строки shopItem.
void Inventory::bagAddElement(const QString& shopItem)
{
//I USE THIS TO CHECK THE VALUE shopItem.
qDebug()<<"bagAddElement: " << shopItem;
//IF THE CURRENT POSITION IN THE BAG
//IS BIGGER THAN THE CURRENT SIZE
//IT WILL INCREASE THE BAG FOR US
if(nrOfEl >= bagSize)
{
bagExpand();
}
//CHECK FOR VALUES INSIDE ARRAY AND CHECK IF THEY ARE NULL
//IF SO, IT WILL ADD THE ITEM INTO THE NULL POSITION
for(int i = 0; i < bagSize; i++)
{
if(items[i] == nullptr)
{
nrOfEl = i;
items[nrOfEl++] = shopItem;
break;
}
}
//UPDATE WIDGET LIST
bagLWPrint();
}
Здесь я передаю текущее выбранное значение строки внутри bagLW
и передаю его в void Inventory::bagDeleteAt
.
void Inventory::on_deleteB_clicked()
{
//BagLW IS A LIST WIDGET
bagDeleteAt(bagLW->currentRow());
}
Теперь мы ищем что внутри items[row]
и устанавливаем его в nullptr. Затем мы go в void Inventory::bagLWPrint
.
void Inventory::bagDeleteAt(int row)
{
if(items[row] == nullptr)
{
//IF THE ITEM IS ALREADY NULL WILL PRINT A MESSAGE
QMessageBox::information(this,"Bag","No item in that slot");
}
else
{
//SET CURRENTLY SELECTED ITEM TO NULL
items[row] = nullptr;
bagLWPrint();
}
}
Я очищаю bagLW
и пополняю его обновленным массивом.
void Inventory::bagLWPrint()
{
bagLW->clear();
for(int i = 0; i < bagSize; i++)
{
if(items[i] != nullptr)
{
bagLW->addItem(items[i]);
}
if(items[i] == nullptr)
{
bagLW->addItem(items[i]);
}
}
}
Другие примечания.
- Элемент удваивается только при вставке в void Inventory::bagAddElement
.
- Я пытался добавить еще один элемент внутри void GameScreen::initGame
, и он не удваивался после удаления и повторного ввода.
Извините за такой длинный вопрос. И любая помощь будет очень, очень ценится.
void Inventory::bagExpand()
{
//1: INCREASE BAGSPACE
bagSize *= 2;
//2: CREATE TEMP ARRAY
QString *tempItems = new QString[bagSize];
//3: COPY OVER VALID VALUES FROM OLD ARRAY
for(int i = 0; i < nrOfEl; i++)
{
tempItems[i] = items[i];
}
//4: DELETE OLD ARRAY MEMORY
delete[] items;
//5: POINT OLD ARRAY POINTER TO NEW ARRAY LOCATION
items = tempItems;
//PRINT BAGLW - (UDPATE)
bagLWPrint();
qDebug()<<"Bag has increased";
}