简体   繁体   English

SFML 精灵根本不显示

[英]SFML Sprites not displaying at all

I have a method which should take a spritesheet which is 64x128 and turn it into 8x8 sprites.我有一个方法,它应该采用 64x128 的 spritesheet 并将其转换为 8x8 的 sprite。

after each texture is found from the stored Image, it is added to a sprite, and that sprite is added to a sprite array which is being called in my main method.从存储的图像中找到每个纹理后,将其添加到精灵中,并将该精灵添加到在我的主要方法中调用的精灵数组中。

I have tested displaying a static sprite before, and my code worked (I displayed 1 8x8 sprite successfully)我之前测试过显示静态精灵,并且我的代码有效(我成功显示了 1 个 8x8 精灵)

However, when trying to display any of the 128 sprites in my list of sprites, now none are being rendered.但是,当尝试显示我的精灵列表中的 128 个精灵中的任何一个时,现在都没有渲染。

I believe the logic error may be in my MakeSprite method, but I'm unsure, and I can't see where the issue is.我相信逻辑错误可能出在我的 MakeSprite 方法中,但我不确定,我看不出问题出在哪里。

[EDIT]: it seems that every sprite I call is returning the sprite at the very end of the spritesheet (sprite 128) [编辑]:似乎我调用的每个精灵都在精灵表的最后返回精灵(精灵 128)

[Edit 2]: the texture (tex) of the previous sprite is overwritten by the next sprite to be spawned. [编辑 2]:前一个精灵的纹理 (tex) 被下一个要生成的精灵覆盖。

Below is a full verifiable working example of my code:以下是我的代码的完整可验证工作示例:

main.cpp主程序

#include "Main.h"




int main() {

    srand(time(NULL));


    RenderWindow window(VideoMode(1280, 720), "Conduit");


    MakeCircle(10, 100, 100, Color::White);
    MakeCircle(30, 10, 100, Color::Cyan);
    MakeCircle(100, 200, 100, Color::Magenta);
    MakeCircle(100, 400, 100, Color::Cyan);



    if (!LoadSpritesheet())
    {
        return 1;
    }

    while (window.isOpen()) {

        Event event;
        while (window.pollEvent(event)) {

            if (event.type == Event::Closed)
                window.close();
            else if (event.key.code == Keyboard::Num1)
            {

                DrawRandomSprite(window);
            }
        }



        window.clear();
        DrawCircles(window);


        int c = 0;

        for (int i = 0; i < 128; i++)
        {

            Spritesheet.at(i).setPosition(c, c);
            window.draw(Spritesheet.at(i));
            c += 8;
        }





        window.display();
    }

}


void DrawRandomSprite(RenderWindow &window)
{

    //DEBUG METHOD: draws a random sprite for testing.

    int sprite = rand() % 128 + 1;



    Spritesheet.at(sprite).setPosition(rand() % 128 + 1, rand() % 128 + 1);

    window.draw(Spritesheet.at(sprite));



}

void MakeCircle(float radius, float xpos, float ypos, Color color)
{
    //makes a circle then adds it to the circle vector.
    CircleShape shape;
    shape.setRadius(radius);
    shape.setPosition(xpos, ypos);
    shape.setFillColor(color);

    Circles.push_back(shape);
}

void DrawCircles(RenderWindow &window)
{
    //Renders the circles in the circles vector.

    for (int i = 0; i < Circles.size(); i++)
    {
        window.draw(Circles.at(i));
    }
}

int LoadSpritesheet()
{
    //make sure spritesheet exists, then loads it into an image.

    Texture sheet;
    if (!sheet.loadFromFile("Sprites/A.png"))
    {
        return 0;
    }
    else
    {
        sheetIMG = sheet.copyToImage();
        SetMask();
        MakeSprite(8, 4);
        return 1;
    }


}

void SetMask()
{
    //creates a mask.

    sheetIMG.createMaskFromColor(sf::Color(151, 56, 14, 0), 100);


}

void MakeSprite(int dimension, int scale)
{
    //seperates the spritesheet into a list of 8x8 modular sprites.

    int c = 0, r = 0;

    do
    {
        for (int i = 0; i <= (sheetIMG.getSize().x * sheetIMG.getSize().y) / 64; i++)
        {
            if (r == 64)
                break;
            if (!tex.loadFromImage(sheetIMG, IntRect(c, r, dimension, dimension)))
                break;
            else
            {
                Sprite spr;
                spr.setTexture(tex);
                spr.setScale(scale, scale);
                Spritesheet.push_back(spr);
                c += dimension;
                if (c == sheetIMG.getSize().x) { c = 0; r+=8; };
            }
        }
    } while (r < sheetIMG.getSize().y);     
}

Main.h主文件

#pragma once
#include <SFML/Graphics.hpp>
#include <vector>
#include <stdio.h>      /* printf, scanf, puts, NULL */
#include <stdlib.h>     /* srand, rand */
#include <time.h>       /* time */


//standard and SFML namespaces;
using namespace std;
using namespace sf;



//===============================VARIBLES===========================


//the main spritesheet.

Texture tex;

Image sheetIMG;

//array to hold circles.
vector<CircleShape> Circles;

//array to hold sprites.
vector<Sprite> Spritesheet;

//===============================PROTOTYPES=============================



void DrawCircles(RenderWindow &window);
void MakeCircle(float radius, float xpos, float ypos, Color color);
void MakeSprite(int dimension, int scale);
void SetMask();
int LoadSpritesheet();
void DrawRandomSprite(RenderWindow &window);

There's two major issues with your code:您的代码有两个主要问题:

  1. You're using global variables.您正在使用全局变量。 While this might be okay with some libraries, with SFML this is not a good thing at all.虽然这对于某些库来说可能没问题,但对于 SFML,这根本不是一件好事。

  2. You're clear ing the window after calling DrawRandomSprite .调用DrawRandomSprite后,您正在clear窗口。 Therefore your sprite will never show up.因此你的精灵永远不会出现。

All your sprites have the same texture: tex .您所有的精灵都具有相同的纹理: tex And as tex is a single global variable, when your loop finishes, it's set to the last texture.由于tex是一个单一的全局变量,当你的循环结束时,它被设置为最后一个纹理。 So all sprites will draw the last texture.所以所有的精灵都会绘制最后的纹理。 You need to get rid of the globals and have one texture per sprite (or at least one per sprite that you want to have a different texture).您需要摆脱全局变量并为每个精灵设置一个纹理(或者每个精灵至少有一个您想要具有不同纹理的纹理)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM