Hello,
I'm starting this little project and I started with writing a Room class. Room is a single board that we see in the game, like a street, a lab room. Room consists of layers. This should allow me to do some nice work with z order. I don't know how many layers each room will have - one could have only 2 layers, second 5 layers and third 3 layers. So creating a simple array with a constant number of elements wouldn't do the trick, it would be useless consuming too much memory. Therefore I thought about vector. But personally I don't really like vector, it also can consume much memory. I decided to create my own easy template class for some dynamic array. I did that and I think it works okay right now (although there are some things that I could improve, but that's not a matter of my problem). Once I created my dynamic array class I, of course, began writing Room class. I started with a constructor, deconstructor and a method for adding layers. I've done drawing by making Room class inherit from Drawable (so in the game loop I can do something like this: window.draw(myroom)). I overrode draw method correctly, I think... And so, I created a Room object and I added one layer to it, pressed F7, then F5 and... Nothing is drawn. There's only a white sprite in the place where my background should be visible. This white sprite's position is the same as the position given in the parameter in the add layer function, so I think it kinda works... Something there works, but something doesn't. And I have no idea what doesn't. Here's the complete code I have (it's not long):
DArray.h
#ifndef DARRAY_H
#define DARRAY_H
#include <iostream>
using namespace std;
template<class Foo>
class DArray {
private:
struct node {
Foo data;
node* ptr;
node(Foo d) {
data = d;
ptr = NULL;
}
};
node* first;
int counter;
public:
DArray();
~DArray();
void push(Foo d);
Foo pop();
int size() const;
bool empty();
Foo& operator[](int i) const;
};
template<class Foo>
DArray<Foo>::DArray() {
first = NULL;
counter = 0;
}
template<class Foo>
DArray<Foo>::~DArray() {
while (!empty())
pop();
}
template<class Foo>
void DArray<Foo>::push(Foo d) {
if (empty()) {
first = new node(d);
}
else {
node* tmp = first;
while (tmp->ptr != NULL)
tmp = tmp->ptr;
tmp->ptr = new node(d);
}
counter++;
}
template<class Foo>
Foo DArray<Foo>::pop() {
if (!empty()) {
Foo d;
node* tmp;
tmp = first;
first = first->ptr;
d = tmp->data;
delete tmp;
return d;
}
}
template<class Foo>
int DArray<Foo>::size() const {
return counter;
}
template<class Foo>
bool DArray<Foo>::empty() {
if (first == NULL)
return true;
else
return false;
}
template<class Foo>
Foo& DArray<Foo>::operator[](int i) const {
node* tmp = first;
for (int j = 1; j < i+1; j++) {
tmp = tmp->ptr;
}
return tmp->data;
}
#endif
Room.h
#ifndef ROOM_H
#define ROOM_H
#include <SFML\Graphics.hpp>
#include "DArray.h"
using namespace sf;
using namespace std;
struct Layer {
Texture tex;
Sprite spr;
//id, name
Layer() { }
Layer(const string path, Vector2f pos) {
tex.loadFromFile(path);
spr.setTexture(tex);
spr.setPosition(pos);
}
};
class Room : public Drawable {
private:
DArray<Layer> layers;
//int id;
//string name;
virtual void draw(RenderTarget& target, RenderStates states) const {
for (int i = 0; i < layers.size(); i++) {
target.draw(layers[i].spr, states);
}
}
public:
Room();
~Room();
void AddLayer(const string path, Vector2f pos);
//void RemoveLayer();
//show layers' names
};
#endif
Room.cpp
#include "Room.h"
Room::Room() {
}
Room::~Room() {
}
void Room::AddLayer(const string path, Vector2f pos) {
layers.push(Layer(path, pos));
}
GameApp.h
#ifndef GAMEAPP_H
#define GAMEAPP_H
#include <SFML\Graphics.hpp>
#include <iostream>
#include "Room.h"
using namespace sf;
using namespace std;
class GameApp {
private:
RenderWindow win;
bool fullscreen;
Event evt;
double dt, dwticks, dwnewticks;
Clock main_clock;
public:
GameApp();
~GameApp();
void Run();
//void ToggleFullscreen();
};
#endif
GameApp.cpp
#include "GameApp.h"
GameApp::GameApp() {
fullscreen = false;
dt = dwticks = dwnewticks = 0.f;
win.create(VideoMode(800, 600), "PNC", fullscreen ? Style::Fullscreen : Style::Default);
win.setFramerateLimit(60);
win.setVerticalSyncEnabled(true);
win.setMouseCursorVisible(true);
}
GameApp::~GameApp() {
}
void GameApp::Run() {
main_clock.restart();
dwticks = main_clock.getElapsedTime().asMilliseconds();
Room str;
str.AddLayer("data/rooms/str/gfx/bgr.jpg", Vector2f(0, 50));
while (win.isOpen()) {
if (win.pollEvent(evt)) {
if (Keyboard::isKeyPressed(Keyboard::Key::Escape) ||
evt.type == Event::Closed) {
win.close();
}
}
else {
dwnewticks = main_clock.getElapsedTime().asMilliseconds();
dt = dwnewticks > dwticks ? (dwnewticks - dwticks) / 4000.f : 0.f;
dwticks = dwnewticks;
win.clear(Color(0, 0, 0));
win.draw(str);
win.display();
}
}
}
main.cpp
#include "GameApp.h"
int main() {
GameApp game;
game.Run();
return 0;
}
When I replaced the const string path parameter in Layer constructor with Texture& t (and also did the same changes in add layer method) and then in the Run() method in GameApp class I created a texture:
Texture t;
t.loadFromFile("data/rooms/str/gfx/bgr.jpg");
and passed it to the parameter as this:
Room str;
str.AddLayer(t, Vector2f(0, 50));
it did the trick. Background shows correctly that way. But I want it to work also with that string parameter.
I'd be forever ashamed if I did something really stupid.