2013-11-27 41 views
0

我目前正在创建一个项目,涉及不同的游戏状态,如主菜单状态和玩状态等战斗状态等进行切换我目前正在努力与使我的战斗状态只能吸引玩家在游戏状态内碰撞的敌人。我试图用一个非常简单的“enemyNo =”来做到这一点。第一个敌人是1,第二个是2,依此类推。然后在战斗状态下告诉它“如果(敌人= 1)然后画出敌人1并且它是相应的统计数据。我不能在生活中弄清楚它的存在,很确定我没有正确地继承敌人的值。帮助将不胜感激。C++ - 不能得到,如果语句工作使用状态

StatePlay.cpp

#include "StatePlay.h" 
#include <iostream> 
// stringstream and string 
#include <sstream> 
#include <string> 


#include "Game.h" 


StatePlay::StatePlay(void) 
{ 
} 


StatePlay::~StatePlay(void) 
{ 
} 

void StatePlay::init(Game &context) 
{ 

std::cout << "Initialising play state." << std::endl; 
player = new Rect(0.0f, 0.0f, 0.15f, 0.15f); 
//player stats 
health = 10; 
maxHealth = 10; 
strength = 10; 
speed = 10; 
dollars = 0; 

noTargets = false; 
targetCount = 5; 
bruteCount = 3; 
raiderCount = 1; 

//target 
for(int i = 1; i <=5; i++) 
{ 
target[i] = new Rect(); 
target[i]->setX((float)rand()/RAND_MAX - 0.75f); 
target[i]->setY((float)rand()/RAND_MAX - 0.75f);  
targetAlive[i] = true; 
} 

//brute 
for(int i = 1; i <=3; i++) 
{ 
brute[i] = new Rect(); 
brute[i]->setX((float)rand()/RAND_MAX - 0.75f); 
brute[i]->setY((float)rand()/RAND_MAX - 0.75f); 
bruteAlive[i] = true; 
} 

//raider 
for(int i = 1; i <=1; i++) 
{ 
raider[i] = new Rect(); 
raider[i]->setX((float)rand()/RAND_MAX - 0.75f); 
raider[i]->setY((float)rand()/RAND_MAX - 0.75f);  
raiderAlive[i] = true; 
} 


score = 0; 

} 


void StatePlay::enter() 
{ 
std::cout << "Entering play state. Press ESCAPE to return to menu" << std::endl; 
} 

void StatePlay::exit() 
{ 
} 


void StatePlay::draw(SDL_Window * window) 
{ 
// Replace this with OpenGL draw calls to draw the main menu screen 

TTF_Font *textFont = TTF_OpenFont("MavenPro-Regular.ttf", 24); 
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
glColor3f(1.0,1.0,1.0); 
player->draw(); 
std::stringstream strStream2; 
std::stringstream strStream3; 
strStream2 << "Player" << std::endl; 
strStream3 << "Target" << std::endl; 
Label :: displayString(player->x() + player->w()/2.0,player->y() + player->h(),  strStream2.str().c_str(), textFont); 

//enemy 
for(int i = 1; i <=5; i++) 
{ 
    if(targetAlive[i] == true) 
    { 
Label :: displayString(target[i]->x() + target[i]->w()/2.0,target[i]->y() + target[i]->h(), strStream3.str().c_str(), textFont); 

glColor3f(1.0,0.0,0.0); 
targetAlive[i] = target[i]; 
target[i]->draw(); 
} 
} 



std::stringstream strStream4; 
strStream4 << "Brute" << std::endl; 

//brute 
for(int i = 1; i <=3; i++) 
{ 
    if(bruteAlive[i] == true) 
    { 
Label :: displayString(brute[i]->x() + brute[i]->w()/2.0,brute[i]->y() + brute[i]->h(), strStream4.str().c_str(), textFont); 

glColor3f(0.6,0.3,0.1); 
bruteAlive[i] = brute[i]; 
brute[i]->draw(); 

} 
} 

std::stringstream strStream6; 
strStream6 << "Raider" << std::endl; 

//raider 
for(int i = 1; i <=1; i++) 
{ 
    if(raiderAlive[i] == true) 
    { 
     Label :: displayString(raider[i]->x() + raider[i]->w()/2.0,raider[i]->y() + raider[i]->h(), strStream6.str().c_str(), textFont); 

     glColor3f(0.2,0.9,0.4); 
     raiderAlive[i] = raider[i]; 
     raider[i]->draw(); 
    } 
} 

//information 
std::stringstream strStream; 
std::stringstream strStream1; 
strStream << "Score:" << score; 
strStream1 << "Health:" << health; 
Label :: displayString(-0.9,-0.9, strStream.str().c_str(), textFont); 
Label :: displayString(-0.4,-0.9, strStream1.str().c_str(), textFont); 
SDL_GL_SwapWindow(window); // swap buffers 
} 



