Page 1 of 4

I guess I'll start

Posted: May 7th, 2019, 1:12 am
by albinopapa
FeatureTest branch

I've worked out the animations, though they can be improved upon.
The collision handling works like 99.999% of the time for me, I did have an instance where I was able to get stuck in a wall with no chance of closing the app outside of using the stop button in VS...will need to figure out how to bail out of the endless loop in the collision detection.
The maze is generated without a seed/random device so it's the same maze over and over.
No end goal yet, but am about try something and see how it goes.

With all the images, I wasn't able to upload a ZIP file, but I have included my dim2d headers in a rar file which you'll need to use. The github repo link is where you can get the project source code.

The project properties look for the dim2d headers in a folder one level up from where ever you place the main project in an Includes folder.

If you store on desktop, like:
C:\Users\(profile_name)\chili_framework\
it will look for the Includes in
C:\Users\(profile_name)\Includes\
You might be better off creating a folder and put the Includes folder and the chili_framework folders in there.

Re: I guess I'll start

Posted: May 7th, 2019, 5:28 am
by albinopapa
My idea for adding an ending tile for the maze worked. Now when you reach the end, you get a little message at the bottom of the screen.
Also added a room index counter at the bottom, not that it helped me any when trying to traverse the maze, but it's there.

Just need to figure out what to add next. I want to add monsters which will be interesting to see if they can traverse the maze. I also want to add items. One of the issues I haven't fully fleshed out is how to add items like chests or keys and have it still make sense. One thing I've thought of is checking for dead ends and have those rooms designated for something, but haven't decided on what, like that's where I could put the chest room or keys to unlock doors.

I have been thinking about some stuff to try, but it would break a lot of things and use a lot more memory. I want to make the rooms different sizes and be somewhat customizable. The issue with that is right now, I can calculate the position of tiles and rooms because everything is uniform, so I'm thinking that if I give each room it's own Rect, and just iterate through the room list I'll be able to pull it off. I may have to switch to hardware rendering before long if things start slowing down, but works fine in Release.

Changes are already uploaded to GitHub.

Re: I guess I'll start

Posted: May 8th, 2019, 1:15 am
by MrGodin
Every tried the Box2D format of multiple checks against collision on a single frame?.

Re: I guess I'll start

Posted: May 8th, 2019, 7:05 am
by albinopapa
I do, but I just do a while(isColliding) loop, which if you are stuck in a wall, you are always colliding so the loop never releases control. I only had this happen once and the only thing I can think of that caused it was the sprite being exactly between two wall tiles. There might have been other factors, because I haven't been able to replicate it. It might be the order I'm checking the wall tiles in relation to the direction I was traveling, but again haven't been able to reproduce it.

Re: I guess I'll start

Posted: May 8th, 2019, 11:05 pm
by albinopapa
Ok, my son found the issue within seconds of playing, lol little bastard keeps finding bugs in my stuff so quick. Anyway, the issue is when you are between two rooms, the algorithm only checks the room you are in, so if a tile pushes you up into the next room, then the next room will push you back down. So the fix is to not only check for current room's tiles, but the next rooms tiles if you're near the border to the next room.

Re: I guess I'll start

Posted: May 18th, 2019, 2:39 am
by MrGodin
some of my collision detection (2d)

Code: Select all

#pragma once




namespace Thor
{
	static constexpr int _pt0 = 0;
	static constexpr int _pt1 = 1;
	static constexpr int _pt2 = 2;
	class Line_2D;
	class AABB_2D;
	class Sphere_2D;
	class Triangle_2D;
	class Polygon_2D;
	template<typename T,int count>
	class  Shape
	{
	protected:
		T points[count];
	public:
		Shape() {};
		virtual ~Shape() {}
	};

	class  AABB_2D : public Shape<Math::vec2, 2>
	{
		static constexpr int _min = 0;
		static constexpr int _max = 1;
		Math::vec2 m_extents;
	public:
		AABB_2D() {}
		AABB_2D(const Math::vec2& pos, const Math::vec2& extents);
		~AABB_2D() {}
		Math::vec2 getMinPoint()const;
		Math::vec2 getMaxPoint()const;
		Math::vec2 getHalfExtents()const;
		Math::vec2 getExtents()const;
		Math::vec2& operator[](const int& index)
		{
			if (index < _min || index > _max)
				return points[0];

			return points[index];
		}
		Math::vec2 operator[](const int& index)const
		{
			if (index < _min || index > _max)
				return Math::vec2(FLT_MAX);

			return points[index];
		}
		void set(const Math::vec2& position, const Math::vec2& extents);

