Meine 2 Cent:
Dein Programierstil ist total C, und nicht C++, und selbst für C sind soweit ich weiß ein paar Sachen daneben. Nur ein kleines Beispiel:
int map[100][100];
memset(map, 0, sizeof(int) * 100 * 100);
// -->
int map[100][100] {};
Und selbst da gibt es vermutlich besseres als raw arrays.
Integer Konstanten sollten auch nicht mit Makros definiert werden, sondern const , constexpr , oder als enum (je nachdem).
Das using namespace ist in kleinen Programmen noch vertretbar, sollte aber grundsätzlich vermieden werden.
sf::Clock::restart() gibt auch den momentanen Zeitwert zurück, da kann man sich auch eine Zeile sparen.
changeDirection würde ich über einen Rückgabewert machen.
Makros sollten per Konvention so oder so immer in Großbuchstaben gehalten werden (und in C++ für solche Zwecke vermieden werden).
Bei case UP fehlt ein break.
Der Code ist jetzt noch weit von perfekt, aber ich behaupte mal ein Tick besser, und läuft auch:
#include <SFML/Graphics.hpp>
#include <iostream>
using namespace sf;
using namespace std;
#define WHITE 0
#define BLACK 1
enum class Direction {
Up, Down, Left, Right
};
// man könnte hier auch über den pre-increment operator gehen, aber das muss nicht sein
Direction rotateRight(Direction dir)
{
switch (dir) {
case Direction::Up: return Direction::Right;
case Direction::Right: return Direction::Down;
case Direction::Down: return Direction::Left;
case Direction::Left: return Direction::Up;
}
}
Direction rotateLeft(Direction dir)
{
switch (dir) {
case Direction::Up: return Direction::Left;
case Direction::Right: return Direction::Up;
case Direction::Down: return Direction::Right;
case Direction::Left: return Direction::Down;
}
}
int main() {
constexpr unsigned WIDTH = 100;
constexpr unsigned HEIGHT = 100;
constexpr unsigned BLOCKSIZE = 10;
RenderWindow window(VideoMode(1000, 1000), "PHYSIK!");
RectangleShape shape;
shape.setSize(Vector2f(BLOCKSIZE, BLOCKSIZE));
Clock clock;
Vector2i position(50, 50);
Direction direction = Direction::Up;
int map[HEIGHT][WIDTH] {};
while (window.isOpen()) {
float deltaTime = clock.restart().asSeconds();
Event event;
while (window.pollEvent(event))
if (event.type == event.Closed)
window.close();
if (Keyboard::isKeyPressed(Keyboard::Escape))
window.close();
if (map[position.y][position.x] == WHITE) {
direction = rotateRight(direction);
map[position.y][position.x] = BLACK;
}
else if (map[position.y][position.x] == BLACK) {
direction = rotateLeft(direction);
map[position.y][position.x] = WHITE;
}
switch (direction) {
case Direction::Up:
position.y--;
break;
case Direction::Down:
position.y++;
break;
case Direction::Right:
position.x++;
break;
case Direction::Left:
position.x--;
break;
default:
cerr << "Invalid Direction\n";
return -1;
}
cout << static_cast<int>(direction) << "\t" << position.x << "\t" << position.y << endl;
window.clear(Color(0, 100, 255, 1));
for (int i = 0; i < HEIGHT; ++i) {
for (int j = 0; j < WIDTH; ++j) {
shape.setPosition(Vector2f(j * BLOCKSIZE, i * BLOCKSIZE));
// shape.setFillColor(map[i][j] == WHITE ? Color::White : Color::Black);
if (map[i][j] == WHITE)
shape.setFillColor(Color::White);
else if (map[i][j] == BLACK)
shape.setFillColor(Color::Black);
window.draw(shape);
}
}
window.display();
}
return 0;
}
EDIT: Der andere logische Fehler (neben dem fehlenden break) liegt in der changeDirection Funktion. Und Als Beispiel schauen wir uns nur eine Richtung an, denn das lässt sich auf die Andere übertragen.
Das Hauptproblem ist, dass hier nicht mit if-else, sondern nur mit if gearbeitet wird. Wenn also z.B. die Richtung von UP->RIGHT geändert wird, springt das Programm zu den nächsten ifs und gelangt irgendwann wieder bei if (toChange == RIGHT) und dann wird die Richtung gleich wieder auf RIGHT->DOWN geändert.
// toChange == UP
if (dir == dirRight) {
if (toChange == UP)
toChange = RIGHT; // hier wird geändert UP->RIGHT
if (toChange == DOWN)
toChange = LEFT;
if (toChange == RIGHT) // hier ist toChange schon RIGHT von oben
toChange = DOWN; // toChange wird geändert RIGHT->DOWN
if (toChange == LEFT)
toChange = UP;
}
Also: entweder else-if, oder switch.
Frage: Kann es vorkommen, dass position x/y >= 100 werden und was würde dann passieren?
P.S.: Cooles Programm, macht Spaß anzuschauen, weiter so!