void StatePlay::handleSDLEvent(SDL_Event const &sdlEvent, Game &context) 
{ 
if (sdlEvent.type == SDL_KEYDOWN) 
{ 
    //std::cout << "Scancode: " << sdlEvent.key.keysym.scancode ; 
    //std::cout << ", Name: " << SDL_GetKeyName(sdlEvent.key.keysym.sym) << std::endl; 
    switch(sdlEvent.key.keysym.sym) 
    { 
     case SDLK_UP: 
     case 'w': case 'W': 
      player->setY(player->y() + 0.05f); 
      break; 
     case SDLK_DOWN: 
     case 's': case 'S': 
      player->setY(player->y() - 0.05f); 
      break; 
     case SDLK_LEFT: 
     case 'a': case 'A': 
      player->setX(player->x() - 0.05f); 
      break; 
     case SDLK_RIGHT: 
     case 'd': case 'D': 
      player->setX(player->x() + 0.05f); 
      break; 
     default: 
      break; 
    } 
} 


if (sdlEvent.type == SDL_KEYDOWN) 
{ 
    //std::cout << "Scancode: " << sdlEvent.key.keysym.scancode ; 
    //std::cout << ", Name: " << SDL_GetKeyName(sdlEvent.key.keysym.sym) << std::endl; 
    switch(sdlEvent.key.keysym.sym) 
    { 
     case SDLK_ESCAPE: 
      context.setState(context.getMainMenuState()); 
     default: 
      break; 
    } 
} 

//target 
for(int i = 1; i <=5; i++) 
{ 
if ((target[i]->x() >= player->x()) && (target[i]->x()+target[i]->w() <= player->x()+player->w()) // cursor surrounds target in x 
&& (target[i]->y() >= player->y()) && (target[i]->y()+target[i]->h() <= player->y()+player->h()) && targetAlive[i] == true) // cursor surrounds target in y 
{ 
    score += 100; 
    enemyNo = 1; 
    context.setState(context.getBattleState()); 

    delete target[i]; 
    targetAlive[i] = false; 

    targetCount -= 1; 

} 
} 

//brute 
    for(int i = 1; i <=3; i++) 
{ 
if ((brute[i]->x() >= player->x()) && (brute[i]->x()+brute[i]->w() <= player->x()+player->w())  // cursor surrounds target in x 
&& (brute[i]->y() >= player->y()) && (brute[i]->y()+brute[i]->h() <= player->y()+player->h()) && bruteAlive[i] == true) // cursor surrounds target in y 
{ 

    score += 100; 
    enemyNo = 2; 
    context.setState(context.getBattleState()); 
    delete brute[i]; 
    bruteAlive[i] = false; 

    bruteCount -= 1; 

} 
} 

//raider 
for(int i = 1; i <=1; i++) 
{ 
if ((raider[i]->x() >= player->x()) && (raider[i]->x()+raider[i]->w() <= player->x()+player->w()) // cursor surrounds target in x 
&& (raider[i]->y() >= player->y()) && (raider[i]->y()+raider[i]->h() <= player->y()+player->h()) && raiderAlive[i] == true) // cursor surrounds target in y 
{ 
    score += 100; 
    enemyNo = 3; 
    context.setState(context.getBattleState()); 
    delete raider[i]; 
    raiderAlive[i] = false; 

    raiderCount -= 1; 

} 
} 





} 

