Last active
December 17, 2015 04:59
-
-
Save hyzhak/5554317 to your computer and use it in GitHub Desktop.
Implementation of cyclic behaviour on darlingjs game engine
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var m = darlingjs.m('ngCyclic'); | |
/** | |
* Marker for entity with cyclic pattern behaviour | |
*/ | |
m.$c('ngCyclic', { | |
/** | |
* PatternWidth, if value <= 0.0 that pattern doesn't cyclic in that direction | |
*/ | |
patternWidth: 0.0, | |
/** | |
* PatternHeight, if value <= 0.0 that pattern doesn't cyclic in that direction | |
*/ | |
patternHeight: 0.0 | |
}); | |
/** | |
* Mark entity by component if it outside the ViewPort | |
*/ | |
m.$c('ngMarkIfOutsideOfTheViewPortVertical2D', { | |
/** | |
* handler callback get $entity and top/bottom edge | |
*/ | |
handler: null, | |
/** | |
* apply component-markers for any $entity that goes outside | |
* can be {string} name of component, or object with key, value | |
* where key is component name, value is config of component | |
*/ | |
marker: null, | |
/** | |
* auto-remove current component | |
*/ | |
autoRemove: true | |
}); | |
/** | |
* Mark entity by component if it outside the ViewPort | |
*/ | |
m.$c('ngMarkIfOutsideOfTheViewPortHorizontal2D', { | |
/** | |
* handler callback get $entity and top/bottom edge | |
*/ | |
handler: null, | |
/** | |
* apply component-markers for any $entity that goes outside | |
* can be {string} name of component, or object with key, value | |
* where key is component name, value is config of component | |
*/ | |
marker: null, | |
/** | |
* auto-remove current component | |
*/ | |
autoRemove: true | |
}); | |
/** | |
* Mark entity by component if it outside the ViewPort | |
*/ | |
m.$c('ngMarkIfInsideOfTheViewPortVertical2D', { | |
/** | |
* handler callback get $entity and top/bottom edge | |
*/ | |
handler: null, | |
/** | |
* apply component-markers for any $entity that goes inside | |
* can be {string} name of component, or object with key, value | |
* where key is component name, value is config of component | |
*/ | |
marker: null, | |
/** | |
* auto-remove current component | |
*/ | |
autoRemove: true | |
}); | |
/** | |
* Mark entity by component if it outside the ViewPort | |
*/ | |
m.$c('ngMarkIfInsideOfTheViewPortHorizontal2D', { | |
/** | |
* handler callback get $entity and top/bottom edge | |
*/ | |
handler: null, | |
/** | |
* apply component-markers for any $entity that goes inside | |
* can be {string} name of component, or object with key, value | |
* where key is component name, value is config of component | |
*/ | |
marker: null, | |
/** | |
* auto-remove current component | |
*/ | |
autoRemove: true | |
}); | |
/** | |
* System that implement 2D cyclic layer | |
*/ | |
m.$s('ng2DCyclicLayer', { | |
$require: ['ngCyclic', 'ng2D'], | |
$addEntity: ['$entity', function($entity) { | |
if ($entity.ngCyclic.patternWidth) { | |
insideConfigHorizontal2D.minWidth = $entity.ngCyclic.patternWidth; | |
$entity.$add('ngMarkIfInsideOfTheViewPortHorizontal2D', | |
insideConfigHorizontal2D); | |
outsideConfigHorizontal2D.minWidth = $entity.ngCyclic.patternWidth; | |
$entity.$add('ngMarkIfOutsideOfTheViewPortHorizontal2D', | |
outsideConfigHorizontal2D); | |
} | |
if ($entity.ngCyclic.patternHeight) { | |
insideConfigVertical2D.minHeight = $entity.ngCyclic.patternHeight; | |
$entity.$add('ngMarkIfInsideOfTheViewPortVertical2D', | |
insideConfigVertical2D); | |
outsideConfigVertical2D.minHeight = $entity.ngCyclic.patternHeight; | |
$entity.$add('ngMarkIfOutsideOfTheViewPortVertical2D', | |
outsideConfigVertical2D); | |
} | |
}] | |
}); | |
/** | |
* Define handler for entity that goes outside | |
* | |
* @private | |
* @ignore | |
* @type {{handler: Function}} | |
*/ | |
var outsideConfigHorizontal2D = { | |
handler: function($entity, lowerEdge, higherEdge) { | |
if (lowerEdge) { | |
//if goes left place to right side | |
$entity.ng2D.x += $entity.ngCyclic.patternWidth; | |
} else if (higherEdge) { | |
//if goes right place to left side | |
$entity.ng2D.x -= $entity.ngCyclic.patternWidth; | |
} | |
//handle of returning to the viewport | |
if (!$entity.ngMarkIfInsideOfTheViewPortHorizontal2D) { | |
$entity.$add('ngMarkIfInsideOfTheViewPortHorizontal2D', | |
insideConfigHorizontal2D); | |
} | |
//stop handling of goes outside | |
$entity.$remove('ngMarkIfOutsideOfTheViewPortHorizontal2D'); | |
} | |
}; | |
/** | |
* Define handler for entity that goes outside | |
* | |
* @private | |
* @ignore | |
* @type {{handler: Function}} | |
*/ | |
var outsideConfigVertical2D = { | |
handler: function($entity, lowerEdge, higherEdge) { | |
if (lowerEdge) { | |
$entity.ng2D.y += $entity.ngCyclic.patternHeight; | |
} else if (higherEdge) { | |
$entity.ng2D.y -= $entity.ngCyclic.patternHeight; | |
} | |
//handle of returning to the viewport | |
if (!$entity.ngMarkIfInsideOfTheViewPortVertical2D) { | |
$entity.$add('ngMarkIfInsideOfTheViewPortVertical2D', | |
insideConfigVertical2D); | |
} | |
//stop handling of goes outside | |
$entity.$remove('ngMarkIfOutsideOfTheViewPortVertical2D'); | |
} | |
}; | |
/** | |
* Start handle again if goes inside of viewPort | |
* | |
* @private | |
* @ignore | |
* @type {{marker: {ngMarkIfOutsideOfTheViewPortHorizontal2D: {handler: Function}}}} | |
*/ | |
var insideConfigHorizontal2D = { | |
marker: { | |
ngMarkIfOutsideOfTheViewPortHorizontal2D: outsideConfigHorizontal2D | |
} | |
}; | |
/** | |
* Start handle again if goes inside of viewPort | |
* | |
* @private | |
* @ignore | |
* @type {{marker: {ngMarkIfOutsideOfTheViewPortVertical2D: {handler: Function}}}} | |
*/ | |
var insideConfigVertical2D = { | |
marker: { | |
ngMarkIfOutsideOfTheViewPortVertical2D: outsideConfigVertical2D | |
} | |
}; | |
/** | |
* System that waits for entity goes outside of viewport in vertical dimension | |
* and handle that situation | |
*/ | |
m.$s('ngMarkIfOutsideOfTheViewPortVertical2D', { | |
$require: ['ng2D', 'ngMarkIfOutsideOfTheViewPortVertical2D'], | |
$update: ['$entity', 'ng2DViewPort', function($entity, ng2DViewPort) { | |
var component = $entity.ngMarkIfOutsideOfTheViewPortVertical2D; | |
var viewPortHeight = component.viewPortHeight || | |
0.5 * Math.max(ng2DViewPort.height, component.minHeight); | |
component.viewPortHeight = viewPortHeight; | |
outsideOf($entity, | |
'ngMarkIfOutsideOfTheViewPortVertical2D', | |
component, | |
$entity.ng2D.y, | |
ng2DViewPort.lookAt.y, | |
viewPortHeight | |
); | |
}] | |
}); | |
/** | |
* System that waits for entity goes outside of viewport in horizontal dimension | |
* and handle that situation | |
*/ | |
m.$s('ngMarkIfOutsideOfTheViewPortHorizontal2D', { | |
$require: ['ng2D', 'ngMarkIfOutsideOfTheViewPortHorizontal2D'], | |
$update: ['$entity', 'ng2DViewPort', function($entity, ng2DViewPort) { | |
var component = $entity.ngMarkIfOutsideOfTheViewPortHorizontal2D; | |
var viewPortWidth = component.viewPortWidth || | |
0.5 * Math.max(ng2DViewPort.width, component.minWidth); | |
component.viewPortWidth = viewPortWidth; | |
outsideOf($entity, | |
'ngMarkIfOutsideOfTheViewPortVertical2D', | |
component, | |
$entity.ng2D.x, | |
ng2DViewPort.lookAt.x, | |
viewPortWidth | |
); | |
}] | |
}); | |
/** | |
* System that waits for entity goes inside of viewport in vertical dimension | |
* and handle that situation | |
*/ | |
m.$s('ngMarkIfInsideOfTheViewPortVertical2D', { | |
$require: ['ng2D', 'ngMarkIfInsideOfTheViewPortVertical2D'], | |
$update: ['$entity', 'ng2DViewPort', function($entity, ng2DViewPort) { | |
var component = $entity.ngMarkIfInsideOfTheViewPortVertical2D; | |
var viewPortHeight = component.viewPortHeight || | |
0.5 * Math.max(ng2DViewPort.height, component.minHeight); | |
component.viewPortHeight = viewPortHeight; | |
insideOf($entity, | |
'ngMarkIfOutsideOfTheViewPortVertical', | |
component, | |
$entity.ng2D.y, | |
ng2DViewPort.lookAt.y, | |
viewPortHeight | |
); | |
}] | |
}); | |
/** | |
* System that waits for entity goes inside of viewport in horizontal dimension | |
* and handle that situation | |
*/ | |
m.$s('ngMarkIfInsideOfTheViewPortHorizontal2D', { | |
$require: ['ng2D', 'ngMarkIfInsideOfTheViewPortHorizontal2D'], | |
$update: ['$entity', 'ng2DViewPort', function($entity, ng2DViewPort) { | |
var component = $entity.ngMarkIfInsideOfTheViewPortHorizontal2D; | |
var viewPortWidth = component.viewPortWidth || | |
0.5 * Math.max(ng2DViewPort.width, component.minWidth); | |
component.viewPortWidth = viewPortWidth; | |
insideOf($entity, | |
'ngMarkIfInsideOfTheViewPortHorizontal2D', | |
component, | |
$entity.ng2D.x, | |
ng2DViewPort.lookAt.x, | |
viewPortWidth | |
); | |
}] | |
}); | |
/** | |
* check is $entity is outside of viewPort | |
* | |
* @private | |
* @ignore | |
* | |
* @param $entity | |
* @param componentName | |
* @param component | |
* @param componentPosition | |
* @param viewPortPosition | |
* @param viewPortSize | |
*/ | |
function outsideOf($entity, componentName, component, | |
componentPosition, viewPortPosition, viewPortSize) { | |
var crossBottom = viewPortPosition + viewPortSize < componentPosition, | |
crossTop = componentPosition < viewPortPosition - viewPortSize; | |
if (crossTop || crossBottom) { | |
var handler = component.handler; | |
applyMarker($entity, component.marker); | |
if (component.autoRemove) { | |
$entity.$remove(componentName); | |
} | |
callIfHasHandler(handler, $entity, crossTop, crossBottom); | |
} | |
} | |
/** | |
* check is $entity is inside of viewPort | |
* | |
* @ignore | |
* | |
* @private | |
* | |
* @param $entity | |
* @param componentName | |
* @param component | |
* @param componentPosition | |
* @param viewPortPosition | |
* @param viewPortSize | |
*/ | |
function insideOf($entity, componentName, component, | |
componentPosition, viewPortPosition, viewPortSize) { | |
var crossBottom = viewPortPosition + viewPortSize >= componentPosition, | |
crossTop = componentPosition >= viewPortPosition - viewPortSize; | |
if (crossTop && crossBottom) { | |
var handler = component.handler; | |
applyMarker($entity, component.marker); | |
if (component.autoRemove) { | |
$entity.$remove(componentName); | |
} | |
callIfHasHandler(handler, $entity, crossTop, crossBottom); | |
} | |
} | |
/** | |
* Execute handle if has it defined | |
* | |
* @private | |
* @ignore | |
* @param handler | |
* @param $entity | |
* @param lowerEdge | |
* @param higherEdge | |
*/ | |
function callIfHasHandler(handler, $entity, lowerEdge, higherEdge) { | |
if (handler) { | |
handler($entity, lowerEdge, higherEdge); | |
} | |
} | |
/** | |
* apply markers from component | |
* | |
* @ignore | |
* | |
* @private | |
* | |
* @param $entity | |
* @param marker | |
*/ | |
function applyMarker($entity, marker) { | |
if (darlingutil.isString(marker)) { | |
if (!$entity[marker]) { | |
$entity.$add(marker); | |
} | |
} else if (darlingutil.isObject(marker)) { | |
for (var key in marker) { | |
if (!$entity[key]) { | |
$entity.$add(key, marker[key]); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment