[Added] The ability to fire bullets to the player

This commit is contained in:
Ninjaws
2024-12-13 22:04:33 +01:00
parent 88e0b7cb05
commit 55792bb954
7 changed files with 266 additions and 9 deletions
+83
View File
@@ -0,0 +1,83 @@
#ifndef BULLET_H
#define BULLET_H
#include "raylib.h"
#include <cmath>
#include "entities/TextureWrapper.h"
#include "entities/Vector2i.h"
#include "services/MapService.h"
#include <iostream>
class Bullet
{
public:
Bullet() {}
Bullet(Vector2 pos, float direction)
{
this->position = pos;
this->direction = direction;
std::cout << direction << std::endl;
}
// ~Bullet() {}
void logic()
{
move();
hasCollided = false;
envCollision();
objCollision();
// // detectCollision();
}
void draw()
{
DrawCircle(position.x, position.y, size, color);
}
bool getHasCollided()
{
return this->hasCollided;
}
protected:
Color color = RED;
private:
// TextureWrapper object;
Vector2 position;
float direction;
float velocity = 15.0f;
int size = 7;
bool hasCollided = false;
void move()
{
// float directionInRadians = this->direction * M_PI / 180.0f;
position.x += velocity * cos(direction);
position.y += velocity * sin(direction);
}
void envCollision()
{
if (position.y < 0 || position.y > GetScreenHeight())
{
hasCollided = true;
return;
}
const int tileSize = MapService::getInstance().getMap().getTileSize();
Vector2i tilePos = Vector2i((int)this->position.x / tileSize, (int)this->position.y / tileSize);
if (MapService::getInstance().getMap().getColMap()[tilePos.y][tilePos.x] == 1)
{
hasCollided = true;
return;
}
}
virtual void objCollision() = 0;
// void handleCollision() {
// }
};
#endif
+20
View File
@@ -0,0 +1,20 @@
// #ifndef EBULLET_H
// #define EBULLET_H
// #include "Bullet.h"
// #include <iostream>
// class EBullet : public Bullet {
// public:
// EBullet() {}
// ~EBullet() {}
// void detectCollision() override {
// std::cout << "Enemy bullets" << std::endl;
// }
// private:
// };
// #endif
+19 -6
View File
@@ -10,14 +10,15 @@
#include "services/GameService.h" #include "services/GameService.h"
#include "entities/Player.h" #include "entities/Player.h"
#include "entities/Text.h" #include "entities/Text.h"
#include "entities/Bullet.h"
#include "entities/PBullet.h"
class Game class Game
{ {
public: public:
Game() Game()
{ {
GameService::getInstance().setGameOver(false); GameService::getInstance().resetGame();
GameService::getInstance().setPaused(false);
TextureWrapper wrapper1 = TextureWrapper(AssetService::getInstance().getBackground(EBackground::GAME1), {GetScreenWidth() * 2.0f, (float)GetScreenHeight()}, {0, 0}); TextureWrapper wrapper1 = TextureWrapper(AssetService::getInstance().getBackground(EBackground::GAME1), {GetScreenWidth() * 2.0f, (float)GetScreenHeight()}, {0, 0});
wrapper1.setSourceRect({0, 0, wrapper1.getSize().x, wrapper1.getSize().y}); wrapper1.setSourceRect({0, 0, wrapper1.getSize().x, wrapper1.getSize().y});
@@ -42,10 +43,8 @@ public:
camera.zoom = 1.0f; camera.zoom = 1.0f;
// this->camera = camera; // this->camera = camera;
GameService::getInstance().setCamera(camera); GameService::getInstance().setCamera(camera);
this->player = Player(); this->player = Player();
this->player.setPosition({200, 350}); this->player.setPosition({200, 350});
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});
initPauseScreen(); initPauseScreen();
@@ -81,7 +80,9 @@ public:
AudioService::getInstance().pauseMusic(); AudioService::getInstance().pauseMusic();
return; return;
} }
// this->camera.offset.x -= 1.5;
GameService::getInstance().bulletLogic();
this->player.logic(); this->player.logic();
if (this->player.getTexture().getPosition().x > (StateService::getInstance().getScreenSize().x / 2.0f)) if (this->player.getTexture().getPosition().x > (StateService::getInstance().getScreenSize().x / 2.0f))
{ {
@@ -95,6 +96,13 @@ public:
BeginMode2D(GameService::getInstance().getCamera()); BeginMode2D(GameService::getInstance().getCamera());
this->background.draw(); this->background.draw();
// std::vector<PBullet> pbs = GameService::getInstance().getPlayerBullets();
// for (int i = 0; i < GameService::getInstance().getPlayerBullets().size(); i++)
// {
// GameService::getInstance().getPlayerBullets()[i].draw();
// }
GameService::getInstance().drawBullets();
this->map.draw(); this->map.draw();
this->player.draw(); this->player.draw();
@@ -126,12 +134,13 @@ private:
std::vector<Text> gameOverScreenButtons; std::vector<Text> gameOverScreenButtons;
int hoveredGameOverScreenButton = 0; int hoveredGameOverScreenButton = 0;
// std::vector<PBullet> playerBullets;
// bool isPaused = false; // bool isPaused = false;
// bool isGameOver = false; // bool isGameOver = false;
// std::vector<Enemy> enemies // std::vector<Enemy> enemies
// std::vector<Create> crates // std::vector<Create> crates
// std::vector<PBullet> playerBullets
// std::vector<EBullet> enemyBullets // std::vector<EBullet> enemyBullets
// std::vector<Jelly> jellies // std::vector<Jelly> jellies
// std::vector<Ammo> ammo // std::vector<Ammo> ammo
@@ -241,6 +250,10 @@ private:
} }
} }
void shootLogic()
{
}
void drawPaused() void drawPaused()
{ {
// 100, 100, 255, 60 // 100, 100, 255, 60
+23
View File
@@ -0,0 +1,23 @@
#ifndef PBULLET_H
#define PBULLET_H
#include "entities/Bullet.h"
#include <iostream>
class PBullet : public Bullet {
public:
PBullet() {}
PBullet(Vector2 pos, float angle) : Bullet(pos, angle) {
this->color = YELLOW;
}
private:
void objCollision() override {
}
};
#endif
+52 -3
View File
@@ -10,6 +10,7 @@
#include "entities/TextureWrapper.h" #include "entities/TextureWrapper.h"
#include "enums/ECorner.h" #include "enums/ECorner.h"
#include "entities/Vector2i.h" #include "entities/Vector2i.h"
#include "entities/PBullet.h"
class Player class Player
{ {
@@ -22,6 +23,8 @@ public:
spriteAnimation = {0, 0}; spriteAnimation = {0, 0};
this->gunRight = TextureWrapper(AssetService::getInstance().getSprite(ESprite::PLAYER_GUN_RIGHT), {58, 29}, {0, 0}); this->gunRight = TextureWrapper(AssetService::getInstance().getSprite(ESprite::PLAYER_GUN_RIGHT), {58, 29}, {0, 0});
this->gunLeft = TextureWrapper(AssetService::getInstance().getSprite(ESprite::PLAYER_GUN_LEFT), {58, 29}, {0, 0}); this->gunLeft = TextureWrapper(AssetService::getInstance().getSprite(ESprite::PLAYER_GUN_LEFT), {58, 29}, {0, 0});
this->ammo = max_ammo;
this->prevShot = GetTime();
} }
~Player() ~Player()
{ {
@@ -30,6 +33,7 @@ public:
void logic() void logic()
{ {
rotateGun(); rotateGun();
shoot();
movement(); movement();
outofboundsCheck(); outofboundsCheck();
} }
@@ -59,9 +63,9 @@ private:
float jumpPower = 7.2f; float jumpPower = 7.2f;
float moveSpeed = 5.0f; float moveSpeed = 5.0f;
float gravity = 0.6f; float gravity = 0.6f;
float animationDelay = 0.2f; // In seconds float animationDelay = 0.2f; // In seconds
double prevFrame; double prevFrame;
Vector2 spriteAnimation; // Keeps track of (1) Sprite cycling and (2) Player direction Vector2 spriteAnimation; // Keeps track of (1) Sprite cycling and (2) Player direction
enum Direction enum Direction
{ {
Down, Down,
@@ -70,11 +74,16 @@ private:
Up Up
}; // Used in conjuction with spriteAnimation, makes sure sprite direction matches with player direction }; // Used in conjuction with spriteAnimation, makes sure sprite direction matches with player direction
std::vector<Vector2i> tiles; // Holds eight points of the player for accurate collision std::vector<Vector2i> tiles; // Holds eight points of the player for accurate collision
std::vector<unsigned int> timesCollision; // Holds the amount of times the player has collided with a tile, and which corner of the player is touching a tile std::vector<unsigned int> timesCollision; // Holds the amount of times the player has collided with a tile, and which corner of the player is touching a tile
bool groundCollision; // Keeps track of whether or not the player has collided with the ground bool groundCollision; // Keeps track of whether or not the player has collided with the ground
bool crateTopCollision; // Whether the player is standing on top of a crate bool crateTopCollision; // Whether the player is standing on top of a crate
int ammo;
int max_ammo = 100;
float firingRate= 0.2f; // Delay in seconds
double prevShot; // The last time the player fired a bullet
void applyGravity() void applyGravity()
{ {
if (!groundCollision) if (!groundCollision)
@@ -320,6 +329,46 @@ private:
WHITE); WHITE);
} }
} }
void shoot()
{
if (InputService::getInstance().isMouseButtonDown(MOUSE_BUTTON_LEFT) && GetTime() - prevShot > firingRate && groundCollision)
{
prevShot = GetTime();
if (ammo == 0) {
// Play empty gun sound
return;
}
// Play shooting sound
ammo--;
Vector2 bulletStartLocation = {this->texture.getPosition().x + 10, this->texture.getPosition().y + 10};
Vector2 mouseWorldPos = GameService::getInstance().getMouseWorldPos();
if (spriteAnimation.y == Left)
{
bulletStartLocation.y = this->texture.getPosition().y + 10;
bulletStartLocation.x = this->texture.getPosition().x - 5;
}
if (spriteAnimation.y == Right)
{
bulletStartLocation.y = this->texture.getPosition().y + 10;
bulletStartLocation.x = this->texture.getPosition().x + 37;
}
if (mouseWorldPos.x > this->texture.getPosition().x + (this->gunLeft.getSize().x) && spriteAnimation.y == Right ||
mouseWorldPos.x + (this->gunLeft.getSize().x / 2) < this->texture.getPosition().x && spriteAnimation.y == Left)
{
// PlayGunSound();
// currentAmmo--;
// .push_back(bulletStartLocation);
float angleShot = atan2(mouseWorldPos.y - bulletStartLocation.y,
mouseWorldPos.x - bulletStartLocation.x);
GameService::getInstance().addPlayerBullet(PBullet(bulletStartLocation, angleShot));
// bulletDirections.push_back(angleShot);
}
}
}
}; };
#endif #endif
+57
View File
@@ -3,6 +3,9 @@
#include "services/Service.h" #include "services/Service.h"
#include "entities/Game.h" #include "entities/Game.h"
#include "entities/PBullet.h"
#include <vector>
#include <list>
class GameService : public Service<GameService> class GameService : public Service<GameService>
{ {
@@ -52,10 +55,64 @@ public:
// return this->game; // return this->game;
// } // }
void addPlayerBullet(PBullet bullet)
{
this->playerBullets.push_back(bullet);
}
// std::list<PBullet>& getPlayerBullets() {
// return this->playerBullets;
// }
// void removeCollidedBullets()
// {
// for (auto it = playerBullets.begin(); it != playerBullets.end(); /* no increment here */)
// {
// if (it->getHasCollided())
// {
// it = playerBullets.erase(it); // Remove element and get the next valid iterator
// }
// else
// {
// ++it; // Only increment if no removal happens
// }
// }
// }
void bulletLogic()
{
for (auto it = this->playerBullets.begin(); it != this->playerBullets.end();)
{
it->logic();
if (it->getHasCollided())
it = this->playerBullets.erase(it);
else
++it;
}
}
void drawBullets()
{
for (auto it = this->playerBullets.begin(); it != this->playerBullets.end();)
{
it->draw();
++it;
}
}
void resetGame()
{
paused = false;
gameOver = false;
// playerBullets.clear();
}
private: private:
bool paused = false; bool paused = false;
bool gameOver = false; bool gameOver = false;
Camera2D camera; Camera2D camera;
std::list<PBullet> playerBullets;
}; };
#endif #endif
+12
View File
@@ -57,10 +57,15 @@ public:
for (auto button : watchedMouseButtons) for (auto button : watchedMouseButtons)
{ {
mouseButtonsPressed[button] = false; mouseButtonsPressed[button] = false;
mouseButtonsDown[button] = false;
if (IsMouseButtonPressed(button)) if (IsMouseButtonPressed(button))
{ {
mouseButtonsPressed[button] = true; mouseButtonsPressed[button] = true;
} }
if (IsMouseButtonDown(button))
{
mouseButtonsDown[button] = true;
}
} }
} }
@@ -78,22 +83,29 @@ public:
return mouseButtonsPressed[button]; return mouseButtonsPressed[button];
} }
bool isMouseButtonDown(MouseButton button) {
return mouseButtonsDown[button];
}
private: private:
std::unordered_set<KeyboardKey> watchedKeys; std::unordered_set<KeyboardKey> watchedKeys;
std::unordered_map<KeyboardKey, bool> keysPressed; std::unordered_map<KeyboardKey, bool> keysPressed;
std::unordered_map<KeyboardKey, bool> keysDown; std::unordered_map<KeyboardKey, bool> keysDown;
std::unordered_set<MouseButton> watchedMouseButtons; std::unordered_set<MouseButton> watchedMouseButtons;
std::unordered_map<MouseButton, bool> mouseButtonsPressed; std::unordered_map<MouseButton, bool> mouseButtonsPressed;
std::unordered_map<MouseButton, bool> mouseButtonsDown;
void setMouseButtonsToWatch(std::vector<MouseButton> mouseButtonsToWatch) void setMouseButtonsToWatch(std::vector<MouseButton> mouseButtonsToWatch)
{ {
this->watchedMouseButtons.clear(); this->watchedMouseButtons.clear();
this->mouseButtonsPressed.clear(); this->mouseButtonsPressed.clear();
this->mouseButtonsDown.clear();
for (int i = 0; i < mouseButtonsToWatch.size(); i++) for (int i = 0; i < mouseButtonsToWatch.size(); i++)
{ {
this->watchedMouseButtons.insert(mouseButtonsToWatch[i]); this->watchedMouseButtons.insert(mouseButtonsToWatch[i]);
this->mouseButtonsPressed[mouseButtonsToWatch[i]] = false; this->mouseButtonsPressed[mouseButtonsToWatch[i]] = false;
this->mouseButtonsDown[mouseButtonsToWatch[i]] = false;
} }
} }
}; };