Hello everybody! I want to create a simple game called
Bug by the New Year. To do that, I'm developing a
SGM (Simple Game Engine). This is how it works:
There are multiple
level data files. There is one
linear list of objectives.
SGM takes one
objective, constantly checks if it is accomplished, and when it is, loads a
new level data file. Even though it's horribly inefficient, it allows very high scenario flexibility and super easy scripting. I've successfully completed one of the most complicated code segments inside the
SGM:
square grid collision detection and correct response mechanism. The segment itself is mere 37 lines of code, with 100 in total to be able to test it. Here it is:
#include <fstream>
#include <SFML/Graphics.hpp>
int main ()
{
int w, h, **lvl, posX, posY, block;
float velX(0), velY(0), inertia, friction;
std::ifstream data("data.txt");
/// I ASSUME THAT FILE EXISTS AND HAS VALID DATA. BEWARE - ERRORS UNHANDLED!
data >> w >> h >> posX >> posY >> block >> inertia >> friction;
posX *= block; posY *= block;
lvl = new int*[h]; for (int i = 0; i < h; ++i) lvl[i] = new int[w];
for (int i = 0; i < h; ++i)
for (int j = 0; j < w; ++j)
data >> lvl[i][j];
data.close();
sf::RenderWindow window(sf::VideoMode(w*block,h*block),"Collision", sf::Style::Close);
window.setFramerateLimit(30);
sf::Event event;
sf::Keyboard kboard;
sf::RectangleShape rectangle(sf::Vector2f(block,block));
event.type = sf::Event::GainedFocus; // In case event.type==sf::Event::Closed at the very beginning
while (window.isOpen())
{
if (kboard.isKeyPressed(sf::Keyboard::Up )) velY -= inertia;
if (kboard.isKeyPressed(sf::Keyboard::Down )) velY += inertia;
if (kboard.isKeyPressed(sf::Keyboard::Left )) velX -= inertia;
if (kboard.isKeyPressed(sf::Keyboard::Right)) velX += inertia;
if (velX > friction) velX -= friction; else
if (velX < -friction) velX += friction; else
velX = 0;
if (velY > friction) velY -= friction; else
if (velY < -friction) velY += friction; else
velY = 0;
/// SQUARE GRID COLLISION DETECTION AND CORRECT RESPONSE MECHANISM
bool collisionX(false), collisionY(false);
int positionX, positionY;
sf::IntRect hero(posX+velX, posY+velY, block, block);
for (int i = 0; i < h; ++i)
for (int j = 0; j < w; ++j)
if (lvl[i][j] == 1)
{
sf::IntRect rect(j*block, i*block, block, block);
if (hero.intersects(rect))
{
hero.left = posX;
if(hero.intersects(rect))
{
collisionY = true;
positionY = rect.top;
}
hero.left += velX; hero.top = posY;
if (hero.intersects(rect))
{
collisionX = true;
positionX = rect.left;
}
hero.top += velY;
}
}
if (collisionX)
{
if (velX > 0) posX = positionX - block; else
if (velX < 0) posX = positionX + block;
velX = 0;
}
if (collisionY)
{
if (velY > 0) posY = positionY - block; else
if (velY < 0) posY = positionY + block;
velY = 0;
}
/// END OF SQUARE GRID COLLISION DETECTION AND RESPONSE MECHANISM
posX += velX; posY += velY;
rectangle.setPosition(posX, posY);
window.clear(sf::Color(255,255,255));
rectangle.setFillColor(sf::Color(255,0,0));
window.draw(rectangle);
rectangle.setFillColor(sf::Color(0,0,0));
for (int i = 0; i < h; ++i)
for (int j = 0; j < w; ++j)
if (lvl[i][j] == 1)
{
rectangle.setPosition(j*block,i*block);
window.draw(rectangle);
}
window.display();
window.pollEvent(event);
if (event.type == sf::Event::Closed) window.close();
}
for (int i = 0; i < h; ++i) delete [] lvl[i];
delete [] lvl;
return 0;
}
I hope that maybe someone someday will find it useful. Code improvement discussion would be very appreciated
Oh, and
"data.txt" contents:
10 10 1 1 20 0.9 0.5
1 1 1 1 1 1 1 1 1 1
1 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 1
1 0 0 0 1 1 0 0 0 1
1 0 0 0 1 1 0 0 0 1
1 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 1
1 1 1 1 1 1 1 1 1 1