c++ - 将类添加到具有纹理的另一个类的向量中
问题描述
我正在尝试制作基于蛇游戏的游戏。我在 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);
}
如果需要,我可以添加头文件:)
解决方案
没有看到你的标题...
我假设您期望使用多态性(virtual
关键字)调用派生类成员函数?virtual
函数调用仅在通过指针或对基类的引用调用时才是多态的。通过基类值 存储派生类对象会切分对象,因此它实际上是该上下文中的基类对象。
您将身体部位存储在std::vector<Body>
. 当你push_back
是一个Body
对象时,这是有效的。当您push_back
创建一个IronMan
对象时,只有该对象的Body
一部分会存储在向量中。std::vector<std::unique_ptr<Base>>
假设 C++11 或更高版本,您可能想要一个. 或者至少,你想要std::vector<Base *>
,但你必须手动进行生命周期管理。
推荐阅读
- git - 错误:RPC 失败;curl 55 发送失败:连接被中止
- spectrum - 如果您在 Multism 中没有频谱分析仪怎么办?
- python - 为什么我不能导入 PyTube?
- javascript - 为什么调用一个`setState`函数会更新一个完全独立的状态值?
- python - 在循环中请求新代理导致代理错误并崩溃
- python - 蟒蛇 | JSONPath-ng:过滤器和值提取问题
- wordpress - ACF 自定义字段 WP GraphQL 突然开始在 Gatsby 中返回 null,即使它曾经可以工作
- javascript - 在单个空格上拆分字符串并用单个空格替换三个空格
- flutter - Flutter:如何在一个按钮上添加两条文本行?
- android - Espresso 测试在解组时导致“ClassNotFoundException”(在基本应用程序上重新生成)