Bienvenue, Invité. Merci de vous connecter ou de vous inscrire.
Avez-vous perdu votre e-mail d'activation ?

Auteur Sujet: Framework  (Lu 57067 fois)

0 Membres et 1 Invité sur ce sujet

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Framework
« Réponse #15 le: Décembre 02, 2013, 09:21:52 am »
Ok, de mon côté, j'ai enfin réussi à déterminé d'ou venait ce crash, donc, j'ai enfin réussi à exécuté un projet utilisant SFGL, je vais donc mettre à jour tout ça sur git-hub et commencer à faire quelques tutoriels.
Mais il y a surement moyen d'encore améliorer l'installation du framework et de la rendre fonctionnelle sur d'autres plateformes, mais, comme je galère beaucoup avec CMake et que c'est mon tout premier framework je pense que je vais laisser le soin à un expert de s'en charger, de plus je n'ai pas de mac et je ne connais pas xcode.

J'ai oublié de préciser que SFGL utilise boost également donc, il faut installer boost. :)

Plus tard quand je mettrai le module réseau sur git-hub, il faudra aussi installer openssl que j'utilise pour le module réseau.

Un aperçu du code source  pour le réseau :
Classe qui se charge d'appliquer un chiffrement RSA aux octets envoyés sur le réseau
#include "rsa.h"
#include <stdlib.h>
#include <iostream>

int Rsa::size = 0;
X509* Rsa::x = X509_new();
EVP_PKEY* Rsa::evp_pkey = EVP_PKEY_new();
BIO* Rsa::pub = BIO_new(BIO_s_mem());
size_t Rsa::pub_len = 0;
char* Rsa::pub_key = NULL;
RSA* Rsa::keypair = generateKeys(2048);
int Rsa::getCertificate (unsigned char **out) {
    int len= i2d_X509(x, out);
    return len;
}

void Rsa::setCertificate(const unsigned char* in, int length) {
    x = d2i_X509(NULL,&in,length);
    evp_pkey = X509_get_pubkey(x);
    keypair = EVP_PKEY_get1_RSA(evp_pkey);
    PEM_write_bio_RSAPublicKey(pub, keypair);
    pub_len = BIO_pending(pub);
    free(pub_key);
    pub_key = (char*)malloc(pub_len + 1);
    BIO_read(pub, pub_key, pub_len);
    pub_key[pub_len] = '\0';
}
int Rsa::encryptWithPrKey (const char *data, size_t dataSize, char **encData) {
    *encData = new char[RSA_size(keypair)];
    int encDataLen = RSA_private_encrypt(dataSize, (unsigned char*) data, (unsigned char*)*encData, keypair, RSA_PKCS1_PADDING);
    if (encDataLen == -1) {
        char* err = (char*) malloc(130);
        ERR_load_crypto_strings();
        ERR_error_string(ERR_get_error(), err);
        fprintf(stderr, "Error encrypting message: %s\n", err);
        free(err);
        return FAILURE;
    }
    return encDataLen;
}
int Rsa::decryptWithPrKey (const char *encData, size_t dataSize, char **data) {
    char *msg = new char[dataSize];
    int dataLen = RSA_private_decrypt(dataSize, (unsigned char*) encData, (unsigned char*)msg, keypair, RSA_PKCS1_OAEP_PADDING);
    if (dataLen == -1) {
        char* err = (char*) malloc(130);
        ERR_load_crypto_strings();
        ERR_error_string(ERR_get_error(), err);
        fprintf(stderr, "Error encrypting message: %s\n", err);
        free(err);
    }
    *data = new char[dataLen+1];
    memcpy(*data, msg, dataLen);
    (*data)[dataLen] = '\0';
    delete[] msg;
    return dataLen;
}
int Rsa::encryptWithPbKey (const char *data, size_t dataSize, char **encData) {
    *encData = new char[RSA_size(keypair)];
    int encDataLen = RSA_public_encrypt(dataSize, (unsigned char*) data, (unsigned char*) *encData, keypair, RSA_PKCS1_OAEP_PADDING);
    if (encDataLen == -1) {
        char* err = (char*) malloc(130);
        ERR_load_crypto_strings();
        ERR_error_string(ERR_get_error(), err);
        fprintf(stderr, "Error encrypting message: %s\n", err);
        free(err);
        return FAILURE;
    }
    return encDataLen;
}
int Rsa::decryptWithPbKey (const char *encData, size_t dataSize, char **data) {
    char *msg = new char[dataSize];
    int dataLen = RSA_public_decrypt(dataSize, (unsigned char*) encData, (unsigned char*) msg, keypair, RSA_PKCS1_PADDING);
    if (dataLen == -1) {
        char* err = (char*) malloc(130);

        ERR_load_crypto_strings();
        ERR_error_string(ERR_get_error(), err);
        fprintf(stderr, "Error encrypting message: %s\n", err);
        free(err);
        return FAILURE;
    }
    *data = new char[dataLen+1];
    memcpy(*data, msg, dataLen);
    (*data)[dataLen] = '\0';
    delete[] msg;
    return dataLen;
}
 

