fixed refresh spaceship bug; add mini map

This commit is contained in:
VisualGMQ 2022-02-09 16:44:09 +08:00
parent 61fd49bb7d
commit a9f94b0df3
18 changed files with 115 additions and 40 deletions

View File

@ -1,11 +1,16 @@
#pragma once
#include "tinyengine/libmath.hpp"
constexpr float FreightShipMaxSpeed = 100;
constexpr float FightShipMaxSpeed = 300;
constexpr float FightShipMaxSpeed = 250;
constexpr int FreightLife = 10;
constexpr float LazerDamage = 2;
constexpr float LazerShooterSpeed = 500;
constexpr float LazerShooterMaxSpeed = 1000;
constexpr float LazerShooterCooldown = 0.3;
constexpr int GameWindowWidth = 1024;
constexpr int GameWindowHeight = 720;
constexpr Size GameWindowSize = {1024, 720};
constexpr Rect BulletRefreshArea{-100, -100, 1124, 820};
constexpr Rect SpaceshipRefreshArea{-1024 * 3, -720 * 3, 1024 * 4, 720 * 4};

View File

@ -9,7 +9,9 @@ extern Unique<TileSheet> GameTileSheet;
extern std::unordered_map<std::string, Unique<Sound>> Sounds;
extern QuickList<Entity*> Bullets;
extern QuickList<Entity*> Entities;
extern Entity* PlayerSpaceship;
void LoadResources();
Point MapGlobal2PlayerCoord(const Point& pos);

View File

@ -7,7 +7,7 @@ public:
void OnRender() override;
private:
Camera camera;
Camera camera_;
float initTime_;
Unique<Sound> sound_;
bool soundPlayed_;

View File

@ -15,11 +15,11 @@ public:
void OnQuit() override;
private:
Entity* spaceship_;
Unique<FreightShipController> freightController_;
Unique<FightShipController> fightController_;
void renderGUI();
void renderMiniMap();
Camera guiCamera_;
Camera gameCamera_;

View File

@ -9,11 +9,13 @@ public:
void MoveTo(const Point& pos);
/* scale screen in [1.0, 2.0] */
void Scale(const Point& scale);
void SetAnchor(const Point& anchor);
bool TryCalcView();
private:
Mat44 viewMat_;
Point position_ = {0, 0};
Point scale_ = {1, 1};
bool dirty_ = false;
Point anchor_ = {0, 0};
bool dirty_ = true;
};

View File

@ -47,7 +47,6 @@ public:
static void SetViewport(int x, int y, int w, int h);
static const Color& GetDrawColor();
static void SetCamera(Camera& camera);
static void Update();
private:
static Color color_;

View File

