Compare commits
11 Commits
b4e76a4c7d
...
v1.0
| Author | SHA1 | Date | |
|---|---|---|---|
| 3a3182fc74 | |||
| 5098ed1638 | |||
| f63ff07397 | |||
| 58f9841f71 | |||
| fd1fc0b582 | |||
| 770b06f2da | |||
| 33ad51e1c2 | |||
| 0a16c1cd0e | |||
| e8406c87b0 | |||
| ca5adf9433 | |||
| e753f6fbdb |
5
.gitignore
vendored
5
.gitignore
vendored
@@ -1,4 +1,5 @@
|
||||
.DS_store
|
||||
.vscode
|
||||
super_pang_clone
|
||||
bin
|
||||
super_pang_clone*
|
||||
bin/*
|
||||
info.plist*
|
||||
10
Makefile
10
Makefile
@@ -2,14 +2,10 @@ executable = super_pang_clone
|
||||
source = source/*.cpp
|
||||
|
||||
windows:
|
||||
@echo off
|
||||
if not exist bin\ (mkdir bin)
|
||||
g++ $(source) -std=c++11 -Wall -O2 -lmingw32 -lSDL2main -lSDL2 -lSDL2_image -lSDL2_mixer -ffunction-sections -fdata-sections -Wl,--gc-sections -static-libstdc++ -Wl,-subsystem,windows -o $(executable).exe
|
||||
g++ $(source) -std=c++11 -Wall -O2 -lmingw32 -lSDL2main -lSDL2 -ffunction-sections -fdata-sections -Wl,--gc-sections -static-libstdc++ -Wl,-subsystem,windows -o $(executable).exe
|
||||
strip -s -R .comment -R .gnu.version $(executable).exe --strip-unneeded
|
||||
macos:
|
||||
mkdir -p bin
|
||||
g++ $(source) -std=c++11 -Wall -O2 -lSDL2 -lSDL2_image -lSDL2_mixer -ffunction-sections -fdata-sections -o $(executable)_macos
|
||||
g++ $(source) -std=c++11 -Wall -O2 -lSDL2 -ffunction-sections -fdata-sections -o $(executable)_macos
|
||||
linux:
|
||||
mkdir -p bin
|
||||
g++ $(source) -std=c++11 -Wall -Os -lSDL2 -lSDL2_image -lSDL2_mixer -ffunction-sections -fdata-sections -Wl,--gc-sections -o $(executable)_linux
|
||||
g++ $(source) -std=c++11 -Wall -Os -lSDL2 -ffunction-sections -fdata-sections -Wl,--gc-sections -o $(executable)_linux
|
||||
strip -s -R .comment -R .gnu.version $(executable)_linux --strip-unneeded
|
||||
@@ -78,6 +78,11 @@ void Bullet::init(int x, int y, int kind)
|
||||
break;
|
||||
|
||||
default:
|
||||
// Establece la velocidad inicial
|
||||
mVelX = 0;
|
||||
|
||||
// Rectangulo con los gráficos del objeto
|
||||
mSprite.setSpriteClip(0 * mWidth, 0, mSprite.getWidth(), mSprite.getHeight());
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,118 +31,60 @@ GameDirector::GameDirector(SDL_Renderer *gRenderer)
|
||||
{
|
||||
this->gRenderer = gRenderer;
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
// Destructor
|
||||
GameDirector::~GameDirector()
|
||||
{
|
||||
// Libera los efectos de sonido
|
||||
Mix_FreeChunk(gPopBalloonFX);
|
||||
Mix_FreeChunk(gBulletFX);
|
||||
gPopBalloonFX = NULL;
|
||||
gBulletFX = NULL;
|
||||
|
||||
// Libra la música
|
||||
Mix_FreeMusic(gTitleMusic);
|
||||
gTitleMusic = NULL;
|
||||
Mix_FreeMusic(gPlayingMusic);
|
||||
gPlayingMusic = NULL;
|
||||
|
||||
// Libera el mando
|
||||
SDL_JoystickClose(gGameController);
|
||||
gGameController = NULL;
|
||||
|
||||
// Libera texturas
|
||||
gGameBackgroundTexture->free();
|
||||
gTitleBackgroundTexture->free();
|
||||
gWhiteFontTexture->free();
|
||||
gBlackFontTexture->free();
|
||||
gMiscTexture->free();
|
||||
|
||||
// Libera objetos
|
||||
delete player;
|
||||
delete menuPause;
|
||||
delete menuTitle;
|
||||
|
||||
for (Uint8 i = 0; i < mMaxBalloons; i++)
|
||||
mMaxBalloons = 50;
|
||||
for (int i = 0; i < mMaxBalloons; ++i)
|
||||
{
|
||||
if (balloon[i])
|
||||
{
|
||||
delete balloon[i];
|
||||
}
|
||||
balloon[i] = new Balloon(gRenderer);
|
||||
}
|
||||
|
||||
for (int i = 0; i < mMaxBullets; i++)
|
||||
mMaxBullets = 50;
|
||||
for (int i = 0; i < mMaxBullets; ++i)
|
||||
{
|
||||
if (bullet[i])
|
||||
{
|
||||
delete bullet[i];
|
||||
}
|
||||
bullet[i] = new Bullet(gRenderer);
|
||||
}
|
||||
}
|
||||
|
||||
// Iniciador
|
||||
void GameDirector::init()
|
||||
{
|
||||
// Carga la música del titulo
|
||||
gTitleMusic = Mix_LoadMUS("media/music/title.ogg");
|
||||
if (gTitleMusic == NULL)
|
||||
{
|
||||
printf("Failed to load title music! SDL_mixer Error: %s\n", Mix_GetError());
|
||||
}
|
||||
gTitleMusic = JA_LoadMusic("media/music/title.ogg");
|
||||
|
||||
// Carga la música del juego
|
||||
gPlayingMusic = Mix_LoadMUS("media/music/playing.ogg");
|
||||
if (gPlayingMusic == NULL)
|
||||
{
|
||||
printf("Failed to load playing music! SDL_mixer Error: %s\n", Mix_GetError());
|
||||
}
|
||||
gPlayingMusic = JA_LoadMusic("media/music/playing.ogg");
|
||||
|
||||
// Carga los efectos de sonido para la explosión de los globos
|
||||
gPopBalloonFX = Mix_LoadWAV("media/sound/balloon.wav");
|
||||
if (gPopBalloonFX == NULL)
|
||||
{
|
||||
printf("Failed to load balloon sound effect! SDL_mixer Error: %s\n", Mix_GetError());
|
||||
}
|
||||
gPopBalloonFX = JA_LoadSound("media/sound/balloon.wav");
|
||||
|
||||
// Carga los efectos de sonido para los disparos del jugador
|
||||
gBulletFX = Mix_LoadWAV("media/sound/bullet.wav");
|
||||
if (gBulletFX == NULL)
|
||||
{
|
||||
printf("Failed to load bullet sound effect! SDL_mixer Error: %s\n", Mix_GetError());
|
||||
}
|
||||
gBulletFX = JA_LoadSound("media/sound/bullet.wav");
|
||||
|
||||
gGameBackgroundTexture = new LTexture(gRenderer);
|
||||
// Carga los gráficos del fondo del juego
|
||||
gGameBackgroundTexture = new LTexture(gRenderer);
|
||||
if (!gGameBackgroundTexture->loadFromFile("media/gfx/background.png"))
|
||||
{
|
||||
printf("Failed to load game background texture!\n");
|
||||
}
|
||||
|
||||
gTitleBackgroundTexture = new LTexture(gRenderer);
|
||||
// Carga los gráficos del fondo de la pantalla de titulo
|
||||
gTitleBackgroundTexture = new LTexture(gRenderer);
|
||||
if (!gTitleBackgroundTexture->loadFromFile("media/gfx/title.png"))
|
||||
{
|
||||
printf("Failed to load title texture!\n");
|
||||
}
|
||||
|
||||
gMiscTexture = new LTexture(gRenderer);
|
||||
// Carga varios gráficos para varios propósitos
|
||||
gMiscTexture = new LTexture(gRenderer);
|
||||
if (!gMiscTexture->loadFromFile("media/gfx/misc.png"))
|
||||
{
|
||||
printf("Failed to load misc texture!\n");
|
||||
}
|
||||
|
||||
gWhiteFontTexture = new LTexture(gRenderer);
|
||||
// Carga los gráficos para el texto blanco
|
||||
gWhiteFontTexture = new LTexture(gRenderer);
|
||||
if (!gWhiteFontTexture->loadFromFile("media/gfx/white_font.png"))
|
||||
{
|
||||
printf("Failed to load white font texture!\n");
|
||||
}
|
||||
|
||||
gBlackFontTexture = new LTexture(gRenderer);
|
||||
// Carga los gráficos para el texto negro
|
||||
gBlackFontTexture = new LTexture(gRenderer);
|
||||
if (!gBlackFontTexture->loadFromFile("media/gfx/black_font.png"))
|
||||
{
|
||||
printf("Failed to load black font texture!\n");
|
||||
@@ -165,11 +107,53 @@ void GameDirector::init()
|
||||
std::cout << SDL_JoystickNumButtons(gGameController) << " buttons\n";
|
||||
}
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
// Destructor
|
||||
GameDirector::~GameDirector()
|
||||
{
|
||||
// Libera los efectos de sonido
|
||||
JA_DeleteSound(gPopBalloonFX);
|
||||
JA_DeleteSound(gBulletFX);
|
||||
|
||||
// Libra la música
|
||||
JA_DeleteMusic(gTitleMusic);
|
||||
JA_DeleteMusic(gPlayingMusic);
|
||||
|
||||
// Libera el mando
|
||||
SDL_JoystickClose(gGameController);
|
||||
gGameController = NULL;
|
||||
|
||||
// Libera texturas
|
||||
gGameBackgroundTexture->free();
|
||||
gTitleBackgroundTexture->free();
|
||||
gWhiteFontTexture->free();
|
||||
gBlackFontTexture->free();
|
||||
gMiscTexture->free();
|
||||
|
||||
// Libera objetos
|
||||
delete player;
|
||||
delete menuPause;
|
||||
delete menuTitle;
|
||||
|
||||
for (int i = 0; i < mMaxBalloons; ++i)
|
||||
{
|
||||
delete balloon[i];
|
||||
}
|
||||
|
||||
for (int i = 0; i < mMaxBullets; ++i)
|
||||
{
|
||||
delete bullet[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Iniciador
|
||||
void GameDirector::init()
|
||||
{
|
||||
// Variables
|
||||
mGameStatus = GAME_STATE_TITLE;
|
||||
mOldTicks = 0;
|
||||
mMaxBalloons = 50;
|
||||
mMaxBullets = 50;
|
||||
mGameSpeed = 15;
|
||||
mMenaceLevel = 0;
|
||||
mMenaceLevelThreshold = 7;
|
||||
@@ -186,24 +170,12 @@ void GameDirector::init()
|
||||
// Establece a cero todos los valores del vector de objetos globo
|
||||
resetBalloons();
|
||||
|
||||
// Crea dos objetos globo y los centra en el area de juego
|
||||
// balloon[0].init(0, BLOCK, BALLOON_4, BALLON_VELX_POSITIVE, 0);
|
||||
// balloon[0].allignTo(PLAY_AREA_WIDTH / 2);
|
||||
// balloon[1].init(0, BLOCK, BALLOON_4, BALLON_VELX_NEGATIVE, 0);
|
||||
// balloon[1].allignTo(PLAY_AREA_WIDTH / 2);
|
||||
|
||||
// Con los globos creados, calcula el nivel de amenaza
|
||||
calculateMenaceLevel();
|
||||
|
||||
// Establece a cero todos los valores del vector de objetos bala
|
||||
resetBullets();
|
||||
|
||||
#ifdef TEST
|
||||
balloonTest.init(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, BALLOON_4, 0);
|
||||
balloonTest.stop();
|
||||
bulletTest.init(SCREEN_WIDTH / 4, SCREEN_HEIGHT / 2, BULLET_UP);
|
||||
#endif
|
||||
|
||||
// Los fondos
|
||||
gameBackground.init(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT - (0 * BLOCK), gGameBackgroundTexture);
|
||||
titleBackground.init(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, gTitleBackgroundTexture);
|
||||
@@ -229,16 +201,6 @@ void GameDirector::init()
|
||||
menuPause->centerMenuOnScreen();
|
||||
}
|
||||
|
||||
// Hace una pausa de milisegundos
|
||||
void GameDirector::sleep(Uint16 time)
|
||||
{
|
||||
Uint32 ticks = SDL_GetTicks();
|
||||
while (SDL_GetTicks() - ticks < time)
|
||||
{
|
||||
/* code */
|
||||
}
|
||||
}
|
||||
|
||||
// Establece el valor de la variable
|
||||
void GameDirector::setScore(Uint32 score)
|
||||
{
|
||||
@@ -288,6 +250,7 @@ std::string GameDirector::updateScoreText(Uint32 num)
|
||||
case 100000 ... 999999:
|
||||
return (std::to_string(num));
|
||||
break;
|
||||
|
||||
default:
|
||||
return (std::to_string(num));
|
||||
break;
|
||||
@@ -349,8 +312,7 @@ Uint8 GameDirector::getBallonFreeIndex()
|
||||
// Crea un globo nuevo en el vector de globos
|
||||
Uint8 GameDirector::createNewBalloon(int x, int y, Uint8 kind, float velx, Uint16 creationtimer)
|
||||
{
|
||||
Uint8 index = getBallonFreeIndex();
|
||||
balloon[index] = new Balloon(gRenderer);
|
||||
const Uint8 index = getBallonFreeIndex();
|
||||
balloon[index]->init(x, y, kind, velx, creationtimer);
|
||||
return index;
|
||||
}
|
||||
@@ -358,7 +320,7 @@ Uint8 GameDirector::createNewBalloon(int x, int y, Uint8 kind, float velx, Uint1
|
||||
// Establece a cero todos los valores del vector de objetos globo
|
||||
void GameDirector::resetBalloons()
|
||||
{
|
||||
for (Uint8 i = 0; i < mMaxBalloons; i++)
|
||||
for (int i = 0; i < mMaxBalloons; ++i)
|
||||
{
|
||||
balloon[i]->erase();
|
||||
}
|
||||
@@ -468,7 +430,7 @@ void GameDirector::processBulletBallonCollision()
|
||||
setScore(player->getScore());
|
||||
updateHiScore();
|
||||
popBalloon(i);
|
||||
Mix_PlayChannel(-1, gPopBalloonFX, 0);
|
||||
JA_PlaySound(gPopBalloonFX);
|
||||
bullet[j]->erase();
|
||||
calculateMenaceLevel();
|
||||
break;
|
||||
@@ -522,7 +484,7 @@ Uint8 GameDirector::getBulletFreeIndex()
|
||||
// Establece a cero todos los valores del vector de objetos bala
|
||||
void GameDirector::resetBullets()
|
||||
{
|
||||
for (Uint8 i = 0; i < mMaxBullets; i++)
|
||||
for (int i = 0; i < mMaxBullets; ++i)
|
||||
{
|
||||
bullet[i]->init(0, 0, NO_KIND);
|
||||
}
|
||||
@@ -532,7 +494,6 @@ void GameDirector::resetBullets()
|
||||
void GameDirector::createBullet(int x, int y, Uint8 kind)
|
||||
{
|
||||
const int index = getBulletFreeIndex();
|
||||
bullet[index] = new Bullet(gRenderer);
|
||||
bullet[index]->init(x, y, kind);
|
||||
}
|
||||
|
||||
@@ -540,7 +501,7 @@ void GameDirector::createBullet(int x, int y, Uint8 kind)
|
||||
void GameDirector::calculateMenaceLevel()
|
||||
{
|
||||
mMenaceLevel = 0;
|
||||
for (Uint8 i = 0; i < mMaxBalloons; i++)
|
||||
for (int i = 0; i < mMaxBalloons; ++i)
|
||||
{
|
||||
switch (balloon[i]->getKind())
|
||||
{
|
||||
@@ -634,7 +595,7 @@ void GameDirector::checkGameInput()
|
||||
player->setFireCooldown(10);
|
||||
|
||||
// Reproduce el sonido de disparo
|
||||
Mix_PlayChannel(-1, gBulletFX, 0);
|
||||
JA_PlaySound(gBulletFX);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -647,7 +608,7 @@ void GameDirector::checkGameInput()
|
||||
player->setFireCooldown(10);
|
||||
|
||||
// Reproduce el sonido de disparo
|
||||
Mix_PlayChannel(-1, gBulletFX, 0);
|
||||
JA_PlaySound(gBulletFX);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -660,7 +621,7 @@ void GameDirector::checkGameInput()
|
||||
player->setFireCooldown(10);
|
||||
|
||||
// Reproduce el sonido de disparo
|
||||
Mix_PlayChannel(-1, gBulletFX, 0);
|
||||
JA_PlaySound(gBulletFX);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -670,7 +631,7 @@ void GameDirector::checkGameInput()
|
||||
setGameStatus(GAME_STATE_PAUSED);
|
||||
|
||||
// Detiene la música
|
||||
Mix_HaltMusic();
|
||||
JA_StopMusic();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -695,88 +656,6 @@ void GameDirector::checkMenuInput(Menu *menu)
|
||||
{
|
||||
menu->checkInput(INPUT_FIRE);
|
||||
}
|
||||
|
||||
#ifdef TEST
|
||||
if (SDL_JoystickGetButton(gGameController, 1))
|
||||
{
|
||||
std::cout << "button1\n";
|
||||
}
|
||||
|
||||
if (SDL_JoystickGetButton(gGameController, 1))
|
||||
{
|
||||
std::cout << "button1\n";
|
||||
}
|
||||
|
||||
if (SDL_JoystickGetButton(gGameController, 2))
|
||||
{
|
||||
std::cout << "button2\n";
|
||||
}
|
||||
|
||||
if (SDL_JoystickGetButton(gGameController, 3))
|
||||
{
|
||||
std::cout << "button3\n";
|
||||
}
|
||||
|
||||
if (SDL_JoystickGetButton(gGameController, 4))
|
||||
{
|
||||
std::cout << "button4\n";
|
||||
}
|
||||
|
||||
if (SDL_JoystickGetButton(gGameController, 5))
|
||||
{
|
||||
std::cout << "button5\n";
|
||||
}
|
||||
|
||||
if (SDL_JoystickGetButton(gGameController, 6))
|
||||
{
|
||||
std::cout << "button6\n";
|
||||
}
|
||||
|
||||
if (SDL_JoystickGetButton(gGameController, 7))
|
||||
{
|
||||
std::cout << "button7\n";
|
||||
}
|
||||
|
||||
if (SDL_JoystickGetButton(gGameController, 8))
|
||||
{
|
||||
std::cout << "button8\n";
|
||||
}
|
||||
|
||||
if (SDL_JoystickGetButton(gGameController, 9))
|
||||
{
|
||||
std::cout << "button9\n";
|
||||
}
|
||||
|
||||
if (SDL_JoystickGetButton(gGameController, 10))
|
||||
{
|
||||
std::cout << "button10\n";
|
||||
}
|
||||
|
||||
if (SDL_JoystickGetButton(gGameController, 11))
|
||||
{
|
||||
std::cout << "button11\n";
|
||||
}
|
||||
|
||||
if (SDL_JoystickGetButton(gGameController, 12))
|
||||
{
|
||||
std::cout << "button12\n";
|
||||
}
|
||||
|
||||
if (SDL_JoystickGetButton(gGameController, 13))
|
||||
{
|
||||
std::cout << "button13\n";
|
||||
}
|
||||
|
||||
if (SDL_JoystickGetButton(gGameController, 14))
|
||||
{
|
||||
std::cout << "button14\n";
|
||||
}
|
||||
|
||||
if (SDL_JoystickGetButton(gGameController, 15))
|
||||
{
|
||||
std::cout << "button15\n";
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Obtiene el valor de la variable
|
||||
@@ -886,10 +765,10 @@ void GameDirector::renderGetReady()
|
||||
void GameDirector::runTitle()
|
||||
{
|
||||
// Si la música no está sonando
|
||||
if (Mix_PlayingMusic() == 0)
|
||||
if ((JA_GetMusicState() == JA_MUSIC_INVALID) || (JA_GetMusicState() == JA_MUSIC_STOPPED))
|
||||
{
|
||||
// Reproduce la música
|
||||
Mix_PlayMusic(gTitleMusic, -1);
|
||||
JA_PlayMusic(gTitleMusic);
|
||||
}
|
||||
|
||||
// Comprueba los eventos que hay en la cola
|
||||
@@ -923,15 +802,17 @@ void GameDirector::runTitle()
|
||||
setGameStatus(GAME_STATE_PLAYING);
|
||||
menuTitle->resetMenu();
|
||||
renderTransition(1);
|
||||
Mix_HaltMusic();
|
||||
JA_StopMusic();
|
||||
SDL_Delay(1200);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
setGameStatus(GAME_STATE_QUIT);
|
||||
menuTitle->resetMenu();
|
||||
renderTransition(1);
|
||||
Mix_HaltMusic();
|
||||
JA_StopMusic();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -941,10 +822,10 @@ void GameDirector::runTitle()
|
||||
void GameDirector::runGame()
|
||||
{
|
||||
// Si la música no está sonando
|
||||
if (Mix_PlayingMusic() == 0)
|
||||
if ((JA_GetMusicState() == JA_MUSIC_INVALID) || (JA_GetMusicState() == JA_MUSIC_STOPPED))
|
||||
{
|
||||
// Reproduce la música
|
||||
Mix_PlayMusic(gPlayingMusic, -1);
|
||||
JA_PlayMusic(gPlayingMusic);
|
||||
}
|
||||
|
||||
// Lógica del juego
|
||||
@@ -973,39 +854,6 @@ void GameDirector::runGame()
|
||||
popBalloon(0);
|
||||
break;
|
||||
}
|
||||
#ifdef TEST
|
||||
// W key pressed
|
||||
if (eventHandler.key.keysym.sym == SDLK_w)
|
||||
{
|
||||
bulletTest.setPosY(bulletTest.getPosY() - 1);
|
||||
bulletTest.testMove();
|
||||
break;
|
||||
}
|
||||
|
||||
// S key pressed
|
||||
if (eventHandler.key.keysym.sym == SDLK_s)
|
||||
{
|
||||
bulletTest.setPosY(bulletTest.getPosY() + 1);
|
||||
bulletTest.testMove();
|
||||
break;
|
||||
}
|
||||
|
||||
// A key pressed
|
||||
if (eventHandler.key.keysym.sym == SDLK_a)
|
||||
{
|
||||
bulletTest.setPosX(bulletTest.getPosX() - 1);
|
||||
bulletTest.testMove();
|
||||
break;
|
||||
}
|
||||
|
||||
// D key pressed
|
||||
if (eventHandler.key.keysym.sym == SDLK_d)
|
||||
{
|
||||
bulletTest.setPosX(bulletTest.getPosX() + 1);
|
||||
bulletTest.testMove();
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Actualiza el jugador
|
||||
@@ -1014,10 +862,6 @@ void GameDirector::runGame()
|
||||
// Mueve los globos
|
||||
moveBalloons();
|
||||
|
||||
#ifdef TEST
|
||||
balloonTest.move();
|
||||
#endif
|
||||
|
||||
// Mueve las balas
|
||||
moveBullets();
|
||||
|
||||
@@ -1041,16 +885,6 @@ void GameDirector::runGame()
|
||||
// Dibuja los objetos
|
||||
gameBackground.render();
|
||||
renderBalloons();
|
||||
#ifdef TEST
|
||||
balloonTest.render();
|
||||
bulletTest.render();
|
||||
if (checkCollision(balloonTest.getCollider(), bulletTest.getCollider()))
|
||||
{
|
||||
whiteText.write(0, 0, "X");
|
||||
}
|
||||
#endif
|
||||
// whiteText.write(0, 0, std::to_string(mMenaceLevelThreshold));
|
||||
// whiteText.write(0, BLOCK, std::to_string(player->getPosX() + player->getWidth()));
|
||||
renderBullets();
|
||||
player->render();
|
||||
renderScoreBoard(whiteText);
|
||||
@@ -1094,12 +928,14 @@ void GameDirector::runPausedGame()
|
||||
setGameStatus(GAME_STATE_PLAYING);
|
||||
menuPause->resetMenu();
|
||||
break;
|
||||
|
||||
case 1:
|
||||
setGameStatus(GAME_STATE_TITLE);
|
||||
menuPause->resetMenu();
|
||||
renderTransition(1);
|
||||
init();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "menu.h"
|
||||
#include "player.h"
|
||||
#include "text.h"
|
||||
#include "jail_audio.h"
|
||||
|
||||
#ifndef GAMEDIRECTOR_H
|
||||
#define GAMEDIRECTOR_H
|
||||
@@ -26,9 +27,6 @@ public:
|
||||
// Iniciador
|
||||
void init();
|
||||
|
||||
// Hace una pausa de milisegundos
|
||||
void sleep(Uint16 time);
|
||||
|
||||
// Establece el valor de la variable
|
||||
void setScore(Uint32 score);
|
||||
|
||||
@@ -133,12 +131,16 @@ private:
|
||||
SDL_Renderer *gRenderer = NULL;
|
||||
|
||||
// Objetos con la música del juego
|
||||
Mix_Music *gTitleMusic = NULL;
|
||||
Mix_Music *gPlayingMusic = NULL;
|
||||
//Mix_Music *gTitleMusic = NULL;
|
||||
//Mix_Music *gPlayingMusic = NULL;
|
||||
JA_Music gTitleMusic;
|
||||
JA_Music gPlayingMusic;
|
||||
|
||||
// Objetos con los efectos de sonido del juego
|
||||
Mix_Chunk *gPopBalloonFX = NULL;
|
||||
Mix_Chunk *gBulletFX = NULL;
|
||||
//Mix_Chunk *gPopBalloonFX = NULL;
|
||||
//Mix_Chunk *gBulletFX = NULL;
|
||||
JA_Sound gPopBalloonFX;
|
||||
JA_Sound gBulletFX;
|
||||
|
||||
// Manejador para el mando 1
|
||||
SDL_Joystick *gGameController = NULL;
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
#include <SDL2/SDL_image.h>
|
||||
#include <SDL2/SDL_mixer.h>
|
||||
|
||||
#ifndef GLOBALS_H
|
||||
#define GLOBALS_H
|
||||
|
||||
238
source/jail_audio.cpp
Normal file
238
source/jail_audio.cpp
Normal file
@@ -0,0 +1,238 @@
|
||||
#include "jail_audio.h"
|
||||
#include "stb_vorbis.c"
|
||||
#include <SDL2/SDL.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define JA_MAX_SIMULTANEOUS_CHANNELS 5
|
||||
|
||||
struct JA_Sound_t {
|
||||
Uint32 length {0};
|
||||
Uint8* buffer {NULL};
|
||||
};
|
||||
|
||||
struct JA_Channel_t {
|
||||
JA_Sound sound;
|
||||
int pos {0};
|
||||
int times {0};
|
||||
JA_Channel_state state { JA_CHANNEL_FREE };
|
||||
};
|
||||
|
||||
struct JA_Music_t {
|
||||
int samples {0};
|
||||
int pos {0};
|
||||
int times {0};
|
||||
short* output {NULL};
|
||||
JA_Music_state state {JA_MUSIC_INVALID};
|
||||
};
|
||||
|
||||
JA_Music current_music{NULL};
|
||||
JA_Channel_t channels[JA_MAX_SIMULTANEOUS_CHANNELS];
|
||||
|
||||
int JA_freq {48000};
|
||||
SDL_AudioFormat JA_format {AUDIO_S16};
|
||||
Uint8 JA_channels {2};
|
||||
int JA_volume = 128;
|
||||
|
||||
void audioCallback(void * userdata, uint8_t * stream, int len) {
|
||||
SDL_memset(stream, 0, len);
|
||||
if (current_music != NULL && current_music->state == JA_MUSIC_PLAYING) {
|
||||
const int size = SDL_min(len, current_music->samples*2-current_music->pos);
|
||||
SDL_MixAudioFormat(stream, (Uint8*)(current_music->output+current_music->pos), AUDIO_S16, size, JA_volume);
|
||||
current_music->pos += size/2;
|
||||
if (size < len) {
|
||||
if (current_music->times != 0) {
|
||||
SDL_MixAudioFormat(stream+size, (Uint8*)current_music->output, AUDIO_S16, len-size, JA_volume);
|
||||
current_music->pos = (len-size)/2;
|
||||
if (current_music->times > 0) current_music->times--;
|
||||
} else {
|
||||
current_music->pos = 0;
|
||||
current_music->state = JA_MUSIC_STOPPED;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Mixar els channels mi amol
|
||||
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) {
|
||||
if (channels[i].state == JA_CHANNEL_PLAYING) {
|
||||
const int size = SDL_min(len, channels[i].sound->length - channels[i].pos);
|
||||
SDL_MixAudioFormat(stream, channels[i].sound->buffer + channels[i].pos, AUDIO_S16, size, JA_volume/2);
|
||||
channels[i].pos += size;
|
||||
if (size < len) {
|
||||
if (channels[i].times != 0) {
|
||||
SDL_MixAudioFormat(stream + size, channels[i].sound->buffer, AUDIO_S16, len-size, JA_volume/2);
|
||||
channels[i].pos = len-size;
|
||||
if (channels[i].times > 0) channels[i].times--;
|
||||
} else {
|
||||
JA_StopChannel(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JA_Init(const int freq, const SDL_AudioFormat format, const int channels) {
|
||||
JA_freq = freq;
|
||||
JA_format = format;
|
||||
JA_channels = channels;
|
||||
SDL_AudioSpec audioSpec{JA_freq, JA_format, JA_channels, 0, 1024, 0, 0, audioCallback, NULL};
|
||||
SDL_AudioDeviceID sdlAudioDevice = SDL_OpenAudioDevice(NULL, 0, &audioSpec, NULL, 0);
|
||||
SDL_PauseAudioDevice(sdlAudioDevice, 0);
|
||||
}
|
||||
|
||||
JA_Music JA_LoadMusic(const char* filename) {
|
||||
int chan, samplerate;
|
||||
JA_Music music = new JA_Music_t();
|
||||
|
||||
// [RZC 28/08/22] Carreguem primer el arxiu en memòria i després el descomprimim. Es algo més rapid.
|
||||
FILE *f = fopen(filename, "rb");
|
||||
fseek(f, 0, SEEK_END);
|
||||
long fsize = ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
Uint8 *buffer = (Uint8*)malloc(fsize + 1);
|
||||
fread(buffer, fsize, 1, f);
|
||||
fclose(f);
|
||||
music->samples = stb_vorbis_decode_memory(buffer, fsize, &chan, &samplerate, &music->output);
|
||||
free(buffer);
|
||||
// [RZC 28/08/22] Abans el descomprimiem mentre el teniem obert
|
||||
// music->samples = stb_vorbis_decode_filename(filename, &chan, &samplerate, &music->output);
|
||||
|
||||
SDL_AudioCVT cvt;
|
||||
SDL_BuildAudioCVT(&cvt, AUDIO_S16, chan, samplerate, JA_format, JA_channels, JA_freq);
|
||||
cvt.len = music->samples * chan * 2;
|
||||
cvt.buf = (Uint8 *) SDL_malloc(cvt.len * cvt.len_mult);
|
||||
SDL_memcpy(cvt.buf, music->output, cvt.len);
|
||||
SDL_ConvertAudio(&cvt);
|
||||
free(music->output);
|
||||
music->output = (short*)cvt.buf;
|
||||
|
||||
music->pos = 0;
|
||||
music->state = JA_MUSIC_STOPPED;
|
||||
|
||||
return music;
|
||||
}
|
||||
|
||||
void JA_PlayMusic(JA_Music music, const int loop) {
|
||||
if (current_music != NULL) {
|
||||
current_music->pos = 0;
|
||||
current_music->state = JA_MUSIC_STOPPED;
|
||||
}
|
||||
current_music = music;
|
||||
current_music->pos = 0;
|
||||
current_music->state = JA_MUSIC_PLAYING;
|
||||
current_music->times = loop;
|
||||
}
|
||||
|
||||
void JA_PauseMusic() {
|
||||
if (current_music == NULL || current_music->state == JA_MUSIC_INVALID) return;
|
||||
current_music->state = JA_MUSIC_PAUSED;
|
||||
}
|
||||
|
||||
void JA_ResumeMusic() {
|
||||
if (current_music == NULL || current_music->state == JA_MUSIC_INVALID) return;
|
||||
current_music->state = JA_MUSIC_PLAYING;
|
||||
}
|
||||
|
||||
void JA_StopMusic() {
|
||||
if (current_music == NULL || current_music->state == JA_MUSIC_INVALID) return;
|
||||
current_music->pos = 0;
|
||||
current_music->state = JA_MUSIC_STOPPED;
|
||||
}
|
||||
|
||||
JA_Music_state JA_GetMusicState() {
|
||||
if (current_music == NULL) return JA_MUSIC_INVALID;
|
||||
return current_music->state;
|
||||
}
|
||||
|
||||
void JA_DeleteMusic(JA_Music music) {
|
||||
if (current_music == music) current_music = NULL;
|
||||
SDL_free(music->output);
|
||||
delete music;
|
||||
}
|
||||
|
||||
JA_Sound JA_NewSound(Uint8* buffer, Uint32 length) {
|
||||
JA_Sound sound = new JA_Sound_t();
|
||||
sound->buffer = buffer;
|
||||
sound->length = length;
|
||||
return sound;
|
||||
}
|
||||
|
||||
JA_Sound JA_LoadSound(const char* filename) {
|
||||
JA_Sound sound = new JA_Sound_t();
|
||||
SDL_AudioSpec wavSpec;
|
||||
SDL_LoadWAV(filename, &wavSpec, &sound->buffer, &sound->length);
|
||||
|
||||
SDL_AudioCVT cvt;
|
||||
SDL_BuildAudioCVT(&cvt, wavSpec.format, wavSpec.channels, wavSpec.freq, JA_format, JA_channels, JA_freq);
|
||||
cvt.len = sound->length;
|
||||
cvt.buf = (Uint8 *) SDL_malloc(cvt.len * cvt.len_mult);
|
||||
SDL_memcpy(cvt.buf, sound->buffer, sound->length);
|
||||
SDL_ConvertAudio(&cvt);
|
||||
SDL_FreeWAV(sound->buffer);
|
||||
sound->buffer = cvt.buf;
|
||||
sound->length = cvt.len_cvt;
|
||||
|
||||
return sound;
|
||||
}
|
||||
|
||||
int JA_PlaySound(JA_Sound sound, const int loop) {
|
||||
int channel = 0;
|
||||
while (channel < JA_MAX_SIMULTANEOUS_CHANNELS && channels[channel].state != JA_CHANNEL_FREE) { channel++; }
|
||||
if (channel == JA_MAX_SIMULTANEOUS_CHANNELS) channel = 0;
|
||||
|
||||
channels[channel].sound = sound;
|
||||
channels[channel].times = loop;
|
||||
channels[channel].pos = 0;
|
||||
channels[channel].state = JA_CHANNEL_PLAYING;
|
||||
return channel;
|
||||
}
|
||||
|
||||
void JA_DeleteSound(JA_Sound sound) {
|
||||
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) {
|
||||
if (channels[i].sound == sound) JA_StopChannel(i);
|
||||
}
|
||||
SDL_free(sound->buffer);
|
||||
delete sound;
|
||||
}
|
||||
|
||||
void JA_PauseChannel(const int channel) {
|
||||
if (channel == -1) {
|
||||
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) {
|
||||
if (channels[i].state == JA_CHANNEL_PLAYING) channels[i].state = JA_CHANNEL_PAUSED;
|
||||
}
|
||||
} else if (channel >= 0 && channel < JA_MAX_SIMULTANEOUS_CHANNELS) {
|
||||
if (channels[channel].state == JA_CHANNEL_PLAYING) channels[channel].state = JA_CHANNEL_PAUSED;
|
||||
}
|
||||
}
|
||||
|
||||
void JA_ResumeChannel(const int channel) {
|
||||
if (channel == -1) {
|
||||
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) {
|
||||
if (channels[i].state == JA_CHANNEL_PAUSED) channels[i].state = JA_CHANNEL_PLAYING;
|
||||
}
|
||||
} else if (channel >= 0 && channel < JA_MAX_SIMULTANEOUS_CHANNELS) {
|
||||
if (channels[channel].state == JA_CHANNEL_PAUSED) channels[channel].state = JA_CHANNEL_PLAYING;
|
||||
}
|
||||
}
|
||||
|
||||
void JA_StopChannel(const int channel) {
|
||||
if (channel == -1) {
|
||||
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) {
|
||||
channels[i].state = JA_CHANNEL_FREE;
|
||||
channels[i].pos = 0;
|
||||
channels[i].sound = NULL;
|
||||
}
|
||||
} else if (channel >= 0 && channel < JA_MAX_SIMULTANEOUS_CHANNELS) {
|
||||
channels[channel].state = JA_CHANNEL_FREE;
|
||||
channels[channel].pos = 0;
|
||||
channels[channel].sound = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
JA_Channel_state JA_GetChannelState(const int channel) {
|
||||
if (channel < 0 || channel >= JA_MAX_SIMULTANEOUS_CHANNELS) return JA_CHANNEL_INVALID;
|
||||
return channels[channel].state;
|
||||
}
|
||||
|
||||
int JA_SetVolume(int volume) {
|
||||
JA_volume = volume > 128 ? 128 : volume < 0 ? 0 : volume;
|
||||
return JA_volume;
|
||||
}
|
||||
29
source/jail_audio.h
Normal file
29
source/jail_audio.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
enum JA_Channel_state { JA_CHANNEL_INVALID, JA_CHANNEL_FREE, JA_CHANNEL_PLAYING, JA_CHANNEL_PAUSED };
|
||||
enum JA_Music_state { JA_MUSIC_INVALID, JA_MUSIC_PLAYING, JA_MUSIC_PAUSED, JA_MUSIC_STOPPED };
|
||||
|
||||
typedef struct JA_Sound_t *JA_Sound;
|
||||
typedef struct JA_Music_t *JA_Music;
|
||||
|
||||
void JA_Init(const int freq, const SDL_AudioFormat format, const int channels);
|
||||
|
||||
JA_Music JA_LoadMusic(const char* filename);
|
||||
void JA_PlayMusic(JA_Music music, const int loop = -1);
|
||||
void JA_PauseMusic();
|
||||
void JA_ResumeMusic();
|
||||
void JA_StopMusic();
|
||||
JA_Music_state JA_GetMusicState();
|
||||
void JA_DeleteMusic(JA_Music music);
|
||||
|
||||
JA_Sound JA_NewSound(Uint8* buffer, Uint32 length);
|
||||
JA_Sound JA_LoadSound(const char* filename);
|
||||
int JA_PlaySound(JA_Sound sound, const int loop = 0);
|
||||
void JA_PauseChannel(const int channel);
|
||||
void JA_ResumeChannel(const int channel);
|
||||
void JA_StopChannel(const int channel);
|
||||
JA_Channel_state JA_GetChannelState(const int channel);
|
||||
void JA_DeleteSound(JA_Sound sound);
|
||||
|
||||
int JA_SetVolume(int volume);
|
||||
@@ -1,4 +1,6 @@
|
||||
#include "ltexture.h"
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include "stb_image.h"
|
||||
|
||||
LTexture::LTexture(SDL_Renderer *gRenderer)
|
||||
{
|
||||
@@ -18,6 +20,72 @@ LTexture::~LTexture()
|
||||
|
||||
bool LTexture::loadFromFile(std::string path)
|
||||
{
|
||||
const std::string filename = path.substr(path.find_last_of("\\/") + 1);
|
||||
int req_format = STBI_rgb_alpha;
|
||||
int width, height, orig_format;
|
||||
unsigned char *data = stbi_load(path.c_str(), &width, &height, &orig_format, req_format);
|
||||
if (data == nullptr)
|
||||
{
|
||||
SDL_Log("Loading image failed: %s", stbi_failure_reason());
|
||||
exit(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Image loaded: %s\n", filename.c_str());
|
||||
}
|
||||
|
||||
int depth, pitch;
|
||||
Uint32 pixel_format;
|
||||
if (req_format == STBI_rgb)
|
||||
{
|
||||
depth = 24;
|
||||
pitch = 3 * width; // 3 bytes por pixel * pixels per linea
|
||||
pixel_format = SDL_PIXELFORMAT_RGB24;
|
||||
}
|
||||
else
|
||||
{ // STBI_rgb_alpha (RGBA)
|
||||
depth = 32;
|
||||
pitch = 4 * width;
|
||||
pixel_format = SDL_PIXELFORMAT_RGBA32;
|
||||
}
|
||||
|
||||
// Limpia
|
||||
free();
|
||||
|
||||
// La textura final
|
||||
SDL_Texture *newTexture = nullptr;
|
||||
|
||||
// Carga la imagen desde una ruta específica
|
||||
SDL_Surface *loadedSurface = SDL_CreateRGBSurfaceWithFormatFrom((void *)data, width, height, depth, pitch, pixel_format);
|
||||
if (loadedSurface == nullptr)
|
||||
{
|
||||
printf("Unable to load image %s!\n", path.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Crea la textura desde los pixels de la surface
|
||||
newTexture = SDL_CreateTextureFromSurface(gRenderer, loadedSurface);
|
||||
if (newTexture == nullptr)
|
||||
{
|
||||
printf("Unable to create texture from %s! SDL Error: %s\n", path.c_str(), SDL_GetError());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Obtiene las dimensiones de la imagen
|
||||
this->mWidth = loadedSurface->w;
|
||||
this->mHeight = loadedSurface->h;
|
||||
}
|
||||
|
||||
// Elimina la textura cargada
|
||||
SDL_FreeSurface(loadedSurface);
|
||||
}
|
||||
|
||||
// Return success
|
||||
mTexture = newTexture;
|
||||
return mTexture != nullptr;
|
||||
|
||||
|
||||
/*
|
||||
// Get rid of preexisting texture
|
||||
free();
|
||||
|
||||
@@ -55,6 +123,7 @@ bool LTexture::loadFromFile(std::string path)
|
||||
// Return success
|
||||
mTexture = newTexture;
|
||||
return mTexture != NULL;
|
||||
*/
|
||||
}
|
||||
|
||||
bool LTexture::createBlank(int width, int height, SDL_TextureAccess access)
|
||||
|
||||
@@ -35,7 +35,6 @@ Los objetos globo tienen varios contadores para alternar de un estado a otro.
|
||||
En los vectores que contienen objetos, se considera activos los objetos que tienen
|
||||
un tipo asociado diferente a NO_KIND
|
||||
*/
|
||||
#define TEST_
|
||||
|
||||
#include "background.h"
|
||||
#include "balloon.h"
|
||||
@@ -88,13 +87,6 @@ bool init()
|
||||
printf("Warning: Nearest texture filtering not enabled!");
|
||||
}
|
||||
|
||||
// Inicializa SDL_mixer
|
||||
if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048) < 0)
|
||||
{
|
||||
printf("SDL_mixer could not initialize! SDL_mixer Error: %s\n", Mix_GetError());
|
||||
success = false;
|
||||
}
|
||||
|
||||
// Crea la ventana
|
||||
gWindow = SDL_CreateWindow("Super Popping (Like Loc) in Jailers World", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, VIEW_WIDTH, VIEW_HEIGHT, SDL_WINDOW_SHOWN);
|
||||
if (gWindow == NULL)
|
||||
@@ -118,18 +110,13 @@ bool init()
|
||||
|
||||
// Establece el tamaño del buffer de renderizado
|
||||
SDL_RenderSetLogicalSize(gRenderer, SCREEN_WIDTH, SCREEN_HEIGHT);
|
||||
|
||||
// Inicializa el cargador de PNG
|
||||
int imgFlags = IMG_INIT_PNG;
|
||||
if (!(IMG_Init(imgFlags) & imgFlags))
|
||||
{
|
||||
printf("SDL_image could not initialize! SDL_image Error: %s\n", IMG_GetError());
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Inicializa JailAudio
|
||||
JA_Init(44100, AUDIO_S16, 2);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
@@ -143,7 +130,6 @@ void close()
|
||||
gRenderer = NULL;
|
||||
|
||||
// Sal del subsistema SDL
|
||||
IMG_Quit();
|
||||
SDL_Quit();
|
||||
}
|
||||
|
||||
@@ -161,13 +147,6 @@ int main(int argc, char *args[])
|
||||
// Crea el objeto gameDirector
|
||||
GameDirector gameDirector(gRenderer);
|
||||
|
||||
// Inicializa el objeto gameDirector
|
||||
gameDirector.init();
|
||||
|
||||
#ifdef TEST
|
||||
gameDirector.resetBalloons();
|
||||
#endif
|
||||
|
||||
// Mientras no se quiera salir del juego
|
||||
while (!(gameDirector.getGameStatus() == GAME_STATE_QUIT))
|
||||
{
|
||||
|
||||
@@ -12,7 +12,7 @@ Menu::Menu(SDL_Renderer *gRenderer)
|
||||
printf("Failed to load menu texture!\n");
|
||||
}
|
||||
|
||||
init(0, 0, 0, MENU_BACKGROUND_SOLID);
|
||||
//init(0, 0, 0, MENU_BACKGROUND_SOLID);
|
||||
}
|
||||
|
||||
// Destructor
|
||||
@@ -50,9 +50,9 @@ void Menu::init(int x, int y, int offset_sprite_selector, int backgroundType)
|
||||
// Elementos del menu
|
||||
for (Uint8 i = 0; i < 10; i++)
|
||||
{
|
||||
mMenuItem[i].label = "";
|
||||
mMenuItem[i].x = mPosX;
|
||||
mMenuItem[i].y = mPosY + (i * (BLOCK + 2));
|
||||
mMenuItem[i].label = "s";
|
||||
}
|
||||
|
||||
// Mueve el grafico del selector al elemento seleccionado
|
||||
|
||||
7897
source/stb_image.h
Normal file
7897
source/stb_image.h
Normal file
File diff suppressed because it is too large
Load Diff
5565
source/stb_vorbis.c
Normal file
5565
source/stb_vorbis.c
Normal file
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Reference in New Issue
Block a user