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 - RetroRain

Pages: [1]
1
I've been trying to recreate the game, called Snake, in C++, using the SFML library.

I was programming it my way, with certain code aspects taken from this video:



I was having a lagging problem.  The snake wouldn't move downwards smoothly without lagging.  And I couldn't figure out why.

So I was forced to strip my code down similar to the code in the video.

Even after modifying every line, and testing, I kept getting the lagging.

Even when the code was exactly the same as the one in the video, I kept getting the lagging (I omitted the fruit code and my aesthetics were different, but the code was the same).

After a few hours of testing, I finally traced where the lagging is coming from.

This is what is bizarre.

Why would NOT drawing something, be causing a lag?

If you omit (or comment out) this block of code, or any of the invididual lines here, lagging occurs.  This code is meant to draw the background tiles.

    for (int i=0; i<N; i++)
      for (int j=0; j<M; j++)
        { sprite1.setPosition(i*size, j*size);  window.draw(sprite1); }
 

The source code and folder with images is downloadable at the YouTube video link I posted above.  But you can simply use any 16x16 pixel square to represent the snake (sprite2) and background (sprite1).

Here is the code.  It's actually not that long at all, and the code block above appears right after window.clear().

#include <SFML/Graphics.hpp>
#include <time.h>
using namespace sf;

int N=30,M=20;
int size=16;
int w = size*N;
int h = size*M;

int dir,num=4;

struct Snake
{ int x,y;}  s[100];


void Tick()
 {
    for (int i=num;i>0;--i)
     {s[i].x=s[i-1].x; s[i].y=s[i-1].y;}

    if (dir==0) s[0].y+=1;
    if (dir==1) s[0].x-=1;
    if (dir==2) s[0].x+=1;
    if (dir==3) s[0].y-=1;
 }

int main()
{
    srand(time(0));

    RenderWindow window(VideoMode(w, h), "Snake Game!");

    Texture t1,t2;
    t1.loadFromFile("images/white.png");
    t2.loadFromFile("images/red.png");

    Sprite sprite1(t1);
    Sprite sprite2(t2);

    Clock clock;
    float time = 0;
    float timer=0, delay=0.1;

    while (window.isOpen())
    {
        time = clock.getElapsedTime().asSeconds();
        clock.restart();
        timer+=time;

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

        if (Keyboard::isKeyPressed(Keyboard::Left)) dir=1;
        if (Keyboard::isKeyPressed(Keyboard::Right)) dir=2;
        if (Keyboard::isKeyPressed(Keyboard::Up)) dir=3;
        if (Keyboard::isKeyPressed(Keyboard::Down)) dir=0;

        if (timer>delay) {timer=0; Tick();}

   ////// draw  ///////
    window.clear();

      for (int i=0; i<N; i++)                       //IF YOU COMMENT OUT THIS LINE
         for (int j=0; j<M; j++)                   //OR THIS LINE
           { sprite1.setPosition(i*size, j*size);  window.draw(sprite1); }     //OR THIS LINE, LAGS OCCUR.

    //BUT IF YOU KEEP THIS BLOCK IN, THE LAGS DON'T OCCUR.  THAT DOESN'T MAKE ANY SENSE TO ME.

    for (int i=0;i<num;i++)
        { sprite2.setPosition(s[i].x*size, s[i].y*size);  window.draw(sprite2); }

    window.display();
    }

    return 0;
}
 

I'm simply trying to understand why NOT drawing something, is causing a problem?  But if the code is left in there, there is no problem at all.

In other words, if you decide to not draw the background tiles, a lagging problem will occur with the snake.  The snake will freeze and move irregulary.  But if the background tiles are drawn, the snake moves smoothly and perfectly along.

The only thing that comes to mind, that would even cause a potential problem, is the code that deals with the clock and timing.  But it still doesn't make any sense to me.

By omitting the background tile drawing, this should not impact the movement of the snake in the slightest.

Does anyone know what exactly is going on here?

The only reason I am posting this topic, is because I do find it very bizarre that leaving out a code that is meant to draw something is very weird.  What if I didn't want a background?  NOT drawing something shouldn't be causing a problem.

Thank you for taking the time to look at this.

2
Below is the whole program.  It is a very small and simple program made to test collisions.

