C++ SFML tile map last line wrong size problem - c++

I make a game in c++ using SFML library with 2d world made of tiles but when I display it, the last lines are wrong size as you can see:
The size of world is 100x100 tiles. I tried to check last tile width or displaying only first 10x10 tiles but the problem still exist so this is not problem with size of last tiles.
Here you can see:
Here is a class of Tile
class Square{
public:
int x, y, object_type;
sf::RectangleShape rect;
sf::Sprite object;
Square(sf::Color col, int b, int c){
rect = sf::RectangleShape(sf::Vector2f(200, 200));
rect.setFillColor(col);
rect.setOutlineColor(sf::Color(0, 0, 0, 0));
rect.setOutlineThickness(1);
object_type = 0;
x = b;
y = c;
rect.setPosition(790+15*x, 440+15*y);
}
...
}
This is code of filling the world without changing colors of the tiles(it's only cosmetic)
vector<vector<Square>> world;
for(int i=0;i<100;i++){
vector<Square> v;
for(int j=0;j<100;j++){
Square sq(sf::Color(255, 255, 255), j, i);
v.push_back(sq);
}
world.push_back(v);
}
And this is how am I displaying it
window.clear();
for(int i=0;i<world.size();i++) for(int j=0;j<world.at(i).size();j++){
window.draw(world.at(i).at(j).rect);
if(world.at(i).at(j).object_type) window.draw(world.at(i).at(j).object);
}
window.display();

XDDDDDDDD
I cannot belive how terrible idiot I am
rect = sf::RectangleShape(sf::Vector2f(200, 200));
rect.setPosition(790+15*x, 440+15*y);
I just made wrond position details 15 != 200
I will not delete this question even if it's shaming for my programming(and brain-using) skills because someone can has similar problem

Related

Trying to draw rectangles stored in an array, but only one rectangle appears?

My code is here:
As stated above, I'm trying to draw a series of bars across the screen with different x positions and I've stored them in arrays. It seems the code only draws 1 rectangle, even though I've checked and each bar has a different x position so I'm sure its an issue with how I'm drawing the objects but it feels right.
I've also made a similar program with vectors using the same loop for drawing but with .at(i) instead which does work but this oddly does not.
I've been trying to figure this out for a while and I'm tired now so please help, point out my errors... etc...
#include <SFML/Graphics.hpp>
int main()
{
sf::RenderWindow window(sf::VideoMode(640, 640), "Square", sf::Style::Close | sf::Style::Resize);
sf::RectangleShape bar[64] = {sf::RectangleShape(sf::Vector2f( (window.getSize().x)/64.0f ,100.0f))};
// creates 64 bars of equal width
for (int i = 0; i < 64; i++)
{
bar[i].setFillColor(sf::Color(0, 0, 255, 255));
bar[i].setPosition( 10*i , (window.getSize().y)/2);
// sets bars x position to shift over for every bar
}
bar[3].setPosition(600, 300);
// just a test doesn't render even though it should
while (window.isOpen())
{
//////////////////////////////////////////////////
window.clear(sf::Color(130, 130, 150, 255));
for (int i = 0; i < 64; i++)
{
window.draw(bar[i]);
}
window.display();
/////////////////////////////////////////////////
}```
I cut out the rest of the code as the rest works and really has nothing to do with the code for simplicity sake
I want it to render out rectangles across the screen but it only displays one and I can't figure out why?
sf::RectangleShape has default ctor:
sf::RectangleShape::RectangleShape ( const Vector2f & size = Vector2f(0, 0) )
You have defined rectangle's size only for the first one, other 63 have default size (0,0).
You can copy/paste your rect definition in raw array, or use std::vector and call ctor which takes value and number of elements:
std::vector<sf::RectangleShape> bars( 64, // num of elems
sf::RectangleShape( sf::Vector2f(window.getSize().x/64.0f ,100.0f) ) );
Another solution is to call setSize in every iteration of loop (just like with setFillColor, setPosition etc).

Plot a function using SFML

I'm new to SFML. I searched Google to find a way to plot multiple points in SFML from an equation. For example, I want to plot 200 points (x,y) such that y = 2x, in the range (-10 < x < 10).
I couldn't seem to find the right functions to plot points in SFML, because most other functions are just drawing circle and other geometric shapes. If anyone know any functions for graphing in SFML, please tell me (Something like this: https://www.youtube.com/watch?v=jMrnSa6CHfE&t=42s, not the animation, just the plotting part).
Thanks a lot!
As Galik suggested, drawing pixels onto an image is a good solution.
You could try something along the lines of this:
sf::Vector2u size;
sf::Image graph;
graph.create(size.x, size.y, sf::Color(255, 255, 255));
// y = 2x
for (unsigned int x = 0; x < size.x; x++)
{
unsigned int y = 2u * x;
if (y < size.y)
{
graph.setPixel(x, y, sf::Color(0, 0, 0));
}
}

Rendering an array of the same sprite at different locations

I am trying to recreate Space Invaders and I am having trouble with getting my invader sprite to display in a row instead of on top of each other. I have a STRUCT called Sprite that contains the x position, y position, width, height, and color and I am passing that information into a custom function that draws the sprite. Everything works if I am just creating one sprite. But I want to create multiple ones (say 5 for testing purposes). So I created an array of the Sprite structure and in a For-Loop I tried to change the x position of each element within the array and than use the custom function to draw an element of the array at each iteration of the loop but for some reason I am not getting the proper result. I can see in the debugger that the x position is in fact being changed but everything is still getting drawn on top of each other I think.
struct INVADER
{
int xPos = 100;
int yPos;
int width;
int height;
D3DCOLOR color;
INVADER()
{
xPos;
yPos;
width = 64;
height = 64;
color = D3DCOLOR_XRGB(255, 255, 255);
}
};
INVADER invaderArmy[5];
for (int index = 0; index < 5; index++)
{
//invaderArmy->xPos = 100;
invaderArmy[index].xPos *= index;
Draw_And_Rotate_Sprite(invaderImage, invaderArmy[index].xPos);
}
I'm only wiriting here because i dont have 50 rep to comment.
Shouldn't the parameter from the called Draw_And_Rotate_Sprite() function be invaderArmy[index] instead of invaderArmy[index].xPos ?
Also there isn't a problem i can see in the code presented. Please show us the Draw_And_Rotate_Sprite() function definition.

SFML Drawing Pixel Array

I found this (http://lodev.org/cgtutor/raycasting.html) tutorial on the Internet and was interested and wanted to make my own. I wanted to do it in SFML though, and I wanted to extend it, and make a 3D version, so there could be different levels the player can walk on. Thus, you would need 1 ray for every pixel, and thus each pixel would have to be drawn independently. I found this (http://www.sfml-dev.org/tutorials/2.1/graphics-vertex-array.php) tutorial, and it seemed easy enough to have the array be of individual vertices. To start, I figured the best thing to do would be to create a class that could read the pixels returned by the rays, and draw them to the screen. I used the VertexArray, but things were not working for some reason. I tried to isolate the problem, but I've had little success. I wrote a simple vertex array of just green pixels that should fill up part of the screen, and still there are problems. The pixels only show my code and the pic. of what I mean.
#include "SFML/Graphics.hpp"
int main() {
sf::RenderWindow window(sf::VideoMode(400, 240), "Test Window");
window.setFramerateLimit(30);
sf::VertexArray pointmap(sf::Points, 400 * 10);
for(register int a = 0;a < 400 * 10;a++) {
pointmap[a].position = sf::Vector2f(a % 400,a / 400);
pointmap[a].color = sf::Color::Green;
}
while (window.isOpen()) {
sf::Event event;
while (window.pollEvent(event)) {
if (event.type == sf::Event::Closed)
window.close();
}
window.clear();
window.draw(pointmap);
//</debug>
window.display();
}
return 0;
}
I meant for this to just fill in the top 10 rows with Green, but apparently that is not what I did... I think if I can figure out what is causing this not to work, I can probably fix the main problem. Also if you think there is a better way to do this instead, you could let me know :)
Thanks!
I think you misused the vertex array. Take a look at the sf::Quads primitive in the tutorial's table : you need to define 4 points (coordinates) to draw a quad, and a pixel is just a quad of side length 1.
So what you need is to create a vertex array of size 400*10*4, and set the same position to every following four vertices.
You can also use another method provided by SFML : draw directly a texture pixel by pixel and display it. It may not be the most efficient thing to do (you'll have to compare with vertices) but it has the advantage of being rather simple.
const unsigned int W = 400;
const unsigned int H = 10; // you can change this to full window size later
sf::UInt8* pixels = new sf::UInt8[W*H*4];
sf::Texture texture;
texture.create(W, H);
sf::Sprite sprite(texture); // needed to draw the texture on screen
// ...
for(register int i = 0; i < W*H*4; i += 4) {
pixels[i] = r; // obviously, assign the values you need here to form your color
pixels[i+1] = g;
pixels[i+2] = b;
pixels[i+3] = a;
}
texture.update(pixels);
// ...
window.draw(sprite);
The sf::Texture::update function accepts an array of sf::UInt8. They represent the color of each pixel of the texture. But as the pixels need to be 32bit RGBA, 4 following sf::UInt8 are the RGBA composants of the pixel.
Replace the line:
pointmap[a].position = sf::Vector2f(a % 400,a / 400);
With:
pointmap[a].position = sf::Vector2f(a % 400,(a/400) % 400);

opengl array of pool balls

i am drawing an array of pool balls in opengl using c++
the problem i am facing is the array draws in a straight line.
when i use gltranslate the balls still only translate along the line when i edit the z and y axis
what i want to do is set the balls up in a triangle shape like the breaking of a pool match
how do i use the array code to set the balls up like this?
any help would be much appreciated
balls[7];
for (int x = ball-start; x<ball-end;x++)
{
glTranslatef(0,0,0.5);
glColor3f(1,0,0);
ball[x].drawball();
}
assuming:
struct Ball {
double x,y,z;
void drawball(void);
/* ... */
} ball[7];
try:
for(int i=0; i<7 ;i++)
{
glPushMatrix();
glTranslated(ball[i].x,ball[i].y,ball[i].z);
glColor3f(1,0,0);
ball[i].drawball();
glPopMatrix();
}
details probably vary, but hopefully you get the idea.
Do something like this:
// first of all, include the x,y position (assuming 2D, since pool) in the Ball object:
class Ball
{
//...
private:
float xpos, ypos;
//...
};
Then when you construct the array of balls, rather than just making 8 balls, you're going to want to allocate the memory on the heap so that it will last throughout your entire game. So do this:
Ball *ball= new Ball*[8];
ball[0] = new Ball(x0,y0);
ball[1] = new Ball(x1,y1);
ball[2] = new Ball(x2,y2);
ball[3] = new Ball(x3,y3);
// ...
Make sure that when your game is over, you clean up after yourself.
for (int i = 0; i < 8; i++)
delete ball[i];
delete [] ball;
Then in your Ball::draw() do something like this:
Ball::draw()
{
glColor3f(/*yellow*/); // Set the color to yellow
glTranslatef(-xpos, -ypos, 0); // Move to the position of the ball
// Draw the ball
glTranslatef(xpos, ypos, 0); // Move back to the default position
}
All you have to do is come up with the correct (x0,y0),(x1,y1),(x2,y2)... to form a triangle! Does this make sense/answer your question?