@ -5,7 +5,8 @@ void Shoot(SpaceshipWeaponCmpt& weapon, const Point& dir) {
Point playerCenterPos = weapon.owner->Get<MoveCmpt>()->position;
auto bullet = weapon.ShootBullet(dir);
Entity* bullet;
bullet = weapon.ShootBullet(dir);
Bullets.Add(bullet);
weapon.coolDown = weapon.shootDuration;

View File

@ -26,8 +26,14 @@ void FightShipController::Update(float dt) {
if (IsLeftPressing()) {
if (entity_->Has<SpaceshipWeaponCmpt>()) {
Shoot(*entity_->Use<SpaceshipWeaponCmpt>(),
auto weapon = entity_->Use<SpaceshipWeaponCmpt>();
if (weapon->type == SpaceshipWeaponCmpt::Orientation) {
Shoot(*weapon,
Rotate(Point{0, -1}, -entity_->Get<FightShipCmpt>()->degree));
} else {
Shoot(*weapon,
GetMousePosition() - entity_->Get<MoveCmpt>()->position);
}
}
}
}

View File

@ -30,8 +30,15 @@ void FreightShipController::Update(float dt) {
if (IsLeftPressing()) {
if (entity_->Has<SpaceshipWeaponCmpt>()) {
Shoot(*entity_->Use<SpaceshipWeaponCmpt>(),
// FIXME duplicated codes in here and fightship_controller.cpp
auto weapon = entity_->Use<SpaceshipWeaponCmpt>();
if (weapon->type == SpaceshipWeaponCmpt::Orientation) {
Shoot(*weapon,
Rotate(Point{0, -1}, entity_->Get<FightShipCmpt>()->degree));
} else {
Shoot(*weapon,
GetMousePosition() - entity_->Get<MoveCmpt>()->position);
}
}
}
}

View File

@ -6,7 +6,7 @@ Entity* CreateFreightShip() {
entity->Add<MoveCmpt>(Point{0, 0});
entity->Add<MotionCmpt>(Point{0, 0}, FreightShipMaxSpeed);
entity->Add<RenderCmpt>(GameTileSheet->GetTile(0, 0));
entity->Add<SpaceshipWeaponCmpt>(SpaceshipWeaponCmpt::Orientation,
entity->Add<SpaceshipWeaponCmpt>(SpaceshipWeaponCmpt::FreeRotation,
entity,
LazerDamage,
LazerShooterSpeed,

View File

@ -1,12 +1,16 @@
#include "game/global.hpp"
#include "game/component.hpp"
Context ECSContext;
SystemManager SystemMgr;
Unique<TileSheet> GameTileSheet;
std::unordered_map<std::string, Unique<Sound>> Sounds;
QuickList<Entity*> Bullets;
QuickList<Entity*> Entities;
Entity* PlayerSpaceship;
void loadImages() {
GameTileSheet.reset(new TileSheet("assets/tilesheet.png", 8, 8));
}
@ -19,3 +23,11 @@ void LoadResources() {
loadImages();
loadSounds();
}
Point MapGlobal2PlayerCoord(const Point& pos) {
if (PlayerSpaceship && PlayerSpaceship->Has<MoveCmpt>()) {
return pos - PlayerSpaceship->Get<MoveCmpt>()->position + GameWindowSize / 2;
} else {
return pos;
}
}

View File

@ -2,4 +2,4 @@
#include "game/stages/space.hpp"
#include "game/constants.hpp"
RUN_WINDOW("Space Sector", GameWindowWidth, GameWindowHeight, SpaceScence)
RUN_WINDOW("Space Sector", GameWindowSize.w, GameWindowSize.h, SpaceScence)

View File

@ -10,6 +10,8 @@ void GameLogoScence::OnInit() {
initTime_ = GetTime();
sound_.reset(new Sound("assets/1mgame_sound.wav"));
soundPlayed_ = false;
Renderer::SetCamera(camera_);
}
void GameLogoScence::OnRender() {

View File

@ -4,9 +4,12 @@ void SpaceScence::OnInit() {
Renderer::SetClearColor(Color{0, 0, 0, 255});
LoadResources();
spaceship_ = CreateFightShip();
Entities.Add(spaceship_);
spaceship_->Use<MoveCmpt>()->position = Point{400, 400};
Entities.Clear();
Bullets.Clear();
PlayerSpaceship = CreateFightShip();
Entities.Add(PlayerSpaceship);
PlayerSpaceship->Use<MoveCmpt>()->position = Point{400, 400};
Entity* enemy = CreateFreightShip();
enemy->Use<MoveCmpt>()->position = Point{100, 100};
@ -21,7 +24,9 @@ void SpaceScence::OnInit() {
Entities.Add(enemy);
// freightController_.reset(new FreightShipController(spaceship_));
fightController_.reset(new FightShipController(spaceship_));
fightController_.reset(new FightShipController(PlayerSpaceship));
gameCamera_.SetAnchor(GameWindowSize / 2);
SystemMgr.Clear();
SystemMgr.AddUpdateSystem(new BulletCooldownSystem);
@ -35,22 +40,53 @@ void SpaceScence::OnInit() {
void SpaceScence::OnUpdate(float dt) {
fightController_->Update(dt);
SystemMgr.Update(dt);
gameCamera_.MoveTo(PlayerSpaceship->Get<MoveCmpt>()->position);
}
void SpaceScence::OnRender() {
Renderer::SetCamera(gameCamera_);
SystemMgr.Render();
Renderer::SetCamera(guiCamera_);
renderGUI();
}
void SpaceScence::renderGUI() {
Renderer::SetCamera(guiCamera_);
auto life = spaceship_->Get<LifeCmpt>()->hp;
auto life = PlayerSpaceship->Get<LifeCmpt>()->hp;
float xOffset = 16 * life;
for (int i = 0; i < life; i++) {
Renderer::DrawTile(GameTileSheet->GetTile(1, 1),
Point{GameWindowWidth - xOffset + i * 16, 8});
Point{GameWindowSize.w - xOffset + i * 16, 8});
}
renderMiniMap();
}
void SpaceScence::renderMiniMap() {
Rect mapRect = {1, 0, 100, 100};
mapRect.y = GameWindowSize.h - mapRect.h;
Renderer::SetDrawColor(Color{0, 0, 0, 255});
Renderer::FillRect(mapRect);
Renderer::SetDrawColor(Color{255, 255, 255, 255});
Renderer::DrawRect(mapRect);
for (auto& entity: Entities) {
if (entity != PlayerSpaceship) {
const auto& pos = entity->Get<MoveCmpt>()->position;
Point entityOnMapPos = (pos - PlayerSpaceship->Get<MoveCmpt>()->position) * Size{mapRect.w, mapRect.h} / GameWindowSize +
Point{mapRect.x, mapRect.y} + Size{mapRect.w, mapRect.h} / 2;
if (IsPointInRect(entityOnMapPos, mapRect)) {
if (entity->Has<FreightShipCmpt>()) {
Renderer::SetDrawColor(Color{255, 255, 255, 255});
} else {
Renderer::SetDrawColor(Color{0, 0, 255, 255});
}
Renderer::FillRect(Rect{entityOnMapPos.x - 1, entityOnMapPos.y - 1, 2, 2});
}
}
}
}

View File

@ -75,21 +75,26 @@ void CollideSystem::Update(float dt) {
void CleanupSystem::Update(float dt) {
using EntityPtr = Entity*;
auto destroyFunc = [&](const EntityPtr& entity){
ECSContext.DestroyEntity(entity);
};
Bullets.RemoveAll([](const EntityPtr& entity){
return !entity->Get<BulletCmpt>()->alive || !IsPointInRect(entity->Get<MoveCmpt>()->position,
Rect{0, 0, GameWindowWidth, GameWindowHeight});
});
return !entity->Get<BulletCmpt>()->alive ||
!IsPointInRect(MapGlobal2PlayerCoord(entity->Get<MoveCmpt>()->position),
BulletRefreshArea);
}, destroyFunc);
Entities.RemoveAll([](const EntityPtr& entity){
if (entity->Has<LifeCmpt>() &&
entity->Get<LifeCmpt>()->hp <= 0) {
entity->Get<LifeCmpt>()->hp <= 0 ||
entity->Has<MoveCmpt>() &&
!IsPointInRect(MapGlobal2PlayerCoord(entity->Get<MoveCmpt>()->position), SpaceshipRefreshArea)) {
return true;
} else {
return false;
}
},
[&](const EntityPtr& entity){
ECSContext.DestroyEntity(entity);
});
}, destroyFunc);
}
void BulletCooldownSystem::Update(float dt) {

View File

@ -3,8 +3,8 @@
bool Camera::TryCalcView() {
if (dirty_) {
viewMat_ = Mat44({
scale_.x, 0, 0, -position_.x,
0, scale_.y, 0, -position_.y,
scale_.x, 0, 0, -position_.x + anchor_.x,
0, scale_.y, 0, -position_.y + anchor_.y,
0, 0, 1, 0,
0, 0, 0, 1,
});
@ -30,3 +30,8 @@ void Camera::Scale(const Point& scale) {
scale_.y = Clamp(1.0f, 2.0f, scale.y);
dirty_ = true;
}
void Camera::SetAnchor(const Point& anchor) {
anchor_ = anchor;
dirty_ = true;
}

View File

@ -89,7 +89,6 @@ void Engine::Shutdown() {
void Engine::Update(float deltaTime) {
if (scence_)
scence_->OnUpdate(deltaTime);
Renderer::Update();
}
void Engine::Render() {

View File

@ -229,14 +229,8 @@ void Renderer::SetViewport(int x, int y, int w, int h) {
void Renderer::SetCamera(Camera& camera) {
Context.camera = &camera;
}
void Renderer::Update() {
if (Context.camera && Context.camera->TryCalcView()) {
Context.camera->TryCalcView();
Context.shader->SetMat4("view", Context.camera->GetView());
} else {
Context.shader->SetMat4("view", Mat44::Eye);
}
}
void Renderer::Shutdown() {