Добавить класс в вектор другого класса с текстурами - PullRequest
0 голосов
/ 26 мая 2018

Я пытаюсь сделать игру, основанную на игре змей.Я получил основы ООП в c ++, но я только начал учиться на SFML.

Моя проблема в том, что в моей змее некоторые части не видны, как на картинке ниже.enter image description here

Так что "Тело" - это мой базовый класс.Я хочу, чтобы моя змея делала каждую часть из разных подклассов.Это также означает, что каждая часть будет иметь различную текстуру.

На данный момент я создал первый подкласс под названием «Ironman».Пробел, который я отметил на картинке, является частью этого подкласса.Остальные змеи - это части из класса «Тело».

Если мой код будет работать в «промежутке», то должна быть видна текстура, такая же, как в середине картинки (голова Железного человека).

Голова Ironman посередине просто для теста :) показывает, как должна выглядеть деталь Ironman.

Вот мой код.

main.cpp

#include <SFML/Graphics.hpp>
#include<vector>
#include"Body.h"
#include<iostream>
#include"Ironman.h"

int main()
{
int w_width = 1000, w_height = 700;
float x = w_width / 2.0, y = w_height / 2.0;
double speed = 2.5;

sf::RenderWindow window(sf::VideoMode(w_width, w_height), "Snake practise");

sf::RectangleShape map;
map.setSize(sf::Vector2f(700, 500));
map.setOrigin(map.getSize().x / 2.0, map.getSize().y / 2.0);
map.setPosition(w_width / 2.0, w_height / 2.0);
map.setFillColor(sf::Color::White);

enum Direction { UP, DOWN, RIGHT, LEFT };

int direct = UP;


sf::Texture pTexture;
pTexture.setSmooth(false);
if (!pTexture.loadFromFile("image/cp_shield.png"))
    std::cerr << "Error texture!" << std::endl;

sf::Texture ironTexture;
if (!ironTexture.loadFromFile("image/ironman.png"))
    std::cerr << "Error ironman!" << std::endl;

std::vector<Body> snake;
Body head(pTexture, w_width, w_height);
snake.push_back(head);

Ironman glowa(ironTexture, w_width, w_height);


for (int i = 1; i < 500; i++) {

    if (i <= 32) {
        Ironman newIron(ironTexture, w_width, w_height);

        snake.push_back(newIron);
    }
    else {
        Body newPart(pTexture, w_width, w_height);

        snake.push_back(newPart);
    }
}

for (int i = 1; i < snake.size(); i++) {
    if (i % 16 != 0) {
        snake[i].makeTransparent();
    }
}

sf::View view;
view.setCenter(sf::Vector2f(0,0));
view.setSize(w_width, w_height);


while (window.isOpen())
{
    sf::Vector2f lastPosition(snake[0].getPosX(),snake[0].getPosY());

    sf::Event event;
    while (window.pollEvent(event))
    {
        if (event.type == sf::Event::Closed)
            window.close();
    }

    //textures
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up) && snake[0].getDirection() != DOWN) {
        snake[0].setDirection(UP);
    }
    else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down) && snake[0].getDirection() != UP) {
        snake[0].setDirection(DOWN);
    }
    else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right) && snake[0].getDirection() != LEFT) {
        snake[0].setDirection(RIGHT);
    }
    else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left) && snake[0].getDirection() != RIGHT) {
        snake[0].setDirection(LEFT);
    }

    if (snake[0].getDirection() == UP) {
        snake[0].moveUp(speed);
    }
    else if (snake[0].getDirection() == DOWN) {
        snake[0].moveDown(speed);
    }
    else if (snake[0].getDirection() == LEFT) {
        snake[0].moveLeft(speed);
    }
    else if (snake[0].getDirection() == RIGHT) {
        snake[0].moveRight(speed);
    }

    view.setCenter(snake[0].getPosX(), snake[0].getPosY());


    //movement
    sf::Vector2f newPosition(lastPosition);

    for (int i = 1; i < snake.size(); i++) {
        sf::Vector2f lastPosition(snake[i].getPosX(), snake[i].getPosY());
        //lastPosition = snake[i].getPosition();
        snake[i].setPosX(newPosition.x,newPosition.y);
        newPosition = lastPosition;

    }

    window.clear();

    window.setView(view);

    window.draw(map);
    window.draw(glowa);

    for (auto itr : snake)
        window.draw(itr);
        //itr.drawBody(window);

    window.display();
}

return 0;

}

Body.cpp

#include"Body.h"

Body::Body(){

}

Body::Body(sf::Texture& imgPath, int wWidth, int wHeight) {
  _Sprite.setTexture(imgPath);
  _Sprite.setPosition(sf::Vector2f(wWidth / 2.0, wHeight / 2.0));
  _Sprite.setOrigin(imgPath.getSize().x / 2.0, imgPath.getSize().y / 2.0);
  _Sprite.setScale(0.025,0.025);
}

Body::~Body() {

}

void Body::draw(sf::RenderTarget& target, sf::RenderStates states)const {
  target.draw(_Sprite, states);
}

void Body::drawBody(sf::RenderWindow& window) {
  window.draw(_Sprite);
}

void Body::setDirection(int direct) {
  _direction = direct;
}

int Body::getDirection() {
  return _direction;
}

void Body::moveUp(double speed) {
  _Sprite.move(sf::Vector2f(0, -speed));
}

void Body::moveDown(double speed) {
  _Sprite.move(sf::Vector2f(0, speed));
}

void Body::moveLeft(double speed) {
  _Sprite.move(sf::Vector2f(-speed, 0));
}

void Body::moveRight(double speed) {
  _Sprite.move(sf::Vector2f(speed, 0));
}

void Body::setPosX(float x, float y) {
  _Sprite.setPosition(x, y);
}

float Body::getPosX() {
  return _Sprite.getPosition().x;
}

float Body::getPosY() {
  return _Sprite.getPosition().y;
}

void Body::makeTransparent() {
  _Sprite.setColor(sf::Color(0, 0, 0, 0));
}

Ironman.cpp

#include"Ironman.h"

Ironman::Ironman() {

}

Ironman::Ironman(sf::Texture& imgPath, int wWidth, int wHeight) {
  _Sprite.setTexture(imgPath);
  _Sprite.setPosition(sf::Vector2f(wWidth / 2.0, wHeight / 2.0));
  _Sprite.setOrigin(imgPath.getSize().x / 2.0, imgPath.getSize().y / 2.0);
  _Sprite.setScale(0.1, 0.1);
}

Ironman::~Ironman() {

}

void Ironman::draw(sf::RenderTarget& target, sf::RenderStates states)const {
  target.draw(_Sprite, states);
}

При необходимости я могу добавить заголовочные файлы:)

1 Ответ

0 голосов
/ 27 мая 2018

Не видя ваших заголовков ...

Я предполагаю, что вы ожидаете вызова производных функций-членов класса с полиморфизмом (ключевое слово virtual)?virtual вызовы функций полиморфны только при вызове через указатель или ссылку на базовый класс.Хранение объектов производного класса по базовому классу значение срезы объекта, так что это фактически объект базового класса в этом контексте.

Вы храните свое телочасти в std::vector<Body>.Когда вы push_back a Body объект, это работает.Когда вы push_back a IronMan объект, только часть Body этого объекта когда-либо сохраняется в векторе.Вы, вероятно, хотите std::vector<std::unique_ptr<Base>>, предполагая, что C ++ 11 или новее.Или, как минимум, вы хотите std::vector<Base *>, но затем вы должны выполнить управление временем жизни вручную.

...