Cocos2D-X用WASD移动Sprite时报expression must be a modifiable lvalue错误如何解决
错误原因
你遇到的编译错误是Lambda表达式的默认捕获规则导致的:你用[playerX, playerY]值捕获的方式把两个局部变量传入Lambda,默认状态下Lambda的调用运算符是const属性的,值捕获的变量在Lambda内部属于只读常量,不允许修改,因此你对这两个变量做加减操作时,编译器就会抛出「expression must be a modifiable lvalue」的错误。
除此之外你的代码还有一个隐藏问题:就算你修改了Lambda内部的playerX、playerY,改动的也只是捕获的变量副本,不会同步到外部的原始变量,而且你没有在坐标修改后调用Sprite的setPosition方法更新精灵位置,最终按键后精灵也不会移动。
解决方案
推荐两种可以直接落地的修改方案:
方案1:直接操作Sprite指针(无需修改类结构,适合新手)
直接捕获player指针,每次按键时读取精灵当前的坐标,修改后再赋值回精灵即可,替换你的事件监听器代码为以下内容:
auto keyboardListener = EventListenerKeyboard::create(); keyboardListener->onKeyPressed = [player](EventKeyboard::KeyCode keyCode, Event* event) { Vec2 currentPos = player->getPosition(); switch (keyCode) { case EventKeyboard::KeyCode::KEY_W: currentPos.y += 5.0f; break; case EventKeyboard::KeyCode::KEY_A: currentPos.x -= 5.0f; break; case EventKeyboard::KeyCode::KEY_S: currentPos.y -= 5.0f; break; case EventKeyboard::KeyCode::KEY_D: currentPos.x += 5.0f; break; case EventKeyboard::KeyCode::KEY_ESCAPE: Director::getInstance()->end(); break; } player->setPosition(currentPos); }; _eventDispatcher->addEventListenerWithSceneGraphPriority(keyboardListener, this);
方案2:将坐标设为类成员变量(适合需要多处使用坐标的场景)
如果后续你需要在类的其他方法中用到玩家坐标,可以把playerX、playerY和player指针都设为当前Layer类的成员变量:
- 在你的Layer头文件中添加成员变量声明:
class YourGameLayer : public cocos2d::Layer { // 原有代码省略 private: float playerX; float playerY; cocos2d::Sprite* player; // 原有代码省略 };
- 事件监听器的Lambda捕获this指针即可直接修改成员变量,修改后同步更新精灵位置:
auto keyboardListener = EventListenerKeyboard::create(); keyboardListener->onKeyPressed = [this](EventKeyboard::KeyCode keyCode, Event* event) { switch (keyCode) { case EventKeyboard::KeyCode::KEY_W: playerY += 5.0f; break; case EventKeyboard::KeyCode::KEY_A: playerX -= 5.0f; break; case EventKeyboard::KeyCode::KEY_S: playerY -= 5.0f; break; case EventKeyboard::KeyCode::KEY_D: playerX += 5.0f; break; case EventKeyboard::KeyCode::KEY_ESCAPE: Director::getInstance()->end(); break; } player->setPosition(cocos2d::Vec2(playerX, playerY)); }; _eventDispatcher->addEventListenerWithSceneGraphPriority(keyboardListener, this);
内容的提问来源于stack exchange,提问作者goochelheim
相关产品推荐
相关产品推荐