Classe qui se charge de d'appliquer un chiffrement aes aux octets envoyé sur le réseau :

#include "aes.h"
using namespace std;

#include <iostream>

int AES_ENC::size = 0;
unsigned char* AES_ENC::key = new unsigned char[32];
unsigned char* AES_ENC::iv = new unsigned char[32];
unsigned char* AES_ENC::aesSalt = new unsigned char[32];
EVP_CIPHER_CTX* AES_ENC::e_ctx = new EVP_CIPHER_CTX;
EVP_CIPHER_CTX* AES_ENC::d_ctx = new EVP_CIPHER_CTX;
unsigned char* AES_ENC::aesPass = generateKey(256);

int AES_ENC::encrypt(const char* data, size_t dataSize, char **encData) {
    size_t blockLen  = 0;
    size_t encDataLen  = 0;
    *encData = new char[dataSize + AES_BLOCK_SIZE];
    if (EVP_EncryptInit_ex(e_ctx, EVP_aes_256_cbc(), NULL, key, iv) == 0)
        return FAILURE;
    if (EVP_EncryptUpdate(e_ctx, (unsigned char*) *encData, (int*)&blockLen, (unsigned char*) data, dataSize) == 0)
        return FAILURE;
    encDataLen += blockLen;
    if(EVP_EncryptFinal_ex(e_ctx, (unsigned char*) *encData + encDataLen, (int*)&blockLen) == 0)
        return FAILURE;
    EVP_CIPHER_CTX_cleanup(e_ctx);
    return encDataLen + blockLen;
}
int AES_ENC::decrypt(const char* encData, size_t dataSize, char **data) {
    size_t dataLen   = 0;
    size_t blockLen = 0;
    *data = new char[dataSize];
    if (EVP_DecryptInit_ex(d_ctx, EVP_aes_256_cbc(), NULL, key, iv) == 0)
        return FAILURE;
    if (EVP_DecryptUpdate(d_ctx, (unsigned char*) *data, (int*)&blockLen, (unsigned char*) encData, (int)dataSize) == 0)
        return FAILURE;
    dataLen += blockLen;
    if (EVP_DecryptFinal_ex(d_ctx, (unsigned char*) *data + dataLen, (int*)&blockLen) == 0)
        return FAILURE;
    dataLen += blockLen;
    (*data)[dataLen] = '\0';
    EVP_CIPHER_CTX_cleanup(d_ctx);
    return dataLen;
}
void AES_ENC::setKey(char* sKey) {
   strncpy((char*) key, sKey, size / 8);
}
void AES_ENC::setIv(char* sIv) {
   strncpy((char*) iv, sIv, size / 8);
}
char* AES_ENC::getKey() {
   return (char*) key;
}
char* AES_ENC::getIv() {
   return (char*) iv;
}
 

Classes qui se charge de chiffrer les octets dans des paquets SFML :

#include "encryptedPacket.h"
#include "client.h"
using namespace std;
using namespace sf;

const void* EncryptedPacket::onSend (size_t& dataSize) {
    char* buffer = NULL;
    dataSize = Rsa::encryptWithPbKey(static_cast<const char*> (getData()), getDataSize(), &buffer);
    return &buffer[0];
}
void EncryptedPacket::onReceive (const void* data, size_t dataSize) {
    char* buffer = NULL;
    int newDataSize = Rsa::decryptWithPbKey(static_cast<const char*> (data), dataSize, &buffer);
    append(&buffer[0], newDataSize);
}
 

#include "symEncPacket.h"

using namespace std;
using namespace sf;

const void* SymEncPacket::onSend (size_t& dataSize) {
    char* buffer = NULL;
    dataSize = AES_ENC::encrypt(static_cast<const char*> (getData()), getDataSize(), &buffer);
    return &buffer[0];
}
void SymEncPacket::onReceive (const void* data, size_t dataSize) {
    char* buffer = NULL;
    int newDataSize = AES_ENC::decrypt(static_cast<const char*> (data), dataSize, &buffer);
    append(&buffer[0], newDataSize);
}
 

La classe client qui se charge d'établir une connexion sécurisée entre un client et un serveur du framework et d'envoyer des message sur le réseau :

