Skip to content
Snippets Groups Projects
Unverified Commit b46623b1 authored by Jannik Schmitt's avatar Jannik Schmitt Committed by Leon Lux
Browse files

shooting enhancements (delay and proper bullet spawn point) , collision works...

shooting enhancements (delay and proper bullet spawn point) , collision works with player to calculate health
parent 4a5ab557
No related branches found
No related tags found
1 merge request!55Abgabe des Projektes
#include "BulletManager.hpp"
#include <algorithm>
#include <box2d/b2_math.h>
BulletManager::BulletManager(GameWindow *window, b2World* world) : m_world(world), m_window(window) {}
......@@ -21,16 +22,18 @@ void BulletManager::addPlayerProjectile(const b2Vec2 &player_position, const b2V
{
BulletObject *new_projectile = new BulletObject(m_world, player_position, b2Vec2(0.2f, 0.2f), 0.1f, 0.0f, m_window, "game/res/actor.spr");
new_projectile->ApplyLinearImpulse(impulse);
new_projectile->getBody()->GetUserData().pointer =1; // 1 = PlayerBullet (idenfier for contact listener)
new_projectile->getBody()->GetUserData().pointer = 1; // 1 = PlayerBullet (idenfier for contact listener)
m_player_projectiles.emplace_back(new_projectile);
}
void BulletManager::addEnemyProjectile(const b2Vec2 &enemy_position, const b2Vec2 &amplify_velocity)
void BulletManager::addEnemyProjectile(const b2Vec2 &enemy_position, const b2Vec2& enemy_size, const float amplify_velocity)
{
b2Vec2 impulse = m_window->getPlayerPosition() - enemy_position;
impulse.Normalize();
impulse *= amplify_velocity.x;
BulletObject *new_projectile = new BulletObject(m_world, enemy_position, b2Vec2(0.2f, 0.2f), 0.1f, 0.0f, m_window, "game/res/actor.spr");
//offset the enemy position to avoid self collision
b2Vec2 offset_position = enemy_position + enemy_size.x * impulse; //enemy_size.x is valid due to square hitbox
impulse *= amplify_velocity;
BulletObject *new_projectile = new BulletObject(m_world, offset_position, b2Vec2(0.2f, 0.2f), 0.1f, 0.0f, m_window, "game/res/actor.spr");
new_projectile->ApplyLinearImpulse(impulse);
new_projectile->getBody()->GetUserData().pointer =3; // 3 = 'EnemyBullet (idenfier for contact listener)
m_enemy_projectiles.emplace_back(new_projectile);
......
......@@ -58,7 +58,7 @@ public:
* @param enemy_position The position of the enemy firing the projectile in the world.
* @param amplify_velocity The amplify velocity of the new projectile to speed up according to enemy type.
*/
void addEnemyProjectile(const b2Vec2& enemy_position, const b2Vec2& amplify_velocity);
void addEnemyProjectile(const b2Vec2& enemy_position, const b2Vec2& enemy_size, const float amplify_velocity);
/**
* @brief Removes obsolete projectiles by handling destruction.
......
#include "ContactListener.hpp"
#include <iostream>
void ContactListener::BeginContact(b2Contact* contact) {
b2Fixture* fixtureA = contact->GetFixtureA();
b2Fixture* fixtureB = contact->GetFixtureB();
void ContactListener::BeginContact(b2Contact *contact)
{
b2Fixture *fixtureA = contact->GetFixtureA();
b2Fixture *fixtureB = contact->GetFixtureB();
b2Body* bodyA = fixtureA->GetBody();
b2Body* bodyB = fixtureB->GetBody();
b2Body *bodyA = fixtureA->GetBody();
b2Body *bodyB = fixtureB->GetBody();
HandleCollision(bodyA, bodyB);
}
void ContactListener::EndContact(b2Contact* contact) {
void ContactListener::EndContact(b2Contact *contact)
{
}
void ContactListener::HandleCollision(b2Body* bodyA, b2Body* bodyB) {
void ContactListener::HandleCollision(b2Body *bodyA, b2Body *bodyB)
{
// Player Bullet ID: 1
// Enemy ID: 2
// Player ID: 2
// Enemy Bullet ID: 3
// Enemy ID: 4
if (bodyA->GetUserData().pointer == 1) {
// Player Bullet Collision
if (bodyA->GetUserData().pointer == 1)
{
playerBulletsToDestroy.push_back(bodyA);
if (bodyB->GetUserData().pointer == 2) {
if (bodyB->GetUserData().pointer == 4)
{
enemiesToDestroy.push_back(bodyB);
}
}
if (bodyB->GetUserData().pointer == 1) {
if (bodyB->GetUserData().pointer == 1)
{
playerBulletsToDestroy.push_back(bodyB);
if (bodyA->GetUserData().pointer == 2) {
if (bodyA->GetUserData().pointer == 4)
{
enemiesToDestroy.push_back(bodyA);
}
}
if (bodyA->GetUserData().pointer == 3) {
enemyBulletsToDestroy.push_back(bodyA);
}
// Enemy Bullet Collision
if (bodyB->GetUserData().pointer == 3) {
enemyBulletsToDestroy.push_back(bodyB);
if (bodyA->GetUserData().pointer == 3)
{
enemyBulletsToDestroy.push_back(bodyA);
if (bodyB->GetUserData().pointer == 2)
{
// Player Hit
std::cout << "Player Hit" << std::endl;
}
}
if (bodyB->GetUserData().pointer == 3)
{
enemyBulletsToDestroy.push_back(bodyB);
if (bodyA->GetUserData().pointer == 2)
{
// Player Hit
std::cout << "Player Hit" << std::endl;
}
}
}
......@@ -2,31 +2,46 @@
#include <box2d/b2_math.h>
Enemy::Enemy(b2World *world, const b2Vec2 &position, const b2Vec2 &size, float density, float friction,
BulletManager& bulletmanager, GameWindow *window, const std::string &filepath)
: DynamicObject(world, position, size, density, friction, window, filepath), m_bulletManager(bulletmanager)
BulletManager &bulletmanager, GameWindow *window, const std::string &filepath)
: DynamicObject(world, position, size, density, friction, window, filepath), m_bulletManager(bulletmanager),
m_lastFire(1000), m_fireRate(2), m_fireDelay(static_cast<Uint32>(std::round(1000.0 / m_fireRate)))
{
m_body->GetUserData().pointer =2; // 2 = Enemy (idenfier for contact listener)
m_body->GetUserData().pointer = 4; // 4 = Enemy (idenfier for contact listener)
}
void Enemy::render()
{
SDL_Rect rectangle;
rectangle.w = m_size.x;
rectangle.h = m_size.y;
rectangle.x = static_cast<int32_t>(getPosition().x) - m_size.x / 2;
rectangle.y = static_cast<int32_t>(getPosition().y) - m_size.y / 2;
SDL_Rect rectangle;
rectangle.w = m_size.x;
rectangle.h = m_size.y;
rectangle.x = static_cast<int32_t>(getPosition().x) - m_size.x / 2;
rectangle.y = static_cast<int32_t>(getPosition().y) - m_size.y / 2;
// Draw test Rectangle
SDL_SetRenderDrawColor(m_window->renderer(), 255, 0, 0, 255);
SDL_RenderFillRect(m_window->renderer(), &rectangle);
// Draw test Rectangle
SDL_SetRenderDrawColor(m_window->renderer(), 255, 0, 0, 255);
SDL_RenderFillRect(m_window->renderer(), &rectangle);
}
void Enemy::shoot()
bool Enemy::shoot()
{
Uint32 currentTime = SDL_GetTicks();
if (currentTime - m_lastFire < m_fireDelay)
{
return false;
}
b2Vec2 enemy_position = getPosition();
//offset the enemy position to avoid self collision
enemy_position += b2Vec2(0, 40.0f);
m_bulletManager.addEnemyProjectile(enemy_position, b2Vec2(5.0f, 5.0f));
// offset the enemy position to avoid self collision -> now in BulletManager
// enemy_position += b2Vec2(0, 40.0f);
m_bulletManager.addEnemyProjectile(enemy_position, m_size, 5.0f);
m_lastFire = currentTime;
return true;
}
void Enemy::set_fireRate(int rate)
{
m_fireRate = rate;
m_fireDelay = static_cast<Uint32>(std::round(1000.0 / m_fireRate));
}
b2Body *Enemy::getBody()
......
......@@ -55,11 +55,23 @@ public:
* This method creates a new projectile at the enemy's position and fires it towards the player's
* current position. The projectile is added to the `BulletManager` object for tracking and rendering.
*/
void shoot();
bool shoot();
/**
* @brief Sets the enemy's fire rate.
*
* This method adjusts the number of bullets the enemy can fire per second.
*
* @param rate The fire rate in bullets per second.
*/
void set_fireRate(int rate);
private:
int health; /**< The health of the enemy, representing its hit points. */
int damage; /**< The amount of damage the enemy can inflict on other objects. */
int m_fireRate; /**< The rate at which the enemy can fire projectiles. */
Uint32 m_fireDelay; /**< The delay between shots in milliseconds. */
Uint32 m_lastFire; /**< The timestamp of the last shot fired. */
BulletManager& m_bulletManager; /**< The `BulletManager` object for handling enemy projectiles. */
};
......@@ -30,7 +30,8 @@ void EnemyManager::randomEnemyShoot()
}
int random = rand() % m_enemies.size(); // get random number between 0 and size of enemies vector
m_enemies[random]->shoot();
bool successful = m_enemies[random]->shoot();
//further logic can be added here
}
void EnemyManager::update(std::vector<b2Body *> enemiesToDestroy)
......
......@@ -5,7 +5,9 @@ Player::Player(b2World *world, const b2Vec2 &position, const b2Vec2 &size, float
: DynamicObject(world, position, size, density, friction, window, filepath),
m_alive(true), m_bulletManager(bulletmanager), m_lastFire(1000), m_fireRate(5),
m_fireDelay(static_cast<Uint32>(std::round(1000.0 / m_fireRate)))
{}
{
m_body->GetUserData().pointer = 2; // 2 = Player (idenfier for contact listener)
}
Player::~Player() {
// Empty implementation, but needed for vtable generation
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment