Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Utility] and [New Bullet] weight system and better simulation of knockback #476

Closed
wants to merge 21 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ build
out
CMakeSettings.json
compile_commands.json
.cache/
.cache/

Binary file added assets/textures/snowball.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/battle_game/core/bullets/bullets.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "battle_game/core/bullets/rebounding_ball.h"
#include "battle_game/core/bullets/rocket.h"
#include "battle_game/core/bullets/smoke_bomb.h"
#include "battle_game/core/bullets/snowball.h"
#include "battle_game/core/bullets/sweaty_soybean.h"
#include "battle_game/core/bullets/udongein_directional_bullet.h"
#include "battle_game/core/bullets/warning_line.h"
Expand Down
59 changes: 59 additions & 0 deletions src/battle_game/core/bullets/snowball.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#include "battle_game/core/bullets/snowball.h"

#include "battle_game/core/game_core.h"
#include "battle_game/core/particles/particles.h"

namespace battle_game::bullet {
SnowBall::SnowBall(GameCore *core,
uint32_t id,
uint32_t unit_id,
uint32_t player_id,
glm::vec2 position,
float rotation,
float damage_scale,
glm::vec2 velocity)
: Bullet(core, id, unit_id, player_id, position, rotation, damage_scale),
velocity_(velocity) {
}

void SnowBall::Render() {
SetTransformation(position_, rotation_, glm::vec2{0.4f});
SetColor(game_core_->GetPlayerColor(player_id_));
SetTexture("../../textures/snowball.png");
DrawModel(0);
}

void SnowBall::Update() {
position_ += velocity_ * kSecondPerTick;
bool should_die = false;
if (game_core_->IsBlockedByObstacles(position_)) {
should_die = true;
}

auto &units = game_core_->GetUnits();
for (auto &unit : units) {
if (unit.first == unit_id_) {
continue;
}
if (unit.second->IsHit(position_)) {
game_core_->PushEventDealDamage(unit.first, id_, damage_scale_ * 5.0f);
auto distance_per_tick = velocity_ * (kSecondPerTick * 0.22f /
(0.1f + unit.second->GetWeight()));
game_core_->PushEventMoveRUForTicks(unit.first, distance_per_tick, 50);
should_die = true;
}
}

if (should_die) {
game_core_->PushEventRemoveBullet(id_);
}
}

SnowBall::~SnowBall() {
for (int i = 0; i < 5; i++) {
game_core_->PushEventGenerateParticle<particle::Smoke>(
position_, rotation_, game_core_->RandomInCircle() * 2.0f, 0.2f,
glm::vec4{0.0f, 0.0f, 0.0f, 1.0f}, 3.0f);
}
}
} // namespace battle_game::bullet
22 changes: 22 additions & 0 deletions src/battle_game/core/bullets/snowball.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#pragma once
#include "battle_game/core/bullet.h"

namespace battle_game::bullet {
class SnowBall : public Bullet {
public:
SnowBall(GameCore *core,
uint32_t id,
uint32_t unit_id,
uint32_t player_id,
glm::vec2 position,
float rotation,
float damage_scale,
glm::vec2 velocity);
~SnowBall() override;
void Render() override;
void Update() override;

private:
glm::vec2 velocity_{};
};
} // namespace battle_game::bullet
51 changes: 49 additions & 2 deletions src/battle_game/core/game_core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ void GameCore::Update() {
particle.second->Update();
}
ProcessEventQueue();
ProcessAwaitingQueue();
for (auto &units : units_) {
units.second->EndTick();
}
}