#include "client.h"
#include "network.h"
using namespace sf;
using namespace std;
SrkClient::SrkClient () {
    running = false;
    selectedCanal = 0;
    remotePortUDP = 4568;


}
void SrkClient::setSelectedCanal (int canal) {
    this->selectedCanal = canal;
}
int SrkClient::getSelectedCanal () {
    return selectedCanal;
}
void SrkClient::getPublicKey () {

    string message = "GetPbKeyRsa";
    Network::sendTCPMessage(message);
    bool done, pbKeyRsaReceived;
    done = pbKeyRsaReceived = false;
    Packet packet;
    EncryptedPacket enc_packet;
    while (!done || !pbKeyRsaReceived) {
        if (!pbKeyRsaReceived) {
            if (clientTCP.receive(packet) == Socket::Done) {
                string message;
                packet>>message;
                Network::setPbKey(message);
                pbKeyRsaReceived = true;
                message = "GetPbKey";
                Network::sendTCPMessage(message);
            }
        } else if (pbKeyRsaReceived && !done) {
            if (clientTCP.receive(enc_packet) == Socket::Done) {
                string message;
                enc_packet>>message;
                Network::setSymPbKey(string(message));
                done = true;
            }
        }
    }
}
bool SrkClient::startCli(int portTCP, int portUDP, IpAddress adress) {

    if (!running) {
        if (clientUDP.bind(portUDP) != Socket::Done) {
            cout<<"Erreur : impossible d'écouter sur le port : "<<portUDP<<endl;
            return false;
        }
        if(clientTCP.connect(adress, portTCP) != Socket::Done) {
            cout<<"Erreur : impossible de se connecter au serveur!"<<endl;
            return false;
        } else {
            cout<<"Client started!"<<endl;

            m_thread = thread (&SrkClient::run, this);
            return true;
        }
    } else {
        cout<<"Client already started!"<<endl;
        return false;
    }
}
void SrkClient::stopCli() {
    if(running) {
        running = false;
        m_thread.join();
    } else {
        cout<<"Client already stopped"<<endl;
    }
}
void SrkClient::sendTCPMessage(Packet &packet) {
    lock_guard<recursive_mutex> locker(rec_mutex);
    if(clientTCP.send(packet) != Socket::Done)
        cout<<"Erreur!"<<endl;
}
void SrkClient::sendUDPMessage(Packet &packet) {
    lock_guard<recursive_mutex> locker(rec_mutex);
    if(clientUDP.send(packet, Configuration::serverAddress, remotePortUDP) != Socket::Done)
        cout<<"Erreur!"<<endl;
}
bool SrkClient::isRunning () {
    return running;
}
void SrkClient::run() {
    SymEncPacket packet;
    running = true;
    getPublicKey();
    short unsigned int port;
    IpAddress address;
    selector.add(clientTCP);
    selector.add(clientUDP);

    while (running) {
        if (selector.wait(seconds(10))) {
            lock_guard<recursive_mutex> locker(rec_mutex);
            if (selector.isReady(clientTCP)) {
                packet.clear();
                if(clientTCP.receive(packet) == Socket::Done) {

                    string message;
                    packet>>message;
                    Network::addResponse(message);

                }
            }
            if (selector.isReady(clientUDP)) {
                packet.clear();
                if (clientUDP.receive(packet, address, port) == Socket::Done) {

                    if (address == Configuration::serverAddress) {
                        string message;
                        packet>>message;
                        Network::addResponse(message);
                        remotePortUDP = (remotePortUDP != port) ? port : remotePortUDP;
                    } else {
                        cout<<"This message don't provide from the server."<<endl;
                    }

                }
            }
        }
    }
}

 

Et enfin, la classe Network qui permettra de récupérer tout les messages renvoyé par le serveur, et d'envoyer des messages au serveur :

#include "network.h"

using namespace sf;
using namespace std;
SrkClient& Network::cli = Network::getCliInstance();
Clock Network::clock = Clock();
vector<string> Network::messages = vector<string>();
Time Network::timeOut = seconds(3.f);
bool Network::startCli (int portTCP, int portUDP, IpAddress address) {

    return cli.startCli(portTCP, portUDP, address);
}
void Network::changeClientChannel(int channel) {
    cli.setSelectedCanal(channel);
}
int Network::getClientChannel () {
    return cli.getSelectedCanal();
}
void Network::stopCli () {
    cli.stopCli ();
}
void Network::addResponse(string message) {

    messages.push_back(message);
}
void Network::sendTCPMessage (string message) {
    if (message == "GetPbKeyRsa") {
        Packet packet;
        packet<<message;
        cli.sendTCPMessage(packet);

    } else if (message == "GetPbKey") {
        EncryptedPacket packet;
        packet<<message;
        cli.sendTCPMessage(packet);
    } else {
        SymEncPacket packet;
        packet<<message;
        cli.sendTCPMessage(packet);
    }
}
void Network::sendUDPMessage(string message) {
   SymEncPacket packet;
   packet<<message;
   cli.sendUDPMessage(packet);
}
bool Network::getResponse(string tag, string &response) {
    vector<string>::iterator it;
   //globalMutex->lock();
    for (it = messages.begin(); it != messages.end();) {

        if (it->find(tag) != string::npos) {
            response = *it;
            it = messages.erase(it);
            return true;
        } else {
            it++;
        }
    }
   // globalMutex->unlock();
    return false;
}
bool Network::hasResponse() {
    return messages.size() != 0;
}
string Network::getLastResponse () {
    string response = "";
    clock.restart();
    vector<string>::iterator it;

    while (response == "" && clock.getElapsedTime().asSeconds() < timeOut.asSeconds()) {
        if (messages.size() > 0) {
            it = messages.begin();
            response = *it;
            it = messages.erase(it);
        }
    }
    return response;
}
string Network::waitForLastResponse(string tag) {
    string response = "";
    clock.restart();
    vector<string>::iterator it;
    //globalMutex->lock();
    while (response == "" && clock.getElapsedTime().asSeconds() < timeOut.asSeconds()) {
        if (messages.size() > 0) {
            for (it = messages.begin(); it != messages.end();) {
                if (it->find(tag) != string::npos) {
                    response = *it;
                    it = messages.erase(it);
                    return response;
                } else {
                    it++;
                }
            }
        }
    }
    //globalMutex->unlock();
    return response;
}
void Network::setPbKey (string message) {
    Rsa::setCertificate(reinterpret_cast<const unsigned char*>(message.c_str()), message.length());
}
void Network::setSymPbKey (string pbKey) {
    vector<string> parts = split(pbKey, "-");
    AES_ENC::setKey(const_cast<char*>(parts[0].c_str()));
    AES_ENC::setIv(const_cast<char*>(parts[1].c_str()));
}
 


