C++ - Class 私有变量没有改变
C++ - Class private variables not changing
我使用 C++ 编程已有一段时间,并且正在使用 SDL2 库制作游戏。不幸的是,播放器的 class 变量仅在方法中更改,然后不更新以备后用。
Header:
class playerChar {
public:
void move();
void handleInput(SDL_Event& lEvent);
void render();
int getValX();
int getValY();
playerChar();
private:
int pPosX, pPosY; //Pos and Direction arent changing
int pDirectionX, pDirectionY;
//Posion and Direction (direction. Has value -1, 0 or 1)
static const int pVel = 10;
static const int pHeight = 10, pWidth = 10;
eTexture playerTex;
};
cpp 文件:
playerChar::playerChar(){
pPosX = 0;
pPosY = 0;
pDirectionX = 0;
pDirectionY = 0;
playerTex.loadFile("playerIMG.png");
}
void playerChar::handleInput(SDL_Event& lEvent){
//Key Pressed
if(lEvent.type == SDL_KEYDOWN && lEvent.key.repeat == 0){
switch(lEvent.key.keysym.sym){
case SDLK_UP:
pDirectionY = -1;
break;
case SDLK_s:
pDirectionY = 1;
printf("%i\n", pDirectionY);
break;
case SDLK_d:
pDirectionX = 1;
break;
case SDLK_a:
pDirectionX = -1;
break;
default:
break;
}
}
//Key Released
else if(lEvent.type == SDL_KEYUP && lEvent.key.repeat == 0){
switch(lEvent.key.keysym.sym){
case SDLK_w:
pDirectionY = 0;
break;
case SDLK_s:
pDirectionY = 0;
break;
case SDLK_d:
pDirectionX = 0;
break;
case SDLK_a:
pDirectionX = 0;
break;
default:
break;
}
}
}
void playerChar::move(){
//printf("pos:%i, vel:%i, dir:%i\n", pPosY, pVel, pDirectionY);
pPosX += pVel*pDirectionX;
pPosY += pVel*pDirectionY;
//If Direction is + then it adds velocity
//If Direction is - then it subtracts
//If Direction is 0 then adds nothing
//printf("%i, %i\n", pDirectionX, pDirectionY);
}
void playerChar::render(){
playerTex.render(pPosX, pPosY);
}
int playerChar::getValX(){
return pDirectionX;
}
int playerChar::getValY(){
return pDirectionY;
}
我每帧都用 printf() 检查它们的值(它只是 main() 中使用 getValX/Y() 方法的 printf())。 handleInput() 内部的那个显示它在方法中发生了变化,但是每帧运行的那个说它仍然是 0。我主要测试了按 s.
我试过使 handleInput() 方法 return 成为值,然后创建一个 set 方法,但没有解决问题。
我看了很多网站和论坛,还有一位有经验的朋友也被难住了,无法解决问题。任何帮助是极大的赞赏。
编辑:
对不起,如果我太含糊,我会尽量保持简洁。上面的 cpp 仅包含 playerChar class.
的方法
Main()中的实际实现是
int main(int argc, char* args[]) {
//irrevelvant to question
playerChar player;
while(!quit) {
fpsTimer.start();
quit = eInputCheck(event, player);
if(fpsTimer.getTicks() < ticksPerFrame) {
SDL_Delay(ticksPerFrame - fpsTimer.getTicks());
}
SDL_RenderClear(gRenderer);
//Render new frame here
player.move();
player.render();
printf("%ix, %iy\n", player.getValX(), player.getValY());
SDL_RenderPresent(gRenderer);
}
eClose();
return 0;
}
其中 eInputCheck() 来自 controls.cpp
bool eInputCheck(SDL_Event event, playerChar player){
while(SDL_PollEvent(&event) != 0){
player.handleInput(event);
if(event.type == SDL_QUIT){
return true;
}
return false;
}
我正在努力做到 pDirectionX/Y 将方向更改为 1 / -1 并使 0 停止。问题是,即使按住按钮,当我在 main.
中调用 getValX/Y 方法时,它似乎也没有改变
终端显示为这样,而 运行 我按 s:
0x, 0y
0x, 0y
0x, 0y
0x, 0y
0x, 0y
0x, 0y
0x, 0y
1 //The printf() from inside the handleInput() method
0x, 0y
0x, 0y
0x, 0y
0x, 0y
它甚至在按住按钮的同时给出了这个。 (我按ESC结束程序)
你传一个COPY给eInputCheck
,这个copy是在进入函数的时候构造的。您按值传递 playerChar
。
是这样的
playerChar otherOne = player; // Copies the player to the variable otherOne using a "copy constructor"
C++的案例非常多,是一门非常丰富的语言
playerChar otherOne = player; // Copies the player (said before).
playerChar &reference = player; // Reference is now refers to otherOne,
// a change on reference is reflected
// on player.
otherOne = player; // otherOne was initialized before,
// so copy constructor is not called
// But a copy assignment is called instead
reference = otherOne; // Reference was set before to refer to
// player, so, a "copy assignment" is
// called. Because references always
// refers to the same object
// initialized with. So, C++ solves this
// by copying the otherOne to the object
// refered by reference, using a copy
// assignment operator
这是 C++ 中最令人困惑和最困难的部分之一。
你有两个解决方案,
现代解决方案(我认为这在性能上对 C++ 不利),不变性,尝试 return 来自 eInputCheck
的新播放器实例。
第二种解决方案是将引用传递给 eInputCheck
请像这样重新定义 eInputCheck:
bool eInputCheck(SDL_Event &event, playerChar &player){
while(SDL_PollEvent(&event) != 0){
player.handleInput(event);
if(event.type == SDL_QUIT){
return true;
}
return false;
}
这会将引用传递给您的函数。
请阅读此内容:
我使用 C++ 编程已有一段时间,并且正在使用 SDL2 库制作游戏。不幸的是,播放器的 class 变量仅在方法中更改,然后不更新以备后用。
Header:
class playerChar {
public:
void move();
void handleInput(SDL_Event& lEvent);
void render();
int getValX();
int getValY();
playerChar();
private:
int pPosX, pPosY; //Pos and Direction arent changing
int pDirectionX, pDirectionY;
//Posion and Direction (direction. Has value -1, 0 or 1)
static const int pVel = 10;
static const int pHeight = 10, pWidth = 10;
eTexture playerTex;
};
cpp 文件:
playerChar::playerChar(){
pPosX = 0;
pPosY = 0;
pDirectionX = 0;
pDirectionY = 0;
playerTex.loadFile("playerIMG.png");
}
void playerChar::handleInput(SDL_Event& lEvent){
//Key Pressed
if(lEvent.type == SDL_KEYDOWN && lEvent.key.repeat == 0){
switch(lEvent.key.keysym.sym){
case SDLK_UP:
pDirectionY = -1;
break;
case SDLK_s:
pDirectionY = 1;
printf("%i\n", pDirectionY);
break;
case SDLK_d:
pDirectionX = 1;
break;
case SDLK_a:
pDirectionX = -1;
break;
default:
break;
}
}
//Key Released
else if(lEvent.type == SDL_KEYUP && lEvent.key.repeat == 0){
switch(lEvent.key.keysym.sym){
case SDLK_w:
pDirectionY = 0;
break;
case SDLK_s:
pDirectionY = 0;
break;
case SDLK_d:
pDirectionX = 0;
break;
case SDLK_a:
pDirectionX = 0;
break;
default:
break;
}
}
}
void playerChar::move(){
//printf("pos:%i, vel:%i, dir:%i\n", pPosY, pVel, pDirectionY);
pPosX += pVel*pDirectionX;
pPosY += pVel*pDirectionY;
//If Direction is + then it adds velocity
//If Direction is - then it subtracts
//If Direction is 0 then adds nothing
//printf("%i, %i\n", pDirectionX, pDirectionY);
}
void playerChar::render(){
playerTex.render(pPosX, pPosY);
}
int playerChar::getValX(){
return pDirectionX;
}
int playerChar::getValY(){
return pDirectionY;
}
我每帧都用 printf() 检查它们的值(它只是 main() 中使用 getValX/Y() 方法的 printf())。 handleInput() 内部的那个显示它在方法中发生了变化,但是每帧运行的那个说它仍然是 0。我主要测试了按 s.
我试过使 handleInput() 方法 return 成为值,然后创建一个 set 方法,但没有解决问题。
我看了很多网站和论坛,还有一位有经验的朋友也被难住了,无法解决问题。任何帮助是极大的赞赏。
编辑:
对不起,如果我太含糊,我会尽量保持简洁。上面的 cpp 仅包含 playerChar class.
的方法
Main()中的实际实现是
int main(int argc, char* args[]) {
//irrevelvant to question
playerChar player;
while(!quit) {
fpsTimer.start();
quit = eInputCheck(event, player);
if(fpsTimer.getTicks() < ticksPerFrame) {
SDL_Delay(ticksPerFrame - fpsTimer.getTicks());
}
SDL_RenderClear(gRenderer);
//Render new frame here
player.move();
player.render();
printf("%ix, %iy\n", player.getValX(), player.getValY());
SDL_RenderPresent(gRenderer);
}
eClose();
return 0;
}
其中 eInputCheck() 来自 controls.cpp
bool eInputCheck(SDL_Event event, playerChar player){
while(SDL_PollEvent(&event) != 0){
player.handleInput(event);
if(event.type == SDL_QUIT){
return true;
}
return false;
}
我正在努力做到 pDirectionX/Y 将方向更改为 1 / -1 并使 0 停止。问题是,即使按住按钮,当我在 main.
中调用 getValX/Y 方法时,它似乎也没有改变终端显示为这样,而 运行 我按 s:
0x, 0y
0x, 0y
0x, 0y
0x, 0y
0x, 0y
0x, 0y
0x, 0y
1 //The printf() from inside the handleInput() method
0x, 0y
0x, 0y
0x, 0y
0x, 0y
它甚至在按住按钮的同时给出了这个。 (我按ESC结束程序)
你传一个COPY给eInputCheck
,这个copy是在进入函数的时候构造的。您按值传递 playerChar
。
是这样的
playerChar otherOne = player; // Copies the player to the variable otherOne using a "copy constructor"
C++的案例非常多,是一门非常丰富的语言
playerChar otherOne = player; // Copies the player (said before).
playerChar &reference = player; // Reference is now refers to otherOne,
// a change on reference is reflected
// on player.
otherOne = player; // otherOne was initialized before,
// so copy constructor is not called
// But a copy assignment is called instead
reference = otherOne; // Reference was set before to refer to
// player, so, a "copy assignment" is
// called. Because references always
// refers to the same object
// initialized with. So, C++ solves this
// by copying the otherOne to the object
// refered by reference, using a copy
// assignment operator
这是 C++ 中最令人困惑和最困难的部分之一。
你有两个解决方案,
现代解决方案(我认为这在性能上对 C++ 不利),不变性,尝试 return 来自
eInputCheck
的新播放器实例。第二种解决方案是将引用传递给
eInputCheck
请像这样重新定义 eInputCheck:
bool eInputCheck(SDL_Event &event, playerChar &player){
while(SDL_PollEvent(&event) != 0){
player.handleInput(event);
if(event.type == SDL_QUIT){
return true;
}
return false;
}
这会将引用传递给您的函数。 请阅读此内容: