├── .babelrc
├── .gitignore
├── LICENSE
├── README.md
├── build
├── tiny.base.js
├── tiny.js
└── tiny.mini.js
├── examples
├── index.html
├── js
│ ├── App2D.js
│ ├── App3D.js
│ ├── objects
│ │ └── MiniMap.js
│ └── particles
│ │ ├── Confetti.js
│ │ ├── Explode.js
│ │ ├── Firework.js
│ │ ├── Ribbon.js
│ │ └── Smoke.js
├── jsm
│ └── particles
│ │ ├── Confetti.js
│ │ ├── Explode.js
│ │ ├── ExplodingConfetti.js
│ │ ├── Firework.js
│ │ ├── MoneyFalling.js
│ │ ├── Ribbon.js
│ │ └── Smoke.js
├── libs
│ ├── GLTFLoader.js
│ ├── ace
│ │ ├── ace.js
│ │ ├── ext-keybinding_menu.js
│ │ ├── ext-language_tools.js
│ │ ├── ext-options.js
│ │ ├── ext-prompt.js
│ │ ├── ext-searchbox.js
│ │ ├── ext-settings_menu.js
│ │ ├── ext-spellcheck.js
│ │ ├── keybinding-sublime.js
│ │ ├── mode-javascript.js
│ │ ├── snippets
│ │ │ └── javascript.js
│ │ ├── theme-monokai.js
│ │ └── worker-javascript.js
│ ├── howler.js
│ ├── three.min.js
│ └── tiny
│ │ ├── plugins
│ │ ├── anim.js
│ │ ├── create.js
│ │ ├── extra.js
│ │ ├── particles.js
│ │ ├── sound.js
│ │ ├── three.js
│ │ └── three.js.LICENSE.txt
│ │ ├── tiny.js
│ │ ├── tiny.js.LICENSE.txt
│ │ ├── tiny.mini.js
│ │ └── tiny.mini.js.LICENSE.txt
├── res
│ ├── image.png
│ ├── image2.png
│ ├── resources.js
│ ├── script.js
│ └── style.css
└── tests
│ ├── AnimKeyframes.js
│ ├── AnimSpritesheet.js
│ ├── Basic.js
│ ├── BlendMode.js
│ ├── CreateSpritesheet.js
│ ├── DemoInfinityWorm.js
│ ├── Extended.js
│ ├── Graphics.js
│ ├── Graphics2.js
│ ├── Input.js
│ ├── Particles1.js
│ ├── Particles2.js
│ ├── ProgressBar.js
│ ├── RenderLayer.js
│ ├── RendererTexture.js
│ ├── Sound.js
│ ├── ThreeBasic.js
│ ├── ThreeCanvas.js
│ ├── ThreeScreen2D.js
│ ├── TilingSprite.js
│ └── Tweens.js
├── package.json
├── plugins
├── anim
│ ├── Anim.js
│ ├── AnimationManager.js
│ ├── KeyframesAnim.js
│ ├── Loader.js
│ ├── SpritesheetAnim.js
│ └── index.js
├── create
│ ├── index.js
│ └── spritesheet.js
├── extra
│ ├── index.js
│ ├── math
│ │ └── Ellipse.js
│ ├── objects
│ │ ├── Button.js
│ │ ├── Object2D.js
│ │ ├── Opaque.js
│ │ ├── ProgressBar.js
│ │ ├── RenderLayer.js
│ │ └── TilingSprite.js
│ ├── systems
│ │ ├── Loader.js
│ │ └── Tween.js
│ └── textures
│ │ └── Texture.js
├── particles
│ ├── Emitter.js
│ ├── Particle.js
│ └── index.js
├── sound
│ └── index.js
└── three
│ ├── index.js
│ ├── objects
│ ├── Canvas2D.js
│ ├── Canvas3D.js
│ ├── Screen2D.js
│ └── Text3D.js
│ └── systems
│ ├── Input.js
│ └── Loader.js
├── src
├── App.js
├── base.js
├── global.js
├── index.js
├── math
│ ├── Circle.js
│ ├── Math.js
│ ├── Matrix.js
│ ├── Point.js
│ ├── Polygon.js
│ ├── Rectangle.js
│ └── RoundedRectangle.js
├── mini.js
├── objects
│ ├── BaseObject2D.js
│ ├── Graphics.js
│ ├── Object2D.js
│ ├── Scene.js
│ ├── Sprite.js
│ └── Text.js
├── renderers
│ ├── CanvasMaskManager.js
│ ├── CanvasRenderer.js
│ ├── CanvasTinter.js
│ └── GraphicsRenderer.js
├── systems
│ ├── Input.js
│ ├── Loader.js
│ ├── RAF.js
│ ├── Timer.js
│ └── Tween.js
├── textures
│ ├── RenderTexture.js
│ └── Texture.js
└── utils
│ ├── CanvasBuffer.js
│ ├── EventEmitter.js
│ └── polyfill.js
├── webpack.build.js
└── webpack.dev.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["@babel/preset-env"]
3 | }
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | dist
2 | node_modules
3 | npm-debug.log
4 | .idea
5 | package-lock.json
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | 2018 GREEN PANDA GAMES. ALL RIGHTS RESERVED.
--------------------------------------------------------------------------------
/examples/js/App2D.js:
--------------------------------------------------------------------------------
1 | class App2D extends Tiny.App {
2 | constructor(width, height, parentNode, states) {
3 | super(states);
4 |
5 | this.width = width;
6 | this.height = height;
7 |
8 | this.renderer = new Tiny.CanvasRenderer(this.width, this.height, {
9 | resolution: 1.25,
10 | autoResize: true
11 | });
12 |
13 | this.renderer.setClearColor("#f4f4f4");
14 |
15 | var view = (this.inputView = this.renderer.domElement);
16 |
17 | parentNode = parentNode ? document.getElementById(parentNode) : document.body;
18 | parentNode.appendChild(view);
19 | // view.style.position = 'absolute';
20 |
21 | // view.style.top = "0px";
22 | // view.style.left = "0px";
23 |
24 | // view.style.transformOrigin = '0% 0%';
25 | view.style.perspective = "1000px";
26 |
27 | this.scene = new Tiny.Scene();
28 | }
29 |
30 | setPixelRatio(dpr) {
31 | this.renderer.setPixelRatio(dpr);
32 | }
33 |
34 | render() {
35 | this.renderer.render(this.scene);
36 | }
37 |
38 | resize(width, height) {
39 | super.resize(width, height);
40 |
41 | this.renderer.resize(width, height);
42 | }
43 |
44 | destroy(clearCache) {
45 | super.destroy(clearCache);
46 |
47 | this.scene.destroy();
48 | this.renderer.destroy(true);
49 | }
50 | }
51 |
52 | Tiny.App2D = App2D;
53 |
--------------------------------------------------------------------------------
/examples/js/App3D.js:
--------------------------------------------------------------------------------
1 | class App3D extends Tiny.App {
2 | constructor(width, height, parentNode, states) {
3 | super(states);
4 |
5 | this.width = width;
6 | this.height = height;
7 |
8 | this.renderer = new THREE.WebGLRenderer({
9 | antialias: true
10 | });
11 |
12 | this.renderer.outputEncoding = THREE.sRGBEncoding;
13 |
14 | this.renderer.setSize(this.width, this.height);
15 | this.renderer.setClearColor("#232323");
16 |
17 | var view = (this.canvas = this.inputView = this.renderer.domElement);
18 |
19 | parentNode = parentNode ? document.getElementById(parentNode) : document.body;
20 | parentNode.appendChild(view);
21 | // view.style.position = 'absolute';
22 |
23 | // view.style.top = "0px";
24 | // view.style.left = "0px";
25 |
26 | // view.style.transformOrigin = '0% 0%';
27 | view.style.perspective = "1000px";
28 |
29 | this.scene = new THREE.Scene();
30 | this.camera = new THREE.OrthographicCamera(1, 1, 1, 1, 0.3, 500);
31 | // this.camera = new PerspectiveCamera(50, window.innerWidth/window.innerHeight, 0.1, 1000);
32 |
33 | this.camera.position.set(40, 50, 40);
34 | this.camera.lookAt(0, 0, 0);
35 | this.camera.distance = 4;
36 |
37 | this.screen2d = new Tiny.Screen2D(this.width, this.height);
38 |
39 | this.setupCamera();
40 | }
41 |
42 | setupCamera() {
43 | if (this.camera) {
44 | var aspect = this.width / this.height;
45 | var distance = this.camera.distance;
46 |
47 | if (this.camera.isOrthographicCamera) {
48 | this.camera.left = -distance * aspect;
49 | this.camera.right = distance * aspect;
50 | this.camera.top = distance;
51 | this.camera.bottom = -distance;
52 | } else {
53 | this.camera.fov = distance * 1.2;
54 | this.camera.aspect = aspect;
55 | }
56 |
57 | this.camera.updateProjectionMatrix();
58 | }
59 | }
60 |
61 | setPixelRatio(dpr) {
62 | this.renderer.setPixelRatio(dpr);
63 | this.screen2d.renderer.setPixelRatio(dpr);
64 | }
65 |
66 | render() {
67 | this.renderer.autoClear = true;
68 | this.renderer.render(this.scene, this.camera);
69 | this.renderer.autoClear = false;
70 | this.renderer.render(this.screen2d.scene, this.screen2d.camera);
71 | }
72 |
73 | resize(width, height) {
74 | super.resize(width, height);
75 |
76 | this.screen2d.setSize(width, height);
77 | this.renderer.setSize(width, height);
78 | this.setupCamera();
79 | }
80 |
81 | destroy(clearCache) {
82 | super.destroy(clearCache);
83 |
84 | // console.log("dasdasd")
85 |
86 | this.screen2d.scene.dispose();
87 | this.scene.dispose();
88 | // this.ui_scene = null;
89 | // this.ui_camera = null;
90 | // this.ui_sprite = this.ui_texture = null;
91 |
92 | if (this.renderer.domElement.parentNode) {
93 | this.renderer.domElement.parentNode.removeChild(this.renderer.domElement);
94 | }
95 |
96 | this.renderer.dispose();
97 | this.renderer = undefined;
98 | }
99 | }
100 |
101 | Tiny.App3D = App3D;
102 |
--------------------------------------------------------------------------------
/examples/js/objects/MiniMap.js:
--------------------------------------------------------------------------------
1 | class MiniMap extends Tiny.Sprite {
2 | constructor(game, resolution) {
3 | var texture = new Tiny.RenderTexture(game.width, game.height, null, resolution || 1);
4 |
5 | super(texture);
6 | this.game = game;
7 | this.scene = game.scene;
8 | this.texture = texture;
9 | this.delay = 100;
10 | this._timer = this.delay;
11 |
12 | this.frames = new Tiny.Graphics();
13 | this.updateFrames();
14 |
15 | this.anchor.y = 1;
16 | this.scale.set(0.3);
17 | this.alpha = 0.7;
18 | // this.width = 150;
19 | // this.height = 100;
20 | this.y = game.height;
21 | this.x = 0;
22 |
23 | this._update();
24 | }
25 |
26 | updateFrames() {
27 | this.frames.clear();
28 | this.frames.beginFill("#000000", 0.2);
29 | this.frames.drawRect(0, 0, this.game.width, this.game.height);
30 | this.frames.endFill();
31 | this.frames.lineStyle(15, "#000000", 0.7);
32 | this.frames.drawRect(0, 0, this.game.width, this.game.height);
33 | }
34 |
35 | resize(width, height) {
36 | this.texture.resize(width, height);
37 | this.y = height;
38 |
39 | this.updateFrames();
40 |
41 | this._update();
42 | }
43 |
44 | _update() {
45 | this.visible = false;
46 | this.texture.render(this.scene, null, true);
47 | this.texture.render(this.frames);
48 | this.visible = true;
49 | }
50 |
51 | update(delta) {
52 | this._timer -= delta;
53 | if (this._timer < 0) {
54 | this._timer = this.delay;
55 | this._update();
56 | }
57 | }
58 | }
59 |
60 | Tiny.MiniMap = MiniMap;
61 |
62 | class RecursiveSprite extends Tiny.Sprite {
63 | constructor(game, resolution) {
64 | var texture = new Tiny.RenderTexture(game.width, game.height, null, resolution || 1);
65 |
66 | super(texture);
67 | this.game = game;
68 | this.scene = game.scene;
69 | this.texture = texture;
70 | this.delay = 1;
71 | this._timer = this.delay;
72 | this.clearAlpha = 0.1;
73 |
74 | this.frames = new Tiny.Graphics();
75 | this.updateFrames();
76 |
77 | this.scale.set(0.98);
78 | this.alpha = 0.9;
79 |
80 | this.setCenter(0, 0);
81 |
82 | this._update();
83 | }
84 |
85 | setCenter(x, y) {
86 | this.anchor.set(x, y);
87 | this.x = this.game.width * x;
88 | this.y = this.game.height * y;
89 | }
90 |
91 | updateFrames() {
92 | this.frames.clear();
93 | this.frames.beginFill(this.game.renderer.clearColor, this.clearAlpha);
94 | this.frames.drawRect(0, 0, this.game.width, this.game.height);
95 | this.frames.endFill();
96 | // this.frames.lineStyle(15, "#000000", 0.2);
97 | // this.frames.drawRect(0, 0, this.game.width, this.game.height);
98 | }
99 |
100 | resize(width, height) {
101 | this.texture.resize(width, height);
102 | this.x = width * this.anchor.x;
103 | this.y = height * this.anchor.y;
104 |
105 | this.updateFrames();
106 |
107 | this._update();
108 | }
109 |
110 | _update() {
111 | // this.visible = false;
112 | this.texture.render(this.scene);
113 | this.frames && this.texture.render(this.frames);
114 | // this.visible = true;
115 | }
116 |
117 | update(delta) {
118 | this._timer -= delta;
119 | if (this._timer < 0) {
120 | this._timer = this.delay;
121 | this._update();
122 | }
123 | }
124 | }
125 |
126 | Tiny.RecursiveSprite = RecursiveSprite;
127 |
--------------------------------------------------------------------------------
/examples/js/particles/Confetti.js:
--------------------------------------------------------------------------------
1 | var PI = Math.PI,
2 | random = Math.random,
3 | cos = Math.cos,
4 | sin = Math.sin;
5 |
6 | var DEG_TO_RAD = PI / 180,
7 | colors = [
8 | ["#df0049", "#660671"],
9 | ["#00e857", "#005291"],
10 | ["#2bebbc", "#05798a"],
11 | ["#ffd200", "#b06c00"]
12 | ];
13 |
14 | Tiny.ConfettiParticle = function (emitter) {
15 | Tiny.Particle.call(this, emitter);
16 |
17 | this.rotationSpeed = random() * 600 + 800;
18 | var angle = DEG_TO_RAD * random() * 360;
19 | this.rotationpart = DEG_TO_RAD * random() * 360;
20 | this.cosA = 1.0;
21 | this.size = 10.0;
22 | this.oscillationSpeed = random() * 1.5 + 0.5;
23 | this.xSpeed = 80.0;
24 | this.ySpeed = random() * 60 + 50.0;
25 | this.corners = new Array();
26 | this.time = random();
27 | var ci = Math.round(random() * (colors.length - 1));
28 | this.frontColor = colors[ci][0];
29 | this.backColor = colors[ci][1];
30 | for (var i = 0; i < 4; i++) {
31 | var dx = cos(angle + DEG_TO_RAD * (i * 90 + 45));
32 | var dy = sin(angle + DEG_TO_RAD * (i * 90 + 45));
33 | this.corners[i] = { x: dx, y: dy };
34 | }
35 | };
36 |
37 | Tiny.ConfettiParticle.prototype = Object.create(Tiny.Particle.prototype);
38 | Tiny.ConfettiParticle.prototype.constructor = Tiny.ConfettiParticle;
39 |
40 | Tiny.ConfettiParticle.prototype._update = function (delta) {
41 | if (this.visible === false) return false;
42 |
43 | this.lifespan -= delta;
44 |
45 | if (this.lifespan <= 0) {
46 | this.visible = false;
47 | return false;
48 | }
49 |
50 | delta = delta * 0.001;
51 |
52 | this.time += delta;
53 | this.rotationpart += this.rotationSpeed * delta;
54 | this.cosA = cos(DEG_TO_RAD * this.rotationpart);
55 | this.x += cos(this.time * this.oscillationSpeed) * this.xSpeed * delta;
56 | this.y += this.ySpeed * delta;
57 | };
58 |
59 | var _g, _res;
60 |
61 | Tiny.ConfettiParticle.prototype.render = function (renderSession) {
62 | if (this.visible === false || this.alpha === 0) return;
63 |
64 | _g = renderSession.context;
65 | _res = renderSession.resolution;
66 |
67 | if (this.cosA > 0) {
68 | _g.fillStyle = this.frontColor;
69 | } else {
70 | _g.fillStyle = this.backColor;
71 | }
72 | _g.beginPath();
73 | _g.moveTo(
74 | (this.x + this.corners[0].x * this.size) * _res,
75 | (this.y + this.corners[0].y * this.size * this.cosA) * _res
76 | );
77 | for (var i = 1; i < 4; i++) {
78 | _g.lineTo(
79 | (this.x + this.corners[i].x * this.size) * _res,
80 | (this.y + this.corners[i].y * this.size * this.cosA) * _res
81 | );
82 | }
83 | _g.closePath();
84 | _g.fill();
85 | };
86 |
--------------------------------------------------------------------------------
/examples/js/particles/Explode.js:
--------------------------------------------------------------------------------
1 | Tiny.ExplodeParticle = function (emitter) {
2 | Tiny.Particle.call(this, emitter);
3 | };
4 |
5 | Tiny.ExplodeParticle.prototype = Object.create(Tiny.Particle.prototype);
6 | Tiny.ExplodeParticle.prototype.constructor = Tiny.ExplodeParticle;
7 |
8 | Tiny.ExplodeParticle.prototype.update = function (time, delta) {
9 | var scale = Math.min(time / 200, 1);
10 | this.scale.set(scale * scale * scale * scale);
11 | this.alpha = Math.min(time / 250, 1);
12 |
13 | var speed = scale * scale * scale * scale * 5;
14 |
15 | this.x += this.xspeed * speed;
16 | this.y += this.yspeed * speed;
17 | };
18 |
19 | Tiny.ExplodeParticle.prototype.onEmit = function () {
20 | var randAgle = Math.random() * Math.PI * 2;
21 |
22 | var rand_speed = Math.random() * 3;
23 |
24 | this.xspeed = Math.sin(randAgle) * rand_speed;
25 | this.yspeed = Math.cos(randAgle) * rand_speed;
26 |
27 | this.x = this.xspeed * Math.random() * 3;
28 | this.y = this.yspeed * Math.random() * 3;
29 | };
30 |
31 | Tiny.ExplodeParticle.prototype.draw = function (context, resolution) {
32 | context.beginPath();
33 | context.arc(0, 0, 20 * resolution, 0, 2 * Math.PI, false);
34 | context.fill();
35 | };
36 |
--------------------------------------------------------------------------------
/examples/js/particles/Firework.js:
--------------------------------------------------------------------------------
1 | Tiny.FireworkParticle = function (emitter) {
2 | Tiny.Particle.call(this, emitter);
3 | };
4 |
5 | Tiny.FireworkParticle.prototype = Object.create(Tiny.Particle.prototype);
6 | Tiny.FireworkParticle.prototype.constructor = Tiny.FireworkParticle;
7 |
8 | var normTime, speed;
9 |
10 | Tiny.FireworkParticle.prototype.update = function (time, delta) {
11 | normTime = time / this.maxlifespan;
12 |
13 | this.scale.set(Math.tan(normTime * normTime));
14 |
15 | this.alpha = Math.min(Math.tan(normTime), 1);
16 |
17 | speed = normTime * normTime * normTime * 10;
18 |
19 | this.x += this.xspeed * speed * delta * normTime;
20 | this.y += this.yspeed * speed * delta + normTime * 0.8 * delta;
21 | };
22 |
23 | Tiny.FireworkParticle.prototype.onEmit = function () {
24 | var randAgle = Math.random() * Math.PI * 2;
25 |
26 | var rand_speed = Math.random() * 3;
27 |
28 | this.maxlifespan = this.lifespan;
29 |
30 | this.xspeed = Math.sin(randAgle) * rand_speed * 0.05;
31 | this.yspeed = Math.cos(randAgle) * rand_speed * 0.05;
32 | };
33 |
34 | Tiny.FireworkParticle.prototype.draw = function (context, resolution) {
35 | context.beginPath();
36 | context.arc(0, 0, 20 * resolution, 0, 2 * Math.PI, false);
37 | context.fill();
38 | };
39 |
--------------------------------------------------------------------------------
/examples/js/particles/Smoke.js:
--------------------------------------------------------------------------------
1 | Tiny.SmokeParticle = function (emitter) {
2 | Tiny.Particle.call(this, emitter);
3 | };
4 |
5 | Tiny.SmokeParticle.prototype = Object.create(Tiny.Particle.prototype);
6 | Tiny.SmokeParticle.prototype.constructor = Tiny.SmokeParticle;
7 |
8 | Tiny.SmokeParticle.prototype.update = function (time, delta) {
9 | this.scale.set(Math.min(time / 1000, 0.7));
10 | this.alpha = Math.min(time / 1000, 1);
11 |
12 | this.y -= this.yspeed * delta;
13 | this.x += this.xspeed * delta;
14 | this.rotation += this.rotationsp;
15 | };
16 |
17 | Tiny.SmokeParticle.prototype.onEmit = function () {
18 | this.xspeed = Tiny.rnd(-4, 4) * 0.05;
19 | this.yspeed = Tiny.rnd(2, 10) * 0.05;
20 | this.rotationsp = Math.random() * 0.02 - 0.01;
21 | };
22 |
23 | Tiny.SmokeParticle.prototype.draw = function (context, resolution) {
24 | //context.fillRect(0, 0, 100, 100)
25 |
26 | context.beginPath();
27 | context.arc(0, 0, 100 * resolution, 0, 2 * Math.PI, false);
28 | context.fill();
29 | };
30 |
--------------------------------------------------------------------------------
/examples/jsm/particles/Confetti.js:
--------------------------------------------------------------------------------
1 | var PI = Math.PI,
2 | random = Math.random,
3 | cos = Math.cos,
4 | sin = Math.sin;
5 |
6 | var DEG_TO_RAD = PI / 180,
7 | colors = [
8 | ["#df0049", "#660671"],
9 | ["#00e857", "#005291"],
10 | ["#2bebbc", "#05798a"],
11 | ["#ffd200", "#b06c00"]
12 | ];
13 |
14 | var _g, _res;
15 |
16 | export default class ConfettiParticle extends Tiny.Particle {
17 | constructor(emitter) {
18 | super(emitter);
19 |
20 | this.rotationSpeed = random() * 600 + 800;
21 | var angle = DEG_TO_RAD * random() * 360;
22 | this.rotationpart = DEG_TO_RAD * random() * 360;
23 | this.cosA = 1.0;
24 | this.size = 10.0;
25 | this.oscillationSpeed = random() * 1.5 + 0.5;
26 | this.xSpeed = 80.0;
27 | this.ySpeed = random() * 60 + 50.0;
28 | this.corners = new Array();
29 | this.time = random();
30 | var ci = Math.round(random() * (colors.length - 1));
31 | this.frontColor = colors[ci][0];
32 | this.backColor = colors[ci][1];
33 | for (var i = 0; i < 4; i++) {
34 | var dx = cos(angle + DEG_TO_RAD * (i * 90 + 45));
35 | var dy = sin(angle + DEG_TO_RAD * (i * 90 + 45));
36 | this.corners[i] = { x: dx, y: dy };
37 | }
38 | }
39 |
40 | _update(delta) {
41 | if (this.visible === false) return false;
42 |
43 | this.lifespan -= delta;
44 |
45 | if (this.lifespan <= 0) {
46 | this.visible = false;
47 | return false;
48 | }
49 |
50 | delta = delta * 0.001;
51 |
52 | this.time += delta;
53 | this.rotationpart += this.rotationSpeed * delta;
54 | this.cosA = cos(DEG_TO_RAD * this.rotationpart);
55 | this.x += cos(this.time * this.oscillationSpeed) * this.xSpeed * delta;
56 | this.y += this.ySpeed * delta;
57 | }
58 |
59 | render(renderSession) {
60 | if (this.visible === false || this.alpha === 0) return;
61 |
62 | _g = renderSession.context;
63 | _res = renderSession.resolution;
64 |
65 | if (this.cosA > 0) {
66 | _g.fillStyle = this.frontColor;
67 | } else {
68 | _g.fillStyle = this.backColor;
69 | }
70 | _g.beginPath();
71 | _g.moveTo(
72 | (this.x + this.corners[0].x * this.size) * _res,
73 | (this.y + this.corners[0].y * this.size * this.cosA) * _res
74 | );
75 | for (var i = 1; i < 4; i++) {
76 | _g.lineTo(
77 | (this.x + this.corners[i].x * this.size) * _res,
78 | (this.y + this.corners[i].y * this.size * this.cosA) * _res
79 | );
80 | }
81 | _g.closePath();
82 | _g.fill();
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/examples/jsm/particles/Explode.js:
--------------------------------------------------------------------------------
1 | export default class ExplodeParticle extends Tiny.Particle {
2 | constructor(emitter) {
3 | super(emitter);
4 | }
5 |
6 | update(time, delta) {
7 | var scale = Math.min(time / 200, 1);
8 | this.scale.set(scale * scale * scale * scale);
9 | this.alpha = Math.min(time / 250, 1);
10 |
11 | var speed = scale * scale * scale * scale * 5;
12 |
13 | this.x += this.xspeed * speed;
14 | this.y += this.yspeed * speed;
15 | }
16 |
17 | onEmit() {
18 | var randAgle = Math.random() * Math.PI * 2;
19 |
20 | var rand_speed = Math.random() * 3;
21 |
22 | this.xspeed = Math.sin(randAgle) * rand_speed;
23 | this.yspeed = Math.cos(randAgle) * rand_speed;
24 |
25 | this.x = this.xspeed * Math.random() * 3;
26 | this.y = this.yspeed * Math.random() * 3;
27 | }
28 |
29 | draw(context, resolution) {
30 | context.beginPath();
31 | context.arc(0, 0, 20 * resolution, 0, 2 * Math.PI, false);
32 | context.fill();
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/examples/jsm/particles/ExplodingConfetti.js:
--------------------------------------------------------------------------------
1 | const HALF_PI = Math.PI * 0.5;
2 | var timeStep = 1 / 60;
3 | var _g, _res, f, p, dx, dy;
4 |
5 | var Point = function (x, y) {
6 | this.x = x || 0;
7 | this.y = y || 0;
8 | };
9 |
10 | Point.prototype.set = function (x, y) {
11 | this.x = x || 0;
12 | this.y = y || 0;
13 | };
14 |
15 | var Ease = {
16 | inCubic: function (t, b, c, d) {
17 | t /= d;
18 | return c * t * t * t + b;
19 | },
20 | outCubic: function (t, b, c, d) {
21 | t /= d;
22 | t--;
23 | return c * (t * t * t + 1) + b;
24 | },
25 | inOutCubic: function (t, b, c, d) {
26 | t /= d / 2;
27 | if (t < 1) return (c / 2) * t * t * t + b;
28 | t -= 2;
29 | return (c / 2) * (t * t * t + 2) + b;
30 | },
31 | inBack: function (t, b, c, d, s) {
32 | s = s || 1.70158;
33 | return c * (t /= d) * t * ((s + 1) * t - s) + b;
34 | }
35 | };
36 |
37 | function cubeBezier(p0, c0, c1, p1, t) {
38 | var p = new Point();
39 | var nt = 1 - t;
40 |
41 | p.x = nt * nt * nt * p0.x + 3 * nt * nt * t * c0.x + 3 * nt * t * t * c1.x + t * t * t * p1.x;
42 | p.y = nt * nt * nt * p0.y + 3 * nt * nt * t * c0.y + 3 * nt * t * t * c1.y + t * t * t * p1.y;
43 |
44 | return p;
45 | }
46 |
47 | export default class ExplodingConfettiParticle extends Tiny.Particle {
48 | constructor(emitter) {
49 | super(emitter);
50 |
51 | this.duration = 3 + Math.random() * 2;
52 | this.color = "#" + Math.floor(Math.random() * 0xffffff).toString(16);
53 |
54 | this.p_w = 18;
55 | this.p_h = 16;
56 |
57 | this.p0 = new Point(0, 0); // Start point
58 |
59 | this.p1 = new Point();
60 | this.p2 = new Point();
61 | this.p3 = new Point();
62 | }
63 |
64 | onEmit() {
65 | this.position.set(0);
66 |
67 | this.time = 0;
68 |
69 | this.p1.set(
70 | this.p0.x - this.parent.width + this.parent.width * 2 * Math.random(),
71 | this.p0.y - this.parent.height / 2 + this.parent.height * Math.random()
72 | );
73 | this.p2.set(
74 | this.p0.x - this.parent.width + this.parent.width * 2 * Math.random(),
75 | this.p0.y - this.parent.height / 2 + this.parent.height * Math.random()
76 | );
77 | this.p3.set(
78 | this.p0.x - this.parent.width + this.parent.width * 2 * Math.random(),
79 | this.p0.y - this.parent.height / 2 + this.parent.height * 2
80 | );
81 | }
82 |
83 | _update(delta) {
84 | if (this.visible === false) return false;
85 |
86 | this.lifespan -= delta;
87 |
88 | if (this.lifespan <= 0) {
89 | this.visible = false;
90 | return false;
91 | }
92 |
93 | this.time = Math.min(this.duration, this.time + timeStep);
94 |
95 | f = Ease.outCubic(this.time, 0, 1, this.duration);
96 | p = cubeBezier(this.p0, this.p1, this.p2, this.p3, f);
97 |
98 | dx = p.x - this.x;
99 | dy = p.y - this.y;
100 |
101 | this.rotation = Math.atan2(dy, dx) + HALF_PI;
102 | this.scale.y = Math.sin(Math.PI * f * 10);
103 | this.position.x = p.x;
104 | this.position.y = p.y;
105 | }
106 |
107 | render(renderSession) {
108 | if (this.visible === false || this.alpha === 0) return;
109 |
110 | _g = renderSession.context;
111 | _res = renderSession.resolution;
112 |
113 | _g.save();
114 | _g.translate(this.position.x, this.position.y);
115 | _g.rotate(this.rotation);
116 | _g.scale(_res, this.scale.y * _res);
117 |
118 | _g.fillStyle = this.color;
119 | _g.fillRect(-this.p_w * 0.5, -this.p_h * 0.5, this.p_w * _res, this.p_h * _res);
120 |
121 | _g.restore();
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/examples/jsm/particles/Firework.js:
--------------------------------------------------------------------------------
1 | var normTime, speed;
2 |
3 | export default class FireworkParticle extends Tiny.Particle {
4 | constructor(emitter) {
5 | super(emitter);
6 | }
7 |
8 | update(time, delta) {
9 | normTime = time / this.maxlifespan;
10 |
11 | this.scale.set(Math.tan(normTime * normTime));
12 |
13 | this.alpha = Math.min(Math.tan(normTime), 1);
14 |
15 | speed = normTime * normTime * normTime * 10;
16 |
17 | this.x += this.xspeed * speed * delta * normTime;
18 | this.y += this.yspeed * speed * delta + normTime * 10 * delta;
19 | }
20 |
21 | onEmit() {
22 | var randAgle = Math.random() * Math.PI * 2;
23 |
24 | var rand_speed = Math.random() * 3;
25 |
26 | this.maxlifespan = this.lifespan;
27 |
28 | this.xspeed = Math.sin(randAgle) * rand_speed * 0.05;
29 | this.yspeed = Math.cos(randAgle) * rand_speed * 0.05;
30 | }
31 |
32 | draw(context, resolution) {
33 | context.beginPath();
34 | context.arc(0, 0, 20 * resolution, 0, 2 * Math.PI, false);
35 | context.fill();
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/examples/jsm/particles/MoneyFalling.js:
--------------------------------------------------------------------------------
1 | var random = Math.random,
2 | cos = Math.cos,
3 | sin = Math.sin;
4 |
5 | export default class MoneyFallingParticle extends Tiny.Particle {
6 | constructor(emitter) {
7 | super(emitter);
8 | }
9 |
10 | onEmit() {
11 | this.tilt = Math.floor(random() * 10) - 10;
12 | this.tiltAngleIncremental = random() * 0.25 + 0.15 - 0.2;
13 | this.tiltAngle = 0;
14 | this.scale.set((random() * 0.4 + 0.6) / 2);
15 | this.angle = random() * 6.28;
16 |
17 | this.speed = random() * 1 + 0.5;
18 | }
19 |
20 | update(time, delta) {
21 | delta = delta * 0.001;
22 | this.angle += delta;
23 | this.tiltAngle += this.tiltAngleIncremental;
24 | this.y += ((cos(this.angle + 3) + 3 + 2 / 2) / 2) * delta * 100 * this.speed;
25 | this.x += sin(this.angle) * delta * 100 * this.speed;
26 | this.rotation = sin(this.tiltAngle) * 0.5 * this.speed;
27 | }
28 |
29 | render(renderSession) {
30 | if (this.visible === false || this.alpha === 0) return;
31 |
32 | renderSession.context.setTransform(
33 | this.worldTransform.a * cos(this.tiltAngle),
34 | this.worldTransform.b,
35 | this.worldTransform.c,
36 | this.worldTransform.d,
37 | this.worldTransform.tx * renderSession.resolution,
38 | this.worldTransform.ty * renderSession.resolution
39 | );
40 |
41 | this.drawTexture(renderSession);
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/examples/jsm/particles/Smoke.js:
--------------------------------------------------------------------------------
1 | export default class SmokeParticle extends Tiny.Particle {
2 | constructor(emitter) {
3 | super(emitter);
4 | }
5 |
6 | update(time, delta) {
7 | this.scale.set(Math.min(time / 1000, 0.7));
8 | this.alpha = Math.min(time / 1000, 1);
9 |
10 | this.y -= this.yspeed * delta;
11 | this.x += this.xspeed * delta;
12 | this.rotation += this.rotationsp;
13 | }
14 |
15 | onEmit() {
16 | this.xspeed = Tiny.rnd(-4, 4) * 0.05;
17 | this.yspeed = Tiny.rnd(2, 10) * 0.05;
18 | this.rotationsp = Math.random() * 0.02 - 0.01;
19 | }
20 |
21 | draw(context, resolution) {
22 | context.fillRect(0, 0, 100 * resolution, 100 * resolution);
23 |
24 | // context.beginPath();
25 | // context.arc(0, 0, 100, 0, 2 * Math.PI, false);
26 | // context.fill();
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/examples/libs/ace/ext-keybinding_menu.js:
--------------------------------------------------------------------------------
1 | define("ace/ext/menu_tools/settings_menu.css",["require","exports","module"],function(e,t,n){n.exports="#ace_settingsmenu, #kbshortcutmenu {\n background-color: #F7F7F7;\n color: black;\n box-shadow: -5px 4px 5px rgba(126, 126, 126, 0.55);\n padding: 1em 0.5em 2em 1em;\n overflow: auto;\n position: absolute;\n margin: 0;\n bottom: 0;\n right: 0;\n top: 0;\n z-index: 9991;\n cursor: default;\n}\n\n.ace_dark #ace_settingsmenu, .ace_dark #kbshortcutmenu {\n box-shadow: -20px 10px 25px rgba(126, 126, 126, 0.25);\n background-color: rgba(255, 255, 255, 0.6);\n color: black;\n}\n\n.ace_optionsMenuEntry:hover {\n background-color: rgba(100, 100, 100, 0.1);\n transition: all 0.3s\n}\n\n.ace_closeButton {\n background: rgba(245, 146, 146, 0.5);\n border: 1px solid #F48A8A;\n border-radius: 50%;\n padding: 7px;\n position: absolute;\n right: -8px;\n top: -8px;\n z-index: 100000;\n}\n.ace_closeButton{\n background: rgba(245, 146, 146, 0.9);\n}\n.ace_optionsMenuKey {\n color: darkslateblue;\n font-weight: bold;\n}\n.ace_optionsMenuCommand {\n color: darkcyan;\n font-weight: normal;\n}\n.ace_optionsMenuEntry input, .ace_optionsMenuEntry button {\n vertical-align: middle;\n}\n\n.ace_optionsMenuEntry button[ace_selected_button=true] {\n background: #e7e7e7;\n box-shadow: 1px 0px 2px 0px #adadad inset;\n border-color: #adadad;\n}\n.ace_optionsMenuEntry button {\n background: white;\n border: 1px solid lightgray;\n margin: 0px;\n}\n.ace_optionsMenuEntry button:hover{\n background: #f0f0f0;\n}"}),define("ace/ext/menu_tools/overlay_page",["require","exports","module","ace/lib/dom","ace/ext/menu_tools/settings_menu.css"],function(e,t,n){"use strict";var r=e("../../lib/dom"),i=e("./settings_menu.css");r.importCssString(i,"settings_menu.css",!1),n.exports.overlayPage=function(t,n,r){function o(e){e.keyCode===27&&u()}function u(){if(!i)return;document.removeEventListener("keydown",o),i.parentNode.removeChild(i),t&&t.focus(),i=null,r&&r()}function a(e){s=e,e&&(i.style.pointerEvents="none",n.style.pointerEvents="auto")}var i=document.createElement("div"),s=!1;return i.style.cssText="margin: 0; padding: 0; position: fixed; top:0; bottom:0; left:0; right:0;z-index: 9990; "+(t?"background-color: rgba(0, 0, 0, 0.3);":""),i.addEventListener("click",function(e){s||u()}),document.addEventListener("keydown",o),n.addEventListener("click",function(e){e.stopPropagation()}),i.appendChild(n),document.body.appendChild(i),t&&t.blur(),{close:u,setIgnoreFocusOut:a}}}),define("ace/ext/menu_tools/get_editor_keyboard_shortcuts",["require","exports","module","ace/lib/keys"],function(e,t,n){"use strict";var r=e("../../lib/keys");n.exports.getEditorKeybordShortcuts=function(e){var t=r.KEY_MODS,n=[],i={};return e.keyBinding.$handlers.forEach(function(e){var t=e.commandKeyBinding;for(var r in t){var s=r.replace(/(^|-)\w/g,function(e){return e.toUpperCase()}),o=t[r];Array.isArray(o)||(o=[o]),o.forEach(function(e){typeof e!="string"&&(e=e.name),i[e]?i[e].key+="|"+s:(i[e]={key:s,command:e},n.push(i[e]))})}}),n}}),define("ace/ext/keybinding_menu",["require","exports","module","ace/editor","ace/ext/menu_tools/overlay_page","ace/ext/menu_tools/get_editor_keyboard_shortcuts"],function(e,t,n){"use strict";function i(t){if(!document.getElementById("kbshortcutmenu")){var n=e("./menu_tools/overlay_page").overlayPage,r=e("./menu_tools/get_editor_keyboard_shortcuts").getEditorKeybordShortcuts,i=r(t),s=document.createElement("div"),o=i.reduce(function(e,t){return e+'
"},"");s.id="kbshortcutmenu",s.innerHTML="Keyboard Shortcuts
"+o+"",n(t,s)}}var r=e("../editor").Editor;n.exports.init=function(e){r.prototype.showKeyboardShortcuts=function(){i(this)},e.commands.addCommands([{name:"showKeyboardShortcuts",bindKey:{win:"Ctrl-Alt-h",mac:"Command-Alt-h"},exec:function(e,t){e.showKeyboardShortcuts()}}])}}); (function() {
2 | window.require(["ace/ext/keybinding_menu"], function(m) {
3 | if (typeof module == "object" && typeof exports == "object" && module) {
4 | module.exports = m;
5 | }
6 | });
7 | })();
8 |
--------------------------------------------------------------------------------
/examples/libs/ace/ext-spellcheck.js:
--------------------------------------------------------------------------------
1 | define("ace/ext/spellcheck",["require","exports","module","ace/lib/event","ace/editor","ace/config"],function(e,t,n){"use strict";var r=e("../lib/event");t.contextMenuHandler=function(e){var t=e.target,n=t.textInput.getElement();if(!t.selection.isEmpty())return;var i=t.getCursorPosition(),s=t.session.getWordRange(i.row,i.column),o=t.session.getTextRange(s);t.session.tokenRe.lastIndex=0;if(!t.session.tokenRe.test(o))return;var u="\x01\x01",a=o+" "+u;n.value=a,n.setSelectionRange(o.length,o.length+1),n.setSelectionRange(0,0),n.setSelectionRange(0,o.length);var f=!1;r.addListener(n,"keydown",function l(){r.removeListener(n,"keydown",l),f=!0}),t.textInput.setInputHandler(function(e){if(e==a)return"";if(e.lastIndexOf(a,0)===0)return e.slice(a.length);if(e.substr(n.selectionEnd)==a)return e.slice(0,-a.length);if(e.slice(-2)==u){var r=e.slice(0,-2);if(r.slice(-1)==" ")return f?r.substring(0,n.selectionEnd):(r=r.slice(0,-1),t.session.replace(s,r),"")}return e})};var i=e("../editor").Editor;e("../config").defineOptions(i.prototype,"editor",{spellcheck:{set:function(e){var n=this.textInput.getElement();n.spellcheck=!!e,e?this.on("nativecontextmenu",t.contextMenuHandler):this.removeListener("nativecontextmenu",t.contextMenuHandler)},value:!0}})}); (function() {
2 | window.require(["ace/ext/spellcheck"], function(m) {
3 | if (typeof module == "object" && typeof exports == "object" && module) {
4 | module.exports = m;
5 | }
6 | });
7 | })();
8 |
--------------------------------------------------------------------------------
/examples/libs/ace/snippets/javascript.js:
--------------------------------------------------------------------------------
1 | define("ace/snippets/javascript.snippets",["require","exports","module"],function(e,t,n){n.exports='# Prototype\nsnippet proto\n ${1:class_name}.prototype.${2:method_name} = function(${3:first_argument}) {\n ${4:// body...}\n };\n# Function\nsnippet fun\n function ${1?:function_name}(${2:argument}) {\n ${3:// body...}\n }\n# Anonymous Function\nregex /((=)\\s*|(:)\\s*|(\\()|\\b)/f/(\\))?/\nsnippet f\n function${M1?: ${1:functionName}}($2) {\n ${0:$TM_SELECTED_TEXT}\n }${M2?;}${M3?,}${M4?)}\n# Immediate function\ntrigger \\(?f\\(\nendTrigger \\)?\nsnippet f(\n (function(${1}) {\n ${0:${TM_SELECTED_TEXT:/* code */}}\n }(${1}));\n# if\nsnippet if\n if (${1:true}) {\n ${0}\n }\n# if ... else\nsnippet ife\n if (${1:true}) {\n ${2}\n } else {\n ${0}\n }\n# tertiary conditional\nsnippet ter\n ${1:/* condition */} ? ${2:a} : ${3:b}\n# switch\nsnippet switch\n switch (${1:expression}) {\n case \'${3:case}\':\n ${4:// code}\n break;\n ${5}\n default:\n ${2:// code}\n }\n# case\nsnippet case\n case \'${1:case}\':\n ${2:// code}\n break;\n ${3}\n\n# while (...) {...}\nsnippet wh\n while (${1:/* condition */}) {\n ${0:/* code */}\n }\n# try\nsnippet try\n try {\n ${0:/* code */}\n } catch (e) {}\n# do...while\nsnippet do\n do {\n ${2:/* code */}\n } while (${1:/* condition */});\n# Object Method\nsnippet :f\nregex /([,{[])|^\\s*/:f/\n ${1:method_name}: function(${2:attribute}) {\n ${0}\n }${3:,}\n# setTimeout function\nsnippet setTimeout\nregex /\\b/st|timeout|setTimeo?u?t?/\n setTimeout(function() {${3:$TM_SELECTED_TEXT}}, ${1:10});\n# Get Elements\nsnippet gett\n getElementsBy${1:TagName}(\'${2}\')${3}\n# Get Element\nsnippet get\n getElementBy${1:Id}(\'${2}\')${3}\n# console.log (Firebug)\nsnippet cl\n console.log(${1});\n# return\nsnippet ret\n return ${1:result}\n# for (property in object ) { ... }\nsnippet fori\n for (var ${1:prop} in ${2:Things}) {\n ${0:$2[$1]}\n }\n# hasOwnProperty\nsnippet has\n hasOwnProperty(${1})\n# docstring\nsnippet /**\n /**\n * ${1:description}\n *\n */\nsnippet @par\nregex /^\\s*\\*\\s*/@(para?m?)?/\n @param {${1:type}} ${2:name} ${3:description}\nsnippet @ret\n @return {${1:type}} ${2:description}\n# JSON.parse\nsnippet jsonp\n JSON.parse(${1:jstr});\n# JSON.stringify\nsnippet jsons\n JSON.stringify(${1:object});\n# self-defining function\nsnippet sdf\n var ${1:function_name} = function(${2:argument}) {\n ${3:// initial code ...}\n\n $1 = function($2) {\n ${4:// main code}\n };\n }\n# singleton\nsnippet sing\n function ${1:Singleton} (${2:argument}) {\n // the cached instance\n var instance;\n\n // rewrite the constructor\n $1 = function $1($2) {\n return instance;\n };\n \n // carry over the prototype properties\n $1.prototype = this;\n\n // the instance\n instance = new $1();\n\n // reset the constructor pointer\n instance.constructor = $1;\n\n ${3:// code ...}\n\n return instance;\n }\n# class\nsnippet class\nregex /^\\s*/clas{0,2}/\n var ${1:class} = function(${20}) {\n $40$0\n };\n \n (function() {\n ${60:this.prop = ""}\n }).call(${1:class}.prototype);\n \n exports.${1:class} = ${1:class};\n# \nsnippet for-\n for (var ${1:i} = ${2:Things}.length; ${1:i}--; ) {\n ${0:${2:Things}[${1:i}];}\n }\n# for (...) {...}\nsnippet for\n for (var ${1:i} = 0; $1 < ${2:Things}.length; $1++) {\n ${3:$2[$1]}$0\n }\n# for (...) {...} (Improved Native For-Loop)\nsnippet forr\n for (var ${1:i} = ${2:Things}.length - 1; $1 >= 0; $1--) {\n ${3:$2[$1]}$0\n }\n\n\n#modules\nsnippet def\n define(function(require, exports, module) {\n "use strict";\n var ${1/.*\\///} = require("${1}");\n \n $TM_SELECTED_TEXT\n });\nsnippet req\nguard ^\\s*\n var ${1/.*\\///} = require("${1}");\n $0\nsnippet requ\nguard ^\\s*\n var ${1/.*\\/(.)/\\u$1/} = require("${1}").${1/.*\\/(.)/\\u$1/};\n $0\n'}),define("ace/snippets/javascript",["require","exports","module","ace/snippets/javascript.snippets"],function(e,t,n){"use strict";t.snippetText=e("./javascript.snippets"),t.scope="javascript"}); (function() {
2 | window.require(["ace/snippets/javascript"], function(m) {
3 | if (typeof module == "object" && typeof exports == "object" && module) {
4 | module.exports = m;
5 | }
6 | });
7 | })();
8 |
--------------------------------------------------------------------------------
/examples/libs/ace/theme-monokai.js:
--------------------------------------------------------------------------------
1 | define("ace/theme/monokai.css",["require","exports","module"],function(e,t,n){n.exports=".ace-monokai .ace_gutter {\n background: #2F3129;\n color: #8F908A\n}\n\n.ace-monokai .ace_print-margin {\n width: 1px;\n background: #555651\n}\n\n.ace-monokai {\n background-color: #272822;\n color: #F8F8F2\n}\n\n.ace-monokai .ace_cursor {\n color: #F8F8F0\n}\n\n.ace-monokai .ace_marker-layer .ace_selection {\n background: #49483E\n}\n\n.ace-monokai.ace_multiselect .ace_selection.ace_start {\n box-shadow: 0 0 3px 0px #272822;\n}\n\n.ace-monokai .ace_marker-layer .ace_step {\n background: rgb(102, 82, 0)\n}\n\n.ace-monokai .ace_marker-layer .ace_bracket {\n margin: -1px 0 0 -1px;\n border: 1px solid #49483E\n}\n\n.ace-monokai .ace_marker-layer .ace_active-line {\n background: #202020\n}\n\n.ace-monokai .ace_gutter-active-line {\n background-color: #272727\n}\n\n.ace-monokai .ace_marker-layer .ace_selected-word {\n border: 1px solid #49483E\n}\n\n.ace-monokai .ace_invisible {\n color: #52524d\n}\n\n.ace-monokai .ace_entity.ace_name.ace_tag,\n.ace-monokai .ace_keyword,\n.ace-monokai .ace_meta.ace_tag,\n.ace-monokai .ace_storage {\n color: #F92672\n}\n\n.ace-monokai .ace_punctuation,\n.ace-monokai .ace_punctuation.ace_tag {\n color: #fff\n}\n\n.ace-monokai .ace_constant.ace_character,\n.ace-monokai .ace_constant.ace_language,\n.ace-monokai .ace_constant.ace_numeric,\n.ace-monokai .ace_constant.ace_other {\n color: #AE81FF\n}\n\n.ace-monokai .ace_invalid {\n color: #F8F8F0;\n background-color: #F92672\n}\n\n.ace-monokai .ace_invalid.ace_deprecated {\n color: #F8F8F0;\n background-color: #AE81FF\n}\n\n.ace-monokai .ace_support.ace_constant,\n.ace-monokai .ace_support.ace_function {\n color: #66D9EF\n}\n\n.ace-monokai .ace_fold {\n background-color: #A6E22E;\n border-color: #F8F8F2\n}\n\n.ace-monokai .ace_storage.ace_type,\n.ace-monokai .ace_support.ace_class,\n.ace-monokai .ace_support.ace_type {\n font-style: italic;\n color: #66D9EF\n}\n\n.ace-monokai .ace_entity.ace_name.ace_function,\n.ace-monokai .ace_entity.ace_other,\n.ace-monokai .ace_entity.ace_other.ace_attribute-name,\n.ace-monokai .ace_variable {\n color: #A6E22E\n}\n\n.ace-monokai .ace_variable.ace_parameter {\n font-style: italic;\n color: #FD971F\n}\n\n.ace-monokai .ace_string {\n color: #E6DB74\n}\n\n.ace-monokai .ace_comment {\n color: #75715E\n}\n\n.ace-monokai .ace_indent-guide {\n background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWPQ0FD0ZXBzd/wPAAjVAoxeSgNeAAAAAElFTkSuQmCC) right repeat-y\n}\n\n.ace-monokai .ace_indent-guide-active {\n background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQIW2PQ1dX9zzBz5sz/ABCcBFFentLlAAAAAElFTkSuQmCC) right repeat-y;\n}\n"}),define("ace/theme/monokai",["require","exports","module","ace/theme/monokai.css","ace/lib/dom"],function(e,t,n){t.isDark=!0,t.cssClass="ace-monokai",t.cssText=e("./monokai.css");var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass,!1)}); (function() {
2 | window.require(["ace/theme/monokai"], function(m) {
3 | if (typeof module == "object" && typeof exports == "object" && module) {
4 | module.exports = m;
5 | }
6 | });
7 | })();
8 |
--------------------------------------------------------------------------------
/examples/libs/tiny/plugins/three.js.LICENSE.txt:
--------------------------------------------------------------------------------
1 | //!\ DECLARE ALIAS AFTER assign prototype !
2 |
--------------------------------------------------------------------------------
/examples/libs/tiny/tiny.js.LICENSE.txt:
--------------------------------------------------------------------------------
1 | /*! ./App.js */
2 |
3 | /*! ./base.js */
4 |
5 | /*! ./global.js */
6 |
7 | /*! ./math/Circle.js */
8 |
9 | /*! ./math/Math.js */
10 |
11 | /*! ./math/Matrix.js */
12 |
13 | /*! ./math/Point.js */
14 |
15 | /*! ./math/Polygon.js */
16 |
17 | /*! ./math/Rectangle.js */
18 |
19 | /*! ./math/RoundedRectangle.js */
20 |
21 | /*! ./mini.js */
22 |
23 | /*! ./objects/BaseObject2D.js */
24 |
25 | /*! ./objects/Graphics.js */
26 |
27 | /*! ./objects/Object2D.js */
28 |
29 | /*! ./objects/Scene.js */
30 |
31 | /*! ./objects/Sprite.js */
32 |
33 | /*! ./objects/Text.js */
34 |
35 | /*! ./renderers/CanvasMaskManager.js */
36 |
37 | /*! ./renderers/CanvasRenderer.js */
38 |
39 | /*! ./renderers/CanvasTinter.js */
40 |
41 | /*! ./renderers/GraphicsRenderer.js */
42 |
43 | /*! ./systems/Input.js */
44 |
45 | /*! ./systems/Loader.js */
46 |
47 | /*! ./systems/RAF.js */
48 |
49 | /*! ./systems/Timer.js */
50 |
51 | /*! ./systems/Tween.js */
52 |
53 | /*! ./textures/RenderTexture.js */
54 |
55 | /*! ./textures/Texture.js */
56 |
57 | /*! ./utils/CanvasBuffer.js */
58 |
59 | /*! ./utils/EventEmitter.js */
60 |
61 | /*! ./utils/polyfill.js */
62 |
63 | /*!********************!*\
64 | !*** ./src/App.js ***!
65 | \********************/
66 |
67 | /*!*********************!*\
68 | !*** ./src/base.js ***!
69 | \*********************/
70 |
71 | /*!*********************!*\
72 | !*** ./src/mini.js ***!
73 | \*********************/
74 |
75 | /*!**********************!*\
76 | !*** ./src/index.js ***!
77 | \**********************/
78 |
79 | /*!***********************!*\
80 | !*** ./src/global.js ***!
81 | \***********************/
82 |
83 | /*!**************************!*\
84 | !*** ./src/math/Math.js ***!
85 | \**************************/
86 |
87 | /*!***************************!*\
88 | !*** ./src/math/Point.js ***!
89 | \***************************/
90 |
91 | /*!****************************!*\
92 | !*** ./src/math/Circle.js ***!
93 | \****************************/
94 |
95 | /*!****************************!*\
96 | !*** ./src/math/Matrix.js ***!
97 | \****************************/
98 |
99 | /*!****************************!*\
100 | !*** ./src/systems/RAF.js ***!
101 | \****************************/
102 |
103 | /*!*****************************!*\
104 | !*** ./src/math/Polygon.js ***!
105 | \*****************************/
106 |
107 | /*!*****************************!*\
108 | !*** ./src/objects/Text.js ***!
109 | \*****************************/
110 |
111 | /*!******************************!*\
112 | !*** ./src/objects/Scene.js ***!
113 | \******************************/
114 |
115 | /*!******************************!*\
116 | !*** ./src/systems/Input.js ***!
117 | \******************************/
118 |
119 | /*!******************************!*\
120 | !*** ./src/systems/Timer.js ***!
121 | \******************************/
122 |
123 | /*!******************************!*\
124 | !*** ./src/systems/Tween.js ***!
125 | \******************************/
126 |
127 | /*!*******************************!*\
128 | !*** ./src/math/Rectangle.js ***!
129 | \*******************************/
130 |
131 | /*!*******************************!*\
132 | !*** ./src/objects/Sprite.js ***!
133 | \*******************************/
134 |
135 | /*!*******************************!*\
136 | !*** ./src/systems/Loader.js ***!
137 | \*******************************/
138 |
139 | /*!*******************************!*\
140 | !*** ./src/utils/polyfill.js ***!
141 | \*******************************/
142 |
143 | /*!*********************************!*\
144 | !*** ./src/objects/Graphics.js ***!
145 | \*********************************/
146 |
147 | /*!*********************************!*\
148 | !*** ./src/objects/Object2D.js ***!
149 | \*********************************/
150 |
151 | /*!*********************************!*\
152 | !*** ./src/textures/Texture.js ***!
153 | \*********************************/
154 |
155 | /*!***********************************!*\
156 | !*** ./src/utils/CanvasBuffer.js ***!
157 | \***********************************/
158 |
159 | /*!***********************************!*\
160 | !*** ./src/utils/EventEmitter.js ***!
161 | \***********************************/
162 |
163 | /*!*************************************!*\
164 | !*** ./src/objects/BaseObject2D.js ***!
165 | \*************************************/
166 |
167 | /*!**************************************!*\
168 | !*** ./src/math/RoundedRectangle.js ***!
169 | \**************************************/
170 |
171 | /*!***************************************!*\
172 | !*** ./src/renderers/CanvasTinter.js ***!
173 | \***************************************/
174 |
175 | /*!***************************************!*\
176 | !*** ./src/textures/RenderTexture.js ***!
177 | \***************************************/
178 |
179 | /*!*****************************************!*\
180 | !*** ./src/renderers/CanvasRenderer.js ***!
181 | \*****************************************/
182 |
183 | /*!*******************************************!*\
184 | !*** ./src/renderers/GraphicsRenderer.js ***!
185 | \*******************************************/
186 |
187 | /*!********************************************!*\
188 | !*** ./src/renderers/CanvasMaskManager.js ***!
189 | \********************************************/
190 |
--------------------------------------------------------------------------------
/examples/libs/tiny/tiny.mini.js.LICENSE.txt:
--------------------------------------------------------------------------------
1 | /*! ./App.js */
2 |
3 | /*! ./base.js */
4 |
5 | /*! ./global.js */
6 |
7 | /*! ./math/Math.js */
8 |
9 | /*! ./math/Matrix.js */
10 |
11 | /*! ./math/Point.js */
12 |
13 | /*! ./math/Rectangle.js */
14 |
15 | /*! ./objects/BaseObject2D.js */
16 |
17 | /*! ./objects/Object2D.js */
18 |
19 | /*! ./objects/Scene.js */
20 |
21 | /*! ./objects/Sprite.js */
22 |
23 | /*! ./objects/Text.js */
24 |
25 | /*! ./renderers/CanvasRenderer.js */
26 |
27 | /*! ./systems/Input.js */
28 |
29 | /*! ./systems/Loader.js */
30 |
31 | /*! ./systems/RAF.js */
32 |
33 | /*! ./systems/Timer.js */
34 |
35 | /*! ./textures/Texture.js */
36 |
37 | /*! ./utils/EventEmitter.js */
38 |
39 | /*! ./utils/polyfill.js */
40 |
41 | /*!********************!*\
42 | !*** ./src/App.js ***!
43 | \********************/
44 |
45 | /*!*********************!*\
46 | !*** ./src/base.js ***!
47 | \*********************/
48 |
49 | /*!*********************!*\
50 | !*** ./src/mini.js ***!
51 | \*********************/
52 |
53 | /*!***********************!*\
54 | !*** ./src/global.js ***!
55 | \***********************/
56 |
57 | /*!**************************!*\
58 | !*** ./src/math/Math.js ***!
59 | \**************************/
60 |
61 | /*!***************************!*\
62 | !*** ./src/math/Point.js ***!
63 | \***************************/
64 |
65 | /*!****************************!*\
66 | !*** ./src/math/Matrix.js ***!
67 | \****************************/
68 |
69 | /*!****************************!*\
70 | !*** ./src/systems/RAF.js ***!
71 | \****************************/
72 |
73 | /*!*****************************!*\
74 | !*** ./src/objects/Text.js ***!
75 | \*****************************/
76 |
77 | /*!******************************!*\
78 | !*** ./src/objects/Scene.js ***!
79 | \******************************/
80 |
81 | /*!******************************!*\
82 | !*** ./src/systems/Input.js ***!
83 | \******************************/
84 |
85 | /*!******************************!*\
86 | !*** ./src/systems/Timer.js ***!
87 | \******************************/
88 |
89 | /*!*******************************!*\
90 | !*** ./src/math/Rectangle.js ***!
91 | \*******************************/
92 |
93 | /*!*******************************!*\
94 | !*** ./src/objects/Sprite.js ***!
95 | \*******************************/
96 |
97 | /*!*******************************!*\
98 | !*** ./src/systems/Loader.js ***!
99 | \*******************************/
100 |
101 | /*!*******************************!*\
102 | !*** ./src/utils/polyfill.js ***!
103 | \*******************************/
104 |
105 | /*!*********************************!*\
106 | !*** ./src/objects/Object2D.js ***!
107 | \*********************************/
108 |
109 | /*!*********************************!*\
110 | !*** ./src/textures/Texture.js ***!
111 | \*********************************/
112 |
113 | /*!***********************************!*\
114 | !*** ./src/utils/EventEmitter.js ***!
115 | \***********************************/
116 |
117 | /*!*************************************!*\
118 | !*** ./src/objects/BaseObject2D.js ***!
119 | \*************************************/
120 |
121 | /*!*****************************************!*\
122 | !*** ./src/renderers/CanvasRenderer.js ***!
123 | \*****************************************/
124 |
--------------------------------------------------------------------------------
/examples/res/image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smoudjs/tiny/2fce883dc7bee738ffb883a681d32156c8a2cdec/examples/res/image.png
--------------------------------------------------------------------------------
/examples/res/image2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smoudjs/tiny/2fce883dc7bee738ffb883a681d32156c8a2cdec/examples/res/image2.png
--------------------------------------------------------------------------------
/examples/res/script.js:
--------------------------------------------------------------------------------
1 | (function () {
2 | var script = document.createElement('script');
3 |
4 | script.onload = function () {
5 | var stats = new Stats();
6 | document.body.appendChild(stats.dom);
7 | requestAnimationFrame(function loop() {
8 | stats.update();
9 | requestAnimationFrame(loop);
10 | });
11 | };
12 |
13 | script.src = 'https://mrdoob.github.io/stats.js/build/stats.min.js';
14 | document.head.appendChild(script);
15 | })();
16 |
17 | document.addEventListener('scroll', function () {
18 | window.game && window.game.input.updateBounds();
19 | });
20 |
21 | window.addEventListener('resize', function () {
22 | window.game && window.game.input.updateBounds();
23 | });
24 |
25 | window.config = {
26 | width: 640,
27 | height: 400
28 | };
29 |
30 | window.GLTFLoader = THREE.GLTFLoader;
31 |
32 | window.initTest = function (states) {
33 | destroyGame();
34 |
35 | const container = document.getElementById('game-container');
36 | container.innerHTML = '';
37 |
38 | // var game;
39 |
40 | // if (!is3D) {
41 | // game = window.game = new Tiny.App2D(config.width, config.height, 'test-container', states);
42 | // } else {
43 | // game = window.game = new Tiny.App3D(config.width, config.height, 'test-container', states);
44 | // }
45 |
46 | var game = (window.game = new MyGame(config.width, config.height));
47 |
48 | game.once('postrender', () => {
49 | resizeCanvas(config.width, config.height);
50 | });
51 | };
52 |
53 | window.destroyGame = function () {
54 | if (window.game) {
55 | window.game.destroy();
56 | window.game = null;
57 | }
58 | const container = document.getElementById('game-container');
59 | container.style.minWidth = '640px';
60 | container.style.minHeight = '400px';
61 | };
62 |
63 | window.resizeCanvas = function (width, height) {
64 | if (window.game) {
65 | const container = document.getElementById('game-container');
66 | config.width = width || Math.floor(Math.random() * 400) + 400;
67 | config.height = height || Math.floor(Math.random() * 300) + 300;
68 |
69 | container.style.minWidth = '';
70 | container.style.minHeight = '';
71 |
72 | window.game.resize(config.width, config.height);
73 | }
74 | };
75 |
76 | window.addEventListener('load', function (argument) {
77 | ace.require('ace/ext/language_tools');
78 |
79 | var editor = ace.edit('editor');
80 |
81 | editor.setOptions({
82 | enableBasicAutocompletion: true,
83 | enableSnippets: true,
84 | enableLiveAutocompletion: true,
85 | copyWithEmptySelection: true
86 | });
87 |
88 | editor.setHighlightActiveLine(true);
89 |
90 | editor.session.on('changeMode', function (e, session) {
91 | if ('ace/mode/javascript' === session.getMode().$id) {
92 | if (!!session.$worker) {
93 | session.$worker.send('setOptions', [
94 | {
95 | esversion: 9,
96 | esnext: true
97 | }
98 | ]);
99 | }
100 | }
101 | });
102 |
103 | editor.setTheme('ace/theme/monokai');
104 | editor.session.setMode('ace/mode/javascript');
105 |
106 | window.editor = editor;
107 |
108 |
109 | window.initCode = function (name) {
110 |
111 | var urlEl = document.getElementById('url-el');
112 |
113 | var url = 'https://github.com/smoudjs/tiny/blob/master/examples/tests/' + name + '.js';
114 |
115 | urlEl.innerHTML = url;
116 | urlEl.href = url;
117 |
118 | fetch('tests/' + name + '.js')
119 | .then((res) => {
120 | res.text().then((e) => {
121 | // var js = ace.createEditSession(e);
122 | // var css = ace.createEditSession(["some", "css", "code here"]);
123 | // // and then to load document into editor, just call
124 | // editor.setSession(js);
125 | editor.session.setValue(e);
126 | runCode();
127 | // editor.setValue(e);
128 |
129 | // editor.session.replace(editor.selection.getRange(), e);
130 | });
131 | })
132 | .catch((err) => {
133 | alert(err.message);
134 | });
135 | };
136 |
137 | window.runCode = function () {
138 | var code = editor.getValue();
139 |
140 | code = '(function () {' + code + ';window.MyGame = MyGame;})()';
141 |
142 | var script = document.createElement('script');
143 | script.text = code;
144 | document.body.appendChild(script);
145 |
146 | initTest();
147 | };
148 |
149 | window.saveCode = function () {
150 |
151 | var link = document.createElement('a');
152 | var file = new Blob([editor.getValue()], { type: 'application/javascript' });
153 | link.href = URL.createObjectURL(file);
154 | link.download = 'MyGame.js';
155 | link.click();
156 | URL.revokeObjectURL(link.href);
157 | };
158 |
159 | document.addEventListener('keydown', (e) => {
160 | if (e.ctrlKey && e.key === 's') {
161 | // Prevent the Save dialog to open
162 | e.preventDefault();
163 | // Place your code here
164 | runCode();
165 | }
166 | });
167 |
168 | document.getElementById('resources-list').innerHTML = Object.keys(resources).join(", ");
169 | });
170 |
--------------------------------------------------------------------------------
/examples/res/style.css:
--------------------------------------------------------------------------------
1 | body {
2 | font-family: monospace;
3 | background-color: #fff;
4 | color: #454545;
5 | font-family: Nunito, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, Arial,
6 | sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji;
7 | font-size: 1rem;
8 | font-weight: 400;
9 | line-height: 1.5;
10 | margin: 0;
11 | text-align: left;
12 | }
13 |
14 | hr {
15 | width: 100%;
16 | }
17 |
18 | h3 {
19 | font-family: monospace;
20 | margin-top: 10px;
21 | margin-bottom: 5px;
22 | color: #0249ff;
23 | }
24 |
25 | .btn {
26 | font-family: monospace;
27 | border: 0px;
28 | border-bottom: 2px solid #8ec6ff;
29 | display: inline-block;
30 | font-size: 1rem;
31 | font-weight: 400;
32 | padding: 0.375rem 0.75rem;
33 | text-align: center;
34 | transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;
35 | -webkit-user-select: none;
36 | -ms-user-select: none;
37 | user-select: none;
38 | vertical-align: middle;
39 | background-color: #396fa7;
40 | color: #ffffff;
41 | cursor: pointer;
42 | margin: 0px 3px 0px 3px;
43 | }
44 |
45 | .left-panel {
46 | width: 25%;
47 | text-align: center;
48 | display: flex;
49 | flex-direction: column;
50 | padding: 15px;
51 | background-color: #f9f9f9;
52 | }
53 |
54 | .right-panel {
55 | width: 75%;
56 | display: flex;
57 | align-items: center;
58 | flex-direction: column;
59 | padding: 15px;
60 | border-left: 1px solid #c4c4c4;
61 | background-color: #f2f6ff;
62 | }
63 |
64 | .canvas-container {
65 | border: 3px solid rgb(17, 114, 169);
66 | line-height: 0;
67 | border-radius: 5px;
68 | }
69 |
70 | .controll {
71 | display: flex;
72 | background-color: #396fa7;
73 | padding: 8px 10px 5px 10px;
74 | border-radius: 10px 10px 0px 0px;
75 | }
76 |
77 | .source-container {
78 | margin-top: 20px;
79 | width: 100%;
80 | }
81 |
82 | #code-el {
83 | position: relative;
84 | width: 100%;
85 | min-height: 600px;
86 | }
87 |
88 | #editor {
89 | position: absolute;
90 | top: 0;
91 | right: 0;
92 | bottom: 0;
93 | left: 0;
94 | font-size: 16px;
95 | }
96 |
97 | #url-el {
98 | font-family: monospace;
99 | }
100 |
101 |
102 | .ace_scrollbar::-webkit-scrollbar {
103 | height: 12px;
104 | width: 12px;
105 | }
106 |
107 | .ace_scrollbar::-webkit-scrollbar-track
108 | {
109 | box-shadow: inset 0 0 6px rgba(0,0,0,0.3);
110 | background-color: #272822; /* Matches ace monokai */
111 | border-radius: 10px;
112 | }
113 |
114 | .ace_scrollbar::-webkit-scrollbar-thumb {
115 | background-color: darkgrey;
116 | outline: 1px solid slategrey;
117 | border-radius: 10px;
118 | }
--------------------------------------------------------------------------------
/examples/tests/AnimSpritesheet.js:
--------------------------------------------------------------------------------
1 | /**
2 | * import "h5tiny";
3 | * import "h5tiny/examples/js/App2D";
4 | * import "h5tiny/plugins/anim"
5 | * import "h5tiny/plugins/create"
6 | *
7 | * or
8 | *
9 | * import "h5tiny/plugins/create/spritesheet"
10 | *
11 | * To ignore unnecessary extra components
12 | *
13 | */
14 |
15 | class MyGame extends Tiny.App2D {
16 | constructor(width, height) {
17 | super(width, height, 'game-container');
18 | }
19 |
20 | preload() {
21 | this.load.image('base', resources.baseImage);
22 | this.load.spritesheet('gifspritesheet', resources.spritesheet, 222, 222);
23 | this.load.atlas('atlas', resources.atlas, resources.atlas_data);
24 | }
25 |
26 | create() {
27 | const head = new Tiny.Sprite('base');
28 | head.y = -40;
29 | head.scale.set(1.3, 0.5);
30 | head.anchor.set(0, 1);
31 |
32 | const body = new Tiny.Sprite('base');
33 | body.anchor.set(0.5);
34 |
35 | const lleg = new Tiny.Sprite('atlas', 'IH');
36 | lleg.scale.x = 0.3;
37 |
38 | const rleg = new Tiny.Sprite('atlas', 'IH');
39 | rleg.scale.x = 0.3;
40 |
41 | lleg.anchor.set(0.5, 0);
42 | rleg.anchor.set(0.5, 0);
43 |
44 | var group = new Tiny.Object2D();
45 | group.add(lleg);
46 | group.add(body);
47 | group.add(rleg);
48 | body.add(head);
49 |
50 | Tiny.Create.spritesheet({
51 | width: 400,
52 | height: 400,
53 | frames: 30,
54 | resolution: 0.2,
55 | key: 'spritesheetRunAnimation',
56 | draw(progress, ctx, frame) {
57 | body.y = Math.sin(progress * Math.PI * 4) * 30;
58 | lleg.rotation = Math.sin(progress * Math.PI * 2);
59 | rleg.rotation = -Math.sin(progress * Math.PI * 2);
60 | head.x = Math.sin(progress * Math.PI * 2) * 20;
61 | head.rotation = Math.sin(progress * Math.PI * 4) * 0.3;
62 | body.rotation = Math.sin(progress * Math.PI * 4) * 0.2;
63 | return group;
64 | }
65 | });
66 |
67 | Tiny.Create.spritesheet({
68 | width: 400,
69 | height: 400,
70 | frames: 20,
71 | resolution: 0.2,
72 | key: 'spritesheetIdleAnimation',
73 | draw(progress, ctx, frame) {
74 | body.y = Math.sin(progress * Math.PI * 2) * 30;
75 | head.x = Math.sin(progress * Math.PI * 4) * 10;
76 | head.rotation = Math.sin(progress * Math.PI * 4) * 0.1;
77 | return group;
78 | }
79 | });
80 |
81 | this.anim.create({
82 | key: "run",
83 | data: "spritesheetRunAnimation",
84 | fps: 50,
85 | repeat: -1
86 | });
87 |
88 | this.anim.create({
89 | key: "idle",
90 | data: {
91 | key: "spritesheetIdleAnimation"
92 | },
93 | fps: 15,
94 | repeat: -1
95 | });
96 |
97 | this.anim.create({
98 | key: "movie",
99 | data: "gifspritesheet",
100 | fps: 15
101 | });
102 |
103 | this.anim.create({
104 | key: "cutAnim",
105 | data: {
106 | key: "spritesheetRunAnimation",
107 | from: 10,
108 | to: 15
109 | },
110 | fps: 50,
111 | repeat: 5,
112 | yoyo: true,
113 | repeatDelay: 100
114 | });
115 |
116 | var movie = new Tiny.Sprite('gifspritesheet', 0);
117 | movie.position.set(320, 50);
118 | this.anim.add(movie);
119 | this.input.add(movie);
120 | this.scene.add(movie);
121 |
122 | movie.input.on('down', function() {
123 | movie.play({
124 | key: "movie",
125 | onComplete: function() {
126 | console.log("To be continued...")
127 | }
128 | });
129 | })
130 |
131 | var sprite1 = new Tiny.Sprite('spritesheetIdleAnimation', 0);
132 | sprite1.position.set(Tiny.rnd(40, 600), Tiny.rnd(40, 360));
133 | sprite1.anchor.set(0.5);
134 | this.anim.add(sprite1);
135 | this.scene.add(sprite1);
136 |
137 | sprite1.play('idle');
138 |
139 | var runTween = null;
140 | this.input.on('down', function(e) {
141 | if (runTween) {
142 | this.tweens.remove(runTween);
143 | runTween = null;
144 | }
145 | sprite1.play('run');
146 |
147 | if (e.x > sprite1.x) sprite1.scale.x = 1;
148 | else sprite1.scale.x = -1;
149 |
150 | var a = e.x - sprite1.x;
151 | var b = e.y - sprite1.y;
152 |
153 | var distance = Math.sqrt( a*a + b*b );
154 |
155 | runTween = this.tweens.add(sprite1).to({x: e.x, y: e.y}, distance * 4).onComplete(function(argument) {
156 | sprite1.play('idle');
157 | }).start();
158 | }, this);
159 |
160 | var sprite2 = new Tiny.Sprite('spritesheetIdleAnimation', 0);
161 | sprite2.position.set(100, 300);
162 | sprite2.anchor.set(0.5);
163 | this.anim.add(sprite2);
164 | this.input.add(sprite2);
165 | this.scene.add(sprite2);
166 |
167 | sprite2.play('cutAnim');
168 |
169 | sprite2.input.on('down', function() {
170 | sprite2.play({
171 | key: "run",
172 | repeat: 2,
173 | fps: 60,
174 | onComplete: function() {
175 | sprite2.play('cutAnim');
176 | }
177 | })
178 | })
179 | }
180 | }
181 |
--------------------------------------------------------------------------------
/examples/tests/Basic.js:
--------------------------------------------------------------------------------
1 | /**
2 | * import "h5tiny";
3 | */
4 |
5 | class MyGame extends Tiny.App {
6 | constructor(width, height) {
7 | super();
8 |
9 | this.width = width;
10 | this.height = height;
11 |
12 | this.renderer = new Tiny.CanvasRenderer(this.width, this.height, {
13 | resolution: 1.25,
14 | autoResize: true
15 | });
16 |
17 | this.renderer.setClearColor('#f4f4f4');
18 |
19 | var view = (this.inputView = this.renderer.domElement);
20 |
21 | document.getElementById('game-container').appendChild(view);
22 |
23 | this.scene = new Tiny.Scene();
24 | }
25 |
26 | preload() {
27 | this.load.image('coin', resources.baseImage);
28 | }
29 |
30 | create() {
31 | var text = new Tiny.Text('Hello Tiny!');
32 | text.anchor.set(0.5);
33 | text.x = 320;
34 | text.y = 200;
35 | this.text = text;
36 |
37 | var sprite = new Tiny.Sprite('coin');
38 |
39 | this.scene.add(sprite);
40 | this.scene.add(text);
41 | }
42 |
43 | update(time, delta) {
44 | this.text.rotation += delta * 0.001;
45 | }
46 |
47 | setPixelRatio(dpr) {
48 | this.renderer.setPixelRatio(dpr);
49 | }
50 |
51 | render() {
52 | this.renderer.render(this.scene);
53 | }
54 |
55 | resize(width, height) {
56 | super.resize(width, height);
57 |
58 | this.renderer.resize(width, height);
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/examples/tests/BlendMode.js:
--------------------------------------------------------------------------------
1 | /**
2 | * import "h5tiny";
3 | * import "h5tiny/examples/js/App2D";
4 | */
5 |
6 | class MyGame extends Tiny.App2D {
7 | constructor(width, height) {
8 | super(width, height, 'game-container');
9 | }
10 |
11 | preload() {
12 | this.load.image('base', resources.baseImage);
13 |
14 | resizeCanvas(640, 600);
15 |
16 | this.addLabel = (_x, _y, text, color) => {
17 | var text = new Tiny.Text(text, {
18 | fill: color || '#ffffff',
19 | font: '300 9pt Courier',
20 | align: 'center'
21 | });
22 | text.position.set(_x, _y);
23 | text.anchor.set(0.5, 3.2);
24 | this.scene.add(text);
25 | };
26 |
27 | this.addSprite = (x, y, mode, anchorX, anchorY) => {
28 | var sprite = new Tiny.Sprite('base');
29 | sprite.position.set(x, y);
30 | sprite.anchor.set(anchorX, anchorY);
31 | sprite.scale.set(0.4);
32 | sprite.blendMode = mode;
33 | this.scene.add(sprite);
34 | };
35 | }
36 |
37 | create() {
38 | const blendModes = [
39 | 'source-over',
40 | 'screen',
41 | 'lighter',
42 | 'xor',
43 | 'multiply',
44 | 'overlay',
45 | 'darken',
46 | 'lighten',
47 | 'color-dodge',
48 | 'color-burn',
49 | 'hard-light',
50 | 'soft-light',
51 | 'difference',
52 | 'exclusion',
53 | 'luminosity'
54 | ];
55 |
56 | let x = 0;
57 | let y = 0;
58 | const offset = 110;
59 | const start = this.width / 12;
60 |
61 | const background = new Tiny.Graphics();
62 |
63 | background.beginFill('#232323');
64 | background.blendMode = 'source-over';
65 | background.drawRect(0, 0, this.width / 2, this.height);
66 | this.scene.add(background);
67 |
68 | this.input.on('down', function () {
69 | background.clear();
70 | background.beginFill(Tiny.hex2style(Math.floor(Math.random() * 16777215)));
71 | background.drawRect(0, 0, game.width / 2, game.height);
72 | });
73 |
74 | for (let mode of blendModes) {
75 | const _x = x * (this.width / 6) + start;
76 | const _y = y * offset + 70;
77 |
78 | this.addLabel(_x, _y, mode, '#ffffff');
79 | this.addSprite(_x, _y, mode, 0.2, 0.2);
80 | this.addSprite(_x, _y, mode, 0.7, 0.2);
81 | this.addSprite(_x, _y, mode, 0.5, 0.7);
82 |
83 | x++;
84 | if (x > 2) {
85 | x = 0;
86 | y++;
87 | }
88 | }
89 |
90 | x = 0;
91 | y = 0;
92 |
93 | for (let mode of blendModes) {
94 | const _x = this.width / 2 + x * (this.width / 6) + start;
95 | const _y = y * offset + 70;
96 |
97 | this.addLabel(_x, _y, mode, '#232323');
98 | this.addSprite(_x, _y, mode, 0.2, 0.2);
99 | this.addSprite(_x, _y, mode, 0.7, 0.2);
100 | this.addSprite(_x, _y, mode, 0.5, 0.7);
101 |
102 | x++;
103 | if (x > 2) {
104 | x = 0;
105 | y++;
106 | }
107 | }
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/examples/tests/Extended.js:
--------------------------------------------------------------------------------
1 | /**
2 | * import "h5tiny";
3 | * import "h5tiny/examples/js/App2D";
4 | */
5 |
6 | class MyGame extends Tiny.App2D {
7 | constructor(width, height) {
8 | super(width, height, 'game-container');
9 | }
10 |
11 | preload() {
12 | this.load.image('base', resources.baseImage);
13 | this.load.atlas('atlas', resources.atlas, resources.atlas_data);
14 | // this.load.spritesheet("gifsprite", spritesheet, 222, 222);
15 | // this.load.spritesheet("gifsprite", spritesheet, spritesheet_data);
16 |
17 | this.load.all([
18 | // { key: "base", src: resources.baseImage, type: "image" },
19 | // { key: "atlas", src: resources.atlas, data: atlas_data, type: "atlas" },
20 | // { key: "gifsprite", src: spritesheet, cols: 12, rows: 1, total: 15, duration: 40, type: "spritesheet" },
21 | // { key: "gifsprite", src: spritesheet, width: 222, height: 222, duration: 40, type: "spritesheet" },
22 | { key: 'gifsprite', src: resources.spritesheet, cols: 6, rows: 1, duration: 90, type: 'spritesheet' }
23 | // { key: "gifsprite", src: spritesheet, data: spritesheet_data, type: "spritesheet" }
24 | ]);
25 | }
26 |
27 | create() {
28 |
29 | this.anim.create({
30 | key: "idle",
31 | type: "spritesheet",
32 | data: {
33 | key: "gifsprite",
34 | // from: 0,
35 | // to: 3
36 | },
37 | repeat: -1,
38 | yoyo: true,
39 | fps: 16
40 | });
41 |
42 | this.group = new Tiny.Object2D();
43 | this.group.x = 200;
44 | this.group.y = 200;
45 |
46 | this.group.add(new Tiny.Text('Hello World'));
47 | this.group.add(new Tiny.Sprite('base'));
48 | this.group.add(new Tiny.Text('Hello World', { fill: '#ff0000' }));
49 | this.group.cacheAsBitmap = true;
50 | this.group.children[2].y = 70;
51 | this.group.updateCache();
52 |
53 | var texture1 = (this.texture1 = this.group.generateTexture());
54 | var spriteFromGenerated = new Tiny.Sprite(texture1);
55 |
56 | spriteFromGenerated.x = this.group.x;
57 | spriteFromGenerated.y = this.group.y;
58 | spriteFromGenerated.alpha = 0.3;
59 | spriteFromGenerated.scale.set(0.7);
60 |
61 | this.scene.add(spriteFromGenerated);
62 | this.scene.add(this.group);
63 |
64 | var spriteFromGenerated2 = new Tiny.Sprite(texture1);
65 | spriteFromGenerated2.x = 70;
66 | spriteFromGenerated2.y = 70;
67 | spriteFromGenerated2.rotation = 0.5;
68 | spriteFromGenerated2.alpha = 0.3;
69 | spriteFromGenerated2.scale.set(0.7);
70 |
71 | this.group.add(spriteFromGenerated2);
72 | this.group.updateCache();
73 |
74 | this.input.add(this.group);
75 | this.group.input.on('click', function () {
76 | alert('Oup, you catched me !');
77 | });
78 |
79 | this.bottomRightSprite = new Tiny.Sprite('base');
80 | this.bottomRightSprite.anchor.set(0.5);
81 | this.scene.add(this.bottomRightSprite);
82 | this.bottomRightSprite.position.set(this.width - 100, this.height - 100);
83 |
84 | this.testCoin = new Tiny.Sprite('base');
85 | this.testCoin.x = 350;
86 | this.testCoin.y = 200;
87 | this.testCoin.scale.set(0.5);
88 | this.scene.add(this.testCoin);
89 |
90 | this.icon = new Tiny.Sprite('atlas', 'IH');
91 | this.icon.tint = '#23f423';
92 | this.icon.scale.set(0.5);
93 | this.scene.add(this.icon);
94 |
95 | const animatedSprite = new Tiny.Sprite('gifsprite', 0);
96 | animatedSprite.anchor.set(0.5);
97 | animatedSprite.position.set(450, 120);
98 | animatedSprite.scale.set(0.7);
99 | animatedSprite.game = this;
100 | // animatedSprite.animate(60, true);
101 |
102 | this.anim.add(animatedSprite);
103 | this.input.add(animatedSprite);
104 |
105 |
106 | animatedSprite.play('idle');
107 | animatedSprite.input.once('down', function () {
108 | animatedSprite.play({key: 'idle', yoyo: false, fps: 30});
109 | });
110 |
111 | this.interval = setInterval(function () {
112 | // console.log('Rotate sprite!');
113 | // animatedSprite.rotation = 1 - Math.random() * 2;
114 | }, 1000);
115 |
116 | this.scene.add(animatedSprite);
117 |
118 | /**
119 | * Creating scene mini-map
120 | */
121 | this.miniMap = new Tiny.MiniMap(this);
122 | this.scene.add(this.miniMap);
123 | }
124 |
125 | update(time, delta) {
126 | this.testCoin.rotation += delta * 0.0001;
127 | this.testCoin.anchor.x = Math.sin(time * 0.001);
128 |
129 | this.group.scale.x = Math.sin(time / 500);
130 | this.group.scale.y = Math.cos(time / 500);
131 |
132 | this.group.x = Math.sin(time / 100) * 10 + 200;
133 | this.group.y = Math.cos(time / 100) * 10 + 200;
134 |
135 | this.miniMap.update(delta);
136 | }
137 |
138 | resize(width, height) {
139 | super.resize(width, height);
140 | this.bottomRightSprite.x = width - 100;
141 | this.bottomRightSprite.y = height - 100;
142 |
143 | this.miniMap.resize(width, height);
144 | }
145 |
146 | destroy(clearCache) {
147 | super.destroy(clearCache);
148 | clearInterval(this.interval);
149 | }
150 | }
151 |
--------------------------------------------------------------------------------
/examples/tests/Graphics.js:
--------------------------------------------------------------------------------
1 | /**
2 | * import "h5tiny";
3 | * import "h5tiny/examples/js/App2D";
4 | */
5 |
6 | class MyGame extends Tiny.App2D {
7 | constructor(width, height) {
8 | super(width, height, 'game-container');
9 | }
10 |
11 | create() {
12 | const graphics = new Tiny.Graphics();
13 |
14 | // Rectangle
15 | graphics.beginFill('#DE3249');
16 | graphics.drawRect(20, 20, 100, 100);
17 | graphics.endFill();
18 |
19 | // Rectangle + line style 1
20 | graphics.lineStyle(2, '#FEEB77', 1);
21 | graphics.beginFill('#650A5A');
22 | graphics.drawRect(140, 20, 100, 100);
23 | graphics.endFill();
24 |
25 | // Rectangle + line style 2
26 | graphics.lineStyle(10, '#FFBD01', 1);
27 | graphics.beginFill('#C34288');
28 | graphics.drawRect(260, 20, 100, 100);
29 | graphics.endFill();
30 |
31 | // Rectangle 2
32 | graphics.lineStyle(2, '#000000', 1);
33 | graphics.beginFill('#AA4F08');
34 | graphics.drawRect(410, 20, 140, 100);
35 | graphics.endFill();
36 |
37 | // Circle
38 | graphics.lineStyle(0); // draw a circle, set the lineStyle to zero so the circle doesn't have an outline
39 | graphics.beginFill('#DE3249', 1);
40 | graphics.drawCircle(70, 190, 100);
41 | graphics.endFill();
42 |
43 | // Circle + line style 1
44 | graphics.lineStyle(2, '#FEEB77', 1);
45 | graphics.beginFill('#650A5A', 1);
46 | graphics.drawCircle(190, 190, 100);
47 | graphics.endFill();
48 |
49 | // Circle + line style 2
50 | graphics.lineStyle(10, '#FFBD01', 1);
51 | graphics.beginFill('#C34288', 1);
52 | graphics.drawCircle(310, 190, 100);
53 | graphics.endFill();
54 |
55 | // Ellipse + line style 2
56 | graphics.lineStyle(2, '#000000', 1);
57 | graphics.beginFill('#AA4F08', 1);
58 | graphics.drawEllipse(250, 350, 70, 40);
59 | graphics.endFill();
60 |
61 | // draw a shape
62 | graphics.beginFill('#FF3300');
63 | graphics.lineStyle(4, '#ffd900', 1);
64 | graphics.moveTo(50, 270);
65 | graphics.lineTo(250, 270);
66 | graphics.lineTo(100, 320);
67 | graphics.lineTo(50, 270);
68 | //graphics.closePath();
69 | graphics.endFill();
70 |
71 | // draw a rounded rectangle
72 | graphics.lineStyle(2, '#FF00FF', 1);
73 | graphics.beginFill('#f1f1f1', 0.25);
74 | graphics.drawRoundedRect(330, 270, 100, 100, 16);
75 | graphics.endFill();
76 |
77 | // draw star
78 | // graphics.lineStyle(2, "#FFFFFF");
79 | // graphics.beginFill("#35CC5A", 1);
80 | // graphics.drawStar(360, 370, 5, 50);
81 | // graphics.endFill();
82 |
83 | // draw star 2
84 | // graphics.lineStyle(2, "#FFFFFF");
85 | // graphics.beginFill("#FFCC5A", 1);
86 | // graphics.drawStar(280, 510, 7, 50);
87 | // graphics.endFill();
88 |
89 | // draw star 3
90 | // graphics.lineStyle(4, "#FFFFFF");
91 | // graphics.beginFill("#55335A", 1);
92 | // graphics.drawStar(470, 450, 4, 50);
93 | // graphics.endFill();
94 |
95 | // draw polygon
96 | const path = [450, 170, 550, 260, 630, 220, 580, 370, 440, 320];
97 |
98 | graphics.lineStyle(0);
99 | graphics.beginFill('#3500FA', 1);
100 | graphics.drawPolygon(path);
101 | graphics.endFill();
102 |
103 | this.scene.add(graphics);
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/examples/tests/Graphics2.js:
--------------------------------------------------------------------------------
1 | /**
2 | * import "h5tiny";
3 | * import "h5tiny/examples/js/App2D";
4 | */
5 |
6 | class MyGame extends Tiny.App2D {
7 | constructor(width, height) {
8 | super(width, height, 'game-container');
9 | }
10 |
11 | create() {
12 | this.graphics = new Tiny.Graphics();
13 | this.graphics.x = 100;
14 | this.graphics.y = 100;
15 | this.graphics.beginFill('#0a6dc1');
16 | this.graphics.drawCircle(0, 0, 182);
17 | this.graphics.beginFill('#04589e');
18 | this.graphics.drawCircle(0, 0, 170);
19 |
20 | for (var i = 0; i < 40; i++) {
21 | this.graphics.beginFill('#5500c5', 0.06);
22 | this.graphics.drawCircle(0, 0, i * 4);
23 | }
24 |
25 | // this.scene.add(this.graphics);
26 |
27 | const texture1 = this.graphics.generateTexture();
28 |
29 | const sprite = new Tiny.Sprite(texture1);
30 | this.scene.add(sprite);
31 |
32 | this.graphics.destroy();
33 |
34 | this.graphics = new Tiny.Graphics();
35 | this.graphics.position.set(100, 100);
36 | this.graphics.beginFill('#45a187');
37 | this.graphics.drawCircle(34, 100, 125);
38 | this.graphics.beginFill('#ff4545');
39 | this.graphics.drawRect(120, 45, 50, 50);
40 | this.graphics.scale.set(2, 1);
41 | this.graphics.rotation = 0.3;
42 |
43 | var texture2 = this.graphics.generateTexture(0.5);
44 |
45 | const sprite2 = new Tiny.Sprite(texture2);
46 | this.scene.add(sprite2);
47 |
48 | this.scene.add(this.graphics);
49 |
50 | this.graphics.lineStyle(4, '#232323', 0.5);
51 | this.graphics.moveTo(23, 100);
52 | this.graphics.lineTo(150, 150);
53 |
54 | this.graphics.moveTo(200, 30);
55 |
56 | this.graphics.quadraticCurveTo(100, 134, 220, 145);
57 | this.graphics.bezierCurveTo(30, 5, 140, 10, 100, 50);
58 | this.graphics.arcTo(200, -0, 250, -120, 150);
59 |
60 | this.graphics.beginFill('#f4a187', 0.5);
61 |
62 | this.graphics.drawRoundedRect(120, 0, 100, 60, 15);
63 | // this.graphics.drawRoundedRect2(120, 70, 100, 60, 15);
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/examples/tests/Input.js:
--------------------------------------------------------------------------------
1 | /**
2 | * import "h5tiny";
3 | * import "h5tiny/examples/js/App2D";
4 | *
5 | * import "h5tiny/examples/js/objects/MiniMap";
6 | * to use RecursiveSprite
7 | */
8 |
9 | class MyGame extends Tiny.App2D {
10 |
11 | constructor(width, height) {
12 | super(width, height, "game-container");
13 | }
14 |
15 | preload () {
16 | this.load.image("base", resources.baseImage);
17 | this.load.atlas("atlas", resources.atlas, resources.atlas_data);
18 | }
19 |
20 | create () {
21 | const debugText = (this.debugText = new Tiny.Text("0:0", { fill: "#3434f3" }));
22 | this.scene.add(debugText);
23 |
24 | this.input.on("down", function (e) {
25 | console.log("Mouse down: " + e.x + ":" + e.y);
26 | }, this);
27 |
28 | this.input.on("up", function (e) {
29 | console.log("Mouse up: " + e.x + ":" + e.y);
30 | }, this);
31 |
32 | this.input.on("move", function (e) {
33 | console.log("Mouse move: ", this.input.isDown);
34 | debugText.setText(Math.floor(e.x) + " : " + Math.floor(e.y));
35 | }, this);
36 |
37 | var coin = (this.coin = new Tiny.Sprite("base"));
38 | coin.x = 300;
39 | coin.y = 200;
40 | coin.anchor.set(0.5);
41 | coin.scale.set(0.9);
42 | this.scene.add(coin);
43 |
44 | this.input.add(coin);
45 | coin.input.on("click", function () {
46 | console.log("Coin 2 clicked");
47 | coin.tint = Tiny.hex2style(Math.floor(Math.random() * 162000));
48 | }, this);
49 |
50 | coin.input.on("down", function () {
51 | this.dragging = true;
52 | }, coin);
53 |
54 | var coin2 = (this.coin2 = new Tiny.Sprite("base"));
55 | coin2.x = 100;
56 | coin2.y = 300;
57 | coin2.anchor.set(0.5);
58 | coin2.scale.set(0.9);
59 | this.scene.add(coin2);
60 | this.input.add(coin2);
61 |
62 | this.graphics = new Tiny.Graphics();
63 | this.graphics.x = 100;
64 | this.graphics.beginFill("#0a6dc1");
65 | this.graphics.drawCircle(0, 0, 182);
66 | this.graphics.beginFill("#04589e");
67 | this.graphics.drawCircle(0, 0, 170);
68 | for (var i = 0; i < 40; i++) {
69 | this.graphics.beginFill("#5500c5", 0.06);
70 | this.graphics.drawCircle(0, 0, i * 4);
71 | }
72 | var newTexture = this.graphics.generateTexture();
73 | this.graphics.destroy();
74 |
75 | var sprite = (this.sprite = new Tiny.Sprite(newTexture));
76 | sprite.position.set(560, 120);
77 | sprite.anchor.set(0.5);
78 |
79 | var text = (this.text = new Tiny.Text("Drag me!", { fill: "#ffffff" }));
80 | text.anchor.set(0.5);
81 |
82 | this.tweens
83 | .add(text.scale)
84 | .to({ x: 1.1, y: 1.1 }, 500)
85 | .yoyo(true)
86 | .easing(Tiny.Easing.Sinusoidal.InOut)
87 | .repeat(Infinity)
88 | .start();
89 |
90 | var pulseTween = this.tweens
91 | .add(sprite.scale)
92 | .to({ x: 1.1, y: 1.1 }, 100)
93 | .yoyo(true)
94 | .easing(Tiny.Easing.Sinusoidal.InOut)
95 | .repeat(Infinity)
96 | .start();
97 |
98 | pulseTween.pause();
99 |
100 | sprite.add(text);
101 |
102 | var dragging = false;
103 |
104 | var startOffsetX = 0;
105 | var startOffsetY = 0;
106 |
107 | this.input.on(
108 | "up",
109 | function (e) {
110 | dragging = false;
111 | this.coin2.dragging = false;
112 | this.coin.dragging = false;
113 | pulseTween.pause();
114 | sprite.scale.set(1);
115 | },
116 | this
117 | );
118 |
119 | this.input.on(
120 | "move",
121 | function (e) {
122 | if (dragging) {
123 | sprite.position.set(e.x + startOffsetX, e.y + startOffsetY);
124 | }
125 |
126 | if (this.coin2.dragging) {
127 | this.coin2.position.set(e.x, e.y);
128 | this.recusrive.setCenter(this.coin2.x / game.width, this.coin2.y / game.height);
129 | }
130 |
131 | if (this.coin.dragging) {
132 | this.coin.position.set(e.x, e.y);
133 | this.recusrive.alpha = this.coin.x / game.width;
134 | this.recusrive.clearAlpha = this.coin.y / game.height;
135 | this.recusrive.clearAlpha *= this.recusrive.clearAlpha * this.recusrive.clearAlpha;
136 | this.recusrive.updateFrames();
137 | }
138 | },
139 | this
140 | );
141 |
142 | this.input.add(sprite);
143 |
144 | sprite.input.on("down", function (e) {
145 | startOffsetX = sprite.x - e.x;
146 | startOffsetY = sprite.y - e.y;
147 | dragging = true;
148 | pulseTween.resume();
149 | });
150 |
151 | this.scene.add(sprite);
152 |
153 | /**
154 | * Creating scene recursive sprite
155 | */
156 | this.recusrive = new Tiny.RecursiveSprite(this);
157 | this.scene.add(this.recusrive);
158 |
159 | coin2.input.on("down", function () {
160 | this.dragging = true;
161 | }, coin2);
162 | }
163 |
164 | resize (width, height) {
165 | super.resize(width, height);
166 | this.recusrive.resize(width, height);
167 | }
168 |
169 | update (time, delta) {
170 | this.recusrive.update(delta);
171 | }
172 | }
173 |
--------------------------------------------------------------------------------
/examples/tests/Particles1.js:
--------------------------------------------------------------------------------
1 | /**
2 | * import "h5tiny";
3 | * import "h5tiny/examples/js/App2D";
4 | * import "h5tiny/plugins/particles";
5 | *
6 | * import "h5tiny/examples/js/particles/Smoke";
7 | * to use SmokeParticle pattern
8 | *
9 | * import "h5tiny/examples/js/particles/Explode";
10 | * to use ExplodeParticle pattern
11 | *
12 | * import "h5tiny/examples/js/objects/MiniMap";
13 | * to use RecursiveSprite
14 | */
15 |
16 | class MyGame extends Tiny.App2D {
17 | constructor(width, height) {
18 | super(width, height, 'game-container');
19 | }
20 |
21 | preload() {
22 | this.load.image('base', resources.baseImage);
23 | }
24 |
25 | create() {
26 | var emitter = (this.emitter = new Tiny.Emitter(60));
27 | emitter.x = 200;
28 | emitter.y = 300;
29 | emitter.width = 40;
30 |
31 | emitter.pattern = Tiny.SmokeParticle;
32 | emitter.fillStyle = '#666666';
33 |
34 | emitter.makeParticles('base'); //Tiny.TextureCache["atlas_BR"])
35 | emitter.scale.set(0.7);
36 |
37 | emitter.start(false, 500, 0);
38 |
39 | // emitter.flow(1000, 10, 3);
40 |
41 | this.timer.loop(5000, function () {
42 | if (Math.random() > 0.5) {
43 | emitter.width = 300;
44 | emitter.flow(500, 10, 5);
45 | } else {
46 | emitter.width = 40;
47 | emitter.flow(1000, 100, 8);
48 | }
49 | });
50 |
51 | this.particles.add(emitter);
52 | this.scene.add(emitter);
53 |
54 | var bombEmitter = (this.bombEmitter = new Tiny.Emitter(30));
55 | bombEmitter.pattern = Tiny.ExplodeParticle;
56 | bombEmitter.makeParticles();
57 |
58 | var clickMe = new Tiny.Text('Click me !');
59 | clickMe.anchor.set(0.5);
60 | clickMe.position.set(this.width / 2, this.height / 2);
61 | this.scene.add(clickMe);
62 |
63 | this.input.once('down', function (e) {
64 | clickMe.destroy();
65 | });
66 |
67 | this.input.on('down', function (e) {
68 | bombEmitter.fillStyle = '#' + Math.floor(Math.random() * 0xffffff).toString(16);
69 | bombEmitter.x = e.x;
70 | bombEmitter.y = e.y;
71 | console.log('Explode');
72 | bombEmitter.explode(300, 80);
73 | });
74 |
75 | this.particles.add(bombEmitter);
76 | this.scene.add(bombEmitter);
77 |
78 | this.recusrive = new Tiny.RecursiveSprite(this);
79 | this.recusrive.delay = 1;
80 | this.recusrive.setCenter(0.5, 0.7);
81 | this.scene.add(this.recusrive);
82 | }
83 |
84 | update(time, delta) {
85 | this.recusrive.update(delta);
86 | }
87 |
88 | resize(width, height) {
89 | super.resize(width, height);
90 | this.recusrive.resize(width, height);
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/examples/tests/Particles2.js:
--------------------------------------------------------------------------------
1 | /**
2 | * import "h5tiny";
3 | * import "h5tiny/examples/js/App2D";
4 | * import "h5tiny/plugins/particles";
5 | *
6 | * import "h5tiny/examples/js/particles/Confetti";
7 | * to use ConfettiParticle pattern
8 | *
9 | * import "h5tiny/examples/js/particles/Ribbon";
10 | * to use RibbonParticle pattern
11 | *
12 | */
13 |
14 | class MyGame extends Tiny.App2D {
15 | constructor(width, height) {
16 | super(width, height, 'game-container');
17 | }
18 |
19 | create() {
20 | var confetti = (this.confetti = new Tiny.Emitter(150));
21 | confetti.x = 350;
22 | confetti.width = 800;
23 |
24 | confetti.pattern = Tiny.ConfettiParticle;
25 |
26 | confetti.makeParticles();
27 | confetti.scale.set(0.7);
28 |
29 | confetti.flow(10000, 300, 5);
30 |
31 | this.particles.add(confetti);
32 | this.scene.add(confetti);
33 |
34 | var ribbon = (this.ribbon = new Tiny.Emitter(18));
35 | ribbon.x = 350;
36 | ribbon.width = 800;
37 |
38 | ribbon.pattern = Tiny.RibbonParticle;
39 | ribbon.makeParticles();
40 | ribbon.scale.set(0.7);
41 |
42 | ribbon.start(false, 5000, 300);
43 |
44 | this.particles.add(ribbon);
45 | this.scene.add(ribbon);
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/examples/tests/ProgressBar.js:
--------------------------------------------------------------------------------
1 | /**
2 | * import "h5tiny";
3 | * import "h5tiny/examples/js/App2D";
4 | * import "h5tiny/plugins/extra"
5 | *
6 | * or
7 | *
8 | * import "h5tiny/plugins/extra/objects/ProgressBar"
9 | *
10 | * To ignore unnecessary extra components
11 | *
12 | */
13 |
14 | class MyGame extends Tiny.App2D {
15 | constructor(width, height) {
16 | super(width, height, 'game-container');
17 | }
18 |
19 | create() {
20 | const _self = this;
21 |
22 | function addProgressBar(x, y, options) {
23 | options = options || {};
24 | options.game = _self;
25 |
26 | const progress = new Tiny.ProgressBar(options);
27 |
28 | progress.x = x;
29 | progress.y = y;
30 |
31 | _self.scene.add(progress);
32 |
33 | _self.timer.loop(1500, function () {
34 | progress.setValue(Math.random());
35 | });
36 |
37 | _self.input.on('down', function () {
38 | progress.setValue(1);
39 | });
40 |
41 | return progress;
42 | }
43 |
44 | addProgressBar(150, 40);
45 | addProgressBar(150, 100, { colors: ['#ff0000', '#0000ff'] });
46 | addProgressBar(150, 160, {
47 | radius: 0,
48 | height: 20,
49 | width: 250,
50 | duration: 1100,
51 | easing: Tiny.Easing.Elastic.Out,
52 | colors: ['#666666', '#69d6e1', '#5778e0', '#583fbe', '#e01b1b', '#ffd700']
53 | });
54 |
55 | addProgressBar(150, 220, {
56 | strokeWidth: 10
57 | // strokeColor: "#e1e1e1",
58 | // strokeAlpha: 1
59 | });
60 |
61 | addProgressBar(150, 280, {
62 | strokeWidth: 3,
63 | bgColor: '#a1a1ff',
64 | bgAlpha: 0.5,
65 | strokeColor: '#0000a1',
66 | colors: ['#0000ff']
67 | });
68 |
69 | addProgressBar(150, 340, {
70 | animated: false,
71 | value: 0.5
72 | });
73 |
74 | var circleProgress = addProgressBar(370, 300, {
75 | radius: 35,
76 | height: 70,
77 | width: 70
78 | });
79 |
80 | circleProgress.rotation = Math.PI;
81 |
82 | var progress = addProgressBar(400, 130, {
83 | value: 0.2,
84 | strokeWidth: 10
85 | // strokeColor: "#e1e1e1",
86 | // strokeAlpha: 1
87 | });
88 |
89 | progress.scale.set(0.5);
90 | progress.rotation = -Math.PI / 2;
91 |
92 | var progress2 = addProgressBar(460, 150, {
93 | radius: 0,
94 | height: 20,
95 | width: 250,
96 | colors: ['#666666', '#69d6e1', '#5778e0', '#583fbe', '#e01b1b', '#ffd700']
97 | });
98 |
99 | progress2.rotation = -Math.PI / 2;
100 |
101 | var progress3 = addProgressBar(560, 150, {
102 | height: 80,
103 | width: 120,
104 | strokeWidth: 5,
105 | strokeColor: '#aaa0aa',
106 | colors: ['#0000ff', '#fff000']
107 | });
108 |
109 | progress3.rotation = -Math.PI / 2;
110 |
111 | var graphics = new Tiny.Graphics();
112 |
113 | graphics.drawCircle(0, -90, 120);
114 | graphics.drawPolygon([0, -56, 23, -11, 67, 23, -12, -64, 1, 354]);
115 | graphics.drawRect(-50, 20, 100, 100);
116 |
117 | graphics.x = progress3.x;
118 | graphics.y = progress3.y;
119 | this.scene.add(graphics);
120 |
121 | progress3.mask = graphics;
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/examples/tests/RenderLayer.js:
--------------------------------------------------------------------------------
1 | /**
2 | * import "h5tiny";
3 | * import "h5tiny/examples/js/App2D";
4 | * import "h5tiny/plugins/extra"
5 | *
6 | * or
7 | *
8 | * import "h5tiny/plugins/extra/objects/RenderLayer"
9 | * import "h5tiny/plugins/extra/objects/Opaque"
10 | *
11 | * To ignore unnecessary extra components
12 | *
13 | */
14 |
15 | class MyGame extends Tiny.App2D {
16 | constructor(width, height) {
17 | super(width, height, 'game-container');
18 | }
19 |
20 | preload() {
21 | this.load.image("base", resources.baseImage);
22 | this.load.atlas("atlas", resources.atlas, resources.atlas_data);
23 | }
24 |
25 | create() {
26 | const bottomLayer = new Tiny.Object2D();
27 | bottomLayer.position.set(this.width / 2, this.height / 2);
28 | const topLayer = new Tiny.RenderLayer();
29 | topLayer.position.set(this.width / 2, this.height / 2);
30 | const opaque = new Tiny.Opaque({game: this, alpha: 0.7});
31 |
32 | this.scene.add(bottomLayer);
33 | this.scene.add(opaque);
34 | this.scene.add(topLayer);
35 |
36 | /**
37 | * Running tweens - to transform main bottom group
38 | * To see child behaviour after layer changes
39 | */
40 | this.tweens
41 | .add(bottomLayer.pivot)
42 | .to({ x: [-50, 0, 50, 0] }, 6000)
43 | .repeat(Infinity)
44 | .start();
45 | this.tweens
46 | .add(bottomLayer)
47 | .to({ rotation: [-0.5, 0, 0.5, 0] }, 5000)
48 | .repeat(Infinity)
49 | .start();
50 | this.tweens.add(bottomLayer.scale).to({ x: 1.2, y: 1.2 }, 3000).yoyo(true).repeat(Infinity).start();
51 |
52 | var _self = this;
53 |
54 | function addSprite(key, frame) {
55 | var sprite = new Tiny.Sprite(key, frame);
56 | sprite.x = Tiny.rnd(-_self.width / 2, _self.width / 2);
57 | sprite.y = Tiny.rnd(-_self.height / 2, _self.height / 2);
58 | sprite.scale.set(0.5);
59 | sprite.anchor.set(0.5);
60 | sprite.addedToTop = false;
61 | bottomLayer.add(sprite);
62 |
63 | _self.input.add(sprite);
64 |
65 | sprite.input.on( "down", function () {
66 | if (this.addedToTop) topLayer.remove(this);
67 | else topLayer.add(this);
68 |
69 | this.addedToTop = !this.addedToTop;
70 | }, sprite);
71 | }
72 |
73 | let spritesAmount = 10;
74 | while (spritesAmount--) {
75 | if (Math.random() > 0.3) addSprite("base");
76 | else addSprite("atlas", "BR");
77 | }
78 |
79 | const tip = new Tiny.Text("Click any object", {
80 | fill: "#ffffff"
81 | });
82 | tip.anchor.set(0.5);
83 | tip.x = this.width / 2;
84 | tip.y = 30;
85 | this.scene.add(tip);
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/examples/tests/RendererTexture.js:
--------------------------------------------------------------------------------
1 | /**
2 | * import "h5tiny";
3 | * import "h5tiny/examples/js/App2D";
4 | *
5 | * import "h5tiny/plugins/particles";
6 | * to use particles
7 | *
8 | * import "h5tiny/examples/js/objects/MiniMap";
9 | * to use RecursiveSprite and MiniMap
10 | */
11 |
12 | class MyGame extends Tiny.App2D {
13 | constructor(width, height) {
14 | super(width, height, 'game-container');
15 | }
16 |
17 | preload() {
18 | this.load.image('base', resources.baseImage);
19 | this.load.atlas('atlas', resources.atlas, resources.atlas_data);
20 | }
21 |
22 | create() {
23 | var emitter = (this.emitter = new Tiny.Emitter(300));
24 | emitter.x = this.width / 2;
25 | emitter.y = 300;
26 | emitter.width = 400;
27 |
28 | emitter.pattern = Tiny.SmokeParticle;
29 | emitter.fillStyle = '#666666';
30 |
31 | emitter.makeParticles(this.cache.texture['atlas.IH']);
32 | emitter.scale.set(0.7);
33 |
34 | emitter.flow(500, 10, 5);
35 |
36 | // emitter.flow(1000, 10, 3);
37 |
38 | this.particles.add(emitter);
39 | this.scene.add(emitter);
40 |
41 | var bombEmitter = (this.bombEmitter = new Tiny.Emitter(300));
42 | bombEmitter.pattern = Tiny.ExplodeParticle;
43 | bombEmitter.makeParticles();
44 |
45 | this.input.on('down', function (e) {
46 | bombEmitter.fillStyle = '#' + Math.floor(Math.random() * 0xffffff).toString(16);
47 | bombEmitter.x = e.x;
48 | bombEmitter.y = e.y;
49 | console.log('Explode');
50 | bombEmitter.explode(300, 80);
51 | });
52 |
53 | this.particles.add(bombEmitter);
54 | this.scene.add(bombEmitter);
55 |
56 | var text = (this.text = new Tiny.Text('Tiny', {
57 | font: 'bold 40pt Courier',
58 | fill: '#4e73df',
59 | wordWrap: true,
60 | wordWrapWidth: 150,
61 | align: 'center'
62 | }));
63 |
64 | this.timer.loop(100, function (argument) {
65 | text.rotation = Math.random() * Math.PI;
66 | game.text.pivot.x = Tiny.rnd(-100, 100);
67 | game.text.pivot.y = Tiny.rnd(-100, 100);
68 | });
69 |
70 | text.anchor.set(0.5);
71 |
72 | text.x = this.width / 2;
73 | text.y = this.height * 0.3;
74 |
75 | this.scene.add(text);
76 |
77 | this.recusrive = new Tiny.RecursiveSprite(this);
78 | this.recusrive.setCenter(0.5, 0.7);
79 | this.recusrive.scale.set(0.5);
80 | this.recusrive.clearAlpha = 0.01;
81 | this.recusrive.alpha = 0.8;
82 | this.recusrive.updateFrames();
83 | this.scene.add(this.recusrive);
84 |
85 | this.miniMap = new Tiny.MiniMap(this, 0.5);
86 | this.miniMap.delay = 1;
87 | this.scene.add(this.miniMap);
88 | }
89 |
90 | update(time, delta) {
91 | this.recusrive.update(delta);
92 | this.miniMap.update(delta);
93 | }
94 |
95 | resize(width, height) {
96 | super.resize(width, height);
97 | this.recusrive.resize(width, height);
98 | this.miniMap.resize(width, height);
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/examples/tests/Sound.js:
--------------------------------------------------------------------------------
1 | /**
2 | * import "h5tiny";
3 | * import "h5tiny/examples/js/App2D";
4 | * import "h5tiny/plugins/sound";
5 | */
6 |
7 | class MyGame extends Tiny.App2D {
8 | constructor(width, height) {
9 | super(width, height, 'game-container');
10 | }
11 |
12 | preload() {
13 | this.load.image("base", resources.baseImage);
14 | this.load.sound("theme", resources.theme);
15 | this.load.sound("click", resources.sound);
16 | }
17 |
18 | create() {
19 | this.sound.loop("theme");
20 |
21 | var sprite = new Tiny.Sprite("base");
22 | sprite.position.set(this.width / 2, this.height / 2);
23 | sprite.anchor.set(0.5);
24 | this.scene.add(sprite);
25 |
26 | this.input.add(sprite);
27 | sprite.input.on("click", function() {
28 | this.sound.play("click");
29 | }, this);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/examples/tests/ThreeBasic.js:
--------------------------------------------------------------------------------
1 | /**
2 | * import "h5tiny";
3 | * import "h5tiny/examples/js/App3D";
4 | * import "h5tiny/plugins/three";
5 | */
6 |
7 | class MyGame extends Tiny.App3D {
8 | constructor(width, height) {
9 | super(width, height, 'game-container');
10 | }
11 |
12 | preload() {
13 | this.load.image('base', resources.baseImage);
14 | this.load.atlas('atlas', resources.atlas, resources.atlas_data);
15 |
16 | // this.cache.image["key"]
17 | // this.cache.texture["key.1"];
18 | // this.cache.texture["key.frameName"];
19 |
20 | this.load.gltf('gltfTest', resources.gltf, true, function (gltf) {
21 | gltf.scene.traverse(function (obj) {
22 | if (obj.isMesh) obj.geometry.computeVertexNormals();
23 | });
24 | });
25 |
26 | this.load.texture3d('base', resources.baseImage);
27 |
28 | // this.cache.gltf["key"];
29 | // this.cache.texture3d["key"];
30 | // this.cache.mesh3d["key.meshName"];
31 | // this.cache.animation3d["key.animationName"];
32 | }
33 |
34 | create() {
35 | /**
36 | * Adding directional light to scene
37 | */
38 | var light = new THREE.DirectionalLight(0xffffff, 0.8);
39 | light.position.set(15, 59, 53);
40 | light.lookAt(0, 0, 0);
41 | this.scene.add(light);
42 |
43 | /**
44 | * Adding ambient light to scene
45 | */
46 | var alight = new THREE.AmbientLight(0xffffff, 0.3);
47 | this.scene.add(alight);
48 |
49 | /**
50 | * Creating test mesh, with texture.map from cache atlas image,
51 | * Playing with texture frame data via offset property
52 | */
53 | var mesh = (this.mesh = new THREE.Mesh(
54 | new THREE.BoxBufferGeometry(1, 1, 1),
55 | new THREE.MeshLambertMaterial({
56 | // color: "#ff4534",
57 | map: new THREE.Texture(this.cache.image['atlas'])
58 | })
59 | ));
60 | // mesh.scale.set(3,3,3);
61 | var map = (window.texture = mesh.material.map);
62 | map.repeat.set(0.5, 0.5);
63 | // map.offset.set(0, 0); // BR
64 | // map.offset.set(0.5, 0); // MM
65 | map.offset.set(0, 0.5); // SB
66 | // map.offset.set(0.5, 0.5); // IH
67 | map.encoding = THREE.sRGBEncoding;
68 | map.needsUpdate = true;
69 | this.scene.add(mesh);
70 |
71 | /**
72 | * Adding scene from cache
73 | */
74 | var car = (this.car = this.cache.gltf['gltfTest'].scene);
75 | var material = new THREE.MeshLambertMaterial({
76 | map: this.cache.texture3d['base']
77 | });
78 | car.traverse(function (obj) {
79 | if (obj.isMesh) obj.material = material;
80 | });
81 | car.position.x = 3;
82 | car.position.z = 3;
83 | this.scene.add(car);
84 |
85 | /**
86 | * Creating new mesh with geometry from cached mesh
87 | */
88 | var mesh2 = (this.mesh2 = new THREE.Mesh(
89 | this.cache.mesh3d['gltfTest.cabin'].geometry,
90 | mesh.material
91 | ));
92 | mesh2.rotation.z = -Math.PI / 2;
93 | mesh2.position.x = -3;
94 | mesh2.position.z = -3;
95 | this.scene.add(mesh2);
96 |
97 | /**
98 | * Getting ang clonning mesh from cache
99 | */
100 | this.scene.add(game.cache.mesh3d['gltfTest.cabin'].clone());
101 |
102 | /**
103 | * Creating new Tiny.Text3D object which is avaiable on three plugin
104 | */
105 | var text = new Tiny.Text3D('Hello World', {
106 | font: 'bold 30pt Courier',
107 | fill: '#ffffff',
108 | wordWrap: true,
109 | wordWrapWidth: 100,
110 | align: 'center',
111 | size: 4
112 | });
113 | this.scene.add(text);
114 | }
115 |
116 | update(time, delta) {
117 | this.mesh.rotation.x += delta * 0.001;
118 | this.mesh2.rotation.z += delta * 0.001;
119 | this.car.rotation.y += delta * 0.001;
120 | this.mesh.position.x = Math.sin(time * 0.0001);
121 | this.mesh.position.z = 1 + Math.sin(time * 0.0001);
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/examples/tests/ThreeCanvas.js:
--------------------------------------------------------------------------------
1 | /**
2 | * import "h5tiny";
3 | * import "h5tiny/examples/js/App3D";
4 | * import "h5tiny/plugins/three";
5 | */
6 |
7 | class MyGame extends Tiny.App3D {
8 | constructor(width, height) {
9 | super(width, height, 'game-container');
10 | }
11 |
12 | preload() {
13 | this.load.image('base', resources.baseImage);
14 | }
15 |
16 | create() {
17 | const light = new THREE.DirectionalLight(0xffffff, 1);
18 | light.position.set(15, 59, 53);
19 | light.lookAt(0, 0, 0);
20 | this.scene.add(light);
21 |
22 | const mesh = (this.mesh = new THREE.Mesh(
23 | new THREE.BoxBufferGeometry(1, 1, 1),
24 | new THREE.MeshLambertMaterial({
25 | color: '#ff4534'
26 | })
27 | ));
28 |
29 | mesh.material.color.convertSRGBToLinear();
30 |
31 | this.scene.add(mesh);
32 |
33 | const text = new Tiny.Text3D('Hello World', {
34 | font: 'bold 30pt Arial',
35 | fill: '#ffffff',
36 | wordWrap: true,
37 | wordWrapWidth: 100,
38 | align: 'center',
39 | size: 4
40 | });
41 |
42 | this.scene.add(text);
43 |
44 | const canvas2d = new Tiny.Canvas2D(300, 300);
45 | canvas2d.scale.set(4, 4, 1);
46 | canvas2d.position.z = 1.3;
47 |
48 | const sprite2d = new Tiny.Sprite('base');
49 | canvas2d.add(sprite2d);
50 |
51 | const text2d = new Tiny.Text('Hello From Canvas 2D', {
52 | font: 'bold 30pt Arial',
53 | fill: '#ffffff',
54 | wordWrap: true,
55 | wordWrapWidth: 200,
56 | align: 'center'
57 | });
58 |
59 | canvas2d.add(text2d);
60 |
61 | canvas2d.update();
62 | this.mesh.add(canvas2d);
63 |
64 | const canvas3d = new Tiny.Canvas3D(300, 300);
65 | canvas3d.scale.set(4, 4, 1);
66 | canvas3d.position.z = 1.3;
67 | canvas3d.position.x = 3.3;
68 | canvas3d.material.side = 2;
69 |
70 | canvas3d.add(sprite2d);
71 | text2d.setText('Hello From Canvas 3D');
72 | canvas3d.add(text2d);
73 |
74 | canvas3d.update();
75 | this.mesh.add(canvas3d);
76 | }
77 |
78 | update(time, delta) {
79 | this.mesh.rotation.x += delta * 0.005;
80 | this.mesh.position.x = Math.sin(time * 0.001);
81 | this.mesh.position.z = 1 + Math.sin(time * 0.001);
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/examples/tests/ThreeScreen2D.js:
--------------------------------------------------------------------------------
1 | /**
2 | * import "h5tiny";
3 | * import "h5tiny/examples/js/App3D";
4 | * import "h5tiny/plugins/three";
5 | */
6 |
7 | class MyGame extends Tiny.App3D {
8 | constructor(width, height) {
9 | super(width, height, 'game-container');
10 | }
11 |
12 | preload() {
13 | this.load.image('base', resources.baseImage);
14 | this.load.atlas('atlas', resources.atlas, resources.atlas_data);
15 | }
16 |
17 | create() {
18 | var debugText = new Tiny.Text('', {
19 | font: 'bold 30pt Arial',
20 | fill: '#ffffff',
21 | wordWrap: true,
22 | wordWrapWidth: 200,
23 | align: 'center'
24 | });
25 |
26 | debugText.x = 200;
27 | debugText.y = 20;
28 | this.screen2d.add(debugText);
29 |
30 | const button = (this.button = new Tiny.Sprite('base'));
31 | button.x = 200;
32 | button.y = 100;
33 |
34 | this.input.add(button);
35 | button.input.on('click', function () {
36 | debugText.setText('Clicked Button');
37 | console.log('Clicked Button');
38 | });
39 |
40 | // this.input.attach(button);
41 |
42 | // button.input.on("click", function() {
43 |
44 | // })
45 |
46 | // this.input.objects.push(button);
47 |
48 | this.screen2d.add(button);
49 |
50 | button.add(new Tiny.Text('Button'));
51 |
52 | // this.screen2d.canvas.autoUpdate = true;
53 | // this.screen2d.canvas.update();
54 |
55 | this.screen2d.scene.add(
56 | new THREE.Mesh(
57 | new THREE.BoxBufferGeometry(1, 1, 1),
58 | new THREE.MeshLambertMaterial({ color: 0xffffff })
59 | )
60 | );
61 |
62 | const light = new THREE.DirectionalLight(0xffffff, 1);
63 | light.position.set(15, 59, 53);
64 | light.lookAt(0, 0, 0);
65 | this.scene.add(light);
66 |
67 | const mesh = (this.mesh = new THREE.Mesh(
68 | new THREE.BoxBufferGeometry(1, 1, 1),
69 | new THREE.MeshLambertMaterial({ color: '#ff4534' })
70 | ));
71 |
72 | var clickMeT = new Tiny.Text3D('Click Me');
73 | clickMeT.position.z = 0.51;
74 | mesh.add(clickMeT);
75 |
76 | var clickMeF = new Tiny.Text3D('Click Me');
77 | clickMeF.position.y = 0.51;
78 | clickMeF.rotation.x = -Math.PI / 2;
79 | mesh.add(clickMeF);
80 |
81 | var clickMeB = new Tiny.Text3D('Click Me');
82 | clickMeB.position.y = -0.51;
83 | clickMeB.rotation.x = Math.PI / 2;
84 | mesh.add(clickMeB);
85 | // mesh.input = new Tiny.Input.Object3D();
86 |
87 | // mesh.input.on("click", function() {
88 | // // body...
89 | // })
90 |
91 | // sprite.position.x = 10;
92 | // sprite.position.y = 4;
93 |
94 | this.input.add3d(mesh, {
95 | hitBox: new THREE.Vector3(2, 2, 2),
96 | transparent: true
97 | });
98 |
99 | mesh.input.on('click', function () {
100 | debugText.setText('Click from raycaster');
101 | console.log('Click from raycaster');
102 | });
103 |
104 | this.scene.add(mesh);
105 |
106 | var confetti = (this.confetti = new Tiny.Emitter(150));
107 | confetti.x = 350;
108 | confetti.width = 800;
109 |
110 | confetti.pattern = Tiny.ConfettiParticle;
111 |
112 | confetti.makeParticles();
113 | confetti.scale.set(0.7);
114 |
115 | confetti.flow(10000, 300, 5);
116 |
117 | this.particles.add(confetti);
118 | this.screen2d.add(confetti);
119 |
120 | var ribbon = (this.ribbon = new Tiny.Emitter(18));
121 | ribbon.x = 350;
122 | ribbon.width = 800;
123 |
124 | ribbon.pattern = Tiny.RibbonParticle;
125 | ribbon.makeParticles();
126 | ribbon.scale.set(0.7);
127 |
128 | ribbon.start(false, 5000, 300);
129 |
130 | this.particles.add(ribbon);
131 | this.screen2d.add(ribbon);
132 |
133 | this.bottomRightSprite = new Tiny.Sprite('base');
134 | this.bottomRightSprite.anchor.set(0.5);
135 |
136 | this.input.add(this.bottomRightSprite, { transparent: true });
137 | this.bottomRightSprite.input.on('click', function () {
138 | mesh.scale.set(Math.random() * 2 + 1, Math.random() * 2 + 1, Math.random() * 2 + 1);
139 | });
140 |
141 | this.screen2d.add(this.bottomRightSprite);
142 |
143 | this.bottomRightSprite.position.set(this.width - 100, this.height - 100);
144 |
145 | this.input.on(
146 | 'move',
147 | function (e) {
148 | debugText.setText(Math.floor(e.x) + ' : ' + Math.floor(e.y));
149 | },
150 | this
151 | );
152 |
153 | // this.screen2d.scene.add(mesh);
154 | }
155 |
156 | update(time, delta) {
157 | this.button.scale.x = Math.sin(time * 0.001);
158 | this.mesh.rotation.x += delta * 0.005;
159 | this.mesh.position.x = Math.sin(time * 0.001);
160 | this.mesh.position.z = 1 + Math.sin(time * 0.001);
161 | }
162 |
163 | resize(width, height) {
164 | super.resize(width, height);
165 | this.bottomRightSprite.x = width - 100;
166 | this.bottomRightSprite.y = height - 100;
167 | }
168 | }
169 |
--------------------------------------------------------------------------------
/examples/tests/TilingSprite.js:
--------------------------------------------------------------------------------
1 | /**
2 | * import "h5tiny";
3 | * import "h5tiny/examples/js/App2D";
4 | * import "h5tiny/plugins/extra"
5 | *
6 | * or
7 | *
8 | * import "h5tiny/plugins/extra/objects/TilingSprite"
9 | *
10 | * To ignore unnecessary extra components
11 | *
12 | */
13 |
14 | class MyGame extends Tiny.App2D {
15 | constructor(width, height) {
16 | super(width, height, 'game-container');
17 | }
18 |
19 | preload() {
20 | this.load.atlas('atlas', resources.atlas, resources.atlas_data);
21 | }
22 |
23 | create() {
24 | this.sprite = new Tiny.TilingSprite('atlas', 'MM', this.width - 10, this.height - 10);
25 | this.sprite.x = this.sprite.y = 5;
26 | // this.sprite.scale.set(0.6);
27 |
28 | this.scene.add(this.sprite);
29 | }
30 |
31 | update(time, delta) {
32 | this.sprite.tilePosition.x += 0.5 * delta;
33 | this.sprite.tilePosition.y += Math.sin(time * 0.01) * 10;
34 |
35 | this.sprite.tileScale.x = this.sprite.tileScale.y = Math.sin(time * 0.0007) * 1;
36 | }
37 |
38 | resize(width, height) {
39 | super.resize(width, height);
40 | this.sprite.width = width - 10;
41 | this.sprite.height = height - 10;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/examples/tests/Tweens.js:
--------------------------------------------------------------------------------
1 | /**
2 | * import "h5tiny";
3 | * import "h5tiny/examples/js/App2D";
4 | */
5 |
6 | class MyGame extends Tiny.App2D {
7 | constructor(width, height) {
8 | super(width, height, 'game-container');
9 | }
10 |
11 | preload() {
12 | this.load.image('base', resources.baseImage);
13 | }
14 |
15 | create() {
16 | var sprite1 = new Tiny.Sprite('base');
17 | var sprite2 = new Tiny.Sprite('base');
18 | var sprite3 = new Tiny.Sprite('base');
19 | var sprite4 = new Tiny.Sprite('base');
20 |
21 | sprite1.scale.set(0.5);
22 | sprite2.scale.set(0.5);
23 | sprite3.scale.set(0.5);
24 | sprite4.scale.set(0.5);
25 | sprite1.position.set(50, 40);
26 | sprite2.position.set(50, 40 + 70);
27 | sprite3.position.set(50, 40 + 70 + 70);
28 | sprite4.position.set(50, 40 + 70 + 70 + 70);
29 |
30 | this.scene.add(sprite1);
31 | this.scene.add(sprite2);
32 | this.scene.add(sprite3);
33 | this.scene.add(sprite4);
34 |
35 | this.tweens.add(sprite1).to({ x: 200 }, 1400).start();
36 | this.tweens.add(sprite2).to({ x: 200 }, 1000).delay(1400).repeatDelay(100).repeat(5).start();
37 | this.tweens
38 | .add(sprite3)
39 | .to({ x: 200 }, 500)
40 | .yoyo(true)
41 | .easing(Tiny.Easing.Sinusoidal.InOut)
42 | .repeat(Infinity)
43 | .start();
44 | var tween = this.tweens
45 | .add(sprite4)
46 | .to({ x: 200 }, 500)
47 | .yoyo(true)
48 | .easing(Tiny.Easing.Sinusoidal.InOut)
49 | .repeat(Infinity)
50 | .start();
51 |
52 | this.timer.loop(2000, function () {
53 | if (tween.isPaused()) tween.resume();
54 | else tween.pause();
55 | });
56 |
57 | /**
58 | * Easing tests
59 | */
60 | let y = 15;
61 |
62 | for (let easeName in Tiny.Easing) {
63 | for (let fun in Tiny.Easing[easeName]) {
64 | let name = easeName + '.' + fun;
65 | let ease = Tiny.Easing[easeName][fun];
66 |
67 | let sprite = new Tiny.Sprite('base');
68 | sprite.scale.set(0.1);
69 | sprite.x = 400;
70 | sprite.y = y;
71 | y += 12;
72 | this.scene.add(sprite);
73 |
74 | var nameText = new Tiny.Text(name, { font: '300 7pt Courier' });
75 | nameText.x = sprite.x - 10;
76 | nameText.y = sprite.y;
77 | nameText.anchor.x = 1;
78 |
79 | this.scene.add(nameText);
80 |
81 | this.tweens
82 | .add(sprite)
83 | .to({ x: 570 }, 2000)
84 | .yoyo(true)
85 | .repeatDelay(500)
86 | .repeat(Infinity)
87 | .easing(ease)
88 | .start();
89 | }
90 | }
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "h5tiny",
3 | "version": "2.2.3",
4 | "description": "Fast and tiny JavaScript library for HTML5 game and creatives developing.",
5 | "main": "./build/tiny.js",
6 | "files": [
7 | "src",
8 | "build",
9 | "plugins",
10 | "examples/js",
11 | "examples/jsm",
12 | "README.md"
13 | ],
14 | "directories": {
15 | "examples": "examples"
16 | },
17 | "repository": {
18 | "type": "git",
19 | "url": "https://github.com/peter-hutsul/h5tiny"
20 | },
21 | "scripts": {
22 | "serve": "webpack-dev-server --port 3000 --open --live-reload --mode development --watch-files examples --static-directory examples",
23 | "watch": "webpack --config webpack.dev.js --watch",
24 | "dev": "start npm run watch && npm run serve",
25 | "build": "webpack --config webpack.build.js"
26 | },
27 | "keywords": [
28 | "2d",
29 | "html5",
30 | "canvas",
31 | "game",
32 | "tiny",
33 | "javascript",
34 | "playable",
35 | "three"
36 | ],
37 | "author": "Peter Hutsul",
38 | "license": "ISC",
39 | "devDependencies": {
40 | "terser-webpack-plugin": "^5.3.6",
41 | "three": "^0.112.1",
42 | "webpack": "^5.75.0",
43 | "webpack-cli": "^5.0.1",
44 | "webpack-dev-server": "^4.13.3"
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/plugins/anim/Anim.js:
--------------------------------------------------------------------------------
1 | var noop = function () {};
2 |
3 | var _nextId = 0;
4 |
5 | class Anim {
6 | constructor(obj, options) {
7 | this.uuid = _nextId++;
8 | this.key = options.key;
9 | this.system = options.system;
10 | this.parent = obj;
11 | this.valid = false;
12 | this.duration = options.duration || 1000;
13 | this._time = 0;
14 | this.running = false;
15 | this.repeat = options.repeat || 0;
16 | this._reverse = options.reverse || false;
17 | this.yoyo = options.yoyo || false;
18 | this.repeatDelay = options.repeatDelay || 0;
19 | this._delay = 0;
20 | this.onStart = options.onStart || noop;
21 | this.onStop = options.onStop || noop;
22 | this.onComplete = options.onComplete || noop;
23 | this.onRepeat = options.onRepeat || noop;
24 | if (options.delay) this._delay = -options.delay;
25 | this._onStartFired = false;
26 | }
27 | setValue() {}
28 | reverse() {
29 | this._reverse = !this._reverse;
30 | }
31 | start() {
32 | if (!this.running) {
33 | this.running = true;
34 | if (this.system) this.system.addAnim(this);
35 | }
36 | }
37 | pause() {
38 | if (this.running) {
39 | this.running = false;
40 | if (this.system) this.system.removeAnim(this);
41 | }
42 | }
43 | stop() {
44 | this.running = false;
45 | this._time = 0;
46 | this.setValue(0);
47 | if (this.system) this.system.removeAnim(this);
48 | this.onStop(this.parent);
49 | }
50 | update(delta) {
51 | if (!this.parent.worldTransform || !this.valid) return false;
52 |
53 | if (this.running) {
54 | if (this._delay < 0) {
55 | this._delay += delta;
56 | return true;
57 | }
58 |
59 | if (!this._onStartFired) {
60 | this._onStartFired = true;
61 | this.onStart(this.parent);
62 | }
63 |
64 | this._time += delta;
65 | if (this._time > this.duration) {
66 | if (this.repeat > 0 || this.repeat == -1) {
67 | do {
68 | this._time -= this.duration;
69 | } while (this._time > this.duration);
70 |
71 | if (this.repeat > 0) this.repeat--;
72 |
73 | if (this.repeatDelay) {
74 | this._delay = -this.repeatDelay;
75 | }
76 |
77 | if (this.yoyo) this.reverse();
78 | this.onRepeat(this.parent);
79 | } else {
80 | this.onComplete(this.parent);
81 | this._time = this.duration;
82 | this.running = false;
83 | return false;
84 | }
85 | }
86 | var progress = this._time / this.duration;
87 | if (this._reverse) progress = 1 - progress;
88 | this.setValue(progress);
89 | }
90 |
91 | return true;
92 | }
93 | }
94 |
95 | Tiny.Anim = Anim;
96 |
--------------------------------------------------------------------------------
/plugins/anim/AnimationManager.js:
--------------------------------------------------------------------------------
1 | class AnimationManager {
2 | constructor(game) {
3 | this.game = game;
4 | this.anims = {};
5 | // this._addedAnims = {};
6 | this.cache = {};
7 | }
8 |
9 | create(options) {
10 | options.system = this;
11 | options.type = options.type || 'spritesheet';
12 | this.cache[options.key] = options;
13 | // this.list.push(options);
14 | }
15 |
16 | removeAnim(animation) {
17 | var uuid = animation.uuid;
18 | delete this.anims[uuid];
19 | // delete this._addedAnims[uuid];
20 |
21 | // var index = this.list.indexOf(animation);
22 | // if (index > -1) this.list.splice(index, 1);
23 | }
24 |
25 | addAnim(anim) {
26 | var uuid = anim.uuid;
27 | this.anims[uuid] = anim;
28 | // this._addedAnims[uuid] = anim;
29 | }
30 |
31 | add(obj, data) {
32 | let manager = this;
33 |
34 | obj.anim = {
35 | cache: {},
36 | data: data || {},
37 | current: null,
38 | system: this
39 | };
40 |
41 | obj.play = function (options) {
42 | if (obj.anim.current) manager.removeAnim(obj.anim.current);
43 |
44 | if (typeof options === 'string') options = { key: options };
45 |
46 | var source = manager.cache[options.key];
47 | var __class__ = Tiny.Anim[source.type];
48 |
49 | for (var key in source) {
50 | if (options[key] === undefined) options[key] = source[key];
51 | }
52 |
53 | var animation = new __class__(obj, options);
54 | obj.anim.current = animation;
55 |
56 | // manager.list.push(animation);
57 | animation.start();
58 | // manager.addAnim(animation);
59 |
60 | return animation;
61 |
62 | // body...
63 | };
64 |
65 | obj.resume = function () {
66 | obj.anim.current && obj.anim.current.start();
67 | };
68 |
69 | obj.pause = function () {
70 | obj.anim.current && obj.anim.current.pause();
71 | };
72 |
73 | obj.stop = function () {
74 | obj.anim.current && obj.anim.current.stop();
75 | };
76 | }
77 |
78 | update(delta) {
79 | // for (var i = 0; i < this.list.length; i++) {
80 | // this.list[i].update(delta);
81 | // }
82 |
83 | var _ids = Object.keys(this.anims);
84 |
85 | if (_ids.length === 0) return;
86 |
87 | // do {
88 | // this._addedAnims = {};
89 |
90 | for (var i = 0; i < _ids.length; i++) {
91 | var anim = this.anims[_ids[i]];
92 |
93 | if (anim && anim.update(delta) === false) {
94 | // anim.running = false;
95 |
96 | // if (!preserve) {
97 | delete this.anims[_ids[i]];
98 | // }
99 | }
100 | }
101 |
102 | // _ids = Object.keys(this._addedAnims);
103 |
104 | // } while (_ids.length > 0);
105 |
106 | // while (ids.length > 0) {
107 | // this._addedAnims = {};
108 |
109 | // for (var i = 0; i < ids.length; i++) {
110 | // var anim = this.anims[ids[i]];
111 |
112 | // if (anim && anim.update(delta) === false) {
113 | // // anim.running = false;
114 |
115 | // // if (!preserve) {
116 | // delete this.anims[ids[i]];
117 | // // }
118 | // }
119 | // }
120 |
121 | // ids = Object.keys(this._addedAnims);
122 | // }
123 |
124 | return true;
125 | }
126 |
127 | destroy(clearCache) {
128 | // this.list.length = 0;
129 | this.cache = {};
130 | this.anims = {};
131 | // this._addedAnims = {};
132 | }
133 | }
134 |
135 | Tiny.registerSystem('anim', AnimationManager);
136 |
--------------------------------------------------------------------------------
/plugins/anim/Loader.js:
--------------------------------------------------------------------------------
1 | Tiny.Cache.keyframes = {};
2 |
3 | Tiny.Loader.prototype.keyframes = function (key, src) {
4 | if (src) {
5 | this.list.push({
6 | key: key,
7 | src: src,
8 | type: 'keyframes'
9 | });
10 | }
11 | };
12 |
13 | Tiny.Loader.keyframes = function (resource, cb) {
14 | Tiny.Cache.keyframes[resource.key] = resource.src;
15 | cb();
16 | };
17 |
--------------------------------------------------------------------------------
/plugins/anim/SpritesheetAnim.js:
--------------------------------------------------------------------------------
1 | class SpritesheetAnim extends Tiny.Anim {
2 | constructor(obj, options) {
3 | super(obj, options);
4 |
5 | this.frames = [];
6 | this.currentIndex = 0;
7 |
8 | var data = options.data;
9 |
10 | if (typeof data === 'string') {
11 | data = { key: data };
12 | }
13 |
14 | if (Array.isArray(data)) this.frames = data;
15 | else if (data.key) {
16 | var texture = Tiny.Cache.texture[data.key + '.0'];
17 |
18 | if (texture) {
19 | var from = data.from || 0;
20 | var to = data.to || texture.lastFrame;
21 |
22 | for (var frame = from; frame <= to; frame++) {
23 | this.frames.push(texture.key + '.' + frame);
24 | }
25 | }
26 | }
27 |
28 | if (this.frames.length > 0) {
29 | if (options.fps) this.duration = (1000 / options.fps) * this.frames.length;
30 |
31 | this.valid = true;
32 | }
33 | }
34 |
35 | reverse() {
36 | super.reverse();
37 | if (!this.repeatDelay) this._time += this.duration / this.frames.length;
38 | }
39 |
40 | setValue(progress) {
41 | var index = (this.frames.length * progress) | 0;
42 | if (index > this.frames.length - 1) index = this.frames.length - 1;
43 |
44 | // console.log(index);
45 |
46 | if (index != this.currentIndex) {
47 | this.currentIndex = index;
48 | // if (this.reverse) index = this.frames.length - index - 1;
49 | var frame = this.frames[index];
50 |
51 | // console.log(index);
52 | var texture = Tiny.Cache.texture[frame];
53 |
54 | // texture &&
55 | this.parent.setTexture(texture);
56 | // this.parent.setTexture(Tiny.Cache.texture[this.texture.key + "." +frame]);
57 | // console.log(progress);
58 | }
59 | }
60 | }
61 |
62 | Tiny.Anim.spritesheet = SpritesheetAnim;
63 |
--------------------------------------------------------------------------------
/plugins/anim/index.js:
--------------------------------------------------------------------------------
1 | require('./Anim');
2 | require('./SpritesheetAnim');
3 | require('./KeyframesAnim');
4 | require('./AnimationManager');
--------------------------------------------------------------------------------
/plugins/create/index.js:
--------------------------------------------------------------------------------
1 | Tiny.Create = {};
2 |
3 | require('./spritesheet');
--------------------------------------------------------------------------------
/plugins/create/spritesheet.js:
--------------------------------------------------------------------------------
1 | Tiny.Create.spritesheet = function spritesheet(options) {
2 | var resolution = options.resolution || 1;
3 | var frameWidth = (resolution * options.width) | 0;
4 | var frameHeight = (resolution * options.height) | 0;
5 | var frames = options.frames;
6 | var key = options.key;
7 | var lastFrame = frames - 1;
8 |
9 | var totalWidth = frameWidth * options.frames;
10 | var renderer = Tiny.defaultRenderer;
11 |
12 | var textureBuffer = new Tiny.CanvasBuffer(totalWidth, frameHeight);
13 |
14 | var tmpMatrix = new Tiny.Matrix();
15 | // var scale =
16 | // tmpMatrix.scale(0.5, 0.5);
17 |
18 | var uuid, texture, frame, displayObject, bounds, wt, context;
19 |
20 | for (var index = 0; index < frames; index++) {
21 | frame = new Tiny.Rectangle(frameWidth * index, 0, frameWidth, frameHeight);
22 |
23 | context = textureBuffer.context;
24 |
25 | displayObject = options.draw((index + 1) / frames, context, frame);
26 |
27 | if(displayObject) {
28 |
29 | bounds = displayObject.getBounds();
30 | // console.log(bounds.x, bounds.y, bounds.width, bounds.height);
31 |
32 | // tmpMatrix.translate()
33 | tmpMatrix.tx = -bounds.x + frame.x;
34 | tmpMatrix.ty = -bounds.y;
35 |
36 | wt = displayObject.worldTransform;
37 | wt.tx = options.width * index + options.width / 2;
38 | wt.ty = options.height / 2;
39 | // wt.identity();
40 | // wt.scale(0.5, 0.5);
41 | // wt.a = 0.5;
42 | // wt.d = 0.5;
43 |
44 | // console.log(wt.a, wt.d)
45 |
46 | // wt.append(tmpMatrix);
47 | // console.log(wt.a, wt.d)
48 |
49 | // displayObject.width = 50;
50 | // displayObject.height = 50;
51 |
52 | // setWorld Alpha to ensure that the object is renderer at full opacity
53 | displayObject.worldAlpha = 1;
54 |
55 | // Time to update all the children of the displayObject with the new matrix..
56 | var children = displayObject.children;
57 |
58 | for (var i = 0, j = children.length; i < j; i++) {
59 | children[i].updateTransform();
60 | }
61 |
62 | var realResolution = renderer.resolution;
63 |
64 | renderer.resolution = resolution;
65 |
66 | renderer.renderObject(displayObject, context);
67 |
68 | // if (__DEBUG__) {
69 | // context.resetTransform();
70 | // context.rect(frame.x, frame.y, frame.width, frame.height);
71 | // context.stroke();
72 | // }
73 |
74 | renderer.resolution = realResolution;
75 | }
76 |
77 | uuid = key + '.' + index;
78 |
79 | texture = new Tiny.Texture(textureBuffer.canvas, frame);
80 |
81 | texture.key = key;
82 | texture.lastFrame = lastFrame;
83 |
84 | Tiny.Cache.texture[uuid] = texture;
85 | }
86 |
87 | Tiny.Cache.texture[key] = new Tiny.Texture(textureBuffer.canvas);
88 |
89 | // return renderTexture;
90 | };
91 |
--------------------------------------------------------------------------------
/plugins/extra/index.js:
--------------------------------------------------------------------------------
1 | require('./systems/Tween');
2 | require('./systems/Loader');
3 | require('./math/Ellipse');
4 | require('./objects/TilingSprite');
5 | require('./objects/RenderLayer');
6 | require('./objects/ProgressBar');
7 | require('./objects/Opaque');
8 | // require('./objects/Button');
9 | require('./textures/Texture');
10 |
--------------------------------------------------------------------------------
/plugins/extra/math/Ellipse.js:
--------------------------------------------------------------------------------
1 | Tiny.Ellipse = function (x, y, width, height) {
2 | x = x || 0;
3 | y = y || 0;
4 | width = width || 0;
5 | height = height || 0;
6 |
7 | this.x = x || 0;
8 | this.y = y || 0;
9 |
10 | this.width = width || 0;
11 | this.height = height || 0;
12 |
13 | this.type = Tiny.Primitives.ELIP;
14 | };
15 |
16 | Tiny.Ellipse.prototype.constructor = Tiny.Ellipse;
17 |
18 | Tiny.Graphics.prototype.drawEllipse = function (x, y, width, height) {
19 | this.drawShape(new Tiny.Ellipse(x, y, width, height));
20 |
21 | return this;
22 | };
23 |
--------------------------------------------------------------------------------
/plugins/extra/objects/Button.js:
--------------------------------------------------------------------------------
1 | Tiny.Button = function(input, params) {
2 |
3 | var options;
4 |
5 | if (typeof params === "string") {
6 | options = {
7 | label: params,
8 | width: 160,
9 | height: 40
10 | }
11 | }
12 | else {
13 | options = params;
14 | options.width = options.width || 160;
15 | options.height = options.height || 40;
16 | }
17 |
18 | var bg = new Tiny.Graphics();
19 | bg.beginFill("#4e63df");
20 | bg.drawRoundedRect(0, 0, options.width, options.height, 10);
21 | bg.endFill();
22 | bg.lineStyle(5, "#3e4fb2", 1);
23 | bg.drawRoundedRect(0, 0, options.width, options.height, 10);
24 |
25 | Tiny.Sprite.call(this, bg.generateTexture());
26 |
27 | var label = this.label = new Tiny.Text(options.label, {
28 | fill: "#ffffff",
29 | font: "300 13pt Arial",
30 | align: "center"
31 | });
32 | label.y = 2;
33 | label.anchor.set(0.5);
34 | this.add(label);
35 |
36 | this.anchor.set(0.5);
37 |
38 | input.add(this);
39 |
40 | input.on("move", function(e) {
41 | var bounds = this.getBounds();
42 | if (bounds.contains(e.x, e.y)) this.tint = "#a1a1a1"
43 | else this.tint = "#ffffff"
44 | } , this)
45 |
46 | this.input.on("down", function(e) {
47 | this.scale.set(0.95);
48 | }, this)
49 |
50 | this.input.on("up", function(e) {
51 | this.scale.set(1.05);
52 | }, this)
53 | };
54 |
55 | Tiny.Button.prototype = Object.create(Tiny.Sprite.prototype);
56 | Tiny.Button.prototype.constructor = Tiny.Button;
--------------------------------------------------------------------------------
/plugins/extra/objects/Object2D.js:
--------------------------------------------------------------------------------
1 | Tiny.Object2D.prototype.removeChildren = function (beginIndex, endIndex) {
2 | var begin = beginIndex || 0;
3 | var end = typeof endIndex === "number" ? endIndex : this.children.length;
4 | var range = end - begin;
5 |
6 | if (range > 0 && range <= end) {
7 | var removed = this.children.splice(begin, range);
8 | for (var i = 0; i < removed.length; i++) {
9 | var child = removed[i];
10 | child.parent = undefined;
11 | }
12 | return removed;
13 | } else if (range === 0 && this.children.length === 0) {
14 | return [];
15 | } else {
16 | throw new Error("removeChildren: Range Error, numeric values are outside the acceptable range");
17 | }
18 | };
--------------------------------------------------------------------------------
/plugins/extra/objects/Opaque.js:
--------------------------------------------------------------------------------
1 | Tiny.Opaque = function (options) {
2 | // Tiny.BaseObject2D.call(this);
3 |
4 | var game = (this.game = options.game);
5 | this.visible = true;
6 | this._bounds = new Tiny.Rectangle(0, 0, 1, 1);
7 | this.color = options.color || '#000000';
8 | this.alpha = options.alpha || 0.5;
9 |
10 | if (options.input !== false) {
11 | game.input.add(this, { transparent: options.transparent });
12 | }
13 | };
14 |
15 | // Tiny.Opaque.prototype = Object.create(Tiny.BaseObject2D.prototype);
16 | Tiny.Opaque.prototype.constructor = Tiny.Opaque;
17 |
18 | Tiny.Opaque.prototype.destroy = function () {};
19 | Tiny.Opaque.prototype.updateTransform = function () {};
20 |
21 | Object.defineProperty(Tiny.Opaque.prototype, "worldVisible", {
22 | get: function () {
23 | return this.visible;
24 | }
25 | });
26 |
27 | Tiny.Opaque.prototype.getBounds = function () {
28 | this._bounds.setTo(0, 0, this.game.width, this.game.height);
29 | return this._bounds;
30 | };
31 |
32 | Tiny.Opaque.prototype.render = function (renderSession) {
33 | if (this.visible === false || this.alpha === 0) return;
34 |
35 | renderSession.context.resetTransform();
36 |
37 | renderSession.context.globalAlpha = this.alpha;
38 | renderSession.context.fillStyle = this.color;
39 | renderSession.context.fillRect(
40 | 0,
41 | 0,
42 | renderSession.context.canvas.width,
43 | renderSession.context.canvas.height
44 | );
45 | };
46 |
--------------------------------------------------------------------------------
/plugins/extra/objects/ProgressBar.js:
--------------------------------------------------------------------------------
1 | var defaultOptions = {
2 | bgColor: "#ffffff",
3 | bgAlpha: 1,
4 | value: 1,
5 | width: 230,
6 | height: 30,
7 | radius: 15,
8 | colors: ["#ff0000", "#ffc322", "#08c013"],
9 | animated: true,
10 | duration: 1000,
11 | easing: Tiny.Easing.Cubic.InOut,
12 | strokeColor: "#e1e1e1",
13 | strokeWidth: 0,
14 | strokeAlpha: 1,
15 | resolution: 1
16 | };
17 |
18 | Tiny.ProgressBar = function (options) {
19 | options = options || {};
20 |
21 | for (var key in defaultOptions) {
22 | if (options[key] == undefined) options[key] = defaultOptions[key];
23 | }
24 |
25 | var graphics = new Tiny.Graphics();
26 |
27 | graphics.beginFill(options.bgColor, options.bgAlpha);
28 | graphics.drawRoundedRect(
29 | options.strokeWidth / 2,
30 | options.strokeWidth / 2,
31 | options.width,
32 | options.height,
33 | options.radius
34 | );
35 | graphics.endFill();
36 |
37 | if (options.strokeWidth) {
38 | graphics.lineStyle(options.strokeWidth, options.strokeColor, options.strokeAlpha);
39 | graphics.drawRoundedRect(
40 | 0,
41 | 0,
42 | options.width + options.strokeWidth,
43 | options.height + options.strokeWidth,
44 | options.radius + options.strokeWidth / 2
45 | );
46 | }
47 |
48 | Tiny.Sprite.call(this, graphics.generateTexture(options.resolution));
49 |
50 | this.anchor.set(0.5);
51 |
52 | this.game = options.game || this.game;
53 | this.animated = options.animated;
54 | this.duration = options.duration;
55 | this.easing = options.easing;
56 | this.value = options.value;
57 | this.originalWidth = options.width * options.resolution;
58 | this._tween = null;
59 | this._crop = new Tiny.Rectangle(
60 | 0,
61 | 0,
62 | options.width * options.resolution,
63 | options.height * options.resolution
64 | );
65 | this._sprites = [];
66 |
67 | for (var i = 0; i < options.colors.length; i++) {
68 | graphics.clear();
69 | graphics.beginFill(options.colors[i]);
70 | graphics.drawRoundedRect(0, 0, options.width, options.height, options.radius);
71 | graphics.endFill();
72 |
73 | var colorSprite = new Tiny.Sprite(graphics.generateTexture(options.resolution));
74 | colorSprite.anchor = this.anchor;
75 | // colorSprite.anchor.set(0.5);
76 | colorSprite.texture.crop = this._crop;
77 | this.add(colorSprite);
78 | this._sprites.push(colorSprite);
79 | }
80 |
81 | graphics.destroy();
82 |
83 | this._setValue(this.value);
84 | };
85 |
86 | Tiny.ProgressBar.prototype = Object.create(Tiny.Sprite.prototype);
87 | Tiny.ProgressBar.prototype.constructor = Tiny.ProgressBar;
88 |
89 | Tiny.ProgressBar.prototype._setValue = function (value) {
90 |
91 | value = Math.min(1, Math.max(0, value));
92 |
93 | if (value == this._value) return;
94 |
95 | this._value = value;
96 |
97 | this._crop.width = this.originalWidth * value;
98 |
99 | if (value == 0 || this._sprites.length === 1) return;
100 | if (value == 1) {
101 | this._sprites[this._sprites.length - 1].alpha = 1;
102 | return;
103 | }
104 |
105 | var step;
106 | if (this._sprites.length == 2) {
107 | this._sprites[1].alpha = value;
108 | } else if (this._sprites.length == 3) {
109 | step = 0.5;
110 | var lerp;
111 |
112 | if (value >= step) {
113 | lerp = 1 - (1 - value) / step;
114 | this._sprites[1].alpha = 1;
115 | this._sprites[2].alpha = lerp * lerp;
116 | } else if (value < step) {
117 | lerp = (1 - value - step) / step;
118 | this._sprites[1].alpha = 1 - lerp * lerp;
119 | this._sprites[2].alpha = 0;
120 | }
121 | } else {
122 | var mixes = this._sprites.length - 1;
123 | step = 1 / mixes;
124 |
125 | var index = Math.floor(value * mixes) + 1;
126 | var alpha = (value - step * (index - 1)) / step;
127 |
128 | for (var i = 0; i < this._sprites.length; i++) {
129 | this._sprites[i].alpha = 0;
130 | }
131 |
132 | this._sprites[index - 1].alpha = 1;
133 | this._sprites[index].alpha = alpha;
134 | }
135 | };
136 |
137 | Tiny.ProgressBar.prototype.setValue = function (value) {
138 | value = Math.min(1, Math.max(0, value));
139 | this.value = value;
140 |
141 | if (this.animated) {
142 | if (this._tween) this._tween.stop();
143 |
144 | var _self = this;
145 |
146 | var tmpObj = { value: _self._value };
147 |
148 | this._tween = this.game.tweens
149 | .add(tmpObj)
150 | .to({ value: value }, this.duration)
151 | .easing(this.easing)
152 | .onUpdate(function () {
153 | _self._setValue(tmpObj.value);
154 | })
155 | .start();
156 | } else {
157 | this._setValue(value);
158 | }
159 | };
160 |
161 | Tiny.ProgressBar.defaultOptions = defaultOptions;
162 |
--------------------------------------------------------------------------------
/plugins/extra/objects/RenderLayer.js:
--------------------------------------------------------------------------------
1 | Tiny.RenderLayer = function () {
2 | Tiny.Object2D.call(this);
3 | };
4 |
5 | Tiny.RenderLayer.prototype = Object.create(Tiny.Object2D.prototype);
6 | Tiny.RenderLayer.prototype.constructor = Tiny.RenderLayer;
7 |
8 | var noop = function () {};
9 |
10 | Tiny.RenderLayer.prototype.addChildAt = function (child, index) {
11 | if (index >= 0 && index <= this.children.length) {
12 |
13 | child._RenderLayer_render = child.render;
14 | child.render = noop;
15 |
16 | this.children.splice(index, 0, child);
17 |
18 | return child;
19 | } else {
20 | throw new Error(
21 | child + "addChildAt: The index " + index + " supplied is out of bounds " + this.children.length
22 | );
23 | }
24 | };
25 |
26 | Tiny.RenderLayer.prototype.removeChildAt = function (index) {
27 | var child = this.getChildAt(index);
28 | this.children.splice(index, 1);
29 |
30 | child.render = child._RenderLayer_render;
31 | child._RenderLayer_render = null;
32 |
33 | return child;
34 | };
35 |
36 | Tiny.RenderLayer.prototype.updateTransform = function () {}
37 |
38 |
39 | Tiny.RenderLayer.prototype.render = function (renderSession) {
40 | if (this.visible === false || this.alpha === 0) return;
41 |
42 | if (this._cacheAsBitmap) {
43 | this._renderCachedSprite(renderSession);
44 | return;
45 | }
46 |
47 | if (this._mask) {
48 | renderSession.maskManager.pushMask(this._mask, renderSession);
49 | }
50 |
51 | for (var i = 0; i < this.children.length; i++) {
52 | this.children[i]._RenderLayer_render(renderSession);
53 | }
54 |
55 | if (this._mask) {
56 | renderSession.maskManager.popMask(renderSession);
57 | }
58 | };
59 |
--------------------------------------------------------------------------------
/plugins/extra/systems/Loader.js:
--------------------------------------------------------------------------------
1 | Tiny.Cache.font = {};
2 |
3 | Tiny.Loader.prototype.font = function (key, src, weight) {
4 | this.list.push({
5 | key: key,
6 | src: src,
7 | weight: weight,
8 | type: "font"
9 | });
10 | };
11 |
12 | Tiny.Loader.font = function (resource, cb) {
13 |
14 | var weight = resource.weight || 'normal';
15 | var key = resource.key + '-' + weight;
16 |
17 | if (Tiny.Cache.font[key]) return cb();
18 |
19 | var font = new FontFace(resource.key, 'url(' + resource.src + ')', { weight: weight });
20 | font.load().then(
21 | function () {
22 | document.fonts.add(font);
23 | Tiny.Cache.font[key] = font;
24 | cb();
25 | },
26 | function () {
27 | console.error(err);
28 | }
29 | );
30 | };
--------------------------------------------------------------------------------
/plugins/extra/systems/Tween.js:
--------------------------------------------------------------------------------
1 | Tiny.TweenManager.prototype.removeByObject = function (obj) {
2 | var tweens = this.group._tweens;
3 | var tweenIds = Object.keys(tweens);
4 |
5 | for (var i = 0; i < tweenIds.length; i++) {
6 | var tween = tweens[tweenIds[i]];
7 |
8 | if (tween._object === obj) this.remove(tween);
9 | }
10 | };
11 |
--------------------------------------------------------------------------------
/plugins/extra/textures/Texture.js:
--------------------------------------------------------------------------------
1 | Tiny.Texture.EMPTY = new Tiny.Texture({}, new Tiny.Rectangle(), new Tiny.Rectangle());
--------------------------------------------------------------------------------
/plugins/particles/Particle.js:
--------------------------------------------------------------------------------
1 | Tiny.Particle = function (emitter) {
2 | Tiny.BaseObject2D.call(this);
3 |
4 | this.parent = emitter;
5 |
6 | this.anchor = new Tiny.Point();
7 |
8 | this.texture = { valid: false };
9 |
10 | this._frame = 0;
11 |
12 | this.lifespan = 0;
13 | };
14 |
15 | Tiny.Particle.prototype = Object.create(Tiny.BaseObject2D.prototype);
16 | Tiny.Particle.prototype.constructor = Tiny.Particle;
17 |
18 | Tiny.Particle.prototype.setTexture = function (texture, key) {
19 | if (typeof texture == "string") {
20 | var imagePath = texture;
21 |
22 | if (key != undefined) {
23 | imagePath = imagePath + "_" + key;
24 | }
25 |
26 | texture = Tiny.Cache.texture[imagePath];
27 |
28 | if (!texture) texture = new Tiny.Texture(imagePath);
29 | }
30 |
31 | this.texture = texture;
32 | };
33 |
34 | Object.defineProperty(Tiny.Particle.prototype, "frameName", {
35 | get: function () {
36 | return this.texture.frame.name;
37 | },
38 |
39 | set: function (value) {
40 | if (this.texture.frame.name) {
41 | this.setTexture(Tiny.TextureCache[this.texture.key + "_" + value]);
42 | }
43 | }
44 | });
45 |
46 | Object.defineProperty(Tiny.Particle.prototype, "frame", {
47 | get: function () {
48 | return this._frame;
49 | },
50 |
51 | set: function (value) {
52 | if (this.texture.max_no_frame) {
53 | this._frame = value;
54 | if (this._frame > this.texture.max_no_frame) this._frame = 0;
55 | this.setTexture(Tiny.TextureCache[this.texture.key + "_" + this._frame]);
56 | }
57 | }
58 | });
59 |
60 | Tiny.Particle.prototype.drawTexture = function (renderSession) {
61 | var dx = this.anchor.x * -this.texture.frame.width;
62 | var dy = this.anchor.y * -this.texture.frame.height;
63 |
64 | var resolution = this.texture.resolution / renderSession.resolution;
65 |
66 | renderSession.context.drawImage(
67 | this.texture.source,
68 | this.texture.crop.x,
69 | this.texture.crop.y,
70 | this.texture.crop.width,
71 | this.texture.crop.height,
72 | dx / resolution,
73 | dy / resolution,
74 | this.texture.crop.width / resolution,
75 | this.texture.crop.height / resolution
76 | );
77 | };
78 |
79 | Tiny.Particle.prototype.reset = function (x, y) {
80 | this.x = x || 0;
81 | this.y = y || 0;
82 |
83 | this.alpha = 1;
84 | this.scale.set(1);
85 | };
86 |
87 | Tiny.Particle.prototype.update = function (time, delta) {};
88 |
89 | Tiny.Particle.prototype.onEmit = function () {};
90 |
91 | Tiny.Particle.prototype.draw = function (renderSession) {};
92 |
93 | Tiny.Particle.prototype._update = function (delta) {
94 | if (this.visible === false) return false;
95 |
96 | this.lifespan -= delta;
97 |
98 | if (this.lifespan <= 0) {
99 | this.visible = false;
100 | return false;
101 | }
102 |
103 | this.update(this.lifespan, delta);
104 | };
105 |
106 | Tiny.Particle.prototype.render = function (renderSession) {
107 | if (this.visible === false || this.alpha === 0) return;
108 |
109 | this.updateTransform();
110 |
111 | renderSession.context.globalAlpha = this.worldAlpha;
112 |
113 | renderSession.context.setTransform(
114 | this.worldTransform.a,
115 | this.worldTransform.b,
116 | this.worldTransform.c,
117 | this.worldTransform.d,
118 | this.worldTransform.tx * renderSession.resolution,
119 | this.worldTransform.ty * renderSession.resolution
120 | );
121 |
122 | if (this.texture.valid) this.drawTexture(renderSession);
123 | else this.draw(renderSession.context, renderSession.resolution);
124 | };
125 |
--------------------------------------------------------------------------------
/plugins/particles/index.js:
--------------------------------------------------------------------------------
1 | Tiny.Particles = function (game) {
2 | this.game = game;
3 |
4 | this.list = [];
5 | };
6 |
7 | Tiny.Particles.prototype = {
8 | add: function (emitter) {
9 | emitter.system = this;
10 |
11 | this.list.push(emitter);
12 |
13 | return emitter;
14 | },
15 |
16 | remove: function (emitter) {
17 | var indexOf = this.list.indexOf(emitter);
18 |
19 | if (indexOf > -1) {
20 | var emitter = this.list.splice(indexOf, 1);
21 | emitter.system = null;
22 | return emitter;
23 | }
24 | },
25 |
26 | update: function (delta) {
27 | var i = this.list.length;
28 |
29 | while (i--) {
30 | this.list[i].update(delta);
31 | }
32 | },
33 |
34 | destroy: function () {
35 | this.list.length = 0;
36 | }
37 | };
38 |
39 | Tiny.Particles.prototype.constructor = Tiny.Particles;
40 |
41 | require("./Particle");
42 | require("./Emitter");
43 |
44 | Tiny.registerSystem("particles", Tiny.Particles);
45 |
--------------------------------------------------------------------------------
/plugins/sound/index.js:
--------------------------------------------------------------------------------
1 | var context = window;
2 |
3 | class SoundManager {
4 | constructor(game) {
5 | this.game = game;
6 | }
7 |
8 | volume(vol) {
9 | if (context.Howler) {
10 | context.Howler.volume(vol);
11 | }
12 | }
13 |
14 | loop(audio, volume) {
15 | var sound = Tiny.Cache.sound[audio];
16 |
17 | if (sound) {
18 | if (volume !== undefined) {
19 | sound.volume(volume);
20 | }
21 |
22 | sound.loop(true);
23 | sound.play();
24 | }
25 |
26 | return sound;
27 | }
28 |
29 | play(audio, volume) {
30 | var sound = Tiny.Cache.sound[audio];
31 |
32 | if (sound) {
33 | if (context.Howler.state === "running") {
34 | if (volume !== undefined) {
35 | sound.volume(volume);
36 | }
37 |
38 | sound.play();
39 | }
40 | }
41 |
42 | return sound;
43 | }
44 |
45 | fade(audio, volume, duration) {
46 | var sound = Tiny.Cache.sound[audio];
47 |
48 | if (volume == undefined) volume = 1;
49 | if (duration == undefined) duration = 600;
50 |
51 | if (sound) {
52 | if (context.Howler.state === "running") {
53 | sound.fade(volume, 0, duration);
54 |
55 | sound.play();
56 | }
57 | }
58 |
59 | return sound;
60 | }
61 |
62 | destroy(clearCache) {
63 | for (var y in Tiny.Cache.sound) Tiny.Cache.sound[y].stop();
64 |
65 | if (clearCache) {
66 | for (var y in Tiny.Cache.sound) Tiny.Cache.sound[y].unload();
67 | }
68 | }
69 | }
70 |
71 | Tiny.Cache.sound = {};
72 |
73 | Tiny.Loader.prototype.sound = function (key, src) {
74 | if (src) {
75 | this.list.push({
76 | key: key,
77 | src: src,
78 | type: "sound"
79 | });
80 | }
81 | };
82 |
83 | Tiny.Loader.sound = function (resource, cb) {
84 |
85 | if (Tiny.Cache.sound[resource.key]) return cb();
86 |
87 | var sound = new window.Howl({
88 | src: [resource.src]
89 | });
90 |
91 | sound.once("load", function () {
92 | Tiny.Cache.sound[resource.key] = sound;
93 | cb();
94 | });
95 | };
96 |
97 | // Tiny.SoundManager = SoundManager;
98 | Tiny.registerSystem("sound", SoundManager);
99 |
--------------------------------------------------------------------------------
/plugins/three/index.js:
--------------------------------------------------------------------------------
1 | require("./objects/Canvas2D");
2 | require("./objects/Canvas3D");
3 | require("./objects/Text3D");
4 | require("./objects/Screen2D");
5 |
6 | require("./systems/Loader");
7 | require("./systems/Input");
8 |
--------------------------------------------------------------------------------
/plugins/three/objects/Canvas2D.js:
--------------------------------------------------------------------------------
1 | var THREE = require("three"),
2 | Sprite = THREE.Sprite,
3 | SpriteMaterial = THREE.SpriteMaterial,
4 | CanvasTexture = THREE.CanvasTexture,
5 | sRGBEncoding = THREE.sRGBEncoding,
6 | LinearFilter = THREE.LinearFilter;
7 |
8 | class Canvas2D extends Sprite {
9 | constructor(width, height) {
10 | const renderer = new Tiny.CanvasRenderer(width, height, { transparent: true });
11 | // renderer.setClearColor("#ffffff");
12 |
13 | const canvasTexture = new CanvasTexture(renderer.domElement);
14 | canvasTexture.encoding = sRGBEncoding;
15 | canvasTexture.minFilter = LinearFilter;
16 |
17 | const material = new SpriteMaterial({
18 | map: canvasTexture
19 | // color: 0x00ffff,
20 | // depthWrite: false
21 | });
22 |
23 | super(material);
24 |
25 | this.width = width;
26 | this.height = height;
27 | this.autoUpdate = false;
28 | this.renderer = renderer;
29 | const container = (this.container = new Tiny.Scene());
30 | this.texture = canvasTexture;
31 |
32 | this.add = container.add.bind(container);
33 | this.remove = container.remove.bind(container);
34 | }
35 |
36 | onBeforeRender() {
37 | this.autoUpdate && this.update();
38 | }
39 |
40 | update() {
41 | this.renderer.render(this.container);
42 |
43 | this.texture.needsUpdate = true;
44 | }
45 | }
46 |
47 | Tiny.Canvas2D = Canvas2D;
48 |
--------------------------------------------------------------------------------
/plugins/three/objects/Canvas3D.js:
--------------------------------------------------------------------------------
1 | var THREE = require("three"),
2 | Mesh = THREE.Mesh,
3 | MeshBasicMaterial = THREE.MeshBasicMaterial,
4 | CanvasTexture = THREE.CanvasTexture,
5 | sRGBEncoding = THREE.sRGBEncoding,
6 | LinearFilter = THREE.LinearFilter,
7 | PlaneBufferGeometry = THREE.PlaneBufferGeometry;
8 |
9 | var geometry = null;
10 |
11 | class Canvas3D extends Mesh {
12 | constructor(width, height) {
13 | const renderer = new Tiny.CanvasRenderer(width, height, { transparent: true });
14 | // renderer.setClearColor("#ffffff");
15 |
16 | const canvasTexture = new CanvasTexture(renderer.domElement);
17 | canvasTexture.encoding = sRGBEncoding;
18 | canvasTexture.minFilter = LinearFilter;
19 |
20 | const material = new MeshBasicMaterial({
21 | map: canvasTexture,
22 | transparent: true
23 | });
24 |
25 | if (geometry == null) geometry = new PlaneBufferGeometry(1, 1);
26 |
27 | super(geometry, material);
28 |
29 | this.width = width;
30 | this.height = height;
31 | this.autoUpdate = false;
32 | this.renderer = renderer;
33 | const container = (this.container = new Tiny.Scene());
34 | this.texture = canvasTexture;
35 |
36 | this.add = container.add.bind(container);
37 | this.remove = container.remove.bind(container);
38 | }
39 |
40 | onBeforeRender() {
41 | this.autoUpdate && this.update();
42 | }
43 |
44 | update() {
45 | this.renderer.render(this.container);
46 |
47 | this.texture.needsUpdate = true;
48 | }
49 | }
50 |
51 | Tiny.Canvas3D = Canvas3D;
52 |
--------------------------------------------------------------------------------
/plugins/three/objects/Screen2D.js:
--------------------------------------------------------------------------------
1 | var THREE = require("three"),
2 | Scene = THREE.Scene,
3 | OrthographicCamera = THREE.OrthographicCamera;
4 |
5 | class Screen2D extends Tiny.Canvas2D {
6 | constructor(width, height) {
7 | super(width, height);
8 |
9 | this.autoUpdate = true;
10 |
11 | this.scene = new Scene();
12 | this.camera = new OrthographicCamera(
13 | -this.width / 2,
14 | this.width / 2,
15 | this.height / 2,
16 | -this.height / 2,
17 | 1,
18 | 10
19 | );
20 |
21 | this.scale.set(this.width, this.height, 1);
22 | this.camera.position.z = 1;
23 | this.scene.add(this);
24 |
25 | // this.setSize(this.width, this.height)
26 | // const renderer = new Tiny.CanvasRenderer(width, height, { transparent: true });
27 | // // renderer.setClearColor(0xffffff, 0.1);
28 |
29 | // const scene = new Tiny.Scene();
30 |
31 | // const canvasTexture = new CanvasTexture(renderer.view);
32 | // canvasTexture.encoding = sRGBEncoding;
33 | // canvasTexture.minFilter = LinearFilter;
34 |
35 | // const material = new SpriteMaterial({
36 | // map: canvasTexture,
37 | // // color: 0x00ffff,
38 | // // depthWrite: false
39 | // });
40 |
41 | // super(material);
42 |
43 | // this.width = width;
44 | // this.height = height;
45 | // this.autoUpdate = false;
46 | // this.renderer = renderer;
47 | // this.scene = scene;
48 | // this.texture = canvasTexture;
49 |
50 | // this.add = scene.add.bind(scene);
51 | // this.remove = scene.remove.bind(scene);
52 | }
53 |
54 | setSize(width, height) {
55 | this.renderer.resize(width, height);
56 |
57 | this.width = width;
58 | this.height = height;
59 |
60 | this.camera.left = -this.width / 2;
61 | this.camera.right = this.width / 2;
62 | this.camera.top = this.height / 2;
63 | this.camera.bottom = -this.height / 2;
64 | this.camera.updateProjectionMatrix();
65 |
66 | this.scale.set(this.width, this.height, 1);
67 | }
68 | }
69 |
70 | Tiny.Screen2D = Screen2D;
71 |
--------------------------------------------------------------------------------
/plugins/three/objects/Text3D.js:
--------------------------------------------------------------------------------
1 | var THREE = require("three"),
2 | Mesh = THREE.Mesh,
3 | MeshBasicMaterial = THREE.MeshBasicMaterial,
4 | CanvasTexture = THREE.CanvasTexture,
5 | sRGBEncoding = THREE.sRGBEncoding,
6 | LinearFilter = THREE.LinearFilter,
7 | PlaneBufferGeometry = THREE.PlaneBufferGeometry;
8 |
9 | class Text3D extends Mesh {
10 | constructor(text, options) {
11 | options = options || {};
12 | options.size = options.size || 1;
13 |
14 | const _text = new Tiny.Text(text, options);
15 |
16 | const canvasTexture = new CanvasTexture(_text.canvas);
17 | canvasTexture.encoding = sRGBEncoding;
18 | canvasTexture.minFilter = LinearFilter;
19 |
20 | const material = new MeshBasicMaterial({
21 | map: canvasTexture,
22 | // color: 0xff4545,
23 | transparent: true
24 | });
25 |
26 | const geometry = new PlaneBufferGeometry(1, 1);
27 |
28 | super(geometry, material);
29 |
30 | const max = Math.max(_text.width, _text.height);
31 | this.scale.set((options.size * _text.width) / max, (options.size * _text.height) / max, 1);
32 |
33 | this.size = options.size;
34 | this.text = _text;
35 | this.texture = canvasTexture;
36 |
37 | // this.text.updateCanvas();
38 | }
39 |
40 | setText(text) {
41 | const _text = this.text;
42 | _text.setText(text);
43 | _text.updateText();
44 |
45 | const max = Math.max(_text.width, _text.height);
46 |
47 | this.scale.set((this.size * _text.width) / max, (this.size * _text.height) / max, 1);
48 |
49 | this.texture.needsUpdate = true;
50 | }
51 | }
52 |
53 | Tiny.Text3D = Text3D;
54 |
--------------------------------------------------------------------------------
/plugins/three/systems/Input.js:
--------------------------------------------------------------------------------
1 | var THREE = require("three"),
2 | Vector3 = THREE.Vector3,
3 | Box3 = THREE.Box3,
4 | Raycaster = THREE.Raycaster;
5 |
6 | const tempBox = new Box3(),
7 | hitBox = new Vector3(1, 1, 1),
8 | temp = new Vector3();
9 |
10 | var ThreeInputSystem = {
11 | init: function () {
12 | this.raycaster = new Raycaster();
13 | },
14 |
15 | preHandle: function (x, y) {
16 | if (!this.game.camera) return;
17 | temp.set((x / this.game.width) * 2 - 1, -(y / this.game.height) * 2 + 1, 0);
18 | this.raycaster.setFromCamera(temp, this.game.camera);
19 | }
20 | };
21 |
22 | Tiny.Input.systems.push(ThreeInputSystem);
23 |
24 | Tiny.Input.checkBounds3D = function (obj, x, y) {
25 | if (obj.input.hitBox) {
26 | hitBox.copy(obj.input.hitBox);
27 | } else {
28 | obj.getWorldScale(hitBox);
29 | }
30 |
31 | tempBox.setFromCenterAndSize(obj.position, hitBox);
32 |
33 | if (this.raycaster.ray.intersectsBox(tempBox)) {
34 | return true;
35 | }
36 | };
37 |
38 | Tiny.Input.prototype.add3d = function (object, options) {
39 | options = options || {};
40 | options.checkBounds = Tiny.Input.checkBounds3D;
41 |
42 | this.add(object, options);
43 | };
44 |
--------------------------------------------------------------------------------
/plugins/three/systems/Loader.js:
--------------------------------------------------------------------------------
1 | var THREE = require("three"),
2 | LoadingManager = THREE.LoadingManager,
3 | Texture = THREE.Texture,
4 | sRGBEncoding = THREE.sRGBEncoding;
5 |
6 | var gltfLoader = null;
7 |
8 | Tiny.Cache.gltf = {};
9 | Tiny.Cache.texture3d = {};
10 | Tiny.Cache.mesh3d = {};
11 | Tiny.Cache.animation3d = {};
12 |
13 | Tiny.Loader.prototype.gltf = function (key, json, splitObjects, cb) {
14 | this.list.push({
15 | key: key,
16 | src: json,
17 | type: "gltf",
18 | split: splitObjects,
19 | cb: cb
20 | });
21 | };
22 |
23 | Tiny.Loader.prototype.texture3d = function (key, src, cb) {
24 | this.list.push({
25 | key: key,
26 | src: src,
27 | type: "texture3d",
28 | cb: cb
29 | });
30 | };
31 |
32 | Tiny.Loader.gltf = function (resource, cb) {
33 | var key = resource.key;
34 |
35 | if (gltfLoader == null) {
36 | var manager = new LoadingManager();
37 | gltfLoader = new window.GLTFLoader(manager);
38 | }
39 |
40 | function loaded(gltf) {
41 | Tiny.Cache.gltf[key] = gltf;
42 |
43 | if (resource.split) {
44 | gltf.scene.traverse(function (obj) {
45 | if (obj.isMesh) Tiny.Cache.mesh3d[key + "." + obj.name] = obj;
46 | });
47 |
48 | for (var i = 0; i < gltf.animations.length; i++) {
49 | var obj = gltf.animations[i];
50 | Tiny.Cache.animation3d[key + "." + obj.name] = obj;
51 | }
52 | }
53 |
54 | if (resource.cb) resource.cb(gltf);
55 |
56 | cb();
57 | }
58 |
59 | if (resource.src.length > 200) {
60 | gltfLoader.parse(resource.src, "", loaded);
61 | } else {
62 | gltfLoader.load(resource.src, loaded);
63 | }
64 | };
65 |
66 | Tiny.Loader.texture3d = function (resource, cb) {
67 | var key = resource.key;
68 |
69 | Tiny.Loader.image(resource, function (resource, image) {
70 | var texture = new Texture(image);
71 | texture.encoding = sRGBEncoding;
72 | texture.flipY = false;
73 | texture.needsUpdate = true;
74 | texture.key = key;
75 |
76 | Tiny.Cache.texture3d[resource.key] = texture;
77 |
78 | cb();
79 | });
80 | };
81 |
--------------------------------------------------------------------------------
/src/App.js:
--------------------------------------------------------------------------------
1 | var noop = function () {};
2 |
3 | Tiny.App = function (states) {
4 | this.callbackContext = this;
5 | this.state = 0;
6 | this.timeScale = 1;
7 | this.width = 0;
8 | this.height = 0;
9 | this.systems = [];
10 | this.updatable = [];
11 | this.paused = false;
12 | this.pauseDuration = 0;
13 | this.inputView = document.body;
14 |
15 | if (!Tiny.app) Tiny.app = this;
16 |
17 | Tiny.EventEmitter.mixin(this);
18 |
19 | states = states || {};
20 | this.boot = states.boot || this.boot || noop;
21 | this.preload = states.preload || this.preload || noop;
22 | this.create = states.create || this.create || noop;
23 | this.update = states.update || this.update || noop;
24 | this.render = states.render || this.render || noop;
25 | this._resize_cb = states.resize || noop;
26 | this._destroy_cb = states.destroy || noop;
27 |
28 | var self = this;
29 | setTimeout(function () {
30 | self._boot();
31 | }, 0);
32 | };
33 |
34 | Tiny.App.prototype._boot = function () {
35 | for (var i = 0; i < Tiny.systems.length; i++) {
36 | var system = Tiny.systems[i];
37 |
38 | var _sys_ = new system._class_(this);
39 | this.systems.push(_sys_);
40 | if (_sys_.update) this.updatable.push(_sys_);
41 |
42 | if (system.name) this[system.name] = _sys_;
43 | }
44 |
45 | if (Tiny.RAF) {
46 | this.raf = new Tiny.RAF(this);
47 | }
48 |
49 | this.boot.call(this.callbackContext);
50 |
51 | var self = this;
52 | setTimeout(function () {
53 | if (self.load) self._preload();
54 | else self._create();
55 | }, 0);
56 | };
57 |
58 | Tiny.App.prototype._preload = function () {
59 | this.preload.call(this.callbackContext);
60 | this.state = 1;
61 | this.load.start(this._create);
62 | };
63 |
64 | Tiny.App.prototype._create = function () {
65 | this.emit('load');
66 | this.create.call(this.callbackContext);
67 |
68 | if (this.raf) {
69 | this.raf.start();
70 | }
71 |
72 | this.state = 2;
73 | };
74 |
75 | Tiny.App.prototype.pause = function () {
76 | if (this.raf) {
77 | this.raf.reset();
78 | }
79 |
80 | if (!this.paused) {
81 | for (var i = 0; i < this.systems.length; i++) {
82 | if (this.systems[i].pause) this.systems[i].pause();
83 | }
84 |
85 | this.paused = true;
86 | }
87 | };
88 |
89 | Tiny.App.prototype.resume = function () {
90 | if (this.raf) {
91 | this.raf.reset();
92 | }
93 |
94 | if (this.paused) {
95 | for (var i = 0; i < this.systems.length; i++) {
96 | if (this.systems[i].resume) this.systems[i].resume();
97 | }
98 |
99 | this.paused = false;
100 | }
101 | };
102 |
103 | Tiny.App.prototype._update = function (time, delta) {
104 | if (!this.paused) {
105 | delta *= this.timeScale;
106 | this.update.call(this.callbackContext, time, delta);
107 | this.emit('update', delta);
108 |
109 | for (var i = 0; i < this.updatable.length; i++) {
110 | this.updatable[i].update(delta);
111 | }
112 | } else {
113 | this.pauseDuration += delta;
114 | }
115 |
116 | this.render();
117 | this.emit('postrender');
118 | };
119 |
120 | Tiny.App.prototype.resize = function (width, height) {
121 | this.width = width || this.width;
122 | this.height = height || this.height;
123 |
124 | if (this.state > 0) {
125 | this._resize_cb.call(this.callbackContext, this.width, this.height);
126 | this.emit('resize', width, height);
127 | }
128 |
129 | var self = this;
130 | setTimeout(function () {
131 | if (self.input) self.input.updateBounds();
132 | }, 0);
133 | };
134 |
135 | Tiny.App.prototype.destroy = function (clearCache) {
136 | for (var i = 0; i < this.systems.length; i++) {
137 | if (this.systems[i].destroy) this.systems[i].destroy(clearCache);
138 | }
139 |
140 | this.paused = true;
141 |
142 | if (clearCache) {
143 | this.load.clearCache();
144 | }
145 |
146 | if (this.raf) {
147 | this.raf.stop();
148 | }
149 |
150 | this._destroy_cb.call(this.callbackContext);
151 |
152 | if (Tiny.app === this) Tiny.app = null;
153 | };
154 |
--------------------------------------------------------------------------------
/src/base.js:
--------------------------------------------------------------------------------
1 | require("./utils/polyfill.js");
2 |
3 | window.Tiny = {};
4 |
5 | require("./App.js");
6 | require("./global.js");
7 | require("./math/Math.js"); // 1 Kb
8 | require("./math/Point.js"); //
9 | require("./math/Matrix.js"); //
10 | require("./math/Rectangle.js"); // 8 Kb
11 |
12 | require("./objects/BaseObject2D.js"); //
13 | require("./objects/Object2D.js"); //
14 | require("./objects/Scene.js"); // 10 Kb
15 |
16 | require("./renderers/CanvasRenderer.js"); // 3 Kb
17 |
--------------------------------------------------------------------------------
/src/global.js:
--------------------------------------------------------------------------------
1 | Tiny.VERSION = '2.2.2';
2 |
3 | Tiny.systems = [];
4 |
5 | Tiny.registerSystem = function (name, system) {
6 | Tiny.systems.push({
7 | name: name,
8 | _class_: system
9 | });
10 | };
11 |
12 | Tiny.Primitives = {
13 | POLY: 0,
14 | RECT: 1,
15 | CIRC: 2,
16 | ELIP: 3,
17 | RREC: 4,
18 | RREC_LJOIN: 5
19 | };
20 |
21 | Tiny.rnd = function (min, max) {
22 | return min + Math.floor(Math.random() * (max - min + 1));
23 | };
24 |
25 | Tiny.style2hex = function (color) {
26 | return +color.replace('#', '0x');
27 | };
28 |
29 | Tiny.hex2style = function (hex) {
30 | return '#' + ('00000' + (hex | 0).toString(16)).substr(-6);
31 | };
32 |
33 | Tiny.hex2rgb = function (hex) {
34 | return [((hex >> 16) & 0xff) / 255, ((hex >> 8) & 0xff) / 255, (hex & 0xff) / 255];
35 | };
36 |
37 | Tiny.rgb2hex = function (rgb) {
38 | return ((rgb[0] * 255) << 16) + ((rgb[1] * 255) << 8) + rgb[2] * 255;
39 | };
40 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | require("./mini.js");
2 |
3 | // require('./systems/ObjectCreator.js'); // 1 Kb
4 | // require('./systems/Loader.js'); // 3 Kb
5 | // require('./systems/Input.js'); // 1 Kb
6 | // require('./systems/Timer.js'); // 1 Kb
7 | require("./systems/Tween.js");
8 |
9 | require("./math/RoundedRectangle.js"); //
10 | require("./math/Polygon.js"); //
11 | require("./math/Circle.js"); // 6 Kb
12 |
13 | require("./renderers/GraphicsRenderer.js"); // 4Kb
14 |
15 | require("./objects/Graphics.js"); // 10 Kb
16 | // require('./objects/TilingSprite.js'); // 4 Kb ############### TilingSprite game.add.tilesprite
17 |
18 | require("./textures/RenderTexture.js"); // 2 Kb
19 |
20 | require("./utils/CanvasBuffer.js"); // 1 Kb
21 | require("./renderers/CanvasMaskManager.js"); // 1Kb
22 | require("./renderers/CanvasTinter.js"); // 3 Kb ################ tint function
23 |
--------------------------------------------------------------------------------
/src/math/Math.js:
--------------------------------------------------------------------------------
1 | Tiny.Math = {
2 | distance: function (x1, y1, x2, y2) {
3 | var dx = x1 - x2;
4 | var dy = y1 - y2;
5 |
6 | return Math.sqrt(dx * dx + dy * dy);
7 | }
8 | };
9 |
10 | var degreeToRadiansFactor = Math.PI / 180;
11 | var radianToDegreesFactor = 180 / Math.PI;
12 |
13 | Tiny.Math.degToRad = function degToRad(degrees) {
14 | return degrees * degreeToRadiansFactor;
15 | };
16 |
17 | Tiny.Math.radToDeg = function radToDeg(radians) {
18 | return radians * radianToDegreesFactor;
19 | };
20 |
--------------------------------------------------------------------------------
/src/math/Matrix.js:
--------------------------------------------------------------------------------
1 | Tiny.Matrix = function () {
2 | this.a = 1;
3 |
4 | this.b = 0;
5 |
6 | this.c = 0;
7 |
8 | this.d = 1;
9 |
10 | this.tx = 0;
11 |
12 | this.ty = 0;
13 |
14 | this.type = Tiny.MATRIX;
15 | };
16 |
17 | Tiny.Matrix.prototype.fromArray = function (array) {
18 | this.a = array[0];
19 | this.b = array[1];
20 | this.c = array[3];
21 | this.d = array[4];
22 | this.tx = array[2];
23 | this.ty = array[5];
24 | };
25 |
26 | Tiny.Matrix.prototype.toArray = function (transpose) {
27 | if (!this.array) {
28 | this.array = new Float32Array(9);
29 | }
30 |
31 | var array = this.array;
32 |
33 | if (transpose) {
34 | array[0] = this.a;
35 | array[1] = this.b;
36 | array[2] = 0;
37 | array[3] = this.c;
38 | array[4] = this.d;
39 | array[5] = 0;
40 | array[6] = this.tx;
41 | array[7] = this.ty;
42 | array[8] = 1;
43 | } else {
44 | array[0] = this.a;
45 | array[1] = this.c;
46 | array[2] = this.tx;
47 | array[3] = this.b;
48 | array[4] = this.d;
49 | array[5] = this.ty;
50 | array[6] = 0;
51 | array[7] = 0;
52 | array[8] = 1;
53 | }
54 |
55 | return array;
56 | };
57 |
58 | Tiny.Matrix.prototype.apply = function (pos, newPos) {
59 | newPos = newPos || new Tiny.Point();
60 |
61 | var x = pos.x;
62 | var y = pos.y;
63 |
64 | newPos.x = this.a * x + this.c * y + this.tx;
65 | newPos.y = this.b * x + this.d * y + this.ty;
66 |
67 | return newPos;
68 | };
69 |
70 | Tiny.Matrix.prototype.applyInverse = function (pos, newPos) {
71 | newPos = newPos || new Tiny.Point();
72 |
73 | var id = 1 / (this.a * this.d + this.c * -this.b);
74 | var x = pos.x;
75 | var y = pos.y;
76 |
77 | newPos.x = this.d * id * x + -this.c * id * y + (this.ty * this.c - this.tx * this.d) * id;
78 | newPos.y = this.a * id * y + -this.b * id * x + (-this.ty * this.a + this.tx * this.b) * id;
79 |
80 | return newPos;
81 | };
82 |
83 | Tiny.Matrix.prototype.translate = function (x, y) {
84 | this.tx += x;
85 | this.ty += y;
86 |
87 | return this;
88 | };
89 |
90 | Tiny.Matrix.prototype.scale = function (x, y) {
91 | this.a *= x;
92 | this.d *= y;
93 | this.c *= x;
94 | this.b *= y;
95 | this.tx *= x;
96 | this.ty *= y;
97 |
98 | return this;
99 | };
100 |
101 | Tiny.Matrix.prototype.rotate = function (angle) {
102 | var cos = Math.cos(angle);
103 | var sin = Math.sin(angle);
104 |
105 | var a1 = this.a;
106 | var c1 = this.c;
107 | var tx1 = this.tx;
108 |
109 | this.a = a1 * cos - this.b * sin;
110 | this.b = a1 * sin + this.b * cos;
111 | this.c = c1 * cos - this.d * sin;
112 | this.d = c1 * sin + this.d * cos;
113 | this.tx = tx1 * cos - this.ty * sin;
114 | this.ty = tx1 * sin + this.ty * cos;
115 |
116 | return this;
117 | };
118 |
119 | Tiny.Matrix.prototype.append = function (matrix) {
120 | var a1 = this.a;
121 | var b1 = this.b;
122 | var c1 = this.c;
123 | var d1 = this.d;
124 |
125 | this.a = matrix.a * a1 + matrix.b * c1;
126 | this.b = matrix.a * b1 + matrix.b * d1;
127 | this.c = matrix.c * a1 + matrix.d * c1;
128 | this.d = matrix.c * b1 + matrix.d * d1;
129 |
130 | this.tx = matrix.tx * a1 + matrix.ty * c1 + this.tx;
131 | this.ty = matrix.tx * b1 + matrix.ty * d1 + this.ty;
132 |
133 | return this;
134 | };
135 |
136 | Tiny.Matrix.prototype.identity = function () {
137 | this.a = 1;
138 | this.b = 0;
139 | this.c = 0;
140 | this.d = 1;
141 | this.tx = 0;
142 | this.ty = 0;
143 |
144 | return this;
145 | };
146 |
147 | Tiny.identityMatrix = new Tiny.Matrix();
148 |
--------------------------------------------------------------------------------
/src/math/Point.js:
--------------------------------------------------------------------------------
1 | Tiny.Point = function (x, y) {
2 | this.x = x || 0;
3 | this.y = y || 0;
4 | };
5 |
6 | Tiny.Point.prototype = {
7 | set: function (x, y) {
8 | this.x = x || 0;
9 | this.y = y || (y !== 0 ? this.x : 0);
10 |
11 | return this;
12 | }
13 | };
14 |
--------------------------------------------------------------------------------
/src/math/Polygon.js:
--------------------------------------------------------------------------------
1 | Tiny.Polygon = function () {
2 | this.area = 0;
3 | this._points = [];
4 |
5 | if (arguments.length > 0) {
6 | this.setTo.apply(this, arguments);
7 | }
8 | this.closed = true;
9 | this.type = Tiny.Primitives.POLY;
10 | };
11 |
12 | Tiny.Polygon.prototype = {
13 | toNumberArray: function (output) {
14 | if (typeof output === "undefined") {
15 | output = [];
16 | }
17 |
18 | for (var i = 0; i < this._points.length; i++) {
19 | if (typeof this._points[i] === "number") {
20 | output.push(this._points[i]);
21 | output.push(this._points[i + 1]);
22 | i++;
23 | } else {
24 | output.push(this._points[i].x);
25 | output.push(this._points[i].y);
26 | }
27 | }
28 |
29 | return output;
30 | },
31 |
32 | flatten: function () {
33 | this._points = this.toNumberArray();
34 |
35 | return this;
36 | },
37 |
38 | clone: function (output) {
39 | var points = this._points.slice();
40 |
41 | if (typeof output === "undefined" || output === null) {
42 | output = new Tiny.Polygon(points);
43 | } else {
44 | output.setTo(points);
45 | }
46 |
47 | return output;
48 | },
49 |
50 | contains: function (x, y) {
51 | var length = this._points.length;
52 | var inside = false;
53 |
54 | for (var i = -1, j = length - 1; ++i < length; j = i) {
55 | var ix = this._points[i].x;
56 | var iy = this._points[i].y;
57 |
58 | var jx = this._points[j].x;
59 | var jy = this._points[j].y;
60 |
61 | if (((iy <= y && y < jy) || (jy <= y && y < iy)) && x < ((jx - ix) * (y - iy)) / (jy - iy) + ix) {
62 | inside = !inside;
63 | }
64 | }
65 |
66 | return inside;
67 | },
68 |
69 | setTo: function (points) {
70 | this.area = 0;
71 | this._points = [];
72 |
73 | if (arguments.length > 0) {
74 | // If points isn't an array, use arguments as the array
75 | if (!Array.isArray(points)) {
76 | points = Array.prototype.slice.call(arguments);
77 | }
78 |
79 | var y0 = Number.MAX_VALUE;
80 |
81 | // Allows for mixed-type arguments
82 | for (var i = 0, len = points.length; i < len; i++) {
83 | if (typeof points[i] === "number") {
84 | var p = new Tiny.Point(points[i], points[i + 1]);
85 | i++;
86 | } else {
87 | var p = new Tiny.Point(points[i].x, points[i].y);
88 | }
89 |
90 | this._points.push(p);
91 |
92 | // Lowest boundary
93 | if (p.y < y0) {
94 | y0 = p.y;
95 | }
96 | }
97 |
98 | this.calculateArea(y0);
99 | }
100 |
101 | return this;
102 | },
103 |
104 | calculateArea: function (y0) {
105 | var p1;
106 | var p2;
107 | var avgHeight;
108 | var width;
109 |
110 | for (var i = 0, len = this._points.length; i < len; i++) {
111 | p1 = this._points[i];
112 |
113 | if (i === len - 1) {
114 | p2 = this._points[0];
115 | } else {
116 | p2 = this._points[i + 1];
117 | }
118 |
119 | avgHeight = (p1.y - y0 + (p2.y - y0)) / 2;
120 | width = p1.x - p2.x;
121 | this.area += avgHeight * width;
122 | }
123 |
124 | return this.area;
125 | }
126 | };
127 |
128 | Tiny.Polygon.prototype.constructor = Tiny.Polygon;
129 |
130 | Object.defineProperty(Tiny.Polygon.prototype, "points", {
131 | get: function () {
132 | return this._points;
133 | },
134 |
135 | set: function (points) {
136 | if (points != null) {
137 | this.setTo(points);
138 | } else {
139 | // Clear the points
140 | this.setTo();
141 | }
142 | }
143 | });
144 |
--------------------------------------------------------------------------------
/src/math/Rectangle.js:
--------------------------------------------------------------------------------
1 | Tiny.Rectangle = function (x, y, width, height) {
2 | x = x || 0;
3 | y = y || 0;
4 | width = width || 0;
5 | height = height || 0;
6 |
7 | this.x = x;
8 | this.y = y;
9 |
10 | this.width = width;
11 | this.height = height;
12 |
13 | this.type = Tiny.Primitives.RECT;
14 | };
15 |
16 | Tiny.Rectangle.prototype = {
17 | setTo: function (x, y, width, height) {
18 | this.x = x;
19 | this.y = y;
20 | this.width = width;
21 | this.height = height;
22 |
23 | return this;
24 | },
25 |
26 | contains: function (x, y) {
27 | return Tiny.Rectangle.contains(this, x, y);
28 | },
29 |
30 | intersects: function (b) {
31 | return Tiny.Rectangle.intersects(this, b);
32 | }
33 | };
34 |
35 | Object.defineProperty(Tiny.Rectangle.prototype, "bottom", {
36 | get: function () {
37 | return this.y + this.height;
38 | },
39 |
40 | set: function (value) {
41 | if (value <= this.y) {
42 | this.height = 0;
43 | } else {
44 | this.height = value - this.y;
45 | }
46 | }
47 | });
48 |
49 | Object.defineProperty(Tiny.Rectangle.prototype, "right", {
50 | get: function () {
51 | return this.x + this.width;
52 | },
53 |
54 | set: function (value) {
55 | if (value <= this.x) {
56 | this.width = 0;
57 | } else {
58 | this.width = value - this.x;
59 | }
60 | }
61 | });
62 |
63 | Object.defineProperty(Tiny.Rectangle.prototype, "volume", {
64 | get: function () {
65 | return this.width * this.height;
66 | }
67 | });
68 |
69 | Tiny.Rectangle.prototype.constructor = Tiny.Rectangle;
70 |
71 | Tiny.Rectangle.contains = function (a, x, y) {
72 | if (a.width <= 0 || a.height <= 0) {
73 | return false;
74 | }
75 |
76 | return x >= a.x && x < a.right && y >= a.y && y < a.bottom;
77 | };
78 |
79 | Tiny.Rectangle.containsPoint = function (a, point) {
80 | return Tiny.Rectangle.contains(a, point.x, point.y);
81 | };
82 |
83 | Tiny.Rectangle.containsRect = function (a, b) {
84 | // If the given rect has a larger volume than this one then it can never contain it
85 | if (a.volume > b.volume) {
86 | return false;
87 | }
88 |
89 | return a.x >= b.x && a.y >= b.y && a.right < b.right && a.bottom < b.bottom;
90 | };
91 |
92 | Tiny.Rectangle.intersects = function (a, b) {
93 | if (a.width <= 0 || a.height <= 0 || b.width <= 0 || b.height <= 0) {
94 | return false;
95 | }
96 |
97 | return !(a.right < b.x || a.bottom < b.y || a.x > b.right || a.y > b.bottom);
98 | };
99 |
100 | Tiny.EmptyRectangle = new Tiny.Rectangle(0, 0, 0, 0);
101 |
--------------------------------------------------------------------------------
/src/math/RoundedRectangle.js:
--------------------------------------------------------------------------------
1 | Tiny.RoundedRectangle = function (x, y, width, height, radius) {
2 | this.x = x || 0;
3 | this.y = y || 0;
4 | this.width = width || 0;
5 | this.height = height || 0;
6 | this.radius = radius || 0;
7 | this.type = Tiny.Primitives.RREC;
8 | };
9 |
10 | Tiny.RoundedRectangle.prototype.clone = function () {
11 | return new Tiny.RoundedRectangle(this.x, this.y, this.width, this.height, this.radius);
12 | };
13 |
14 | Tiny.RoundedRectangle.prototype.contains = function (x, y) {
15 | if (this.width <= 0 || this.height <= 0) {
16 | return false;
17 | }
18 |
19 | var x1 = this.x;
20 |
21 | if (x >= x1 && x <= x1 + this.width) {
22 | var y1 = this.y;
23 |
24 | if (y >= y1 && y <= y1 + this.height) {
25 | return true;
26 | }
27 | }
28 |
29 | return false;
30 | };
31 |
32 | Tiny.RoundedRectangle.prototype.constructor = Tiny.RoundedRectangle;
33 |
--------------------------------------------------------------------------------
/src/mini.js:
--------------------------------------------------------------------------------
1 | require("./base.js");
2 |
3 | require("./systems/RAF.js"); // 2 Kb
4 | // require('./systems/ObjectCreator.js'); // 1 Kb
5 | require("./systems/Loader.js"); // 3 Kb
6 | require("./systems/Input.js"); // 1 Kb
7 | require("./systems/Timer.js"); // 1 Kb
8 |
9 | require("./utils/EventEmitter.js");
10 |
11 | require("./textures/Texture.js"); // 4 Kb
12 |
13 | require("./objects/Sprite.js"); // 3 Kb
14 | require("./objects/Text.js"); // 5 Kb
15 |
--------------------------------------------------------------------------------
/src/objects/Scene.js:
--------------------------------------------------------------------------------
1 | Tiny.Scene = function (game) {
2 | Tiny.Object2D.call(this);
3 | this.worldTransform = new Tiny.Matrix();
4 | this.game = game;
5 | };
6 |
7 | Tiny.Scene.prototype = Object.create(Tiny.Object2D.prototype);
8 | Tiny.Scene.prototype.constructor = Tiny.Scene;
9 |
10 | Tiny.Scene.prototype.updateTransform = function () {
11 | this.worldAlpha = 1;
12 |
13 | for (var i = 0; i < this.children.length; i++) {
14 | this.children[i].updateTransform();
15 | }
16 | };
17 |
--------------------------------------------------------------------------------
/src/renderers/CanvasMaskManager.js:
--------------------------------------------------------------------------------
1 | Tiny.CanvasMaskManager = function () {};
2 |
3 | Tiny.CanvasMaskManager.prototype.constructor = Tiny.CanvasMaskManager;
4 |
5 | Tiny.CanvasMaskManager.prototype.pushMask = function (maskData, renderSession) {
6 | var context = renderSession.context;
7 |
8 | context.save();
9 |
10 | var cacheAlpha = maskData.alpha;
11 | var transform = maskData.worldTransform;
12 |
13 | var resolution = renderSession.resolution;
14 |
15 | context.setTransform(
16 | transform.a * resolution,
17 | transform.b * resolution,
18 | transform.c * resolution,
19 | transform.d * resolution,
20 | transform.tx * resolution,
21 | transform.ty * resolution
22 | );
23 |
24 | Tiny.CanvasGraphics.renderGraphicsMask(maskData, context);
25 |
26 | context.clip();
27 |
28 | maskData.worldAlpha = cacheAlpha;
29 | };
30 |
31 | Tiny.CanvasMaskManager.prototype.popMask = function (renderSession) {
32 | renderSession.context.restore();
33 | };
34 |
--------------------------------------------------------------------------------
/src/renderers/CanvasRenderer.js:
--------------------------------------------------------------------------------
1 | Tiny.CanvasRenderer = function (width, height, options) {
2 | options = options || {};
3 |
4 | this.resolution = options.resolution != undefined ? options.resolution : 1;
5 |
6 | this.clearBeforeRender = options.clearBeforeRender != undefined ? options.clearBeforeRender : true;
7 |
8 | this.transparent = options.transparent != undefined ? options.transparent : false;
9 |
10 | this.autoResize = options.autoResize || false;
11 |
12 | // this.width = width || 800;
13 | // this.height = height || 600;
14 |
15 | // this.width *= this.resolution;
16 | // this.height *= this.resolution;
17 |
18 | if (!Tiny.defaultRenderer) Tiny.defaultRenderer = this;
19 |
20 | var view = (this.domElement = options.domElement || document.createElement("canvas"));
21 |
22 | this.context = view.getContext("2d", { alpha: this.transparent });
23 |
24 | // view.width = this.width * this.resolution;
25 | // view.height = this.height * this.resolution;
26 |
27 | this.resize(width || 800, height || 600);
28 |
29 | this.setClearColor("#ffffff");
30 |
31 | if (Tiny.CanvasMaskManager) this.maskManager = new Tiny.CanvasMaskManager();
32 |
33 | this.renderSession = {
34 | context: this.context,
35 | maskManager: this.maskManager,
36 | smoothProperty: null,
37 | /**
38 | * If true Pixi will Math.floor() x/y values when rendering, stopping pixel interpolation.
39 | * Handy for crisp pixel art and speed on legacy devices.
40 | *
41 | */
42 | roundPixels: false
43 | };
44 |
45 | if ("imageSmoothingEnabled" in this.context) this.renderSession.smoothProperty = "imageSmoothingEnabled";
46 | else if ("webkitImageSmoothingEnabled" in this.context)
47 | this.renderSession.smoothProperty = "webkitImageSmoothingEnabled";
48 | else if ("mozImageSmoothingEnabled" in this.context)
49 | this.renderSession.smoothProperty = "mozImageSmoothingEnabled";
50 | else if ("oImageSmoothingEnabled" in this.context)
51 | this.renderSession.smoothProperty = "oImageSmoothingEnabled";
52 | else if ("msImageSmoothingEnabled" in this.context)
53 | this.renderSession.smoothProperty = "msImageSmoothingEnabled";
54 | };
55 |
56 | Tiny.CanvasRenderer.prototype.constructor = Tiny.CanvasRenderer;
57 |
58 | Tiny.CanvasRenderer.prototype.setClearColor = function (color) {
59 | this.clearColor = color;
60 |
61 | // if (color === null) {
62 | // this.clearColor = null;
63 | // return;
64 | // }
65 |
66 | // this.clearColor = color || 0x000000;
67 | // // this.backgroundColorSplit = Tiny.hex2rgb(this.backgroundColor);
68 | // var hex = this.clearColor.toString(16);
69 | // hex = '000000'.substr(0, 6 - hex.length) + hex;
70 | // this._clearColor = '#' + hex;
71 | };
72 |
73 | // Tiny.CanvasRenderer.prototype.setPixelArt = function() {
74 |
75 | // var canvas = this.domElement;
76 |
77 | // var types = [ 'optimizeSpeed', '-moz-crisp-edges', '-o-crisp-edges', '-webkit-optimize-contrast', 'optimize-contrast', 'crisp-edges', 'pixelated' ];
78 |
79 | // types.forEach(function (type)
80 | // {
81 | // canvas.style['image-rendering'] = type;
82 | // });
83 |
84 | // canvas.style.msInterpolationMode = 'nearest-neighbor';
85 | // this.renderSession.roundPixels = true;
86 | // }
87 |
88 | Tiny.CanvasRenderer.prototype.render = function (scene) {
89 | scene.updateTransform();
90 |
91 | this.context.setTransform(1, 0, 0, 1, 0, 0);
92 |
93 | this.context.globalAlpha = 1;
94 |
95 | this.renderSession.currentBlendMode = "source-over";
96 | this.context.globalCompositeOperation = "source-over";
97 |
98 | if (navigator.isCocoonJS && this.domElement.screencanvas) {
99 | this.context.fillStyle = "black";
100 | this.context.clear();
101 | }
102 |
103 | if (this.clearBeforeRender) {
104 | if (this.transparent) {
105 | this.context.clearRect(0, 0, this.width * this.resolution, this.height * this.resolution);
106 | } else {
107 | this.context.fillStyle = this.clearColor;
108 | this.context.fillRect(0, 0, this.width * this.resolution, this.height * this.resolution);
109 | }
110 | }
111 |
112 | this.renderObject(scene);
113 | };
114 |
115 | Tiny.CanvasRenderer.prototype.destroy = function (removeView) {
116 | if (typeof removeView === "undefined") {
117 | removeView = true;
118 | }
119 |
120 | if (removeView && this.domElement.parentNode) {
121 | this.domElement.parentNode.removeChild(this.domElement);
122 | }
123 |
124 | this.domElement = null;
125 | this.context = null;
126 | this.maskManager = null;
127 | this.renderSession = null;
128 |
129 | if (Tiny.defaultRenderer === this) Tiny.defaultRenderer = null;
130 | };
131 |
132 | Tiny.CanvasRenderer.prototype.resize = function (width, height) {
133 | this.width = width;
134 | this.height = height;
135 |
136 | var view = this.domElement;
137 |
138 | view.width = Math.floor(this.width * this.resolution);
139 | view.height = Math.floor(this.height * this.resolution);
140 |
141 | if (this.autoResize) {
142 | view.style.width = width + "px";
143 | view.style.height = height + "px";
144 | }
145 | };
146 |
147 | Tiny.CanvasRenderer.prototype.setPixelRatio = function (resolution) {
148 | this.resolution = resolution;
149 |
150 | var view = this.domElement;
151 |
152 | view.width = Math.floor(this.width * this.resolution);
153 | view.height = Math.floor(this.height * this.resolution);
154 | };
155 |
156 | Tiny.CanvasRenderer.prototype.renderObject = function (displayObject, context) {
157 | this.renderSession.context = context || this.context;
158 | this.renderSession.resolution = this.resolution;
159 | displayObject.render(this.renderSession);
160 | };
161 |
--------------------------------------------------------------------------------
/src/renderers/CanvasTinter.js:
--------------------------------------------------------------------------------
1 | Tiny.CanvasTinter = function () {};
2 |
3 | Tiny.CanvasTinter.getTintedTexture = function (sprite, color) {
4 | var texture = sprite.texture;
5 |
6 | if (!texture._tintCache) texture._tintCache = {};
7 |
8 | if (texture._tintCache[color]) return texture._tintCache[color];
9 |
10 | var canvas = Tiny.CanvasTinter.canvas || document.createElement("canvas");
11 |
12 | Tiny.CanvasTinter.tintMethod(texture, color, canvas);
13 |
14 | if (Tiny.CanvasTinter.convertTintToImage) {
15 | // is this better?
16 | var tintImage = new Image();
17 | tintImage.src = canvas.toDataURL();
18 |
19 | // texture._tintCache[stringColor] = tintImage;
20 | } else {
21 | Tiny.CanvasTinter.canvas = null;
22 | }
23 |
24 | if (Tiny.CanvasTinter.cacheTint) texture._tintCache[color] = canvas;
25 |
26 | return canvas;
27 | };
28 |
29 | Tiny.CanvasTinter.tintWithMultiply = function (texture, color, canvas) {
30 | var context = canvas.getContext("2d");
31 |
32 | var crop = texture.crop;
33 |
34 | canvas.width = crop.width;
35 | canvas.height = crop.height;
36 |
37 | context.fillStyle = color;
38 |
39 | context.fillRect(0, 0, crop.width, crop.height);
40 |
41 | context.globalCompositeOperation = "multiply";
42 |
43 | context.drawImage(texture.source, crop.x, crop.y, crop.width, crop.height, 0, 0, crop.width, crop.height);
44 |
45 | context.globalCompositeOperation = "destination-atop";
46 |
47 | context.drawImage(texture.source, crop.x, crop.y, crop.width, crop.height, 0, 0, crop.width, crop.height);
48 | };
49 |
50 | Tiny.CanvasTinter.tintWithPerPixel = function (texture, color, canvas) {
51 | var context = canvas.getContext("2d");
52 |
53 | var crop = texture.crop;
54 |
55 | canvas.width = crop.width;
56 | canvas.height = crop.height;
57 |
58 | context.globalCompositeOperation = "copy";
59 | context.drawImage(texture.source, crop.x, crop.y, crop.width, crop.height, 0, 0, crop.width, crop.height);
60 |
61 | var rgbValues = Tiny.hex2rgb(Tiny.style2hex(color));
62 | var r = rgbValues[0],
63 | g = rgbValues[1],
64 | b = rgbValues[2];
65 |
66 | var pixelData = context.getImageData(0, 0, crop.width, crop.height);
67 |
68 | var pixels = pixelData.data;
69 |
70 | for (var i = 0; i < pixels.length; i += 4) {
71 | pixels[i + 0] *= r;
72 | pixels[i + 1] *= g;
73 | pixels[i + 2] *= b;
74 |
75 | if (!Tiny.canHandleAlpha) {
76 | var alpha = pixels[i + 3];
77 |
78 | pixels[i + 0] /= 255 / alpha;
79 | pixels[i + 1] /= 255 / alpha;
80 | pixels[i + 2] /= 255 / alpha;
81 | }
82 | }
83 |
84 | context.putImageData(pixelData, 0, 0);
85 | };
86 |
87 | function checkInverseAlpha() {
88 | var canvas = new Tiny.CanvasBuffer(2, 1, { willReadFrequently: true });
89 |
90 | canvas.context.fillStyle = "rgba(10, 20, 30, 0.5)";
91 |
92 | // Draw a single pixel
93 | canvas.context.fillRect(0, 0, 1, 1);
94 |
95 | // Get the color values
96 | var s1 = canvas.context.getImageData(0, 0, 1, 1);
97 |
98 | // Plot them to x2
99 | canvas.context.putImageData(s1, 1, 0);
100 |
101 | // Get those values
102 | var s2 = canvas.context.getImageData(1, 0, 1, 1);
103 |
104 | // Compare and return
105 | return (
106 | s2.data[0] === s1.data[0] &&
107 | s2.data[1] === s1.data[1] &&
108 | s2.data[2] === s1.data[2] &&
109 | s2.data[3] === s1.data[3]
110 | );
111 | }
112 |
113 | function checkBlendMode() {
114 | var pngHead = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAABAQMAAADD8p2OAAAAA1BMVEX/";
115 | var pngEnd = "AAAACklEQVQI12NgAAAAAgAB4iG8MwAAAABJRU5ErkJggg==";
116 |
117 | var magenta = new Image();
118 |
119 | magenta.onload = function () {
120 | var yellow = new Image();
121 |
122 | yellow.onload = function () {
123 | var canvas = document.createElement("canvas");
124 | canvas.width = 6;
125 | canvas.height = 1;
126 | var context = canvas.getContext("2d", { willReadFrequently: true });
127 |
128 | context.globalCompositeOperation = "multiply";
129 |
130 | context.drawImage(magenta, 0, 0);
131 | context.drawImage(yellow, 2, 0);
132 |
133 | if (!context.getImageData(2, 0, 1, 1)) {
134 | return false;
135 | }
136 |
137 | var data = context.getImageData(2, 0, 1, 1).data;
138 |
139 | Tiny.supportNewBlendModes = data[0] === 255 && data[1] === 0 && data[2] === 0;
140 | Tiny.CanvasTinter.tintMethod = Tiny.CanvasTinter.tintWithMultiply;
141 | };
142 |
143 | yellow.src = pngHead + "/wCKxvRF" + pngEnd;
144 | };
145 |
146 | magenta.src = pngHead + "AP804Oa6" + pngEnd;
147 |
148 | return false;
149 | }
150 |
151 | Tiny.CanvasTinter.convertTintToImage = false;
152 |
153 | Tiny.CanvasTinter.cacheTint = false;
154 |
155 | Tiny.canHandleAlpha = checkInverseAlpha();
156 |
157 | Tiny.supportNewBlendModes = checkBlendMode();
158 |
159 | Tiny.CanvasTinter.tintMethod = Tiny.supportNewBlendModes
160 | ? Tiny.CanvasTinter.tintWithMultiply
161 | : Tiny.CanvasTinter.tintWithPerPixel;
162 |
--------------------------------------------------------------------------------
/src/systems/RAF.js:
--------------------------------------------------------------------------------
1 | var _isSetTimeOut, _onLoop, _timeOutID, _prevTime, _lastTime;
2 |
3 | var now = function () {
4 | return new Date().getTime();
5 | };
6 |
7 | if (self.performance !== undefined && self.performance.now !== undefined) {
8 | now = self.performance.now.bind(self.performance);
9 | } else if (Date.now !== undefined) {
10 | now = Date.now;
11 | }
12 |
13 | Tiny.RAF = function (game, forceSetTimeOut) {
14 | if (forceSetTimeOut === undefined) {
15 | forceSetTimeOut = false;
16 | }
17 | this.game = game;
18 |
19 | this.isRunning = false;
20 | this.forceSetTimeOut = forceSetTimeOut;
21 |
22 | var vendors = ["ms", "moz", "webkit", "o"];
23 |
24 | for (var x = 0; x < vendors.length && !window.requestAnimationFrame; x++) {
25 | window.requestAnimationFrame = window[vendors[x] + "RequestAnimationFrame"];
26 | window.cancelAnimationFrame =
27 | window[vendors[x] + "CancelAnimationFrame"] || window[vendors[x] + "CancelRequestAnimationFrame"];
28 | }
29 |
30 | _isSetTimeOut = false;
31 | _onLoop = null;
32 | _timeOutID = null;
33 |
34 | _prevTime = 0;
35 | _lastTime = 0;
36 | };
37 |
38 | Tiny.RAF.prototype = {
39 | start: function () {
40 | _prevTime = now();
41 |
42 | this.isRunning = true;
43 |
44 | var _this = this;
45 |
46 | if (!window.requestAnimationFrame || this.forceSetTimeOut) {
47 | _isSetTimeOut = true;
48 |
49 | _onLoop = function () {
50 | return _this.updateSetTimeout();
51 | };
52 |
53 | _timeOutID = window.setTimeout(_onLoop, 0);
54 | } else {
55 | _isSetTimeOut = false;
56 |
57 | _onLoop = function () {
58 | return _this.updateRAF();
59 | };
60 |
61 | _timeOutID = window.requestAnimationFrame(_onLoop);
62 | }
63 | },
64 |
65 | updateRAF: function () {
66 | _lastTime = now();
67 |
68 | if (this.isRunning) {
69 | this.game._update(Math.floor(_lastTime), _lastTime - _prevTime);
70 |
71 | _timeOutID = window.requestAnimationFrame(_onLoop);
72 | }
73 |
74 | _prevTime = _lastTime;
75 | },
76 |
77 | updateSetTimeout: function () {
78 | _lastTime = now();
79 | if (this.isRunning) {
80 | this.game._update(Math.floor(_lastTime), _lastTime - _prevTime);
81 |
82 | _timeOutID = window.setTimeout(_onLoop, Tiny.RAF.timeToCall);
83 | }
84 | _prevTime = _lastTime;
85 | },
86 |
87 | reset: function () {
88 | _prevTime = now();
89 | },
90 |
91 | stop: function () {
92 | if (_isSetTimeOut) {
93 | clearTimeout(_timeOutID);
94 | } else {
95 | window.cancelAnimationFrame(_timeOutID);
96 | }
97 |
98 | this.isRunning = false;
99 | }
100 | };
101 |
102 | Tiny.RAF.timeToCall = 15;
103 |
--------------------------------------------------------------------------------
/src/systems/Timer.js:
--------------------------------------------------------------------------------
1 | var noop = function () {};
2 |
3 | var Timer = function (autoStart, autoRemove, game, cb, ctx, delay, loop, n, oncomplete) {
4 | this.game = game;
5 | this.cb = cb || noop;
6 | this.ctx = ctx || this;
7 | this.delay = delay == undefined ? 1000 : delay;
8 | this.loop = loop;
9 | this.count = n || 0;
10 | this.repeat = this.count > 0;
11 | this.running = !!autoStart;
12 | this._lastFrame = 0;
13 | this.autoRemove = autoRemove;
14 | this.onComplete = oncomplete || noop;
15 | };
16 |
17 | Timer.prototype = {
18 | start: function () {
19 | this.running = true;
20 | },
21 | pause: function () {
22 | this.running = false;
23 | },
24 | stop: function () {
25 | this.running = false;
26 | this._lastFrame = 0;
27 | },
28 | update: function (deltaTime) {
29 | if (this.running) {
30 | this._lastFrame += deltaTime;
31 | if (this._lastFrame >= this.delay) {
32 | this.cb.call(this.ctx);
33 | this._lastFrame = 0;
34 | if (this.repeat) {
35 | this.count--;
36 | if (this.count === 0) {
37 | this.running = false;
38 | this.autoRemove && this.game.timer.remove(this);
39 | this.onComplete();
40 | }
41 | } else if (!this.loop) {
42 | this.running = false;
43 | this.autoRemove && this.game.timer.remove(this);
44 | }
45 | }
46 | }
47 | }
48 | };
49 |
50 | Tiny.Timer = Timer;
51 |
52 | Tiny.TimerCreator = function (game) {
53 | this.game = game;
54 | this.list = [];
55 | this.autoStart = true;
56 | this.autoRemove = true;
57 | };
58 |
59 | Tiny.TimerCreator.prototype = {
60 | update: function (delta) {
61 | for (var i = 0; i < this.list.length; i++) {
62 | this.list[i].update(delta);
63 | }
64 | },
65 | removeAll: function () {
66 | for (var i = 0; i < this.list.length; i++) {
67 | this.list[i].stop();
68 | }
69 |
70 | this.list = [];
71 | },
72 | remove: function (tm) {
73 | var indexOf = this.list.indexOf(tm);
74 | if (indexOf > -1) {
75 | tm.stop();
76 | this.list.splice(indexOf, 1);
77 | }
78 | },
79 | add: function (delay, cb, ctx, autostart, autoremove) {
80 | autostart = autostart != undefined ? autostart : this.autoStart;
81 | autoremove = autoremove != undefined ? autoremove : this.autoRemove;
82 |
83 | var timer = new Timer(autostart, autoremove, this.game, cb, ctx, delay);
84 | this.list.push(timer);
85 | return timer;
86 | },
87 | loop: function (delay, cb, ctx, autostart, autoremove) {
88 | autostart = autostart != undefined ? autostart : this.autoStart;
89 | autoremove = autoremove != undefined ? autoremove : this.autoRemove;
90 |
91 | var timer = new Timer(autostart, autoremove, this.game, cb, ctx, delay, true);
92 | this.list.push(timer);
93 | return timer;
94 | },
95 | repeat: function (delay, n, cb, ctx, autostart, autoremove, complete) {
96 | autostart = autostart != undefined ? autostart : this.autoStart;
97 | autoremove = autoremove != undefined ? autoremove : this.autoRemove;
98 |
99 | var timer = new Timer(autostart, autoremove, this.game, cb, ctx, delay, false, n, complete);
100 | this.list.push(timer);
101 | return timer;
102 | },
103 | destroy: function () {
104 | this.removeAll();
105 | }
106 | };
107 |
108 | Tiny.registerSystem("timer", Tiny.TimerCreator);
109 |
--------------------------------------------------------------------------------
/src/textures/RenderTexture.js:
--------------------------------------------------------------------------------
1 | Tiny.RenderTexture = function (width, height, renderer, resolution) {
2 | this.width = width || 100;
3 | this.height = height || 100;
4 |
5 | // console.log(this);
6 | resolution = resolution || 1;
7 |
8 | // this.frame = new Tiny.Rectangle(0, 0, this.width * this.resolution, this.height * this.resolution);
9 |
10 | // this.crop = new Tiny.Rectangle(0, 0, this.width * this.resolution, this.height * this.resolution);
11 |
12 | // this.baseTexture = new Tiny.BaseTexture();
13 | // this.baseTexture.width = this.width * this.resolution;
14 | // this.baseTexture.height = this.height * this.resolution;
15 | // this.baseTexture.resolution = this.resolution;
16 |
17 | // this.baseTexture.hasLoaded = true;
18 | this.textureBuffer = new Tiny.CanvasBuffer(this.width * resolution, this.height * resolution);
19 |
20 | Tiny.Texture.call(
21 | this,
22 | this.textureBuffer.canvas,
23 | new Tiny.Rectangle(0, 0, Math.floor(this.width * resolution), Math.floor(this.height * resolution))
24 | );
25 |
26 | this.resolution = resolution;
27 |
28 | // this.hasLoaded = true;
29 |
30 | this.renderer = renderer || Tiny.defaultRenderer;
31 |
32 | this.valid = true;
33 | };
34 |
35 | Tiny.RenderTexture.prototype = Object.create(Tiny.Texture.prototype);
36 | Tiny.RenderTexture.prototype.constructor = Tiny.RenderTexture;
37 |
38 | Tiny.RenderTexture.prototype.resize = function (width, height, updateBase) {
39 | if (width === this.width && height === this.height) return;
40 |
41 | this.valid = width > 0 && height > 0;
42 |
43 | this.width = width;
44 | this.height = height;
45 | this.frame.width = this.crop.width = width * this.resolution;
46 | this.frame.height = this.crop.height = height * this.resolution;
47 |
48 | if (updateBase) {
49 | // this.baseTexture.width = this.width * this.resolution;
50 | // this.baseTexture.height = this.height * this.resolution;
51 | }
52 |
53 | if (!this.valid) return;
54 |
55 | this.textureBuffer.resize(this.width * this.resolution, this.height * this.resolution);
56 | };
57 |
58 | Tiny.RenderTexture.prototype.clear = function () {
59 | if (!this.valid) return;
60 |
61 | this.textureBuffer.clear();
62 | };
63 |
64 | Tiny.RenderTexture.prototype.render = function (displayObject, matrix, clear) {
65 | if (!this.valid) return;
66 |
67 | var wt = displayObject.worldTransform;
68 | wt.identity();
69 | if (matrix) wt.append(matrix);
70 |
71 | // setWorld Alpha to ensure that the object is renderer at full opacity
72 | displayObject.worldAlpha = 1;
73 |
74 | // Time to update all the children of the displayObject with the new matrix..
75 | var children = displayObject.children;
76 |
77 | for (var i = 0, j = children.length; i < j; i++) {
78 | children[i].updateTransform();
79 | }
80 |
81 | if (clear) this.textureBuffer.clear();
82 |
83 | var context = this.textureBuffer.context;
84 |
85 | var realResolution = this.renderer.resolution;
86 |
87 | this.renderer.resolution = this.resolution;
88 |
89 | this.renderer.renderObject(displayObject, context);
90 |
91 | this.renderer.resolution = realResolution;
92 | };
93 |
94 | Tiny.RenderTexture.prototype.getImage = function () {
95 | var image = new Image();
96 | image.src = this.getBase64();
97 | return image;
98 | };
99 |
100 | Tiny.RenderTexture.prototype.getBase64 = function () {
101 | return this.getCanvas().toDataURL();
102 | };
103 |
104 | Tiny.RenderTexture.prototype.getCanvas = function () {
105 | return this.textureBuffer.canvas;
106 | };
107 |
--------------------------------------------------------------------------------
/src/textures/Texture.js:
--------------------------------------------------------------------------------
1 | // Tiny.TextureCache = {};
2 | // Tiny.FrameCache = {};
3 | Tiny.TextureCacheIdGenerator = 0;
4 | Tiny.TextureSilentFail = false;
5 |
6 | Tiny.Texture = function (source, frame, crop, trim) {
7 | // console.log(this);
8 | this.noFrame = false;
9 |
10 | this.resolution = 1;
11 |
12 | this.hasLoaded = false;
13 |
14 | if (!frame) {
15 | this.noFrame = true;
16 | frame = new Tiny.Rectangle(0, 0, 1, 1);
17 | }
18 |
19 | if (typeof source == 'string') {
20 | var key = source;
21 |
22 | source = Tiny.Cache.image[key];
23 |
24 | if (!source) throw new Error('Cache Error: image ' + key + ' does`t found in cache');
25 |
26 | Tiny.Cache.texture[key] = this;
27 |
28 | this.key = key;
29 | }
30 |
31 | this.source = source;
32 |
33 | this.frame = frame;
34 |
35 | this.trim = trim;
36 |
37 | this.valid = false;
38 |
39 | this.width = 0;
40 |
41 | this.height = 0;
42 |
43 | this.crop = crop || new Tiny.Rectangle(0, 0, 1, 1);
44 |
45 | if ((this.source.complete || this.source.getContext) && this.source.width && this.source.height) {
46 | this.onSourceLoaded();
47 | } else {
48 | var scope = this;
49 | this.source.onload = function () {
50 | scope.onSourceLoaded();
51 | };
52 | }
53 | };
54 |
55 | Tiny.Texture.prototype.constructor = Tiny.Texture;
56 |
57 | Tiny.Texture.prototype.onSourceLoaded = function () {
58 | this.hasLoaded = true;
59 | this.width = this.source.naturalWidth || this.source.width;
60 | this.height = this.source.naturalHeight || this.source.height;
61 |
62 | if (this.noFrame) this.frame = new Tiny.Rectangle(0, 0, this.width, this.height);
63 |
64 | this.setFrame(this.frame);
65 | };
66 |
67 | Tiny.Texture.prototype.addToCache = function (key, frameName) {
68 | this.key = this.key || key;
69 | this.frame.name = this.frame.name || frameName;
70 |
71 | if (this.frame.name) key += '.' + this.frame.name;
72 |
73 | Tiny.Cache.texture[key] = this;
74 | };
75 |
76 | Tiny.Texture.prototype.destroy = function () {
77 | if (this.key) {
78 | delete Tiny.Cache.texture[this.key];
79 | }
80 |
81 | this.source = null;
82 | this.valid = false;
83 | };
84 |
85 | Tiny.Texture.prototype.setFrame = function (frame) {
86 | this.noFrame = false;
87 |
88 | this.frame = frame;
89 |
90 | this.valid = frame && frame.width && frame.height && this.source && this.hasLoaded;
91 |
92 | if (!this.valid) return;
93 |
94 | // this.width = frame.width;
95 | // this.height = frame.height;
96 |
97 | this.crop.x = frame.x;
98 | this.crop.y = frame.y;
99 | this.crop.width = frame.width;
100 | this.crop.height = frame.height;
101 |
102 | if (!this.trim && (frame.x + frame.width > this.width || frame.y + frame.height > this.height)) {
103 | if (!Tiny.TextureSilentFail) {
104 | throw new Error('Texture Error: frame does not fit inside the base Texture dimensions ' + this);
105 | }
106 |
107 | this.valid = false;
108 | return;
109 | }
110 |
111 | if (this.trim) {
112 | // this.width = this.trim.width;
113 | // this.height = this.trim.height;
114 | this.frame.width = this.trim.width;
115 | this.frame.height = this.trim.height;
116 | }
117 | };
118 |
119 | // Tiny.Texture.fromImage = function(key, imageUrl, crossorigin)
120 | // {
121 | // var texture = Tiny.TextureCache[key];
122 |
123 | // if(!texture)
124 | // {
125 | // texture = new Tiny.Texture(Tiny.BaseTexture.fromImage(key, imageUrl, crossorigin));
126 | // texture.key = key
127 | // Tiny.TextureCache[key] = texture;
128 | // }
129 |
130 | // return texture;
131 | // };
132 |
133 | // Tiny.Texture.fromFrame = function(frameId)
134 | // {
135 | // var texture = Tiny.TextureCache[frameId];
136 | // if(!texture) throw new Error('The frameId "' + frameId + '" does not exist in the texture cache ');
137 | // return texture;
138 | // };
139 |
140 | Tiny.Texture.fromCanvas = function (canvas) {
141 | // if(!canvas._tinyId)
142 | // {
143 | // canvas._tinyId = '_from_canvas_' + Tiny.TextureCacheIdGenerator++;
144 | // }
145 |
146 | // var texture = Tiny.Cache.texture[canvas._tinyId];
147 |
148 | // if(!texture)
149 | // {
150 | // texture = new Tiny.Texture( canvas );
151 | // Tiny.Cache.texture[canvas._tinyId] = texture;
152 | // }
153 |
154 | // return texture;
155 | return new Tiny.Texture(canvas);
156 | };
157 |
158 | // Tiny.Texture.addTextureToCache = function(texture, id)
159 | // {
160 | // Tiny.TextureCache[id] = texture;
161 | // };
162 |
163 | // Tiny.Texture.removeTextureFromCache = function(id)
164 | // {
165 | // var texture = Tiny.TextureCache[id];
166 | // delete Tiny.TextureCache[id];
167 | // delete Tiny.BaseTextureCache[id];
168 | // return texture;
169 | // };
170 |
--------------------------------------------------------------------------------
/src/utils/CanvasBuffer.js:
--------------------------------------------------------------------------------
1 | Tiny.CanvasBuffer = function (width, height, options) {
2 | this.width = width;
3 | this.height = height;
4 |
5 | this.canvas = document.createElement("canvas");
6 | this.context = this.canvas.getContext("2d", options);
7 |
8 | this.canvas.width = width;
9 | this.canvas.height = height;
10 | };
11 |
12 | Tiny.CanvasBuffer.prototype.constructor = Tiny.CanvasBuffer;
13 |
14 | Tiny.CanvasBuffer.prototype.clear = function () {
15 | this.context.setTransform(1, 0, 0, 1, 0, 0);
16 | this.context.clearRect(0, 0, this.width, this.height);
17 | };
18 |
19 | Tiny.CanvasBuffer.prototype.resize = function (width, height) {
20 | this.width = this.canvas.width = width;
21 | this.height = this.canvas.height = height;
22 | };
23 |
--------------------------------------------------------------------------------
/src/utils/EventEmitter.js:
--------------------------------------------------------------------------------
1 | function EventListeners() {
2 | this.a = [];
3 | this.n = 0;
4 | }
5 |
6 | Tiny.EventEmitter = {
7 | call: function (obj) {
8 | if (obj) {
9 | obj = obj.prototype || obj;
10 | Tiny.EventEmitter.mixin(obj);
11 | }
12 | },
13 |
14 | mixin: function (obj) {
15 | const listeners_events = {};
16 |
17 | function pushListener(event, fn, context, once) {
18 | var listeners = listeners_events[event];
19 |
20 | if (!listeners) {
21 | listeners = listeners_events[event] = new EventListeners();
22 | }
23 |
24 | listeners.a.push(fn, context || null, once || false);
25 | listeners.n += 3;
26 | }
27 |
28 | obj.once = function (event, fn, context) {
29 | pushListener(event, fn, context, true);
30 | };
31 |
32 | obj.on = pushListener;
33 |
34 | obj.off = function (event, fn, context) {
35 | var listeners = listeners_events[event];
36 |
37 | if (!listeners) return;
38 |
39 | var fnArray = listeners_events[event].a;
40 |
41 | if (!fn) {
42 | fnArray.length = 0;
43 | } else if (!context) {
44 | for (var i = 0; i < fnArray.length; i += 3) {
45 | if (fnArray[i] == fn) {
46 | fnArray.splice(i, 3);
47 | i -= 3;
48 | }
49 | }
50 | } else {
51 | for (var i = 0; i < fnArray.length; i += 3) {
52 | if (fnArray[i] == fn && fnArray[i + 1] == context) {
53 | fnArray.splice(i, 3);
54 | i -= 3;
55 | }
56 | }
57 | }
58 |
59 | if (fnArray.length == 0) {
60 | delete listeners_events[event];
61 | }
62 | };
63 |
64 | obj.emit = function (event, a1, a2, a3) {
65 | var listeners = listeners_events[event];
66 |
67 | if (!listeners) return;
68 |
69 | var fnArray = listeners.a;
70 | listeners.n = 0;
71 |
72 | var len = arguments.length;
73 | var fn, ctx;
74 |
75 | for (var i = 0; i < fnArray.length - listeners.n; i += 3) {
76 | fn = fnArray[i];
77 | ctx = fnArray[i + 1];
78 |
79 | if (fnArray[i + 2]) {
80 | fnArray.splice(i, 3);
81 | i -= 3;
82 | }
83 |
84 | if (len <= 1) fn.call(ctx);
85 | else if (len == 2) fn.call(ctx, a1);
86 | else if (len == 3) fn.call(ctx, a1, a2);
87 | else fn.call(ctx, a1, a2, a3);
88 |
89 | // if (fnArray[i + 2])
90 | // {
91 | // fnArray.splice(i, 3);
92 | // i -= 3;
93 | // }
94 | }
95 |
96 | if (fnArray.length == 0) {
97 | delete listeners_events[event];
98 | }
99 | };
100 | }
101 | };
102 |
--------------------------------------------------------------------------------
/src/utils/polyfill.js:
--------------------------------------------------------------------------------
1 | if (!Date.now) {
2 | Date.now = function now() {
3 | return new Date().getTime();
4 | };
5 | }
6 |
7 | if (typeof Float32Array == "undefined") {
8 | window.Float32Array = Array;
9 | }
10 |
--------------------------------------------------------------------------------
/webpack.build.js:
--------------------------------------------------------------------------------
1 | const TerserPlugin = require('terser-webpack-plugin'),
2 | Webpack = require('webpack');
3 |
4 | const config = {
5 | mode: 'production',
6 |
7 | context: `${__dirname}/src`,
8 |
9 | entry: {
10 | 'tiny': './index.js',
11 | 'tiny.mini': './mini.js',
12 | 'tiny.base': './base.js'
13 | },
14 |
15 | output: {
16 | path: `${__dirname}/build/`,
17 | filename: `[name].js`,
18 | environment: {
19 | arrowFunction: false
20 | }
21 | },
22 |
23 | performance: {
24 | hints: false
25 | },
26 |
27 | optimization: {
28 | minimize: true,
29 | minimizer: [
30 | new TerserPlugin({
31 | include: /\.js$/,
32 | parallel: true,
33 | terserOptions: {
34 | sourceMap: false,
35 | compress: true,
36 | ie8: false,
37 | ecma: 5,
38 | output: {
39 | comments: false
40 | },
41 | warnings: false
42 | }
43 | })
44 | ]
45 | },
46 |
47 | plugins: [
48 | new Webpack.DefinePlugin({
49 | __DEBUG__: 'false'
50 | })
51 | ],
52 |
53 | stats: {
54 | colors: true
55 | }
56 | };
57 |
58 | module.exports = config;
59 |
--------------------------------------------------------------------------------
/webpack.dev.js:
--------------------------------------------------------------------------------
1 | const Webpack = require('webpack'),
2 | // TerserPlugin = require('terser-webpack-plugin'),
3 | path = require('path');
4 |
5 | const webpackConfig = {
6 | mode: 'development',
7 | // mode: 'production',
8 | // watch: true,
9 |
10 | devtool: 'inline-source-map',
11 |
12 | // context: `${__dirname}`,
13 |
14 | entry: {
15 | 'tiny': './src/index.js',
16 | 'tiny.mini': './src/mini.js',
17 | 'plugins/extra': './plugins/extra',
18 | 'plugins/particles': './plugins/particles',
19 | 'plugins/three': './plugins/three',
20 | 'plugins/create': './plugins/create',
21 | 'plugins/sound': './plugins/sound',
22 | 'plugins/anim': './plugins/anim'
23 | // 'particles_pack': './particles_pack.js',
24 | },
25 |
26 | // optimization: {
27 | // minimize: true,
28 | // minimizer: [
29 | // new TerserPlugin({
30 | // include: /\.js$/,
31 | // parallel: true,
32 | // terserOptions: {
33 | // sourceMap: false,
34 | // compress: true,
35 | // ie8: false,
36 | // ecma: 5,
37 | // output: {
38 | // comments: false
39 | // },
40 | // warnings: false
41 | // }
42 | // })
43 | // ]
44 | // },
45 |
46 | output: {
47 | path: path.resolve(__dirname, 'examples/libs/tiny'),
48 | filename: '[name].js',
49 | environment: {
50 | arrowFunction: false
51 | }
52 | },
53 |
54 | plugins: [
55 | new Webpack.DefinePlugin({
56 | __DEBUG__: 'true'
57 | })
58 | ],
59 |
60 | stats: {
61 | colors: true
62 | }
63 |
64 | // devServer: {
65 | // host: '0.0.0.0',
66 | // port: 3000,
67 | // // hot: true,
68 | // static: {
69 | // directory: path.resolve('examples')
70 | // // watch: true
71 | // }
72 | // }
73 | };
74 |
75 | // const compiler = Webpack(webpackConfig);
76 | // const devServerOptions = { ...webpackConfig.devServer, open: true };
77 | // const server = new WebpackDevServer(devServerOptions, compiler);
78 |
79 | // const runServer = async () => {
80 | // console.log('Starting server...');
81 | // await server.start();
82 | // };
83 |
84 | // runServer();
85 |
86 | module.exports = webpackConfig;
87 |
--------------------------------------------------------------------------------