diff --git a/Crawler/Crawler.vcxproj b/Crawler/Crawler.vcxproj index 9c6368ef..a47757da 100644 --- a/Crawler/Crawler.vcxproj +++ b/Crawler/Crawler.vcxproj @@ -133,6 +133,7 @@ + diff --git a/Crawler/Crawler.vcxproj.filters b/Crawler/Crawler.vcxproj.filters index ea59ed75..69ac8a8b 100644 --- a/Crawler/Crawler.vcxproj.filters +++ b/Crawler/Crawler.vcxproj.filters @@ -27,6 +27,9 @@ Header Files + + Header Files + diff --git a/Crawler/assets/nico-warrior.png b/Crawler/assets/nico-warrior.png index 03428b2e..9b84f38a 100644 Binary files a/Crawler/assets/nico-warrior.png and b/Crawler/assets/nico-warrior.png differ diff --git a/Crawler/assets/nico-warrior.xcf b/Crawler/assets/nico-warrior.xcf index 361693c7..1ce35b5b 100644 Binary files a/Crawler/assets/nico-warrior.xcf and b/Crawler/assets/nico-warrior.xcf differ diff --git a/Crawler/main.cpp b/Crawler/main.cpp index 29d6e38d..84793f09 100644 --- a/Crawler/main.cpp +++ b/Crawler/main.cpp @@ -3,18 +3,51 @@ #include "olcUTIL_Camera2D.h" #define OLC_PGEX_TRANSFORMEDVIEW #include "olcPGEX_TransformedView.h" +#include "olcUTIL_Animate2D.h" using namespace olc; using namespace olc::utils; const vi2d WINDOW_SIZE={24*8,24*8}; +enum AnimationState{ + WALK_S,WALK_E,WALK_N,WALK_W, + IDLE_S,IDLE_E,IDLE_N,IDLE_W +}; + struct Player{ vf2d pos; float moveSpd; + AnimationState animState=AnimationState::IDLE_S; + private: + Animate2D::Animationanimation; + Animate2D::AnimationState internal_animState; + Key lastReleasedMovementKey; + public: Player(){}; Player(vf2d pos,float moveSpd): - pos(pos),moveSpd(moveSpd){}; + pos(pos),moveSpd(moveSpd){ + }; + void Update(float fElapsedTime){ + animation.UpdateState(internal_animState,fElapsedTime); + } + void AddAnimation(AnimationState state,Animate2D::FrameSequence frame){ + animation.AddState(state,frame); + }; + void UpdateAnimation(AnimationState animState){ + animation.ChangeState(internal_animState,animState); + } + + Animate2D::Frame GetFrame(){ + return animation.GetFrame(internal_animState); + } + + void SetLastReleasedMovementKey(Key k){ + lastReleasedMovementKey=k; + } + Key GetLastReleasedMovementKey(){ + return lastReleasedMovementKey; + } }; class Crawler : public olc::PixelGameEngine @@ -23,6 +56,7 @@ class Crawler : public olc::PixelGameEngine Camera2D camera; TileTransformedView view; Player player=Player{{},100}; + Renderable GFX_Pl_sheet; public: Crawler() @@ -33,35 +67,167 @@ public: public: bool OnUserCreate() override { + //Initialize Camera. camera=Camera2D{WINDOW_SIZE}; camera.SetMode(olc::utils::Camera2D::Mode::LazyFollow); camera.SetTarget(player.pos); camera.SetWorldBoundary({0,0},WORLD_SIZE*24); camera.EnableWorldBoundary(false); + + //Graphics + GFX_Pl_sheet.Load("assets/nico-warrior.png"); + + //Animations + Animate2D::FrameSequence pl_walk_s{0.2}; + pl_walk_s.AddFrame({&GFX_Pl_sheet,{vi2d{0,0}*24,{24,24}}}); + pl_walk_s.AddFrame({&GFX_Pl_sheet,{vi2d{1,0}*24,{24,24}}}); + pl_walk_s.AddFrame({&GFX_Pl_sheet,{vi2d{0,0}*24,{24,24}}}); + pl_walk_s.AddFrame({&GFX_Pl_sheet,{vi2d{2,0}*24,{24,24}}}); + Animate2D::FrameSequence pl_walk_e{0.2}; + pl_walk_e.AddFrame({&GFX_Pl_sheet,{vi2d{0,3}*24,{24,24}}}); + pl_walk_e.AddFrame({&GFX_Pl_sheet,{vi2d{1,3}*24,{24,24}}}); + pl_walk_e.AddFrame({&GFX_Pl_sheet,{vi2d{0,3}*24,{24,24}}}); + pl_walk_e.AddFrame({&GFX_Pl_sheet,{vi2d{2,3}*24,{24,24}}}); + Animate2D::FrameSequence pl_walk_w{0.2}; + pl_walk_w.AddFrame({&GFX_Pl_sheet,{vi2d{0,2}*24,{24,24}}}); + pl_walk_w.AddFrame({&GFX_Pl_sheet,{vi2d{1,2}*24,{24,24}}}); + pl_walk_w.AddFrame({&GFX_Pl_sheet,{vi2d{0,2}*24,{24,24}}}); + pl_walk_w.AddFrame({&GFX_Pl_sheet,{vi2d{2,2}*24,{24,24}}}); + Animate2D::FrameSequence pl_walk_n{0.2}; + pl_walk_n.AddFrame({&GFX_Pl_sheet,{vi2d{0,1}*24,{24,24}}}); + pl_walk_n.AddFrame({&GFX_Pl_sheet,{vi2d{1,1}*24,{24,24}}}); + pl_walk_n.AddFrame({&GFX_Pl_sheet,{vi2d{0,1}*24,{24,24}}}); + pl_walk_n.AddFrame({&GFX_Pl_sheet,{vi2d{2,1}*24,{24,24}}}); + Animate2D::FrameSequence pl_idle_s; + pl_idle_s.AddFrame({&GFX_Pl_sheet,{vi2d{0,0}*24,{24,24}}}); + Animate2D::FrameSequence pl_idle_e; + pl_idle_e.AddFrame({&GFX_Pl_sheet,{vi2d{0,3}*24,{24,24}}}); + Animate2D::FrameSequence pl_idle_w; + pl_idle_w.AddFrame({&GFX_Pl_sheet,{vi2d{0,2}*24,{24,24}}}); + Animate2D::FrameSequence pl_idle_n; + pl_idle_n.AddFrame({&GFX_Pl_sheet,{vi2d{0,1}*24,{24,24}}}); + + + player.AddAnimation(WALK_N,pl_walk_n); + player.AddAnimation(WALK_E,pl_walk_e); + player.AddAnimation(WALK_S,pl_walk_s); + player.AddAnimation(WALK_W,pl_walk_w); + player.AddAnimation(IDLE_N,pl_idle_n); + player.AddAnimation(IDLE_E,pl_idle_e); + player.AddAnimation(IDLE_S,pl_idle_s); + player.AddAnimation(IDLE_W,pl_idle_w); view=TileTransformedView{GetScreenSize(),{1,1}}; + + player.UpdateAnimation(IDLE_S); + return true; } bool OnUserUpdate(float fElapsedTime) override { HandleUserInput(fElapsedTime); + player.Update(fElapsedTime); UpdateCamera(fElapsedTime); RenderWorld(); return true; } void HandleUserInput(float fElapsedTime){ + bool setIdleAnimation=true; if(GetKey(RIGHT).bHeld){ player.pos.x+=fElapsedTime*player.moveSpd; + player.UpdateAnimation(WALK_E); + setIdleAnimation=false; } if(GetKey(LEFT).bHeld){ player.pos.x-=fElapsedTime*player.moveSpd; + if(setIdleAnimation){ + player.UpdateAnimation(WALK_W); + } + setIdleAnimation=false; } if(GetKey(UP).bHeld){ player.pos.y-=fElapsedTime*player.moveSpd; + if(setIdleAnimation){ + player.UpdateAnimation(WALK_N); + } + setIdleAnimation=false; } if(GetKey(DOWN).bHeld){ player.pos.y+=fElapsedTime*player.moveSpd; + if(setIdleAnimation){ + player.UpdateAnimation(WALK_S); + } + setIdleAnimation=false; + } + + if(GetKey(UP).bReleased){ + player.SetLastReleasedMovementKey(UP); + if(GetKey(RIGHT).bHeld){ + player.UpdateAnimation(WALK_E); + } else + if(GetKey(DOWN).bHeld){ + player.UpdateAnimation(WALK_S); + } else + if(GetKey(LEFT).bHeld){ + player.UpdateAnimation(WALK_W); + } + } + if(GetKey(RIGHT).bReleased){ + player.SetLastReleasedMovementKey(RIGHT); + if(GetKey(UP).bHeld){ + player.UpdateAnimation(WALK_N); + } else + if(GetKey(DOWN).bHeld){ + player.UpdateAnimation(WALK_S); + } else + if(GetKey(LEFT).bHeld){ + player.UpdateAnimation(WALK_W); + } + } + if(GetKey(LEFT).bReleased){ + player.SetLastReleasedMovementKey(LEFT); + if(GetKey(RIGHT).bHeld){ + player.UpdateAnimation(WALK_E); + } else + if(GetKey(DOWN).bHeld){ + player.UpdateAnimation(WALK_S); + } else + if(GetKey(UP).bHeld){ + player.UpdateAnimation(WALK_N); + } + } + if(GetKey(DOWN).bReleased){ + player.SetLastReleasedMovementKey(DOWN); + if(GetKey(RIGHT).bHeld){ + player.UpdateAnimation(WALK_E); + } else + if(GetKey(UP).bHeld){ + player.UpdateAnimation(WALK_N); + } else + if(GetKey(LEFT).bHeld){ + player.UpdateAnimation(WALK_W); + } + } + + if(setIdleAnimation){ + switch(player.GetLastReleasedMovementKey()){ + case UP:{ + player.UpdateAnimation(IDLE_N); + }break; + case DOWN:{ + player.UpdateAnimation(IDLE_S); + }break; + case LEFT:{ + player.UpdateAnimation(IDLE_W); + }break; + case RIGHT:{ + player.UpdateAnimation(IDLE_E); + }break; + default:{ + player.UpdateAnimation(IDLE_S); + } + } } } @@ -71,13 +237,13 @@ public: } void RenderWorld(){ - Clear(BLACK); + Clear({100,180,100}); for (int x = view.GetTopLeftTile().x/24-1; x <= view.GetBottomRightTile().x/24; x++){ for (int y = view.GetTopLeftTile().y/24-1; y <= view.GetBottomRightTile().y/24; y++){ view.DrawRect(vi2d{x,y}*24,{24,24},VERY_DARK_GREY); } } - view.DrawCircle(player.pos,8); + view.DrawPartialDecal(player.pos-vi2d{12,12},player.GetFrame().GetSourceImage()->Decal(),player.GetFrame().GetSourceRect().pos,player.GetFrame().GetSourceRect().size); } }; diff --git a/Crawler/olcUTIL_Animate2D.h b/Crawler/olcUTIL_Animate2D.h index 0fe2fc29..5fd8c01f 100644 --- a/Crawler/olcUTIL_Animate2D.h +++ b/Crawler/olcUTIL_Animate2D.h @@ -55,7 +55,7 @@ David Barr, aka javidx9, �OneLoneCoder 2019, 2020, 2021, 2022 #pragma once #include "olcPixelGameEngine.h" -#include "utilities/olcUTIL_Geometry2D.h" +#include "olcUTIL_Geometry2D.h" namespace olc::utils::Animate2D { diff --git a/Crawler/olcUTIL_Geometry2D.h b/Crawler/olcUTIL_Geometry2D.h new file mode 100644 index 00000000..1b7d1be9 --- /dev/null +++ b/Crawler/olcUTIL_Geometry2D.h @@ -0,0 +1,1046 @@ +/* +OneLoneCoder - Geometry 2D v1.01 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +A collection of 2D Geometric primitives and functions to work with +and between them. + + +License (OLC-3) +~~~~~~~~~~~~~~~ + +Copyright 2018 - 2022 OneLoneCoder.com + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions or derivations of source code must retain the above +copyright notice, this list of conditions and the following disclaimer. + +2. Redistributions or derivative works in binary form must reproduce +the above copyright notice. This list of conditions and the following +disclaimer must be reproduced in the documentation and/or other +materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its +contributors may be used to endorse or promote products derived +from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Links +~~~~~ +YouTube: https://www.youtube.com/javidx9 +Discord: https://discord.gg/WhwHUMV +Twitter: https://www.twitter.com/javidx9 +Twitch: https://www.twitch.tv/javidx9 +GitHub: https://www.github.com/onelonecoder +Homepage: https://www.onelonecoder.com + +Author +~~~~~~ +David Barr, aka javidx9, �OneLoneCoder 2019, 2020, 2021, 2022 + +Changes: +v1.01: +Made constants inline ++Header guards (lol... sigh...) + +*/ + +#pragma once +#include "olcPixelGameEngine.h" + +namespace olc::utils::geom2d +{ + // Lemon Meringue + inline const double pi = 3.141592653589793238462643383279502884; + + // Floating point error margin + inline const double epsilon = 0.001; + + //https://stackoverflow.com/questions/1903954/is-there-a-standard-sign-function-signum-sgn-in-c-c + template + constexpr int sgn(T val) { return (T(0) < val) - (val < T(0)); } + + // Defines a line segment + template + struct line + { + olc::v2d_generic start; + olc::v2d_generic end; + + inline line(const olc::v2d_generic& s = { T(0), T(0) }, + const olc::v2d_generic& e = { T(0), T(0) }) + : start(s), end(e) + { } + + + // Get length of line + inline constexpr T length() + { + return (end - start).mag(); + } + + // Get length of line^2 + inline constexpr T length2() + { + return (end - start).mag2(); + } + + inline constexpr olc::v2d_generic vector() const + { + return (end - start); + } + + // Given a real distance, get point along line + inline constexpr olc::v2d_generic rpoint(const T& distance) const + { + return start + (end - start).norm() * distance; + } + + // Given a unit distance, get point along line + inline constexpr olc::v2d_generic upoint(const T& distance) const + { + return start + (end - start) * distance; + } + + // Return which side of the line does a point lie + inline constexpr int32_t side(const olc::v2d_generic& point) const + { + double d = (end - start).cross(point - start); + if (d < 0) + return -1; + else + if (d > 0) + return 1; + else + return 0; + } + }; + + template + struct ray + { + olc::v2d_generic origin; + olc::v2d_generic direction; + }; + + template + struct rect + { + olc::v2d_generic pos; + olc::v2d_generic size; + + inline rect(const olc::v2d_generic& p = { T(0), T(0) }, + const olc::v2d_generic& s = { T(1), T(1) }) + : pos(p), size(s) + { } + + inline olc::v2d_generic middle() const + { + return pos + (size * double(0.5)); + } + + // Get line segment from top side of rectangle + inline line top() const + { + return { pos, {pos.x + size.x, pos.y } }; + } + + // Get line segment from bottom side of rectangle + inline line bottom() const + { + return { {pos.x, pos.y + size.y}, pos + size }; + } + + // Get line segment from left side of rectangle + inline line left() const + { + return { pos, {pos.x, pos.y + size.y} }; + } + + // Get line segment from right side of rectangle + inline line right() const + { + return { {pos.x + size.x, pos.y }, pos + size }; + } + + // Get a line from an indexed side, starting top, going clockwise + inline line side(const size_t i) const + { + if (i & 0b11 == 0) return top(); + if (i & 0b11 == 1) return right(); + if (i & 0b11 == 2) return bottom(); + if (i & 0b11 == 3) return left(); + } + + // Get area of rectangle + inline constexpr T area() const + { + return size.x * size.y; + } + + // Get perimeter of rectangle + inline constexpr T perimeter() const + { + return T(2) * (size.x + size.y); + } + }; + + + template + struct circle + { + olc::v2d_generic pos; + T radius = T(0); + + inline circle(const olc::v2d_generic& p = { T(0), T(0) }, const T r = T(0)) + : pos(p), radius(r) + { } + + // Get area of circle + inline constexpr T area() const + { + return T(pi) * radius * radius; + } + + // Get circumference of circle + inline constexpr T perimeter() const + { + return T(2.0 * pi) * radius; + } + + // Get circumference of circle + inline constexpr T circumference() const + { + return perimeter(); + } + }; + + + template + struct triangle + { + std::array, 3> pos; + + inline triangle( + const olc::v2d_generic& p0 = { T(0), T(0) }, + const olc::v2d_generic& p1 = { T(0), T(0) }, + const olc::v2d_generic& p2 = { T(0), T(0) }) + : pos{ p0,p1,p2 } + { } + + // Get a line from an indexed side, starting top, going clockwise + inline line side(const size_t i) const + { + return line(pos[i % 3], pos[(i + 1) % 3]); + } + + // Get area of triangle + inline constexpr T area() const + { + return double(0.5) * std::abs( + (pos[0].x * (pos[1].y - pos[2].y)) + + (pos[1].x * (pos[2].y - pos[0].y)) + + (pos[2].x * (pos[0].y - pos[1].y))); + } + + // Get perimeter of triangle + inline constexpr T perimeter() const + { + return line(pos[0], pos[1]).length() + + line(pos[1], pos[2]).length() + + line(pos[2], pos[0]).length(); + } + }; + + + template + struct polygon + { + std::vector> vPoints; + }; + + + // ========================================================================================================================= + // Closest(shape, point) =================================================================================================== + + // Returns closest point to point + template + inline olc::v2d_generic closest(const olc::v2d_generic& p1, const olc::v2d_generic& p2) + { + return p1; + } + + // Returns closest point on line to point + template + inline olc::v2d_generic closest(const line& l, const olc::v2d_generic& p) + { + auto d = l.vector(); + double u = std::clamp(double(d.dot(p - l.start)) / d.mag2(), 0.0, 1.0); + return l.start + u * d; + } + + // Returns closest point on circle to point + template + inline olc::v2d_generic closest(const circle& c, const olc::v2d_generic& p) + { + return c.pos + olc::vd2d(p - c.pos).norm() * c.radius; + } + + // Returns closest point on rectangle to point + template + inline olc::v2d_generic closest(const rect& r, const olc::v2d_generic& p) + { + // This could be a "constrain" function hmmmm + // TODO: Not quite what i wanted, should restrain to boundary + return olc::v2d_generic{ std::clamp(p.x, r.pos.x, r.pos.x + r.size.x), std::clamp(p.y, r.pos.y, r.pos.y + r.size.y) }; + + } + + // Returns closest point on triangle to point + template + inline olc::v2d_generic closest(const triangle& t, const olc::v2d_generic& p) + { + olc::utils::geom2d::line l{t.pos[0], t.pos[1]}; + auto p0 = closest(l, p); + auto d0 = (p0 - p).mag2(); + + l.end = t.pos[2]; + auto p1 = closest(l, p); + auto d1 = (p1 - p).mag2(); + + l.start = t.pos[1]; + auto p2 = closest(l, p); + auto d2 = (p2 - p).mag2(); + + if((d0 <= d1) && (d0 <= d2)) { + return p0; + } else if((d1 <= d0) && (d1 <= d2)) { + return p1; + } else { + return p2; + } + } + + + + + + + + + + + + // ================================================================================================================ + // POINT ========================================================================================================== + + // Checks if point contains point + template + inline constexpr bool contains(const olc::v2d_generic& p1, const olc::v2d_generic& p2) + { + return (p1 - p2).mag2() < epsilon; + } + + // Checks if line contains point + template + inline constexpr bool contains(const line& l, const olc::v2d_generic& p) + { + double d = ((p.x - l.start.x) * (l.end.y - l.start.y) - (p.y - l.start.y) * (l.end.x - l.start.x)); + if (std::abs(d) < epsilon) + { + // point is on line + double u = l.vector().dot(p - l.start) / l.vector().mag2(); + return (u >= double(0.0) && u <= double(1.0)); + } + + return false; + } + + // Checks if rectangle contains point + template + inline constexpr bool contains(const rect& r, const olc::v2d_generic& p) + { + return !(p.x < r.pos.x || p.y < r.pos.y || + p.x > (r.pos.x + r.size.x) || p.y > (r.pos.y + r.size.y)); + } + + // Checks if circle contains a point + template + inline constexpr bool contains(const circle& c, const olc::v2d_generic& p) + { + return (c.pos - p).mag2() < (c.radius * c.radius); + } + + // Checks if triangle contains a point + template + inline constexpr bool contains(const triangle& t, const olc::v2d_generic& p) + { + // http://jsfiddle.net/PerroAZUL/zdaY8/1/ + T2 A = T2(0.5) * (-t.pos[1].y * t.pos[2].x + t.pos[0].y * (-t.pos[1].x + t.pos[2].x) + t.pos[0].x * (t.pos[1].y - t.pos[2].y) + t.pos[1].x * t.pos[2].y); + T2 sign = A < T2(0) ? T2(-1) : T2(1); + T2 s = (t.pos[0].y * t.pos[2].x - t.pos[0].x * t.pos[2].y + (t.pos[2].y - t.pos[0].y) * p.x + (t.pos[0].x - t.pos[2].x) * p.y) * sign; + T2 v = (t.pos[0].x * t.pos[1].y - t.pos[0].y * t.pos[1].x + (t.pos[0].y - t.pos[1].y) * p.x + (t.pos[1].x - t.pos[0].x) * p.y) * sign; + return s > T2(0) && v > T2(0) && (s + v) < T2(2) * A * sign; + } + + + + + // Check if point overlaps with point (analagous to contains()) + template + inline constexpr bool overlaps(const olc::v2d_generic& p1, const olc::v2d_generic& p2) + { + return contains(p1, p2); + } + + // Checks if line segment overlaps with point + template + inline constexpr bool overlaps(const line& l, const olc::v2d_generic& p) + { + return contains(l, p); + } + + // Checks if rectangle overlaps with point + template + inline constexpr bool overlaps(const rect& r, const olc::v2d_generic& p) + { + return contains(r, p); + } + + // Checks if circle overlaps with point + template + inline constexpr bool overlaps(const circle& c, const olc::v2d_generic& p) + { + return contains(c, p); + } + + // Checks if triangle overlaps with point + template + inline constexpr bool overlaps(const triangle& t, const olc::v2d_generic& p) + { + return contains(t, p); + } + + + + + // Get intersection points where point intersects with point + template + inline std::vector> intersects(const olc::v2d_generic& p1, const olc::v2d_generic& p2) + { + if (contains(p1, p2)) + return { p1 }; + else + return {}; + } + + // Get intersection points where line segment intersects with point + template + inline std::vector> intersects(const line& l, const olc::v2d_generic& p) + { + if (contains(l, p)) + return { p }; + else + return {}; + } + + // Get intersection points where rectangle intersects with point + template + inline std::vector> intersects(const rect& r, const olc::v2d_generic& p) + { + std::vector> vPoints; + if (contains(r.top(), p)) vPoints.push_back(p); + if (contains(r.bottom(), p)) vPoints.push_back(p); + if (contains(r.left(), p)) vPoints.push_back(p); + if (contains(r.right(), p)) vPoints.push_back(p); + return vPoints; + } + + // Get intersection points where circle intersects with point + template + inline std::vector> intersects(const circle& c, const olc::v2d_generic& p) + { + if (std::abs((p - c.pos).mag2() - (c.radius * c.radius)) <= epsilon) + return { p }; + else + return {}; + } + + // Get intersection points where triangle intersects with point + template + inline std::vector> intersects(const triangle& r, const olc::v2d_generic& p) + { + // TODO: + return {}; + } + + + + + + + + + + + + + // ================================================================================================================ + // LINE =========================================================================================================== + + // Check if point contains line segment + template + inline constexpr bool contains(const olc::v2d_generic& p, const line& l) + { + return false; // It can't! + } + + // Check if line segment contains line segment + template + inline constexpr bool contains(const line& l1, const line& l2) + { + // TODO: Check if segments are colinear, and l1 exists within bounds of l2 + return false; + } + + // Check if rectangle contains line segment + template + inline constexpr bool contains(const rect& r, const line& l) + { + return contains(r, l.start) && contains(r, l.end); + } + + // Check if circle contains line segment + template + inline constexpr bool contains(const circle& c1, const line& l) + { + return contains(c1, l.start) && contains(c1, l.end); + } + + // Check if triangle contains line segment + template + inline constexpr bool contains(const triangle& t, const line& l) + { + return contains(t, l.start) && contains(t, l.end); + } + + + + + // Check if point overlaps line segment + template + inline constexpr bool overlaps(const olc::v2d_generic& p, const line& l) + { + return contains(l, p); + } + + // Check if line segment overlaps line segment + template + inline constexpr bool overlaps(const line& l1, const line& l2) + { + // TODO: + return false; + } + + // Check if rectangle overlaps line segment + template + inline constexpr bool overlaps(const rect& r, const line& l) + { + return contains(r, l.start) + || contains(r, l.end); + + // TODO: This method is no good, it cant detect lines whose start and end + // points are outside the rectangle + } + + // Check if circle overlaps line segment + template + inline constexpr bool overlaps(const circle& c, const line& l) + { + // TODO: + return false; + } + + // Check if triangle overlaps line segment + template + inline constexpr bool overlaps(const triangle& t, const line& l) + { + return overlaps(t, l.start) || overlaps(t, l.end); + + // TODO: This method is no good, it cant detect lines whose start and end + // points are outside the triangle + } + + + + + // Get intersection points where point intersects with line segment + template + inline std::vector> intersects(const olc::v2d_generic& p, const line& l) + { + // TODO: + return {}; + } + + // Get intersection points where line segment intersects with line segment + template + inline std::vector> intersects(const line& l1, const line& l2) + { + // TODO: + return {}; + } + + // Get intersection points where rectangle intersects with line segment + template + inline std::vector> intersects(const rect& r, const line& l) + { + // TODO: + return {}; + } + + // Get intersection points where circle intersects with line segment + template + inline std::vector> intersects(const circle& c, const line& l) + { + // TODO: + return {}; + } + + // Get intersection points where triangle intersects with line segment + template + inline std::vector> intersects(const triangle& t, const line& l) + { + // TODO: + return {}; + } + + + + + + + + + + + + + // ================================================================================================================ + // RECTANGLE ====================================================================================================== + + // Check if point contains rectangle + template + inline constexpr bool contains(const olc::v2d_generic& p, const rect& r) + { + return false; // It can't! + } + + // Check if line segment contains rectangle + template + inline constexpr bool contains(const line& l, const rect& r) + { + return false; // It can't + } + + // Check if rectangle contains rectangle + template + inline constexpr bool contains(const rect& r1, const rect& r2) + { + return (r2.pos.x >= r1.pos.x) && (r2.pos.x + r2.size.x < r1.pos.x + r1.size.x) && + (r2.pos.y >= r1.pos.y) && (r2.pos.y + r2.size.y < r1.pos.y + r1.size.y); + } + + // Check if circle contains rectangle + template + inline constexpr bool contains(const circle& c, const rect& r) + { + return contains(c, r.pos) + && contains(c, olc::v2d_generic{ r.pos.x + r.size.x, r.pos.y }) + && contains(c, olc::v2d_generic{ r.pos.x, r.pos.y + r.size.y }) + && contains(c, r.pos + r.size); + } + + // Check if triangle contains rectangle + template + inline constexpr bool contains(const triangle& t, const rect& r) + { + return contains(t, r.pos) + && contains(t, r.pos + r.size) + && contains(t, olc::v2d_generic{ r.pos.x + r.size.x,r.pos.y }) + && contains(t, olc::v2d_generic{ r.pos.x, r.pos.y + r.size.y }); + } + + + + + // Check if point overlaps rectangle + template + inline constexpr bool overlaps(const olc::v2d_generic& p, const rect& r) + { + return overlaps(r, p); + } + + // Check if line segment overlaps rectangle + template + inline constexpr bool overlaps(const line& l, const rect& r) + { + return overlaps(r, l); + } + + // Check if rectangle overlaps rectangle + template + inline constexpr bool overlaps(const rect& r1, const rect& r2) + { + return (r1.pos.x < r2.pos.x + r2.size.x && r1.pos.x + r1.size.x >= r2.pos.x && + r1.pos.y < r2.pos.y + r2.size.y && r1.pos.y + r1.size.y >= r2.pos.y); + } + + // Check if circle overlaps rectangle + template + inline constexpr bool overlaps(const circle& c, const rect& r) + { + // Inspired by this (very clever btw) + // https://stackoverflow.com/questions/45370692/circle-rectangle-collision-response + // But modified to work :P + T2 overlap = (olc::v2d_generic{ std::clamp(c.pos.x, r.pos.x, r.pos.x + r.size.x), std::clamp(c.pos.y, r.pos.y, r.pos.y + r.size.y) } - c.pos).mag2(); + if (std::isnan(overlap)) overlap = T2(0); + return (overlap - (c.radius * c.radius)) < T2(0); + } + + // Check if triangle overlaps rectangle + template + inline constexpr bool overlaps(const triangle& t, const rect& r) + { + return contains(t, r.pos) + || contains(t, r.pos + r.size) + || contains(t, olc::v2d_generic{ r.pos.x + r.size.x, r.pos.y }) + || contains(t, olc::v2d_generic{ r.pos.x, r.pos.y + r.size.y }); + + // TODO: This method is no good, consider rectangle with all vertices + // outside of triangle, but edges still crossing + } + + + + + // Get intersection points where point intersects with rectangle + template + inline std::vector> intersects(const olc::v2d_generic& p, const rect& r) + { + return intersects(r, p); + } + + // Get intersection points where line segment intersects with rectangle + template + inline std::vector> intersects(const line& l, const rect& r) + { + // TODO: + return {}; + } + + // Get intersection points where rectangle intersects with rectangle + template + inline std::vector> intersects(const rect& r1, const rect& r2) + { + // TODO: + return {}; + } + + // Get intersection points where circle intersects with rectangle + template + inline std::vector> intersects(const circle& c, const rect& r) + { + // TODO: + return {}; + } + + // Get intersection points where triangle intersects with rectangle + template + inline std::vector> intersects(const triangle& t, const rect& r) + { + // TODO: + return {}; + } + + + + + + + + + + + + + + // ================================================================================================================ + // CIRCLE ========================================================================================================= + + // Check if point contains circle + template + inline constexpr bool contains(const olc::v2d_generic& p, const circle& c) + { + return false; // It can't! + } + + // Check if line segment contains circle + template + inline constexpr bool contains(const line& l, const circle& c) + { + return false; // It can't! + } + + // Check if rectangle contains circle + template + inline constexpr bool contains(const rect& r, const circle& c) + { + // TODO: + return false; + } + + // Check if circle contains circle + template + inline constexpr bool contains(const circle& c1, const circle& c2) + { + return (c1.pos - c2.pos).mag2() <= (c1.radius - c2.radius) * (c1.radius - c2.radius); + } + + // Check if triangle contains circle + template + inline constexpr bool contains(const triangle& t, const circle& c) + { + // TODO: + return false; + } + + + + + // Check if point overlaps circle + template + inline constexpr bool overlaps(const olc::v2d_generic& p, const circle& c) + { + return overlaps(c, p); + } + + // Check if line segment overlaps circle + template + inline constexpr bool overlaps(const line& l, const circle& c) + { + return overlaps(c, l); + } + + // Check if rectangle overlaps circle + template + inline constexpr bool overlaps(const rect& r, const circle& c) + { + return overlaps(c, r); + } + + // Check if circle overlaps circle + template + inline constexpr bool overlaps(const circle& c1, const circle& c2) + { + return (c1.pos - c2.pos).mag2() <= (c1.radius + c2.radius) * (c1.radius + c2.radius); + } + + // Check if triangle overlaps circle + template + inline constexpr bool overlaps(const triangle& t, const circle& c) + { + // TODO: + return false; + } + + + + + // Get intersection points where point intersects with circle + template + inline std::vector> intersects(const olc::v2d_generic& p, const circle& c) + { + // TODO: + return {}; + } + + // Get intersection points where line segment intersects with circle + template + inline std::vector> intersects(const line& l, const circle& c) + { + // TODO: + return {}; + } + + // Get intersection points where rectangle intersects with circle + template + inline std::vector> intersects(const rect& r, const circle& c) + { + // TODO: + return {}; + } + + // Get intersection points where circle intersects with circle + template + inline std::vector> intersects(const circle& c1, const circle& c2) + { + // TODO: + return {}; + } + + // Get intersection points where triangle intersects with circle + template + inline std::vector> intersects(const triangle& t, const circle& c) + { + // TODO: + return {}; + } + + + + + + + + + + + + + + // ================================================================================================================ + // TRIANGLE ======================================================================================================= + + // Check if point contains triangle + template + inline constexpr bool contains(const olc::v2d_generic& p, const triangle& t) + { + return false; // It can't! + } + + // Check if line segment contains triangle + template + inline constexpr bool contains(const line& l, const triangle& t) + { + return false; // It can't + } + + // Check if rectangle contains triangle + template + inline constexpr bool contains(const rect& r, const triangle& t) + { + // TODO: + return false; + } + + // Check if circle contains triangle + template + inline constexpr bool contains(const circle& c, const triangle& t) + { + // TODO: + return false; + } + + // Check if triangle contains triangle + template + inline constexpr bool contains(const triangle& t1, const triangle& t2) + { + // TODO: + return false; + } + + + + + // Check if point overlaps triangle + template + inline constexpr bool overlaps(const olc::v2d_generic& p, const triangle& t) + { + return overlaps(t, p); + } + + // Check if line segment overlaps triangle + template + inline constexpr bool overlaps(const line& l, const triangle& t) + { + return overlaps(t, l); + } + + // Check if rectangle overlaps triangle + template + inline constexpr bool overlaps(const rect& r, const triangle& t) + { + return overlaps(t, r); + } + + // Check if circle overlaps triangle + template + inline constexpr bool overlaps(const circle& c, const triangle& t) + { + return overlaps(t, c); + } + + // Check if triangle overlaps triangle + template + inline constexpr bool overlaps(const triangle& t1, const triangle& t2) + { + // TODO: + return false; + } + + + + + // Get intersection points where point intersects with triangle + template + inline std::vector> intersects(const olc::v2d_generic& p, const triangle& t) + { + // TODO: + return {}; + } + + // Get intersection points where line segment intersects with triangle + template + inline std::vector> intersects(const line& l, const triangle& t) + { + // TODO: + return {}; + } + + // Get intersection points where rectangle intersects with triangle + template + inline std::vector> intersects(const rect& r, const triangle& t) + { + // TODO: + return {}; + } + + // Get intersection points where circle intersects with triangle + template + inline std::vector> intersects(const circle& c, const triangle& t) + { + // TODO: + return {}; + } + + // Get intersection points where triangle intersects with triangle + template + inline std::vector> intersects(const triangle& t1, const triangle& t2) + { + // TODO: + return {}; + } + +} \ No newline at end of file