Cmdu76

  • Full Member
  • ***
  • Messages: 194
    • Voir le profil
Re : Framework
« Réponse #16 le: Décembre 02, 2013, 12:42:14 pm »
Je suis en cours mais j'ai fait une liste des "systèmes" qu'un framework devrait posséder. Je posterais un .txt les listant ce soir

J'ai réfléchit et ce que je vais faire je vais push les classes de mon projet perso ensuite on va faire un bon gros tri.

Il faut que toutes nos classes soient comprises dans le namespace sfgl

Et oui le fait d'être dépendant de boost je trouve pas ça vraiment top... surtout que C++11 intègre beaucoup des fonctionnalités de boost :)

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Framework
« Réponse #17 le: Décembre 02, 2013, 01:15:04 pm »
Citer
Et oui le fait d'être dépendant de boost je trouve pas ça vraiment top... surtout que C++11 intègre beaucoup des fonctionnalités de boost :)

Ha oui, le c++11 intègre aussi la fonction tokenizer de boost ???
vector<string> split (const string &chaine, const string &separators) {
    vector<string> sousChaines;
    typedef boost::tokenizer<boost::char_separator<char> > myTok;
    boost::char_separator<char> sep(separators.c_str());
    myTok tok (chaine, sep);
    for (myTok::const_iterator it = tok.begin(); it != tok.end(); ++it) {
        sousChaines.push_back(*it);
    }
    return sousChaines;
}
 

Si oui bah je vais pouvoir enlever la dépendance de boost. :) (Ce qui me ferai en effet plaisir car moins il y a de dépendances plus simple ça sera pour l'installation)

A part ça, j'ai commencé à rédigé un petit tutoriel sur ce site :
http://www.jeux-libres.com/tutoriaux/tuto-679-chapitre-introduction-et-installation-de-sfgl.php

Qui illustre déjà un peu le principe de base.




« Modifié: Décembre 02, 2013, 01:17:49 pm par Lolilolight »

Cmdu76

  • Full Member
  • ***
  • Messages: 194
    • Voir le profil
Re : Framework
« Réponse #18 le: Décembre 02, 2013, 02:35:42 pm »
Pas mal le tutoriel, mais je trouve que l'utilisation est plutôt "brouillon"...

Aussi utilse les std::shared_ptr, c'est beaucoup plus safe :)

Liste de modules :
- Resources
- Graphismes
- Input
- States
- Gui
- Audio
- Network
- Errors
- Maths
- Files
- Application
- Physique
- Collisions
- Gameplay
- String
- Paramètres
- Surcouche
- Scripts
- XML
- SQL
- ...

Lo-X

  • Hero Member
  • *****
  • Messages: 618
    • Voir le profil
    • My personal website, with CV, portfolio and projects
Re : Framework
« Réponse #19 le: Décembre 02, 2013, 03:19:39 pm »
Salut,

Alors déjà merci de citer Potato dans la liste, ça fait toujours plaisir :)

Je suis un peu en retard dans la conversation, mais puisque tu le demande, voici des précisions sur mes frameworks.

Le plus vieux, Engenesis, n'est plus du tout à jour. Je débutais et je ne re-ferai plus rien de la même manière maintenant. Je le garde sur GitHub parce que j'ai pas le coeur à le supprimer, mais il ne faut pas aller le voir :p

Potato est un peu plus récent et se base beaucoup sur le livre "SFML Game Development" (que je recommande à tous une fois de plus).
Je ne l'ai pas mis à jour depuis quelques temps (enfin sur GitHub), mais j'ai une partie réseau, quelques ajouts et modifications à commiter une fois que ce sera propre. Cependant, Binary1259 sur le forum anglais m'a pris de cours en publiant son framework réseau, qui semble vraiment vraiment très bien, alors je vais peut-être utiliser sa lib plutôt que de refaire des choses. Néanmoins mon framework devrait être une bonne base, si tant est que vous êtes un peu débrouillard (y'a pas de doc).


