Testing some enemies
This commit is contained in:
@ -19,4 +19,6 @@ add_subdirectory(scene)
|
||||
|
||||
# Assets
|
||||
set(ROSE_ASSETS_DIR ${DAWN_ASSETS_DIR}/games/rose)
|
||||
tool_prefab(${ROSE_ASSETS_DIR}/prefabs/Player.xml)
|
||||
tool_prefab(${ROSE_ASSETS_DIR}/prefabs/Player.xml)
|
||||
tool_prefab(${ROSE_ASSETS_DIR}/prefabs/Urchin.xml)
|
||||
tool_prefab(${ROSE_ASSETS_DIR}/prefabs/Crab.xml)
|
@ -8,4 +8,7 @@ target_sources(${DAWN_TARGET_NAME}
|
||||
PRIVATE
|
||||
GameCamera.cpp
|
||||
PlayerController.cpp
|
||||
EntityHealth.cpp
|
||||
HurtHazard.cpp
|
||||
EntityRandomWalk.cpp
|
||||
)
|
39
src/dawnrose/scene/components/EntityHealth.cpp
Normal file
39
src/dawnrose/scene/components/EntityHealth.cpp
Normal file
@ -0,0 +1,39 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "EntityHealth.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
EntityHealth::EntityHealth(SceneItem* item) : SceneItemComponent(item) {
|
||||
|
||||
}
|
||||
|
||||
void EntityHealth::onStart() {
|
||||
useEvent([&](float_t delta){
|
||||
if(this->invincibleTime > 0.0f) {
|
||||
this->invincibleTime -= delta;
|
||||
}
|
||||
|
||||
if(this->stunTime > 0.0f) {
|
||||
this->stunTime -= delta;
|
||||
}
|
||||
}, getScene()->eventSceneUpdate);
|
||||
}
|
||||
|
||||
bool_t EntityHealth::isInvincible() {
|
||||
return this->invincibleTime > 0.0f;
|
||||
}
|
||||
|
||||
bool_t EntityHealth::isStunned() {
|
||||
return this->stunTime > 0.0f;
|
||||
}
|
||||
|
||||
void EntityHealth::damage(struct DamageInformation info) {
|
||||
if(this->isInvincible()) return;
|
||||
this->health -= info.amount;
|
||||
this->invincibleTime = info.invincibleTime;
|
||||
this->stunTime = info.stunTime;
|
||||
}
|
51
src/dawnrose/scene/components/EntityHealth.hpp
Normal file
51
src/dawnrose/scene/components/EntityHealth.hpp
Normal file
@ -0,0 +1,51 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "scene/SceneItemComponent.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
struct DamageInformation {
|
||||
int32_t amount = 0;
|
||||
float_t invincibleTime = 2.0f;
|
||||
float_t stunTime = 0.4f;
|
||||
};
|
||||
|
||||
class EntityHealth : public SceneItemComponent {
|
||||
public:
|
||||
// @optional
|
||||
int32_t health = 10;
|
||||
// @optional
|
||||
int32_t maxHealth = 10;
|
||||
// @optional
|
||||
float_t invincibleTime = 0.0f;
|
||||
// @optional
|
||||
float_t stunTime = 0.0f;
|
||||
|
||||
EntityHealth(SceneItem* item);
|
||||
void onStart() override;
|
||||
|
||||
/**
|
||||
* Returns true if the entity is invincible
|
||||
*
|
||||
* @return True if invincible, false otherwise.
|
||||
*/
|
||||
bool_t isInvincible();
|
||||
|
||||
/**
|
||||
* Returns true if the entity is stunned.
|
||||
*
|
||||
* @return True if stunned, false otherwise.
|
||||
*/
|
||||
bool_t isStunned();
|
||||
|
||||
/**
|
||||
* Apply damage to this entity.
|
||||
*
|
||||
* @param info The damage information.
|
||||
*/
|
||||
void damage(struct DamageInformation info);
|
||||
};
|
||||
}
|
53
src/dawnrose/scene/components/EntityRandomWalk.cpp
Normal file
53
src/dawnrose/scene/components/EntityRandomWalk.cpp
Normal file
@ -0,0 +1,53 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "EntityRandomWalk.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
EntityRandomWalk::EntityRandomWalk(SceneItem* item) : SceneItemComponent(item) {
|
||||
|
||||
}
|
||||
|
||||
std::vector<SceneItemComponent*> EntityRandomWalk::getDependencies() {
|
||||
return {
|
||||
(characterController = item->getComponent<CharacterController2D>())
|
||||
};
|
||||
}
|
||||
|
||||
void EntityRandomWalk::onStart() {
|
||||
assertNotNull(characterController);
|
||||
|
||||
useEvent([&](float_t delta) {
|
||||
// Do we need to pick a new destination
|
||||
if(timeLeftUntilNextDecision <= 0.0f) {
|
||||
// Pick a new destination to walk to.
|
||||
destination = randRange(-walkRange, walkRange);
|
||||
destination.x = mathAbs(destination.y) > mathAbs(destination.x) ? 0 : destination.x;
|
||||
destination.y = destination.x == 0 ? destination.y : 0;
|
||||
destination += glm::vec2(transform->getLocalPosition().x, transform->getLocalPosition().z);
|
||||
timeLeftUntilNextDecision = 4.0f;
|
||||
} else {
|
||||
timeLeftUntilNextDecision -= delta;
|
||||
}
|
||||
|
||||
// Get the direction to move in
|
||||
glm::vec2 pos = destination - glm::vec2(
|
||||
transform->getLocalPosition().x,
|
||||
transform->getLocalPosition().z
|
||||
);
|
||||
|
||||
// Conver to an angle and then convert back into a 2D vector. This mimics a
|
||||
// user essentially "moving the analogue stick in this direction"
|
||||
|
||||
if(mathAbs(pos.x) > 1.0f || mathAbs(pos.y) > 1.0f) {
|
||||
float_t angle = atan2(pos.y, pos.x);
|
||||
glm::vec2 movement(cos(angle), sin(angle));
|
||||
transform->setLocalRotation(glm::quat(glm::vec3(0, -angle + 1.5708f, 0)));
|
||||
characterController->velocity += movement * delta * moveSpeed;
|
||||
}
|
||||
|
||||
}, getScene()->eventSceneUpdate);
|
||||
}
|
30
src/dawnrose/scene/components/EntityRandomWalk.hpp
Normal file
30
src/dawnrose/scene/components/EntityRandomWalk.hpp
Normal file
@ -0,0 +1,30 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "scene/SceneItemComponent.hpp"
|
||||
#include "util/random.hpp"
|
||||
#include "scene/components/physics/2d/CharacterController2D.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class EntityRandomWalk : public SceneItemComponent {
|
||||
protected:
|
||||
CharacterController2D *characterController = nullptr;
|
||||
|
||||
public:
|
||||
// @optional
|
||||
float_t timeLeftUntilNextDecision = 0.0f;
|
||||
// @optional
|
||||
float_t moveSpeed = 30.0f;
|
||||
// @optional
|
||||
glm::vec2 destination = glm::vec2(0, 0);
|
||||
// @optional
|
||||
glm::vec2 walkRange = glm::vec2(12.0f, 12.0f);
|
||||
|
||||
EntityRandomWalk(SceneItem* item);
|
||||
std::vector<SceneItemComponent*> getDependencies() override;
|
||||
void onStart() override;
|
||||
};
|
||||
}
|
11
src/dawnrose/scene/components/HurtHazard.cpp
Normal file
11
src/dawnrose/scene/components/HurtHazard.cpp
Normal file
@ -0,0 +1,11 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "HurtHazard.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
HurtHazard::HurtHazard(SceneItem* item) : SceneItemComponent(item) {}
|
||||
|
16
src/dawnrose/scene/components/HurtHazard.hpp
Normal file
16
src/dawnrose/scene/components/HurtHazard.hpp
Normal file
@ -0,0 +1,16 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "scene/SceneItemComponent.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class HurtHazard : public SceneItemComponent {
|
||||
public:
|
||||
int32_t damage = 1;
|
||||
|
||||
HurtHazard(SceneItem* item);
|
||||
};
|
||||
}
|
@ -14,19 +14,24 @@ PlayerController::PlayerController(SceneItem *item) : SceneItemComponent(item) {
|
||||
|
||||
std::vector<SceneItemComponent*> PlayerController::getDependencies() {
|
||||
return {
|
||||
(this->characterController = item->getComponent<CharacterController2D>())
|
||||
(this->characterController = item->getComponent<CharacterController2D>()),
|
||||
(this->entityHealth = item->getComponent<EntityHealth>())
|
||||
};
|
||||
}
|
||||
|
||||
void PlayerController::onStart() {
|
||||
assertNotNull(this->characterController);
|
||||
assertNotNull(this->entityHealth);
|
||||
|
||||
useEvent([&](float_t delta){
|
||||
// Don't move if stunned.
|
||||
if(entityHealth->isStunned()) return;
|
||||
|
||||
// Movement
|
||||
auto inputMove = getGame()->inputManager.getAxis2D(
|
||||
INPUT_BIND_NEGATIVE_X, INPUT_BIND_POSITIVE_X,
|
||||
INPUT_BIND_NEGATIVE_Y, INPUT_BIND_POSITIVE_Y
|
||||
) * delta * moveSpeed;
|
||||
);
|
||||
|
||||
if(inputMove.x != 0 || inputMove.y != 0) {
|
||||
float_t angle = atan2(inputMove.y, inputMove.x);
|
||||
@ -37,4 +42,26 @@ void PlayerController::onStart() {
|
||||
characterController->velocity += movement * delta * moveSpeed;
|
||||
}
|
||||
}, getScene()->eventSceneUpdate);
|
||||
|
||||
// Hurt Hazard Processing
|
||||
useEvent([&](struct CharacterController2DCollisionEventInfo info) {
|
||||
if(entityHealth->isInvincible()) return;
|
||||
|
||||
auto hurtHazard = info.collider->item->getComponent<HurtHazard>();
|
||||
if(hurtHazard == nullptr) return;
|
||||
|
||||
glm::vec2 back = glm::vec2(
|
||||
info.collider->transform->getLocalPosition().x,
|
||||
info.collider->transform->getLocalPosition().z
|
||||
) - glm::vec2(
|
||||
this->transform->getLocalPosition().x,
|
||||
this->transform->getLocalPosition().z
|
||||
);
|
||||
|
||||
this->characterController->velocity = back * -hitKnockback;
|
||||
this->entityHealth->damage({
|
||||
.amount = hurtHazard->damage
|
||||
});
|
||||
}, this->characterController->eventCollision);
|
||||
|
||||
}
|
@ -5,20 +5,23 @@
|
||||
|
||||
#pragma once
|
||||
#include "scene/components/physics/2d/CharacterController2D.hpp"
|
||||
#include "scene/components/HurtHazard.hpp"
|
||||
#include "scene/components/EntityHealth.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class PlayerController : public SceneItemComponent {
|
||||
protected:
|
||||
CharacterController2D *characterController;
|
||||
EntityHealth *entityHealth;
|
||||
|
||||
public:
|
||||
// @optional
|
||||
float_t moveSpeed = 80.0f;
|
||||
float_t moveSpeed = 60.0f;
|
||||
// @optional
|
||||
float_t hitKnockback = 20.0f;
|
||||
|
||||
PlayerController(SceneItem *item);
|
||||
|
||||
std::vector<SceneItemComponent*> getDependencies() override;
|
||||
|
||||
void onStart() override;
|
||||
};
|
||||
}
|
@ -7,6 +7,8 @@
|
||||
#include "scene/Scene.hpp"
|
||||
#include "scene/components/GameCamera.hpp"
|
||||
#include "prefabs/Player.hpp"
|
||||
#include "prefabs/Urchin.hpp"
|
||||
#include "prefabs/Crab.hpp"
|
||||
#include "prefabs/ui/debug/FPSLabel.hpp"
|
||||
#include "display/mesh/CapsuleMesh.hpp"
|
||||
#include "display/mesh/CubeMesh.hpp"
|
||||
@ -21,15 +23,21 @@ namespace Dawn {
|
||||
|
||||
auto player = Player::create(this);
|
||||
|
||||
auto urchin = Urchin::create(this);
|
||||
urchin->transform.setLocalPosition(glm::vec3(0, 0, -5));
|
||||
|
||||
auto crab = Crab::create(this);
|
||||
crab->transform.setLocalPosition(glm::vec3(3, 0, 0));
|
||||
|
||||
canvas = UICanvas::create(this);
|
||||
|
||||
auto wallBox = this->createSceneItem()->addComponent<BoxCollider>();
|
||||
wallBox->min = glm::vec2(-4, -3);
|
||||
wallBox->max = glm::vec2(-3, 3);
|
||||
// auto wallBox = this->createSceneItem()->addComponent<BoxCollider>();
|
||||
// wallBox->min = glm::vec2(-4, -3);
|
||||
// wallBox->max = glm::vec2(-3, 3);
|
||||
|
||||
auto wallBox2 = this->createSceneItem()->addComponent<BoxCollider>();
|
||||
wallBox2->min = glm::vec2(-3, -4);
|
||||
wallBox2->max = glm::vec2(3, -3);
|
||||
// auto wallBox2 = this->createSceneItem()->addComponent<BoxCollider>();
|
||||
// wallBox2->min = glm::vec2(-3, -4);
|
||||
// wallBox2->max = glm::vec2(3, -3);
|
||||
|
||||
camera = Camera::create(this);
|
||||
camera->fov = 0.436332f;
|
||||
|
Reference in New Issue
Block a user