		inline Math::vec2 getCenter() { return points[_min] + getHalfExtents(); }
		inline float getMinX()const { return points[_min].x; };
		inline float getMinY()const { return points[_min].y; };
		inline float getMaxX()const { return points[_max].x; };
		inline float getMaxY()const { return points[_max].y; };
		AABB_2D transform(const Math::vec2& position);
		inline bool pointIn(const  Math::vec2& pt)
		{
			return (pt.x > points[_min].x && pt.x < points[_max].x && 
				pt.y > points[_min].y && pt.y < points[_max].y);
		}
		Line_2D getEdge(const unsigned int& index)const;
	};
	
	class  Sphere_2D : public Shape<Math::vec2, 1>
	{
		float m_radius;
	public:
		Sphere_2D() {}
		Sphere_2D(const Math::vec2& position, const float& radius);
		~Sphere_2D() {}
		inline Math::vec2 getCenter()const { return points[0]; }
		inline float getRadius()const { return m_radius; }
		inline float getRadiusSq()const { return m_radius * m_radius ; }
		inline void set(const Math::vec2& position, const float& radius)
		{
			points[0] = position;
			m_radius = radius;
		}
		inline void set(const Math::vec2& position)
		{
		   points[0] = position;
		}
		inline bool pointIn(const  Math::vec2& pt)
		{
			return (points[0] - pt).Magnitude() < m_radius;
		}
	};

	class  Line_2D : public Shape<Math::vec2, 2>
	{
		
	public:
		Line_2D() {}
		Line_2D(const Math::vec2& pt0, const Math::vec2& pt1);
		~Line_2D() {}

		inline  Math::vec2 getPt0()const { return points[_pt0]; }
		inline  Math::vec2 getPt1()const { return points[_pt1]; }
		inline void set(const Math::vec2& pt0, const Math::vec2& pt1)
		{
			points[_pt0] = pt0;
			points[_pt1] = pt1;
		};
		Math::vec2& operator[](const int& index)
		{
			if (index < _pt0 || index > _pt1)
				return points[_pt0];

			return points[index];
		}
		Math::vec2 operator[](const int& index)const
		{
			if (index < _pt0 || index > _pt1)
				return Math::vec2(FLT_MAX);

			return points[index];
		}
	};

	class  Triangle_2D : public Shape<Math::vec2, 3>
	{
		
	public:
		Triangle_2D() {}
		Triangle_2D(const Math::vec2& pt0, const Math::vec2& pt1, const Math::vec2& pt2);
		~Triangle_2D() {}

		inline  Math::vec2 getPt0()const { return points[_pt0]; }
		inline  Math::vec2 getPt1()const { return points[_pt1]; }
		inline  Math::vec2 getPt2()const { return points[_pt2]; }
		inline  Math::vec2 getCenter()const
		{
			Math::vec2 result = (points[_pt0] + points[_pt1] + points[_pt2]) / 3.0f;
			
			return result;
		}
		Math::vec2& operator[](const int& index)
		{
			if (index < _pt0 || index > _pt2)
				return points[0];
			return points[index];
		}
		Math::vec2 operator[](const int& index)const
		{
			if (index < _pt0 || index > _pt2)
				return Math::vec2(FLT_MAX);

			return points[index];
		}
		Line_2D getEdge(const unsigned int& index)const;
	};
	
	class  Polygon_2D 
	{
	protected:
		std::vector<Math::vec2> m_points;
	public:
		Polygon_2D() {}
		Polygon_2D(const std::vector<Math::vec2>& points)
			:m_points(points)
		{};
		~Polygon_2D() {}
		inline size_t getPointCount()const { return m_points.size(); }
		Line_2D getEdge(const unsigned int& index)const;
		Math::vec2& operator[](const int& index)
		{
			if (index < 0 || index >  m_points.size())
				return m_points[0];

			return m_points[index];
		}
		Math::vec2 operator[](const int& index)const
		{
			if (index < 0 || index >  m_points.size())
				return Math::vec2(FLT_MAX);

			return m_points[index];
		}

	};
	
}

Code: Select all