Concernant la collaboration, j'aimerais dire que j'y participerai, la vérité c'est que je ne sais pas si j'aurai vraiment le temps. J'ai déjà pas le temps pour mes frameworks/jeux.
De plus je suis assez d'accord avec Laurent, personnellement ce que je publie sur GitHub c'est surtout de l'essai ou de l'apprentissage, je ne prétends pas être apte à créer une lib. Mais c'est fun, apprendre avec ce genre de projet c'est fun. Passer sur quelque chose de plus sérieux, ça l'est moins.

Donc, pour le moment, je ne sais pas. Il faut voir, s'il y a de bonnes idées. Je suivrai le projet de près bien sur, pourquoi pas faire un fork et y ajouter ma pierre. Mais je ne pense pas pouvoir faire partie des "fondateurs"

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Framework
« Réponse #20 le: Décembre 02, 2013, 03:30:30 pm »
Citer
Pas mal le tutoriel, mais je trouve que l'utilisation est plutôt "brouillon"...

Aussi utilse les std::shared_ptr, c'est beaucoup plus safe :)

Je ne connais pas encore toutes les fonctionnalités du c++11 car ça n'existait pas encore quand j'ai commencé le framework donc je dois en effet faire quelques modifs encore.

Pour le peu que je sache comment les mécanismes du c++11 fonctionne. :) (Et si c'est encore en expérimental ou pas)

Citer
Liste de modules :
- Resources
- Graphismes
- Input
- States
- Gui
- Audio
- Network
- Errors
- Maths
- Files
- Application
- Physique
- Collisions
- Gameplay
- String
- Paramètres
- Surcouche
- Scripts
- XML
- SQL
- ...
Ca me semble faire un peu beaucoup de modules différents là. (Sachant qu'il faut tous les linker au projet j'aimerais n'en faire que 10 grand max)

Bref je vais m'amuser un peu en testant les shared_ptr et les std::array. :D

Le projet est en effet assez sérieux. (Mais même dans les projets sérieux, sans fun on y arrive pas)
« Modifié: Décembre 02, 2013, 03:34:05 pm par Lolilolight »

Cmdu76

  • Full Member
  • ***
  • Messages: 194
    • Voir le profil
Re : Framework
« Réponse #21 le: Décembre 02, 2013, 04:14:29 pm »
Lolilolight,
Honnêtement dans la liste des modules, la plupart ne sont pas si complexe que ça.  Mon framework actuel les couvrent plus ou moins, mais après pour certains c'est clair que je ne suis pas tout à fait à l'aise... Genre la partie graphique :)

Je vais fork le github et poster mes modules dès ce soir

Lo-x
La plupart de mes modules sont très fortement inspiré du SFML Game Development que tu recommandes.
Par contre, l'EntitySyteme que tu mentionnes sur ton devblog me paraît vraiment bien, et je ne comprends pas pourquoi tu dis que "tu ne referais pas de la même manière" ? Ton EntitySyteme sur Engenesis est-il obsolète ?

En tout n'hésite pas, le but du projet est de réunir un maximum de monde, peu importe la quantité,  c'est surtout la qualité qui est importante et qui fera qu'on sera utilisé,  ensuite les gens soumettront eux-même des améliorations (comme pour SFML) et qui viendront grossir petit à petit le projet :)

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Framework
« Réponse #22 le: Décembre 02, 2013, 04:41:13 pm »
Ok bah rien ne t'empêche de rajouté tes modules, pas de soucis. :)

Je regarderai tout ça.

PS : j'ai essayé l'équivalent de boost avec c++11 mais mon compilateur ne le prend pas.
Est ce que std::sregex_token_iterator n'a pas encore été implémenté dans ma version actuelle que j'ai de mingw ?

Bref si c'est le cas dans une version futur de toute façon on pourra très bien se passer de boost.
Mais je pense que je vais l'utiliser en attendant que je trouve une version de mingw qui implémente ça.

Je ne sais pas non plus si le c++11 permet de faire l'équivalent de ce que fait boost::any et boost::variant.
« Modifié: Décembre 02, 2013, 04:46:19 pm par Lolilolight »

Lo-X

  • Hero Member
  • *****
  • Messages: 618
    • Voir le profil
    • My personal website, with CV, portfolio and projects
Re : Re : Framework
« Réponse #23 le: Décembre 02, 2013, 04:46:38 pm »
Par contre, l'EntitySyteme que tu mentionnes sur ton devblog me paraît vraiment bien, et je ne comprends pas pourquoi tu dis que "tu ne referais pas de la même manière" ? Ton EntitySyteme sur Engenesis est-il obsolète ?

J'aime beaucoup le principe des entity-system et entity-components, mais :

1) Il faut en avoir besoin, typiquement sur un petit jeu, je pense que c'est se prendre la tête pour rien.
1.bis) Du coup, dans un framework, c'est difficile. Soit tu force l'utilisateur à choisir un ES ou une hiérarchie objet, soit tu trouves un moyen de proposer les deux (j'aimerai trouver cette solution, j'ai jamais eu d'assez bonne idée).
2) ça varie beaucoup d'un programmeur à l'autre (et pour moi même d'un mois à l'autre). Je lis régulièrement des articles dessus, à chaque fois je trouve que la façon de faire est meilleure ou que des choses sont à reprendre

