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

Author Topic: Check to show sprite function  (Read 6594 times)

0 Members and 2 Guests are viewing this topic.

Canvas

  • Full Member
  • ***
  • Posts: 107
    • View Profile
Check to show sprite function
« on: July 07, 2012, 06:29:39 pm »
Hey guys,
Its ok i found the solution myself, Now the probelm i am having is my fps is only 30 maybe 27, is that ok? i have 500 16 by 16 blocks every row and i have 300 columns, to create a 2D level. i have code to stop they showing their sprite if they are not on the screen
« Last Edit: July 07, 2012, 06:48:56 pm by Canvas »

mastodona7x

  • Newbie
  • *
  • Posts: 21
    • View Profile
Re: Check to show sprite function
« Reply #1 on: July 07, 2012, 06:49:49 pm »
Hey you should post the code for us fellow noobies :) Did you use the "window view" part of sfml as I was browsing over that last night and was going to suggest it?

Canvas

  • Full Member
  • ***
  • Posts: 107
    • View Profile
Re: Check to show sprite function
« Reply #2 on: July 07, 2012, 06:57:54 pm »
K this is my maths cpp
public:
        bool pointInRect(int pnt_x, int pnt_y, int rect_x, int rect_y, int rect_w, int rect_h)
        {
        if ( (pnt_x >= rect_x) && (pnt_x <= rect_x + rect_w - 1) )
        {
                if ( (pnt_y >= rect_y) && (pnt_y <= rect_y + rect_h - 1) )
                {return true;}
        }
        return false;
        }
 

this is my collision detection between the screen and the blocks, but now and then im running at 60 then it will drop to 30, then after some seconds it will jump back up

for(int i=0;i<blocks.size();i++)
                {
                        if(math.pointInRect(blocks.at(i).pos.x,blocks.at(i).pos.y,player.pos.x-600,player.pos.y-500,1024,768))
                        {
                                blocks.at(i).show = true;
                        }
                        else
                        {
                                blocks.at(i).show = false;
                        }
                }
 
blocks is a vector of gBlocks, which is a class in my game

mastodona7x

  • Newbie
  • *
  • Posts: 21
    • View Profile
Re: Check to show sprite function
« Reply #3 on: July 07, 2012, 07:27:11 pm »
Clever stuff! As a noobie can I ask when you use blocks.at(i) instead of
Code: [Select]
blocks[i] which is what I was using with vectors?  :)
« Last Edit: July 07, 2012, 08:20:34 pm by mastodona7x »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11033
    • View Profile
    • development blog
    • Email
Re: Check to show sprite function
« Reply #4 on: July 07, 2012, 07:30:12 pm »
Hey guys,
Its ok i found the solution myself, Now the probelm i am having is my fps is only 30 maybe 27, is that ok? i have 500 16 by 16 blocks every row and i have 300 columns, to create a 2D level. i have code to stop they showing their sprite if they are not on the screen

Did you edit away your initial questions? Because now your whole text doesn't make any sense... ??? (Don't do that!)

500*300 Sprites = 150000, that's quite a hugh number for sprites. If you're trying to do something like a tilemap, you should defently rethink your desing and use sf::RenderTexture or better sf::VertexArray.
Also if performance gets a problem with the vertex array than you should use an octtree so you won't have to check every 150000 tiles.

Clever stuff! As a noobie can I ask when you use blocks.at(i) instead of blocks which is what I was using with vectors?  :)
vector.at checks if the dimensions isn't out of bound. vector[] doesn't do that and you could still accidently try to access wrong data.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Canvas

  • Full Member
  • ***
  • Posts: 107
    • View Profile
Re: Check to show sprite function
« Reply #5 on: July 07, 2012, 07:57:19 pm »
Ok i do apologize, well at the moment, i have a for loop to fill in my vector of blocks with just template blocks
for(int i=0;i<75;i++){
                        //Row
                        for(int j=0;j<150;j++){
                                blockTemp.setup((32*j),(32*i),32,32,1); blocks.push_back(blockTemp);
                        }
                }
 

like so, now i have decreased them as anything higher is abit high, so now it works quite fine. but im still having a small problem with textures

Now i have a tileset.gif which has all the tiles i need for a basic level.
now im trying to code it so if a mouse button is pressed while in contact with a block it will change the sprite of that block. this is the code so far

