C ++ - не могу получить, если оператор работает с использованием состояний

0

В настоящее время я создаю проект, который включает в себя переход между различными игровыми состояниями, такими как главное меню, чтобы играть состояние состояния и воспроизведения в состояние битвы и т.д. Я в настоящее время борется с тем, чтобы мое боевое состояние только нарисовало врага, с которым игрок сталкивается внутри воспроизведения. Я пробовал делать это, используя очень просто "врагNo =;" где первый противник был 1, второй - 2 и т.д. то в состоянии битвы скажите "if (enemyNo = 1), затем нарисуйте врага 1 и соответствующие ему статистики. Невозможно, чтобы жизнь меня поняла, довольно уверен, что я не наследую значение врагаНо по всем состояниям должным образом. помощь будет оценена.

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
    "hopefully this is enough. If not i can upload more." Посмотрите на это: sscce.org
  • 0
    Это слишком много кода для одного вопроса. Спросите нас о конкретной части кода, с которой у вас возникли проблемы.
Показать ещё 1 комментарий
Теги:
if-statement

3 ответа

0

Вы должны объявить dstor в StatePlay virtual, потому что он действует как базовый класс для класса StateBattle. И в файле реализации StateBattle вы инициализируете врагаNo до 1 вместо сравнения с 1:

    //Enemy
    if(enemyNo == 1) // <-- missing == 
  • 0
    Ранее у нас было "==", но потом оно вообще ничего не рисовало. Извините за очень длинный пример кода, но на самом деле он не выдает никаких ошибок, просто он не рисует врага, которого мы ударили.
0

Вам не хватает =, вы должны написать

if(enemyNo == 1)

вместо

if(enemyNo = 1)

Но в следующий раз, пожалуйста, укажите меньший пример (как уже было предложено) с точным сообщением об ошибке.

  • 0
    Ранее у нас было "==", но потом оно вообще ничего не рисовало. Извините за очень длинный пример кода, но на самом деле он не выдает никаких ошибок, просто он не рисует врага, которого мы ударили.
  • 0
    Вы пытались пройти через StateBattle::draw и проверить, не имеет ли ваш enemyNo ожидаемое значение 1, 2 или 3?
0

Внутри ваших состояний вы должны удерживать только переменные состояния: переменные, привязанные только к этому конкретному состоянию. Враги могут быть переменными состояния, если у вас есть только одно игровое состояние, а все остальные состояния полностью независимы (т.е. состояние меню, состояние настройки...). Но у ваших государств есть перекрестные зависимости.

Чтобы решить эту проблему, вы должны сначала извлечь все, что не относится к одному конкретному состоянию в другой класс. Т.е. у вас может быть класс "Мир", который управляет списком врагов, ландшафтом... Или классом для списка ваших сущностей. Это дизайнерское решение, которое вы должны взять на себя.

Однако ваш StatePlay не должен обращаться с врагами - и получить его унаследованный StateBattle. StateBattle переопределяет функцию init (Game & context) из StatePlay - поэтому она никогда не вызывается, если вы ее не называете сами. ВрагНо в StateBattle так никогда не инициализируется (на самом деле это, а просто из-за другой ошибки)! Вы могли бы написать:

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

для этого. Но, как я уже указывал, в вашем классе есть некоторые вещи, которые делают работу с этими вещами сложной и избыточной.

Также вы не проверяете врага. Нет, вы его устанавливаете. = - оператор присваивания - вы хотите использовать оператор сравнения == Так лучше использовать:

if(enemyNo == 1)

вместо

if(enemyNo = 1)

В противном случае он установит ваш переменный врагNo в 1 вместо сравнения с 1.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню