Skip to content

Commit

Permalink
Alpha 1.0
Browse files Browse the repository at this point in the history
Alpha 1.0
  • Loading branch information
justin-ys authored Dec 24, 2023
2 parents 878a8ba + 2ba82a1 commit ac5eede
Show file tree
Hide file tree
Showing 55 changed files with 3,890 additions and 278 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
log.txt
test_log.txt
Spylike-v*
lib/bin
lib/include
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
[submodule "lib/PDCurses"]
path = lib/PDCurses
url = https://github.com/wmcbrine/PDCurses.git
[submodule "lib/miniaudio"]
path = lib/miniaudio
url = https://github.com/mackron/miniaudio
13 changes: 7 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
CXX=g++
CPPFLAGS=-std=c++11 -Iinclude
CPPFLAGS=-std=c++2a -Iinclude -Igame/include -Ilib/include -DMA_NO_PULSEAUDIO
LDLIBS=
OBJS=graphics/*.cpp logging/*.cpp models/*.cpp level/*.cpp game/*.cpp game/UI/*.cpp main.cpp
OBJS=graphics/*.cpp logging/*.cpp models/*.cpp level/*.cpp audio/*.cpp game/*.cpp game/entities/*.cpp game/UI/*.cpp util/*.cpp main.cpp
VER=vA1

ifndef PDCURSES_BACKEND
Expand All @@ -14,15 +14,15 @@ ifndef PDCURSES_BACKEND
USE_NCURSES=1
endif
PDCURSES_BACKEND=x11
LDLIBS+= -lpthread -lm -ldl
endif
endif
endif

ifeq ($(USE_NCURSES), 1)
LDLIBS+= -lncurses
LDLIBS+= -lncursesw
else
LDLIBS+= -Llib/bin -lpdcurses
CPPFLAGS+= -Ilib/include
endif

ifndef PDCURSES_BACKEND
Expand All @@ -31,9 +31,10 @@ endif

build: build-pdcurses
build: $(OBJS)
cp lib/miniaudio/miniaudio.h lib/include/miniaudio.h
$(CXX) $(CPPFLAGS) -o Spylike-$(VER) $(OBJS) $(LDLIBS)

debug: CPPFLAGS+= -g
debug: CPPFLAGS+= -g -O0
debug: build

build-pdcurses:
Expand All @@ -45,7 +46,7 @@ else # BEGIN PDCURSES BUILD BLOCK
cp lib/PDCurses/curses.h lib/include/curses.h
cp lib/PDCurses/panel.h lib/include/panel.h
ifeq ($(PDCURSES_BACKEND), wincon)
cd lib/PDCurses/wincon && $(MAKE)
cd lib/PDCurses/wincon && $(MAKE) UTF8=Y WIDE=Y
cp lib/PDCurses/wincon/pdcurses.a lib/bin/libpdcurses.a
else ifeq ($(PDCURSES_BACKEND), x11)
cd lib/PDCurses/x11 && ./configure
Expand Down
Binary file added Spylike-TestSuite-vA1.exe
Binary file not shown.
67 changes: 67 additions & 0 deletions audio/audio.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#define MINIAUDIO_IMPLEMENTATION
#include "logger.h"
#include "miniaudio.h"

#include "audio.h"

#include <memory>

extern SpylikeLogger LOGGER;

void AudioManager::on_event(Event& e) {
if (e.type == "AUDIO_PlayMusic") {
SpylikeEvents::AudioPlayEvent& ap = dynamic_cast<SpylikeEvents::AudioPlayEvent&>(e);
playMusic(ap.sound, ap.volume);
}
else if (e.type == "AUDIO_PauseMusic") {
pauseMusic();
}
}

MiniaudioManager::MiniaudioManager(std::string rootPath) : rootPath{rootPath} {
LOGGER.log("Initalizing audio manager", DEBUG);
engine = new ma_engine;
ma_result result = ma_engine_init(NULL, engine);
if (result != MA_SUCCESS) throw "Error initalizing audio engine.";
}

void MiniaudioManager::playMusic(std::string track, float volume) {
LOGGER.log("Playing music " + track, DEBUG);
if (playing) stopMusic();
playing = true;
cMusic = new ma_sound;
std::string path = rootPath + "music/" + track;
const char* path_str = path.c_str();
ma_result res = ma_sound_init_from_file(engine, path_str, 0, NULL, NULL, cMusic);
ma_sound_set_volume(cMusic, volume);
ma_sound_set_looping(cMusic, true);
ma_sound_start(cMusic);
}

void MiniaudioManager::playSound(std::string sound, float volume) {
const char* path = (rootPath + "sound/" + sound).c_str();
ma_engine_play_sound(engine, path, NULL);
}

void MiniaudioManager::stopMusic() {
LOGGER.log("Stopping music", DEBUG);
if (cMusic && engine && playing) {
ma_sound_uninit(cMusic);
delete cMusic;
}
cMusic = nullptr;
playing = false;
}

void MiniaudioManager::pauseMusic() {
LOGGER.log("Pausing music", DEBUG);
if (cMusic) ma_sound_stop(cMusic);
}

void MiniaudioManager::resumeMusic() {
if (cMusic) ma_sound_start(cMusic);
}

void MiniaudioManager::setMusicVolume(float volume) {
if (cMusic) ma_sound_set_volume(cMusic, volume);
}
27 changes: 27 additions & 0 deletions events.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
STANDARD EVENT TYPES

Input:
INPUT_KeyPress : Of type KeyInputEvent. For any keypress, emitted by InputManager.

Graphics:
CAMERA_MoveUp: Moves the camera up by one unit. (CameraEvent)
CAMERA_MoveDown: Moves the camera down by one unit. (CameraEvent)
CAMERA_MoveRight: Moves the camera right by one unit. (CameraEvent)
CAMERA_MoveLeft: Moves the camera left by one unit. (CameraEvent)
CAMERA_Move: Moves the camera to pos specified in CameraEvent.pos.

Audio:
AUDIO_PlayMusic: Plays the music with filepath [rootPath]/AudioPlayEvent.sound and volume AudioPlayEvent.volume
AUDIO_PauseMusic: Pauses any currently playing music

Game:
GAME_PlayerDeath: Emitted when the Player reaches 0 health (or some other death-causing event)
GAME_PlayerHurt: Emitted when the player is hurt, PlayerHurtEvent.health gives *current* health (after hurt)
MENU_Show: Shows the menu with id specified in MenuEvent.menuID
MENU_Close: Closes any active menus
MENU_ButtonClick: Calls when any button is clicked, ID given in MenuButtonEvent.buttonID
Standard button ID behaviors: Buttons with id "close" close the menu
LEVEL_change: Changes the level to LevelChangeEvent.levelPath
GAME_KeyCollect: The key for the final boss door was collected.
GAME_DoorRequest: Event for the door to check whether it can be opened.
GAME_DoorResponse: Response from the game manager about GAME_DoorRequest, result in bool DoorResponse.result.
135 changes: 116 additions & 19 deletions game/UI/menus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,17 @@
#include "rendering.h"
#include "event.h"
#include "logger.h"
#include <curses.h>
#include <string>
#include <stdexcept>
#include <memory>

extern SpylikeLogger LOGGER;

MenuButton::MenuButton(int width, int height, std::string buttonText, std::string buttonID) : width{width}, height{height}, text{buttonText}, buttonID{buttonID} {}
MenuButton::MenuButton(Coordinate pos, int width, int height, std::string buttonText, std::string buttonID) : pos{pos}, width{width}, height{height}, text{buttonText}, buttonID{buttonID} {}

void MenuButton::click() {
auto ev = SpylikeEvents::MenuButtonEvent("ButtonClickEvent", buttonID);
auto ev = SpylikeEvents::MenuButtonEvent("MENU_ButtonClick", buttonID);
eventManager->emit(ev);
}

Expand All @@ -25,11 +27,11 @@ void MenuButton::draw(GeometryRenderer& painter) {
drawnText = text.substr(0, width - 5) + "...";
}
}
Coordinate topLeft = Coordinate(tile->pos.x, tile->pos.y);
Coordinate bottomRight = Coordinate(tile->pos.x + width - 1, tile->pos.y + height - 1);
Coordinate topLeft = pos;
Coordinate bottomRight = Coordinate(pos.x + width - 1, pos.y + height - 1);
painter.drawBox(topLeft, bottomRight, "UI");
Coordinate drawOffset = Coordinate(width/2 - drawnText.length()/2 + tile->pos.x,
height/2 + tile->pos.y);
Coordinate drawOffset = Coordinate(width/2 - drawnText.length()/2 + pos.x,
height/2 + pos.y);
painter.drawString(drawOffset, drawnText, "UI");
}

Expand All @@ -41,19 +43,51 @@ void MenuButton::on_event(Event& e) {}

void MenuButton::on_update() {}

void Menu::draw(GeometryRenderer& painter) {
Coordinate selectionPos = buttons.find(currentSelection)->second.pos;
Coordinate arrowPos = Coordinate(selectionPos.x + buttons.find(currentSelection)->second.width/2, selectionPos.y - 1);
painter.draw(arrowPos, 'v', "UI");
painter.draw(Coordinate(arrowPos.x, arrowPos.y-1), '|', "UI");
for (auto& buttonPair : buttons) {
buttonPair.second.draw(painter);
}
}

void PauseMenu::draw(GeometryRenderer& painter) {
/*
painter.drawString(Coordinate(1, 1), ""
"|||\n"
"| |\n"
"| | || | | ||||| |||||||\n"
"|||| | | | | | | \n"
"| |||||| | | ||||| |||||||\n"
"| | | | | | | \n"
"| | | |||||| ||||| |||||||\n", "UI");
*/
painter.drawString(Coordinate(painter.getScreenWidth()/2-5, 1), "PAUSED!", "UI");
Menu::draw(painter);
}

