duck-hunt-ds

Duck Hunt clone for Nintendo DS
git clone https://git.neuralcrash.com/duck-hunt-ds.git
Log | Files | Refs | LICENSE

Programme.cpp (9282B)


      1 #include <cstdio>
      2 #include <fstream>
      3 #include <iostream>
      4 #include <map>
      5 #include <sstream>
      6 #include <vector>
      7 #include <PA9.h>
      8 #include <fat.h>
      9 #include "../gfx/all_gfx.h"
     10 #include "musique.h"
     11 #include "Programme.hpp"
     12 #include "Canard.hpp"
     13 
     14 
     15 Programme::Programme()
     16 {
     17 	// Initialisation de PAlib
     18 	PA_Init();
     19 
     20 	// Initialisation de la VBL
     21 	PA_InitVBL();
     22 
     23 	// Initialisation de l'écriture
     24 	PA_InitText(0, 0);
     25 	PA_InitText(1, 0);
     26 
     27 	// Initialisation du système de fichiers
     28 	fatInitDefault();
     29 
     30 	// Initialisation du système de sons
     31 	PA_VBLFunctionInit(AS_SoundVBL);
     32 	AS_Init(AS_MODE_MP3 | AS_MODE_SURROUND | AS_MODE_16CH);
     33 	AS_SetDefaultSettings(AS_PCM_8BIT, 11025, AS_SURROUND);
     34 
     35 	// Chargement des palettes de couleurs pour les sprites
     36 	PA_LoadSpritePal(0, 0, (void*)canard_Pal);
     37 	PA_LoadSpritePal(1, 0, (void*)canard_Pal);
     38 
     39 	// Chargement des sprites pour l'écran 0
     40 	PA_CreateSprite(0, 0, (void*)canard0_Sprite, OBJ_SIZE_32X32, 1, 0, 256, 256);
     41 	PA_CreateSprite(0, 1, (void*)canard1_Sprite, OBJ_SIZE_32X32, 1, 0, 256, 256);
     42 	PA_CreateSprite(0, 2, (void*)canard2_Sprite, OBJ_SIZE_32X32, 1, 0, 256, 256);
     43 	PA_CreateSprite(0, 3, (void*)canard3_Sprite, OBJ_SIZE_32X32, 1, 0, 256, 256);
     44 	PA_CreateSprite(0, 4, (void*)canard4_Sprite, OBJ_SIZE_32X32, 1, 0, 256, 256);
     45 	PA_CreateSprite(0, 5, (void*)canard5_Sprite, OBJ_SIZE_32X32, 1, 0, 256, 256);
     46 	PA_CreateSprite(0, 6, (void*)canard6_Sprite, OBJ_SIZE_32X32, 1, 0, 256, 256);
     47 	PA_CreateSprite(0, 7, (void*)canard7_Sprite, OBJ_SIZE_32X32, 1, 0, 256, 256);
     48 
     49 	// Chargement des sprites pour l'écran 1
     50 	PA_CreateSprite(1, 0, (void*)canard0_Sprite, OBJ_SIZE_32X32, 1, 0, 256, 256);
     51 	PA_CreateSprite(1, 1, (void*)canard1_Sprite, OBJ_SIZE_32X32, 1, 0, 256, 256);
     52 	PA_CreateSprite(1, 2, (void*)canard2_Sprite, OBJ_SIZE_32X32, 1, 0, 256, 256);
     53 	PA_CreateSprite(1, 3, (void*)canard3_Sprite, OBJ_SIZE_32X32, 1, 0, 256, 256);
     54 	PA_CreateSprite(1, 4, (void*)canard4_Sprite, OBJ_SIZE_32X32, 1, 0, 256, 256);
     55 	PA_CreateSprite(1, 5, (void*)canard5_Sprite, OBJ_SIZE_32X32, 1, 0, 256, 256);
     56 	PA_CreateSprite(1, 6, (void*)canard6_Sprite, OBJ_SIZE_32X32, 1, 0, 256, 256);
     57 	PA_CreateSprite(1, 7, (void*)canard7_Sprite, OBJ_SIZE_32X32, 1, 0, 256, 256);
     58 
     59 	// Lecture de la musique de d'ambience, en boucle
     60 	AS_MP3DirectPlay((u8*)musique, (u32)musique_size);
     61 	AS_SetMP3Loop(1);
     62 
     63 	// Initialisation des variables
     64 	m_iScore = 0;
     65 	m_iNumRound = 1;
     66 	m_iNbCanardsTues = 0;
     67 	m_iNbCanardsTuesRound = 0;
     68 	m_iNbBalles = 0;
     69 }
     70 
     71 void Programme::EcranTitre() const
     72 {
     73 	PA_ClearTextBg(0);
     74 	PA_ClearTextBg(1);
     75 
     76 	PA_EasyBgLoad(0, 1, background2);
     77 	PA_EasyBgLoad(1, 1, background2);
     78 
     79 	// Affichage de l'écran titre
     80 	PA_OutputText(0, 10, 9, "Duck Hunt DS");
     81 	PA_OutputText(0, 1, 13, "Touchez l'écran pour commencer");
     82 
     83 	PA_OutputText(1, 0, 0, "Nom"); // Nom
     84 	PA_OutputText(1, 16, 0, "Score"); // Score
     85 	PA_OutputText(1, 24, 0, "Canards"); // Canards
     86 	PA_OutputText(1, 0, 1, "--------------------------------");
     87 
     88 	std::ifstream Fichier;
     89 	std::string Nom, Score, NbCanards;
     90 
     91 	// Clé : Score, Valeur : <Nom, NbCanards>
     92 	std::multimap<std::string, std::pair<std::string, std::string> > Scores;
     93 
     94 	// Lecture du fichier des scores
     95 	Fichier.open("DuckHuntDS.csv");
     96 
     97 	// Si le fichier éxiste
     98 	if (!Fichier.fail())
     99 	{
    100 
    101 		while (!Fichier.eof())
    102 		{
    103 			getline(Fichier, Nom, ';');
    104 			getline(Fichier, Score, ';');
    105 			getline(Fichier, NbCanards);
    106 
    107 			if (Nom != "" && Score != "" && NbCanards != "")
    108 				Scores.insert(std::make_pair(Score, std::make_pair(Nom, NbCanards)));
    109 		}
    110 
    111 		Fichier.close();
    112 	}
    113 
    114 	// Affichage des scores
    115 	std::multimap<std::string, std::pair<std::string, std::string> >::const_iterator it;
    116 	int i = 2;
    117 
    118 	for (it = Scores.end(); it != Scores.begin();)
    119 	{
    120 		it--;
    121 		PA_OutputText(1, 0, i, it->second.first.c_str()); // Nom
    122 		PA_OutputText(1, 16, i, it->first.c_str()); // Score
    123 		PA_OutputText(1, 24, i, it->second.second.c_str()); // Canards
    124 		i++;
    125 
    126 		if (i > 21)
    127 			break;
    128 	}
    129 
    130 	// On attend que le joueur touche l'écran
    131 	PA_WaitFor(Stylus.Newpress);
    132 
    133 	PA_ClearTextBg(0);
    134 	PA_ClearTextBg(1);
    135 
    136 	return;
    137 }
    138 
    139 void Programme::Partie()
    140 {
    141 
    142 	// Nouvelle partie : on réinitialise les variables
    143 	m_iScore = 0;
    144 	m_iNumRound = 1;
    145 	m_iNbCanardsTues = 0;
    146 	m_iNbCanardsTuesRound = 0;
    147 	m_iNbBalles = 0;
    148 
    149 	int iNbCanards;
    150 
    151 	PA_EasyBgLoad(0, 1, background0);
    152 	PA_EasyBgLoad(1, 1, background1);
    153 
    154 	do
    155 	{
    156 		// Nombre de canards lachés par Round
    157 		iNbCanards = (((m_iNumRound - 1) / 5) + 1) * NB_LACHE_PAR_ROUND;
    158 		m_iNbCanardsTuesRound = 0;
    159 
    160 		Round();
    161 
    162 		m_iNumRound++;
    163 	}
    164 	while (m_iNbCanardsTuesRound > iNbCanards / 2);
    165 
    166 	// Fin de partie
    167 	// Le jouer tape sont nom
    168 
    169 	PA_InitKeyboard(1);
    170 	PA_KeyboardIn(32, 64);
    171 
    172 	char c = 'A';
    173 	std::string name;
    174 
    175 	while(c != '\n')
    176 	{
    177 		c = PA_CheckKeyboard();
    178 
    179 		if (c > 31)
    180 		{
    181 			name += c;
    182 		}
    183 
    184 		else if (c == PA_BACKSPACE)
    185 		{
    186 			name.erase(name.end() - 1);
    187 		}
    188 
    189 		PA_ClearTextBg(0);
    190 		PA_OutputText(0, 0, 0, "Veuillez taper votre nom :");
    191 		PA_OutputText(0, 0, 1, "%s", name.c_str());
    192 
    193 		PA_WaitForVBL();
    194 	}
    195 
    196 	std::ofstream Fichier;
    197 	Fichier.open("DuckHuntDS.csv", std::ios::app);
    198 	Fichier << name << ';' << ToString(m_iScore) << ';' << ToString(m_iNbCanardsTues) << std::endl;
    199 	Fichier.close();
    200 }
    201 
    202 void Programme::Round()
    203 {
    204 	int iNbCanards = ((m_iNumRound - 1) / 5) + 1;
    205 
    206 	PA_ClearTextBg(0);
    207 	PA_ClearTextBg(1);
    208 
    209 	// Affichage des informations de la partie sur l'écran du haut
    210 	AfficherInformations();
    211 
    212 	PA_OutputText(0, 11, 11, "Round %d", m_iNumRound);
    213 
    214 	Attendre(2);
    215 
    216 	for (int i = 0; i != NB_LACHE_PAR_ROUND; i++)
    217 	{
    218 		LacheCanards(iNbCanards);
    219 	}
    220 
    221 }
    222 
    223 // Effectue un laché de iNbCanards canards
    224 // Les fait bouger et les affiche
    225 // En attendant que tous les canards soient, soit envolés, soit tués
    226 void Programme::LacheCanards(int iNbCanards)
    227 {
    228 	bool estEnvole;
    229 	int iNbCanardsEnvoles = 0;
    230 	m_iNbBalles = iNbCanards + 2;
    231 
    232 	// Vecteur contenant nos canards
    233 	std::vector<Canard *> lesCanards(iNbCanards);
    234 	std::vector<Canard *>::iterator it;
    235 
    236 	int leId = 8;
    237 
    238 	// Initilisation des canards
    239 	for (it = lesCanards.begin(); it != lesCanards.end(); it++, leId++)
    240 	{
    241 		// Les coordonnées du canards sont choisient aléatoirement dans le constructeur
    242 		*it = new Canard(leId);
    243 	}
    244 
    245 	// Tant qu'il reste des canards en jeux
    246 	while (iNbCanards > 0)
    247 	{
    248 		PA_ClearTextBg(0);
    249 		PA_ClearTextBg(1);
    250 
    251 		if (m_iNbBalles == 0)
    252 		{
    253 			PA_OutputText(0, 8, 11, "Plus de balles");
    254 		}
    255 
    256 		// Affichage des informations de la partie sur l'écran du haut
    257 		AfficherInformations();
    258 
    259 		// Déplacement et affichage des 
    260 		for (it = lesCanards.begin(); it != lesCanards.end(); it++)
    261 		{
    262 			estEnvole = (*it)->getEstEnvole();
    263 			(*it)->Bouger();
    264 			(*it)->Afficher();
    265 
    266 			// Si le canard viens de s'envolé
    267 			if (!estEnvole && (*it)->getEstEnvole())
    268 			{
    269 				iNbCanards--;
    270 				iNbCanardsEnvoles++;
    271 			}
    272 
    273 		}
    274 
    275 		// Si le joueur a tiré
    276 		if (Stylus.Newpress && m_iNbBalles > 0)
    277 		{
    278 			// On enregistre les coordonnées du tire
    279 			int iTireX = Stylus.X;
    280 			int iTireY = Stylus.Y;
    281 
    282 			// On décrémente le nombre de balles
    283 			m_iNbBalles--;
    284 
    285 			// On parcours tous les canards
    286 			for (it = lesCanards.begin(); it != lesCanards.end(); it++)
    287 			{
    288 
    289 				// Si le canard est touché par ce tire
    290 				if ((*it)->Tirer(iTireX, iTireY))
    291 				{
    292 					iNbCanards--;
    293 					m_iNbCanardsTues++;
    294 					m_iNbCanardsTuesRound++;
    295 					m_iScore += 200 - (*it)->getSonTick();
    296 					break;
    297 				}
    298 
    299 			}
    300 
    301 		}
    302 
    303 		// Pause
    304 		else if (Pad.Newpress.Start)
    305 		{
    306 			PA_ClearTextBg(0);
    307 			PA_OutputText(0, 11, 11, "Pause");
    308 			PA_WaitForVBL();
    309 
    310 			while (!Pad.Newpress.Start)
    311 			{
    312 				PA_WaitForVBL();
    313 			}
    314 
    315 			PA_ClearTextBg(0);
    316 		}
    317 
    318 		PA_WaitForVBL();
    319 	}
    320 
    321 	// Il n'y a plus de canards à tuer
    322 	// Fin du laché de canards
    323 
    324 	PA_ClearTextBg(0);
    325 	PA_ClearTextBg(1);
    326 
    327 	// Affichage des informations de la partie sur l'écran du haut
    328 	AfficherInformations();
    329 
    330 	// Si tous les canards n'ont pas été tués
    331 	if (iNbCanardsEnvoles != 0)
    332 	{
    333 
    334 		if (iNbCanardsEnvoles == 1)
    335 		{
    336 			PA_OutputText(0, 11, 10, "Un canard");
    337 			PA_OutputText(0, 9, 12, "s'est échappé");
    338 		}
    339 
    340 		else
    341 		{
    342 			PA_OutputText(0, 10, 10, "Des canards");
    343 			PA_OutputText(0, 7, 12, "se sont échappés");
    344 		}
    345 
    346 	}
    347 
    348 	// Si tous les canards ont été tués
    349 	else
    350 	{
    351 		int i = rand() % 3;
    352 
    353 		switch (i)
    354 		{
    355 			case 0:
    356 				PA_OutputText(0, 12, 11, "Bravo!");
    357 				break;
    358 			case 1:
    359 				PA_OutputText(0, 8, 11, "Félicitations!");
    360 				break;
    361 			case 2:
    362 				PA_OutputText(0, 10, 11, "Bien joué!");
    363 				break;
    364 		}
    365 
    366 	}
    367 
    368 	for (int i = 0; i < 120; i++, PA_WaitForVBL())
    369 	{
    370 
    371 		for (it = lesCanards.begin(); it != lesCanards.end(); it++)
    372 		{
    373 			(*it)->Bouger();
    374 			(*it)->Afficher();
    375 		}
    376 
    377 	}
    378 
    379 	// Destruction des canards
    380 	for (it = lesCanards.begin(); it != lesCanards.end(); it++)
    381 	{
    382 		delete *it;
    383 	}
    384 
    385 	return;
    386 }
    387 
    388 // Affiche les informations de la partie en cours sur l'écran du haut
    389 void Programme::AfficherInformations() const
    390 {
    391 	PA_OutputText(1, 0, 0, "Round %d", m_iNumRound);
    392 	PA_OutputText(1, 0, 2, "%d balles restantes", m_iNbBalles);
    393 	PA_OutputText(1, 0, 4, "%d canards tués", m_iNbCanardsTues);
    394 	PA_OutputText(1, 0, 6, "Score : %d", m_iScore);
    395 }
    396 
    397 void Programme::Attendre(double dNbSec)
    398 {
    399 
    400 	for (int i = 0; i < (dNbSec * 60); i++)
    401 	{
    402 		PA_WaitForVBL();
    403 	}
    404 
    405 	return;
    406 }
    407 
    408 std::string Programme::ToString(int valeur)
    409 {
    410 	// créer un flux de sortie
    411 	std::ostringstream oss;
    412 	// écrire un nombre dans le flux
    413 	oss << valeur;
    414 	// récupérer une chaîne de caractères
    415 	return oss.str();
    416 }
    417