[Added] Ability to serve the project using nginx on localhost:4600

This commit is contained in:
Ninjaws
2024-12-19 22:40:59 +01:00
parent c0bfe9bd13
commit 33f6504b6c
10 changed files with 220 additions and 121 deletions
+36 -1
View File
@@ -63,4 +63,39 @@ RUN cd libs/raylib/src && \
emar rcs libraylib.a rcore.o rshapes.o rtextures.o rtext.o rmodels.o utils.o raudio.o && \ emar rcs libraylib.a rcore.o rshapes.o rtextures.o rtext.o rmodels.o utils.o raudio.o && \
cd ../.. cd ../..
CMD ["bash"] # CMD ["bash"]
FROM development as build
RUN mkdir dist html src include assets
COPY include include
COPY src src
COPY html html
COPY assets assets
# CMD ["tail", "-f", "/dev/null"]
# Run the production build command to generate game.js and game.wasm
RUN source /app/libs/emsdk/emsdk_env.sh && \
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
# CMD ["tail", "-f", "/dev/null"]
FROM nginx:alpine as production
# Remove the default nginx index.html
RUN rm -rf /usr/share/nginx/html/*
# Copy the generated files from the production stage into the Nginx html directory
COPY --from=build /app/dist/ /usr/share/nginx/html/
COPY --from=build /app/html/index.html /usr/share/nginx/html/
# Expose port 80 to allow Nginx to serve the files
EXPOSE 80
# Start Nginx server
CMD ["nginx", "-g", "daemon off;"]
+38 -1
View File
@@ -1,2 +1,39 @@
# WebJelly-Rescue # WebJelly-Rescue
Jelly Rescue, but now for the web! [Jelly Rescue](https://github.com/Ninjaws/JellyGame), but now for the web!
## Installation
### Install Docker
- On Windows and Mac
```
Install Docker Desktop
Windows: https://docs.docker.com/desktop/install/windows-install/
Mac: https://docs.docker.com/desktop/install/mac-install/
```
- On Linux
```bash
# For Debian-based systems
sudo apt install -y docker.io
sudo apt install docker-compose
#For Arch-based systems
sudo pacman -S docker.io
sudo pacman -S docker-compose
# Making Docker run now and on startup
sudo systemctl start docker
sudo systemctl enable docker
# Using the CLI without sudo
sudo usermod -aG docker $USER
sudo reboot
```
## How to run
- Navigate to the root of the project
- Open a terminal
- Start the container:
```bash
docker compose up #(might take a few minutes to build)
```
- Visit https://localhost:4600 to play the game locally
- Or visit play it live [here!](https://jelly.ianvink.nl)
+13
View File
@@ -0,0 +1,13 @@
services:
frontend:
build:
context: .
dockerfile: Dockerfile
target: production
image: jelly-rescue-prod
container_name: jelly-rescue-prod-cont
ports:
- "4600:80"
restart: always
cpu_period: 100000 # Default is 100,000 microseconds (100ms)
cpu_quota: 30000 # 5% of the total CPU time
-56
View File
@@ -1,56 +0,0 @@
<!doctypehtml>
<html lang=EN-us>
<head>
<meta charset=utf-8>
<meta content="text/html; charset=utf-8" http-equiv=Content-Type>
<title>raylib web game</title>
<meta content="raylib web game" name=title>
</head>
<style>
html {
/* width:fit-content; */
width: 100vw;
height:100vh;
}
body {
margin: 0px;
/* overflow: hidden; */
/* background-color: black; */
width:100%;
height:100%;
display:flex;
cursor:none;
}
canvas {
margin:auto;
}
</style>
<body>
<canvas id="canvas" width="640" height="544"></canvas>
<p id="output" />
<script>
var Module = {
print: (function() {
var element = document.getElementById('output');
if (element) element.value = ''; // clear browser cache
return function(text) {
if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' ');
console.log(text);
if (element) {
element.value += text + "\n";
element.scrollTop = element.scrollHeight; // focus on bottom
}
};
})(),
canvas: (function() {
var canvas = document.getElementById('canvas');
return canvas;
})()
};
</script>
<script src=game.js async></script>
</body>
</html>
+114
View File
@@ -0,0 +1,114 @@
<!doctypehtml>
<html lang=EN-us>
<head>
<meta charset=utf-8>
<meta content="text/html; charset=utf-8" http-equiv=Content-Type>
<title>Jelly Rescue</title>
<meta content="Jelly Rescue" name=title>
<link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap" rel="stylesheet">
</head>
<style>
html {
width: 100vw;
height:100vh;
background: #0C0D14;
}
body {
margin: 0px;
width:100%;
height:100%;
display:flex;
}
canvas {
margin:auto;
cursor:none;
background: black;
}
.media-player {
margin:auto;
padding: 0.5rem 0.5rem 0.5rem 0.5rem;
border-radius: 0.4rem;
display: flex;
flex-direction: column;
background: rgb(33, 34, 51);
box-shadow: inset 0px 0px 10px rgba(0, 0, 0, 0.4);
overflow: hidden;
}
.game-title {
color:ivory;
margin:0.3rem 0.5rem 0.8rem 0.5rem;
font-size: larger;
font-family: 'Press Start 2P', cursive;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.6);
}
.links {
display: flex;
justify-content: space-between;
margin:1.2rem 0.5rem 0 0.4rem;
}
a {
height: 24px;
}
.bi-github {
margin-top:0.1rem;
width: 24px;
height: 24px;
fill: white;
}
.bi-github:hover {
transform: scale(1.2);
}
@media (max-width: 643px) {
.media-player {
width: 100%; /* Make media-player take full width */
}
canvas {
width:100%;
}
.game-title {
font-size:medium;
}
}
</style>
<body>
<div class="media-player">
<canvas id="canvas" width="640" height="544"></canvas>
<div class="links">
<span class="game-title">Jelly Rescue</span>
<a href="https://github.com/Ninjaws/WebJelly-Rescue" class="github-link" target="_blank">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-github" viewBox="0 0 16 16">
<path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27s1.36.09 2 .27c1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.01 8.01 0 0 0 16 8c0-4.42-3.58-8-8-8"/>
</svg>
</a>
</div>
</div>
<p id="output" />
<script>
var Module = {
print: (function() {
var element = document.getElementById('output');
if (element) element.value = '';
return function(text) {
if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' ');
console.log(text);
if (element) {
element.value += text + "\n";
element.scrollTop = element.scrollHeight;
}
};
})(),
canvas: (function() {
var canvas = document.getElementById('canvas');
return canvas;
})()
};
</script>
<script src=game.js async></script>
</body>
</html>
+1 -1
View File
@@ -43,7 +43,7 @@ public:
private: private:
TextureWrapper texture; TextureWrapper texture;
bool hit; // Whether a PBullet has hit the crate bool hit = false; // Whether a PBullet has hit the crate
}; };
#endif #endif
+2
View File
@@ -14,6 +14,7 @@
#include "services/BulletService.h" #include "services/BulletService.h"
#include "entities/Text.h" #include "entities/Text.h"
#include <sstream> #include <sstream>
#include <iostream>
class Game class Game
{ {
@@ -49,6 +50,7 @@ public:
this->crosshair = TextureWrapper(AssetService::getInstance().getSprite(ESprite::CROSSHAIR), {15, 15}, {0, 0}, {0, 0, 15, 15}); this->crosshair = TextureWrapper(AssetService::getInstance().getSprite(ESprite::CROSSHAIR), {15, 15}, {0, 0}, {0, 0, 15, 15});
CollectableService::getInstance().initCollectables(); CollectableService::getInstance().initCollectables();
std::cout << "Initting" << std::endl;
initHud(); initHud();
initPauseScreen(); initPauseScreen();
+2 -2
View File
@@ -10,13 +10,13 @@ class Jelly
public: public:
Jelly(){ Jelly(){
this->texture = TextureWrapper(AssetService::getInstance().getSprite(ESprite::JELLY),{32,32}); this->texture = TextureWrapper(AssetService::getInstance().getSprite(ESprite::JELLY),{32,32});
AssetService::getInstance().playSound(ESound::JELLY_FREED); // AssetService::getInstance().playSound(ESound::JELLY_FREED);
} }
Jelly(Vector2 startPos) Jelly(Vector2 startPos)
{ {
this->startPosition = startPos; this->startPosition = startPos;
this->texture = TextureWrapper(AssetService::getInstance().getSprite(ESprite::JELLY),{32,32},startPos); this->texture = TextureWrapper(AssetService::getInstance().getSprite(ESprite::JELLY),{32,32},startPos);
AssetService::getInstance().playSound(ESound::JELLY_FREED); // AssetService::getInstance().playSound(ESound::JELLY_FREED);
} }
void logic() void logic()
+13 -60
View File
@@ -73,23 +73,16 @@ std::vector<Vector2i> Enemy::getCorners()
float top = texture.getPosition().y + velocity.y; float top = texture.getPosition().y + velocity.y;
int tileSize = MapService::getInstance().getMap().getTileSize(); int tileSize = MapService::getInstance().getMap().getTileSize();
// Vector2i leftTop(Vector2i((int)left / tileSize, (int)(top + 5) / 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 leftBottom(Vector2i((int)left / tileSize, (int)(bottom - 5) / 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 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+ (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 bottomLeft(Vector2i((int)(left + 5) / tileSize, (int)bottom / tileSize));
Vector2i bottomRight(Vector2i((int)(right - 5) / tileSize, (int)bottom / tileSize)); // -5 to separate bottom from side Vector2i bottomRight(Vector2i((int)(right - 5) / tileSize, (int)bottom / tileSize));
std::vector<Vector2i> corners; std::vector<Vector2i> corners;
corners.push_back(leftCenter); corners.push_back(leftCenter);
corners.push_back(rightCenter); corners.push_back(rightCenter);
// corners.push_back(leftBottom);
// corners.push_back(rightTop);
// corners.push_back(rightBottom);
corners.push_back(bottomLeft); corners.push_back(bottomLeft);
corners.push_back(bottomRight); corners.push_back(bottomRight);
@@ -105,7 +98,6 @@ void Enemy::animate()
Rectangle sourceRect = this->texture.getSourceRect(); Rectangle sourceRect = this->texture.getSourceRect();
sourceRect.x = spriteAnimation.x * this->texture.getSize().x; sourceRect.x = spriteAnimation.x * this->texture.getSize().x;
sourceRect.y = spriteAnimation.y * this->texture.getSize().y; sourceRect.y = spriteAnimation.y * this->texture.getSize().y;
// sourceRect.x = std::fmod(sourceRect.x, 3 * this->texture.getSize().x);
this->texture.setSourceRect(sourceRect); this->texture.setSourceRect(sourceRect);
prevFrame = GetTime(); prevFrame = GetTime();
} }
@@ -154,7 +146,6 @@ void Enemy::fall()
void Enemy::detectPlayer() void Enemy::detectPlayer()
{ {
// playerSpotted = false;
Player &player = PlayerService::getInstance().getPlayer(); Player &player = PlayerService::getInstance().getPlayer();
if (this->health > 0) if (this->health > 0)
{ {
@@ -168,8 +159,6 @@ void Enemy::detectPlayer()
float gunRotationLeft = atan2(playerCenter.y - enemyCenter.y, float gunRotationLeft = atan2(playerCenter.y - enemyCenter.y,
enemyCenter.x - playerCenter.x); enemyCenter.x - playerCenter.x);
float target = -gunRotationLeft * 180 / M_PI; 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)); this->gunLeft.setRotation(std::min(this->gunLeft.getRotation() + aimSpeed, target));
} }
else if (spriteAnimation.y == Right && player.getTexture().getPosition().x - this->texture.getPosition().x <= spottingRange && else if (spriteAnimation.y == Right && player.getTexture().getPosition().x - this->texture.getPosition().x <= spottingRange &&
@@ -179,8 +168,6 @@ void Enemy::detectPlayer()
float gunRotationRight = atan2(playerCenter.y - enemyCenter.y, float gunRotationRight = atan2(playerCenter.y - enemyCenter.y,
playerCenter.x - enemyCenter.x); playerCenter.x - enemyCenter.x);
float target = gunRotationRight * 180 / M_PI; float target = gunRotationRight * 180 / M_PI;
// this->gunRight.setRotation(gunRotationRight * 180 / M_PI);
this->gunRight.setRotation(std::max(this->gunRight.getRotation() - aimSpeed, target)); this->gunRight.setRotation(std::max(this->gunRight.getRotation() - aimSpeed, target));
} }
@@ -195,8 +182,8 @@ void Enemy::detectPlayer()
{ {
this->playerSpotted = false; this->playerSpotted = false;
/** Slowly ease the gun back to default position */ /** Slowly ease the gun back to default position */
this->gunLeft.setRotation(std::max(this->gunLeft.getRotation() - aimSpeed/2.0f, 0.0f)); 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)); this->gunRight.setRotation(std::min(this->gunRight.getRotation() + aimSpeed / 2.0f, 0.0f));
} }
} }
} }
@@ -215,49 +202,15 @@ void Enemy::shoot()
float offsetDistance = this->gunLeft.getSize().x - this->gunLeft.getSize().x / 3; 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 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}; Vector2 enemyCenter = {texture.getPosition().x + texture.getSize().x / 2.0f, texture.getPosition().y + texture.getSize().y / 2.0f};
// if (spriteAnimation.y == Left) float angleShot = atan2(playerCenter.y - enemyCenter.y,
// { playerCenter.x - enemyCenter.x);
float angleShot = atan2(playerCenter.y - enemyCenter.y, float offsetX = cos(angleShot) * offsetDistance;
playerCenter.x - enemyCenter.x); 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};
// float gunRotationRadians = this->gunLeft.getRotation() * (M_PI / 180.0f); // Convert degrees to radians BulletService::getInstance().addEnemyBullet(bulletStartLocation, angleShot);
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);
// }
} }
} }
+1
View File
@@ -11,6 +11,7 @@ void PBullet::objCollision()
this->position.y + this->size > crate.getObject().getPosition().y && this->position.y-this->size < crate.getObject().getPosition().y + crate.getObject().getSize().y) { this->position.y + this->size > crate.getObject().getPosition().y && this->position.y-this->size < crate.getObject().getPosition().y + crate.getObject().getSize().y) {
crate.setHit(true); crate.setHit(true);
AssetService::getInstance().playSound(ESound::CRATE_BREAK); AssetService::getInstance().playSound(ESound::CRATE_BREAK);
AssetService::getInstance().playSound(ESound::JELLY_FREED);
this->hasCollided = true; this->hasCollided = true;
} }
} }