#include "pch.h"
#include "Shapes.h"
namespace Thor
{
	AABB_2D::AABB_2D(const Math::vec2 & pos, const Math::vec2 & extents)
	{
		points[_min] = pos;
		points[_max] = pos + extents;
		m_extents = extents;
	}
	Math::vec2 AABB_2D::getMinPoint() const
	{
		return points[_min];
	}
	Math::vec2 AABB_2D::getMaxPoint() const
	{
		return points[_max];
	}
	Math::vec2 AABB_2D::getHalfExtents() const
	{
		return m_extents * 0.5f;
	}
	Math::vec2 AABB_2D::getExtents() const
	{
		return m_extents;
	}
	void AABB_2D::set(const Math::vec2 & position, const Math::vec2 & extents)
	{
		points[_min] = position;
		points[_max] = position + extents;
		m_extents = extents;
	}
	AABB_2D AABB_2D::transform(const Math::vec2 & position)
	{
		return AABB_2D(position,m_extents);
	}
	Line_2D AABB_2D::getEdge(const unsigned int & index)const
	{
		switch (index)
		{
		case 0:
			return Line_2D(Math::vec2(getMinX(),getMinY()), Math::vec2(getMaxX(), getMinY()));
		case 1:
			return Line_2D(Math::vec2(getMaxX(), getMinY()), Math::vec2(getMaxX(), getMaxY()));
		case 2:
			return Line_2D(Math::vec2(getMaxX(), getMaxY()), Math::vec2(getMinX(), getMaxY()));
		case 3:
			return Line_2D(Math::vec2(getMinX(), getMaxY()), Math::vec2(getMinX(), getMinY()));
		};
		return Line_2D();
	}
	
	
	
	Sphere_2D::Sphere_2D(const Math::vec2 & position, const float & radius)
	{
		points[0] = position;
		m_radius = radius;
	}
	
	
	Line_2D::Line_2D(const Math::vec2 & pt0, const Math::vec2 & pt1)
	{
		points[_pt0] = pt0;
		points[_pt1] = pt1;
	}
	
	Triangle_2D::Triangle_2D(const Math::vec2 & pt0, const Math::vec2 & pt1, const Math::vec2 & pt2)
	{
		points[_pt0] = pt0;
		points[_pt1] = pt1;
		points[_pt2] = pt2;
	}
	
	Line_2D Triangle_2D::getEdge(const unsigned int & index)const
	{
		switch (index)
		{
		case 0:
			return Line_2D(points[_pt0], points[_pt1]);
		case 1:
			return Line_2D(points[_pt1], points[_pt2]);
		case 2:
			return Line_2D(points[_pt2], points[_pt0]);
		};

		return Line_2D();
	}
	Line_2D Polygon_2D::getEdge(const unsigned int & index) const
	{
		if (index >= 0)
		{
			if (index == m_points.size() - 1)
			{
				return Line_2D(m_points[index], m_points[0]);
			}

			return Line_2D(m_points[index], m_points[index + 1]);

		}
		return Line_2D();
	};
}

Code: Select all

#pragma once

#include "Shapes.h"

namespace Thor
{
	class  Physics
	{
	public:
		struct  Intersection
		{
			bool hit;
			float distance;
			Intersection() {}
			Intersection(const bool& hit, const float& dist)
				:hit(hit), distance(distance)
			{}
		};

		static Intersection line_Line2D(const Line_2D& lineA, const Line_2D& lineB);
		static Intersection line_Line2D(const Math::vec2& pt1, const Math::vec2& pt2, const Math::vec2& pt3, const Math::vec2& pt4);
		static Intersection line_AABB2D(const Line_2D& line, const AABB_2D& box);
		static Intersection line_Triangle2D(const Line_2D& line, const Triangle_2D& tri);
		static Intersection line_Polygon2D(const Line_2D& line, const Polygon_2D& poly);
		static Intersection line_Sphere(const Line_2D& line, const Sphere_2D& sphere);
		static Intersection AABB2D_AABB2D(const AABB_2D& box1, const AABB_2D& box2);
		static Intersection Sphere2D_Sphere2D(const Sphere_2D& sphere1, const Sphere_2D& sphere2);
	};
}

Code: Select all

#include "pch.h"

#include "Physics.h"

namespace Thor
{
	