Alors je ne sais plus ce que j'ai utilisé dans Engenesis (et du coup sur mon blog), je sais juste qu'étant donné  le temps qui s'est passé depuis la dernière mise à jour, j'ai du apprendre suffisamment de nouveautés pour ne plus le faire de la même manière.

Le top, dans mes frameworks et peut-être aussi dans celui que tu veux faire, serai d'intégrer un ES avec ce qu'on tire du bouquin, mais en laissant le choix à l'utilisateur de ne pas l'utiliser. (y'a du boulot :p )

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Framework
« Réponse #24 le: Décembre 02, 2013, 05:04:27 pm »
Citer
Le top, dans mes frameworks et peut-être aussi dans celui que tu veux faire, serai d'intégrer un ES avec ce qu'on tire du bouquin, mais en laissant le choix à l'utilisateur de ne pas l'utiliser. (y'a du boulot :p )

C'est justement ce que je voudrais faire. :P

Laisser le choix à l'utilisateur d'utiliser l'ES du framework ou bien de ne pas l'utiliser. (Car pour les petits jeux utiliser juste SFML est en effet suffisant)

Mais comme tu l'as dis il faut de bonnes idées et il y a du boulot. :P
« Modifié: Décembre 02, 2013, 05:07:16 pm par Lolilolight »

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Framework
« Réponse #25 le: Décembre 02, 2013, 05:57:25 pm »
Sinon, je ne sais pas si tu as bien regardé les sources que j'ai mises sur github mais on est pas obligé de passer par l'entité système du framework, pour les plus petits jeux, comme le framework est compatible SFML, on peut dessiner directement des entités SFML de base (des sf::Sprite, des sf::ConvexShape, etc...) sans passer par les classes Entity qui se trouvent dans le module "graphics" du framework. :)

Hors les autres framework comme Irrlicht par exemple pour la 3D, je ne pense pas qu'ils permettent de faire ça.

Mais ici comme le framework se veut être utilisé par le plus de personnes possible, je ne veux rien imposer comme architecture (aussi bien au niveau du développement que au niveau de la 2D et de la 3D), donc on pourra aussi bien l'utiliser pour des jeux en 2D et en 3D, pour des petits jeux ou des jeux plus complexes, etc...
De plus je ne compte pas imposer de système pour remettre à jour les entités avec un thread, mais j'en fournirai peut être un dans le framework déjà fait histoire que l'utilisateur aie un exemple, mais, j'ai envie aussi de laisser le soin à l'utilisateur d'orchestrer tout ça un peu comme il le veut.
Je ne compte donc pas imposer une standardisation dont la plupart n'auront pas besoin et que ça sera finalement trop complexe pour eux à utiliser.

Donc voilà. :)

Par exemple dans le framework rien n'empêchera l'utilisateur de coder sa propre classe light si il a une autre idée, vu que le but est de justement rassembler des idées.
Il devra juste bien sûr redéfinir la fonction draw un peu comme dans les tutoriels de SFML, le framework fonctionne presque exactement comme SFML vu qu'il utilise SFML et n'impose pas d'entity system tout comme SFML.

Il faudra juste hériter des classes transformable et dessinable du framework et non plus de celles de SFML..., car, on ne peut ajouté que des entités du framework au monde, ce qui me semble logique.
Mais encore une fois l'utilisateur pourrait très bien coder son propre conteneur pour stocker ses entités, la classe World et la classe Map du framework sont juste une surcouche offerte par le framework.

Par la suite je compte rajouté d'autres classes que la classe gridMap (une classe quadtree et une classe bsptree) et laissé le choix à l'utilisateur d'utiliser le conteneur qu'il veut.
La classe gridMap est juste un conteneur simple que j'ai utilisé pour mon propre jeux, même chose pour mon système de lumière, pour information je me suis basé sur le moteur de jeux de holyspirit que j'ai amélioré à ma façon pour le fun. :P

« Modifié: Décembre 02, 2013, 06:16:12 pm par Lolilolight »

Cmdu76

  • Full Member
  • ***
  • Messages: 194
    • Voir le profil
