Welcome, Guest. Please login or register. Did you miss your activation email?

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Topics - N_K

Pages: [1]
1
General / Grid-based sprite movement
« on: November 07, 2012, 04:56:35 pm »
Hello all,

Well, I think it's not specifically related to SFML, but I'm sure that some other beginners might run into this problem as well, so at least it's not completely off-topic...

Since my game world is constructed from square tiles, I want all the actor sprites to move tile by tile, not pixel by pixel. Well, just moving them by jumping from one tile to another is easy, but I don't know how to translate them smoothly, just like in basically all 2D RPGs. So even if a movement key is pressed and released immediately, the sprite would smoothly "walk" to the next tile, not just move by a few pixels and stop immediately when the key has been released.

Does anybody know a tutorial about this, or have some code to share? The only tutorial I've found was implemented in XNA, and didn't even work on my machine... Thank you in advance!

2
Graphics / Drawing things on viewport
« on: September 18, 2012, 06:28:54 am »
Hi all,

Is there a way to draw text/sprites onto an sf::View? I use the view as a camera, instead of scrolling the game map, I move the viewport. But when I try to display some text, it will be drawn on the map, not on the viewport, and it will go out of sight when I move the camera. Or do I have to transform the text element(s) at the same speed and in the same direction as the viewport itself?

3
General / Animated tiles
« on: September 16, 2012, 03:23:49 am »
Hi all,

I almost finished implementing a basic tile engine, utilizing vertex arrays (thanks again to all the people who taught me how to handle them in an earlier topic). Now I'm at the point were I have to figure out how to render animated tiles.

So far, I have two ways in my mind. The first one is to exclude the animated tiles from the vertex array during map loading, and render them as sprites. In this way, they could be animated just like any other sprites, setting the texture rect according to the playback speed. However, I'm a bit worried that this method could become slow when rendering many animated tiles at once (when displaying large water surfaces, for example), since as far as I know, SFML doesn't do any kind of batch processing for sprites.

My other idea is to place all the animated tiles (of the same tile) on a separate layer, then manipulate the vertex array texture coordinates to do the animation. Since there would be no other tiles on these layers, it would be fast enough (I guess).

In your opinion, which way would be better/safer/faster? I haven't really played with the vertex array texture coordinates yet, but it doesn't seems to be more difficult to manipulate them than manipulating a texture rect. Is it safe to manipulate them dynamically?

4
Window / Strange window behavior under Linux
« on: September 15, 2012, 02:55:42 am »
Hi all,

I was testing SFML2 under Linux (Ubuntu 12.04.1 64-bit) in VirtualBox, and I noticed something strange.

The test app was nothing specific, it was the code from the documentation. But when I moved the window, I noticed that the content of the window remains at the place where the window originally was (and kept on updating), while the window itself displayed a part of the desktop background. When I released the mouse button and dropped the window, everything was fine again.

Another thing I noticed is that while the app was running, and I opened an other window (or restored a minimized one), the content of the SFML window (just the content, not the window frame/titlebar) was always on top, blocking the view of the other, supposedly overlapping window(s).

Is this happened because of the virtual machine? The few other OpenGL apps I've tested ran fine, both in fullscreen and windowed mode.

EDIT: According to a few posts on the VirtualBox forum, similar behaviour has been observed under older versions of VirtualBox, but it has been supposedly fixed about a year ago. But since the problem they've described is extremely similiar to this one (although they didn't mention the window drag glitch), it would be the best if someone could test this on a real system. Or, if nobody does, I'm planning to replace win7 with Ubuntu 12.04 next week, so I'll check it out.

5
General / Empty texture for vertex array quads
« on: September 12, 2012, 05:00:59 pm »
Hello all,

Another noob problem here. The vertex array based tile system uses this method to define texture coorinates for each tile:
map[current + 0].texCoords = sf::Vector2f((tx + 0) * size, (ty + 0) * size);
map[current + 1].texCoords = sf::Vector2f((tx + 0) * size, (ty + 1) * size);
map[current + 2].texCoords = sf::Vector2f((tx + 1) * size, (ty + 1) * size);
map[current + 3].texCoords = sf::Vector2f((tx + 1) * size, (ty + 0) * size);

(int tx and int ty are the x and y coordinates of the desired part of the texture, int size is the size of the tile).

The vertex array itself is defined like this:
sf::VertexArray map(sf::Quads, layer_width * layer_height * 4);

Now the problem with this is that I can't define an empty texture. If both tx and ty are 0, the first image of the tileset will be drawn. When I modified the texture coordinate routine to this:
map[current + 0].texCoords = sf::Vector2f(0, 0);
map[current + 1].texCoords = sf::Vector2f(0, 0);
map[current + 2].texCoords = sf::Vector2f(0, 0);
map[current + 3].texCoords = sf::Vector2f(0, 0);
the empty tiles were filled with the first pixel of the tileset image, resulting in a solid color.

