kontra
Version:
Kontra HTML5 game development library
465 lines (405 loc) • 19.5 kB
HTML
<html lang="en">
<head>
<title>Kontra.js – Plugin</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<base href="https://straker.github.io/kontra/">
<script>
// adjust path based on location (github pages required kontra url)
if (window.location.host.indexOf('localhost') !== -1) {
let base = document.querySelector('base');
base.setAttribute('href', '/');
}
</script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.16.0/themes/prism.min.css">
<link rel="stylesheet" href="assets/styles.css">
<script src="assets/js/kontra.js"></script>
</head>
<body>
<div class="content">
<header class="main-nav">
<div id="kontra-heading" class="nav-heading">Kontra</div>
<a href="#main">Skip navigation</a>
<nav>
<button class="menu-button" aria-expanded="false" aria-controls="menu"><span aria-hidden="true">☰</span> Menu</button>
<!-- add role=list back to list so screen readers still read it as list when
css list-style: none is set
@see https://web-a11y.slack.com/archives/C042TSFGN/p1501699529181172 -->
<ul id="menu" role="list">
<li><a href="." >Introduction</a></li>
<li><a href="getting-started" >Getting Started</a></li>
<li><a href="download" >Download</a></li>
<li><a href="tutorials" >Tutorials</a></li>
<li><a href="made-with-kontra" >Made With Kontra</a></li>
<li>
<span id="api" class="nav-api-heading">API</span>
<ul aria-labelledby="api">
<li><a href="api/animation" >Animation</a></li>
<li><a href="api/assets" >Assets</a></li>
<li><a href="api/core" >Core</a></li>
<li><a href="api/events" >Events</a></li>
<li><a href="api/gameLoop" >GameLoop</a></li>
<li><a href="api/keyboard" >Keyboard</a></li>
<li><a href="api/plugin" aria-current="page">Plugin</a></li>
<li><a href="api/pointer" >Pointer</a></li>
<li><a href="api/pool" >Pool</a></li>
<li><a href="api/quadtree" >Quadtree</a></li>
<li><a href="api/sprite" >Sprite</a></li>
<li><a href="api/spriteSheet" >SpriteSheet</a></li>
<li><a href="api/store" >Store</a></li>
<li><a href="api/tileEngine" >TileEngine</a></li>
<li><a href="api/vector" >Vector</a></li>
</ul>
</li>
</ul>
</nav>
<div class="scroll-indicator" aria-hidden="true"><span>^</span></div>
</header>
<main id="main">
<div>
<a href="https://github.com/straker/kontra" class="github-corner" aria-label="View source on GitHub"><svg width="80" height="80" viewBox="0 0 250 250" style="fill:#151513; color:#fff; position: absolute; top: 0; border: 0; right: 0;" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a>
<h1>Plugin </h1>
<p>A plugin system based on the <a href="https://en.wikipedia.org/wiki/Interceptor_pattern">interceptor pattern</a>, designed to share reusable code such as more advance collision detection or a 2D physics engine.</p>
<div class="tablist">
<ul role="tablist">
<li role="presentation" data-tab="global">
<button role="tab" id="plugin-global-tab">Global Object</button>
</li>
<li role="presentation" data-tab="es">
<button role="tab" id="plugin-es-tab">ES Module Import</button>
</li>
<li role="presentation" data-tab="bundle">
<button role="tab" id="plugin-bundle-tab">Module Bundler</button>
</li>
<li role="presentation"></li>
</ul>
<section role="tabpanel" aria-labelledby=plugin-global-tab data-tabpanel="global"><pre><code class="language-js">let { registerPlugin, Sprite } = kontra;
import loggingPlugin from 'path/to/plugin/code.js'
// register a plugin that adds logging to all Sprites
registerPlugin(Sprite, loggingPlugin);</code></pre></section>
<section role="tabpanel" aria-labelledby=plugin-es-tab data-tabpanel="es"><pre><code class="language-js">import { registerPlugin, Sprite } from 'path/to/kontra.mjs';
import loggingPlugin from 'path/to/plugin/code.js'
// register a plugin that adds logging to all Sprites
registerPlugin(Sprite, loggingPlugin);</code></pre></section>
<section role="tabpanel" aria-labelledby=plugin-bundle-tab data-tabpanel="bundle"><pre><code class="language-js">import { registerPlugin, Sprite } from 'kontra';
import loggingPlugin from 'path/to/plugin/code.js'
// register a plugin that adds logging to all Sprites
registerPlugin(Sprite, loggingPlugin);</code></pre></section>
</div>
<section class="toc">
<h2 id="toc"><a href="#toc" class="section-link">Table of Contents<span aria-hidden="true">#</span></a></h2>
<ul aria-labelledby="toc">
<li>
<ul>
<li><a href="api/plugin#how-to create a plugin">How to Create a Plugin</a></li>
<li><a href="api/plugin#before-intercept functions">Before Intercept Functions</a></li>
<li><a href="api/plugin#after-intercept functions">After Intercept Functions</a></li>
</ul>
</li>
<li>
<h3 id="methods">Methods</h3>
<ul aria-labelledby="methods">
<li>
<a href="api/plugin#extendObject">
<span>extendObject(​kontraObj, properties)</span>
</a>
</li>
<li>
<a href="api/plugin#registerPlugin">
<span>registerPlugin(​kontraObj, pluginObj)</span>
</a>
</li>
<li>
<a href="api/plugin#unregisterPlugin">
<span>unregisterPlugin(​kontraObj, pluginObj)</span>
</a>
</li>
</ul>
</li>
</ul>
</section>
<section>
<h2 id="how-to create a plugin">
<a href="#how-to create a plugin" class="section-link">
<span>How to Create a Plugin</span>
<span aria-hidden="true">#</span>
</a>
</h2>
<p>A plugin is an object that defines a set of intercept functions that should be run before or after a Kontra objects functions. These functions allow you to modify the code or change the behavior of the intercepted functions.</p>
<p>An intercept function is named the same name as the function it will intercept. The function name is also prefixed with <code>before</code> to have the function run before the intercepted function, or <code>after</code> to run after the intercepted function.</p>
<p>For example, if you wish to add a function to run after a Sprites <code>collidesWidth()</code> function, the name of the intercept function would be <code>afterCollidesWidth</code> (note the capitalization of the <code>collidesWidth</code> function name). <code>beforeCollidesWidth</code> would run before the Sprites <code>collidesWidth()</code> function.</p>
<p>A plugin can define any number of before and after intercept functions. When the plugin is registered for a Kontra object, only intercept functions that match a function name in the Kontra object will be intercepted.</p>
<p>As the plugin author, you should not <a href="#registerPlugin">register</a> the plugin yourself. You should only export the plugin object and let the consumer register it.</p>
<pre><code class="language-js">// pluginCode.js
const loggingPlugin = {
afterCollidesWith(sprite, result, object) {
console.log('collision between sprites!');
}
};
export default loggingPlugin;</code></pre>
<div class="tablist">
<ul role="tablist">
<li role="presentation" data-tab="global">
<button role="tab" id="how-to-create-a-plugin-global-tab">Global Object</button>
</li>
<li role="presentation" data-tab="es">
<button role="tab" id="how-to-create-a-plugin-es-tab">ES Module Import</button>
</li>
<li role="presentation" data-tab="bundle">
<button role="tab" id="how-to-create-a-plugin-bundle-tab">Module Bundler</button>
</li>
<li role="presentation"></li>
</ul>
<section role="tabpanel" aria-labelledby=how-to-create-a-plugin-global-tab data-tabpanel="global"><pre><code class="language-js">// consumerCode.js
let { registerPlugin, Sprite } = kontra;
import loggingPlugin from pluginCode.js;
// have the plugin run for all Sprites
registerPlugin(Sprite, loggingPlugin);
let sprite1 = Sprite({
x: 10,
y: 20,
width: 10,
height: 10
});
let sprite2 = Sprite({
x: 15,
y: 20,
width: 10,
height: 10
});
sprite1.collidesWith(sprite2); //=> 'collision between sprites!'; true</code></pre></section>
<section role="tabpanel" aria-labelledby=how-to-create-a-plugin-es-tab data-tabpanel="es"><pre><code class="language-js">// consumerCode.js
import { registerPlugin, Sprite } from 'path/to/kontra.mjs';
import loggingPlugin from pluginCode.js;
// have the plugin run for all Sprites
registerPlugin(Sprite, loggingPlugin);
let sprite1 = Sprite({
x: 10,
y: 20,
width: 10,
height: 10
});
let sprite2 = Sprite({
x: 15,
y: 20,
width: 10,
height: 10
});
sprite1.collidesWith(sprite2); //=> 'collision between sprites!'; true</code></pre></section>
<section role="tabpanel" aria-labelledby=how-to-create-a-plugin-bundle-tab data-tabpanel="bundle"><pre><code class="language-js">// consumerCode.js
import { registerPlugin, Sprite } from 'kontra';
import loggingPlugin from pluginCode.js;
// have the plugin run for all Sprites
registerPlugin(Sprite, loggingPlugin);
let sprite1 = Sprite({
x: 10,
y: 20,
width: 10,
height: 10
});
let sprite2 = Sprite({
x: 15,
y: 20,
width: 10,
height: 10
});
sprite1.collidesWith(sprite2); //=> 'collision between sprites!'; true</code></pre></section>
</div>
</section>
<section>
<h2 id="before-intercept functions">
<a href="#before-intercept functions" class="section-link">
<span>Before Intercept Functions</span>
<span aria-hidden="true">#</span>
</a>
</h2>
<p>A before intercept function can be used to modify or change the arguments that will be passed to the intercepted function.</p>
<p>The function will be passed the <code>this</code> context of the intercepted object as well as all arguments of the original call. The function should either return an Array of the arguments if modifying them or return <code>null</code> or nothing if not modifying the arguments.</p>
<pre><code class="language-js">class MyObj {
add(a, b) {
return a + b;
}
}
// create a plugin that doubles the arguments before passing
// them to the original add function
registerPlugin(MyObj, {
beforeAdd(context, a, b) {
return [a * 2, b * 2];
}
});
const obj = new MyObj();
obj.add(1, 2); //=> 6</code></pre>
<p>Multiple before intercept functions can be registered for the same function. All functions will be run in the order they were registered. The functions return value will be passed to the next function. If the function doesn't modify the arguments (returned <code>null</code> or nothing) then the functions parameters will be passed to the next function instead.</p>
<pre><code class="language-js">class MyObj {
add(a, b) {
return a + b;
}
}
// log the arguments of the call and pass them unchanged to
// the next plugin
registerPlugin(MyObj, {
beforeAdd(context, a, b) {
console.log(`add passed: ${a}, ${b}`);
}
});
registerPlugin(MyObj, {
beforeAdd(context, a, b) { // receives a=1 and b=2
return [a * 2, b * 2];
}
});
const obj = new MyObj();
obj.add(1, 2); //=> 'add passed: 1, 2'; 6</code></pre>
</section>
<section>
<h2 id="after-intercept functions">
<a href="#after-intercept functions" class="section-link">
<span>After Intercept Functions</span>
<span aria-hidden="true">#</span>
</a>
</h2>
<p>An after intercept function can be used to modify or change the results of the intercepted function.</p>
<p>The function will be passed the <code>this</code> context of the intercepted object, the result of the intercepted function, and the final arguments passed to the intercepted function. The function should either return a value if modifying the result or return <code>null</code> or nothing if not modifying the result.</p>
<pre><code class="language-js">class MyObj {
add(a, b) {
return a + b;
}
}
// create a plugin that doubles the result
registerPlugin(MyObj, {
afterAdd(context, result, a, b) {
return result * 2;
}
});
const obj = new MyObj();
obj.add(1, 2); //=> 6</code></pre>
<p>Multiple after intercept functions can be registered for the same function. All functions will be run in the order they were registered. Each functions return value will be passed to the next function. If the function doesn't modify the result (returned <code>null</code> or nothing) then the functions parameters will be passed to the next function instead.</p>
<pre><code class="language-js">class MyObj {
add(a, b) {
return a + b;
}
}
// log the arguments of the call and pass them unchanged to
// the next plugin
registerPlugin(MyObj, {
afterAdd(context, result, a, b) {
console.log(`add passed: ${a}, ${b} and returned ${result}`);
}
});
registerPlugin(MyObj, {
afterAdd(context, result, a, b) { // receives result=3
return result * 2;
}
});
const obj = new MyObj();
obj.add(1, 2); //=> 'add passed: 1, 2 and returned 3'; 6</code></pre>
</section>
<section>
<h2 id="extendObject">
<a href="api/plugin#extendObject" class="section-link">
<span>extendObject(​kontraObj, properties)</span>
<span aria-hidden="true">#</span>
</a>
</h2>
<p>Safely extend the functionality of a Kontra object. Any properties that already exist on the Kontra object will not be added.</p>
<div class="tablist">
<ul role="tablist">
<li role="presentation" data-tab="global">
<button role="tab" id="extendobject-global-tab">Global Object</button>
</li>
<li role="presentation" data-tab="es">
<button role="tab" id="extendobject-es-tab">ES Module Import</button>
</li>
<li role="presentation" data-tab="bundle">
<button role="tab" id="extendobject-bundle-tab">Module Bundler</button>
</li>
<li role="presentation"></li>
</ul>
<section role="tabpanel" aria-labelledby=extendobject-global-tab data-tabpanel="global"><pre><code class="language-js">let { extendObject, Vector } = kontra;
// add a subtract function to all Vectors
extendObject(Vector, {
subtract(vec) {
return Vector(this.x - vec.x, this.y - vec.y);
}
});</code></pre></section>
<section role="tabpanel" aria-labelledby=extendobject-es-tab data-tabpanel="es"><pre><code class="language-js">import { extendObject, Vector } from 'path/to/kontra.mjs';
// add a subtract function to all Vectors
extendObject(Vector, {
subtract(vec) {
return Vector(this.x - vec.x, this.y - vec.y);
}
});</code></pre></section>
<section role="tabpanel" aria-labelledby=extendobject-bundle-tab data-tabpanel="bundle"><pre><code class="language-js">import { extendObject, Vector } from 'kontra';
// add a subtract function to all Vectors
extendObject(Vector, {
subtract(vec) {
return Vector(this.x - vec.x, this.y - vec.y);
}
});</code></pre></section>
</div>
<h3 id="title-extendObject"><span class="visually-hidden">extendObject</span> Parameters</span></h3>
<dl aria-labelledby="title-extendObject">
<dt>
<code>kontraObj</code>
</dt>
<dd><p>Object. Kontra object to extend</p>
</dd>
<dt>
<code>properties</code>
</dt>
<dd><p>Object. Properties to add.</p>
</dd>
</dl>
</section>
<section>
<h2 id="registerPlugin">
<a href="api/plugin#registerPlugin" class="section-link">
<span>registerPlugin(​kontraObj, pluginObj)</span>
<span aria-hidden="true">#</span>
</a>
</h2>
<p>Register a plugin to run a set of functions before or after the Kontra object functions.</p>
<h3 id="title-registerPlugin"><span class="visually-hidden">registerPlugin</span> Parameters</span></h3>
<dl aria-labelledby="title-registerPlugin">
<dt>
<code>kontraObj</code>
</dt>
<dd><p>Object. Kontra object to attach the plugin to.</p>
</dd>
<dt>
<code>pluginObj</code>
</dt>
<dd><p>Object. Plugin object with before and after intercept functions.</p>
</dd>
</dl>
</section>
<section>
<h2 id="unregisterPlugin">
<a href="api/plugin#unregisterPlugin" class="section-link">
<span>unregisterPlugin(​kontraObj, pluginObj)</span>
<span aria-hidden="true">#</span>
</a>
</h2>
<p>Unregister a plugin from a Kontra object.</p>
<h3 id="title-unregisterPlugin"><span class="visually-hidden">unregisterPlugin</span> Parameters</span></h3>
<dl aria-labelledby="title-unregisterPlugin">
<dt>
<code>kontraObj</code>
</dt>
<dd><p>Object. Kontra object to detach plugin from.</p>
</dd>
<dt>
<code>pluginObj</code>
</dt>
<dd><p>Object. The plugin object that was passed during registration.</p>
</dd>
</dl>
</section>
</div>
</main>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.16.0/prism.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.16.0/components/prism-javascript.min.js"></script>
<script src="assets/js/navbar.js"></script>
<script src="assets/js/exampleTabList.js"></script>
</body>
</html>