Re : Framework
« Réponse #26 le: Décembre 02, 2013, 09:04:21 pm »
Okay c'est bon je suis sur le PC, j'ajoute mes "modules" de suite (enfin je renomme tout d'abord et je les intègre dans le namespace)

Lolilolight,
Tu utilises bien MinGW 4.7.2 ? En tout cas moi c'est celui que j'ai actuellement. Je sais qu'il ne gère pas encore tout le C++11 mais il gère ce que j'utilise pour le moment c'est-à-dire principalement les pointeurs intelligents.

Lo-x,
Oui le top serait de fournir le choix du système. Je pense qu'il faudrait du coup une classe GraphicsSettings qui permettent de choisir entre 2D/3D et aussi de choisir le système d'entités. Après je sais pas si GraphicsSettings est réellement le bon nom car en disant Settings on peut penser aux paramètres que le joueur va choisir lui-même (même si je sais pas si ça fera partit du framework pour le moment...)
La meilleure façon de laisser le développeur choisir est de fournir des classes plus ou moins abstraites que le développeur n'a plus qu'à hériter dans une classe perso et du coup il choisit les entités qu'il veut.

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Framework
« Réponse #27 le: Décembre 02, 2013, 09:16:31 pm »
Citer
Okay c'est bon je suis sur le PC, j'ajoute mes "modules" de suite (enfin je renomme tout d'abord et je les intègre dans le namespace)

Lolilolight,
Tu utilises bien MinGW 4.7.2 ? En tout cas moi c'est celui que j'ai actuellement. Je sais qu'il ne gère pas encore tout le C++11 mais il gère ce que j'utilise pour le moment c'est-à-dire principalement les pointeurs intelligents.

Non j'utilise mingw 4.8.0 mais j'aimerais bien trouvé une version de mingw plus récente qui gère les regex afin de pouvoir me passer de boost, j'ai essayé de le mettre à jour via l'installeur qu'ils fournissent sur le site de sourceforge pour avoir la version 4.8.1 mais ça n'a pas marché. (Du fait que j'avais oublié de virer mon dossier de mingw avant d'installer le nouveau)

Donc je dois recommencer, je ferai ça demain.

Citer
La meilleure façon de laisser le développeur choisir est de fournir des classes plus ou moins abstraites que le développeur n'a plus qu'à hériter dans une classe perso et du coup il choisit les entités qu'il veut.

Ouais je ne vois pas d'autre façon de faire alors j'ai proposé quelques classes dans le framework dont le développeur pourra hérité et redéfinir quelques fonctions abstraites, il peut ainsi définir ces propres type d'entité grâce à la std::map que j'ai mis dans la classe Entity qui lie un type d'entité et un id pour chaque type d'entité.
D'ailleurs mon composant 'map" ne gère pas un ensemble de type d'entité bien précis, mais n'importe quel type d'entité qui hérite d'une des classes de graphisme de base du framework. (DrawableEntity, DynamicDrawableEntity, TexturedDynamicDrawableEntity, AnimatedEntity et EntityWithShadow si on veut que notre entité aie une ombre)

Mais il n'y aura pas plus d'héritage que ça, après, ce sera au développeur de choisir si il décide d'utiliser un entity système ou pas pour les monstres, les personnages, les armes, etc...

Le framework ne stocke que des entités graphiques, pour les autres type d'entités il n'y a pas vraiment besoin de faire d'optimisation spécifique à l'affichage vu qu'elle ne s'affichage pas.

Mais les classes ne sont pas encore complète vu que cet architecture est récente, dans la classe animation je devrai rajouté une interpolation linéaire pour les transformations sur les différents entités de l'animations.

Je compte aussi ajouté la possibilité de faire des entités animée avec des ombres. :) (Et donc de rajouter autre chose que de simple tiles pour les animations)

Bref j'ai encore du boulot.


Je dois encore aussi faire le chargement des fichiers .obj et l'interpolation linéaire pour les animations, (je compte utiliser les même technique pour la 2D et la 3D pour les animations, les collisions, etc... afin de simplifier l'utilisation du framework un maximum)

Donc en 3D la grille ne sera plus composée de polygônes mais de cubes.

Bref j'ai encore du boulot vu que je dois encore implémenté tout ça mais pour avoir facile je compte me baser sur les même technique que ce que j'ai utilisé pour la 2D et si il y a lieu j'optimiserai après pour la 3D.

Il me faut aussi faire les lampes en 3D, etc...
J'ai séparé tout ce qui concerne la 2D et la 3D dans 2 namespaces différent, tout ce qui concerne la 3D est dans le namespace sfgl::sfgl3f (ou un truc comme ça je sais plus le nom exact du namespace pour la 3D)

Mais je pense que je vais m'inspirer des sources du projet sf3 du forum Anglais.

PS : je crois que je vais aussi ajouté la possibilité de changer la matice de projection dans la classe gridMap pour que on puisse aussi créer des jeux en 2D pure et non en 2D iso.


 
« Modifié: Décembre 02, 2013, 09:38:28 pm par Lolilolight »

Cmdu76

  • Full Member
  • ***
  • Messages: 194
    • Voir le profil
Re : Framework
« Réponse #28 le: Décembre 02, 2013, 09:49:15 pm »
C'est bon la version actuelle de mon framework est commit !

Je dois juste re-vérifier que j'ai pas laissé d'erreurs dans les includes et ajuster toutes les implémentations.

Je vais aussi apporter quelques modifications à la version de mon framework.

Si tu veux voir un peu son fonctionnement, je te conseille https://github.com/Cmdu76/GameTest
car sur la version que j'ai postée tu as vraiment juste le framework. Mon projet GameTest montre les classes que tu dois refaire toi-même.

