2017-02-07 29 views
-1

我遇到的問題是,當我更改對象的屬性時,更改不是「保存」。更容易向你展示發生了什麼。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在調用Select()函數時,我得到的selected屬性是false。奇怪的是這不是碰巧不在vector之內的那一段,簡稱爲k

之前你問也沒有地方在我的代碼,我設置selectedfalse :)(除了構造函數: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(); 
} 
+0

哈哈哈很好皮卡 – Andy

回答

5

此:

Piece p = pieces[i]; 

正在創建一個副本在片段索引我在向量中。

之後調用的任何方法都是在副本上進行操作,而不是在數組中的塊上進行操作。

相反,採取對它的引用:

Piece& p = pieces[i]; 

之後,p是在載體和你在其上執行的任何操作元件i基準的向量元件上被執行。

+0

剛剛更新與參考harmia :) – Boz

+0

啊謝謝,猜我需要使用指針?如果是的話,你會介意幫我拿出代碼嗎?真的很新的概念。 – Andy

+0

@Andy無需使用指針,使用參考如答案 – harmic

相關問題