[Added] Gun angling

This commit is contained in:
Ninjaws
2024-12-13 00:24:51 +01:00
parent dbeb15ee60
commit 88e0b7cb05
8 changed files with 333 additions and 228 deletions
+89 -86
View File
@@ -40,13 +40,13 @@ public:
camera.target = (Vector2){screenSize.x / 2.0f, screenSize.y / 2.0f}; // Initially at the center of the world
camera.rotation = 0.0f;
camera.zoom = 1.0f;
this->camera = camera;
// this->camera = camera;
GameService::getInstance().setCamera(camera);
this->player = Player();
this->player.getTexture().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();
initGameOverScreen();
@@ -55,10 +55,89 @@ public:
AudioService::getInstance().setMusic(EMusic::GAME);
AudioService::getInstance().playMusic();
}
~Game()
{
}
void logic()
{
this->crosshair.setPosition(GetMousePosition());
if (GameService::getInstance().isPaused())
{
pausedLogic();
return;
}
else if (GameService::getInstance().isGameOver())
{
gameOverLogic();
return;
}
if (InputService::getInstance().isKeyPressed(KEY_ENTER))
{
GameService::getInstance().setPaused(true);
AudioService::getInstance().pauseMusic();
return;
}
// this->camera.offset.x -= 1.5;
this->player.logic();
if (this->player.getTexture().getPosition().x > (StateService::getInstance().getScreenSize().x / 2.0f))
{
GameService::getInstance().getCamera().offset = {(StateService::getInstance().getScreenSize().x / 2.0f) + ((StateService::getInstance().getScreenSize().x / 2.0f) - this->player.getTexture().getPosition().x), StateService::getInstance().getScreenSize().y / 2.0f};
}
}
void draw()
{
BeginDrawing();
BeginMode2D(GameService::getInstance().getCamera());
this->background.draw();
this->map.draw();
this->player.draw();
EndMode2D();
if (GameService::getInstance().isPaused())
{
drawPaused();
}
else if (GameService::getInstance().isGameOver())
{
drawGameOver();
}
drawCrosshair();
EndDrawing();
}
private:
// Camera2D camera;
Background background;
Map map;
Player player;
TextureWrapper crosshair;
std::vector<Text> pauseScreenButtons;
int hoveredPauseScreenButton = 0;
Text gameOverText;
std::vector<Text> gameOverScreenButtons;
int hoveredGameOverScreenButton = 0;
// bool isPaused = false;
// bool isGameOver = false;
// std::vector<Enemy> enemies
// std::vector<Create> crates
// std::vector<PBullet> playerBullets
// std::vector<EBullet> enemyBullets
// std::vector<Jelly> jellies
// std::vector<Ammo> ammo
// std::vector<Healthpack> healthpacks
// Powerup powerup
void initPauseScreen()
{
const int TOP_GAP = 100;
@@ -106,35 +185,6 @@ public:
}
}
void logic()
{
this->crosshair.setPosition(GetMousePosition());
if (GameService::getInstance().isPaused())
{
pausedLogic();
return;
}
else if (GameService::getInstance().isGameOver())
{
gameOverLogic();
return;
}
if (InputService::getInstance().isKeyPressed(KEY_ENTER))
{
GameService::getInstance().setPaused(true);
AudioService::getInstance().pauseMusic();
return;
}
// this->camera.offset.x -= 1.5;
this->player.logic();
if (this->player.getTexture().getPosition().x > (StateService::getInstance().getScreenSize().x / 2.0f))
{
this->camera.offset = {(StateService::getInstance().getScreenSize().x / 2.0f) + ((StateService::getInstance().getScreenSize().x / 2.0f) - this->player.getTexture().getPosition().x), StateService::getInstance().getScreenSize().y / 2.0f};
}
}
void pausedLogic()
{
if (InputService::getInstance().isKeyPressed(KEY_S) || InputService::getInstance().isKeyPressed(KEY_W))
@@ -191,29 +241,6 @@ public:
}
}
void draw()
{
BeginDrawing();
BeginMode2D(this->camera);
this->background.draw();
this->map.draw();
this->player.draw();
EndMode2D();
if (GameService::getInstance().isPaused())
{
drawPaused();
}
else if (GameService::getInstance().isGameOver())
{
drawGameOver();
}
drawCrosshair();
EndDrawing();
}
void drawPaused()
{
// 100, 100, 255, 60
@@ -239,41 +266,17 @@ public:
}
}
void drawCrosshair() {
DrawTextureEx(this->crosshair.getTexture(),GetMousePosition(),0,1.2f,RED);
void drawCrosshair()
{
DrawTextureEx(this->crosshair.getTexture(), GetMousePosition(), 0, 1.2f, RED);
// DrawTexturePro(
// this->crosshair.getTexture(),
// this->crosshair.getSourceRect(),
// {GetMousePosition().x, GetMousePosition().y, GetMousePosition().x+this->crosshair.getSize().x, GetMousePosition().y+this->crosshair.getSize().y},
// this->crosshair.getSourceRect(),
// {GetMousePosition().x, GetMousePosition().y, GetMousePosition().x+this->crosshair.getSize().x, GetMousePosition().y+this->crosshair.getSize().y},
// {this->crosshair.getSize().x/2.0f, this->crosshair.getSize().y/2.0f},
// 0,
// 0,
// WHITE);
}
private:
Camera2D camera;
Background background;
Map map;
Player player;
TextureWrapper crosshair;
std::vector<Text> pauseScreenButtons;
int hoveredPauseScreenButton = 0;
Text gameOverText;
std::vector<Text> gameOverScreenButtons;
int hoveredGameOverScreenButton = 0;
// bool isPaused = false;
// bool isGameOver = false;
// std::vector<Enemy> enemies
// std::vector<Create> crates
// std::vector<PBullet> playerBullets
// std::vector<EBullet> enemyBullets
// std::vector<Jelly> jellies
// std::vector<Ammo> ammo
// std::vector<Healthpack> healthpacks
// Powerup powerup
};
#endif
+2 -2
View File
@@ -18,7 +18,7 @@ public:
void draw();
/** Checks and returns which corners of the object have been collided with */
std::unordered_map<ECorner, bool> checkForCollision(TextureWrapper texture);
// std::unordered_map<ECorner, bool> checkForCollision(TextureWrapper texture);
int getTileSize() {
return this->tileSize;
@@ -45,7 +45,7 @@ private:
/**
* Converts the corners of the object to the matching tiles, so that they can be checked for collision
*/
std::unordered_map<ECorner, Vector2> cornersToTilePos(std::unordered_map<ECorner, Vector2> corners);
// std::unordered_map<ECorner, Vector2> cornersToTilePos(std::unordered_map<ECorner, Vector2> corners);
};
#endif
+134 -75
View File
@@ -16,11 +16,12 @@ class Player
public:
Player()
{
TextureWrapper wrapper = TextureWrapper(AssetService::getInstance().getSprite(ESprite::PLAYER), {32, 32}, {200, 200});
wrapper.setSourceRect({0, 0, 32, 32});
this->texture = wrapper;
this->texture = TextureWrapper(AssetService::getInstance().getSprite(ESprite::PLAYER), {32, 32}, {200, 200});
prevFrame = GetTime();
spriteAnimation = {0,0};
spriteAnimation = {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});
}
~Player()
{
@@ -28,14 +29,14 @@ public:
void logic()
{
// applyGravity();
rotateGun();
movement();
// handleCollision();
outofboundsCheck();
}
void draw()
{
drawGun();
DrawTextureRec(this->texture.getTexture(), this->texture.getSourceRect(), this->texture.getPosition(), WHITE);
}
@@ -44,26 +45,35 @@ public:
return this->texture;
}
void setPosition(Vector2 pos)
{
this->texture.setPosition(pos);
}
protected:
private:
TextureWrapper texture;
TextureWrapper gunLeft;
TextureWrapper gunRight;
Vector2 velocity = {0, 0};
float jumpPower = 7.2f;
float moveSpeed = 5.0f;
float gravity = 0.6f;
float animationDelay = 0.2f; // seconds
float animationDelay = 0.2f; // In seconds
double prevFrame;
Vector2 spriteAnimation; // Keeps track of (1) Sprite cycling and (2) Player direction
enum Direction { Down, Left, Right, Up }; // 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
Vector2 spriteAnimation; // Keeps track of (1) Sprite cycling and (2) Player direction
enum Direction
{
Down,
Left,
Right,
Up
}; // 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<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 crateTopCollision;
/**
* Holds the corners of the player
* Is used for precise collision detection
*/
bool crateTopCollision; // Whether the player is standing on top of a crate
void applyGravity()
{
@@ -90,15 +100,20 @@ private:
spriteAnimation.y = Right;
velocity.x = moveSpeed;
animate();
} else {
}
else
{
velocity.x = 0.0f;
}
positionUpdates();
handleCollision();
if (!groundCollision) {
if (!groundCollision)
{
velocity.y += gravity;
} else {
}
else
{
velocity.y = 0.0f;
}
@@ -106,7 +121,11 @@ private:
{
velocity.y -= jumpPower;
}
move(velocity);
}
void move(Vector2 velocity)
{
this->texture.move(velocity);
}
@@ -114,7 +133,7 @@ private:
{
if (GetTime() - prevFrame > animationDelay)
{
spriteAnimation.x = std::fmod(spriteAnimation.x + 1,3);
spriteAnimation.x = std::fmod(spriteAnimation.x + 1, 3);
Rectangle sourceRect = this->texture.getSourceRect();
sourceRect.x = spriteAnimation.x * this->texture.getSize().x;
@@ -125,82 +144,76 @@ private:
}
}
void positionUpdates() {
const Vector2 pos = this->texture.getPosition();
const Vector2 size = this->texture.getSize();
const int tileSize = MapService::getInstance().getMap().getTileSize();
void positionUpdates()
{
const Vector2 pos = this->texture.getPosition();
const Vector2 size = this->texture.getSize();
const int tileSize = MapService::getInstance().getMap().getTileSize();
const float bottom = pos.y + size.y + velocity.y;
const float left = pos.x + velocity.x;
const float right = pos.x + size.x + velocity.x;
const float top = pos.y + velocity.y;
const float bottom = pos.y + size.y + velocity.y;
const float left = pos.x + velocity.x;
const float right = pos.x + size.x + velocity.x;
const float top = pos.y + velocity.y;
Vector2i topLeft(Vector2i((int)(left + 5) / tileSize, (int)top / tileSize)); // +5 to separate top from side
Vector2i topRight(Vector2i((int)(right - 5) / tileSize, (int)top / tileSize)); // -5 to separate top from side
Vector2i topLeft(Vector2i((int)(left + 5) / tileSize, (int)top / tileSize)); // +5 to separate top from side
Vector2i topRight(Vector2i((int)(right - 5) / tileSize, (int)top / tileSize)); // -5 to separate top from side
Vector2i leftTop(Vector2i((int)left / tileSize, (int)(top + 5) / tileSize));
Vector2i leftBottom(Vector2i((int)left / tileSize, (int)(bottom - 5) / tileSize));
Vector2i rightTop(Vector2i((int)right / tileSize, (int)(top + 5) / tileSize));
Vector2i rightBottom(Vector2i((int)right / tileSize, (int)(bottom - 5) / tileSize));
Vector2i leftTop(Vector2i((int)left / tileSize, (int)(top + 5) / tileSize));
Vector2i leftBottom(Vector2i((int)left / tileSize, (int)(bottom - 5) / tileSize));
Vector2i rightTop(Vector2i((int)right / tileSize, (int)(top + 5) / tileSize));
Vector2i rightBottom(Vector2i((int)right / tileSize, (int)(bottom - 5) / 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
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
tiles.clear();
tiles.clear();
tiles.push_back(topLeft);
tiles.push_back(topRight);
tiles.push_back(topLeft);
tiles.push_back(topRight);
tiles.push_back(leftTop);
tiles.push_back(leftBottom);
tiles.push_back(rightTop);
tiles.push_back(rightBottom);
tiles.push_back(leftTop);
tiles.push_back(leftBottom);
tiles.push_back(rightTop);
tiles.push_back(rightBottom);
tiles.push_back(bottomLeft);
tiles.push_back(bottomRight);
tiles.push_back(bottomLeft);
tiles.push_back(bottomRight);
}
/**
* Stores the current position
* Applies the current velocity
* Checks for collision, and removes all velocities that are causing collisions
* Set the object exactly against the object it is colliding with position
*/
void handleCollision()
{
timesCollision.clear();
for (int i = 0; i < tiles.size(); i++)
{
if (MapService::getInstance().getMap().getColMap()[tiles[i].y][tiles[i].x] == 1)
for (int i = 0; i < tiles.size(); i++)
{
timesCollision.push_back(i);
}
}
groundCollision = false;
if (timesCollision.size() > 0)
{
for (int i = 0; i < timesCollision.size(); i++)
{
if (timesCollision[i] == 0 || timesCollision[i] == 1) //Topleft and Topright
if (MapService::getInstance().getMap().getColMap()[tiles[i].y][tiles[i].x] == 1)
{
velocity.y = 0;
timesCollision.push_back(i);
}
else if (timesCollision[i] == 2 || timesCollision[i] == 3 || //Lefttop and Leftbottom
timesCollision[i] == 4 || timesCollision[i] == 5) //Righttop and Lefttop
}
groundCollision = false;
if (timesCollision.size() > 0)
{
for (int i = 0; i < timesCollision.size(); i++)
{
velocity.x = 0;
}
else if (timesCollision[i] == 6 || timesCollision[i] == 7) //Bottomleft and Bottomright
{
groundCollision = true;
if (timesCollision[i] == 0 || timesCollision[i] == 1) // Topleft and Topright
{
velocity.y = 0;
}
else if (timesCollision[i] == 2 || timesCollision[i] == 3 || // Lefttop and Leftbottom
timesCollision[i] == 4 || timesCollision[i] == 5) // Righttop and Lefttop
{
velocity.x = 0;
}
else if (timesCollision[i] == 6 || timesCollision[i] == 7) // Bottomleft and Bottomright
{
groundCollision = true;
}
}
}
}
// Set velocity.x based on going right or left
@@ -217,7 +230,7 @@ private:
// Set groundcollision to false
// Loop through collisions
// Based on their location (TopLeft, RightTop, etc) change the velocity
// Apply gravity if not on the floor
// If jumping and on the floor, go up
@@ -261,6 +274,52 @@ private:
AudioService::getInstance().playMusic();
}
}
void rotateGun()
{
if (GameService::getInstance().getMouseWorldPos().x > this->texture.getPosition().x + (this->gunLeft.getSize().x) && spriteAnimation.y == Right)
{
float gunRotationRight = atan2(GameService::getInstance().getMouseWorldPos().y - this->texture.getPosition().y,
GameService::getInstance().getMouseWorldPos().x - this->texture.getPosition().x);
this->gunRight.setRotation(gunRotationRight * 90);
}
else if (GameService::getInstance().getMouseWorldPos().x + (this->gunLeft.getSize().x / 2) < this->texture.getPosition().x && spriteAnimation.y == Left)
{
float gunRotationLeft = atan2(GameService::getInstance().getMouseWorldPos().y - this->texture.getPosition().y,
this->texture.getPosition().x - GameService::getInstance().getMouseWorldPos().x);
this->gunLeft.setRotation(-gunRotationLeft * 90);
}
}
void drawGun()
{
if (GameService::getInstance().getMouseWorldPos().x > this->texture.getPosition().x + this->gunLeft.getSize().x && spriteAnimation.y == Right)
{
DrawTexturePro(
this->gunRight.getTexture(),
{0, 0, this->gunRight.getSize().x, this->gunRight.getSize().y},
{this->texture.getPosition().x + this->texture.getSize().x / 2.0f,
this->texture.getPosition().y + this->texture.getSize().x / 2.0f,
this->gunRight.getSize().x,
this->gunRight.getSize().y},
{this->gunRight.getSize().x / 2.0f, this->gunRight.getSize().y / 2.0f},
this->gunRight.getRotation(),
WHITE);
}
else if (GameService::getInstance().getMouseWorldPos().x + (this->gunLeft.getSize().x / 2) < this->texture.getPosition().x && spriteAnimation.y == Left)
{
DrawTexturePro(
this->gunLeft.getTexture(),
{0, 0, this->gunLeft.getSize().x, this->gunLeft.getSize().y},
{this->texture.getPosition().x + this->texture.getSize().x / 2.0f,
this->texture.getPosition().y + this->texture.getSize().x / 2.0f,
this->gunLeft.getSize().x,
this->gunLeft.getSize().y},
{this->gunLeft.getSize().x / 2.0f, this->gunLeft.getSize().y / 2.0f},
this->gunLeft.getRotation(),
WHITE);
}
}
};
#endif
+27 -17
View File
@@ -12,6 +12,7 @@ class TextureWrapper {
this->texture = texture;
this->size = size;
this->position = position;
this->sourceRect = sourceRect;
}
~TextureWrapper() {
@@ -33,6 +34,10 @@ class TextureWrapper {
return this->position;
}
float getRotation() {
return this->rotation;
}
void setSourceRect(Rectangle rect) {
this->sourceRect = rect;
}
@@ -41,35 +46,40 @@ class TextureWrapper {
this->position = position;
}
void setRotation(float rot) {
this->rotation = rot;
}
void move(Vector2 deltaPos) {
this->position = {this->position.x + deltaPos.x, this->position.y + deltaPos.y};
}
/** Returns the 4 corners of the texture */
std::unordered_map<ECorner, Vector2> getCorners() {
std::unordered_map<ECorner, Vector2> corners;
float top = this->position.y;
float right = this->position.x+this->size.x;
float bottom = this->position.y + this->size.y;
float left = this->position.x;
float margin = 8; // Space to the corner
corners[ECorner::TOP_LEFT] = {left+margin, top};
corners[ECorner::TOP_RIGHT] = {right-margin, top};
corners[ECorner::RIGHT_TOP] = {right, top+margin};
corners[ECorner::RIGHT_BOTTOM] = {right, bottom-margin};
corners[ECorner::BOTTOM_RIGHT] = {right-margin, bottom};
corners[ECorner::BOTTOM_LEFT] = {left+margin, bottom};
corners[ECorner::LEFT_BOTTOM] = {left, bottom-margin};
corners[ECorner::LEFT_TOP] = {left, top+margin};
// std::unordered_map<ECorner, Vector2> getCorners() {
// std::unordered_map<ECorner, Vector2> corners;
// float top = this->position.y;
// float right = this->position.x+this->size.x;
// float bottom = this->position.y + this->size.y;
// float left = this->position.x;
// float margin = 8; // Space to the corner
// corners[ECorner::TOP_LEFT] = {left+margin, top};
// corners[ECorner::TOP_RIGHT] = {right-margin, top};
// corners[ECorner::RIGHT_TOP] = {right, top+margin};
// corners[ECorner::RIGHT_BOTTOM] = {right, bottom-margin};
// corners[ECorner::BOTTOM_RIGHT] = {right-margin, bottom};
// corners[ECorner::BOTTOM_LEFT] = {left+margin, bottom};
// corners[ECorner::LEFT_BOTTOM] = {left, bottom-margin};
// corners[ECorner::LEFT_TOP] = {left, top+margin};
return corners;
}
// return corners;
// }
private:
Texture2D texture;
Rectangle sourceRect;
Vector2 size;
Vector2 position;
float rotation;
};
#endif
+38 -7
View File
@@ -1,30 +1,61 @@
#ifndef GAME_SERVICE_H
#define GAME_SERVICE_H
#include "Service.h"
#include "services/Service.h"
#include "entities/Game.h"
class GameService : public Service<GameService> {
class GameService : public Service<GameService>
{
public:
bool isPaused() {
bool isPaused()
{
return this->paused;
}
bool isGameOver() {
bool isGameOver()
{
return this->gameOver;
}
void setPaused(bool paused) {
void setPaused(bool paused)
{
this->paused = paused;
}
void setGameOver(bool gameOver) {
void setGameOver(bool gameOver)
{
this->gameOver = gameOver;
}
void setCamera(Camera2D camera)
{
this->camera = camera;
}
Camera2D &getCamera()
{
return this->camera;
}
/**
* Returns the position of the mouse in world coordinates
*/
Vector2 getMouseWorldPos()
{
Vector2 mouseWorldPos = {GetMousePosition().x + camera.target.x - camera.offset.x, GetMousePosition().y};
return mouseWorldPos;
}
// void setGame(Game game) {
// this->game = game;
// }
// Game& getGame() {
// return this->game;
// }
private:
bool paused = false;
bool gameOver = false;
Camera2D camera;
};
#endif