From d4a8e9d908ed69e943aa334a77fca3c163a4943c Mon Sep 17 00:00:00 2001 From: Fredrick Johansson Date: Wed, 19 Aug 2020 20:56:14 +0200 Subject: [PATCH] JAMSPOOK-13 - Acceleration and reverse - Can now accelerate and reverse in the direction the car is pointing in. --- assets/meshes/kart-driver.bcosm | Bin 52124 -> 52124 bytes assets/meshes/kart-hulls.bcosp | Bin 11724 -> 11724 bytes assets/meshes/kart-vehicle.bcosm | Bin 61724 -> 61724 bytes src/JamSpookGame.cpp | 26 ++--- src/entities/KartFactory.cpp | 17 +++- src/entities/KartFactory.h | 23 +++-- src/entities/KartInteractionComponent.cpp | 114 ++++++++++++++++++++++ src/entities/KartInteractionComponent.h | 87 +++++++++++++++++ src/entities/KartPhysicsComponent.cpp | 44 ++++++++- src/entities/KartPhysicsComponent.h | 16 +++ src/messages/JumpMessage.cpp | 28 ++++++ src/messages/JumpMessage.h | 41 ++++++++ 12 files changed, 368 insertions(+), 28 deletions(-) create mode 100755 src/entities/KartInteractionComponent.cpp create mode 100755 src/entities/KartInteractionComponent.h create mode 100755 src/messages/JumpMessage.cpp create mode 100755 src/messages/JumpMessage.h diff --git a/assets/meshes/kart-driver.bcosm b/assets/meshes/kart-driver.bcosm index 01225db63b4d0ae6f96743222a577b43650ab554..dcfc87a7048dbc708a3841f5f70885d99bd44e7f 100644 GIT binary patch literal 52124 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 Y0Neb)??-depF#P7#t-60c=UYxKcs}D`Tzg` literal 52124 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 diff --git a/assets/meshes/kart-hulls.bcosp b/assets/meshes/kart-hulls.bcosp index a23875bd1c70ef1d7098415bb64630abbe5af0b7..c773a183144b3f8851d92425868dc44d6193cd16 100644 GIT binary patch literal 11724 zcmeHNU5Hgx6h31HWl4ewp^m@Rs5#a{J?MDPzCxC1L`>g z$%+CoA5=7uqSl`vPZdy-whmHJyemB)vW`+swnD@ z@z0aK9iA+Db82$o=H+-Q#b3VOr;eQYo8sf>ZQ_X0|51-oe8K#|)$KRlPE5QOr+7vG zr%&RS@Q)Jz#{2iEc_Th1e&{p&;D$yiF7Zzq)}a<=^hb*HE98bVBz_4$nfPBJ{m(l6 zhTrO!;u1gAM{T6~9Cr1oYW>8o>m%_?_*UZIn&}V2Z~H@vOZ@r%szJZ*J=CBCzt^8x ze7^ro-0IKPH$wm0^L2ko{z>{IehHt|4}Ddw&+3=@BisMWaQ#}m?(eMsh#P*}KN7!$ zm+C(-i=)WS;x+q+CgUESq7IGPna(;hYjHhbCiPOh{n+%XiPvW_VtBul#y@Nx+RtZk z8c!sC3BQi`$C5t7U!TRq4}FOgm-tugAF38pejhpgx>t2>W%wn0C-KAIx_-y6^-FPy zea#f2kVyVX`Ahr~KC8bzi>*gee`Nc=K8xWkII{lLXK@-=62F9(>OU}x>$CW3)0X5| z%ZB*$(TA#hFSfP5M)5J#*VHK;&(C7SM^pUAZP=?3H+!qCbs2sMf0*pmzXV>L$mnC5+54Z1aV8U7M@ufH9?)zA7TKZ_;*r2Hu^@)!9BeEs^&&tj=Rvi+Z* z#aaLIv$za@eLjToMg27}i=*feeOSS3U8OY{Id7WUapf!8i>rE;(mbW#&8wHLo>$fF+pov%r&^QsFV0YJ%{qA;@y^M+)SqoPl8z_VtD|G?jGvp{l05%&i`sPd zi@sHrRyCUV-`D&#{T&1G(>dnVN%1bi|3&!kR$huzys~)2XVdw>&-vxwI6YtS^R2!n ztv^y+AIF<`4RMF(=kMP)1^Fw|@6PA>H{!SY8{w@#CLV#``BTP!ix2s`mi+&%_YE~; z!`=Na99^Qe@10r!KY1UMhl%7r;=dEVjqtmBj>jn;wbOX+PpCe;{-OLhKI9KSf5H3_ z&VPHp#4q8wKZf7jC#qXJYUqAX|*bftD!hdx4rgO7I|GUWl33Pqz)%aSR z;`Q}m@kRCF`a=0h{_yi@E;|3Meu-bgbAJrK@!#^>c%%7a61YsmkrBTrOr(ER@3^bmEZKL0U;#QEP%`8SU`QNjG*NwrJyn7L48QT8^B3KJIX>hs;@7_4+=lwKZyTg;*6+^= z?$5}-=>7}+SI%#4!~GS#o#JtS)Oem>s6Jd@C_j!5`ODA0gRU?1e|mq`=a=EP`WxY` zKPK+>1I;h(2R-D^T-ranPu^Aa_!aqEA$@8h&2Pj>dvL$8`%7s5knmFdr2S+y^~W=$ zf3?%^^4I#M{3Lz}FZm0734vYkY3MQ9Qp;eYn0*ejFe27jb)jU_Vl2 z_$9pcC$OKXGX7h9$Y1owCHnk?{`dByxNQFe-%faMztMQ^PhkJl{#bpX{5U@3FXHxm zZ~xTi^ZshYUxerWc>9^=m;C4WkiWpMrtc3h|GoW4m6`vze{~anG~vDdM&r3Zq55!r zq5L>LjMd+x^1ZKUJCii0=>H{;BaizfgU+zEFM~ zAM%%mA{b{hD7UnPErTplgGVu3; z_%e)M*Xg;-&E@aJOMco#-yinVXUXi}sQf|kcR$;tOnjXFj*vgMLVP>L?^!yyKlEI* z48Mf`hx856{Ltr~yW+W40{)`7r0)_v*F%2yI{guz%h|WcFX1l}|1HvQ__e=|8~UZV z#EGT)zOZa^MIex7_+dmQd zALk;b-;#e){$==!^2_RnKJCBNr=(^b literal 11724 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 N|A-&qdHj*||39iK6o>!- diff --git a/src/JamSpookGame.cpp b/src/JamSpookGame.cpp index ceead3c..1b2b8bf 100644 --- a/src/JamSpookGame.cpp +++ b/src/JamSpookGame.cpp @@ -242,17 +242,17 @@ void JamSpookGame::set() // delete floorFactory; // - // Create 2 jump180s - unique_ptr jump180Factory = make_unique( - dynamic_pointer_cast(findSystem(IDCache::get("AssetSystem"))), - graphicsSystem, - dynamic_pointer_cast(findSystem(IDCache::get("PhysicsSystem"))), - renderLayerGame); - - jump180Factory->createJump180(vec3(0, 0, 0), vec3(0, 0, 0)); - jump180Factory->createJump180(vec3(18,-10, 12), vec3(0, 180, 0)); - - jump180Factory.reset(); +// // Create 2 jump180s +// unique_ptr jump180Factory = make_unique( +// dynamic_pointer_cast(findSystem(IDCache::get("AssetSystem"))), +// graphicsSystem, +// dynamic_pointer_cast(findSystem(IDCache::get("PhysicsSystem"))), +// renderLayerGame); +// +// jump180Factory->createJump180(vec3(0, 0, 0), vec3(0, 0, 0)); +// jump180Factory->createJump180(vec3(18,-10, 12), vec3(0, 180, 0)); +// +// jump180Factory.reset(); // Create the goal unique_ptr goalFactory = make_unique( @@ -261,7 +261,8 @@ void JamSpookGame::set() dynamic_pointer_cast(findSystem(IDCache::get("PhysicsSystem"))), renderLayerGame); - goalFactory->createGoal(vec3(0, -25, -10)); +// goalFactory->createGoal(vec3(0, -25, -10)); + goalFactory->createGoal(vec3(0, 0, 0)); goalFactory.reset(); @@ -285,6 +286,7 @@ void JamSpookGame::set() dynamic_pointer_cast(findSystem(IDCache::get("AssetSystem"))), graphicsSystem, dynamic_pointer_cast(findSystem(IDCache::get("PhysicsSystem"))), + dynamic_pointer_cast(findSystem(IDCache::get("InteractionSystem"))), renderLayerGame); kartFactory->createKart(vec3(0, 3, 0), // position diff --git a/src/entities/KartFactory.cpp b/src/entities/KartFactory.cpp index 78a419d..8d64228 100644 --- a/src/entities/KartFactory.cpp +++ b/src/entities/KartFactory.cpp @@ -9,13 +9,15 @@ namespace JamSpook { -KartFactory::KartFactory(weak_ptr assetSystem, - weak_ptr graphicsSystem, - weak_ptr physicsSystem, - weak_ptr renderLayer): +KartFactory::KartFactory(weak_ptr assetSystem, + weak_ptr graphicsSystem, + weak_ptr physicsSystem, + weak_ptr interactionSystem, + weak_ptr renderLayer): mAssetSystem(assetSystem), mGraphicsSystem(graphicsSystem), mPhysicsSystem(physicsSystem), + mInteractionSystem(interactionSystem), mRenderLayer(renderLayer) {} @@ -98,6 +100,13 @@ shared_ptr KartFactory::createKart(const vec3 position, graphicsComponent->setLightSource(lightSource); delete lightSourceFactory; + // Add interaction component + shared_ptr interactionComponent = + make_shared(transform, + entity, + getShared(mInteractionSystem)); + entity->addComponent(interactionComponent); + // Return instance return entity; } diff --git a/src/entities/KartFactory.h b/src/entities/KartFactory.h index 7888ead..9a9f2f4 100644 --- a/src/entities/KartFactory.h +++ b/src/entities/KartFactory.h @@ -55,7 +55,10 @@ #include #include +#include + #include "KartPhysicsComponent.h" +#include "KartInteractionComponent.h" namespace JamSpook { @@ -110,6 +113,8 @@ using ecos::graphics::ModelRenderable; using ecos::graphics::lighting::LightSource; using ecos::graphics::lighting::LightSourceFactory; +using ecos::interaction::InteractionSystem; + using ecos::physics::PhysicsSystem; using ecos::physics::PhysicsComponent; using ecos::physics::ColliderFactory; @@ -119,16 +124,18 @@ using ecos::physics::Collider; class KartFactory { private: - weak_ptr mAssetSystem; - weak_ptr mGraphicsSystem; - weak_ptr mPhysicsSystem; - weak_ptr mRenderLayer; + weak_ptr mAssetSystem; + weak_ptr mGraphicsSystem; + weak_ptr mPhysicsSystem; + weak_ptr mInteractionSystem; + weak_ptr mRenderLayer; public: - KartFactory(weak_ptr assetSystem, - weak_ptr graphicsSystem, - weak_ptr physicsSystem, - weak_ptr renderLayer); + KartFactory(weak_ptr assetSystem, + weak_ptr graphicsSystem, + weak_ptr physicsSystem, + weak_ptr interactionSystem, + weak_ptr renderLayer); virtual ~KartFactory(); /// Compose a kart entity diff --git a/src/entities/KartInteractionComponent.cpp b/src/entities/KartInteractionComponent.cpp new file mode 100755 index 0000000..415b78a --- /dev/null +++ b/src/entities/KartInteractionComponent.cpp @@ -0,0 +1,114 @@ +/* + * KartInteractionComponent.cpp + * + * Created on: Aug 19, 2020 + * Author: fredrick + */ + +#include "KartInteractionComponent.h" + +namespace JamSpook { + +KartInteractionComponent::KartInteractionComponent(mat4 transform, + shared_ptr > > entity, + weak_ptr interactionSystem): + InteractionComponent(transform, entity, interactionSystem), + mOldDirection(vec3(0)), + mIsOnGround(false) +{} + +KartInteractionComponent::~KartInteractionComponent() +{} + +void KartInteractionComponent::onInputDeviceStateChange(const InputDeviceState inputDeviceState) +{ + Log::write(LogLevel::debug, "KartInteractionComponent - onInputDeviceStateChange"); + + vec3 accumulatedDirection = vec3(0); + + // Handle controls + if (inputDeviceState.left == ButtonState::pressed || inputDeviceState.left == ButtonState::held) + { + accumulatedDirection += vec3(-1.0f, 0, 0); + } + else if (inputDeviceState.left == ButtonState::released) + { + accumulatedDirection -= vec3(-1.0f, 0, 0); + } + + if (inputDeviceState.right == ButtonState::pressed || inputDeviceState.right == ButtonState::held) + { + accumulatedDirection += vec3(1.0f, 0, 0); + } + else if (inputDeviceState.right == ButtonState::released) + { + accumulatedDirection -= vec3(1.0f, 0, 0); + } + + if (inputDeviceState.up == ButtonState::pressed || inputDeviceState.up == ButtonState::held) + { + accumulatedDirection += vec3(0, 0, 1.0f); + } + else if (inputDeviceState.up == ButtonState::released) + { + accumulatedDirection -= vec3(0, 0, 1.0f); + } + + if (inputDeviceState.down == ButtonState::pressed || inputDeviceState.down == ButtonState::held) + { + accumulatedDirection += vec3(0, 0, -1.0f); + } + else if (inputDeviceState.down == ButtonState::released) + { + accumulatedDirection -= vec3(0, 0, -1.0f); + } + + + if (inputDeviceState.action == ButtonState::pressed) + { + // if on ground (can jump) + if (mIsOnGround) + { + // Send jump message, containing current position + ICCBroadcast(dynamic_pointer_cast( + make_shared(getTranslation(mTransform)))); + } + } + + if (inputDeviceState.up == ButtonState::neutral && + inputDeviceState.down == ButtonState::neutral && + inputDeviceState.left == ButtonState::neutral && + inputDeviceState.right == ButtonState::neutral) + { + accumulatedDirection = vec3(0); + } + + if (accumulatedDirection != mOldDirection) + { + ICCBroadcast(dynamic_pointer_cast( + make_shared( + getTranslation(mTransform), + mOldDirection, + accumulatedDirection))); + } + mOldDirection = accumulatedDirection; +} + +void KartInteractionComponent::onICCMessage(shared_ptr message) +{ + InteractionComponent::onICCMessage(message); + + // Jump message, make the kart jump + if (message->getMessageType() == IDCache::get("GroundCollisionMessage")) + { + Log::write(LogLevel::debug, "KartInteractionComponent - onICCMessage - GroundCollisionMessage"); + mIsOnGround = true; + } + if (message->getMessageType() == IDCache::get("GroundSeparationMessage")) + { + Log::write(LogLevel::debug, "KartInteractionComponent - onICCMessage - GroundSeparationMessage"); + mIsOnGround = false; + } +} + +} // namespace JamSpook diff --git a/src/entities/KartInteractionComponent.h b/src/entities/KartInteractionComponent.h new file mode 100755 index 0000000..1969e27 --- /dev/null +++ b/src/entities/KartInteractionComponent.h @@ -0,0 +1,87 @@ +/* + * KartInteractionComponent.h + * + * Created on: Aug 19, 2020 + * Author: fredrick + */ + +#ifndef KARTINTERACTIONCOMPONENT_H_ +#define KARTINTERACTIONCOMPONENT_H_ + +#include +#include +#include + +#define GLM_FORCE_RADIANS +#include +#include + +#include + +#include +#include +#include +#include + +#include + +#include +#include + +#include "../messages/DirectionChangeMessage.h" +#include "../messages/JumpMessage.h" + +namespace JamSpook { + +using std::chrono::milliseconds; +using std::shared_ptr; +using std::make_shared; +using std::weak_ptr; +using std::dynamic_pointer_cast; + +using glm::vec3; +using glm::mat4; +using glm::translate; +using glm::rotate; +using glm::radians; + +using ecos::utility::getTranslation; + +using ecos::core::IDCache; +using ecos::core::logging::Log; +using ecos::core::logging::LogLevel; +using ecos::core::BroadcastObservable; +using ecos::core::Message; + +using ecos::physics::TransformChangeMessage; + +using ecos::interaction::InteractionSystem; +using ecos::interaction::InputDeviceState; +using ecos::interaction::ButtonState; +using ecos::interaction::InteractionComponent; + +using messages::DirectionChangeMessage; +using messages::JumpMessage; + +/// Kart interaction component +/// entity specific interaction system code +class KartInteractionComponent : + public InteractionComponent +{ +private: + vec3 mOldDirection; ///< Used to construct the DirectionChangeMessaage + bool mIsOnGround; + +public: + KartInteractionComponent(mat4 transform, + shared_ptr > > entity, + weak_ptr wInteractionSystem); + virtual ~KartInteractionComponent(); + + virtual void onInputDeviceStateChange(const InputDeviceState inputDeviceState); + virtual void onICCMessage(shared_ptr message); +}; + +} // namespace JamSpook + +#endif // KARTINTERACTIONCOMPONENT_H_ diff --git a/src/entities/KartPhysicsComponent.cpp b/src/entities/KartPhysicsComponent.cpp index aef2ca9..0ec58c6 100644 --- a/src/entities/KartPhysicsComponent.cpp +++ b/src/entities/KartPhysicsComponent.cpp @@ -37,20 +37,56 @@ void KartPhysicsComponent::update(const milliseconds dtms) 10, /// above the ball getFloatInRange(-10.0f, 10.0f))); } + + if (glm::length(mDirection) > 0) + { + // Forward or backwards force + mCollider->applyForce(mat3(mTransform) * vec3(0, 0, mDirection.z * 500), + vec3(0, 0, 0)); + + // Turning torque + + } } void KartPhysicsComponent::onICCMessage(shared_ptr message) { PhysicsComponent::onICCMessage(message); + + // DirectionChangeMessage + if (message->getMessageType() == IDCache::get("DirectionChangeMessage")) + { + Log::write(LogLevel::debug, "KartPhysicsComponent - onICCMessage - DirectionChangeMessage - getNewDirection: " + glm::to_string(mDirection)); + + shared_ptr msg = dynamic_pointer_cast(message); + mDirection = msg->getNewDirection(); + } + + // Jump message, make the kart jump + if (message->getMessageType() == IDCache::get("JumpMessage")) + { + Log::write(LogLevel::debug, "KartPhysicsComponent - onICCMessage - JumpMessage"); + + // shared_ptr msg = dynamic_pointer_cast(message); + // Does not use any data in message, skip casting, but leave code as reference + + mCollider->applyImpulse(vec3(0, 1000, 0), vec3(0, 0, 0)); + } } void KartPhysicsComponent::onCollision(const string& tag) { - if (tag == "ground-plane") + if (tag == "goal") { - vec3 position = getPosition(); - setPosition(vec3(position.x, 10.0f, position.z)); - ICCBroadcast(make_shared(IDCache::get("GroundContactMessage"))); + ICCBroadcast(make_shared(IDCache::get("GroundCollisionMessage"))); + } +} + +void KartPhysicsComponent::onSeparation(const string& tag) +{ + if (tag == "goal") + { + ICCBroadcast(make_shared(IDCache::get("GroundSeparationMessage"))); } } diff --git a/src/entities/KartPhysicsComponent.h b/src/entities/KartPhysicsComponent.h index e45469c..4dd6eac 100644 --- a/src/entities/KartPhysicsComponent.h +++ b/src/entities/KartPhysicsComponent.h @@ -15,7 +15,9 @@ #include #include +#include +#include #include #include @@ -30,6 +32,9 @@ #include #include +#include "../messages/DirectionChangeMessage.h" +#include "../messages/JumpMessage.h" + namespace JamSpook { using std::chrono::milliseconds; @@ -40,10 +45,14 @@ using std::dynamic_pointer_cast; using std::string; using glm::vec3; +using glm::vec4; +using glm::mat3; using glm::mat4; using glm::translate; using glm::scale; +using glm::rotate; +using ecos::utility::getDirection; using ecos::utility::getFloatInRange; using ecos::core::IDCache; @@ -59,10 +68,16 @@ using ecos::physics::TransformChangeMessage; using ecos::physics::CollisionStateChangeMessage; using ecos::physics::ColliderQueryMessage; +using messages::DirectionChangeMessage; +using messages::JumpMessage; + /// class KartPhysicsComponent: public ecos::physics::PhysicsComponent { +private: + vec3 mDirection; + public: KartPhysicsComponent(mat4 transform, shared_ptr > > entity, @@ -75,6 +90,7 @@ public: virtual void update(const milliseconds dtms); virtual void onICCMessage(shared_ptr message); virtual void onCollision(const string& tag); + virtual void onSeparation(const string& tag); }; } // namespace JamSpook diff --git a/src/messages/JumpMessage.cpp b/src/messages/JumpMessage.cpp new file mode 100755 index 0000000..8986008 --- /dev/null +++ b/src/messages/JumpMessage.cpp @@ -0,0 +1,28 @@ +/* + * JumpMessage.cpp + * + * Created on: Oct 20, 2018 + * Author: fredrick + */ + +#include "JumpMessage.h" + +namespace JamSpook { +namespace messages { + + +JumpMessage::JumpMessage(const vec3 position): + Message(IDCache::add("JumpMessage")), + mPosition(position) +{} + +JumpMessage::~JumpMessage() +{} + +const vec3 JumpMessage::getPosition() const +{ + return mPosition; +} + +} // namespace messages +} // namespace JamSpook diff --git a/src/messages/JumpMessage.h b/src/messages/JumpMessage.h new file mode 100755 index 0000000..f14d237 --- /dev/null +++ b/src/messages/JumpMessage.h @@ -0,0 +1,41 @@ +/* + * JumpMessage.h + * + * Created on: Aug 19, 2020 + * Author: fredrick + */ + +#ifndef JUMPMESSAGE_H_ +#define JUMPMESSAGE_H_ + +#include + +#include +#include + +namespace JamSpook { +namespace messages { + +using glm::vec3; +using ecos::core::IDCache; +using ecos::core::Message; + +/// Jump message +/// Used to inform systems about a jump action being initiated +class JumpMessage : + public Message +{ +private: + vec3 mPosition; ///< Where the jump occured + +public: + JumpMessage(const vec3 position); + virtual ~JumpMessage(); + + const vec3 getPosition() const; +}; + +} // namespace messages +} // namespace JamSpook + +#endif // JUMPMESSAGE_H_