How can I set up the texture coordinates to render the tile untextured/completely transparent/invisible?

EDIT: Forgot to mention that when the tile map is loaded from a tile, and the app starts processing the tile IDs, the normal coordinate setup routine is used (the first code snippet) if the tile ID is larger than zero, and if it's zero or less, the empty coordinate routine should be used to texture the current tile.

6
General / Smooth scrolling large textures
« on: September 06, 2012, 12:33:09 am »
Hello all,

I'm experimenting with tile-based maps. I created a 800 x 800 RenderTexture, then rendered the tiles to this instead to the screen. Then created a sprite from this RenderTexture, and I'm trying to move it to scroll the map. But no matter what kind of method I try, the movement will be choppy.

Here's the code:
int main()
{
        sf::RenderWindow window(sf::VideoMode(640, 480, 32), "SFML window", sf::Style::Close);
        window.setFramerateLimit(60);

        sf::Clock clock;
        float deltaTime = 0;
        const int scrollSpeed = 150;

        sf::RenderTexture layer1;
        if(!layer1.create(800, 800)) { return EXIT_FAILURE; }

        sf::Sprite layer1sprite;
        layer1sprite.setTexture(layer1.getTexture());

        sf::Texture beach01;
        beach01.loadFromFile("C:/sfml_app/Data/Tiles/Beach01.png");

        Tileset beach1(beach01, 32, 32);

        while(window.isOpen())
        {
                sf::Event event;

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

                layer1.clear();
                beach1.setTile(20);
                beach1.setPosition(64, 64);
                layer1.draw(beach1);
                layer1.display();

                if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) { layer1sprite.move(0.f, -scrollSpeed * deltaTime); }
                else if(sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) { layer1sprite.move(0.f, scrollSpeed * deltaTime); }
                else if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) { layer1sprite.move(-scrollSpeed * deltaTime, 0.f); }
                else if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) { layer1sprite.move(scrollSpeed * deltaTime, 0.f); }

                deltaTime = clock.restart().asSeconds();

                window.clear();
                window.draw(layer1sprite);
                window.display();
        }

        return 0;
}