StatePlay.h

#ifndef STATE_PLAY 
#define STATE_PLAY 

#include "gameState.h" 
#include "Label.h" 
// C stdlib and C time libraries for rand and time functions 
#include <cstdlib> 
#include <ctime> 
#include "rect.h" 

class StatePlay : public GameState 
{ 
public: 
StatePlay(void); 
~StatePlay(void); 
void init(Game &context); 
void draw(SDL_Window * window); 
void handleSDLEvent(SDL_Event const &sdlEvent, Game &context); 
void enter(); 
void exit(); 
int enemyNo; 



int targetCount; 
private: 
//player Stats 
int score; 
int health; 
int maxHealth; 
int strength; 
int speed; 
int dollars; 



int getHealth() {return health;} 
int getMaxHealth() { return maxHealth;} 
int getStrength() { return strength;} 
int getSpeed() { return speed;} 
int getDollars() { return dollars; } 

void setHealth(int newHealth) { health = newHealth; } 
void damageTaken(int damage) { health = health - damage; } 
void setMaxHealth(int newHealth) { maxHealth = maxHealth + newHealth; } 
void setStrength(int newStrength) { strength = strength+newStrength; } 
void setSpeed(int newSpeed) { speed = speed+newSpeed; } 
void setDollars(int newDollars) { dollars = dollars+newDollars; } 

// Another *strong* candidate for creating a new class type 
// is character/agent, to encapsulate player and target data, 
// potentially to include an Agent::draw() function and 
// perhaps also generalise collision detection 
// This is left as a further exercise 
float xpos; 
float ypos; 
float xsize; 
float ysize; 


//target 
float targetXPos; 
float targetYPos; 
float targetXSize; 
float targetYSize; 


bool targetAlive[5]; 
bool noTargets; 

//brute 
float bruteXPos; 
float bruteYPos; 
float bruteXSize; 
float bruteYSize; 

int bruteCount; 
bool bruteAlive[5]; 
bool noBrutes; 

//raider 
float raiderXPos; 
float raiderYPos; 
float raiderXSize; 
float raiderYSize; 

int raiderCount; 
bool raiderAlive[1]; 
bool noRaider; 

clock_t lastTime; // clock_t is an integer type 
clock_t currentTime; // use this to track time between frames 

Label * playerLabel; 
Label * targetLabel; 
Label * bruteLabel; 
Label * raiderLabel; 

TTF_Font * textFont; // SDL type for True-Type font rendering 
Rect * player; 
Rect * target[5]; 
Rect * brute[3]; 
Rect * raider[1]; 

}; 

#endif 

StateBattle.cpp

#include "StateBattle.h" 

#include <iostream> 
#include "Game.h" 
#include "StatePlay.h" 
#include "rect.h" 


StateBattle::StateBattle(void) 
{ 
} 


StateBattle::~StateBattle(void) 
{ 
} 

void StateBattle::init(Game &context) 
{ 
fighting = false; 
} 

void StateBattle::enter() 
{ 
std::cout << "Entering main menu state: Press RETURN to play or ESCAPE to quit " << std::endl; 
} 

void StateBattle::exit() 
{ 
} 