if(iEvent.type == sf::Event::MouseButtonPressed == true)
                {
                        for(int i=0;i<blocks.size();i++)
                        {
                                sf::Vector2f mouseViewPos = screen.convertCoords(sf::Mouse::getPosition(screen));
                                sf::Vector2i blockPos;
                                blockPos.x = blocks.at(i).pos.x; blockPos.y = blocks.at(i).pos.y;
                                sf::Vector2f blockViewPos = screen.convertCoords(blockPos);
                                if(math.pointInRect(mouseViewPos.x,mouseViewPos.y,int(blockViewPos.x),int(blockViewPos.y),blocks.at(i).pos.w,blocks.at(i).pos.h) == true && blocks.at(i).rtnShow() == true)
                                {
                                        blocks.at(i).setBlockId(2);
                                }
                        }
                }
 

but converting the coords doesn't give me the correct position and also the program lags abit when texturing blocks. I also have a camera class that moves around the map, should i add its X and Y pos to the mouseViewPos.x and y? it seems I can only click on the blocks in the rectangle of 0,0,1024,768
« Last Edit: July 07, 2012, 08:14:49 pm by Canvas »

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: Check to show sprite function
« Reply #6 on: July 07, 2012, 08:06:06 pm »
vector.at checks if the dimensions isn't out of bound. vector[] doesn't do that and you could still accidently try to access wrong data.
Meaningful implementations of vector::operator[] also check the bounds in debug mode and stop with a failed assertion in case of invalid indices. This enforces you to fix such bugs instantly.

vector::at() however throws an exception, which tempts people to catch and handle it, although index-out-of-bounds is a logic error that doesn't occur in a correctly written program. Additionally, at() incurs a performance overhead in release mode (even if it's tiny, it's useless).
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11033
    • View Profile
    • development blog
    • Email
Re: Check to show sprite function
« Reply #7 on: July 07, 2012, 08:11:31 pm »
Meaningful implementations of vector::operator[] also check the bounds in debug mode and stop with a failed assertion in case of invalid indices. This enforces you to fix such bugs instantly.

vector::at() however throws an exception, which tempts people to catch and handle it, although index-out-of-bounds is a logic error that doesn't occur in a correctly written program. Additionally, at() incurs a performance overhead in release mode (even if it's tiny, it's useless).
I never thought about it that way... This breaks all my thinking about how vector::at() is better than vector::operator[]... ;D
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Canvas

  • Full Member
  • ***
  • Posts: 107
    • View Profile
Re: Check to show sprite function
« Reply #8 on: July 07, 2012, 08:54:20 pm »
Any help with my question?

Haze

  • Full Member
  • ***
  • Posts: 201
    • View Profile
    • Github Profile
Re: Check to show sprite function
« Reply #9 on: July 07, 2012, 10:41:40 pm »
500*300 Sprites = 150000, that's quite a hugh number for sprites. If you're trying to do something like a tilemap, you should defently rethink your desing and use sf::RenderTexture or better sf::VertexArray.
Also if performance gets a problem with the vertex array than you should use an octtree so you won't have to check every 150000 tiles.
With a VertexArray storing 4 vertices per tile, that would represent 150000 x 4 = 600000 vertices, how come rendering so many vertices could be faster that rendering a single render texture?
I've already wondered this while reading the source code of st::Text (as it also uses a vertex array rather than an intermediate texture), and I don't understand why.

Quote from: Canvas
now im trying to code it so if a mouse button is pressed while in contact with a block it will change the sprite of that block. this is the code so far
You don't need to loop over all your tiles to find the one under the mouse cursor.
You can get the tile index by dividing the mouse position by the tile dimensions.
Here's a schema:


mastodona7x

  • Newbie
  • *
  • Posts: 21
    • View Profile
Re: Check to show sprite function
« Reply #10 on: July 08, 2012, 01:00:43 am »
In the example above why isn't it [4][3] instead of [3][4]?

Haze

  • Full Member
  • ***
  • Posts: 201
    • View Profile
    • Github Profile
Re: Check to show sprite function
« Reply #11 on: July 08, 2012, 01:39:13 am »
In the example above why isn't it [4][3] instead of [3][4]?
When dealing with 2-dimensions array, I've always stored the rows in the first dimension, and the columns in the second dimension, I think it's a common convention to do the following:
int array[NB_LINES][NB_COLUMNS]