/*
Expand Down Expand Up @@ -135,6 +139,13 @@ void GameCore::ProcessEventQueue() {
}
}

void GameCore::ProcessAwaitingQueue() {
while (!awaiting_queue_.empty()) {
awaiting_queue_.front()();
awaiting_queue_.pop();
}
}

bool GameCore::IsBlockedByObstacles(glm::vec2 p) const {
if (IsOutOfRange(p)) {
return true;
Expand All @@ -161,20 +172,56 @@ void GameCore::PushEventMoveUnit(uint32_t unit_id, glm::vec2 new_position) {
event_queue_.emplace([this, unit_id, new_position]() {
auto unit = GetUnit(unit_id);
if (unit) {
unit->SetPosition(new_position);
unit->position_change_ += new_position - unit->GetPosition();
}
});
}

void GameCore::PushEventMoveRelativeUnit(uint32_t unit_id,
glm::vec2 relative_position) {
event_queue_.emplace([this, unit_id, relative_position]() {
auto unit = GetUnit(unit_id);
if (unit) {
unit->position_change_ += relative_position;
}
});
} // this function is inspired by XieRujian, completely abandon the queue

void GameCore::PushEventMoveRUForTicks(uint32_t unit_id,
glm::vec2 r_p,
uint32_t remaining_ticks) {
if (remaining_ticks > 0) {
event_queue_.emplace([this, unit_id, r_p, remaining_ticks]() {
auto unit = GetUnit(unit_id);
if (unit) {
unit->position_change_ += r_p;
awaiting_queue_.emplace([=]() {
PushEventMoveRUForTicks(unit_id, r_p, remaining_ticks - 1);
});
}
});
}
} // this function is an easy simulation for "effects"

void GameCore::PushEventRotateUnit(uint32_t unit_id, float new_rotation) {
event_queue_.emplace([this, unit_id, new_rotation]() {
auto unit = GetUnit(unit_id);
if (unit) {
unit->SetRotation(new_rotation);
unit->rotation_change_ += new_rotation - unit->GetRotation();
}
});
}

void GameCore::PushEventRotateRelativeUnit(uint32_t unit_id,
float relative_rotation) {
event_queue_.emplace([this, unit_id, relative_rotation]() {
auto unit = GetUnit(unit_id);
if (unit) {
unit->rotation_change_ += relative_rotation;
}
});
} // change another btw, although I dont actually use

Unit *GameCore::GetUnit(uint32_t unit_id) const {
if (!units_.count(unit_id)) {
return nullptr;
Expand Down
8 changes: 8 additions & 0 deletions src/battle_game/core/game_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,12 @@ class GameCore {
[[nodiscard]] Obstacle *GetBlockedObstacle(glm::vec2 p) const;

void PushEventMoveUnit(uint32_t unit_id, glm::vec2 new_position);
void PushEventMoveRelativeUnit(uint32_t unit_id, glm::vec2 relative_position);
void PushEventMoveRUForTicks(uint32_t unit_id,
glm::vec2 r_p,
uint32_t remaining_ticks);
void PushEventRotateUnit(uint32_t unit_id, float new_rotation);
void PushEventRotateRelativeUnit(uint32_t unit_id, float new_rotation);
void PushEventDealDamage(uint32_t dst_unit_id,
uint32_t src_unit_id,
float damage);
Expand Down Expand Up @@ -163,6 +168,7 @@ class GameCore {
}

void ProcessEventQueue();
void ProcessAwaitingQueue();

void SetCamera(glm::vec2 position, float rotation = 0.0f);
[[nodiscard]] glm::vec2 GetCameraPosition() const {
Expand All @@ -186,6 +192,8 @@ class GameCore {

private:
std::queue<std::function<void()>> event_queue_;
std::queue<std::function<void()>> awaiting_queue_;
// this one is for "buff" type

std::map<uint32_t, std::unique_ptr<Unit>> units_;
uint32_t unit_index_{1};
Expand Down
2 changes: 1 addition & 1 deletion src/battle_game/core/selectable_units.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ void GameCore::GeneratePrimaryUnitList() {
/*
* TODO: Add Your Unit Here!
* */
ADD_SELECTABLE_UNIT(unit::Snowball_Sample_Sledge);
ADD_SELECTABLE_UNIT(unit::InfernoTank);
ADD_SELECTABLE_UNIT(unit::Tank);
ADD_SELECTABLE_UNIT(unit::DoubleScatterTank);
Expand All @@ -51,7 +52,6 @@ void GameCore::GeneratePrimaryUnitList() {
ADD_SELECTABLE_UNIT(unit::CritTank);
ADD_SELECTABLE_UNIT(unit::Railgun);
ADD_SELECTABLE_UNIT(unit::Udongein);

unit.reset();
}
} // namespace battle_game
9 changes: 9 additions & 0 deletions src/battle_game/core/unit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,15 @@ void Unit::RenderLifeBar() {
void Unit::RenderHelper() {
}

void Unit::EndTick() {
if (!game_core_->IsBlockedByObstacles(position_ + position_change_) &&
!game_core_->IsOutOfRange(position_ + position_change_))
position_ += position_change_;
rotation_ += rotation_change_;
position_change_ = {.0f, .0f};
rotation_change_ = {.0f};
}

const char *Unit::UnitName() const {
return "Unknown Unit";
}
Expand Down
19 changes: 17 additions & 2 deletions src/battle_game/core/unit.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,24 @@ class Unit : public Object {
return health_;
}

[[nodiscard]] float GetWeight() const {
return weight_;
}

/*
* The value of new_health will be clamped to [0, 1]
* */
void SetHealth(float new_health) {
health_ = std::clamp(new_health, 0.0f, 1.0f);
}

/*
* The value of new_weight will be a float from 0 to \infty
* */
void SetWeight(float new_weight) {
weight_ = new_weight;
}

void SetLifeBarLength(float new_length);
void SetLifeBarOffset(glm::vec2 new_offset);
void SetLifeBarFrontColor(glm::vec4 new_color);
Expand Down Expand Up @@ -84,9 +95,15 @@ class Unit : public Object {
return skills_;
}

void EndTick(); // inspired by XieRujian

glm::vec2 position_change_{glm::vec2(.0f, .0f)};
float rotation_change_{.0f};

protected:
uint32_t player_id_{};
float health_{1.0f};
float weight_{1.0f};
std::vector<Skill> skills_;
bool lifebar_display_{true};
glm::vec2 lifebar_offset_{};
Expand All @@ -100,5 +117,3 @@ class Unit : public Object {
};

} // namespace battle_game

