Compare commits

...

22 Commits

Author SHA1 Message Date
Florian Rival
44e10cc9cb Add ObjectPositionsContainer, to choose between RTree or list 2020-01-25 19:50:05 +00:00
Florian Rival
3376520112 Fix GDCpp compilation 2020-01-22 08:07:17 +00:00
Florian Rival
f92917113a Fix Rbush usage in ObjectsPositionsManager 2020-01-21 22:43:44 +00:00
Florian Rival
a990cc1866 Update PlatformRuntimeBehavior to track AABB instead of position+size 2020-01-21 21:26:00 +00:00
Florian Rival
4aa47a7e94 Fix some RuntimeObject missing calls to base class setAngle 2020-01-21 08:25:18 +00:00
Florian Rival
9c99a77fa2 Add counter/timings to gdjs.Profiler, use them in gdjs.ObjectPositionsManager 2020-01-20 23:04:49 +00:00
Florian Rival
2b40949d55 Fix typing 2020-01-20 22:18:20 +00:00
Florian Rival
cc7e956ee1 Use gdjs.ObjectsPositionManager for "CollisionPoint" condition 2020-01-18 15:59:33 +00:00
Florian Rival
7cc21b2237 Add type for ObjectIdsSet, fix bug in gdjs.ObjectsPositionManager and improve perf
* Use a slightly more complex object for ObjectIdsSet to be able to quickly clear the set
* Fix bug where some objects were considered for pointsTest while not in the set of object ids to test.
2020-01-18 15:59:33 +00:00
Florian Rival
4618dbfc8c Make gdjs.ObjectsPositionManager handle raycast tests 2020-01-18 15:59:33 +00:00
Florian Rival
4400c0b23a Move new benchmarks to GDJS/tests/games/object-positions-manager-benchmarks/ 2020-01-18 15:59:33 +00:00
Florian Rival
702a31864c Ensure gdjs.ObjectPositionsManager.update is called once a frame
Remove "GDJS/tests/games/Collisions with creation and deletion benchmark.gdg.json" as now already existing in GDJS/test/games/memory-benchmarks
2020-01-18 15:59:33 +00:00
Florian Rival
9cc03c380f Batch insertion in RBush of updated object positions 2020-01-18 15:59:33 +00:00
Florian Rival
e9d1c6d408 Add test benchmark game for collisions with lots of objects created/deleted 2020-01-18 15:59:33 +00:00
Florian Rival
b206ddb62b Fix gdjs.ObjectPositionsManager crash if using an ID of a removed/inexisting object position
This can happen if a gdjs.RuntimeObject is deleted from the scene: it's marked for deletion,
but still used by the current events, which can pass its id to the gdjs.ObjectPositionsManager
(which won't have an associated ObjectPosition for its id, as it would have been marked for deletion
and really deleted at the next call to "update", which happen at any query like collision handling).
2020-01-18 15:59:33 +00:00
Florian Rival
37df801a93 Add test for gdjs.ObjectPositionsManager.separateObjects 2020-01-18 15:59:32 +00:00
Florian Rival
c9fd56f875 Make gdjs.ObjectsPositionManager handle "cursor on object" test (points test) 2020-01-18 15:59:32 +00:00
Florian Rival
aa2e26ae7b Make gdjs.ObjectsPositionManager handle distance tests 2020-01-18 15:59:32 +00:00
Florian Rival
23d8682da9 Make gdjs.ObjectsPositionManager handle collisions and object separation 2020-01-18 15:59:32 +00:00
Florian Rival
fe7897bbc3 [WIP] Make gdjs.ObjectsPositionManager use a different RBush for each object name 2020-01-18 15:59:32 +00:00
Florian Rival
d409b66f22 [WIP] Add gdjs.PositionsManager storing coordinates/aabb/hitboxes
- Use it for collision tests
2020-01-18 15:59:32 +00:00
Florian Rival
4227451a6a Fix some RuntimeObject missing calls to base class setX/Y 2020-01-18 15:54:00 +00:00
35 changed files with 6352 additions and 226 deletions

View File

