Skip to content

Commit

Permalink
First map editor version
Browse files Browse the repository at this point in the history
  • Loading branch information
DenisD3D committed Mar 16, 2024
1 parent faa91dc commit 96ec4d8
Show file tree
Hide file tree
Showing 23 changed files with 1,168 additions and 485 deletions.
15 changes: 13 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,20 @@ link_directories(minizip-ng)

qt5_add_resources(RESOURCE_ADDED resources.qrc)

add_executable(SnakeQT src/main.cpp src/jeu.cpp src/snakewindow.cpp src/zip.cpp ${RESOURCE_ADDED}
add_executable(SnakeQT ${RESOURCE_ADDED}
src/main.cpp
src/jeu.cpp
src/inmemoryzip.cpp
src/map.cpp
src/map.hpp)
src/constants.hpp
src/screens/snakewindow.cpp
src/screens/mainmenu.hpp
src/screens/gamescreen.cpp
src/screens/editorscreen.cpp
src/screens/snakewindow.cpp
src/screens/gamearea.cpp
)

target_link_libraries(SnakeQT
Qt5::Core
Qt5::Gui
Expand Down
Binary file added maps/map3.skm
Binary file not shown.
7 changes: 7 additions & 0 deletions src/constants.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#ifndef CONSTANTS_HPP
#define CONSTANTS_HPP

#define TEXTURE_SIZE 32
#define MAX_MAP_SIZE 30

#endif //CONSTANTS_HPP
97 changes: 97 additions & 0 deletions src/inmemoryzip.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
#include "inmemoryzip.hpp"


InMemoryZipFileWriter::InMemoryZipFileWriter(const QString &fileName) {
file = zipOpen(qPrintable(fileName), APPEND_STATUS_CREATE);
if (file == nullptr) {
qDebug() << "ERROR: InMemoryZipFileWriter: could not open or create file" << fileName;
}
}

InMemoryZipFileWriter::~InMemoryZipFileWriter() {
zipClose(file, nullptr);
}

bool InMemoryZipFileWriter::addFileToZip(const QString &fileName, const QByteArray &data) const {
if (!isValid()) {
qDebug() << "ERROR: InMemoryZipFileWriter: zip file is not open";
return false;
}

constexpr zip_fileinfo zipInfo = {};
int err = zipOpenNewFileInZip(file, qPrintable(fileName), &zipInfo,
nullptr, 0, nullptr, 0, nullptr,
Z_DEFLATED, -1);

if (err != ZIP_OK) {
qDebug() << "ERROR: InMemoryZipFileWriter: could not open file in zip" << fileName;
return false;
}

qDebug() << "InMemoryZipFileWriter: inserting" << fileName << "buffer size" << data.size();

err = zipWriteInFileInZip(file, data.data(), data.size());
if (err < 0) {
zipCloseFileInZip(file);
qDebug() << "ERROR: InMemoryZipFileWriter: could not write file in zip" << fileName;
return false;
}

err = zipCloseFileInZip(file);
if (err != ZIP_OK) {
qDebug() << "ERROR: InMemoryZipFileWriter: could not close file in zip" << fileName;
return false;
}
return true;
}


InMemoryZipFileReader::InMemoryZipFileReader(const QString &fileName) {
file = unzOpen64(qPrintable(fileName));
if (file == nullptr) {
qDebug() << "ERROR: InMemoryZipFileReader: could not open file" << fileName;
}
}

InMemoryZipFileReader::~InMemoryZipFileReader() {
unzClose(file);
}

bool InMemoryZipFileReader::extractFile(const QString &fileName, QByteArray &data) const {
if (!isValid()) {
qDebug() << "ERROR: InMemoryZipFileReader: zip file is not open";
return false;
}

if (unzLocateFile(file, qPrintable(fileName), 0) != UNZ_OK) {
qDebug() << "ERROR: InMemoryZipFileReader: file not found in the zipfile: " << fileName;
return false;
}

unz_file_info64 file_info;

if (unzGetCurrentFileInfo64(file, &file_info, nullptr, 0, nullptr, 0, nullptr, 0) != UNZ_OK) {
qDebug() << "ERROR: InMemoryZipFileReader: could not read file info: " << fileName;
return false;
}

if (unzOpenCurrentFile(file) != UNZ_OK) {
qDebug() << "ERROR: InMemoryZipFileReader: could not open in zip file: " << fileName;
return false;
}

data.fill(0, static_cast<int>(file_info.uncompressed_size + 1));

qDebug() << "InMemoryZipFileReader: extracting" << fileName << "buffer size" << data.size();

const int read = unzReadCurrentFile(file, data.data(), data.size());

unzCloseCurrentFile(file);

if (read < 0) {
qDebug() << "ERROR: InMemoryZipFileReader: could not read file in zip" << fileName;
return false;
}

return true;
}
63 changes: 63 additions & 0 deletions src/inmemoryzip.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#ifndef IN_MEMORY_ZIP_FILE_HANDLER_H
#define IN_MEMORY_ZIP_FILE_HANDLER_H

#include <QDebug>

#include "unzip.h"
#include "zip.h"


class QByteArray;
class QString;
class QTextStream;


/**
* Handle writing contents of a ZIP file
* Used to write map data and resources to .skm files
*/
class InMemoryZipFileWriter {
zipFile file;

public:
explicit InMemoryZipFileWriter(const QString &fileName);

~InMemoryZipFileWriter();

bool addFileToZip(const QString &fileName, const QByteArray &data) const;

/**
* @brief isValid
* @return true if the ZIP file was opened successfully
*/
bool isValid() const { return file != nullptr; }
};

/**
* Handle reading contents of a ZIP file without extracting it to disk
* Used to read map data and resources from .skm files
* Based on https://asmaloney.com/2011/12/code/in-memory-zip-file-access-using-qt/
*/
class InMemoryZipFileReader {
unzFile file;

public:
explicit InMemoryZipFileReader(const QString &inFileName);

~InMemoryZipFileReader();

/**
* @brief isValid
* @return true if the ZIP file was opened successfully
*/
bool isValid() const { return file != nullptr; }

/**
* Extract a file from the ZIP file and put the contents into a QByteArray
* @param fileName name of the file in the zip to extract
* @param data QByteArray to put the file contents into
* @return error code
*/
bool extractFile(const QString &fileName, QByteArray &data) const;
};
#endif
77 changes: 23 additions & 54 deletions src/jeu.cpp
Original file line number Diff line number Diff line change
@@ -1,26 +1,7 @@
#include <iostream>
#include <cassert>
#include <QtXml>

#include "jeu.hpp"

using namespace std;

Position::Position() = default;

Position::Position(const int a, const int b) {
x = a;
y = b;
}

bool Position::operator==(const Position &pos) const {
return x == pos.x && y == pos.y;
}

bool Position::operator!=(const Position &pos) const {
return x != pos.x || y != pos.y;
}

Jeu::Jeu() {
dirSnake = DROITE;
std::random_device rd;
Expand Down Expand Up @@ -59,19 +40,19 @@ bool Jeu::init() {
snake.clear();

Position posTete;
posTete.x = map.init_x;
posTete.y = map.init_y;
for (int i = 0; i < map.init_snake_length; i++) {
posTete.x = map.getInitX();
posTete.y = map.getInitY();
for (int i = 0; i < map.getInitSnakeLength(); i++) {
snake.push_back(posTete);
}
dirSnake = map.init_direction;
dirSnake = map.getInitDirection();


std::uniform_int_distribution<> distr(0, map.width - 1);
std::uniform_int_distribution<> distr(0, map.getWidth() - 1);
do {
posApple.x = distr(gen);
posApple.y = distr(gen);
} while (!posValide(posApple));
applePos.x = distr(gen);
applePos.y = distr(gen);
} while (!posValide(applePos));

return true;
}
Expand All @@ -87,18 +68,19 @@ void Jeu::evolue() {
constexpr int depX[] = {-1, 1, 0, 0};
constexpr int depY[] = {0, 0, -1, 1};

posTest.x = (snake.front().x + depX[dirSnake] + map.width) % map.width;
posTest.y = (snake.front().y + depY[dirSnake] + map.height) % map.height;
posTest.x = (snake.front().x + depX[dirSnake] + map.getWidth()) % map.getWidth();
posTest.y = (snake.front().y + depY[dirSnake] + map.getHeight()) % map.getHeight();

if (posValide(posTest)) {
snake.push_front(posTest); // Add the new head

if (posTest == posApple) { // The snake eats the apple, place a new apple
std::uniform_int_distribution<> distr(0, map.width - 1);
if (posTest == applePos) {
// The snake eats the apple, place a new apple
std::uniform_int_distribution<> distr(0, map.getWidth() - 1);
do {
posApple.x = distr(gen);
posApple.y = distr(gen);
} while (!posValide(posApple));
applePos.x = distr(gen);
applePos.y = distr(gen);
} while (!posValide(applePos));
// Don't remove the last element of the snake to make it grow
} else {
// Remove the last element of the snake to make it move
Expand All @@ -110,28 +92,15 @@ void Jeu::evolue() {
}
}

int Jeu::getNbCasesX() const {
return map.width;
}

int Jeu::getNbCasesY() const {
return map.height;
}

TileType Jeu::getCase(const Position &pos) const {
assert(pos.x>=0 && pos.x<map.width && pos.y>=0 && pos.y<map.height);
return map.tiles[pos.y * map.width + pos.x];
}

const list<Position> &Jeu::getSnake() const {
return snake;
const list<Position> *Jeu::getSnake() const {
return &snake;
}

bool Jeu::posValide(const Position &pos) const {
if (pos.x < 0 || pos.x >= map.width || pos.y < 0 || pos.y >= map.height) // Out of bounds
if (pos.x < 0 || pos.x >= map.getWidth() || pos.y < 0 || pos.y >= map.getHeight()) // Out of bounds
return false;

if (map.tiles[pos.y * map.width + pos.x].type != GROUND)
if (map.getTileAt(pos).type != GROUND)
return false;

auto itSnake = snake.begin();
Expand Down Expand Up @@ -165,10 +134,10 @@ void Jeu::setDirection(const Direction dir) {
directionsBuffer.push(dir);
}

Position &Jeu::getPosApple() {
return posApple;
const Position *Jeu::getApplePos() const {
return &applePos;
}

Map &Jeu::getMap() {
const Map &Jeu::getMap() const {
return map;
}
30 changes: 4 additions & 26 deletions src/jeu.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,13 @@

#include "map.hpp"

class Position {
public:
int x{}, y{};

Position();

Position(int, int);

bool operator==(const Position &) const;

bool operator!=(const Position &) const;
};

class Jeu {
protected:
Map map;
std::list<Position> snake;
Direction dirSnake;
std::queue<Direction> directionsBuffer;
Position posApple = Position(-1, -1);
Position applePos = Position(-1, -1);
std::mt19937 gen;

public:
Expand All @@ -44,26 +31,17 @@ class Jeu {

void evolue();

// Retourne les dimensions (en nombre de cases)
int getNbCasesX() const;

int getNbCasesY() const;

// Retourne la case ? une position donn?e
TileType getCase(const Position &) const;

// Retourne la liste des ?l?ments du serpent en lecture seule
const std::list<Position> &getSnake() const;
const std::list<Position> *getSnake() const;

// Indique si la case ? une position donn?e existe et est libre
bool posValide(const Position &) const;

// Modifie la direction
void setDirection(Direction);

Position &getPosApple();
const Position *getApplePos() const;

Map &getMap();
const Map &getMap() const;
};

#endif
2 changes: 1 addition & 1 deletion src/main.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "snakewindow.hpp"
#include "screens/snakewindow.hpp"

using namespace std;

Expand Down
Loading

0 comments on commit 96ec4d8

Please sign in to comment.