// add something to pull
17 changes: 6 additions & 11 deletions src/battle_game/core/units/round_UFO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,8 @@ void RoundUFO::Teleport_() {
auto player = game_core_->GetPlayer(player_id_);
if (player) {
auto &input_data = player->GetInputData();
auto new_position = input_data.mouse_cursor_position;
if (!game_core_->IsBlockedByObstacles(new_position)) {
game_core_->PushEventMoveUnit(id_, new_position);
}
game_core_->PushEventMoveRelativeUnit(id_,
input_data.mouse_cursor_position);
}
}

Expand Down Expand Up @@ -113,13 +111,10 @@ void RoundUFO::UFOMove(float move_speed) {
}
float speed = move_speed * GetSpeedScale();
offset *= kSecondPerTick * speed;
auto new_position =
position_ + glm::vec2{glm::rotate(glm::mat4{1.0f}, rotation_,
glm::vec3{0.0f, 0.0f, 1.0f}) *
glm::vec4{offset, 0.0f, 0.0f}};
if (!game_core_->IsBlockedByObstacles(new_position)) {
game_core_->PushEventMoveUnit(id_, new_position);
}
auto relative_position = glm::vec2{
glm::rotate(glm::mat4{1.0f}, rotation_, glm::vec3{0.0f, 0.0f, 1.0f}) *
glm::vec4{offset, 0.0f, 0.0f}};
game_core_->PushEventMoveRelativeUnit(id_, relative_position);

auto diff = input_data.mouse_cursor_position - position_;
float new_rotation;
Expand Down
Loading