Add point inside object condition (#418)

* Add point inside object condition

* Update names and comments
This commit is contained in:
Lizard-13
2017-12-04 05:25:56 -03:00
committed by Florian Rival
parent 19b37b7111
commit 495900c083
11 changed files with 103 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 324 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 382 B

View File

@@ -621,6 +621,18 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(gd:
.AddParameter("objectList", _("Objects"))
.MarkAsSimple();
obj.AddCondition("CollisionPoint",
_("Point inside object"),
_("Test if a point is inside the object collision masks."),
_("_PARAM1_;_PARAM2_ is inside _PARAM0_"),
_("Collision"),
"res/conditions/collisionPoint24.png",
"res/conditions/collisionPoint.png")
.AddParameter("object", _("Object"))
.AddParameter("expression", _("X position of the point"))
.AddParameter("expression", _("Y position of the point"))
.MarkAsSimple();
obj.AddExpression("X", _("X position"), _("X position of the object"), _("Position"), "res/actions/position.png")
.AddParameter("object", _("Object"));

View File

@@ -69,6 +69,7 @@ BaseObjectExtension::BaseObjectExtension()
objectActions["Rebondir"].SetFunctionName("SeparateObjectsWithForces").SetIncludeFile("GDCpp/Extensions/Builtin/ObjectTools.h");
objectActions["Ecarter"].SetFunctionName("SeparateObjectsWithoutForces").SetIncludeFile("GDCpp/Extensions/Builtin/ObjectTools.h");
objectActions["SeparateFromObjects"].SetFunctionName("SeparateFromObjects").SetIncludeFile("GDCpp/Extensions/Builtin/ObjectTools.h");
objectConditions["CollisionPoint"].SetFunctionName("IsCollidingWithPoint");
objectExpressions["X"].SetFunctionName("GetX");

View File

@@ -128,3 +128,19 @@ CollisionResult GD_API PolygonCollisionTest(Polygon2d & p1, Polygon2d & p2)
return result;
}
bool GD_API IsPointInsidePolygon(Polygon2d & poly, float x, float y)
{
bool inside = false;
sf::Vector2f vi, vj;
for (std::size_t i = 0, j = poly.vertices.size()-1; i < poly.vertices.size(); j = i++)
{
vi = poly.vertices[i];
vj = poly.vertices[j];
if ( ((vi.y>y) != (vj.y>y)) && (x < (vj.x-vi.x) * (y-vi.y) / (vj.y-vi.y) + vi.x) )
inside = !inside;
}
return inside;
}

View File

@@ -33,5 +33,16 @@ struct CollisionResult
*/
CollisionResult GD_API PolygonCollisionTest(Polygon2d & p1, Polygon2d & p2);
/**
* Check if a point is inside a polygon.
*
* Uses PNPOLY by W. Randolph Franklin (https://wrf.ecse.rpi.edu//Research/Short_Notes/pnpoly.html)
*
* \return true if the point is inside the polygon
*
* \ingroup GameEngine
*/
bool GD_API IsPointInsidePolygon(Polygon2d & poly, float x, float y);
#endif // POLYGONCOLLISION_H

View File

@@ -379,6 +379,17 @@ bool RuntimeObject::IsCollidingWith(RuntimeObject * obj2)
return false;
}
bool RuntimeObject::IsCollidingWithPoint(float pointX, float pointY){
vector<Polygon2d> hitBoxes = GetHitBoxes();
for (std::size_t i = 0; i < hitBoxes.size(); ++i)
{
if ( IsPointInsidePolygon(hitBoxes[i], pointX, pointY) )
return true;
}
return false;
}
void RuntimeObject::SeparateObjectsWithoutForces( std::map <gd::String, std::vector<RuntimeObject*> *> pickedObjectLists)
{
vector<RuntimeObject*> objects2;

View File

@@ -223,6 +223,14 @@ public:
*/
bool IsCollidingWith(RuntimeObject * other);
/**
* \brief Check if a point is inside the object collision hitboxes.
* \param pointX The point x coordinate.
* \param pointY The point y coordinate.
* \return true if the point is inside the object collision hitboxes.
*/
bool IsCollidingWithPoint(float pointX, float pointY);
/**
* \brief Check collision with each object of the list using their hitboxes, and move the object
* according to the sum of the move vector returned by each collision test.

View File

@@ -71,6 +71,7 @@ BaseObjectExtension::BaseObjectExtension()
objectConditions["ObjectVariableChildExists"].SetFunctionName("variableChildExists").SetIncludeFile("runtimeobject.js");
objectActions["ObjectVariableRemoveChild"].SetFunctionName("variableRemoveChild").SetIncludeFile("runtimeobject.js");
objectActions["ObjectVariableClearChildren"].SetFunctionName("variableClearChildren").SetIncludeFile("runtimeobject.js");
objectConditions["CollisionPoint"].SetFunctionName("isCollidingWithPoint").SetIncludeFile("runtimeobject.js");
objectExpressions["X"].SetFunctionName("getX");
objectExpressions["Y"].SetFunctionName("getY");

View File

@@ -258,3 +258,29 @@ gdjs.Polygon.distance = function(minA, maxA, minB, maxB)
if (minA < minB) return minB - maxA;
else return minA - maxB;
}
/**
* Check if a point is inside a polygon.
*
* Uses <a href="https://wrf.ecse.rpi.edu//Research/Short_Notes/pnpoly.html">PNPOLY</a> by W. Randolph Franklin.
*
* @method isPointInside
* @static
* @param poly {Polygon} The polygon to test
* @param x {Number} The point x coordinate
* @param y {Number} The point y coordinate
* @return {Boolean} true if the point is inside the polygon
*/
gdjs.Polygon.isPointInside = function(poly, x, y)
{
var inside = false;
var vi, vj;
for (var i = 0, j = poly.vertices.length-1; i < poly.vertices.length; j = i++) {
vi = poly.vertices[i];
vj = poly.vertices[j];
if ( ((vi[1]>y) != (vj[1]>y)) && (x < (vj[0]-vi[0]) * (y-vi[1]) / (vj[1]-vi[1]) + vi[0]) )
inside = !inside;
}
return inside;
};

View File

@@ -1202,6 +1202,23 @@ gdjs.RuntimeObject.prototype.cursorOnObject = function(runtimeScene) {
return false;
};
/**
* \brief Check if a point is inside the object collision hitboxes.
* @method isCollidingWithPoint
* @param pointX The point x coordinate.
* @param pointY The point y coordinate.
* @return true if the point is inside the object collision hitboxes.
*/
gdjs.RuntimeObject.prototype.isCollidingWithPoint = function(pointX, pointY) {
var hitBoxes = this.getHitBoxes();
for(var i = 0; i < this.hitBoxes.length; ++i) {
if ( gdjs.Polygon.isPointInside(hitBoxes[i], pointX, pointY) )
return true;
}
return false;
}
/**
* Get the identifier associated to an object name :<br>