-
Notifications
You must be signed in to change notification settings - Fork 0
/
story.scene.js
executable file
·125 lines (112 loc) · 3.88 KB
/
story.scene.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/*jslint browser: true */
(function (exports) {
'use strict';
/** @namespace */
var namespace;
if (exports.ziq && exports.ziq.Story) {
namespace = exports.ziq.Story;
} else {
throw 'ziq.Story is required.';
}
/** Check if the two rectangle area is intersected. */
function isRectsInterseted(r1, r2) {
return !((r1.y + r1.h < r2.y) || (r2.y + r2.h < r1.y) || (r1.x + r1.w < r2.x) || (r2.x + r2.w < r1.x));
}
/**
* Create a new Scene function.
* @constructor
* @function
* @param ctx the context of the scene.
* @param callback (optional) the update callback function.
*/
function Scene(ctx, callback) {
var actors = [];
/**
* The implementation of scene function.
* @function
* @param {Number} frame - current frame.
*/
function scene(frame) {
// Traverse the actors and update them.
var i, actor;
ctx.save();
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.restore();
for (i = 0; i < actors.length; i += 1) {
if (actors[i] && actors[i].object) {
actors[i].object(ctx);
}
}
if (callback) {
callback(frame);
}
}
/**
* Get the context created with the scene.
* @returns {object}
*/
scene.getContext = function () {
return ctx;
};
/**
* Add an actor to the screen. An actor is an active(updatable/paitable) object on the scene.
* @param {object} rect - the rectangle area of the boject.
* @param {object} actor - (optional) the actor object.
*/
scene.addActor = function (rect, actor) {
if (!actor) {
actor = rect;
}
actors.push({
rect: rect,
object: actor
});
actor.scene = scene;
};
/**
* Implementing a Array-like forEach() function.
* @param {function} callback - the callback(rect, object) function
*/
scene.forEach = function (callback) {
var i;
for (i = 0; i < actors.length; i += 1) {
if (actors[i]) {
callback(actors[i].rect, actors[i].object);
}
}
};
/**
* Remove an actor. If the second parameter is absent, all objects within that area will be cleared.
* @param rect rectangle area of the actor.
* @param actor (optional) the actor.
*/
scene.removeActor = function (rect, actor) {
if (rect) {
var i, a, b;
for (i = 0; i < actors.length; i += 1) {
if (actors[i] && isRectsInterseted(actors[i].rect, rect)) {
if (!actor || actor === actors[i].object) {
delete actors[i];
}
}
}
}
};
/**
* Get an arrary of actors around the selected area.
* @param rect the rectangle area(x,y,w,h).
* @returns {Array}
*/
scene.getActors = function (rect) {
var keys = Object.keys(actors), i, results = [];
for (i = 0; i < keys.length; i += 1) {
if (isRectsInterseted(actors[keys[i]].rect, rect)) {
results.push(actors[keys[i]]);
}
}
return results;
};
return scene;
}
namespace.Scene = Scene;
}(window));