		Physics::Intersection Physics::line_Line2D(const Line_2D & lineA, const Line_2D & lineB)
		{
			return line_Line2D(lineA.getPt0(), lineA.getPt1(), lineB.getPt0(), lineB.getPt1());
		}
		Physics::Intersection Physics::line_Line2D(const Math::vec2 & pt1, const Math::vec2 & pt2,
			const Math::vec2 & pt3, const Math::vec2 & pt4)
		{
			float s1_x = pt2.x - pt1.x;
			float s1_y = pt2.y - pt1.y;
			float s2_x = pt4.x - pt3.x;
			float s2_y = pt4.y - pt3.y;
			float s = (-s1_y * (pt1.x - pt3.x) + s1_x * (pt1.y - pt3.y)) / (-s2_x * s1_y + s1_x * s2_y);
			float t = (s2_x * (pt1.y - pt3.y) - s2_y * (pt1.x - pt3.x)) / (-s2_x * s1_y + s1_x * s2_y);

			return Intersection((s >= 0.0f && s <= 1.0f && t >= 0.0f && t <= 1.0f), 0.0f);


		}
		Physics::Intersection Physics::line_AABB2D(const Line_2D & line, const AABB_2D & box)
		{
			for (unsigned int i = 0; i < 4; i++)
			{
				Intersection inter = line_Line2D(line, box.getEdge(i));
				if (inter.hit)
					return inter;
			}
			return Intersection(false, 0.0f);
		}
		Physics::Intersection Physics::line_Triangle2D(const Line_2D & line, const Triangle_2D & tri)
		{
			for (unsigned int i = 0; i < 3; i++)
			{
				Intersection inter = line_Line2D(line, tri.getEdge(i));
				if (inter.hit)
					return inter;
			}
			return  Intersection(false, 0.0f);
		}
		Physics::Intersection Physics::line_Polygon2D(const Line_2D & line, const Polygon_2D& poly)
		{
			for (unsigned int i = 0; i < poly.getPointCount(); i++)
			{
				Intersection inter = line_Line2D(line, poly.getEdge(i));
				if (inter.hit)
					return inter;
			}
			return  Intersection(false, 0.0f);
		}
		Physics::Intersection Physics::line_Sphere(const Line_2D & line, const Sphere_2D & sphere)
		{

			Math::vec2 linePt1 = line.getPt0();
			Math::vec2 linePt2 = line.getPt1();
			Math::vec2 center = sphere.getCenter();


			Math::vec2 ac = Math::vec2(center.x - linePt1.x, center.y - linePt1.y);
			Math::vec2 ab = Math::vec2(linePt2.x - linePt1.x, linePt2.y - linePt1.y);
			float ab2 = ab.Dot(ab);
			float acab = ac.Dot(ab);
			float t = acab / ab2;
			t = (t < 0.0f) ? 0.0f : t;
			t = (t > 1.0f) ? 1.0f : t;
			Math::vec2 h = Math::vec2((ab.x * t + linePt1.x) - center.x, (ab.y * t + linePt1.y) - center.y);
			float h2 = h.Dot(h);
			return  Intersection(h2 <= sphere.getRadiusSq(), 0.0f);
			//return h2 <= sphere.getRadiusSq();

		}
		Physics::Intersection Physics::AABB2D_AABB2D(const AABB_2D & box1, const AABB_2D & box2)
		{
			return Intersection((box1.getMaxX() > box2.getMinX() &&
				box1.getMinX() < box2.getMaxX() &&
				box1.getMaxY() > box2.getMinY() &&
				box1.getMinY() < box2.getMaxY()), 0.0f);

		}
		Physics::Intersection Physics::Sphere2D_Sphere2D(const Sphere_2D & sphere1, const Sphere_2D & sphere2)
		{

			Math::vec2 result = sphere1.getCenter() - sphere2.getCenter();
			float lengthSq = result.x * result.x + result.y * result.y;
			float radiusSq = sphere1.getRadiusSq() + sphere2.getRadiusSq();
			return Intersection((lengthSq < radiusSq), 0.0f);
		}
	
}

Re: I guess I'll start

Posted: May 18th, 2019, 3:16 am
by MrGodin
It's missing collision correction in this code but it always gives a right result if a collision happened

Re: I guess I'll start

Posted: May 18th, 2019, 5:31 am
by albinopapa
This might be useful, thanks.

I have been messing around with Ray/Line collision, and came up with something that will fill in an area where the rays are pointing ( like a light source or line of sight ).

Image

Right now, it scans each pixel in the entire screen, so not very efficient. I'll be widdling it down to just scan the cone.

Re: I guess I'll start

Posted: May 18th, 2019, 6:21 pm
by albinopapa
I was able to use a triangle rasterization method to calculate the triangle of "light" which was a mixture of chili's scanline rasterization method and barycentric coordinates. I didn't want to look up and go through the videos and I was having troubles with blank pixels between triangles, so I just decided to use barycentric coordinates since the process is a lot easier to implement and remember.

Either way, this method is still useful for a flashlight or something similar, if I want a point light like a bulb or candle I'm still going to have to run through every pixel at least the diameter of the circle of light. Perhaps with a little more thinking and planning, I could manage to reduce the cost by only casting rays to each 32x32 tile and just give each tile a light value.

Kind of wondering what that's going to look like. Blocky lighting for tiles ( I'm thinking it'll look like a 2D minecraft, lol ). Anyway, I've had a nice diversion and learned something useful in the process.

Re: I guess I'll start

Posted: May 18th, 2019, 10:27 pm
by MrGodin
Thats a cool idea, hope it works out for you.