If I disable the framerate limiter, the movement will be a bit smoother, but still choppy (plus 60 FPS is quite reasonable, nearly all commercial games are locked at this rate, so this shouldn't be the problem).

What should I do to make it smooth? (Interestingly enough, the same method works fine for small sprites, I don't know what's wrong with larger ones.)

7
Graphics / sf::Rect questions
« on: August 30, 2012, 02:30:06 pm »
Hello all. Sorry for spamming the forum with beginner questions lately, this one will be the last for a while, I promise.

I'm experimenting with a tile engine. I have two different methods to set a specific tile, one uses arrays, one uses vectors.

First, here's the one with arrays:
void Tileset::setTile(int tileNum)
{
        tileRect = new sf::IntRect[numTiles];

        int counter = 0;

        for(int texture_h = 0; texture_h < numTilesY; texture_h++)
        {
                for(int texture_w = 0; texture_w < numTilesX; texture_w++)
                {
                        if(counter < numTiles)
                        {
                                tileRect[counter].left = texture_w * tileWidth;
                                tileRect[counter].top = texture_h * tileHeight;
                                tileRect[counter].width = tileWidth;
                                tileRect[counter].height = tileHeight;

                                counter++;
                        }
                }
        }

        this->setTextureRect(tileRect[tileNum]);

        delete tileRect;
}

In the header, tileRect is defined like this:
sf::IntRect *tileRect;


Now, here is the one that uses vectors:
void Tileset::setTile(int tileNum)
{
        for(int h = 0; h < numTilesY; h++)
        {
                for(int w = 0; w < numTilesX; w++)
                {
                        rect.left = w * tileWidth;
                        rect.top = h * tileHeight;
                        rect.width = tileWidth;
                        rect.height = tileHeight;

                        subRect.push_back(rect);
                }
        }

        this->setTextureRect(subRect[tileNum]);

        subRect.clear();
}

In the header, rect and subRect are defined like this:
std::vector <sf::Rect<int>> subRect;
sf::Rect <int> rect;

Both of these are working fine, and this is what I don't understand. In both methods, I have to destroy the temporary rectangles (tileRect and subRect) after they have been assigned to the texture, othervise they will produce memory leaks (the vector-based one is quite dangerous, it keeps allocating more and more memory until the app is closed).

But how can SFML display the area defined by the rectangle, if the rectangle doesn't even exist any more? Once a set of coordinates are assigned to the setTextureRect function, it will store them until they have been overwritten by another set, or the app is closed? Is this code the way it supposed to be done, anyway, or just plain broken and dangerous?

Thanks for your help in advance.

8
General / Latest SFML snapshot memory usage
« on: August 29, 2012, 11:26:18 pm »
Hi all,

Just out of curiosity: is it normal for SFML to use 40 megabytes of RAM, even when it does nothing (well, it does, it displays an empty, black window, and waits for the user to close the window)?

Interestingly, no matter how many objects I draw (so far, I've only tried text and sprites, but many of them), it never goes beyond 42, so my guess would be that SFML pre-allocates some space to avoid problems later. Is this correct?

If it is, what happens if I run an SFML app on a system with only 64 (or even 32) megabytes of RAM? Before the pre-allocation, does it takes the avaliable memory into consideration?

9
General / Clock controlled loop, delayed text output
« on: August 27, 2012, 04:47:58 am »
Hi all,

I've been trying to display a string character by character, with a short delay between each characters. So far, I set up an array to contain the string, and defined an sf::Text constructor:
char testString[] = "This is a message.";
sf::Text text;

Then, in the main loop, I assign "testString" to "text", and draw it character by character like this:
for(int i = 0; i < sizeof(testString); i++)
{
        text.setString(testString[i]);
        text.setPosition((float)i * 10, 0);
        window.draw(text);
}

It works, however, as mentioned earlier, I'd like to have some delay between the characters. My first idea was to control the loop with a clock. I set up a clock, then replaced "i++" (sorry, I have no idea how this part of the loop initializer is called in english...) with "i += clock.restart().asSeconds()". Of course, it failed miserably, so it did with "clock.restart().asMilliseconds()".

So, what should be the correct way to achieve this? I've seen many videos of various SFML apps doing delayed thext output, but neither of these had public source access, so I couldn't look at their code.

10
General / Problems with animation sample code
« on: August 12, 2012, 10:00:45 pm »
Hello all!

After a long hiatus, I decided to continue with SFML, and since I needed a simple animation system, I decided to use this one from the wiki. I made some minor modifications to get it to work with SFML2, but I don't think that this is the problem.

My first test animation was a picture consisting of 20 frames, each frame is of size 192 x 192. It worked great.

Then, I tried to animate a player sprite from RPG Maker VX. The sprite sheet consist of 12 sprites, each frame is of size 32 x 32. This one doesn't seems to work as it supposed to.

First, I tried to animate this part only (the first 3 frames of the sheet, so I set 0 as the starting frame and 2 as the end frame).



Normally, it should go in this order from left to righ (0-1-2). But for some reason, it plays in 0-2-1 order. No matter what I set the start/stop frames to, the animation order will be messed up.

The other problem is, when I don't specify the start and the end frame, and just let the system play the whole sheet, it will somehow add an extra frame, consisting of a 3-pixels wide, and 32 pixels tall vertical bar. This happens when the final frame has been reached, and before the system loops back to the first frame.

Again, neither of these problems happen with larger images (for example, with the one that consist of 192 x 192 frames). But I have no idea why is this happening.

Even if my code is largely the same as in the wiki, I post it here, since I could have been made a mistake.

Here's Animation.h:
#ifndef ANIMATION_H
#define ANIMATION_H

#include <SFML\Graphics.hpp>

class AnimSprite : public sf::Sprite
{
public:
        AnimSprite();
        AnimSprite(const sf::Texture &img, int frameWidth, int frameHeight);
       
        ~AnimSprite();

        sf::IntRect AnimSprite::getFramePosition(int frame);

        int getFrameCount();

        void setFrameSize(int frameW, int frameH);
        void setFrame(int frame);
        void setLoopSpeed(float newfps);

        void play();
        void play(int start, int end);
        void stop();
        void update();

private:
        sf::Clock animClock;

        float fps;

        bool isPlaying;

        int loopStart;
        int loopEnd;
        int currentFrame;
        int frameWidth;
        int frameHeight;
};

#endif

And here's Animation.cpp:
#include "Animation.h"

AnimSprite::AnimSprite(void) : sf::Sprite()
{
        this->fps = 1;
        this->currentFrame = 0;
        this->loopStart = 0;
        this->isPlaying = false;
        this->setFrameSize(0, 0);
}

AnimSprite::AnimSprite(const sf::Texture &img, int frameWidth, int frameHeight) : sf::Sprite(img)
{
        this->fps = 1;
        this->currentFrame = 0;
        this->loopStart = 0;
        this->isPlaying = false;
        this->setFrameSize(frameWidth, frameHeight);
}

AnimSprite::~AnimSprite() {     }

int AnimSprite::getFrameCount()
{
        unsigned int horizontal = (this->getTexture()->getSize().x / this->frameWidth);
        unsigned int vertical = (this->getTexture()->getSize().y / this->frameHeight);

        return horizontal * vertical;
}

sf::IntRect AnimSprite::getFramePosition(int frame)
{
        unsigned int horizontal = (this->getTexture()->getSize().x / this->frameWidth);
        unsigned int vertical = (this->getTexture()->getSize().y / this->frameHeight);

        int tileY = frame / horizontal;
        int tileX = frame % horizontal;

        sf::IntRect result(
                tileX * this->frameWidth,
                tileY * this->frameHeight,
                this->frameWidth,
                this->frameHeight);

        return result;
}

void AnimSprite::setFrameSize(int frameW, int frameH)
{
        this->frameWidth = frameW;
        this->frameHeight = frameH;
        this->setTextureRect(sf::IntRect(0, 0, frameW, frameH));
}

void AnimSprite::setFrame(int frame) { this->currentFrame = frame; }

void AnimSprite::setLoopSpeed(float newfps) { this->fps = newfps; }

void AnimSprite::play() { this->play(0, getFrameCount()); }

void AnimSprite::play(int start, int end)
{
        loopStart = start;
        loopEnd = end;
        currentFrame = start;

        isPlaying = true;

        animClock.restart();
}

void AnimSprite::stop() { isPlaying = false; }

void AnimSprite::update()
{
        if(isPlaying)
        {
                int frameCount = (loopEnd + 1) - loopStart;
                float timePosition = (animClock.getElapsedTime().asSeconds() * fps);

                currentFrame = loopStart + (int)timePosition % frameCount;

                this->setTextureRect(getFramePosition(currentFrame));
        }
}

Anybody knows what's going on here? Your help would be greatly appreciated. (I believe it's a trivial problem, but I fail to locate it... :S)

EDIT: Okay, I realized it's a bit hard to understand what the problem is, so here's a compiled binary with the full source code.

11
General / Correct way to do player movement
« on: April 18, 2012, 11:51:19 pm »
Hello all,

First of all, sorry if it doesn't belong here.

Since I'm a beginner in C++, I'm a bit confused about what is the correct way to do player movement. Some tutorials insist that I should use a switch/case statement. However, when I started to implement smooth player movement, I based it on the code of the Pong example that comes with SFML. So, at the moment, my sprite movement code looks like this:

Code: [Select]
float deltaTime = clock.restart().asSeconds();

if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
{
sprite.move(0.f, -playerSpeed * deltaTime);
}

if(sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
{
sprite.move(0.f, playerSpeed * deltaTime);
}

if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
{
sprite.move(-playerSpeed * deltaTime, 0.f);
}

if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
{
sprite.move(playerSpeed * deltaTime, 0.f);
}

It works like a charm (in fact, I've tried many, many smooth movement tutorials, and failed with most of them), but I have a strange feeling that it not supposed to be done this way in a larger, state machine driven game, and only meant for a simple example, like the Pong game. Can I just leave it this way, and go on implementing the rest, or should I redo this with a switch statement?

Your help would be greatly appreciated.

12
General / Disabling font smoothing/anti-aliasing
« on: March 16, 2012, 11:19:01 pm »
Hello all.

I would like to disable font smoothing in my app, since the font I'm using looks extremely ugly (and completely unreadeble below size 12) right now.

I did a search, and the only useful thread I found was this.

This code snippet was posted in there:
Code: [Select]
Font* f = MyCustomLoadFontMethod();
((Image&)f->GetImage(30U)).SetSmooth(false);


However, it looks like only a reference code to me, and since I'm not that experienced, I simply have no idea what to do with it.

Could somebody post a sample implementation, please?
Thank you.

13
General / SFML app does nothing
« on: March 14, 2012, 11:33:29 pm »
Hello all.

Today I decided to go ahead and familiarize myself with SFML. So I set it up, and started with the "Opening a window" tutorial. It compiled fine (of course), but when I started the executable, all I got was the wait cursor for about 5 seconds, then nothing. I opened the task manager, and the application was apparently running in the background, but did nothing.

Then I compiled another tutorial ("Using render windows"), and it did exactly the same thing.

I'm on Win7 (64-bit), and my compiler is Visual Studio 2010 Express. Could anybody help me out with this, please?

Also, here is the code I used:
Code: [Select]
#include <SFML/System.hpp>
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>

int main(void)
{
sf::RenderWindow App(sf::VideoMode(800, 600, 32), "Test");

while (App.IsOpened())
{
sf::Event Event;

while (App.GetEvent(Event))
{
if (Event.Type == sf::Event::Closed)
{
App.Close();
}
}

App.Clear();
App.Display();
}

return EXIT_SUCCESS;
}


Thank you in advance.

Pages: [1]
anything