So if you loop over the array and you generate positions (x, y) from array indexes, you will get the y-axis in the first loop, and the x-axis in the second nested loop.
for (int i = 0; i < NB_LINES; ++i)
{
    float y = i * tile_height;
    for (int j = 0; j < NB_COLUMNS; ++j)
    {
        float x = j * tile_width;
    }
}

Maybe some people store the columns in the first dimension, it's up to you really...

Canvas

  • Full Member
  • ***
  • Posts: 107
    • View Profile
Re: Check to show sprite function
« Reply #12 on: July 08, 2012, 01:43:00 am »
500*300 Sprites = 150000, that's quite a hugh number for sprites. If you're trying to do something like a tilemap, you should defently rethink your desing and use sf::RenderTexture or better sf::VertexArray.
Also if performance gets a problem with the vertex array than you should use an octtree so you won't have to check every 150000 tiles.
With a VertexArray storing 4 vertices per tile, that would represent 150000 x 4 = 600000 vertices, how come rendering so many vertices could be faster that rendering a single render texture?
I've already wondered this while reading the source code of st::Text (as it also uses a vertex array rather than an intermediate texture), and I don't understand why.

Quote from: Canvas
now im trying to code it so if a mouse button is pressed while in contact with a block it will change the sprite of that block. this is the code so far
You don't need to loop over all your tiles to find the one under the mouse cursor.
You can get the tile index by dividing the mouse position by the tile dimensions.
Here's a schema:


Ok Haze that makes sense, but my problem is still this, how in SFML can you get the correct mouse.X and mouse.Y, if i get it to do this
sf::Vector2i v2 = sf::Mouse::getPosition();
 
what it actually does, is just gets the position of the mouse on the window, not in the actually game per say, so if i go to the button left i get this cord for the mouse
X:1476
Y:949
if i then move the camera 1000px to the right and click again, i get the same X:1476
how can i get my mouse to take in the position of the screen also?

Haze

  • Full Member
  • ***
  • Posts: 201
    • View Profile
    • Github Profile
Re: Check to show sprite function
« Reply #13 on: July 08, 2012, 01:49:11 am »
if i then move the camera 1000px to the right and click again, i get the same X:1476
how can i get my mouse to take in the position of the screen also?

You need to pass the sfml window as a parameter to get the relative mouse position:
sf::Vector2i pos = sf::Mouse::getPosition(render_window);

read the sf::Mouse documentation

Canvas

  • Full Member
  • ***
  • Posts: 107
    • View Profile
Re: Check to show sprite function
« Reply #14 on: July 08, 2012, 01:55:56 am »
ok i have just tried this
sf::Vector2i pos = sf::Mouse::getPosition(screen);
 

I print this out
std::cout << "X:" << v2.x << ".Y:" << v2.y << std::endl;
and i can get to a total of
X : 1024
Y : 768
now my game is about 4000 by 2000, all I want to try and do is get the mouse coordinates not from the window itself but from its actually position in the game world, so if i moved right by 1000, the
 mouses position would be 2024. how can I achieve that?

its ok i have fixed it and it now works 100% cheers for all the help, i will post some code to help anyone else that needs it

each of my tiles is 32 by 32, and i have 75 columns and 150 rows.

my program window is 1024 by 768. I then create this tiny for loop to check where the mouse is and what to do
for(int i=0;i<blocks.size();i++)
                        {
                                int rowNum = (pos.x+player.pos.x-(496)) / 32;
                                int colNum = (pos.y+player.pos.y-(384)) / 32;
                                blocks.at((colNum*150)+rowNum).setBlockId(2);
                        }
 
the player.pos just replace the player with camera, my "camera" is always in the center, so we take away 496 (my camera has a width??? :D ) and then 768/2 = 384, now the pos.x is this piece of code which is before the for loop
sf::Vector2i pos = sf::Mouse::getPosition(screen);
 
screen is my renderWindow.

now i then divide them by 32 as that is the width and height, if you have different width and height then just change the values. once done, we go through our vector and find which block we want to change and DING, done :) this code will throw a error if it isnt touching a block but that can be easily fixed. hopefully this helps others.
« Last Edit: July 08, 2012, 02:14:40 am by Canvas »