You have a player rectangle, and two block rectangles.  If the player collides with either of the blocks, based on the direction he is coming from, his x or y coordinate gets pushed back.

So, the collision works fine in that sense...

However, for instance, if you are moving up and hit a block from the bottom (holding the up key), then press and hold the left key (while still holding the up key), and then let go of the up key, the player gets pushed all the way to the right, past the block.

I know why this is happening, it's obvious.  It is simply executing the collision routine for when you press left.  But I put flags in, such as movingUp, movingDown, etc., to combat this, and yet it still happens.

Also, in the code below, where it checks the key and the direction you're moving in, I even tried checking false for the other three directions, and it still doesn't solve anything.

For instance:
(if (playerRect.getGlobalBounds().intersects(blockRect[i].getGlobalBounds()) && movingUp && !movingDown && !movingLeft && !movingRight)

Feel free to copy and paste this code, and compile it yourself to see what I am talking about.

The collision works, but I don't know what logic I need to stop this collision bug from happening.  You'd think the flags that I have would work, but they're not.


Does anyone know WHY this is happening?

Any help would be greatly appreciated.  Thank you for your time.



#include <SFML/Graphics.hpp>
using namespace sf;

int main()
{
    RectangleShape playerRect;
    RectangleShape blockRect[2];

    float x = 128;
    float y = 120;

    bool movingUp = false;
    bool movingDown = false;
    bool movingLeft = false;
    bool movingRight = false;

    playerRect.setSize(Vector2f(16,16));
    playerRect.setFillColor(Color::Yellow);
    playerRect.setPosition(x,y);

    blockRect[0].setSize(Vector2f(16,16));
    blockRect[0].setFillColor(Color::Blue);
    blockRect[0].setPosition(200,120);

    blockRect[1].setSize(Vector2f(16,16));
    blockRect[1].setFillColor(Color::Blue);
    blockRect[1].setPosition(128,60);

    RenderWindow window(VideoMode(256,240),"");

    while (window.isOpen())
    {
        // Process events
        Event event;
        while (window.pollEvent(event))
        {
            // Close window: exit
            if (event.type == Event::Closed)
                window.close();
        }

        if (Keyboard::isKeyPressed(Keyboard::Up))
        {
            y -= 0.01;
            movingUp = true;
            movingDown = false;
            movingLeft = false;
            movingRight = false;
        }
        else if (Keyboard::isKeyPressed(Keyboard::Down))
        {
            y += 0.01;
            movingUp = false;
            movingDown = true;
            movingLeft = false;
            movingRight = false;
        }
        else if (Keyboard::isKeyPressed(Keyboard::Left))
        {
            x -= 0.01;
            movingUp = false;
            movingDown = false;
            movingLeft = true;
            movingRight = false;
        }
        else if (Keyboard::isKeyPressed(Keyboard::Right))
        {
            x += 0.01;
            movingUp = false;
            movingDown = false;
            movingLeft = false;
            movingRight = true;
        }

        for (int i = 0; i < 2; i++)
        {
            if (playerRect.getGlobalBounds().intersects(blockRect[i].getGlobalBounds()) && movingUp) y = blockRect[i].getPosition().y + 16;
            if (playerRect.getGlobalBounds().intersects(blockRect[i].getGlobalBounds()) && movingDown) y = blockRect[i].getPosition().y - 16;
            if (playerRect.getGlobalBounds().intersects(blockRect[i].getGlobalBounds()) && movingLeft) x = blockRect[i].getPosition().x + 16;
            if (playerRect.getGlobalBounds().intersects(blockRect[i].getGlobalBounds()) && movingRight) x = blockRect[i].getPosition().x - 16;
        }

        playerRect.setPosition(x,y);

        // Clear screen
        window.clear();

        // Draw the sprite
        window.draw(playerRect);
        window.draw(blockRect[0]);
        window.draw(blockRect[1]);

        // Update the window
        window.display();
    }

    return 0;
}

3
The errors I get are:

In constructor 'Player::Player(sf::Sprite&)':
error: no match for call to '(sf::Sprite) ()'



Brief code with certain things that don't matter omitted (like the RenderWindow and other event stuff).


#include <SFML/Graphics.hpp>

using namespace sf;

class Player
{
  private:
        int bbox_top, bbox_bottom, bbox_left, bbox_right;    //collision for all sides of the player sprite
  public:
        Player(Sprite& playerSprite);   // or (const Sprite& playerSprite) not sure if the const is needed
        ~Player();
};

Player::Player(Sprite& playerSprite)
{
    bbox_top = playerSprite().getLocalBounds().y;
    bbox_bottom = playerSprite().getLocalBounds().height;
    bbox_left = playerSprite().getLocalBounds().x;
    bbox_right = playerSprite().getLocalBounds().width;
}

int main()
{
    Texture playerTexture;
    playerTexture.loadFromFile("player.png");
    Sprite playerSprite(playerTexture);

    Player player;
}
 


I'm referencing the sprite, so I don't get why I'm getting these errors.  It doesn't matter if I use const in the Player constructor parameter or not, I still get the error.  I even tried different names in the parameter list, like Sprite& ps.

I know this is more of a C++ question than SFML, but it is related to the sprites.  I don't get why it's not working.

If you know the answer, you're a life saver.  Thank you.

4
The language is C++.

I Googled tons of different results and looked at them, but I can't seem to find a specific answer to what I'm looking for.

I have a Player class, and I want to set his "state", but I want to do it from its public member function, because the state is an enumeration in his private section.  I've tried various different ways, but the compiler keeps giving me errors.  I know how to do it with other values, but when it comes to enumerations, I can't get it to work.  I even tried references, and still no luck.

Here is sample code.  Do you know what I'd have to change to get it work?  Thanks.

#include <iostream>

using namespace std;


class Player
{
   private:
        enum State {IDLE, MOVING};
        State playerState;
   public:
        Player();
        ~Player();
        enum setPlayerState(enum &playerState ps);
        enum getPlayerState();
};

Player::Player()
{
}

Player::~Player()
{
}


enum Player::setPlayerState(enum &playerState ps)
{
   playerState = ps;
}


enum Player::getPlayerState()
{
   return playerState;
}




int main()
{
   Player player;
   player.setPlayerState(MOVING);
   cout << "The player's state is" player.getPlayerState() << "." << endl;
   return 0;
}

I know how to set and get private integer values, but enumerations, I'm having no luck.  I want to be able to type in the parameters player.setPlayerState(IDLE) OR player.setPlayerState(MOVING), but I don't know how to do it from the public member function.

If you know the answer, I just want to say Thank You, and I appreciate your time.

5
I'm trying to use SFML's RenderWindow class from another function, but I keep getting an error, and honestly, I have no clue why I am getting the error.  I'm referencing the "myWindow" variable in the parameter list, and everything has been declared.  I'm getting frustrated.  I've Googled tons of tutorials and articles, and I can't pinpoint why this error is happening.  Here's the code:

#include <SFML/Graphics.hpp>
#include "declarations.h"

int main()
{
    //create the main window
    sf::RenderWindow window(sf::VideoMode(SCREEN_WIDTH, SCREEN_HEIGHT), "Title");

    //start the game loop
    while (window.isOpen())
    {
        //process events
        sf::Event event;
        while (window.pollEvent(event))
        {
            //close window: exit
            if (event.type == sf::Event::Closed) window.close();
        }
        windowHandler(myWindow);  //Right here is where I am getting the error
    }
    return EXIT_SUCCESS;
}

-----------------------------------


#ifndef DECLARATIONS_H_
#define DECLARATIONS_H_

const short SCREEN_WIDTH = 256;
const short SCREEN_HEIGHT = 240;

void windowHandler(sf::RenderWindow& myWindow);

#endif

-----------------------------------


#include <SFML/Graphics.hpp>
#include "declarations.h"

void windowHandler(sf::RenderWindow& myWindow)
{
    //clear screen
    myWindow.clear();

    //draw to screen, will update this later, right now it doesn't draw anything
    //window.draw();

    //update the window
    myWindow.display();
}

The error I get:

In function 'int main()':|
error: 'myWindow' was not declared in this scope|

I don't understand why I am getting this error.  Everything is declared, and myWindow is referenced with an &.  The function prototype is included in the declarations header file, and the header file is included before it even touches main(), which means it should be able to be used anywhere in the program.  So why is it telling me that 'myWindow' is not declared in this scope.  It is!

If you know the answer to the problem, it would greatly be appreciated.  Thank you so much.

Pages: [1]