edited the first post
Hi, I'm honestly not sure what I'm doing wrong here, I think I might be fundamentally misunderstanding how views work.
I'm using SFML 2.31 for Visual Studio 2015 on Windows 10. Using DLLs.
I'm not completely sure how to make the code more minimal since I'm not sure where the problem might be. Sorry. I'm kind of new to this. I did try to comment it nicely, but if you have any suggestions as to how I can better help you help me, that would be fine.
The goal of the program is to have part of a an std::vector of sprites that represent the level, made up of the same tile, appear in the window, and when the user presses a wasd key, it should scroll in the appropriate direction and stop at the edges.
The texture/all the sprites are 50px x 50px btw.
It displays nicely at the start, but then when I push any of the wasd keys it freaks out and crashes.
#include <SFML/System.hpp>
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <vector>
#include <iostream>
struct Var {
int w; //window width, view width
int h; //window height, view height
int s; //tile size
int half; //half the size of the world
int size; //size of the world
bool foundStart; //for checking what to display in view
};
struct GameSprite {
sf::Sprite sprite;
int rx; //x value of the right side of the sprite
int by; //y value of the bottom side of the sprite
};
struct ViewData {
float leftX, rightX, topY, bottomY, center;
ViewData(Var &var) {
center = var.half;
leftX = center - (var.w / 2);
rightX = center + (var.w / 2);
topY = center - (var.h / 2);
bottomY = center + (var.h / 2);
}
};
char input(sf::RenderWindow &window) {
char inputChar = '\0';
sf::Event event;
while (window.pollEvent(event)) {
if (event.type == sf::Event::Closed) {
window.close();
}
if (event.type == sf::Event::KeyPressed) {
if (event.key.code == sf::Keyboard::W) {
inputChar = 'w';
}
else if (event.key.code == sf::Keyboard::A) {
inputChar = 'a';
}
else if (event.key.code == sf::Keyboard::S) {
inputChar = 's';
}
else if (event.key.code == sf::Keyboard::D) {
inputChar = 'd';
}
}
}
return inputChar;
}
void collision(ViewData &viewData, Var &var, sf::View &view) {
if (viewData.leftX < 0) {
view.move(0 - viewData.leftX, 0);
viewData.leftX = 0;
viewData.rightX = var.w;
}
else if (viewData.rightX > var.size) {
view.move(var.size - viewData.rightX, 0);
viewData.rightX = var.size;
viewData.leftX = var.size - var.w;
}
else if (viewData.topY < 0) {
view.move(0, 0 - viewData.topY);
viewData.topY = 0;
viewData.bottomY = var.h;
}
else if (viewData.bottomY > var.size) {
view.move(0, var.size - viewData.bottomY);
viewData.bottomY = var.size;
viewData.topY = var.size - var.h;
}
}
bool findStart(GameSprite &sprite, ViewData &viewData) {
if (sprite.rx >= viewData.leftX && sprite.sprite.getPosition().x < viewData.rightX) {
if (sprite.by >= viewData.topY && sprite.sprite.getPosition().y < viewData.bottomY) {
return true;
}
}
return false;
}
int main() {
Var var = { 800, 600, 50, 2500, 5000, false };
sf::View view(sf::Vector2f(var.half, var.half), sf::Vector2f(var.w, var.h));
sf::RenderWindow window(sf::VideoMode(var.w, var.h), "test");
window.setView(view);
ViewData viewData(var);
sf::Texture texture;
texture.loadFromFile("background.png");
char in = '\0';
int arrayStart[2];
int arrayEnd[2];
int x = 0;
int y = 0;
std::vector<std::vector<GameSprite> > sprite;
sprite.resize(100);
for (int a = 0; a < 100; ++a) {
sprite[a].resize(100);
}
for (int a = 0; a < 100; ++a) {
for (int b = 0; b < 100; ++b) {
sprite[a][b].sprite.setTexture(texture);
sprite[a][b].sprite.setPosition(x, y);
sprite[a][b].rx = x + var.s;
sprite[a][b].by = y + var.s;
if (!var.foundStart) {
if (findStart(sprite[a][b], viewData)) { //checks to see where to start drawing
arrayStart[0] = a;
arrayStart[1] = b;
arrayEnd[0] = arrayStart[0] + (var.w / var.s) + 1;
arrayEnd[1] = arrayStart[1] + (var.h / var.s) + 1;
var.foundStart = true;
}
}
y += var.s;
}
y = 0;
x += var.s;
}
while (window.isOpen()) {
var.foundStart = false;
in = input(window);
if (in != '\0') {
switch (in) {
case 'w':
view.move(0, -20);
viewData.topY -= 20;
viewData.bottomY -= 20;
break;
case 'a':
view.move(-20, 0);
viewData.leftX -= 20;
viewData.rightX -= 20;
break;
case 's':
view.move(0, 20);
viewData.topY += 20;
viewData.bottomY += 20;
break;
case 'd':
view.move(20, 0);
viewData.rightX += 20;
viewData.leftX += 20;
break;
}
in = '\0';
collision(viewData, var, view); //checks to see if the view is at the edge of the world, moves it back
for (int a = 0; !var.foundStart; ++a) {
for (int b = 0; !var.foundStart; ++b) {
if (findStart(sprite[a][b], viewData)) { //checks if this is a valid location to start drawing to the view
arrayStart[0] = a;
arrayStart[1] = b;
arrayEnd[0] = arrayStart[0] + (var.w / var.s) + 1;
arrayEnd[1] = arrayStart[1] + (var.h / var.s) + 1;
var.foundStart = true;
}
}
}
}
window.setView(view);
window.clear();
for (int a = arrayStart[0]; a < arrayEnd[0]; ++a) {
for (int b = arrayStart[1]; b < arrayEnd[1]; ++b) {
window.draw(sprite[a][b].sprite);
}
}
window.display();
}
return 0;
}