void StateBattle::draw(SDL_Window * window) 
{ 
glClearColor(0.0f,0.0f,0.0f,0.0f); 
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
glColor3f(1.0,1.0,1.0); 
TTF_Font *textFont = TTF_OpenFont("MavenPro-Regular.ttf", 24); 
std::stringstream strStream; 
strStream << "FIGHT!" <<std::endl; 
Label :: displayString(-0.8 ,0.8, strStream.str().c_str(),textFont); 

//player 
Rect * player; 
player = new Rect(-0.4f, 0.0f, 0.15f, 0.15f); 
player ->draw(); 

std::stringstream playerStrStream1; 
playerStrStream1 << "Health:" << std::endl; 
Label :: displayString(-0.4 ,0.5, playerStrStream1.str().c_str(),textFont); 

std::stringstream playerStrStream2; 
playerStrStream2 << "Strength:" << std::endl; 
Label :: displayString(-0.4 , -0.2, playerStrStream2.str().c_str(),textFont); 

std::stringstream playerStrStream3; 
playerStrStream3 << "Speed:" << std::endl; 
Label :: displayString(-0.4 , -0.3, playerStrStream3.str().c_str(),textFont); 

std::stringstream playerStrStream4; 
playerStrStream4 << "Dollars:" << std::endl; 
Label :: displayString(-0.4 , -0.4, playerStrStream4.str().c_str(),textFont); 


//Enemy 
if(enemyNo = 1) 
{ 
Rect * target; 
glColor3f(1.0,0.0,0.0); 
target = new Rect(0.4f, 0.0f, 0.15f, 0.15f); 
target->draw(); 

std::stringstream targetStrStream1; 
targetStrStream1 << "Health:" << std::endl; 
Label :: displayString(0.4f,0.5f, targetStrStream1.str().c_str(),textFont); 

std::stringstream targetStrStream2; 
targetStrStream2 << "Strength:" << std::endl; 
Label :: displayString(0.4, -0.2, targetStrStream2.str().c_str(),textFont); 

std::stringstream targetStrStream3; 
targetStrStream3 << "Speed:" << std::endl; 
Label :: displayString(0.4, -0.3, targetStrStream3.str().c_str(),textFont); 

std::stringstream targetStrStream4; 
targetStrStream4 << "Dollars:" << std::endl; 
Label :: displayString(0.4, -0.4, playerStrStream4.str().c_str(),textFont); 
} 

//brute 
if(enemyNo = 2) 
{ 
Rect * brute; 
glColor3f(0.6,0.3,0.1); 
brute = new Rect(0.6f, 0.0f, 0.15f, 0.15f); 
brute->draw(); 

std::stringstream bruteStrStream1; 
bruteStrStream1 << "Health:" << std::endl; 
Label :: displayString(0.4, 0.5, bruteStrStream1.str().c_str(),textFont); 

std::stringstream bruteStrStream2; 
bruteStrStream2 << "Strength:" << std::endl; 
Label :: displayString(0.4, -0.2, bruteStrStream2.str().c_str(),textFont); 

std::stringstream bruteStrStream3; 
bruteStrStream3 << "Speed:" << std::endl; 
Label :: displayString(0.4, -0.3, bruteStrStream3.str().c_str(),textFont); 

std::stringstream bruteStrStream4; 
bruteStrStream4 << "Dollars:" << std::endl; 
Label :: displayString(0.4, -0.4, bruteStrStream4.str().c_str(),textFont); 
} 

//raider 
if(enemyNo = 3) 
{ 
Rect * raider; 
glColor3f(0.2,0.9,0.4); 
raider = new Rect(0.8f, 0.0f, 0.15f, 0.15f); 
raider->draw(); 

std::stringstream raiderStrStream1; 
raiderStrStream1 << "Health:" << std::endl; 
Label :: displayString(0.4, 0.5, raiderStrStream1.str().c_str(),textFont); 

std::stringstream raiderStrStream2; 
raiderStrStream2 << "Strength:" << std::endl; 
Label :: displayString(0.4, -0.2, raiderStrStream2.str().c_str(),textFont); 

std::stringstream raiderStrStream3; 
raiderStrStream3 << "Speed:" << std::endl; 
Label :: displayString(0.4, -0.3, raiderStrStream3.str().c_str(),textFont); 

std::stringstream raiderStrStream4; 
raiderStrStream4 << "Dollars:" << std::endl; 
Label :: displayString(0.4, -0.4, raiderStrStream4.str().c_str(),textFont); 

} 

SDL_GL_SwapWindow(window); // swap buffers 
} 


