-
Hello, I want to make a side scroller, and I don't know how to make the map(I mean the grass,dirt and the other things that you stay on), I did this with a map made in photoshop, but it was really big so I decided to do it differently, I heard of "tiles", so I downloaded a spritesheet with the dirt and the others(dimentions, 70x70 per sprite).I made it to only show a sprite from the spritesheet.But I don't know how to make an entire map out of it,how to multiply the sprites?
-
You can use a vertex array of quads that define a tile each.
You write some simple file how the level should look like, then you load the file and fill the vertex array with quads that point to the correct tile on your spritesheet texture.
-
Remember that there is an example of how to create a simple tile map (https://www.sfml-dev.org/tutorials/2.4/graphics-vertex-array.php#example-tile-map) in the official SFML tutorials.
-
Can you please explain me how the vertex array positions(and the texture positions) work ? I mean what dimensions to write in the parentheses ?
-
This guide (https://www.sfml-dev.org/tutorials/2.4/graphics-vertex-array.php) will help you.
By the way, if you have questions, please open it in "Help" forum subsection. This section is made for showing off projects you're working on.
-
Ok somehow I did it, but the "map" is blurry, why?
-
I think I found the solution... I expanded 70x70 texture to a 800x70 texture, but how to put 1 by 1(I mean how to put like 11 70x70 squares)?
-
Elias, the example isn't for a spritesheet ?, I have the sprites individually...
-
There are multiple ways to do this, but the easy way is with a 2d array for the map info, and a "print" function for drawing.
Posido code:
//Array
int mapArray[4][5] =
{
{0,0,0,0,0},
{0,1,1,1,0},
{1,2,2,2,1},
{2,2,2,2,2},
};
//Some sprites
SF::sprite airSp....
SF::sprite grassSp....
SF::sprite dirtSp....
//Let's say all sprites are 8 by 8 pixels
Int spriteSize = 8;
//Render it
Window.beginDraw();
for(int i = 0; i < 4; i++){
for(int j = 0; j < 5; j++){
If(mapArray[i][j] == 0) {
airSp.setPosition(i*spriteSize,j*SpriteSize);
Window.draw(airSp);
}
Else If(mapArray[i][j] == 1) {
grassSp.setPosition(i*spriteSize,j*SpriteSize);
Window.draw(grassSp);
}
Else If(mapArray[i][j] == 2) {
dirtSp.setPosition(i*spriteSize,j*SpriteSize);
Window.draw(dirtSp);
}
}
}
Window.display();
Please note, this is posido code, not actual code.
Also, wrote iron my phone, so errors are most likely.... But the algorithm should be sound.
-
Hmm...something is not right the window opens for a second and it closes(Note:The console remains opened)...that's the code....
#include <SFML/Graphics.hpp>
using namespace sf;
int main()
{
RenderWindow window(VideoMode(800,600),"Platformer");
window.setFramerateLimit(60);
window.setVerticalSyncEnabled(1);
View view(FloatRect(0,0,800,600));
Clock clock;
int mapArray[4][5] =
{
{0,0,0,0,0},
{0,0,0,0,0},
{0,0,0,0,0},
{1,1,1,1,1},
};
Texture TTileGrass;
TTileGrass.loadFromFile("Textures/Map/Grass/slice03_03.png");
TTileGrass.setSmooth(1);
Sprite STileGrass;
STileGrass.setTexture(TTileGrass);
Texture TAdventurer;
TAdventurer.loadFromFile("Textures/Characters/Adventurer/adventurer_tilesheet.png");
TAdventurer.setSmooth(1);
Sprite SAdventurer;
SAdventurer.setTexture(TAdventurer);
SAdventurer.setTextureRect(IntRect(0,0,80,110));
SAdventurer.setPosition(0,440);
Vector2f pos = SAdventurer.getPosition();
while(window.isOpen() && !Keyboard::isKeyPressed(Keyboard::Return))
{
clock.restart();
Event event;
while(event.type == Event::Closed)
{
window.close();
}
window.clear();
if(Keyboard::isKeyPressed(Keyboard::Up))
{
pos.y -= 5;
}
if(Keyboard::isKeyPressed(Keyboard::Left))
{
pos.x -= 5;
view.move(-5,0);
}
if(Keyboard::isKeyPressed(Keyboard::Right))
{
pos.x += 5;
view.move(5,0);
}
SAdventurer.setPosition(pos.x,pos.y);
window.setView(view);
window.draw(SAdventurer);
for(int i = 0;i<4;i++)
{
for(int j = 0; j<5;i++)
{
if(mapArray[i][j] == 1)
{
STileGrass.setPosition(i * 70, j * 70);
window.draw(STileGrass);
}
}
}
window.display();
}
}
-
Hmm...something is not right the window opens for a second and it closes
You have to put your logic and drawing code inside a loop. Also, you are polling the events incorrectly. It should be like this:
#include <SFML/Graphics.hpp>
using namespace sf;
int main()
{
// Your variables, like windows, textures and sprites, go outside the loop.
RenderWindow window(VideoMode(800,600),"Platformer");
(...)
// Then you start the game loop.
while( window.isOpen() )
{
// First you poll the events inside ANOTHER loop.
Event event;
while ( window.pollEvent(event) )
{
// The following should be "if", not "while" as you put in your code.
if( event.type == Event::Closed )
{
window.close();
}
}
// Now you do the rest of your code.
if(Keyboard::isKeyPressed(Keyboard::Up))
{
pos.y -= 5;
}
(...)
// Finally you draw.
window.clear( sf::Color::White ) // You have to clear the window first, you forgot about this.
window.setView(view);
window.draw(SAdventurer);
for(int i = 0;i<4;i++)
{
for(int j = 0; j<5;i++)
{
if(mapArray[i][j] == 1)
{
STileGrass.setPosition(i * 70, j * 70);
window.draw(STileGrass);
}
}
window.display();
}
}
I really recommend reading and understanding the tutorials, otherwise you'll run into problems every five minutes, and we won't always be able to help you in time.
-
Ok AFS, I did exactly how you said, but when I start the program it shows me "Platformer.exe has stopped working",why?
PS:I commented the for loop section and it worked, something is wrong with the for loops,but I don't have any idea what...
PSS:The code :
#include <SFML/Graphics.hpp>
using namespace sf;
int main()
{
RenderWindow window(VideoMode(800,600),"Platformer");
window.setFramerateLimit(60);
window.setVerticalSyncEnabled(1);
View view(FloatRect(0,0,800,600));
int mapArray[4][5] =
{
{0,0,0,0,0},
{0,0,0,0,0},
{0,0,0,0,0},
{1,1,1,1,1},
};
Texture TTileGrass;
TTileGrass.loadFromFile("Textures/Map/Grass/slice03_03.png");
TTileGrass.setSmooth(1);
Sprite STileGrass;
STileGrass.setTexture(TTileGrass);
Texture TAdventurer;
TAdventurer.loadFromFile("Textures/Characters/Adventurer/adventurer_tilesheet.png");
TAdventurer.setSmooth(1);
Sprite SAdventurer;
SAdventurer.setTexture(TAdventurer);
SAdventurer.setTextureRect(IntRect(0,0,80,110));
SAdventurer.setPosition(0,440);
Vector2f pos = SAdventurer.getPosition();
while(window.isOpen() && !Keyboard::isKeyPressed(Keyboard::Return))
{
Event event;
while(window.pollEvent(event))
{
if(event.type == Event::Closed)
{
window.close();
}
}
if(Keyboard::isKeyPressed(Keyboard::Up))
{
pos.y -= 5;
}
if(Keyboard::isKeyPressed(Keyboard::Left))
{
pos.x -= 5;
view.move(-5,0);
}
if(Keyboard::isKeyPressed(Keyboard::Right))
{
pos.x += 5;
view.move(5,0);
}
window.clear(Color::White);
SAdventurer.setPosition(pos.x,pos.y);
window.setView(view);
window.draw(SAdventurer);
for(int i = 0;i<4;i++)
{
for(int j = 0; j<5;i++)
{
if(mapArray[i][j] == 1)
{
STileGrass.setPosition(i * 70, j * 70);
window.draw(STileGrass);
}
}
}
window.display();
}
}
-
for(int j = 0; j<5;i++)
The last i should be a j in this one :)
-
Oh, sorry that was the problem thanks! :P You are the best! ;D
-
But...how to change the mapArray to be like 0,530( I mean the map itself), because it is at 0,0
PS:I changed the Map array to : int mapArray[4][5] =
{
{1,0,0,0,0},
{1,0,0,0,0},
{1,0,0,0,0},
{1,0,0,0,0},
};
To show it horrizontally,not vertically, but it is in the left corner up(0,0) and I want it in the left corner down(0,530)
-
To draw in another place you can either set the view:
https://www.sfml-dev.org/tutorials/2.4/graphics-view.php
sf::View view(sf::FloatRect(0, -530, 600, 600));
window.setView(view);
Or draw with an offset:
//Wherever you declare variables//
Int xOffset = 0;
Int yOffset = 530;
//Render part.
STileGrass.setPosition((i * 70)+xOffset ,( j * 70)+yOffset );
window.draw(STileGrass);
If I understand correctly...
Out of curiosity, what is your native language?
Best regards :)
-
I have just one more question...The array is vertically showing, how to put it horizontally ?
I mean to put it like int mapArray[4][5] =
{
{1,0,0,0,0},
{1,0,0,0,0},
{1,0,0,0,0},
{1,0,0,0,0},
};
to int mapArray[4][5] =
{
{0,0,0,0,0},
{0,0,0,0,0},
{0,0,0,0,0},
{1,1,1,1,1},
};
-
Change STileGrass.setPosition(i * 70, j * 70);
To STileGrass.setPosition(i * 70, j * 70);
The setPosition() takes two operators,
X position and Y position. Like this:
setPosition(X,Y);
If X is j then j is horizontal
If Y is i then i is vertical.
Still, what is your language, I'd love to point you to some tutorials....
-
I meant the array to be horizontally looking(because it's easier to look horizontally than vertically) ,not the setposition.
Something like : int mapArray[4][5] =
{
{0,0,0,0,0},
{0,0,0,0,0},
{0,0,0,0,0},
{1,1,1,1,1},
};
-
Ok let the array be like that,but now I have a bigger problem,I tried to make a collision detector and it shows me that only the last piece of "map" collides with the player,how to make the entire "map" collidable ?