@@ -602,17 +602,19 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("object", _("Object"))
.AddParameter("objectList", _("Object 2 (won't move)"));
obj.AddAction("SeparateFromObjects",
_("Separate two objects"),
_("Move an object away from another using their collision "
"masks.\nBe sure to call this action on a reasonable number "
"of objects\nto avoid slowing down the game."),
_("Move _PARAM0_ away from _PARAM1_ (only _PARAM0_ will move)"),
_("Position"),
"res/actions/ecarter24.png",
"res/actions/ecarter.png")
extension
.AddAction(
"SeparateFromObjects",
_("Separate two objects"),
_("Move an object away from another using their collision "
"masks.\nBe sure to call this action on a reasonable number "
"of objects\nto avoid slowing down the game."),
_("Move _PARAM0_ away from _PARAM1_ (only _PARAM0_ will move)"),
_("Position"),
"res/actions/ecarter24.png",
"res/actions/ecarter.png")
.AddParameter("object", _("Object"))
.AddParameter("objectList", _("Object"))
.AddParameter("objectList", _("Objects (won't move)"))
.AddParameter("yesorno",
_("Ignore objects that are touching each other on their "
@@ -620,18 +622,22 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"",
true)
.SetDefaultValue("no")
.AddCodeOnlyParameter("currentScene", "")
.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"))
extension
.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("objectList", _("Object"))
.AddParameter("expression", _("X position of the point"))
.AddParameter("expression", _("Y position of the point"))
.AddCodeOnlyParameter("conditionInverted", "")
.AddCodeOnlyParameter("currentScene", "")
.MarkAsSimple();
obj.AddCondition(
@@ -963,6 +969,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("objectList", _("Object 2"))
.AddParameter("expression", _("Distance"))
.AddCodeOnlyParameter("conditionInverted", "")
.AddCodeOnlyParameter("currentScene", "")
.MarkAsSimple();
extension
@@ -1072,8 +1079,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddCondition("Raycast",
_("Raycast"),
_("Sends a ray from the given source position and angle, "
"intersecting the closest object.\nThe instersected "
"object will become the only one taken into account.\nIf "
"intersecting the closest object.\nThe intersected "
"object will become the only one picked for next "
"conditions and actions.\nIf "
"the condition is inverted, the object to be intersected "
"will be the farthest one within the ray radius."),
_("Raycast _PARAM0_ from _PARAM1_;_PARAM2_, and save the "
@@ -1095,6 +1103,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Scene variable where to store the Y position of the intersection. "
"If no intersection is found, the variable won't be changed."))
.AddCodeOnlyParameter("conditionInverted", "")
.AddCodeOnlyParameter("currentScene", "")
.MarkAsAdvanced();
extension
@@ -1102,8 +1111,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"RaycastToPosition",
_("Raycast to position"),
_("Sends a ray from the given source position to the final point, "
"intersecting the closest object.\nThe instersected "
"object will become the only one taken into account.\nIf "
"intersecting the closest object.\nThe intersected "
"object will become the only one picked for next conditions and "
"actions.\nIf "
"the condition is inverted, the object to be intersected "
"will be the farthest one within the ray radius."),
_("Raycast _PARAM0_ from _PARAM1_;_PARAM2_, and save the "
@@ -1125,6 +1135,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Scene variable where to store the Y position of the intersection. "
"If no intersection is found, the variable won't be changed."))
.AddCodeOnlyParameter("conditionInverted", "")
.AddCodeOnlyParameter("currentScene", "")
.MarkAsAdvanced();
extension

View File

@@ -14,7 +14,8 @@ Copyright (c) 2013-2016 Florian Rival (Florian.Rival@gmail.com)
*/
gdjs.PlatformObjectsManager = function(runtimeScene, sharedData)
{
this._platformRBush = new rbush(9, ['.owner.getAABB().min[0]', '.owner.getAABB().min[1]', '.owner.getAABB().max[0]', '.owner.getAABB().max[1]']);
// TODO: update RBush to avoid using eval-like Function.
this._platformRBush = new rbush(9, ['.aabb.min[0]', '.aabb.min[1]', '.aabb.max[0]', '.aabb.max[1]']);
};
/**
@@ -89,11 +90,14 @@ gdjs.PlatformRuntimeBehavior = function(runtimeScene, behaviorData, owner)
this._canBeGrabbed = behaviorData.canBeGrabbed || false;
this._yGrabOffset = behaviorData.yGrabOffset || 0;
//Note that we can't use getX(), getWidth()... of owner here: The owner is not fully constructed.
this._oldX = 0;
this._oldY = 0;
this._oldWidth = 0;
this._oldHeight = 0;
//Note that we can't use getAABB() of the owner here: The owner is not fully constructed.
this._oldAABBMinX = 0;
this._oldAABBMinX = 0;
this._oldAABBMaxX = 0;
this._oldAABBMaxY = 0;
/** @type {AABB} */
this.aabb = { min: [0,0], max: [0,0] };
this._manager = gdjs.PlatformObjectsManager.getManager(runtimeScene);
this._registeredInManager = false;
@@ -111,17 +115,27 @@ gdjs.PlatformRuntimeBehavior.prototype.onDestroy = function() {
};
gdjs.PlatformRuntimeBehavior.prototype.doStepPreEvents = function(runtimeScene) {
// Track changes in AABB
// TODO: Skip this if the behavior is deactivated.
/** @type {AABB} */
var aabb = this.owner.getAABB();
//Scene change is not supported
/*if ( parentScene != &scene ) //Parent scene has changed
if (this._oldAABBMinX !== aabb.min[0] || this._oldAABBMinY !== aabb.min[1] ||
this._oldAABBMaxX !== aabb.max[0] || this._oldAABBMaxY !== aabb.max[1])
{
if ( sceneManager ) //Remove the object from any old scene manager.
sceneManager->RemovePlatform(this);
// Store the AABB of the platform directly in the behavior, for usage by rbush
this.aabb = aabb;
parentScene = &scene;
sceneManager = parentScene ? &ScenePlatformObjectsManager::managers[&scene] : NULL;
registeredInManager = false;
}*/
if ( this._registeredInManager ) {
this._manager.removePlatform(this);
this._manager.addPlatform(this);
}
this._oldAABBMinX = aabb.min[0];
this._oldAABBMinY = aabb.min[1];
this._oldAABBMaxX = aabb.max[0];
this._oldAABBMaxY = aabb.max[1];
}
//Make sure the platform is or is not in the platforms manager.
if (!this.activated() && this._registeredInManager)
@@ -134,21 +148,6 @@ gdjs.PlatformRuntimeBehavior.prototype.doStepPreEvents = function(runtimeScene)
this._manager.addPlatform(this);
this._registeredInManager = true;
}
//Track changes in size or position
if (this._oldX !== this.owner.getX() || this._oldY !== this.owner.getY() ||
this._oldWidth !== this.owner.getWidth() || this._oldHeight !== this.owner.getHeight())
{
if ( this._registeredInManager ) {
this._manager.removePlatform(this);
this._manager.addPlatform(this);
}
this._oldX = this.owner.getX();
this._oldY = this.owner.getY();
this._oldWidth = this.owner.getWidth();
this._oldHeight = this.owner.getHeight();
}
};
gdjs.PlatformRuntimeBehavior.prototype.doStepPostEvents = function(runtimeScene) {

View File

@@ -56,18 +56,19 @@ gdjs.SkeletonRuntimeObject.prototype.getSkeletonData = function(runtimeScene, ob
// RuntimeObject overwrites
gdjs.SkeletonRuntimeObject.prototype.setX = function(x){
this.x = x;
gdjs.RuntimeObject.prototype.setX.call(this, x);
this.rootArmature.setX(x);
};
gdjs.SkeletonRuntimeObject.prototype.setY = function(y){
this.y = y;
gdjs.RuntimeObject.prototype.setY.call(this, y);
this.rootArmature.setY(y);
};
gdjs.SkeletonRuntimeObject.prototype.setAngle = function(angle){
this.angle = angle;
this.rootArmature.setRot(angle);
gdjs.RuntimeObject.prototype.setAngle.call(this, angle);
};
gdjs.SkeletonRuntimeObject.prototype.getRendererObject = function(){

View File

@@ -109,10 +109,6 @@ BaseObjectExtension::BaseObjectExtension() {
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");
objectExpressions["Y"].SetFunctionName("GetY");
@@ -174,6 +170,9 @@ BaseObjectExtension::BaseObjectExtension() {
.SetFunctionName("PickedObjectsCount")
.SetManipulatedType("number")
.SetIncludeFile("GDCpp/Extensions/Builtin/ObjectTools.h");
GetAllConditions()["SeparateFromObjects"]
.SetFunctionName("SeparateObjects")
.SetIncludeFile("GDCpp/Extensions/Builtin/ObjectTools.h");
GetAllConditions()["CollisionNP"]
.SetFunctionName("HitBoxesCollision")
.SetIncludeFile("GDCpp/Extensions/Builtin/ObjectTools.h");
@@ -186,6 +185,7 @@ BaseObjectExtension::BaseObjectExtension() {
GetAllConditions()["RaycastToPosition"]
.SetFunctionName("RaycastObjectToPosition")
.SetIncludeFile("GDCpp/Extensions/Builtin/RuntimeSceneTools.h");
GetAllConditions()["CollisionPoint"].SetFunctionName("IsCollidingWithPoint");
GetAllExpressions()["Count"]
.SetFunctionName("PickedObjectsCount")

View File

@@ -43,6 +43,35 @@ bool GD_API HitBoxesCollision(
});
}
void GD_API SeparateObjects(
std::map<gd::String, std::vector<RuntimeObject *> *> objectsLists1,
std::map<gd::String, std::vector<RuntimeObject *> *> objectsLists2,
bool ignoreTouchingEdges,
RuntimeScene & /*scene*/) {
for (auto it : objectsLists1) {
if (!it.second) continue;
const std::vector<RuntimeObject *> &list = *it.second;
for (auto runtimeObject : list) {
runtimeObject->SeparateFromObjects(objectsLists2, ignoreTouchingEdges);
}
}
}
bool GD_API IsCollidingWithPoint(
std::map<gd::String, std::vector<RuntimeObject *> *> objectsLists,
double pointX,
double pointY,
bool conditionInverted,
RuntimeScene &scene) {
return PickObjectsIf(objectsLists,
conditionInverted,
[pointX, pointY](RuntimeObject *runtimeObject) {
return runtimeObject->IsCollidingWithPoint(pointX,
pointY);
});
}
bool GD_API ObjectsTurnedToward(
std::map<gd::String, std::vector<RuntimeObject *> *> objectsLists1,
std::map<gd::String, std::vector<RuntimeObject *> *> objectsLists2,
@@ -69,7 +98,8 @@ float GD_API DistanceBetweenObjects(
std::map<gd::String, std::vector<RuntimeObject *> *> objectsLists1,
std::map<gd::String, std::vector<RuntimeObject *> *> objectsLists2,
float length,
bool conditionInverted) {
bool conditionInverted,
RuntimeScene & /*scene*/) {
length *= length;
return TwoObjectListsTest(
objectsLists1,

View File

@@ -25,6 +25,9 @@ bool GD_API ObjectsTurnedToward(
/**
* Only used internally by GD events generated code.
*
* Complexity is O(n*m) and could be improved by using a spatial data structure
* to store object positions (see GDJS).
*/
bool GD_API HitBoxesCollision(
std::map<gd::String, std::vector<RuntimeObject *> *> objectsLists1,
@@ -33,6 +36,31 @@ bool GD_API HitBoxesCollision(
RuntimeScene &scene,
bool ignoreTouchingEdges = false);
/**
* Only used internally by GD events generated code.
*
* Complexity is O(n*m) and could be improved by using a spatial data structure
* to store object positions (see GDJS).
*/
void GD_API SeparateObjects(
std::map<gd::String, std::vector<RuntimeObject *> *> objectsLists1,
std::map<gd::String, std::vector<RuntimeObject *> *> objectsLists2,
bool ignoreTouchingEdges,
RuntimeScene &scene);
/**
* Only used internally by GD events generated code.
*
* Complexity could be improved by using a spatial data structure
* to store object positions (see GDJS).
*/
bool GD_API IsCollidingWithPoint(
std::map<gd::String, std::vector<RuntimeObject *> *> objectsLists,
double x,
double y,
bool conditionInverted,
RuntimeScene &scene);
/**
* Only used internally by GD events generated code.
*/
@@ -41,12 +69,16 @@ double GD_API PickedObjectsCount(
/**
* Only used internally by GD events generated code.
*
* Complexity is O(n*m) and could be improved by using a spatial data structure
* to store object positions (see GDJS).
*/
float GD_API DistanceBetweenObjects(
std::map<gd::String, std::vector<RuntimeObject *> *> objectsLists1,
std::map<gd::String, std::vector<RuntimeObject *> *> objectsLists2,
float length,
bool conditionInverted);
bool conditionInverted,
RuntimeScene &scene);
/**
* Only used internally by GD events generated code.

View File

@@ -114,9 +114,6 @@ BaseObjectExtension::BaseObjectExtension() {
objectConditions["AngleOfDisplacement"]
.SetFunctionName("averageForceAngleIs")
.SetIncludeFile("runtimeobject.js");
objectActions["SeparateFromObjects"]
.SetFunctionName("separateFromObjectsList")
.SetIncludeFile("runtimeobject.js");
objectActions["Ecarter"]
.codeExtraInformation // Deprecated
.SetFunctionName("separateObjectsWithoutForces")
@@ -140,9 +137,6 @@ BaseObjectExtension::BaseObjectExtension() {
objectActions["ObjectVariableClearChildren"]
.SetFunctionName("variableClearChildren")
.SetIncludeFile("runtimeobject.js");
objectConditions["CollisionPoint"]
.SetFunctionName("isCollidingWithPoint")
.SetIncludeFile("runtimeobject.js");
objectConditions["ObjectTimer"]
.SetFunctionName("timerElapsedTime")
.SetIncludeFile("runtimeobject.js");
@@ -202,8 +196,10 @@ BaseObjectExtension::BaseObjectExtension() {
"gdjs.evtTools.object.pickedObjectsCount");
GetAllConditions()["NbObjet"].SetFunctionName(
"gdjs.evtTools.object.pickedObjectsCount");
GetAllConditions()["CollisionNP"]
.SetFunctionName("gdjs.evtTools.object.hitBoxesCollisionTest");
GetAllActions()["SeparateFromObjects"].SetFunctionName(
"gdjs.evtTools.object.separateObjects");
GetAllConditions()["CollisionNP"].SetFunctionName(
"gdjs.evtTools.object.hitBoxesCollisionTest");
GetAllConditions()["Raycast"].SetFunctionName(
"gdjs.evtTools.object.raycastObject");
GetAllConditions()["RaycastToPosition"].SetFunctionName(
@@ -214,6 +210,8 @@ BaseObjectExtension::BaseObjectExtension() {
"gdjs.evtTools.object.movesTowardTest");
GetAllConditions()["EstTourne"].SetFunctionName(
"gdjs.evtTools.object.turnedTowardTest");
GetAllConditions()["CollisionPoint"].SetFunctionName(
"gdjs.evtTools.object.isCollidingWithPoint");
GetAllActions()["AjoutObjConcern"].SetFunctionName(
"gdjs.evtTools.object.pickAllObjects");

View File

@@ -528,6 +528,7 @@ void ExporterHelper::AddLibsInclude(bool pixiRenderers,
InsertUnique(includesFiles, "gd-splash-image.js");
InsertUnique(includesFiles, "libs/hshg.js");
InsertUnique(includesFiles, "libs/rbush.js");
InsertUnique(includesFiles, "objectpositionsmanager.js");
InsertUnique(includesFiles, "inputmanager.js");
InsertUnique(includesFiles, "jsonmanager.js");
InsertUnique(includesFiles, "timemanager.js");

View File

@@ -1,3 +1,5 @@
// @ts-check
/*
* GDevelop JS Platform
* Copyright 2013-2016 Florian Rival (Florian.Rival@gmail.com). All rights reserved.
@@ -95,7 +97,7 @@ gdjs.evtTools.input.keysNameToCode = {
"x": 88,
"y": 89,
"z": 90,
"Num0": 48,
"Num1": 49,
"Num2": 50,
@@ -226,11 +228,85 @@ gdjs.evtTools.input.getMouseY = function(runtimeScene, layer, camera) {
runtimeScene.getGame().getInputManager().getMouseY())[1];
};
/**
* @param {Hashtable} objectsLists The objects to consider for the test
* @returns {Object.<string, ObjectIdsSet>} Sets of object ids keyed by the name of the layer the objects are on.
*/
gdjs.evtTools.input._objectsListsToObjectIdsSetGroupedPerLayer = function(objectsLists) {
/** @type Object.<string, ObjectIdsSet> */
var layerObjectIdsSets = {};
for (var key in objectsLists.items) {
/** @type gdjs.RuntimeObject[] */
var list = objectsLists.items[key];
for (var i = 0; i < list.length; ++i) {
var object = list[i];
var layerName = object.getLayer();
layerObjectIdsSets[layerName] = layerObjectIdsSets[layerName] || gdjs.ObjectPositionsManager.makeNewObjectIdsSet();
layerObjectIdsSets[layerName].items[object.id] = true;
}
}
return layerObjectIdsSets;
}
/**
* @param {Hashtable} objectsLists The objects to consider for the test
* @param {gdjs.RuntimeScene} runtimeScene
* @param {boolean} accurate
* @param {boolean} inverted
* @returns {boolean}
*/
gdjs.evtTools.input.cursorOnObject = function(objectsLists, runtimeScene, accurate, inverted) {
var isTrue = false;
var inputManager = runtimeScene.getGame().getInputManager();
// Find the mouse and touch positions on each layer
/** @type Object.<string, number[][]> */
var layersCursorPositions = {};
/** @type string[] */
var allLayerNames = [];
runtimeScene.getAllLayerNames(allLayerNames);
for(var i = 0;i<allLayerNames.length;i++) {
var layerName = allLayerNames[i];
var layer = runtimeScene.getLayer(layerName);
/** @type number[][] */
var cursorPositions = [];
cursorPositions.push(layer.convertCoords(inputManager.getMouseX(), inputManager.getMouseY(), 0));
var touchIds = inputManager.getAllTouchIdentifiers();
for(var j = 0;j<touchIds.length;++j) {
cursorPositions.push(layer.convertCoords(inputManager.getTouchX(touchIds[j]),
inputManager.getTouchY(touchIds[j]), 0));
}
layersCursorPositions[layerName] = cursorPositions;
}
// Group object ids per layer and check which objects are colliding with any of the cursor positions.
var layerObjectIdsSets = gdjs.evtTools.input._objectsListsToObjectIdsSetGroupedPerLayer(objectsLists);
for(var layerName in layerObjectIdsSets) {
var objectIdsSet = layerObjectIdsSets[layerName];
var cursorPositions = layersCursorPositions[layerName];
isTrue = runtimeScene.getObjectPositionsManager().pointsTest(objectIdsSet, cursorPositions, accurate, inverted) || isTrue;
}
// Trim the object lists to keep only objects satisfying the tests
gdjs.ObjectPositionsManager.keepOnlyObjectsFromGroupedObjectIdsSets(objectsLists, layerObjectIdsSets);
return isTrue;
};
gdjs.evtTools.input._cursorIsOnObject = function(obj, runtimeScene) {
return obj.cursorOnObject(runtimeScene);
};
gdjs.evtTools.input.cursorOnObject = function(objectsLists, runtimeScene, accurate, inverted) {
gdjs.evtTools.input.OLDcursorOnObject = function(objectsLists, runtimeScene, accurate, inverted) {
return gdjs.evtTools.object.pickObjectsIf(gdjs.evtTools.input._cursorIsOnObject,
objectsLists, inverted, runtimeScene);
};

View File

@@ -1,3 +1,4 @@
// @ts-check
/*
* GDevelop JS Platform
* Copyright 2013-2016 Florian Rival (Florian.Rival@gmail.com). All rights reserved.
@@ -165,7 +166,7 @@ gdjs.evtTools.object.twoListsTest = function(predicate, objectsLists1, objectsLi
* @param {Function} predicate The function applied to each object: must return true if the object fulfill the predicate.
* @param {Hashtable} objectsLists The lists of objects to trim
* @param {boolean} negatePredicate If set to true, the result of the predicate is negated.
* @param {*} extraArg Argument passed to the predicate (along with the object). Useful for avoiding relying on temporary closures.
* @param {any=} extraArg Argument passed to the predicate (along with the object). Useful for avoiding relying on temporary closures.
* @return {boolean} true if at least one object fulfill the predicate.
*/
gdjs.evtTools.object.pickObjectsIf = function(predicate, objectsLists, negatePredicate, extraArg) {
@@ -186,6 +187,7 @@ gdjs.evtTools.object.pickObjectsIf = function(predicate, objectsLists, negatePre
var arr = lists[i];
for(var k = 0, lenk = arr.length;k<lenk;++k) {
// @ts-ignore
if (negatePredicate ^ predicate(arr[k], extraArg)) {
isTrue = true;
arr[k].pick = true; //Pick the objects
@@ -211,20 +213,93 @@ gdjs.evtTools.object.pickObjectsIf = function(predicate, objectsLists, negatePre
return isTrue;
};
/**
* @param {Hashtable} objectsLists1 The lists of objects to test collisions for
* @param {Hashtable} objectsLists2 The second lists of objects to test collisions for
* @param {boolean} inverted If set to true, only objects from the first lists that are not in collision with *any* other objects will be picked.
* @param {gdjs.RuntimeScene} runtimeScene The scene objects belong to
* @param {boolean} ignoreTouchingEdges If true, polygons are not considered in collision if only their edges are touching.
*/
gdjs.evtTools.object.hitBoxesCollisionTest = function(objectsLists1, objectsLists2, inverted, runtimeScene, ignoreTouchingEdges) {
var object1IdsSet = gdjs.ObjectPositionsManager.objectsListsToObjectIdsSet(objectsLists1);
var object2IdsSet = gdjs.ObjectPositionsManager.objectsListsToObjectIdsSet(objectsLists2);
var isTrue = runtimeScene.getObjectPositionsManager().collisionTest(object1IdsSet, object2IdsSet, inverted, ignoreTouchingEdges);
gdjs.ObjectPositionsManager.keepOnlyObjectsFromObjectIdsSet(objectsLists1, object1IdsSet);
gdjs.ObjectPositionsManager.keepOnlyObjectsFromObjectIdsSet(objectsLists2, object2IdsSet);
return isTrue;
};
gdjs.evtTools.object.OLDhitBoxesCollisionTest = function(objectsLists1, objectsLists2, inverted, runtimeScene, ignoreTouchingEdges) {
return gdjs.evtTools.object.twoListsTest(gdjs.RuntimeObject.collisionTest,
objectsLists1, objectsLists2, inverted, ignoreTouchingEdges);
objectsLists1, objectsLists2, inverted, ignoreTouchingEdges);
}
/**
* @param {Hashtable} objectsLists1 The lists of objects to test distance from
* @param {Hashtable} objectsLists2 The second lists of objects to test distance to
* @param {number} distance The maximum distance between objects
* @param {boolean} inverted If set to true, only objects from the first lists that have *no* objects from the second lists below the specified distance will be picked.
* @param {gdjs.RuntimeScene} runtimeScene The scene objects belong to
*/
gdjs.evtTools.object.distanceTest = function(objectsLists1, objectsLists2, distance, inverted, runtimeScene) {
var object1IdsSet = gdjs.ObjectPositionsManager.objectsListsToObjectIdsSet(objectsLists1);
var object2IdsSet = gdjs.ObjectPositionsManager.objectsListsToObjectIdsSet(objectsLists2);
var isTrue = runtimeScene.getObjectPositionsManager().distanceTest(object1IdsSet, object2IdsSet, distance, inverted);
gdjs.ObjectPositionsManager.keepOnlyObjectsFromObjectIdsSet(objectsLists1, object1IdsSet);
gdjs.ObjectPositionsManager.keepOnlyObjectsFromObjectIdsSet(objectsLists2, object2IdsSet);
return isTrue;
};
gdjs.evtTools.object._distanceBetweenObjects = function(obj1, obj2, distance) {
gdjs.evtTools.object._distanceBetweenObjectsCount++;
return obj1.getSqDistanceToObject(obj2) <= distance;
};
gdjs.evtTools.object.distanceTest = function(objectsLists1, objectsLists2, distance, inverted) {
gdjs.evtTools.object.OLDdistanceTest = function(objectsLists1, objectsLists2, distance, inverted) {
return gdjs.evtTools.object.twoListsTest(gdjs.evtTools.object._distanceBetweenObjects,
objectsLists1, objectsLists2, inverted, distance*distance);
};
/**
* @param {Hashtable} objectsLists1 The lists of objects to move
* @param {Hashtable} objectsLists2 The lists of objects to move away from
* @param {boolean} ignoreTouchingEdges If true, polygons are not considered in collision if only their edges are touching.
* @param {gdjs.RuntimeScene} runtimeScene The scene objects belong to
*/
gdjs.evtTools.object.separateObjects = function(objectsLists1, objectsLists2, ignoreTouchingEdges, runtimeScene) {
var object1IdsSet = gdjs.ObjectPositionsManager.objectsListsToObjectIdsSet(objectsLists1);
var object2IdsSet = gdjs.ObjectPositionsManager.objectsListsToObjectIdsSet(objectsLists2);
runtimeScene.getObjectPositionsManager().separateObjects(object1IdsSet, object2IdsSet, ignoreTouchingEdges);
};
/**
* @param {Hashtable} objectsLists1 The lists of objects to move
* @param {Hashtable} objectsLists2 The lists of objects to move away from
* @param {boolean} ignoreTouchingEdges If true, polygons are not considered in collision if only their edges are touching.
* @param {gdjs.RuntimeScene} runtimeScene The scene objects belong to
*/
gdjs.evtTools.object.OLDseparateObjects = function(objectsLists1, objectsLists2, ignoreTouchingEdges, runtimeScene) {
var lists = gdjs.staticArray(gdjs.evtTools.object.separateObjects);
objectsLists1.values(lists);
for(var i = 0, len = lists.length;i<len;++i) {
var list = lists[i];
for(var j = 0;j < list.length;++j) {
/** @type gdjs.RuntimeObject */
var object = list[j];
object.OLDseparateFromObjectsList(objectsLists2, ignoreTouchingEdges);
}
}
};
gdjs.evtTools.object._movesToward = function(obj1, obj2, tolerance) {
if ( obj1.hasNoForces() ) return false;
@@ -316,6 +391,7 @@ gdjs.evtTools.object.pickNearestObject = function(objectsLists, x, y, inverted)
for(var j = 0;j < list.length;++j) {
var object = list[j];
var distance = object.getSqDistanceTo(x, y);
// @ts-ignore
if( first || (distance < best ^ inverted)) {
best = distance;
bestObject = object;
@@ -332,16 +408,54 @@ gdjs.evtTools.object.pickNearestObject = function(objectsLists, x, y, inverted)
return true;
};
gdjs.evtTools.object.raycastObject = function(objectsLists, x, y, angle, dist, varX, varY, inverted) {
/**
* @param {Hashtable} objectsLists The lists of objects to intersect the ray with
* @param {number} x X position of the ray starting point
* @param {number} y Y position of the ray starting point
* @param {number} angle Angle of the ray
* @param {number} dist Maximum distance ("radius") before stopping the ray
* @param {gdjs.Variable} varX Variable where to store the ray/object intersection X position
* @param {gdjs.Variable} varY Variable where to store the ray/object intersection Y position
* @param {boolean} inverted true to find the object that is the farthest one intersecting with the ray, false to find the closest.
* @param {gdjs.RuntimeScene} runtimeScene The scene objects belong to
*/
gdjs.evtTools.object.raycastObject = function(objectsLists, x, y, angle, dist, varX, varY, inverted, runtimeScene) {
return gdjs.evtTools.object.raycastObjectToPosition(
objectsLists,
x, y,
x + dist*Math.cos(angle*Math.PI/180.0),
y + dist*Math.sin(angle*Math.PI/180.0),
varX, varY, inverted);
varX, varY, inverted, runtimeScene);
};
gdjs.evtTools.object.raycastObjectToPosition = function(objectsLists, x, y, endX, endY, varX, varY, inverted) {
/**
* @param {Hashtable} objectsLists The lists of objects to intersect the ray with
* @param {number} x X position of the ray starting point
* @param {number} y Y position of the ray starting point
* @param {number} endX X position of the ray ending point
* @param {number} endY Y position of the ray ending point
* @param {gdjs.Variable} varX Variable where to store the ray/object intersection X position
* @param {gdjs.Variable} varY Variable where to store the ray/object intersection Y position
* @param {boolean} inverted true to find the object that is the farthest one intersecting with the ray, false to find the closest.
* @param {gdjs.RuntimeScene} runtimeScene The scene objects belong to
*/
gdjs.evtTools.object.raycastObjectToPosition = function(objectsLists, x, y, endX, endY, varX, varY, inverted, runtimeScene) {
var objectIdsSet = gdjs.ObjectPositionsManager.objectsListsToObjectIdsSet(objectsLists);
var intersectionCoordinates = [0, 0];
var foundIntersection = runtimeScene.getObjectPositionsManager().raycastTest(objectIdsSet, x, y, endX, endY, intersectionCoordinates, inverted);
if (!foundIntersection)
return false;
gdjs.ObjectPositionsManager.keepOnlyObjectsFromObjectIdsSet(objectsLists, objectIdsSet);
varX.setNumber(intersectionCoordinates[0]);
varY.setNumber(intersectionCoordinates[1]);
return true;
}
gdjs.evtTools.object.OLDraycastObjectToPosition = function(objectsLists, x, y, endX, endY, varX, varY, inverted) {
var matchObject = null;
var testSqDist = inverted ? 0 : (endX - x)*(endX - x) + (endY - y)*(endY - y);
var resultX = 0;
@@ -382,6 +496,29 @@ gdjs.evtTools.object.raycastObjectToPosition = function(objectsLists, x, y, endX
return true;
};
/**
* @param {Hashtable} objectsLists The lists of objects to test
* @param {number} x X position of the point
* @param {number} y Y position of the point
* @param {boolean} inverted true to find objects containing the point, false to find objects not containing it.
* @param {gdjs.RuntimeScene} runtimeScene The scene objects belong to
*/
gdjs.evtTools.object.isCollidingWithPoint = function(objectsLists, x, y, inverted, runtimeScene) {
var objectIdsSet = gdjs.ObjectPositionsManager.objectsListsToObjectIdsSet(objectsLists);
var isTrue = runtimeScene.getObjectPositionsManager().pointsTest(
objectIdsSet, [[x, y]], true /* TODO: Allow to specify if the test should be accurate or not */, inverted);
gdjs.ObjectPositionsManager.keepOnlyObjectsFromObjectIdsSet(objectsLists, objectIdsSet);
return isTrue;
};
gdjs.evtTools.object.OLDisCollidingWithPoint = function(objectsLists, x, y, inverted, runtimeScene) {
return gdjs.evtTools.object.pickObjectsIf(function(obj) {
return obj.isCollidingWithPoint(x, y);
}, objectsLists, inverted);
};
/**
* Do the work of creating a new object
* @private

View File

@@ -131,7 +131,7 @@ gdjs.InputManager.prototype.getMouseY = function() {
/**
* Should be called whenever a mouse button is pressed
* @param {number} buttonCode The mouse button code associated to the event.
* @param {number} buttonCode The mouse button code associated to the event.
* See gdjs.InputManager.MOUSE_LEFT_BUTTON, gdjs.InputManager.MOUSE_RIGHT_BUTTON, gdjs.InputManager.MOUSE_MIDDLE_BUTTON
*/
gdjs.InputManager.prototype.onMouseButtonPressed = function(buttonCode) {
@@ -270,7 +270,7 @@ gdjs.InputManager.prototype.popEndedTouch = function() {
*
* If true, any touch will move the mouse position and set mouse buttons
* as pressed/released.
* @param enable {Boolean} true to simulate mouse events, false to disable it.
* @param {boolean=} enable `true` to simulate mouse events, `false` to disable it. `true` if not defined.
*/
gdjs.InputManager.prototype.touchSimulateMouse = function(enable) {
if (enable === undefined) enable = true;

File diff suppressed because it is too large Load Diff

View File

@@ -35,13 +35,16 @@ gdjs.RuntimeScenePixiRenderer.prototype._renderProfileText = function() {
this._profilerText = new PIXI.Text(" ", {
align: "left",
stroke: "#FFF",
strokeThickness: 1
strokeThickness: 1,
fontSize: 12,
});
this._pixiContainer.addChild(this._profilerText);
}
var average = this._runtimeScene.getProfiler().getFramesAverageMeasures();
var outputs = [];
gdjs.Profiler.getProfilerCounterTexts(average.counters, outputs);
gdjs.Profiler.getProfilerTimingTexts(average.timings, outputs);
gdjs.Profiler.getProfilerSectionTexts("All", average, outputs);
this._profilerText.text = outputs.join("\n");

View File

@@ -1,3 +1,4 @@
// @ts-check
/*
* GDevelop JS Platform
* Copyright 2013-2016 Florian Rival (Florian.Rival@gmail.com). All rights reserved.
@@ -33,14 +34,28 @@ gdjs.Polygon = function()
this.center = [0,0];
};
gdjs.Polygon.prototype.move = function(x,y) {
/**
* Move the polygon by the specified offset.
* @param {number} x Offset on X axis
* @param {number} y Offset on Y axis
* @returns {gdjs.Polygon} The same, updated, polygon.
*/
gdjs.Polygon.prototype.move = function(x, y) {
for(var i = 0, len = this.vertices.length;i<len;++i) {
this.vertices[i][0] += x;
this.vertices[i][1] += y;
}
}
return this;
};
/**
* Rotate the polygon by the specified angle (in radians), clockwise.
*
* @param {number} angle The angle, in radians.
* @returns {gdjs.Polygon} The same, updated, polygon.
*/
gdjs.Polygon.prototype.rotate = function(angle) {
var t, cosa = Math.cos(-angle),
sina = Math.sin(-angle); //We want a clockwise rotation
@@ -49,7 +64,9 @@ gdjs.Polygon.prototype.rotate = function(angle) {
t = this.vertices[i][0];
this.vertices[i][0] = t*cosa + this.vertices[i][1]*sina;
this.vertices[i][1] = -t*sina + this.vertices[i][1]*cosa;
}
}
return this;
};
gdjs.Polygon.prototype.computeEdges = function() {
@@ -220,9 +237,23 @@ gdjs.Polygon.collisionTest._statics = {
};
/**
* Do a raycast test.<br>
* Please note that the polygon must be <b>convex</b>!
*
* Represents the result of a raycast test (see `gdjs.Polygon.raycastTest`)
*
* @typedef {Object} PolygonRaycastTestResult
* @property {boolean} collision True if there is a collision between the ray and the polygon
* @property {number} closeX X position of the ray/polygon intersection point closest to the ray start point.
* @property {number} closeY Y position of the ray/polygon intersection point closest to the ray start point.
* @property {number} closeSqDist The squared distance between the ray start point and the closest intersection point.
* @property {number} farX X position of the ray/polygon intersection point farthest to the ray start point.
* @property {number} farY Y position of the ray/polygon intersection point farthest to the ray start point.
* @property {number} farSqDist The squared distance between the ray start point and the farthest intersection point.
*/
/**
* Do an intersection test between a polygon and a ray.
*
* Please note that the polygon must be **convex**!
*
* For some theory, check <a href="https://www.codeproject.com/Tips/862988/Find-the-Intersection-Point-of-Two-Line-Segments">Find the Intersection Point of Two Line Segments</a>.
*
* @param {gdjs.Polygon} poly The polygon to test
@@ -230,10 +261,11 @@ gdjs.Polygon.collisionTest._statics = {
* @param {number} startY The raycast start point Y
* @param {number} endX The raycast end point X
* @param {number} endY The raycast end point Y
* @return A raycast result with the contact points and distances
* @return {PolygonRaycastTestResult} A raycast result with the contact points and distances
*/
gdjs.Polygon.raycastTest = function(poly, startX, startY, endX, endY)
{
/** @type PolygonRaycastTestResult */
var result = gdjs.Polygon.raycastTest._statics.result;
result.collision = false;
@@ -313,7 +345,7 @@ gdjs.Polygon.raycastTest = function(poly, startX, startY, endX, endY)
{
var x = p[0] + t*r[0];
var y = p[1] + t*r[1];
var sqDist = (x-startX)*(x-startX) + (y-startY)*(y-startY);
if ( sqDist < minSqDist )
{
@@ -340,6 +372,21 @@ gdjs.Polygon.raycastTest = function(poly, startX, startY, endX, endY)
return result;
};
/**
* Copy a PolygonRaycastTestResult into another.
* @param {PolygonRaycastTestResult} source The result to copy
* @param {PolygonRaycastTestResult} destination Where to save the results
*/
gdjs.Polygon.raycastTest.copyResultTo = function(source, destination) {
destination.collision = source.collision;
destination.closeX = source.closeX;
destination.closeY = source.closeY;
destination.closeSqDist = source.closeSqDist;
destination.farX = source.farX;
destination.farY = source.farY;
destination.farSqDist = source.farSqDist;
}
gdjs.Polygon.raycastTest._statics = {
p: [0,0],
q: [0,0],

View File

@@ -1,3 +1,5 @@
// @ts-check
/**
* A basic profiling tool that can be used to measure time spent in sections of the engine.
* @class Profiler
@@ -17,6 +19,8 @@ gdjs.Profiler = function() {
parent: null,
time: 0,
subsections: {},
counters: {},
timings: {},
});
}
@@ -32,6 +36,8 @@ gdjs.Profiler.prototype.beginFrame = function() {
time: 0,
lastStartTime: this._getTimeNow(),
subsections: {},
counters: {},
timings: {},
};
this._currentSection = this._currentFrameMeasure;
};
@@ -60,6 +66,29 @@ gdjs.Profiler.prototype.end = function(sectionName) {
this._currentSection = this._currentSection.parent;
};
/**
* Increment a counter for the current frame.
* @param {string} counterName The name of the counter
*/
gdjs.Profiler.prototype.incrementCallCounter = function(counterName) {
if (!this._currentFrameMeasure) return;
this._currentFrameMeasure.counters[counterName] =
(this._currentFrameMeasure.counters[counterName] || 0) + 1;
};
/**
* Increment some timing for the current frame.
* @param {string} timingName The name of the timing
* @param {number} timeInMs The time in milliseconds
*/
gdjs.Profiler.prototype.addTime = function(timingName, timeInMs) {
if (!this._currentFrameMeasure) return;
this._currentFrameMeasure.timings[timingName] =
(this._currentFrameMeasure.timings[timingName] || 0) + timeInMs;
};
gdjs.Profiler.prototype.endFrame = function() {
if (this._currentSection.parent !== null) {
throw new Error(
@@ -116,6 +145,8 @@ gdjs.Profiler.prototype.getFramesAverageMeasures = function() {
parent: null,
time: 0,
subsections: {},
counters: {},
timings: {},
};
for (var i = 0; i < this._framesCount; ++i) {
@@ -125,6 +156,24 @@ gdjs.Profiler.prototype.getFramesAverageMeasures = function() {
this._framesCount,
i
);
// Compute the sum for the counters and timings
for(var counterName in this._framesMeasures[i].counters) {
framesAverageMeasures.counters[counterName] = (framesAverageMeasures.counters[counterName] || 0) +
this._framesMeasures[i].counters[counterName];
}
for(var timingName in this._framesMeasures[i].timings) {
framesAverageMeasures.timings[timingName] = (framesAverageMeasures.timings[timingName] || 0) +
this._framesMeasures[i].timings[timingName];
}
}
// Compute average for counters and timings
for(var counterName in framesAverageMeasures.counters) {
framesAverageMeasures.counters[counterName] /= this._framesCount;
}
for(var timingName in framesAverageMeasures.timings) {
framesAverageMeasures.timings[timingName] /= this._framesCount;
}
return framesAverageMeasures;
@@ -144,8 +193,8 @@ gdjs.Profiler.prototype.getStats = function() {
* Useful for ingame profiling.
*
* @param {string} sectionName The name of the section
* @param {s} profilerSection The section measures
* @param {*} outputs The array where to push the results
* @param {*} profilerSection The section measures
* @param {string[]} outputs The array where to push the results
*/
gdjs.Profiler.getProfilerSectionTexts = function(
sectionName,
@@ -171,3 +220,35 @@ gdjs.Profiler.getProfilerSectionTexts = function(
}
outputs.push.apply(outputs, subsectionsOutputs);
};
/**
* Convert counters into texts.
* Useful for ingame profiling.
*
* @param {Object.<string, number>} counters The counters that were measured
* @param {string[]} outputs The array where to push the results
*/
gdjs.Profiler.getProfilerCounterTexts = function(
counters,
outputs
) {
for (var counterName in counters) {
outputs.push(counterName + ": " + counters[counterName]);
}
};
/**
* Convert timings into texts.
* Useful for ingame profiling.
*
* @param {Object.<string, number>} timings The timings that were measured
* @param {string[]} outputs The array where to push the results
*/
gdjs.Profiler.getProfilerTimingTexts = function(
timings,
outputs
) {
for (var timingName in timings) {
outputs.push(timingName + ": " + timings[timingName].toFixed(2) + "ms");
}
};

View File

@@ -45,7 +45,7 @@ gdjs.RuntimeObject = function(runtimeScene, objectData) {
this.layer = "";
this.livingOnScene = true;
this.id = runtimeScene.createNewUniqueId();
this._runtimeScene = runtimeScene; //This could/should be avoided.
this._runtimeScene = runtimeScene;
//Hit boxes:
if ( this._defaultHitBoxes === undefined ) {
@@ -54,6 +54,8 @@ gdjs.RuntimeObject = function(runtimeScene, objectData) {
}
this.hitBoxes = this._defaultHitBoxes;
this.hitBoxesDirty = true;
this._runtimeScene.getObjectPositionsManager().markObjectAsCreated(this);
if ( this.aabb === undefined )
this.aabb = { min:[0,0], max:[0,0] };
else {
@@ -114,21 +116,21 @@ gdjs.RuntimeObject = function(runtimeScene, objectData) {
* @static
* @private
*/
gdjs.RuntimeObject._identifiers = gdjs.RuntimeObject._identifiers || new Hashtable();
gdjs.RuntimeObject._identifiers = {};
/**
* The next available unique identifier for an object. Do not use directly or modify.
* The next available unique identifier for an object. Do not use directly or modify.
* @static
* @private
*/
gdjs.RuntimeObject._newId = (gdjs.RuntimeObject._newId || 0);
gdjs.RuntimeObject._largestId = 0;
/**
* Global container for unused forces, avoiding recreating forces each tick.
* @static
* @private
*/
gdjs.RuntimeObject.forcesGarbage = [];
gdjs.RuntimeObject.forcesGarbage = [];
//Common members functions related to the object and its runtimeScene :
@@ -206,6 +208,8 @@ gdjs.RuntimeObject.prototype.onDestroyFromScene = function(runtimeScene) {
for(var j = 0, lenj = this._behaviors.length;j<lenj;++j) {
this._behaviors[j].onDestroy();
}
runtimeScene.getObjectPositionsManager().markObjectAsRemoved(this);
};
//Rendering:
@@ -270,6 +274,7 @@ gdjs.RuntimeObject.prototype.setX = function(x) {
this.x = x;
this.hitBoxesDirty = true;
this._runtimeScene.getObjectPositionsManager().markObjectAsDirty(this);
};
/**
@@ -291,6 +296,7 @@ gdjs.RuntimeObject.prototype.setY = function(y) {
this.y = y;
this.hitBoxesDirty = true;
this._runtimeScene.getObjectPositionsManager().markObjectAsDirty(this);
};
/**
@@ -374,6 +380,7 @@ gdjs.RuntimeObject.prototype.setAngle = function(angle) {
this.angle = angle;
this.hitBoxesDirty = true;
this._runtimeScene.getObjectPositionsManager().markObjectAsDirty(this);
};
/**
@@ -839,9 +846,11 @@ gdjs.RuntimeObject.prototype.updateHitBoxes = function() {
};
/**
* An axis aligned bounding box, usually used for an object.
*
* @typedef {Object} AABB
* @property {Array} min The [x,y] coordinates of the top left point
* @property {Array} max The [x,y] coordinates of the bottom right point
* @property {number[]} min The [x,y] coordinates of the top left point
* @property {number[]} max The [x,y] coordinates of the bottom right point
*/
/**
@@ -877,7 +886,7 @@ gdjs.RuntimeObject.prototype.getAABB = function() {
* @return {?AABB} The bounding box (example: `{min: [10,5], max:[20,10]}`) or `null`.
*/
gdjs.RuntimeObject.prototype.getVisibilityAABB = function() {
return this.getAABB();
return this.getAABB(); // TODO: this should return getDrawableX/Y + getWidth/getHeight
};
/**
@@ -1134,7 +1143,7 @@ gdjs.RuntimeObject.prototype.separateFromObjects = function(objects, ignoreTouch
* @param {boolean | undefined} ignoreTouchingEdges If true, then edges that are touching each other, without the hitbox polygons actually overlapping, won't be considered in collision.
* @return true if the object was moved
*/
gdjs.RuntimeObject.prototype.separateFromObjectsList = function(objectsLists, ignoreTouchingEdges) {
gdjs.RuntimeObject.prototype.OLDseparateFromObjectsList = function(objectsLists, ignoreTouchingEdges) {
var moved = false;
var xMove = 0; var yMove = 0;
var hitBoxes = this.getHitBoxes();
@@ -1472,18 +1481,13 @@ gdjs.RuntimeObject.prototype.isCollidingWithPoint = function(pointX, pointY) {
* @static
*/
gdjs.RuntimeObject.getNameIdentifier = function(name) {
gdjs.RuntimeObject._identifiers =
gdjs.RuntimeObject._identifiers
|| new Hashtable();
var identifier = gdjs.RuntimeObject._identifiers[name];
if (identifier !== undefined) return identifier;
if ( gdjs.RuntimeObject._identifiers.containsKey(name) )
return gdjs.RuntimeObject._identifiers.get(name);
gdjs.RuntimeObject._largestId++;
var newIdentifier = gdjs.RuntimeObject._largestId;
gdjs.RuntimeObject._newId =
(gdjs.RuntimeObject._newId || 0) + 1;
var newIdentifier = gdjs.RuntimeObject._newId;
gdjs.RuntimeObject._identifiers.put(name, newIdentifier);
gdjs.RuntimeObject._identifiers[name] = newIdentifier;
return newIdentifier;
};

View File

@@ -27,6 +27,7 @@ gdjs.RuntimeScene = function(runtimeGame)
this._lastId = 0;
this._name = "";
this._timeManager = new gdjs.TimeManager(Date.now());
this._objectPositionsManager = new gdjs.ObjectPositionsManager();
this._gameStopRequested = false;
this._requestedScene = "";
this._isLoaded = false; // True if loadFromScene was called and the scene is being played.
@@ -39,9 +40,14 @@ gdjs.RuntimeScene = function(runtimeGame)
this._instancesRemoved = []; //The instances removed from the scene and waiting to be sent to the cache.
/** @type gdjs.Profiler */
this._profiler = null; // Set to `new gdjs.Profiler()` to have profiling done on the scene.
this._profiler = null;
this._onProfilerStopped = null; // The callback function to call when the profiler is stopped.
// Uncomment to manually launch profiling on the scene.
// Also uncomment the profiler display in `gdjs.RuntimeScenePixiRenderer` if needed.
// this.startProfiler(null);
// window.gdjsProfiler = this._profiler;
this.onGameResolutionResized();
};
@@ -378,7 +384,7 @@ gdjs.RuntimeScene.prototype._updateObjectsVisibility = function() {
if (object.isHidden()) {
rendererObject.visible = false;
} else {
var aabb = object.getVisibilityAABB();
var aabb = object.getVisibilityAABB(); // TODO: Use the ObjectPositionsManager
if (aabb && // If no AABB is returned, the object should always be visible
(aabb.min[0] > cameraCoords[2] || aabb.min[1] > cameraCoords[3] ||
aabb.max[0] < cameraCoords[0] || aabb.max[1] < cameraCoords[1])) {
@@ -465,6 +471,11 @@ gdjs.RuntimeScene.prototype._updateObjectsPreEvents = function() {
}
this._cacheOrClearRemovedInstances(); //Some behaviors may have request objects to be deleted.
// Update the object positions manager to ensure that, in case events or behaviors
// are not triggering themselves an update, we at least call update once per frame. Otherwise,
// we risk a **memory leak** by not clearing the object positions waiting to be deleted.
this._objectPositionsManager.update();
};
/**
@@ -681,6 +692,14 @@ gdjs.RuntimeScene.prototype.getAllLayerNames = function(result) {
this._layers.keys(result);
};
/**
* Get the ObjectPositionsManager of the scene.
* @return {gdjs.ObjectPositionsManager} The gdjs.ObjectPositionsManager of the scene.
*/
gdjs.RuntimeScene.prototype.getObjectPositionsManager = function() {
return this._objectPositionsManager;
};
/**
* Get the TimeManager of the scene.
* @return {gdjs.TimeManager} The gdjs.TimeManager of the scene.
@@ -742,13 +761,14 @@ gdjs.RuntimeScene.prototype.getProfiler = function() {
/**
* Start a new profiler to measures the time passed in sections of the engine
* in the scene.
* @param {Function} onProfilerStopped Function to be called when the profiler is stopped. Will be passed the profiler as argument.
* @param {?Function} onProfilerStopped Function to be called when the profiler is stopped. Will be passed the profiler as argument.
*/
gdjs.RuntimeScene.prototype.startProfiler = function(onProfilerStopped) {
if (this._profiler) return;
this._profiler = new gdjs.Profiler();
this._onProfilerStopped = onProfilerStopped;
this._objectPositionsManager.setProfiler(this._profiler);
}
/**
@@ -761,6 +781,7 @@ gdjs.RuntimeScene.prototype.stopProfiler = function() {
var onProfilerStopped = this._onProfilerStopped;
this._profiler = null;
this._onProfilerStopped = null;
this._objectPositionsManager.setProfiler(null);
if (onProfilerStopped) {
onProfilerStopped(oldProfiler);

View File

@@ -510,10 +510,10 @@ gdjs.SpriteRuntimeObject.prototype.setDirectionOrAngle = function(newValue) {
var anim = this._animations[this._currentAnimation];
if ( !anim.hasMultipleDirections ) {
// "Classic" setAngle implementation
if ( this.angle === newValue ) return;
this.angle = newValue;
this.hitBoxesDirty = true;
gdjs.RuntimeObject.prototype.setAngle.call(this, newValue);
this._renderer.updateAngle();
}
else {
@@ -531,7 +531,10 @@ gdjs.SpriteRuntimeObject.prototype.setDirectionOrAngle = function(newValue) {
this._renderer.update(); //TODO: This may be unnecessary.
this._animationFrameDirty = true;
// Reimplement what RuntimeObject.prototype.setAngle does:
this.hitBoxesDirty = true;
this._runtimeScene.getObjectPositionsManager().markObjectAsDirty(this);
}
};
@@ -764,7 +767,7 @@ gdjs.SpriteRuntimeObject.prototype.getCenterY = function() {
gdjs.SpriteRuntimeObject.prototype.setX = function(x) {
if ( x === this.x ) return;
this.x = x;
gdjs.RuntimeObject.prototype.setX.call(this, x);
if (this._animationFrame !== null) {
this.hitBoxesDirty = true;
this._renderer.updateX();
@@ -778,7 +781,7 @@ gdjs.SpriteRuntimeObject.prototype.setX = function(x) {
gdjs.SpriteRuntimeObject.prototype.setY = function(y) {
if ( y === this.y ) return;
this.y = y;
gdjs.RuntimeObject.prototype.setY.call(this, y);
if ( this._animationFrame !== null) {
this.hitBoxesDirty = true;
this._renderer.updateY();
@@ -795,11 +798,11 @@ gdjs.SpriteRuntimeObject.prototype.setAngle = function(angle) {
}
if ( !this._animations[this._currentAnimation].hasMultipleDirections ) {
// "Classic" setAngle implementation
if (this.angle === angle) return;
this.angle = angle;
gdjs.RuntimeObject.prototype.setAngle.call(this, angle);
this._renderer.updateAngle();
this.hitBoxesDirty = true;
} else {
angle = angle % 360;
if ( angle < 0 ) angle += 360;

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@@ -0,0 +1,489 @@
{
"firstLayout": "",
"gdVersion": {
"build": 98,
"major": 4,
"minor": 0,
"revision": 0
},
"properties": {
"adMobAppId": "",
"folderProject": false,
"linuxExecutableFilename": "",
"macExecutableFilename": "",
"orientation": "default",
"packageName": "",
"projectFile": "/Users/florian/Projects/F/GD/GDJS/tests/games/object-positions-manager-benchmarks/Collisions benchmark.json",
"scaleMode": "linear",
"sizeOnStartupMode": "",
"useExternalSourceFiles": false,
"version": "1.0.0",
"winExecutableFilename": "",
"winExecutableIconFile": "",
"name": "Projet",
"author": "",
"windowWidth": 800,
"windowHeight": 600,
"latestCompilationDirectory": "",
"maxFPS": 60,
"minFPS": 10,
"verticalSync": false,
"platformSpecificAssets": {},
"loadingScreen": {
"showGDevelopSplash": true
},
"extensions": [
{
"name": "BuiltinObject"
},
{
"name": "BuiltinAudio"
},
{
"name": "BuiltinVariables"
},
{
"name": "BuiltinTime"
},
{
"name": "BuiltinMouse"
},
{
"name": "BuiltinKeyboard"
},
{
"name": "BuiltinJoystick"
},
{
"name": "BuiltinCamera"
},
{
"name": "BuiltinWindow"
},
{
"name": "BuiltinFile"
},
{
"name": "BuiltinNetwork"
},
{
"name": "BuiltinScene"
},
{
"name": "BuiltinAdvanced"
},
{
"name": "Sprite"
},
{
"name": "BuiltinCommonInstructions"
},
{
"name": "BuiltinCommonConversions"
},
{
"name": "BuiltinStringInstructions"
},
{
"name": "BuiltinMathematicalTools"
},
{
"name": "BuiltinExternalLayouts"
}
],
"platforms": [
{
"name": "GDevelop JS platform"
}
],
"currentPlatform": "GDevelop JS platform"
},
"resources": {
"resources": [
{
"alwaysLoaded": false,
"file": "2DWoodBox.jpg",
"kind": "image",
"metadata": "",
"name": "2DWoodBox.jpg",
"smoothed": true,
"userAdded": false
},
{
"alwaysLoaded": false,
"file": "spship.png",
"kind": "image",
"metadata": "",
"name": "spship.png",
"smoothed": true,
"userAdded": false
}
],
"resourceFolders": []
},
"objects": [],
"objectsGroups": [],
"variables": [],
"layouts": [
{
"b": 209,
"disableInputWhenNotFocused": true,
"mangledName": "Nouvelle_32sc_232ne",
"name": "Nouvelle scène",
"oglFOV": 90,
"oglZFar": 500,
"oglZNear": 1,
"r": 209,
"standardSortMethod": true,
"stopSoundsOnStartup": true,
"title": "",
"v": 209,
"uiSettings": {
"grid": false,
"gridB": 255,
"gridG": 180,
"gridHeight": 32,
"gridOffsetX": 0,
"gridOffsetY": 0,
"gridR": 158,
"gridWidth": 32,
"snap": true,
"windowMask": false,
"zoomFactor": 1
},
"objectsGroups": [],
"variables": [],
"instances": [
{
"angle": 0,
"customSize": false,
"height": 243,
"layer": "",
"locked": false,
"name": "NouvelObjet1",
"width": 278,
"x": 108.5,
"y": 59,
"zOrder": 1,
"numberProperties": [],
"stringProperties": [],
"initialVariables": []
},
{
"angle": 0,
"customSize": false,
"height": 0,
"layer": "",
"locked": false,
"name": "NouvelObjet",
"width": 0,
"x": 400.5,
"y": 253,
"zOrder": 1,
"numberProperties": [],
"stringProperties": [],
"initialVariables": []
},
{
"angle": 0,
"customSize": false,
"height": 0,
"layer": "",
"locked": false,
"name": "NouvelObjet",
"width": 0,
"x": 195.5,
"y": 95,
"zOrder": 1,
"numberProperties": [],
"stringProperties": [],
"initialVariables": []
},
{
"angle": 0,
"customSize": false,
"height": 0,
"layer": "",
"locked": false,
"name": "NouvelObjet",
"width": 0,
"x": 563.5,
"y": 370,
"zOrder": 1,
"numberProperties": [],
"stringProperties": [],
"initialVariables": []
}
],
"objects": [
{
"name": "NouvelObjet",
"tags": "",
"type": "Sprite",
"updateIfNotVisible": true,
"variables": [
{
"name": "NewVariable",
"value": "1"
},
{
"name": "NewVariable2",
"value": "2"
}
],
"behaviors": [],
"animations": [
{
"name": "",
"useMultipleDirections": false,
"directions": [
{
"looping": false,
"timeBetweenFrames": 1,
"sprites": [
{
"hasCustomCollisionMask": false,
"image": "2DWoodBox.jpg",
"points": [],
"originPoint": {
"name": "origine",
"x": 0,
"y": 0
},
"centerPoint": {
"automatic": true,
"name": "centre",
"x": 0,
"y": 0
},
"customCollisionMask": [
[
{
"x": 0,
"y": 0
},
{
"x": 0,
"y": 0
},
{
"x": 0,
"y": 0
},
{
"x": 0,
"y": 0
}
]
]
}
]
}
]
}
]
},
{
"name": "NouvelObjet1",
"tags": "",
"type": "Sprite",
"updateIfNotVisible": true,
"variables": [],
"behaviors": [],
"animations": [
{
"name": "",
"useMultipleDirections": false,
"directions": [
{
"looping": false,
"timeBetweenFrames": 1,
"sprites": [
{
"hasCustomCollisionMask": false,
"image": "spship.png",
"points": [],
"originPoint": {
"name": "origine",
"x": 0,
"y": 0
},
"centerPoint": {
"automatic": true,
"name": "centre",
"x": 0,
"y": 0
},
"customCollisionMask": [
[
{
"x": 0,
"y": 0
},
{
"x": 0,
"y": 0
},
{
"x": 0,
"y": 0
},
{
"x": 0,
"y": 0
}
]
]
}
]
}
]
}
]
}
],
"events": [
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [
{
"type": {
"inverted": false,
"value": "DepartScene"
},
"parameters": [
""
],
"subInstructions": []
}
],
"actions": [],
"events": [
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Repeat",
"repeatExpression": "1200",
"conditions": [],
"actions": [
{
"type": {
"inverted": false,
"value": "Create"
},
"parameters": [
"",
"NouvelObjet",
"Random(400)",
"Random(300)",
""
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "Create"
},
"parameters": [
"",
"NouvelObjet1",
"0",
"0",
""
],
"subInstructions": []
}
],
"events": []
}
]
},
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [],
"actions": [
{
"type": {
"inverted": false,
"value": "MettreXY"
},
"parameters": [
"NouvelObjet1",
"=",
"MouseX()",
"=",
"MouseY()"
],
"subInstructions": []
}
],
"events": []
},
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [
{
"type": {
"inverted": false,
"value": "CollisionNP"
},
"parameters": [
"NouvelObjet1",
"NouvelObjet",
"",
""
],
"subInstructions": []
}
],
"actions": [
{
"type": {
"inverted": false,
"value": "ChangeDirection"
},
"parameters": [
"NouvelObjet",
"+",
"1"
],
"subInstructions": []
}
],
"events": []
}
],
"layers": [
{
"name": "",
"visibility": true,
"cameras": [
{
"defaultSize": true,
"defaultViewport": true,
"height": 0,
"viewportBottom": 1,
"viewportLeft": 0,
"viewportRight": 1,
"viewportTop": 0,
"width": 0
}
],
"effects": []
}
],
"behaviorsSharedData": []
}
],
"externalEvents": [],
"eventsFunctionsExtensions": [],
"externalLayouts": [],
"externalSourceFiles": []
}

View File

@@ -0,0 +1,532 @@
{
"firstLayout": "",
"gdVersion": {
"build": 98,
"major": 4,
"minor": 0,
"revision": 0
},
"properties": {
"adMobAppId": "",
"folderProject": false,
"linuxExecutableFilename": "",
"macExecutableFilename": "",
"orientation": "landscape",
"packageName": "com.example.gamename",
"projectFile": "/Users/florian/Projects/F/GD/GDJS/tests/games/object-positions-manager-benchmarks/Cursor on object benchmark.json",
"scaleMode": "linear",
"sizeOnStartupMode": "adaptWidth",
"useExternalSourceFiles": false,
"version": "1.0.0",
"winExecutableFilename": "",
"winExecutableIconFile": "",
"name": "Project",
"author": "",
"windowWidth": 800,
"windowHeight": 600,
"latestCompilationDirectory": "",
"maxFPS": 60,
"minFPS": 20,
"verticalSync": false,
"platformSpecificAssets": {},
"loadingScreen": {
"showGDevelopSplash": true
},
"extensions": [
{
"name": "BuiltinObject"
},
{
"name": "BuiltinAudio"
},
{
"name": "BuiltinVariables"
},
{
"name": "BuiltinTime"
},
{
"name": "BuiltinMouse"
},
{
"name": "BuiltinKeyboard"
},
{
"name": "BuiltinJoystick"
},
{
"name": "BuiltinCamera"
},
{
"name": "BuiltinWindow"
},
{
"name": "BuiltinFile"
},
{
"name": "BuiltinNetwork"
},
{
"name": "BuiltinScene"
},
{
"name": "BuiltinAdvanced"
},
{
"name": "Sprite"
},
{
"name": "BuiltinCommonInstructions"
},
{
"name": "BuiltinCommonConversions"
},
{
"name": "BuiltinStringInstructions"
},
{
"name": "BuiltinMathematicalTools"
},
{
"name": "BuiltinExternalLayouts"
}
],
"platforms": [
{
"name": "GDevelop JS platform"
}
],
"currentPlatform": "GDevelop JS platform"
},
"resources": {
"resources": [
{
"alwaysLoaded": false,
"file": "NewObject-1.png",
"kind": "image",
"metadata": "",
"name": "NewObject-1.png",
"smoothed": true,
"userAdded": true
},
{
"alwaysLoaded": false,
"file": "NewObject2-1.png",
"kind": "image",
"metadata": "",
"name": "NewObject2-1.png",
"smoothed": true,
"userAdded": true
},
{
"alwaysLoaded": false,
"file": "NewObject3-1.png",
"kind": "image",
"metadata": "",
"name": "NewObject3-1.png",
"smoothed": true,
"userAdded": false
}
],
"resourceFolders": []
},
"objects": [],
"objectsGroups": [],
"variables": [],
"layouts": [
{
"b": 209,
"disableInputWhenNotFocused": true,
"mangledName": "NewScene",
"name": "NewScene",
"oglFOV": 90,
"oglZFar": 500,
"oglZNear": 1,
"r": 209,
"standardSortMethod": true,
"stopSoundsOnStartup": true,
"title": "",
"v": 209,
"uiSettings": {
"grid": false,
"gridB": 255,
"gridG": 180,
"gridHeight": 32,
"gridOffsetX": 0,
"gridOffsetY": 0,
"gridR": 158,
"gridWidth": 32,
"snap": true,
"windowMask": false,
"zoomFactor": 1
},
"objectsGroups": [],
"variables": [],
"instances": [
{
"angle": 0,
"customSize": false,
"height": 0,
"layer": "",
"locked": false,
"name": "FollowCursorObject",
"width": 0,
"x": 689,
"y": 110,
"zOrder": 1,
"numberProperties": [],
"stringProperties": [],
"initialVariables": []
}
],
"objects": [
{
"name": "Object",
"tags": "",
"type": "Sprite",
"updateIfNotVisible": false,
"variables": [],
"behaviors": [],
"animations": [
{
"name": "NewObject2",
"useMultipleDirections": false,
"directions": [
{
"looping": false,
"timeBetweenFrames": 0.08,
"sprites": [
{
"hasCustomCollisionMask": false,
"image": "NewObject2-1.png",
"points": [],
"originPoint": {
"name": "origine",
"x": 0,
"y": 0
},
"centerPoint": {
"automatic": true,
"name": "centre",
"x": 0,
"y": 0
},
"customCollisionMask": []
}
]
}
]
}
]
},
{
"name": "FollowCursorObject",
"tags": "",
"type": "Sprite",
"updateIfNotVisible": false,
"variables": [],
"behaviors": [],
"animations": [
{
"name": "NewObject3",
"useMultipleDirections": false,
"directions": [
{
"looping": false,
"timeBetweenFrames": 0.08,
"sprites": [
{
"hasCustomCollisionMask": false,
"image": "NewObject3-1.png",
"points": [],
"originPoint": {
"name": "origine",
"x": 0,
"y": 0
},
"centerPoint": {
"automatic": true,
"name": "centre",
"x": 0,
"y": 0
},
"customCollisionMask": []
}
]
}
]
}
]
}
],
"events": [
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [
{
"type": {
"inverted": false,
"value": "DepartScene"
},
"parameters": [
""
],
"subInstructions": []
}
],
"actions": [],
"events": [
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Repeat",
"repeatExpression": "7000",
"conditions": [],
"actions": [
{
"type": {
"inverted": false,
"value": "Create"
},
"parameters": [
"",
"Object",
"Random(600)",
"Random(400)",
""
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "ChangeScale"
},
"parameters": [
"Object",
"=",
"0.3"
],
"subInstructions": []
}
],
"events": []
}
]
},
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [
{
"type": {
"inverted": false,
"value": "Timer"
},
"parameters": [
"",
"1",
"\"DirectionChange\""
],
"subInstructions": []
}
],
"actions": [
{
"type": {
"inverted": false,
"value": "ResetTimer"
},
"parameters": [
"",
"\"DirectionChange\""
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "SetAngle"
},
"parameters": [
"Object",
"=",
"Random(360)"
],
"subInstructions": []
}
],
"events": []
},
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [],
"actions": [
{
"type": {
"inverted": false,
"value": "AddForceAL"
},
"parameters": [
"Object",
"Object.Angle()",
"30",
""
],
"subInstructions": []
}
],
"events": []
},
{
"colorB": 228,
"colorG": 176,
"colorR": 74,
"creationTime": 0,
"disabled": false,
"folded": false,
"name": "Cursor is on object",
"source": "",
"type": "BuiltinCommonInstructions::Group",
"events": [
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [
{
"type": {
"inverted": false,
"value": "SourisSurObjet"
},
"parameters": [
"Object",
"NewObject",
"no",
""
],
"subInstructions": []
}
],
"actions": [
{
"type": {
"inverted": false,
"value": "ChangeColor"
},
"parameters": [
"Object",
"\"71;231;0\""
],
"subInstructions": []
}
],
"events": []
}
],
"parameters": []
},
{
"colorB": 228,
"colorG": 176,
"colorR": 74,
"creationTime": 0,
"disabled": false,
"folded": false,
"name": "Cursor is NOT on object",
"source": "",
"type": "BuiltinCommonInstructions::Group",
"events": [
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [
{
"type": {
"inverted": true,
"value": "SourisSurObjet"
},
"parameters": [
"Object",
"NewObject",
"no",
""
],
"subInstructions": []
}
],
"actions": [
{
"type": {
"inverted": false,
"value": "ChangeColor"
},
"parameters": [
"Object",
"\"255;255;255\""
],
"subInstructions": []
}
],
"events": []
}
],
"parameters": []
},
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [],
"actions": [
{
"type": {
"inverted": false,
"value": "MettreXY"
},
"parameters": [
"FollowCursorObject",
"=",
"MouseX()",
"=",
"MouseY()"
],
"subInstructions": []
}
],
"events": []
}
],
"layers": [
{
"name": "",
"visibility": true,
"cameras": [
{
"defaultSize": true,
"defaultViewport": true,
"height": 0,
"viewportBottom": 1,
"viewportLeft": 0,
"viewportRight": 1,
"viewportTop": 0,
"width": 0
}
],
"effects": []
}
],
"behaviorsSharedData": []
}
],
"externalEvents": [],
"eventsFunctionsExtensions": [],
"externalLayouts": [],
"externalSourceFiles": []
}

View File

@@ -0,0 +1,594 @@
{
"firstLayout": "",
"gdVersion": {
"build": 98,
"major": 4,
"minor": 0,
"revision": 0
},
"properties": {
"adMobAppId": "",
"folderProject": false,
"linuxExecutableFilename": "",
"macExecutableFilename": "",
"orientation": "landscape",
"packageName": "com.example.gamename",
"projectFile": "/Users/florian/Projects/F/GD/GDJS/tests/games/object-positions-manager-benchmarks/Distance between objects benchmark.json",
"scaleMode": "linear",
"sizeOnStartupMode": "adaptWidth",
"useExternalSourceFiles": false,
"version": "1.0.0",
"winExecutableFilename": "",
"winExecutableIconFile": "",
"name": "Project",
"author": "",
"windowWidth": 800,
"windowHeight": 600,
"latestCompilationDirectory": "",
"maxFPS": 60,
"minFPS": 20,
"verticalSync": false,
"platformSpecificAssets": {},
"loadingScreen": {
"showGDevelopSplash": true
},
"extensions": [
{
"name": "BuiltinObject"
},
{
"name": "BuiltinAudio"
},
{
"name": "BuiltinVariables"
},
{
"name": "BuiltinTime"
},
{
"name": "BuiltinMouse"
},
{
"name": "BuiltinKeyboard"
},
{
"name": "BuiltinJoystick"
},
{
"name": "BuiltinCamera"
},
{
"name": "BuiltinWindow"
},
{
"name": "BuiltinFile"
},
{
"name": "BuiltinNetwork"
},
{
"name": "BuiltinScene"
},
{
"name": "BuiltinAdvanced"
},
{
"name": "Sprite"
},
{
"name": "BuiltinCommonInstructions"
},
{
"name": "BuiltinCommonConversions"
},
{
"name": "BuiltinStringInstructions"
},
{
"name": "BuiltinMathematicalTools"
},
{
"name": "BuiltinExternalLayouts"
}
],
"platforms": [
{
"name": "GDevelop JS platform"
}
],
"currentPlatform": "GDevelop JS platform"
},
"resources": {
"resources": [
{
"alwaysLoaded": false,
"file": "NewObject-1.png",
"kind": "image",
"metadata": "",
"name": "NewObject-1.png",
"smoothed": true,
"userAdded": true
},
{
"alwaysLoaded": false,
"file": "NewObject2-1.png",
"kind": "image",
"metadata": "",
"name": "NewObject2-1.png",
"smoothed": true,
"userAdded": true
},
{
"alwaysLoaded": false,
"file": "NewObject3-1.png",
"kind": "image",
"metadata": "",
"name": "NewObject3-1.png",
"smoothed": true,
"userAdded": false
}
],
"resourceFolders": []
},
"objects": [],
"objectsGroups": [],
"variables": [],
"layouts": [
{
"b": 209,
"disableInputWhenNotFocused": true,
"mangledName": "NewScene",
"name": "NewScene",
"oglFOV": 90,
"oglZFar": 500,
"oglZNear": 1,
"r": 209,
"standardSortMethod": true,
"stopSoundsOnStartup": true,
"title": "",
"v": 209,
"uiSettings": {
"grid": false,
"gridB": 255,
"gridG": 180,
"gridHeight": 32,
"gridOffsetX": 0,
"gridOffsetY": 0,
"gridR": 158,
"gridWidth": 32,
"snap": true,
"windowMask": false,
"zoomFactor": 1
},
"objectsGroups": [],
"variables": [],
"instances": [
{
"angle": 0,
"customSize": false,
"height": 0,
"layer": "",
"locked": false,
"name": "NewObject3",
"width": 0,
"x": 689,
"y": 110,
"zOrder": 1,
"numberProperties": [],
"stringProperties": [],
"initialVariables": []
}
],
"objects": [
{
"name": "NewObject",
"tags": "",
"type": "Sprite",
"updateIfNotVisible": false,
"variables": [],
"behaviors": [],
"animations": [
{
"name": "NewObject",
"useMultipleDirections": false,
"directions": [
{
"looping": false,
"timeBetweenFrames": 0.08,
"sprites": [
{
"hasCustomCollisionMask": false,
"image": "NewObject-1.png",
"points": [],
"originPoint": {
"name": "origine",
"x": 0,
"y": 0
},
"centerPoint": {
"automatic": true,
"name": "centre",
"x": 0,
"y": 0
},
"customCollisionMask": []
}
]
}
]
}
]
},
{
"name": "NewObject2",
"tags": "",
"type": "Sprite",
"updateIfNotVisible": false,
"variables": [],
"behaviors": [],
"animations": [
{
"name": "NewObject2",
"useMultipleDirections": false,
"directions": [
{
"looping": false,
"timeBetweenFrames": 0.08,
"sprites": [
{
"hasCustomCollisionMask": false,
"image": "NewObject2-1.png",
"points": [],
"originPoint": {
"name": "origine",
"x": 0,
"y": 0
},
"centerPoint": {
"automatic": true,
"name": "centre",
"x": 0,
"y": 0
},
"customCollisionMask": []
}
]
}
]
}
]
},
{
"name": "NewObject3",
"tags": "",
"type": "Sprite",
"updateIfNotVisible": false,
"variables": [],
"behaviors": [],
"animations": [
{
"name": "NewObject3",
"useMultipleDirections": false,
"directions": [
{
"looping": false,
"timeBetweenFrames": 0.08,
"sprites": [
{
"hasCustomCollisionMask": false,
"image": "NewObject3-1.png",
"points": [],
"originPoint": {
"name": "origine",
"x": 0,
"y": 0
},
"centerPoint": {
"automatic": true,
"name": "centre",
"x": 0,
"y": 0
},
"customCollisionMask": []
}
]
}
]
}
]
}
],
"events": [
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [
{
"type": {
"inverted": false,
"value": "DepartScene"
},
"parameters": [
""
],
"subInstructions": []
}
],
"actions": [],
"events": [
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Repeat",
"repeatExpression": "700",
"conditions": [],
"actions": [
{
"type": {
"inverted": false,
"value": "Create"
},
"parameters": [
"",
"NewObject",
"Random(800)",
"Random(600)",
""
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "Create"
},
"parameters": [
"",
"NewObject2",
"Random(800)",
"Random(600)",
""
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "ChangeScale"
},
"parameters": [
"NewObject",
"=",
"0.3"
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "ChangeScale"
},
"parameters": [
"NewObject2",
"=",
"0.3"
],
"subInstructions": []
}
],
"events": []
}
]
},
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [
{
"type": {
"inverted": false,
"value": "Timer"
},
"parameters": [
"",
"1",
"\"DirectionChange\""
],
"subInstructions": []
}
],
"actions": [
{
"type": {
"inverted": false,
"value": "ResetTimer"
},
"parameters": [
"",
"\"DirectionChange\""
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "SetAngle"
},
"parameters": [
"NewObject",
"=",
"Random(360)"
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "SetAngle"
},
"parameters": [
"NewObject2",
"=",
"Random(360)"
],
"subInstructions": []
}
],
"events": []
},
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [],
"actions": [
{
"type": {
"inverted": false,
"value": "AddForceAL"
},
"parameters": [
"NewObject",
"NewObject.Angle()",
"30",
""
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "AddForceAL"
},
"parameters": [
"NewObject2",
"NewObject2.Angle()",
"30",
""
],
"subInstructions": []
}
],
"events": []
},
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [
{
"type": {
"inverted": false,
"value": "Distance"
},
"parameters": [
"NewObject2",
"NewObject",
"10",
""
],
"subInstructions": []
}
],
"actions": [
{
"type": {
"inverted": false,
"value": "ChangeColor"
},
"parameters": [
"NewObject2",
"\"71;231;0\""
],
"subInstructions": []
}
],
"events": []
},
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [
{
"type": {
"inverted": true,
"value": "Distance"
},
"parameters": [
"NewObject2",
"NewObject",
"10",
""
],
"subInstructions": []
}
],
"actions": [
{
"type": {
"inverted": false,
"value": "ChangeColor"
},
"parameters": [
"NewObject2",
"\"255;255;255\""
],
"subInstructions": []
}
],
"events": []
},
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [],
"actions": [
{
"type": {
"inverted": false,
"value": "MettreXY"
},
"parameters": [
"NewObject3",
"=",
"MouseX()",
"=",
"MouseY()"
],
"subInstructions": []
}
],
"events": []
}
],
"layers": [
{
"name": "",
"visibility": true,
"cameras": [
{
"defaultSize": true,
"defaultViewport": true,
"height": 0,
"viewportBottom": 1,
"viewportLeft": 0,
"viewportRight": 1,
"viewportTop": 0,
"width": 0
}
],
"effects": []
}
],
"behaviorsSharedData": []
}
],
"externalEvents": [],
"eventsFunctionsExtensions": [],
"externalLayouts": [],
"externalSourceFiles": []
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 B

View File

@@ -0,0 +1,555 @@
{
"firstLayout": "",
"gdVersion": {
"build": 98,
"major": 4,
"minor": 0,
"revision": 0
},
"properties": {
"adMobAppId": "",
"folderProject": false,
"linuxExecutableFilename": "",
"macExecutableFilename": "",
"orientation": "landscape",
"packageName": "com.example.gamename",
"projectFile": "/Users/florian/Projects/F/GD/GDJS/tests/games/object-positions-manager-benchmarks/Point inside object benchmark.json",
"scaleMode": "linear",
"sizeOnStartupMode": "adaptWidth",
"useExternalSourceFiles": false,
"version": "1.0.0",
"winExecutableFilename": "",
"winExecutableIconFile": "",
"name": "Project",
"author": "",
"windowWidth": 800,
"windowHeight": 600,
"latestCompilationDirectory": "",
"maxFPS": 60,
"minFPS": 20,
"verticalSync": false,
"platformSpecificAssets": {},
"loadingScreen": {
"showGDevelopSplash": true
},
"extensions": [
{
"name": "BuiltinObject"
},
{
"name": "BuiltinAudio"
},
{
"name": "BuiltinVariables"
},
{
"name": "BuiltinTime"
},
{
"name": "BuiltinMouse"
},
{
"name": "BuiltinKeyboard"
},
{
"name": "BuiltinJoystick"
},
{
"name": "BuiltinCamera"
},
{
"name": "BuiltinWindow"
},
{
"name": "BuiltinFile"
},
{
"name": "BuiltinNetwork"
},
{
"name": "BuiltinScene"
},
{
"name": "BuiltinAdvanced"
},
{
"name": "Sprite"
},
{
"name": "BuiltinCommonInstructions"
},
{
"name": "BuiltinCommonConversions"
},
{
"name": "BuiltinStringInstructions"
},
{
"name": "BuiltinMathematicalTools"
},
{
"name": "BuiltinExternalLayouts"
}
],
"platforms": [
{
"name": "GDevelop JS platform"
}
],
"currentPlatform": "GDevelop JS platform"
},
"resources": {
"resources": [
{
"alwaysLoaded": false,
"file": "NewObject-1.png",
"kind": "image",
"metadata": "",
"name": "NewObject-1.png",
"smoothed": true,
"userAdded": true
},
{
"alwaysLoaded": false,
"file": "NewObject2-1.png",
"kind": "image",
"metadata": "",
"name": "NewObject2-1.png",
"smoothed": true,
"userAdded": true
},
{
"alwaysLoaded": false,
"file": "NewObject3-1.png",
"kind": "image",
"metadata": "",
"name": "NewObject3-1.png",
"smoothed": true,
"userAdded": false
}
],
"resourceFolders": []
},
"objects": [],
"objectsGroups": [],
"variables": [],
"layouts": [
{
"b": 209,
"disableInputWhenNotFocused": true,
"mangledName": "NewScene",
"name": "NewScene",
"oglFOV": 90,
"oglZFar": 500,
"oglZNear": 1,
"r": 209,
"standardSortMethod": true,
"stopSoundsOnStartup": true,
"title": "",
"v": 209,
"uiSettings": {
"grid": false,
"gridB": 255,
"gridG": 180,
"gridHeight": 32,
"gridOffsetX": 0,
"gridOffsetY": 0,
"gridR": 158,
"gridWidth": 32,
"snap": true,
"windowMask": false,
"zoomFactor": 1
},
"objectsGroups": [],
"variables": [],
"instances": [
{
"angle": 0,
"customSize": false,
"height": 0,
"layer": "",
"locked": false,
"name": "NewObject3",
"width": 0,
"x": 689,
"y": 110,
"zOrder": 1,
"numberProperties": [],
"stringProperties": [],
"initialVariables": []
}
],
"objects": [
{
"name": "NewObject",
"tags": "",
"type": "Sprite",
"updateIfNotVisible": false,
"variables": [],
"behaviors": [],
"animations": [
{
"name": "NewObject",
"useMultipleDirections": false,
"directions": [
{
"looping": false,
"timeBetweenFrames": 0.08,
"sprites": [
{
"hasCustomCollisionMask": false,
"image": "NewObject-1.png",
"points": [],
"originPoint": {
"name": "origine",
"x": 0,
"y": 0
},
"centerPoint": {
"automatic": true,
"name": "centre",
"x": 0,
"y": 0
},
"customCollisionMask": []
}
]
}
]
}
]
},
{
"name": "NewObject2",
"tags": "",
"type": "Sprite",
"updateIfNotVisible": false,
"variables": [],
"behaviors": [],
"animations": [
{
"name": "NewObject2",
"useMultipleDirections": false,
"directions": [
{
"looping": false,
"timeBetweenFrames": 0.08,
"sprites": [
{
"hasCustomCollisionMask": false,
"image": "NewObject2-1.png",
"points": [],
"originPoint": {
"name": "origine",
"x": 0,
"y": 0
},
"centerPoint": {
"automatic": true,
"name": "centre",
"x": 0,
"y": 0
},
"customCollisionMask": []
}
]
}
]
}
]
},
{
"name": "NewObject3",
"tags": "",
"type": "Sprite",
"updateIfNotVisible": false,
"variables": [],
"behaviors": [],
"animations": [
{
"name": "NewObject3",
"useMultipleDirections": false,
"directions": [
{
"looping": false,
"timeBetweenFrames": 0.08,
"sprites": [
{
"hasCustomCollisionMask": false,
"image": "NewObject3-1.png",
"points": [],
"originPoint": {
"name": "origine",
"x": 0,
"y": 0
},
"centerPoint": {
"automatic": true,
"name": "centre",
"x": 0,
"y": 0
},
"customCollisionMask": []
}
]
}
]
}
]
}
],
"events": [
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [
{
"type": {
"inverted": false,
"value": "DepartScene"
},
"parameters": [
""
],
"subInstructions": []
}
],
"actions": [],
"events": [
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Repeat",
"repeatExpression": "700",
"conditions": [],
"actions": [
{
"type": {
"inverted": false,
"value": "Create"
},
"parameters": [
"",
"NewObject",
"Random(800)",
"Random(600)",
""
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "Create"
},
"parameters": [
"",
"NewObject2",
"Random(800)",
"Random(600)",
""
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "ChangeScale"
},
"parameters": [
"NewObject",
"=",
"0.3"
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "ChangeScale"
},
"parameters": [
"NewObject2",
"=",
"0.3"
],
"subInstructions": []
}
],
"events": []
}
]
},
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [
{
"type": {
"inverted": false,
"value": "Timer"
},
"parameters": [
"",
"1",
"\"DirectionChange\""
],
"subInstructions": []
}
],
"actions": [
{
"type": {
"inverted": false,
"value": "ResetTimer"
},
"parameters": [
"",
"\"DirectionChange\""
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "SetAngle"
},
"parameters": [
"NewObject2",
"=",
"Random(360)"
],
"subInstructions": []
}
],
"events": []
},
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [],
"actions": [
{
"type": {
"inverted": false,
"value": "AddForceAL"
},
"parameters": [
"NewObject2",
"NewObject2.Angle()",
"30",
""
],
"subInstructions": []
}
],
"events": []
},
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [],
"actions": [
{
"type": {
"inverted": false,
"value": "ChangeColor"
},
"parameters": [
"NewObject2",
"\"255;255;255\""
],
"subInstructions": []
}
],
"events": []
},
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::ForEach",
"object": "NewObject",
"conditions": [
{
"type": {
"inverted": false,
"value": "CollisionPoint"
},
"parameters": [
"NewObject2",
"NewObject.PointX(\"Center\")",
"NewObject.PointY(\"Center\")"
],
"subInstructions": []
}
],
"actions": [
{
"type": {
"inverted": false,
"value": "ChangeColor"
},
"parameters": [
"NewObject2",
"\"71;231;0\""
],
"subInstructions": []
}
],
"events": []
},
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [],
"actions": [
{
"type": {
"inverted": false,
"value": "MettreXY"
},
"parameters": [
"NewObject3",
"=",
"MouseX()",
"=",
"MouseY()"
],
"subInstructions": []
}
],
"events": []
}
],
"layers": [
{
"name": "",
"visibility": true,
"cameras": [
{
"defaultSize": true,
"defaultViewport": true,
"height": 0,
"viewportBottom": 1,
"viewportLeft": 0,
"viewportRight": 1,
"viewportTop": 0,
"width": 0
}
],
"effects": []
}
],
"behaviorsSharedData": []
}
],
"externalEvents": [],
"eventsFunctionsExtensions": [],
"externalLayouts": [],
"externalSourceFiles": []
}

View File

@@ -0,0 +1,576 @@
{
"firstLayout": "",
"gdVersion": {
"build": 98,
"major": 4,
"minor": 0,
"revision": 0
},
"properties": {
"adMobAppId": "",
"adaptGameResolutionAtRuntime": false,
"folderProject": false,
"linuxExecutableFilename": "",
"macExecutableFilename": "",
"orientation": "landscape",
"packageName": "com.example.gamename",
"projectFile": "/Users/florian/Projects/F/GD/GDJS/tests/games/object-positions-manager-benchmarks/Raycast benchmark.json",
"scaleMode": "linear",
"sizeOnStartupMode": "adaptWidth",
"useExternalSourceFiles": false,
"version": "1.0.0",
"winExecutableFilename": "",
"winExecutableIconFile": "",
"name": "Project",
"author": "",
"windowWidth": 800,
"windowHeight": 600,
"latestCompilationDirectory": "",
"maxFPS": 60,
"minFPS": 20,
"verticalSync": false,
"platformSpecificAssets": {},
"loadingScreen": {
"showGDevelopSplash": true
},
"extensions": [
{
"name": "BuiltinObject"
},
{
"name": "BuiltinAudio"
},
{
"name": "BuiltinVariables"
},
{
"name": "BuiltinTime"
},
{
"name": "BuiltinMouse"
},
{
"name": "BuiltinKeyboard"
},
{
"name": "BuiltinJoystick"
},
{
"name": "BuiltinCamera"
},
{
"name": "BuiltinWindow"
},
{
"name": "BuiltinFile"
},
{
"name": "BuiltinNetwork"
},
{
"name": "BuiltinScene"
},
{
"name": "BuiltinAdvanced"
},
{
"name": "Sprite"
},
{
"name": "BuiltinCommonInstructions"
},
{
"name": "BuiltinCommonConversions"
},
{
"name": "BuiltinStringInstructions"
},
{
"name": "BuiltinMathematicalTools"
},
{
"name": "BuiltinExternalLayouts"
}
],
"platforms": [
{
"name": "GDevelop JS platform"
}
],
"currentPlatform": "GDevelop JS platform"
},
"resources": {
"resources": [
{
"alwaysLoaded": false,
"file": "NewObject-1.png",
"kind": "image",
"metadata": "",
"name": "NewObject-1.png",
"smoothed": true,
"userAdded": true
},
{
"alwaysLoaded": false,
"file": "NewObject2-1.png",
"kind": "image",
"metadata": "",
"name": "NewObject2-1.png",
"smoothed": true,
"userAdded": true
},
{
"alwaysLoaded": false,
"file": "NewObject3-1.png",
"kind": "image",
"metadata": "",
"name": "NewObject3-1.png",
"smoothed": true,
"userAdded": false
}
],
"resourceFolders": []
},
"objects": [],
"objectsGroups": [],
"variables": [],
"layouts": [
{
"b": 209,
"disableInputWhenNotFocused": true,
"mangledName": "NewScene",
"name": "NewScene",
"oglFOV": 90,
"oglZFar": 500,
"oglZNear": 1,
"r": 209,
"standardSortMethod": true,
"stopSoundsOnStartup": true,
"title": "",
"v": 209,
"uiSettings": {
"grid": false,
"gridB": 255,
"gridG": 180,
"gridHeight": 32,
"gridOffsetX": 0,
"gridOffsetY": 0,
"gridR": 158,
"gridWidth": 32,
"snap": true,
"windowMask": false,
"zoomFactor": 1
},
"objectsGroups": [],
"variables": [],
"instances": [],
"objects": [
{
"name": "RayLauncher",
"tags": "",
"type": "Sprite",
"updateIfNotVisible": false,
"variables": [],
"behaviors": [],
"animations": [
{
"name": "NewObject",
"useMultipleDirections": false,
"directions": [
{
"looping": false,
"timeBetweenFrames": 0.08,
"sprites": [
{
"hasCustomCollisionMask": false,
"image": "NewObject-1.png",
"points": [],
"originPoint": {
"name": "origine",
"x": 0,
"y": 0
},
"centerPoint": {
"automatic": true,
"name": "centre",
"x": 0,
"y": 0
},
"customCollisionMask": []
}
]
}
]
}
]
},
{
"name": "RayObstacle",
"tags": "",
"type": "Sprite",
"updateIfNotVisible": false,
"variables": [],
"behaviors": [],
"animations": [
{
"name": "NewObject2",
"useMultipleDirections": false,
"directions": [
{
"looping": false,
"timeBetweenFrames": 0.08,
"sprites": [
{
"hasCustomCollisionMask": false,
"image": "NewObject2-1.png",
"points": [],
"originPoint": {
"name": "origine",
"x": 0,
"y": 0
},
"centerPoint": {
"automatic": true,
"name": "centre",
"x": 0,
"y": 0
},
"customCollisionMask": []
}
]
}
]
}
]
},
{
"name": "RayVisualizer",
"tags": "",
"type": "Sprite",
"updateIfNotVisible": false,
"variables": [],
"behaviors": [],
"animations": [
{
"name": "NewObject3",
"useMultipleDirections": false,
"directions": [
{
"looping": false,
"timeBetweenFrames": 0.08,
"sprites": [
{
"hasCustomCollisionMask": false,
"image": "NewObject3-1.png",
"points": [],
"originPoint": {
"name": "origine",
"x": 32,
"y": 32
},
"centerPoint": {
"automatic": true,
"name": "centre",
"x": 0,
"y": 0
},
"customCollisionMask": []
}
]
}
]
}
]
}
],
"events": [
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Comment",
"color": {
"b": 109,
"g": 230,
"r": 255,
"textB": 0,
"textG": 0,
"textR": 0
},
"comment": "Send a ray from every \"RayLauncher\" (on the left) against RayObstacel (on the right).",
"comment2": ""
},
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [
{
"type": {
"inverted": false,
"value": "DepartScene"
},
"parameters": [
""
],
"subInstructions": []
}
],
"actions": [],
"events": [
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Repeat",
"repeatExpression": "700",
"conditions": [],
"actions": [
{
"type": {
"inverted": false,
"value": "Create"
},
"parameters": [
"",
"RayLauncher",
"Random(300)",
"RandomInRange(-2000, 2000)",
""
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "Create"
},
"parameters": [
"",
"RayObstacle",
"RandomInRange(500, 800)",
"RandomInRange(-2000, 2000)",
""
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "ChangeScale"
},
"parameters": [
"RayLauncher",
"=",
"0.3"
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "ChangeScale"
},
"parameters": [
"RayObstacle",
"=",
"0.3"
],
"subInstructions": []
}
],
"events": []
}
]
},
{
"disabled": true,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [
{
"type": {
"inverted": false,
"value": "Timer"
},
"parameters": [
"",
"1",
"\"DirectionChange\""
],
"subInstructions": []
}
],
"actions": [
{
"type": {
"inverted": false,
"value": "ResetTimer"
},
"parameters": [
"",
"\"DirectionChange\""
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "SetAngle"
},
"parameters": [
"RayLauncher",
"=",
"Random(360)"
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "SetAngle"
},
"parameters": [
"RayObstacle",
"=",
"Random(360)"
],
"subInstructions": []
}
],
"events": []
},
{
"disabled": true,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [],
"actions": [
{
"type": {
"inverted": false,
"value": "AddForceAL"
},
"parameters": [
"RayLauncher",
"RayLauncher.Angle()",
"30",
""
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "AddForceAL"
},
"parameters": [
"RayObstacle",
"RayObstacle.Angle()",
"30",
""
],
"subInstructions": []
}
],
"events": []
},
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [],
"actions": [
{
"type": {
"inverted": false,
"value": "ChangeColor"
},
"parameters": [
"RayObstacle",
"\"255;255;255\""
],
"subInstructions": []
}
],
"events": []
},
{
"colorB": 228,
"colorG": 176,
"colorR": 74,
"creationTime": 0,
"disabled": false,
"folded": false,
"name": "Raycast",
"source": "",
"type": "BuiltinCommonInstructions::Group",
"events": [
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::ForEach",
"object": "RayLauncher",
"conditions": [
{
"type": {
"inverted": false,
"value": "Raycast"
},
"parameters": [
"RayObstacle",
"RayLauncher.X()",
"RayLauncher.Y()",
"0",
"800",
"rayEndX",
"rayEndY",
""
],
"subInstructions": []
}
],
"actions": [
{
"type": {
"inverted": false,
"value": "ChangeColor"
},
"parameters": [
"RayObstacle",
"\"42;255;0\""
],
"subInstructions": []
}
],
"events": []
}
],
"parameters": []
}
],
"layers": [
{
"name": "",
"visibility": true,
"cameras": [
{
"defaultSize": true,
"defaultViewport": true,
"height": 0,
"viewportBottom": 1,
"viewportLeft": 0,
"viewportRight": 1,
"viewportTop": 0,
"width": 0
}
],
"effects": []
}
],
"behaviorsSharedData": []
}
],
"externalEvents": [],
"eventsFunctionsExtensions": [],
"externalLayouts": [],
"externalSourceFiles": []
}

View File

@@ -0,0 +1,559 @@
{
"firstLayout": "",
"gdVersion": {
"build": 98,
"major": 4,
"minor": 0,
"revision": 0
},
"properties": {
"adMobAppId": "",
"folderProject": false,
"linuxExecutableFilename": "",
"macExecutableFilename": "",
"orientation": "landscape",
"packageName": "com.example.gamename",
"projectFile": "/Users/florian/Projects/F/GD/GDJS/tests/games/object-positions-manager-benchmarks/Separate objects benchmark.json",
"scaleMode": "linear",
"sizeOnStartupMode": "adaptWidth",
"useExternalSourceFiles": false,
"version": "1.0.0",
"winExecutableFilename": "",
"winExecutableIconFile": "",
"name": "Project",
"author": "",
"windowWidth": 800,
"windowHeight": 600,
"latestCompilationDirectory": "",
"maxFPS": 60,
"minFPS": 20,
"verticalSync": false,
"platformSpecificAssets": {},
"loadingScreen": {
"showGDevelopSplash": true
},
"extensions": [
{
"name": "BuiltinObject"
},
{
"name": "BuiltinAudio"
},
{
"name": "BuiltinVariables"
},
{
"name": "BuiltinTime"
},
{
"name": "BuiltinMouse"
},
{
"name": "BuiltinKeyboard"
},
{
"name": "BuiltinJoystick"
},
{
"name": "BuiltinCamera"
},
{
"name": "BuiltinWindow"
},
{
"name": "BuiltinFile"
},
{
"name": "BuiltinNetwork"
},
{
"name": "BuiltinScene"
},
{
"name": "BuiltinAdvanced"
},
{
"name": "Sprite"
},
{
"name": "BuiltinCommonInstructions"
},
{
"name": "BuiltinCommonConversions"
},
{
"name": "BuiltinStringInstructions"
},
{
"name": "BuiltinMathematicalTools"
},
{
"name": "BuiltinExternalLayouts"
}
],
"platforms": [
{
"name": "GDevelop JS platform"
}
],
"currentPlatform": "GDevelop JS platform"
},
"resources": {
"resources": [
{
"alwaysLoaded": false,
"file": "NewObject-1.png",
"kind": "image",
"metadata": "",
"name": "NewObject-1.png",
"smoothed": true,
"userAdded": true
},
{
"alwaysLoaded": false,
"file": "NewObject2-1.png",
"kind": "image",
"metadata": "",
"name": "NewObject2-1.png",
"smoothed": true,
"userAdded": true
},
{
"alwaysLoaded": false,
"file": "NewObject3-1.png",
"kind": "image",
"metadata": "",
"name": "NewObject3-1.png",
"smoothed": true,
"userAdded": false
}
],
"resourceFolders": []
},
"objects": [],
"objectsGroups": [],
"variables": [],
"layouts": [
{
"b": 209,
"disableInputWhenNotFocused": true,
"mangledName": "NewScene",
"name": "NewScene",
"oglFOV": 90,
"oglZFar": 500,
"oglZNear": 1,
"r": 209,
"standardSortMethod": true,
"stopSoundsOnStartup": true,
"title": "",
"v": 209,
"uiSettings": {
"grid": false,
"gridB": 255,
"gridG": 180,
"gridHeight": 32,
"gridOffsetX": 0,
"gridOffsetY": 0,
"gridR": 158,
"gridWidth": 32,
"snap": true,
"windowMask": false,
"zoomFactor": 1
},
"objectsGroups": [],
"variables": [],
"instances": [
{
"angle": 0,
"customSize": false,
"height": 0,
"layer": "",
"locked": false,
"name": "NewObject3",
"width": 0,
"x": 689,
"y": 110,
"zOrder": 1,
"numberProperties": [],
"stringProperties": [],
"initialVariables": []
}
],
"objects": [
{
"name": "NewObject",
"tags": "",
"type": "Sprite",
"updateIfNotVisible": false,
"variables": [],
"behaviors": [],
"animations": [
{
"name": "NewObject",
"useMultipleDirections": false,
"directions": [
{
"looping": false,
"timeBetweenFrames": 0.08,
"sprites": [
{
"hasCustomCollisionMask": false,
"image": "NewObject-1.png",
"points": [],
"originPoint": {
"name": "origine",
"x": 0,
"y": 0
},
"centerPoint": {
"automatic": true,
"name": "centre",
"x": 0,
"y": 0
},
"customCollisionMask": []
}
]
}
]
}
]
},
{
"name": "NewObject2",
"tags": "",
"type": "Sprite",
"updateIfNotVisible": false,
"variables": [],
"behaviors": [],
"animations": [
{
"name": "NewObject2",
"useMultipleDirections": false,
"directions": [
{
"looping": false,
"timeBetweenFrames": 0.08,
"sprites": [
{
"hasCustomCollisionMask": false,
"image": "NewObject2-1.png",
"points": [],
"originPoint": {
"name": "origine",
"x": 0,
"y": 0
},
"centerPoint": {
"automatic": true,
"name": "centre",
"x": 0,
"y": 0
},
"customCollisionMask": []
}
]
}
]
}
]
},
{
"name": "NewObject3",
"tags": "",
"type": "Sprite",
"updateIfNotVisible": false,
"variables": [],
"behaviors": [],
"animations": [
{
"name": "NewObject3",
"useMultipleDirections": false,
"directions": [
{
"looping": false,
"timeBetweenFrames": 0.08,
"sprites": [
{
"hasCustomCollisionMask": false,
"image": "NewObject3-1.png",
"points": [],
"originPoint": {
"name": "origine",
"x": 0,
"y": 0
},
"centerPoint": {
"automatic": true,
"name": "centre",
"x": 0,
"y": 0
},
"customCollisionMask": []
}
]
}
]
}
]
}
],
"events": [
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [
{
"type": {
"inverted": false,
"value": "DepartScene"
},
"parameters": [
""
],
"subInstructions": []
}
],
"actions": [],
"events": [
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Repeat",
"repeatExpression": "700",
"conditions": [],
"actions": [
{
"type": {
"inverted": false,
"value": "Create"
},
"parameters": [
"",
"NewObject",
"Random(800)",
"Random(600)",
""
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "Create"
},
"parameters": [
"",
"NewObject2",
"Random(800)",
"Random(600)",
""
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "ChangeScale"
},
"parameters": [
"NewObject",
"=",
"0.3"
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "ChangeScale"
},
"parameters": [
"NewObject2",
"=",
"0.3"
],
"subInstructions": []
}
],
"events": []
}
]
},
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [
{
"type": {
"inverted": false,
"value": "Timer"
},
"parameters": [
"",
"1",
"\"DirectionChange\""
],
"subInstructions": []
}
],
"actions": [
{
"type": {
"inverted": false,
"value": "ResetTimer"
},
"parameters": [
"",
"\"DirectionChange\""
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "SetAngle"
},
"parameters": [
"NewObject",
"=",
"Random(360)"
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "SetAngle"
},
"parameters": [
"NewObject2",
"=",
"Random(360)"
],
"subInstructions": []
}
],
"events": []
},
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [],
"actions": [
{
"type": {
"inverted": false,
"value": "AddForceAL"
},
"parameters": [
"NewObject",
"NewObject.Angle()",
"30",
""
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "AddForceAL"
},
"parameters": [
"NewObject2",
"NewObject2.Angle()",
"30",
""
],
"subInstructions": []
}
],
"events": []
},
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [],
"actions": [
{
"type": {
"inverted": false,
"value": "SeparateFromObjects"
},
"parameters": [
"NewObject",
"NewObject2",
""
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "SeparateFromObjects"
},
"parameters": [
"NewObject2",
"NewObject2",
""
],
"subInstructions": []
}
],
"events": []
},
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [],
"actions": [
{
"type": {
"inverted": false,
"value": "MettreXY"
},
"parameters": [
"NewObject3",
"=",
"MouseX()",
"=",
"MouseY()"
],
"subInstructions": []
}
],
"events": []
}
],
"layers": [
{
"name": "",
"visibility": true,
"cameras": [
{
"defaultSize": true,
"defaultViewport": true,
"height": 0,
"viewportBottom": 1,
"viewportLeft": 0,
"viewportRight": 1,
"viewportTop": 0,
"width": 0
}
],
"effects": []
}
],
"behaviorsSharedData": []
}
],
"externalEvents": [],
"eventsFunctionsExtensions": [],
"externalLayouts": [],
"externalSourceFiles": []
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

View File

@@ -19,6 +19,7 @@ module.exports = function(config) {
'../Runtime/fontfaceobserver-font-manager/fontfaceobserver-font-manager.js',
'../Runtime/jsonmanager.js',
'../Runtime/timemanager.js',
'../Runtime/objectpositionsmanager.js',
'../Runtime/runtimeobject.js',
'../Runtime/runtimescene.js',
'../Runtime/scenestack.js',

View File

@@ -1,140 +1,250 @@
// @ts-check
/**
* Tests for gdjs.InputManager and related.
*/
describe('gdjs.InputManager', function() {
var inputManager = new gdjs.InputManager();
var inputManager = new gdjs.InputManager();
it('should handle keyboards events', function(){
expect(inputManager.anyKeyPressed()).to.be(false);
it('should handle keyboards events', function() {
expect(inputManager.anyKeyPressed()).to.be(false);
inputManager.onKeyPressed(32);
expect(inputManager.getLastPressedKey()).to.be(32);
inputManager.onKeyPressed(33);
expect(inputManager.getLastPressedKey()).to.be(33);
expect(inputManager.isKeyPressed(32)).to.be(true);
expect(inputManager.isKeyPressed(30)).to.be(false);
inputManager.onKeyReleased(32);
expect(inputManager.isKeyPressed(32)).to.be(false);
expect(inputManager.wasKeyReleased(32)).to.be(true);
inputManager.onKeyPressed(32);
expect(inputManager.getLastPressedKey()).to.be(32);
inputManager.onKeyPressed(33);
expect(inputManager.getLastPressedKey()).to.be(33);
expect(inputManager.isKeyPressed(32)).to.be(true);
expect(inputManager.isKeyPressed(30)).to.be(false);
inputManager.onKeyReleased(32);
expect(inputManager.isKeyPressed(32)).to.be(false);
expect(inputManager.wasKeyReleased(32)).to.be(true);
expect(inputManager.anyKeyPressed()).to.be(true);
expect(inputManager.anyKeyPressed()).to.be(true);
inputManager.onFrameEnded();
expect(inputManager.wasKeyReleased(32)).to.be(false);
inputManager.onFrameEnded();
expect(inputManager.wasKeyReleased(32)).to.be(false);
expect(inputManager.anyKeyPressed()).to.be(true);
expect(inputManager.isKeyPressed(33)).to.be(true);
expect(inputManager.anyKeyPressed()).to.be(true);
expect(inputManager.isKeyPressed(33)).to.be(true);
inputManager.onFrameEnded();
inputManager.onKeyReleased(33);
expect(inputManager.wasKeyReleased(33)).to.be(true);
expect(inputManager.anyKeyPressed()).to.be(false);
inputManager.onFrameEnded();
inputManager.onKeyReleased(33);
expect(inputManager.wasKeyReleased(33)).to.be(true);
expect(inputManager.anyKeyPressed()).to.be(false);
});
});
it('should handle mouse events', function() {
inputManager.onMouseMove(500, 600);
expect(inputManager.getMouseX()).to.be(500);
expect(inputManager.getMouseY()).to.be(600);
it('should handle mouse events', function(){
inputManager.onMouseMove(500, 600);
expect(inputManager.getMouseX()).to.be(500);
expect(inputManager.getMouseY()).to.be(600);
expect(
inputManager.isMouseButtonPressed(gdjs.InputManager.MOUSE_LEFT_BUTTON)
).to.be(false);
expect(
inputManager.isMouseButtonReleased(gdjs.InputManager.MOUSE_LEFT_BUTTON)
).to.be(false);
inputManager.onMouseButtonPressed(gdjs.InputManager.MOUSE_LEFT_BUTTON);
expect(
inputManager.isMouseButtonPressed(gdjs.InputManager.MOUSE_LEFT_BUTTON)
).to.be(true);
expect(
inputManager.isMouseButtonReleased(gdjs.InputManager.MOUSE_LEFT_BUTTON)
).to.be(false);
inputManager.onFrameEnded();
expect(inputManager.isMouseButtonPressed(gdjs.InputManager.MOUSE_LEFT_BUTTON)).to.be(false);
expect(inputManager.isMouseButtonReleased(gdjs.InputManager.MOUSE_LEFT_BUTTON)).to.be(false);
inputManager.onMouseButtonPressed(gdjs.InputManager.MOUSE_LEFT_BUTTON);
expect(inputManager.isMouseButtonPressed(gdjs.InputManager.MOUSE_LEFT_BUTTON)).to.be(true);
expect(inputManager.isMouseButtonReleased(gdjs.InputManager.MOUSE_LEFT_BUTTON)).to.be(false);
inputManager.onFrameEnded();
inputManager.onMouseButtonReleased(gdjs.InputManager.MOUSE_LEFT_BUTTON);
expect(
inputManager.isMouseButtonPressed(gdjs.InputManager.MOUSE_LEFT_BUTTON)
).to.be(false);
expect(
inputManager.isMouseButtonReleased(gdjs.InputManager.MOUSE_LEFT_BUTTON)
).to.be(true);
inputManager.onFrameEnded();
inputManager.onMouseButtonReleased(gdjs.InputManager.MOUSE_LEFT_BUTTON);
expect(inputManager.isMouseButtonPressed(gdjs.InputManager.MOUSE_LEFT_BUTTON)).to.be(false);
expect(inputManager.isMouseButtonReleased(gdjs.InputManager.MOUSE_LEFT_BUTTON)).to.be(true);
inputManager.onFrameEnded();
expect(
inputManager.isMouseButtonPressed(gdjs.InputManager.MOUSE_LEFT_BUTTON)
).to.be(false);
expect(
inputManager.isMouseButtonReleased(gdjs.InputManager.MOUSE_LEFT_BUTTON)
).to.be(false);
});
expect(inputManager.isMouseButtonPressed(gdjs.InputManager.MOUSE_LEFT_BUTTON)).to.be(false);
expect(inputManager.isMouseButtonReleased(gdjs.InputManager.MOUSE_LEFT_BUTTON)).to.be(false);
});
it('should handle touch events', function() {
inputManager.onTouchStart(46, 510, 610);
inputManager.onTouchStart(10, 510, 610);
expect(inputManager.getStartedTouchIdentifiers()).to.have.length(2);
expect(inputManager.getTouchX(46)).to.be(510);
expect(inputManager.getTouchY(46)).to.be(610);
it('should handle touch events', function(){
inputManager.onTouchStart(46, 510, 610);
inputManager.onTouchStart(10, 510, 610);
expect(inputManager.getStartedTouchIdentifiers()).to.have.length(2);
expect(inputManager.getTouchX(46)).to.be(510);
expect(inputManager.getTouchY(46)).to.be(610);
expect(inputManager.popStartedTouch()).to.be(46);
expect(inputManager.popStartedTouch()).to.be(10);
expect(inputManager.popEndedTouch()).to.be(undefined);
expect(inputManager.popStartedTouch()).to.be(46);
expect(inputManager.popStartedTouch()).to.be(10);
expect(inputManager.popEndedTouch()).to.be(undefined);
inputManager.onFrameEnded();
inputManager.onTouchEnd(10);
expect(inputManager.getAllTouchIdentifiers()).to.have.length(2);
expect(inputManager.getStartedTouchIdentifiers()).to.have.length(0);
expect(inputManager.popStartedTouch()).to.be(undefined);
expect(inputManager.popEndedTouch()).to.be(10);
expect(inputManager.getTouchX(10)).to.be(510);
expect(inputManager.getTouchY(10)).to.be(610);
inputManager.onFrameEnded();
inputManager.onTouchEnd(10);
expect(inputManager.getAllTouchIdentifiers()).to.have.length(2);
expect(inputManager.getStartedTouchIdentifiers()).to.have.length(0);
expect(inputManager.popStartedTouch()).to.be(undefined);
expect(inputManager.popEndedTouch()).to.be(10);
expect(inputManager.getTouchX(10)).to.be(510);
expect(inputManager.getTouchY(10)).to.be(610);
inputManager.onFrameEnded();
expect(inputManager.getAllTouchIdentifiers()).to.have.length(1);
});
it('should simulate (or not) mouse events', function() {
inputManager.touchSimulateMouse();
expect(inputManager.isMouseButtonPressed(0)).to.be(false);
inputManager.onTouchStart(46, 510, 610);
expect(inputManager.isMouseButtonPressed(0)).to.be(true);
expect(inputManager.getMouseX()).to.be(510);
expect(inputManager.getMouseY()).to.be(610);
inputManager.onTouchMove(46, 520, 620);
expect(inputManager.getMouseX()).to.be(520);
expect(inputManager.getMouseY()).to.be(620);
inputManager.onTouchEnd(46);
expect(inputManager.isMouseButtonPressed(0)).to.be(false);
inputManager.onFrameEnded();
expect(inputManager.getAllTouchIdentifiers()).to.have.length(1);
});
it('should simulate (or not) mouse events', function(){
inputManager.touchSimulateMouse();
expect(inputManager.isMouseButtonPressed(0)).to.be(false);
inputManager.onTouchStart(46, 510, 610);
expect(inputManager.isMouseButtonPressed(0)).to.be(true);
expect(inputManager.getMouseX()).to.be(510);
expect(inputManager.getMouseY()).to.be(610);
inputManager.onTouchMove(46, 520, 620);
expect(inputManager.getMouseX()).to.be(520);
expect(inputManager.getMouseY()).to.be(620);
inputManager.onTouchEnd(46);
expect(inputManager.isMouseButtonPressed(0)).to.be(false);
inputManager.touchSimulateMouse(false);
inputManager.onTouchStart(46, 510, 610);
expect(inputManager.isMouseButtonPressed(0)).to.be(false);
expect(inputManager.getMouseX()).to.be(520);
expect(inputManager.getMouseY()).to.be(620);
});
inputManager.touchSimulateMouse(false);
inputManager.onTouchStart(46, 510, 610);
expect(inputManager.isMouseButtonPressed(0)).to.be(false);
expect(inputManager.getMouseX()).to.be(520);
expect(inputManager.getMouseY()).to.be(620);
});
});
describe('gdjs.RuntimeObject.cursorOnObject', function() {
var runtimeGame = new gdjs.RuntimeGame({variables: [], properties: {windowWidth: 800, windowHeight: 600}});
var runtimeScene = new gdjs.RuntimeScene(runtimeGame);
runtimeScene.loadFromScene({
layers:[{name:"", visibility: true}],
variables: [],
behaviorsSharedData: [],
objects: [],
instances: []
});
describe('gdjs.evtTools.input.cursorOnObject', function() {
var runtimeGame = new gdjs.RuntimeGame({
variables: [],
properties: { windowWidth: 800, windowHeight: 600 },
});
var runtimeScene = new gdjs.RuntimeScene(runtimeGame);
runtimeScene.loadFromScene({
layers: [{ name: '', visibility: true }],
variables: [],
behaviorsSharedData: [],
objects: [],
instances: [],
});
var object = new gdjs.RuntimeObject(runtimeScene, {name: "obj1", type: "", behaviors: []});
object.setPosition(450, 500);
var object = new gdjs.RuntimeObject(runtimeScene, {
name: 'obj1',
type: '',
behaviors: [],
variables: [],
});
object.setPosition(450, 500);
object.getWidth = function() {
return 5;
};
object.getHeight = function() {
return 5;
};
it('should handle mouse', function() {
runtimeGame.getInputManager().onMouseMove(100, 100);
expect(object.cursorOnObject(runtimeScene)).to.be(false);
runtimeGame.getInputManager().onMouseMove(450, 500);
expect(object.cursorOnObject(runtimeScene)).to.be(true);
});
it('should handle mouse', function() {
var objectsLists = new Hashtable();
objectsLists.put('obj1', [object]);
runtimeGame.getInputManager().onMouseMove(100, 100);
expect(
gdjs.evtTools.input.cursorOnObject(
objectsLists,
runtimeScene,
true,
false
)
).to.be(false);
expect(objectsLists.get('obj1')).to.have.length(0);
it('should handle touch', function() {
runtimeGame.getInputManager().onMouseMove(0, 0);
runtimeGame.getInputManager().touchSimulateMouse(false);
objectsLists.put('obj1', [object]);
runtimeGame.getInputManager().onMouseMove(450, 500);
expect(
gdjs.evtTools.input.cursorOnObject(
objectsLists,
runtimeScene,
true,
false
)
).to.be(true);
expect(objectsLists.get('obj1')).to.have.length(1);
expect(objectsLists.get('obj1')[0]).to.be(object);
});
runtimeGame.getInputManager().onTouchStart(0, 100, 100);
expect(object.cursorOnObject(runtimeScene)).to.be(false);
runtimeGame.getInputManager().onFrameEnded();
it('should handle inversion of the test', function() {
var objectsLists = new Hashtable();
objectsLists.put('obj1', [object]);
runtimeGame.getInputManager().onMouseMove(100, 100);
expect(
gdjs.evtTools.input.cursorOnObject(objectsLists, runtimeScene, true, true)
).to.be(true);
expect(objectsLists.get('obj1')).to.have.length(1);
expect(objectsLists.get('obj1')[0]).to.be(object);
runtimeGame.getInputManager().onTouchStart(1, 450, 500);
expect(object.cursorOnObject(runtimeScene)).to.be(true);
runtimeGame.getInputManager().onFrameEnded();
objectsLists.put('obj1', [object]);
runtimeGame.getInputManager().onMouseMove(450, 500);
expect(
gdjs.evtTools.input.cursorOnObject(objectsLists, runtimeScene, true, true)
).to.be(false);
expect(objectsLists.get('obj1')).to.have.length(0);
});
runtimeGame.getInputManager().onTouchEnd(1);
expect(object.cursorOnObject(runtimeScene)).to.be(true);
runtimeGame.getInputManager().onFrameEnded();
it('should handle touch', function() {
var objectsLists = new Hashtable();
objectsLists.put('obj1', [object]);
expect(object.cursorOnObject(runtimeScene)).to.be(false);
});
runtimeGame.getInputManager().onMouseMove(0, 0);
runtimeGame.getInputManager().touchSimulateMouse(false);
runtimeGame.getInputManager().onTouchStart(0, 100, 100);
objectsLists.put('obj1', [object]);
expect(
gdjs.evtTools.input.cursorOnObject(
objectsLists,
runtimeScene,
true,
false
)
).to.be(false);
expect(objectsLists.get('obj1')).to.have.length(0);
runtimeGame.getInputManager().onFrameEnded();
objectsLists.put('obj1', [object]);
runtimeGame.getInputManager().onTouchStart(1, 450, 500);
expect(
gdjs.evtTools.input.cursorOnObject(
objectsLists,
runtimeScene,
true,
false
)
).to.be(true);
expect(objectsLists.get('obj1')).to.have.length(1);
expect(objectsLists.get('obj1')[0]).to.be(object);
runtimeGame.getInputManager().onFrameEnded();
runtimeGame.getInputManager().onTouchEnd(1);
expect(
gdjs.evtTools.input.cursorOnObject(
objectsLists,
runtimeScene,
true,
false
)
).to.be(true);
expect(objectsLists.get('obj1')).to.have.length(1);
expect(objectsLists.get('obj1')[0]).to.be(object);
runtimeGame.getInputManager().onFrameEnded();
expect(
gdjs.evtTools.input.cursorOnObject(
objectsLists,
runtimeScene,
true,
false
)
).to.be(false);
expect(objectsLists.get('obj1')).to.have.length(0);
});
});

File diff suppressed because it is too large Load Diff