diff --git a/.vscode/settings.json b/.vscode/settings.json
index 035ee7a..aed8e9a 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -55,6 +55,10 @@
"format": "cpp",
"text_encoding": "cpp",
"ratio": "cpp",
- "cinttypes": "cpp"
+ "cinttypes": "cpp",
+ "__verbose_abort": "cpp",
+ "cfenv": "cpp",
+ "cstring": "cpp",
+ "fstream": "cpp"
}
}
\ No newline at end of file
diff --git a/html/game.html b/html/game.html
new file mode 100644
index 0000000..a6ee798
--- /dev/null
+++ b/html/game.html
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+ raylib web game
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/include/entities/Bullet.h b/include/entities/Bullet.h
index db9f976..1c44314 100644
--- a/include/entities/Bullet.h
+++ b/include/entities/Bullet.h
@@ -27,7 +27,7 @@ public:
void draw()
{
- DrawCircleGradient(position.x, position.y, size, color, BLACK);
+ DrawCircleGradient(position.x, position.y, size, color, ORANGE);
}
bool getHasCollided()
diff --git a/include/entities/Enemy.h b/include/entities/Enemy.h
index db80e7d..a3c4d38 100644
--- a/include/entities/Enemy.h
+++ b/include/entities/Enemy.h
@@ -82,6 +82,7 @@ private:
float shotsPerSecond = 8.0f;
double lastShot;
bool playerSpotted = false;
+ float aimSpeed = 2.0f; // How quickly the enemy can angle its gun to match the player (and to return to default)
void walk();
void checkForCollision();
diff --git a/include/entities/Game.h b/include/entities/Game.h
index 0de6b30..a4b89ca 100644
--- a/include/entities/Game.h
+++ b/include/entities/Game.h
@@ -89,14 +89,15 @@ public:
CollectableService::getInstance().collectableLogic();
EnemyService::getInstance().enemyLogic();
- auto& player = PlayerService::getInstance().getPlayer();
+ auto &player = PlayerService::getInstance().getPlayer();
player.logic();
if (player.getTexture().getPosition().x > (StateService::getInstance().getScreenSize().x / 2.0f) &&
player.getTexture().getPosition().x + (StateService::getInstance().getScreenSize().x / 2.0f) < background.getBackgroundSize().x)
{
GameService::getInstance().getCamera().offset = {(StateService::getInstance().getScreenSize().x / 2.0f) + ((StateService::getInstance().getScreenSize().x / 2.0f) - player.getTexture().getPosition().x), StateService::getInstance().getScreenSize().y / 2.0f};
}
- if(player.isFinishReached()) {
+ if (player.isFinishReached())
+ {
StateService::getInstance().setScreen(EScreen::VICTORY);
}
}
@@ -124,7 +125,9 @@ public:
else if (GameService::getInstance().isGameOver())
{
drawGameOver();
- } else {
+ }
+ else
+ {
drawCrosshair();
}
EndDrawing();
@@ -154,9 +157,16 @@ private:
void initPauseScreen()
{
+#if defined(PLATFORM_WEB)
+ const int TOP_GAP = 100;
+ const int BOTTOM_GAP = 100;
+ const int AMNT_OF_BUTTONS = 2;
+#else
const int TOP_GAP = 100;
const int BOTTOM_GAP = 50;
const int AMNT_OF_BUTTONS = 4;
+#endif
+
const int TOTAL_SPACE = GetScreenHeight() - (TOP_GAP + BOTTOM_GAP);
const int SPACE_PER_ITEM = TOTAL_SPACE / AMNT_OF_BUTTONS;
@@ -166,13 +176,24 @@ private:
pauseScreenButtons.push_back(txt);
}
pauseScreenButtons[0].setColor(RED);
+
+#if defined(PLATFORM_WEB)
+ pauseScreenButtons[1].setText("Quit to Main Menu");
+#else
pauseScreenButtons[1].setText("Save Game");
pauseScreenButtons[2].setText("Quit to Main Menu");
pauseScreenButtons[3].setText("Quit to Desktop");
+#endif
for (int i = 0; i < AMNT_OF_BUTTONS; i++)
{
+#if defined(PLATFORM_WEB)
+ pauseScreenButtons[i].setPosition({(float)(GetScreenWidth() - pauseScreenButtons[i].getDimensions().x) / 2.0f, (float)TOP_GAP + SPACE_PER_ITEM * i + SPACE_PER_ITEM / 2.0f});
+
+#else
pauseScreenButtons[i].setPosition({(float)(GetScreenWidth() - pauseScreenButtons[i].getDimensions().x) / 2.0f, (float)TOP_GAP + SPACE_PER_ITEM * i});
+
+#endif
}
}
diff --git a/scripts/build_wasm.sh b/scripts/build_wasm.sh
index 5227541..79c09b7 100755
--- a/scripts/build_wasm.sh
+++ b/scripts/build_wasm.sh
@@ -3,7 +3,7 @@
# emcc $(find src/ -name "*.cpp") -o dist/game.js -Wno-missing-braces -I./include -I/app/libs/raylib/build/raylib/include -L/app/libs/raylib/src /app/libs/raylib/src/libraylib.a -s ALLOW_MEMORY_GROWTH=1 -s INITIAL_MEMORY=268435456 -s MAXIMUM_MEMORY=4294967296 -s --preload-file assets@/assets -s USE_GLFW=3 -DPLATFORM_WEB
-emcc $(find src/ -name "*.cpp") -o dist/game.js -Wno-missing-braces -I./include -I/app/libs/raylib/build/raylib/include -L/app/libs/raylib/src /app/libs/raylib/src/libraylib.a -s ALLOW_MEMORY_GROWTH=1 -s INITIAL_MEMORY=536870912 -s MAXIMUM_MEMORY=4294967296 -s --preload-file assets@/assets -s USE_GLFW=3 -s ASSERTIONS=2 -DPLATFORM_WEB
+emcc $(find src/ -name "*.cpp") -o dist/game.js -O3 -Wno-missing-braces -I./include -I/app/libs/raylib/build/raylib/include -L/app/libs/raylib/src /app/libs/raylib/src/libraylib.a -s ALLOW_MEMORY_GROWTH=1 -s INITIAL_MEMORY=536870912 -s MAXIMUM_MEMORY=4294967296 -s --preload-file assets@/assets -s USE_GLFW=3 -s ASSERTIONS=2 -DPLATFORM_WEB
# -I./include
# -L$LD_LIBRARY_PATH
# -I.
diff --git a/src/entities/Enemy.cpp b/src/entities/Enemy.cpp
index cffc960..3ab3b08 100644
--- a/src/entities/Enemy.cpp
+++ b/src/entities/Enemy.cpp
@@ -2,6 +2,7 @@
#include "services/PlayerService.h"
#include "services/MapService.h"
#include "services/BulletService.h"
+#include
void Enemy::logic()
{
@@ -74,10 +75,10 @@ std::vector Enemy::getCorners()
int tileSize = MapService::getInstance().getMap().getTileSize();
// Vector2i leftTop(Vector2i((int)left / tileSize, (int)(top + 5) / tileSize));
// Vector2i leftBottom(Vector2i((int)left / tileSize, (int)(bottom - 5) / tileSize));
- Vector2i leftCenter = Vector2i((int)left / tileSize, (int)(bottom - texture.getSize().y / 2.0) / tileSize);
+ Vector2i leftCenter = Vector2i((int)(left -(spriteAnimation.y == Left ? gunLeft.getSize().x*(2.0f/3.0f) : 0.0f)) / tileSize, (int)(bottom - texture.getSize().y / 2.0) / tileSize);
// Vector2i rightTop(Vector2i((int)right / tileSize, (int)(top + 5) / tileSize));
// Vector2i rightBottom(Vector2i((int)right / tileSize, (int)(bottom - 5) / tileSize));
- Vector2i rightCenter = Vector2i((int)right / tileSize, (int)(bottom - texture.getSize().y / 2.0) / tileSize);
+ Vector2i rightCenter = Vector2i((int)(right+ (spriteAnimation.y == Right ? gunRight.getSize().x*(2.0f/3.0f) : 0.0f)) / tileSize, (int)(bottom - texture.getSize().y / 2.0) / tileSize);
Vector2i bottomLeft(Vector2i((int)(left + 5) / tileSize, (int)bottom / tileSize)); // +5 to separate bottom from side
Vector2i bottomRight(Vector2i((int)(right - 5) / tileSize, (int)bottom / tileSize)); // -5 to separate bottom from side
@@ -158,15 +159,29 @@ void Enemy::detectPlayer()
if (this->health > 0)
{
bool spotted = false;
+ Vector2 playerCenter = {player.getTexture().getPosition().x + player.getTexture().getSize().x / 2.0f, player.getTexture().getPosition().y + player.getTexture().getSize().y / 2.0f};
+ Vector2 enemyCenter = {texture.getPosition().x + texture.getSize().x / 2.0f, texture.getPosition().y + texture.getSize().y / 2.0f};
if (this->spriteAnimation.y == Left && this->texture.getPosition().x - player.getTexture().getPosition().x <= spottingRange &&
this->texture.getPosition().x - player.getTexture().getPosition().x > 55 && this->texture.getPosition().y + this->texture.getSize().y >= player.getTexture().getPosition().y)
{
spotted = true;
+ float gunRotationLeft = atan2(playerCenter.y - enemyCenter.y,
+ enemyCenter.x - playerCenter.x);
+ float target = -gunRotationLeft * 180 / M_PI;
+ // float delta = target - this->gunLeft.getRotation();
+ // float sign = std::copysign(1.0f, delta);
+ this->gunLeft.setRotation(std::min(this->gunLeft.getRotation() + aimSpeed, target));
}
else if (spriteAnimation.y == Right && player.getTexture().getPosition().x - this->texture.getPosition().x <= spottingRange &&
player.getTexture().getPosition().x - this->texture.getPosition().x > 55 && this->texture.getPosition().y + this->texture.getSize().y >= player.getTexture().getPosition().y)
{
spotted = true;
+ float gunRotationRight = atan2(playerCenter.y - enemyCenter.y,
+ playerCenter.x - enemyCenter.x);
+ float target = gunRotationRight * 180 / M_PI;
+
+ // this->gunRight.setRotation(gunRotationRight * 180 / M_PI);
+ this->gunRight.setRotation(std::max(this->gunRight.getRotation() - aimSpeed, target));
}
/** Don't set it again if the detection continues */
@@ -179,6 +194,9 @@ void Enemy::detectPlayer()
else if (!spotted)
{
this->playerSpotted = false;
+ /** Slowly ease the gun back to default position */
+ this->gunLeft.setRotation(std::max(this->gunLeft.getRotation() - aimSpeed/2.0f, 0.0f));
+ this->gunRight.setRotation(std::min(this->gunRight.getRotation() + aimSpeed/2.0f, 0.0f));
}
}
}
@@ -189,25 +207,57 @@ void Enemy::shoot()
/** Stop shooting if the player is dead (and falling out of the map) */
if (player.getHealth() > 0 && playerSpotted && GetTime() - this->lastShot >= (1 / this->shotsPerSecond))
{
+
this->lastShot = GetTime();
// Play shooting sound
AssetService::getInstance().playSound(ESound::SHOOT);
- if ((player.getTexture().getPosition().x > this->texture.getPosition().x + this->gunLeft.getSize().x && spriteAnimation.y == Right) ||
- (player.getTexture().getPosition().x + (this->gunLeft.getSize().x / 2) < this->texture.getPosition().x && spriteAnimation.y == Left))
- {
+ float offsetDistance = this->gunLeft.getSize().x - this->gunLeft.getSize().x / 3;
+ Vector2 playerCenter = {player.getTexture().getPosition().x + player.getTexture().getSize().x / 2.0f, player.getTexture().getPosition().y + player.getTexture().getSize().y / 2.0f};
+ Vector2 enemyCenter = {texture.getPosition().x + texture.getSize().x / 2.0f, texture.getPosition().y + texture.getSize().y / 2.0f};
+
- float angleShot = atan2(player.getTexture().getPosition().y - (this->texture.getPosition().y + this->texture.getSize().y / 2.0),
- player.getTexture().getPosition().x - (this->texture.getPosition().x + this->texture.getSize().x / 2.0));
+ // if (spriteAnimation.y == Left)
+ // {
- /** Making the bullet originate from the gun's mouth */
- float offsetDistance = this->gunLeft.getSize().x - this->gunLeft.getSize().x / 3;
+ float angleShot = atan2(playerCenter.y - enemyCenter.y,
+ playerCenter.x - enemyCenter.x);
+
+ // float gunRotationRadians = this->gunLeft.getRotation() * (M_PI / 180.0f); // Convert degrees to radians
float offsetX = cos(angleShot) * offsetDistance;
float offsetY = sin(angleShot) * offsetDistance;
Vector2 bulletStartLocation = {this->texture.getPosition().x + this->texture.getSize().x / 2.0f + offsetX,
this->texture.getPosition().y + this->texture.getSize().y / 2.0f + offsetY};
BulletService::getInstance().addEnemyBullet(bulletStartLocation, angleShot);
- }
+ // }
+
+ // if ((player.getTexture().getPosition().x > this->texture.getPosition().x + this->gunLeft.getSize().x && spriteAnimation.y == Right) ||
+ // (player.getTexture().getPosition().x + (this->gunLeft.getSize().x / 2) < this->texture.getPosition().x && spriteAnimation.y == Left))
+ // {
+
+ // // float gunRotationRight = atan2(GameService::getInstance().getMouseWorldPos().y - (this->texture.getPosition().y + this->texture.getSize().y / 2.0),
+ // // GameService::getInstance().getMouseWorldPos().x - (this->texture.getPosition().x + this->texture.getSize().x / 2.0));
+ // // this->gunRight.setRotation(gunRotationRight * 180 / M_PI);
+
+ // float angleShot = atan2(player.getTexture().getPosition().y - (this->texture.getPosition().y + this->texture.getSize().y / 2.0),
+ // player.getTexture().getPosition().x - (this->texture.getPosition().x + this->texture.getSize().x / 2.0));
+
+ // // this->gunRight.setRotation(angleShot * 180 / M_PI);
+ // // this->gunLeft.setRotation(-angleShot * 180 / M_PI);
+ // /** Making the bullet originate from the gun's mouth */
+ // float offsetDistance = this->gunLeft.getSize().x - this->gunLeft.getSize().x / 3;
+ // float offsetX = cos(angleShot) * offsetDistance;
+ // float offsetY = sin(angleShot) * offsetDistance;
+ // Vector2 bulletStartLocation = {this->texture.getPosition().x + this->texture.getSize().x / 2.0f + offsetX,
+ // this->texture.getPosition().y + this->texture.getSize().y / 2.0f + offsetY};
+
+ // // BulletService::getInstance().addEnemyBullet(bulletStartLocation, angleShot);
+ // }
+ // else
+ // {
+ // // this->gunRight.setRotation(0);
+ // // this->gunLeft.setRotation(0);
+ // }
}
}
\ No newline at end of file
diff --git a/src/screens/MainScreen.cpp b/src/screens/MainScreen.cpp
index 1371361..d13339e 100644
--- a/src/screens/MainScreen.cpp
+++ b/src/screens/MainScreen.cpp
@@ -6,9 +6,16 @@
MainScreen::MainScreen()
{
+#if defined(PLATFORM_WEB)
+ const int TOP_GAP = 100;
+ const int BOTTOM_GAP = 100;
+ const int AMNT_OF_BUTTONS = 2;
+#else
const int TOP_GAP = 100;
const int BOTTOM_GAP = 50;
const int AMNT_OF_BUTTONS = 4;
+#endif
+
const int TOTAL_SPACE = GetScreenHeight() - (TOP_GAP + BOTTOM_GAP);
const int SPACE_PER_ITEM = TOTAL_SPACE / AMNT_OF_BUTTONS;
@@ -18,13 +25,22 @@ MainScreen::MainScreen()
buttons.push_back(txt);
}
buttons[0].setColor(RED);
+#if defined(PLATFORM_WEB)
+ buttons[1].setText("tutorial");
+#else
buttons[1].setText("load game");
buttons[2].setText("tutorial");
buttons[3].setText("quit");
+#endif
for (int i = 0; i < AMNT_OF_BUTTONS; i++)
{
+#if defined(PLATFORM_WEB)
+ buttons[i].setPosition({(float)(GetScreenWidth() - buttons[i].getDimensions().x) / 2.0f, (float)TOP_GAP + SPACE_PER_ITEM * i + SPACE_PER_ITEM / 2.0f});
+
+#else
buttons[i].setPosition({(float)(GetScreenWidth() - buttons[i].getDimensions().x) / 2.0f, (float)TOP_GAP + SPACE_PER_ITEM * i});
+#endif
}
/** Will be ignored if already active (like when coming from the TitleScreen) */
@@ -45,7 +61,6 @@ void MainScreen::logic()
clickLogic();
}
-
void MainScreen::mouseLogic()
{
for (int i = 0; i < buttons.size(); i++)
@@ -78,7 +93,7 @@ void MainScreen::keyboardLogic()
{
buttons[hoveredButton].setColor(WHITE);
/** Move up or down depending on the pressed button. +4 is used so that -1 becomes 3 (the last button) */
- hoveredButton = ((hoveredButton - (InputService::getInstance().isKeyPressed(KEY_S) ? -1 : 1)) + 4) % 4;
+ hoveredButton = ((hoveredButton - (InputService::getInstance().isKeyPressed(KEY_S) ? -1 : 1)) + buttons.size()) % buttons.size();
buttons[hoveredButton].setColor(RED);
}
}