首页 > 解决方案 > 将类添加到具有纹理的另一个类的向量中

问题描述

我正在尝试制作基于蛇游戏的游戏。我在 C++ 中获得了 OOP 的基础知识,但我刚刚开始学习 SFML。

我的问题是在我的蛇中有些部分看不到,如下图所示。 在此处输入图像描述

所以“身体”是我的基类。我希望我的蛇的每个部分都由不同的子类制成。这也意味着每个部分都将具有不同的纹理。

现在我已经制作了第一个名为“Ironman”的子类。我在图片上标记的间隙是由该子类制成的部分。蛇的其余部分是“身体”类的部分。

如果我的代码可以在“间隙”中工作,应该会看到一个纹理,就像图片中间(钢铁侠头部)一样。

中间的 Ironman 头部仅用于测试 :) 它显示了 Ironman-part 的外观。

这是我的代码。

主文件

#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;

}

正文.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));
}

钢铁侠.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);
}

如果需要,我可以添加头文件:)

标签: c++sfml

解决方案


没有看到你的标题...

我假设您期望使用多态性(virtual关键字)调用派生类成员函数?virtual函数调用仅在通过指针或对基类的引用调用时才是多态的。通过基类值 存储派生类对象会分对象,因此它实际上是该上下文中的基类对象。

您将身体部位存储在std::vector<Body>. 当你push_back是一个Body对象时,这是有效的。当您push_back创建一个IronMan对象时,只有该对象的Body一部分会存储在向量中。std::vector<std::unique_ptr<Base>>假设 C++11 或更高版本,您可能想要一个. 或者至少,你想要std::vector<Base *>,但你必须手动进行生命周期管理。


推荐阅读