void GameOverMenu::draw(GeometryRenderer& painter) {
painter.drawString(Coordinate(painter.getScreenWidth()/2-8, 1), "GAME OVER!", "UI");
Menu::draw(painter);
}

void StartMenu::draw(GeometryRenderer& painter) {
painter.drawString(Coordinate(painter.getScreenWidth()/2-12, 1), "WELCOME TO SPYLIKE!", "UI");
painter.drawString(Coordinate(painter.getScreenWidth()/2-7, 2), "CONTROLS:", "UI");
painter.drawString(Coordinate(painter.getScreenWidth()/2-10, 3), "W,A,S,D MOVEMENT", "UI");
painter.drawString(Coordinate(painter.getScreenWidth()/2-9, 4), "V,B,N,G ATTACK", "UI");
painter.drawString(Coordinate(painter.getScreenWidth()/2-9, 5), "ESC PAUSE", "UI");
Menu::draw(painter);
}

void Menu::draw(GeometryRenderer& painter) {}

// pos is *relative* to menu
void Menu::addButton(std::shared_ptr<MenuButton> button, Coordinate pos) {
if (!tile) {
throw std::runtime_error("Menu must be registered before adding buttons");
}
buttons.insert({button->getButtonID(), button});
selectionList.push(button->getButtonID());
world->registerEntity(button, tile->pos + pos);
addChild(button);
currentSelection = button->getButtonID();
void Menu::addButton(MenuButton button) {
buttons.insert({button.getButtonID(), button});
selectionList.push(button.getButtonID());
selectNext();
}

void Menu::setSelection(std::string buttonID) {
Expand All @@ -70,10 +104,73 @@ void Menu::selectNext() {

void Menu::click() {
if (currentSelection != "") {
buttons[currentSelection]->click();
buttons.find(currentSelection)->second.click();
}
}

void Menu::on_event(Event& e) {}
void Menu::on_event(Event& e) {
if (e.type == "INPUT_KeyPress") {
SpylikeEvents::KeyInputEvent& ke = dynamic_cast<SpylikeEvents::KeyInputEvent&>(e);
if (ke.c == ' ' || ke.c == KEY_ENTER) {
click();
}
else if (ke.c == 'w' || ke.c == 'a' || ke.c == 's' || ke.c == 'd') {
selectNext();
}
}
}

void Menu::on_update() {
for (auto& buttonPair : buttons) {
buttonPair.second.update();
}
}

// must set ID before initalization
void Menu::on_init() {
assert(ID != -1);
int nextID = ID+1;
for (auto& buttonPair : buttons) {
buttonPair.second.setID(nextID);
nextID++;
buttonPair.second.init(eventManager);
}
}

namespace SpylikeMenus {
std::shared_ptr<Menu> testMenu() {
Menu menu(80, 40);
MenuButton button(Coordinate(4, 4), 10, 5, "hello!", "close");
MenuButton button2(Coordinate(25, 4), 10, 5, "world!", "testButton2");
menu.addButton(button);
menu.addButton(button2);
return std::make_shared<Menu>(menu);
}
std::shared_ptr<Menu> pauseMenu() {
PauseMenu menu(80, 40);
MenuButton button(Coordinate(12, 10), 15, 5, "Resume", "close");
MenuButton button2(Coordinate(45, 10), 15, 5, "Quit", "quit");
menu.addButton(button);
menu.addButton(button2);
return std::make_shared<PauseMenu>(menu);
}
std::shared_ptr<Menu> gameOver() {
GameOverMenu menu(80, 40);
MenuButton button(Coordinate(12, 10), 15, 5, "Start over", "restart");
MenuButton button2(Coordinate(45, 10), 15, 5, "Quit", "quit");
menu.addButton(button);
menu.addButton(button2);
return std::make_shared<GameOverMenu>(menu);
}
std::shared_ptr<Menu> startMenu() {
StartMenu menu(80, 40);
MenuButton button(Coordinate(12, 10), 15, 5, "Start game", "restart");
MenuButton button2(Coordinate(45, 10), 15, 5, "Quit", "quit");
menu.addButton(button);
menu.addButton(button2);
return std::make_shared<StartMenu>(menu);
}

}

void Menu::on_update() {}
Loading

0 comments on commit ac5eede

Please sign in to comment.