J'ai dit quelque part que ton projet était brouillon (j'espère que tu l'as pas mal pris :) ), ce que je voulais dire par là, c'est qu'il est très très complets et que je devrais mettre plusieurs jours afin de réellement comprendre tous tes concepts. Ensuite oui si tu utilises MinGW 4.8 tu as donc les pointeurs intelligents que tu n'utilises pas mais ça c'est pas le plus important pour le moment.
Ensuite ce code :

#include <iostream>
#include <SFGL/World/2D/world.h>
#include <SFGL/World/2D/tGround.h>
#include <SFGL/Graphics/2D/tile.h>
#include <SFGL/BoundingAreas/boundingRectangle.h>
using namespace sfgl;
using namespace std;
int main () {
    // création de la fenêtre
    sf::RenderWindow window(sf::VideoMode(800, 600), "My window");

    //On récupère la vue courrante pour la passer à sfgl plus tard.
    sf::View currentView = window.getView();

    TextureManager &tm = World::getTextureManager();
    Map *currentMap = new Map(100, 50, 30);
    World::addMap(currentMap);
    currentMap->setName("Map test");
    World::setCurrentMap("Map test");

    if (!tm.loadTexture("tilesets/herbe.png"))
        cerr<<"Error : file not found"<<endl;

    Tile *t = new Tile(*tm.getTexture("tilesets/herbe.png"), Vec2f(0, 0), Vec2f(100, 50), sf::IntRect(0, 0, 100, 50), "E_GROUND");

    TileGround *tg = new TileGround(t);
    currentMap->addEntity(tg);

    BoundingRectangle viewRect (0, 0, currentView.getSize().x, currentView.getSize().y);

    currentMap->checkVisibleEntities(viewRect);

    vector<DrawableEntity*> vEntities = currentMap->getVisibleEntities("E_GROUND");

    // on fait tourner le programme tant que la fenêtre n'a pas été fermée
    while (window.isOpen())
    {
        // on traite tous les évènements de la fenêtre qui ont été générés depuis la dernière itération de la boucle
        sf::Event event;
        while (window.pollEvent(event))
        {
            // fermeture de la fenêtre lorsque l'utilisateur le souhaite
            if (event.type == sf::Event::Closed)
                window.close();
        }
 
        // effacement de la fenêtre en noir
        window.clear(sf::Color::Black); /// Ici c'est du détail mais mettre la couleur à Black sert à rien sachant qur c'est la couleur par défaut :)
 
        // c'est ici qu'on dessine tout
        /// Ici on peut utiliser les itérateurs c'est plus otpimisés pour les conteneurs de la stl
        /// Et sinon on pourrait avoir une classe "EntitySystem" comme on en parle qui aurait juste une fonction draw()
        for (unsigned int i = 0; i < vEntities.size(); i++)
            window.draw(*vEntities[i]);
        // fin de la frame courante, affichage de tout ce qu'on a dessiné
        window.display();
    }
    /// Ici je vois pas pourquoi tu utilises cette fonction sachant que le texturemanager est sensé se vider seul ?
    tm.deleteTexture("tilesets/herbe.png");
    return 0;
 
}

me paraît rudement complexe aux premiers abords :)

EDIT : En fait après révision si on retire quelques optimisations en plus de celles que j'ai déjà repérée, et qu'on intègre ce système dans une classe (GameState ou World dans mon framework) on arrive à quelques choses d'un peu plus propre :)

Dans tous les cas, je pense que je vais te laisser t'occuper de la partie graphique :)
« Modifié: Décembre 02, 2013, 09:52:21 pm par Cmdu76 »

Cmdu76

  • Full Member
  • ***
  • Messages: 194
    • Voir le profil
Re : Framework
« Réponse #29 le: Décembre 02, 2013, 11:36:22 pm »
Bon c'est bon j'ai fini de mettre mon framework (j'y ai passé un temps fou pour tout mettre dans le namespace et enlever tous les "Cm" que j'avais mis devant les noms de classes...)

Donc faut qu'on fasse un tri je pense maintenant et qu'on réfléchisse à la meilleure architecture pour chaque module.

Afin que l'équipe réfléchisse ensemble, je viens de créer un serveur mumble gratuit (12 slots) :

- Nom : Simple&FastGameLibrary
- Adresse : srv22.mumblegratuit.com
- Port : 11924
- Password : sfgl

EDIT : J'ai failli oublier, pour ceux qui n'ont pas encore Mumble : http://www.mumblegratuit.com/index.php?rub=telecharger_mumble

Bon voilà, après je ne sais pas à quelle heure vous êtes connecté mais dans tous les cas parler de vive voix sera beaucoup plus pratique si l'on veut se mettre d'accord et s'organiser un peu plus correctement :)

(Petite parenthèse : On avait dit qu'un projet sans un minimum de fun ne marcherait pas, et honnêtement sans vocal ça me paraît compliqué :D)
« Modifié: Décembre 02, 2013, 11:38:48 pm par Cmdu76 »

 

anything