我已经用C ++编程了一段时间,并且正在使用SDL2库来制作游戏。不幸的是,该播放器的类具有仅在方法中更改的变量,然后不会更新以供以后使用。
部首:
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()s检查它们的值(它只是main()中使用getValX / Y()方法的printf())。 handleInput()内部的一个显示它在方法中已经改变,但是每帧运行的那个表示它仍然是0.我主要测试按s。
我试过让handleInput()方法返回值,然后创建一个set方法但是没有修复它。
我看了很多网站和论坛以及一位经验丰富的朋友,他也很难过,也无法解决问题。任何帮助是极大的赞赏。
修改
对不起,如果我太模糊,我试图保持简洁。 ONLY上方的cpp包含playerChar类的方法
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结束程序)
答案 0 :(得分:1)
您将COPY传递给eInputCheck
,此副本在进入函数时构建。您按值传递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 ++),不变性,尝试从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;
}
这会将引用传递给您的函数。 请阅读此内容: