Проблема, с которой я сталкиваюсь, заключается в том, что при изменении атрибута объекта изменение не является «сохранением». Легче показать вам, что происходит.Объекты в std :: vector не сохраняют атрибуты правильно
Я учусь c++
и решил построить небольшое шахматное приложение. Каждый Piece
является отдельным объектом.
Они хранятся в std::vector
как таковой
std::vector<Piece> pieces;
Они инициализируются как так
for (int i = 0; i < 2; i++)
{
Piece p;
p.Init(i*2+1, 1, renderer, SQUARE_SIZE, "king");
pieces.push_back(p);
}
Когда я нажимаю мышь Я хочу, чтобы выбрать все части (временно)
for (int i = 0; i < pieces.size(); i++)
{
Piece p = pieces[i];
p.Select();
}
Вопрос заключается в том, что w hile функция Select()
вызывается, к тому времени, когда я получаю рендеринг, их атрибут selected
- false
. Странно это не происходит с частью, не содержащейся в пределах vector
, называемой k
.
Перед тем, как задать там нет нигде в моем коде, который я поставил selected
в false
:) (за исключением конструктора: P)
Кроме того, если вы чувствуете, как downvoting, отправить мне комментарий первым, и я буду попробуйте исправить все!
Посмотрите все файлы. (Не уверен, если это правильный способ, чтобы вставить их)
Piece.h
#include <iostream>
#include <SDL2/SDL.h>
#include <SDL2/SDl_image.h>
#include <array>
#include <vector>
class Piece
{
public:
Piece();
void Init(int _x, int _y, SDL_Renderer* renderer, int SQUARE_SIZE, std::string type);
void SetPos(int _x, int _y, int _w);
void LoadTexture(SDL_Renderer* renderer, std::string type);
void LoadMovementVector(std::string type);
void Render(SDL_Renderer* renderer);
void Select(){ selected = true; std::cout << "called\n";}
bool isSelected(){ return selected; }
int GetX(){ return x; } // SDL_Point
int GetY(){ return y; }
private:
int x, y;
std::vector<int> move_vector;
bool selected;
SDL_Rect rect;
SDL_Texture* texture;
};
Piece.cpp
#include <iostream>
#include <SDL2/SDL.h>
#include <SDL2/SDl_image.h>
#include <vector>
#include "Piece.h"
Piece::Piece()
: x(0)
, y(0)
, selected(false)
{
}
void Piece::Init(int _x, int _y, SDL_Renderer* renderer, int SQUARE_SIZE, std::string type)
{
SetPos(_x, _y, SQUARE_SIZE);
LoadTexture(renderer, type);
LoadMovementVector(type);
}
void Piece::Render(SDL_Renderer* renderer)
{
//selected = true;
//std::cout << selected << std::endl;
if (selected)
{
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
SDL_RenderFillRect(renderer, &rect);
}
if (texture != nullptr)
{
SDL_RenderCopy(renderer, texture, nullptr, &rect);
}
else
{
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
SDL_RenderFillRect(renderer, &rect);
}
}
void Piece::LoadMovementVector(std::string type)
{
if (type == "king"){ // There literally has to be a better way to init std::vector
int arr[4] = {1,1,1,0};
for (int i = 0; i < 4; i++){ move_vector.push_back(arr[i]); }
}
for (int i = 0; i < move_vector.size(); i++)
{
std::cout << move_vector[i];
}
std::cout << std::endl;
}
void Piece::LoadTexture(SDL_Renderer* renderer, std::string type)
{
std::string source;
if (type == "king"){
source = "wk.png";
}
texture = IMG_LoadTexture(renderer, "res/wk.png");
}
void Piece::SetPos(int _x, int _y, int _w)
{
x = _x;
y = _y;
rect.x = _w*(_x-1);
rect.y = _w*(8-_y);
rect.w = _w;
rect.h = _w;
std::cout << x << y << std::endl;
}
main.cpp
#include <iostream>
#include <math.h>
#include <SDL2/SDL.h>
#include <SDL2/SDl_image.h>
#include "Piece.h"
using namespace std::chrono;
// Would be 'const int' but I want to make the board resizeable
int SCREEN_WIDTH = 800;
int SCREEN_HEIGHT = 800;
int BOARD_WIDTH, BOARD_HEIGHT, SQUARE_SIZE;
SDL_Window* window;
SDL_Renderer* renderer;
std::vector<Piece> pieces;
Piece k;
bool InitEverything();
bool InitSDL();
bool CreateWindow();
bool CreateRenderer();
void SetupRenderer();
void Quit();
void RunGame();
void Render();
void HandleInput();
void UpdateDimensions();
double GetDelta();
void RenderGameBoard();
bool loop = true;
auto timePrev = high_resolution_clock::now();
int main(int argc, char* args[])
{
if (!InitEverything())
return -1;
std::cout << "Running Game..." << std::endl;
for (int i = 0; i < 2; i++)
{
Piece p;
p.Init(i*2+1, 1, renderer, SQUARE_SIZE, "king");
pieces.push_back(p);
}
k.Init(5, 1, renderer, SQUARE_SIZE, "king");
RunGame();
Quit();
return 0;
}
void RunGame()
{
while (loop)
{
HandleInput();
Render();
double delta = GetDelta();
}
}
void Render()
{
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
SDL_RenderClear(renderer);
RenderGameBoard();
for (int i = 0; i < pieces.size(); i++)
{
pieces[i].Render(renderer);
}
k.Render(renderer);
SDL_RenderPresent(renderer);
}
void RenderGameBoard()
{
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
if ((j%2==0&&i%2==0)||(j%2!=0&&i%2!=0))
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
else
SDL_SetRenderDrawColor(renderer, 180, 180, 180, 255);
SDL_Rect r = {i*SQUARE_SIZE, j*SQUARE_SIZE, SQUARE_SIZE, SQUARE_SIZE};
SDL_RenderFillRect(renderer, &r);
}
}
}
void HandleInput()
{
SDL_Event event;
while (SDL_PollEvent(&event))
{
if (event.type == SDL_QUIT)
loop = false;
else if (event.type == SDL_KEYDOWN)
{
}
else if (event.type == SDL_MOUSEBUTTONDOWN)
{
if (event.button.button == SDL_BUTTON_LEFT)
{
k.Select();
for (int i = 0; i < pieces.size(); i++)
{
Piece p = pieces[i];
p.Select();
}
int x = floor(event.button.x/SQUARE_SIZE)+1;
int y = 8-floor(event.button.y/SQUARE_SIZE);
for (int i = 0; i < pieces.size(); i++)
{
Piece p = pieces[i];
if (p.GetX() == x && p.GetY() == y)
{
p.Select();
}
}
}
}
}
}
void UpdateDimensions()
{
BOARD_WIDTH = SCREEN_WIDTH;
BOARD_HEIGHT = SCREEN_HEIGHT;
SQUARE_SIZE = BOARD_WIDTH/8;
}
double GetDelta()
{
auto timeCurrent = high_resolution_clock::now();
auto timeDiff = duration_cast<nanoseconds>(timeCurrent - timePrev);
double delta = timeDiff.count();
delta /= 1000000000;
timePrev = timeCurrent;
return delta;
}
bool InitEverything()
{
if (!InitSDL())
return false;
if (!CreateWindow())
return false;
if (!CreateRenderer())
return false;
SetupRenderer();
UpdateDimensions();
return true;
}
bool InitSDL()
{
if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
{
std::cout << "SDL failed to initialize : " << SDL_GetError() << std::endl;
return false;
}
return true;
}
bool CreateWindow()
{
window = SDL_CreateWindow("Chess", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
if (!window)
{
std::cout << "Failed to create window : " << SDL_GetError() << std::endl;
return false;
}
return true;
}
bool CreateRenderer()
{
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if (!renderer)
{
std::cout << "Failed to create renderer : " << SDL_GetError() << std::endl;
return false;
}
return true;
}
void SetupRenderer()
{
SDL_RenderSetLogicalSize(renderer, SCREEN_WIDTH, SCREEN_HEIGHT);
}
void Quit()
{
SDL_DestroyWindow(window);
SDL_Quit();
}
Hahaha good pickup – Andy