void StateBattle::handleSDLEvent(SDL_Event const &sdlEvent, Game &context) 
{ 
// Add additional input checks for any other actions carried out in this state 
std::cout << "Event handling in main menu state." << std::endl; 
if (sdlEvent.type == SDL_KEYDOWN) 
{ 
    //std::cout << "Scancode: " << sdlEvent.key.keysym.scancode ; 
    //std::cout << ", Name: " << SDL_GetKeyName(sdlEvent.key.keysym.sym) << std::endl; 
    switch(sdlEvent.key.keysym.sym) 
    { 
     case SDLK_RETURN: 
      context.setState(context.getPlayState()); 
      break; 
     case SDLK_ESCAPE: 
      // Create a SDL quit event and push into the event queue 
      SDL_Event quitEvent; 
      quitEvent.type = SDL_QUIT; 
      SDL_PushEvent(&quitEvent); 
     default: 
      break; 
    } 
} 
} 

StateBattle.h

#ifndef STATE_BATTLE 
#define STATE_BATTLE 

#include "GameState.h" 
#include "Label.h" 
#include "StatePlay.h" 

class StateBattle : public GameState, public StatePlay 
{ 
public: 
StateBattle(void); 
~StateBattle(void); 
void init(Game &context); 
void draw(SDL_Window * window); 
void handleSDLEvent(SDL_Event const &sdlEvent, Game &context); 
void enter(); 
void exit(); 
bool fighting; 
}; 

#endif 

我已经包括了所有的.cpp和参与.h文件,希望这就够了。如果没有,我可以上传更多。 再次感谢

+2

'“希望这已经足够了,如果没有,我可以上传更多。”'看看这个:http://sscce.org/ –

+0

这对于单个问题来说代码太多了。向我们咨询您遇到问题的特定部分代码。 – Salgar

+0

请显示您正在更改状态的代码。 – Constantin

回答

0

你缺少一个=,你应该写

 
if(enemyNo == 1) 

,而不是

 
if(enemyNo = 1) 

但是接下来的时间,请提供较小的例子(如已经建议)与确切的错误信息。

+0

我们以前有过“==”,但是它什么都没画出来。很抱歉,很长的示例代码,但它实际上并没有抛出任何错误,它只是没有吸引我们击中的敌人。 – user3041704

+0

您是否试图通过您的'StateBattle :: draw'来检查您的'enemyNo'是否具有1,2或3的期望值? – Syjin

0

您应该在StatePlay虚拟中声明dstor,因为它充当StateBattle类的基类。而在StateBattle实现文件你被初始化enemyNo 1而不是它比较1:

//Enemy 
    if(enemyNo == 1) // <-- missing == 
+0

我们之前做过“==”,但是它什么都没画。很抱歉,很长的示例代码,但它实际上并没有抛出任何错误,它只是没有吸引我们击中的敌人。 – user3041704

0

你的状态,你应该只保持状态变量里面:绑定到仅此特定的状态变量。如果你只有一个游戏状态,并且所有其他状态都是完全独立的(即菜单状态,设置状态...),敌人可能是一个状态变量。但是你的状态具有交叉依赖性。

要解决此问题,您应该首先将不属于某个特定状态的所有内容提取到另一个类中。即你可以有一个'世界'类,它管理敌人,地形,或者你的实体列表的类。这是一个你必须承担自己的设计决定。

但是,你的StatePlay不应该处理敌人 - 并让它继承StateBattle。 StateBattle覆盖了StatePlay的init(Game &上下文)函数 - 所以如果你不自己调用它,它将永远不会被调用。在StateBattle中的敌人永远不会以这种方式创新(实际上它是,但仅仅是因为另一个错误)! 你可以这样写:

void StateBattle::init(Game &context) 
{ 
    StatePlay::init(context); 
    fighting = false; 
} 

这样做。但就像我指出的那样,你的班级设计中有一些东西,这使得处理这些事情变得艰难和多余。

此外,你不检查敌人否 - 你正在设置它。 =是赋值运算符 - 你要使用的比较操作== 因此更好地利用:

if(enemyNo == 1) 

,而不是

if(enemyNo = 1) 

否则将设置你的变量enemyNo 1而不是把它比对1.