mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
Merge pull request #2157 from 4ian/refactor/ts
Convert the game engine (GDJS) and the extensions to TypeScript
This commit is contained in:
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
@@ -100,7 +100,6 @@
|
||||
"GDJS/docs": true,
|
||||
"GDCpp/docs": true,
|
||||
"Core/docs": true,
|
||||
"Extensions/CommonDialogs/dlib-18.16": true,
|
||||
"newIDE/electron-app/dist": true,
|
||||
"newIDE/app/build": true,
|
||||
"newIDE/app/resources/GDJS": true,
|
||||
|
@@ -5,11 +5,11 @@ GDevelop is architectured around a `Core` library, platforms (`GDJS`, `GDCpp`) a
|
||||
| Directory | ℹ️ Description |
|
||||
| --- | --- |
|
||||
| `Core` | GDevelop core library, containing common tools to implement the IDE and work with GDevelop games. |
|
||||
| `GDCpp` | GDevelop C++ game engine, used to **build native games**. |
|
||||
| `GDJS` | GDevelop JS game engine, used to build **HTML5 games**. |
|
||||
| `GDevelop.js` | Bindings of Core/GDCpp/GDJS and Extensions to JavaScript (used by the IDE). |
|
||||
| `newIDE` | The game editor, written in JavaScript with React, Electron and Pixi.js. |
|
||||
| `Extensions` | Extensions for C++ or JS game engines, providing objects, events and new features. |
|
||||
| `GDCpp` | The C++ game engine, used to build native games (*not used in GDevelop 5*). |
|
||||
| `GDJS` | The game engine, written in TypeScript, using PixiJS (WebGL), powering all GDevelop games. |
|
||||
| `GDevelop.js` | Bindings of `Core`/`GDCpp`/`GDJS` and `Extensions` to JavaScript (with WebAssembly), used by the IDE. |
|
||||
| `newIDE` | The game editor, written in JavaScript with React, Electron and PixiJS. |
|
||||
| `Extensions` | Extensions for the game engine, providing objects, behaviors, events and new features. |
|
||||
|
||||
The rest of this page is an introduction to the main concepts of GDevelop architecture.
|
||||
|
||||
@@ -26,16 +26,16 @@ The rest of this page is an introduction to the main concepts of GDevelop archit
|
||||
Extensions do have the same distinction between the "**IDE**" part and the "**Runtime**" part. For example, most extensions have:
|
||||
|
||||
* A file called [`JsExtension.js`(https://github.com/4ian/GDevelop/blob/master/Extensions/ExampleJsExtension/JsExtension.js)], which contains the *declaration* of the extension for the **IDE**
|
||||
* One or more files implementing the feature for the game, in other words for **Runtime**. This can be a [Runtime Object](https://github.com/4ian/GDevelop/blob/master/Extensions/ExampleJsExtension/dummyruntimeobject.js) or a [Runtime Behavior](https://github.com/4ian/GDevelop/blob/master/Extensions/ExampleJsExtension/dummyruntimebehavior.js), [functions called by actions or conditions](https://github.com/4ian/GDevelop/blob/master/Extensions/ExampleJsExtension/examplejsextensiontools.js) or by the game engine.
|
||||
* One or more files implementing the feature for the game, in other words for **Runtime**. This can be a [Runtime Object](https://github.com/4ian/GDevelop/blob/master/Extensions/ExampleJsExtension/dummyruntimeobject.ts) or a [Runtime Behavior](https://github.com/4ian/GDevelop/blob/master/Extensions/ExampleJsExtension/dummyruntimebehavior.ts), [functions called by actions or conditions](https://github.com/4ian/GDevelop/blob/master/Extensions/ExampleJsExtension/examplejsextensiontools.ts) or by the game engine.
|
||||
|
||||
### "Runtime" and "IDE" difference using an example: the `gd::Variable` class
|
||||
|
||||
In GDevelop, developers can associate and manipulate variables in their games. To represent them, we have two things:
|
||||
|
||||
* The **editor** `gd::Variable` that is part of the structure of the game, so living in [GDCore in Variable.h](https://4ian.github.io/GD-Documentation/GDCore%20Documentation/classgd_1_1_variable.html). This is what is shown in the editor, saved on disk in the project file.
|
||||
* The **game engine** variable, called `gdjs.Variable` in GDJS. [Documentation is in the GDJS **game engine**](https://docs.gdevelop-app.com/GDJS%20Runtime%20Documentation/gdjs.Variable.html). This JavaScript class is what is used during a game.
|
||||
* The **game engine** variable, called `gdjs.Variable` in GDJS. [Documentation is in the GDJS **game engine**](https://docs.gdevelop-app.com/GDJS%20Runtime%20Documentation/Variable.html). This JavaScript class is what is used during a game.
|
||||
|
||||
The editor `gd::Variable` **know nothing** about the game engine class `gdjs.Variable`. And the `gdjs.Variable` class in the game engine know almost nothing from `gd::Variable` (apart from how it's written in JSON, to be able to load a game default variables).
|
||||
The editor `gd::Variable` **knows nothing** about the game engine class `gdjs.Variable`. And the `gdjs.Variable` class in the game engine knows almost nothing from `gd::Variable` (apart from how it's written in JSON, to be able to load a game default variables).
|
||||
|
||||
> Note that the name `gdjs.Variable` is maybe a *bad decision*: it should have been called a `gdjs.RuntimeVariable`, like `gdjs.RuntimeObject` and like most other classes of the game engine.
|
||||
|
||||
@@ -53,7 +53,7 @@ While `GDJS/Runtime` folder is the game engine that is executed inside a game, `
|
||||
* What are [the default extensions](https://github.com/4ian/GDevelop/tree/master/GDJS/GDJS/Extensions/Builtin),
|
||||
* How do you [generate JS code from events](https://github.com/4ian/GDevelop/tree/master/GDJS/GDJS/Events/CodeGeneration),
|
||||
|
||||
The game engine is in GDJS/Runtime and is all JavaScript.
|
||||
The game engine is in GDJS/Runtime and is all written in TypeScript.
|
||||
|
||||
## What about events?
|
||||
|
||||
@@ -68,7 +68,7 @@ A `gd::Instruction` is "just" a type (the name of the action or condition), and
|
||||
|
||||
They do not exist anymore! ✨
|
||||
|
||||
Events are translated (we also say "transpiled" or "generated") into "real" code in a programming language. This process is called "Code Generation", and is [done here for the JavaScript game engine](https://github.com/4ian/GDevelop/tree/master/GDJS/GDJS/Events/CodeGeneration).
|
||||
Events are translated (we also say "transpiled" or "generated") into "real" code in a programming language. This process is called "Code Generation", and is [done here for the TypeScript game engine](https://github.com/4ian/GDevelop/tree/master/GDJS/GDJS/Events/CodeGeneration).
|
||||
|
||||
### Can I extract Events classes and code generator to make a development environment based on GDevelop events?
|
||||
|
||||
@@ -79,7 +79,7 @@ You're welcome to do so! Please get in touch :)
|
||||
The idea of GDevelop editor and game engine is to have a lean game engine, supporting almost nothing. Then, one can add "mods", "plugins", "modules" for GDevelop. We chose to call them "**Extensions**" in GDevelop.
|
||||
|
||||
* `GDevelop/Core/GDCore/Extensions` is the **declaration** of default (we say "builtin") extensions, that are available for any game and are "mandatory". They are called Extensions but they could be named "Extensions that will always be in your game". In programming languages, this is called a "[Standard Library](https://en.wikipedia.org/wiki/Standard_library)" (but don't get too distracted by this naming).
|
||||
* `GDevelop/GDJS/GDJS/Extensions/` and `GDevelop/GDCpp/GDCpp/Extensions/` are reusing these **declarations** and **adding** their own declarations. Mainly, they are setting the name of the functions to be called (either in JS or in C++) for each action, condition or expression.
|
||||
* `GDevelop/GDJS/GDJS/Extensions/` and `GDevelop/GDCpp/GDCpp/Extensions/` are reusing these **declarations** and **adding** their own declarations. Mainly, they are setting the name of the functions to be called (either in TypeScript or in C++) for each action, condition or expression.
|
||||
* `GDevelop/Extensions/` is the folder for the "mods"/"plugins" for GDevelop - the one that are not mandatory. They are not part of GDCore - they work on their own.
|
||||
|
||||
> In theory, all extensions could be moved to `GDevelop/Extensions/`. In practice, it's more pragmatic to have a set of "builtin" extensions with basic features.
|
||||
@@ -111,7 +111,7 @@ All the required C++ files are imported into this huge list: https://github.com/
|
||||
|
||||
GDevelop was originally written in C++. It's a scary language at first but is portable across almost any existing machine in this universe, can be pretty good, safe and readable with the latest C++ features.
|
||||
|
||||
### What's the deal with JavaScript? Why so much of it?
|
||||
### What's the deal with JavaScript/TypeScript? Why so much of it?
|
||||
|
||||
JavaScript, with the latest language proposals, is actually a very capable language, fast to write and safe with typing:
|
||||
|
||||
|
@@ -1,352 +0,0 @@
|
||||
/**
|
||||
* @memberof gdjs
|
||||
* @class adMob
|
||||
* @static
|
||||
* @private
|
||||
*/
|
||||
gdjs.adMob = {
|
||||
// Banner
|
||||
bannerLoading: false,
|
||||
bannerReady: false,
|
||||
bannerShowing: false,
|
||||
bannerExists: false,
|
||||
bannerAutoshow: false, // Needed because the banner event listeners bug
|
||||
// Interstitial
|
||||
interstitialLoading: false,
|
||||
interstitialReady: false,
|
||||
interstitialShowing: false,
|
||||
// Reward video
|
||||
videoLoading: false,
|
||||
videoReady: false,
|
||||
videoShowing: false,
|
||||
videoReward: false,
|
||||
};
|
||||
|
||||
gdjs.adMob._getPlatformName = function() {
|
||||
if (/(android)/i.test(navigator.userAgent)) {
|
||||
return 'android';
|
||||
} else if (/(ipod|iphone|ipad)/i.test(navigator.userAgent)) {
|
||||
return 'ios';
|
||||
} else {
|
||||
return 'windowsPhone';
|
||||
}
|
||||
};
|
||||
|
||||
// Banner
|
||||
gdjs.adMob.isBannerLoading = function() {
|
||||
return gdjs.adMob.bannerLoading;
|
||||
};
|
||||
|
||||
gdjs.adMob.isBannerReady = function() {
|
||||
// This block is needed because the banner event listeners bug
|
||||
if (gdjs.adMob.bannerAutoshow && gdjs.adMob.bannerReady) {
|
||||
gdjs.adMob.bannerReady = false;
|
||||
gdjs.adMob.bannerShowing = true;
|
||||
gdjs.adMob.bannerExists = true;
|
||||
}
|
||||
|
||||
return gdjs.adMob.bannerReady;
|
||||
};
|
||||
|
||||
gdjs.adMob.isBannerShowing = function() {
|
||||
// This block is needed because the banner event listeners bug
|
||||
if (gdjs.adMob.bannerAutoshow && gdjs.adMob.bannerReady) {
|
||||
gdjs.adMob.bannerReady = false;
|
||||
gdjs.adMob.bannerShowing = true;
|
||||
gdjs.adMob.bannerExists = true;
|
||||
}
|
||||
|
||||
return gdjs.adMob.bannerShowing;
|
||||
};
|
||||
|
||||
gdjs.adMob.existBanner = function() {
|
||||
// This block is needed because the banner event listeners bug
|
||||
if (gdjs.adMob.bannerAutoshow && gdjs.adMob.bannerReady) {
|
||||
gdjs.adMob.bannerReady = false;
|
||||
gdjs.adMob.bannerShowing = true;
|
||||
gdjs.adMob.bannerExists = true;
|
||||
}
|
||||
|
||||
return gdjs.adMob.bannerExists;
|
||||
};
|
||||
|
||||
gdjs.adMob.loadBanner = function(
|
||||
androidID,
|
||||
iosID,
|
||||
atTop,
|
||||
overlap,
|
||||
displayOnLoading,
|
||||
testMode
|
||||
) {
|
||||
if (typeof admob === 'undefined') return;
|
||||
|
||||
if (
|
||||
gdjs.adMob.bannerLoading ||
|
||||
gdjs.adMob.bannerReady ||
|
||||
gdjs.adMob.bannerExists
|
||||
)
|
||||
return;
|
||||
|
||||
admob.banner.config({
|
||||
id: gdjs.adMob._getPlatformName() === 'android' ? androidID : iosID, // Support Android & iOS
|
||||
bannerAtTop: atTop,
|
||||
overlap: overlap,
|
||||
autoShow: displayOnLoading,
|
||||
isTesting: testMode,
|
||||
});
|
||||
admob.banner.prepare();
|
||||
|
||||
gdjs.adMob.bannerLoading = true;
|
||||
gdjs.adMob.bannerReady = false;
|
||||
|
||||
// These lines are needed because the banner event listeners bug
|
||||
gdjs.adMob.bannerAutoshow = displayOnLoading;
|
||||
gdjs.adMob.bannerShowing = false;
|
||||
gdjs.adMob.bannerExists = false;
|
||||
};
|
||||
|
||||
gdjs.adMob.showBanner = function() {
|
||||
if (typeof admob === 'undefined') return;
|
||||
|
||||
// This block is needed because the banner event listeners bug
|
||||
if (gdjs.adMob.bannerReady) {
|
||||
gdjs.adMob.bannerReady = false;
|
||||
gdjs.adMob.bannerExists = true;
|
||||
}
|
||||
|
||||
if (gdjs.adMob.bannerExists) gdjs.adMob.bannerShowing = true;
|
||||
|
||||
admob.banner.show();
|
||||
};
|
||||
|
||||
gdjs.adMob.hideBanner = function() {
|
||||
if (typeof admob === 'undefined') return;
|
||||
|
||||
if (gdjs.adMob.bannerExists) gdjs.adMob.bannerShowing = false;
|
||||
|
||||
admob.banner.hide();
|
||||
};
|
||||
|
||||
gdjs.adMob.removeBanner = function() {
|
||||
if (typeof admob === 'undefined') return;
|
||||
|
||||
// These lines are needed because the banner event listeners bug
|
||||
gdjs.adMob.bannerExists = false;
|
||||
gdjs.adMob.bannerShowing = false;
|
||||
|
||||
admob.banner.remove();
|
||||
};
|
||||
|
||||
// Interstitial
|
||||
gdjs.adMob.isInterstitialLoading = function() {
|
||||
return gdjs.adMob.interstitialLoading;
|
||||
};
|
||||
|
||||
gdjs.adMob.isInterstitialReady = function() {
|
||||
return gdjs.adMob.interstitialReady;
|
||||
};
|
||||
|
||||
gdjs.adMob.isInterstitialShowing = function() {
|
||||
return gdjs.adMob.interstitialShowing;
|
||||
};
|
||||
|
||||
gdjs.adMob.loadInterstitial = function(
|
||||
androidID,
|
||||
iosID,
|
||||
displayOnLoading,
|
||||
testMode
|
||||
) {
|
||||
if (typeof admob === 'undefined') return;
|
||||
|
||||
if (
|
||||
gdjs.adMob.interstitialLoading ||
|
||||
gdjs.adMob.interstitialReady ||
|
||||
gdjs.adMob.interstitialShowing
|
||||
)
|
||||
return;
|
||||
|
||||
admob.interstitial.config({
|
||||
id: gdjs.adMob._getPlatformName() === 'android' ? androidID : iosID, // Support Android & iOS
|
||||
autoShow: displayOnLoading,
|
||||
isTesting: testMode,
|
||||
});
|
||||
admob.interstitial.prepare();
|
||||
|
||||
gdjs.adMob.interstitialLoading = true;
|
||||
gdjs.adMob.interstitialReady = false;
|
||||
};
|
||||
|
||||
gdjs.adMob.showInterstitial = function() {
|
||||
if (typeof admob === 'undefined') return;
|
||||
|
||||
admob.interstitial.show();
|
||||
};
|
||||
|
||||
// Reward video
|
||||
gdjs.adMob.isVideoLoading = function() {
|
||||
return gdjs.adMob.videoLoading;
|
||||
};
|
||||
|
||||
gdjs.adMob.isVideoReady = function() {
|
||||
return gdjs.adMob.videoReady;
|
||||
};
|
||||
|
||||
gdjs.adMob.isVideoShowing = function() {
|
||||
return gdjs.adMob.videoShowing;
|
||||
};
|
||||
|
||||
gdjs.adMob.existVideoReward = function(markAsClaimed) {
|
||||
var reward = gdjs.adMob.videoReward;
|
||||
if (markAsClaimed) gdjs.adMob.videoReward = false;
|
||||
|
||||
return reward;
|
||||
};
|
||||
|
||||
gdjs.adMob.loadVideo = function(androidID, iosID, displayOnLoading, testMode) {
|
||||
if (typeof admob === 'undefined') return;
|
||||
|
||||
if (
|
||||
gdjs.adMob.videoLoading ||
|
||||
gdjs.adMob.videoReady ||
|
||||
gdjs.adMob.videoShowing
|
||||
)
|
||||
return;
|
||||
|
||||
admob.rewardvideo.config({
|
||||
id: gdjs.adMob._getPlatformName() === 'android' ? androidID : iosID, // Support Android & iOS
|
||||
autoShow: displayOnLoading,
|
||||
isTesting: testMode,
|
||||
});
|
||||
admob.rewardvideo.prepare();
|
||||
|
||||
gdjs.adMob.videoLoading = true;
|
||||
gdjs.adMob.videoReady = false;
|
||||
};
|
||||
|
||||
gdjs.adMob.showVideo = function() {
|
||||
if (typeof admob === 'undefined') return;
|
||||
|
||||
admob.rewardvideo.show();
|
||||
};
|
||||
|
||||
gdjs.adMob.claimVideoReward = function() {
|
||||
gdjs.adMob.videoReward = false;
|
||||
};
|
||||
|
||||
// Banner event listeners
|
||||
document.addEventListener(
|
||||
'admob.banner.events.LOAD',
|
||||
function() {
|
||||
gdjs.adMob.bannerReady = true;
|
||||
gdjs.adMob.bannerLoading = false;
|
||||
},
|
||||
false
|
||||
);
|
||||
|
||||
document.addEventListener(
|
||||
'admob.banner.events.LOAD_FAIL',
|
||||
function() {
|
||||
gdjs.adMob.bannerLoading = false;
|
||||
},
|
||||
false
|
||||
);
|
||||
|
||||
// BUG: These two never get called
|
||||
/*
|
||||
document.addEventListener(
|
||||
"admob.banner.events.OPEN",
|
||||
function() {
|
||||
gdjs.adMob.bannerExists = true;
|
||||
gdjs.adMob.bannerShowing = true;
|
||||
gdjs.adMob.bannerReady = false;
|
||||
},
|
||||
false
|
||||
);
|
||||
|
||||
document.addEventListener(
|
||||
"admob.banner.events.CLOSE",
|
||||
function() {
|
||||
gdjs.adMob.bannerExists = false;
|
||||
gdjs.adMob.bannerShowing = false;
|
||||
},
|
||||
false
|
||||
);
|
||||
*/
|
||||
|
||||
// Interstitial event listeners
|
||||
document.addEventListener(
|
||||
'admob.interstitial.events.LOAD',
|
||||
function() {
|
||||
gdjs.adMob.interstitialReady = true;
|
||||
gdjs.adMob.interstitialLoading = false;
|
||||
},
|
||||
false
|
||||
);
|
||||
|
||||
document.addEventListener(
|
||||
'admob.interstitial.events.LOAD_FAIL',
|
||||
function() {
|
||||
gdjs.adMob.interstitialLoading = false;
|
||||
},
|
||||
false
|
||||
);
|
||||
|
||||
document.addEventListener(
|
||||
'admob.interstitial.events.OPEN',
|
||||
function() {
|
||||
gdjs.adMob.interstitialShowing = true;
|
||||
gdjs.adMob.interstitialReady = false;
|
||||
},
|
||||
false
|
||||
);
|
||||
|
||||
document.addEventListener(
|
||||
'admob.interstitial.events.CLOSE',
|
||||
function() {
|
||||
gdjs.adMob.interstitialShowing = false;
|
||||
},
|
||||
false
|
||||
);
|
||||
|
||||
// Reward video event listeners
|
||||
document.addEventListener(
|
||||
'admob.rewardvideo.events.LOAD',
|
||||
function() {
|
||||
gdjs.adMob.videoReady = true;
|
||||
gdjs.adMob.videoLoading = false;
|
||||
},
|
||||
false
|
||||
);
|
||||
|
||||
document.addEventListener(
|
||||
'admob.rewardvideo.events.LOAD_FAIL',
|
||||
function() {
|
||||
gdjs.adMob.videoLoading = false;
|
||||
},
|
||||
false
|
||||
);
|
||||
|
||||
document.addEventListener(
|
||||
'admob.rewardvideo.events.OPEN',
|
||||
function() {
|
||||
gdjs.adMob.videoShowing = true;
|
||||
gdjs.adMob.videoReady = false;
|
||||
},
|
||||
false
|
||||
);
|
||||
|
||||
document.addEventListener(
|
||||
'admob.rewardvideo.events.CLOSE',
|
||||
function() {
|
||||
gdjs.adMob.videoShowing = false;
|
||||
},
|
||||
false
|
||||
);
|
||||
|
||||
document.addEventListener(
|
||||
'admob.rewardvideo.events.REWARD',
|
||||
function() {
|
||||
gdjs.adMob.videoReward = true;
|
||||
},
|
||||
false
|
||||
);
|
343
Extensions/AdMob/admobtools.ts
Normal file
343
Extensions/AdMob/admobtools.ts
Normal file
@@ -0,0 +1,343 @@
|
||||
namespace gdjs {
|
||||
declare var admob: any;
|
||||
|
||||
export namespace adMob {
|
||||
// Banner
|
||||
export let bannerLoading = false;
|
||||
export let bannerReady = false;
|
||||
export let bannerShowing = false;
|
||||
export let bannerExists = false;
|
||||
export let bannerAutoshow = false;
|
||||
// Needed because the banner event listeners bug
|
||||
// Interstitial
|
||||
export let interstitialLoading = false;
|
||||
export let interstitialReady = false;
|
||||
export let interstitialShowing = false;
|
||||
// Reward video
|
||||
export let videoLoading = false;
|
||||
export let videoReady = false;
|
||||
export let videoShowing = false;
|
||||
export let videoReward = false;
|
||||
|
||||
export const _getPlatformName = function () {
|
||||
if (/(android)/i.test(navigator.userAgent)) {
|
||||
return 'android';
|
||||
} else {
|
||||
if (/(ipod|iphone|ipad)/i.test(navigator.userAgent)) {
|
||||
return 'ios';
|
||||
} else {
|
||||
return 'windowsPhone';
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Banner
|
||||
export const isBannerLoading = function () {
|
||||
return gdjs.adMob.bannerLoading;
|
||||
};
|
||||
export const isBannerReady = function () {
|
||||
// This block is needed because the banner event listeners bug
|
||||
if (gdjs.adMob.bannerAutoshow && gdjs.adMob.bannerReady) {
|
||||
gdjs.adMob.bannerReady = false;
|
||||
gdjs.adMob.bannerShowing = true;
|
||||
gdjs.adMob.bannerExists = true;
|
||||
}
|
||||
return gdjs.adMob.bannerReady;
|
||||
};
|
||||
export const isBannerShowing = function () {
|
||||
// This block is needed because the banner event listeners bug
|
||||
if (gdjs.adMob.bannerAutoshow && gdjs.adMob.bannerReady) {
|
||||
gdjs.adMob.bannerReady = false;
|
||||
gdjs.adMob.bannerShowing = true;
|
||||
gdjs.adMob.bannerExists = true;
|
||||
}
|
||||
return gdjs.adMob.bannerShowing;
|
||||
};
|
||||
export const existBanner = function () {
|
||||
// This block is needed because the banner event listeners bug
|
||||
if (gdjs.adMob.bannerAutoshow && gdjs.adMob.bannerReady) {
|
||||
gdjs.adMob.bannerReady = false;
|
||||
gdjs.adMob.bannerShowing = true;
|
||||
gdjs.adMob.bannerExists = true;
|
||||
}
|
||||
return gdjs.adMob.bannerExists;
|
||||
};
|
||||
export const loadBanner = function (
|
||||
androidID,
|
||||
iosID,
|
||||
atTop,
|
||||
overlap,
|
||||
displayOnLoading,
|
||||
testMode
|
||||
) {
|
||||
if (typeof admob === 'undefined') {
|
||||
return;
|
||||
}
|
||||
if (
|
||||
gdjs.adMob.bannerLoading ||
|
||||
gdjs.adMob.bannerReady ||
|
||||
gdjs.adMob.bannerExists
|
||||
) {
|
||||
return;
|
||||
}
|
||||
admob.banner.config({
|
||||
id:
|
||||
// Support Android & iOS
|
||||
gdjs.adMob._getPlatformName() === 'android' ? androidID : iosID,
|
||||
bannerAtTop: atTop,
|
||||
overlap: overlap,
|
||||
autoShow: displayOnLoading,
|
||||
isTesting: testMode,
|
||||
});
|
||||
admob.banner.prepare();
|
||||
gdjs.adMob.bannerLoading = true;
|
||||
gdjs.adMob.bannerReady = false;
|
||||
|
||||
// These lines are needed because the banner event listeners bug
|
||||
gdjs.adMob.bannerAutoshow = displayOnLoading;
|
||||
gdjs.adMob.bannerShowing = false;
|
||||
gdjs.adMob.bannerExists = false;
|
||||
};
|
||||
export const showBanner = function () {
|
||||
if (typeof admob === 'undefined') {
|
||||
return;
|
||||
}
|
||||
|
||||
// This block is needed because the banner event listeners bug
|
||||
if (gdjs.adMob.bannerReady) {
|
||||
gdjs.adMob.bannerReady = false;
|
||||
gdjs.adMob.bannerExists = true;
|
||||
}
|
||||
if (gdjs.adMob.bannerExists) {
|
||||
gdjs.adMob.bannerShowing = true;
|
||||
}
|
||||
admob.banner.show();
|
||||
};
|
||||
export const hideBanner = function () {
|
||||
if (typeof admob === 'undefined') {
|
||||
return;
|
||||
}
|
||||
if (gdjs.adMob.bannerExists) {
|
||||
gdjs.adMob.bannerShowing = false;
|
||||
}
|
||||
admob.banner.hide();
|
||||
};
|
||||
export const removeBanner = function () {
|
||||
if (typeof admob === 'undefined') {
|
||||
return;
|
||||
}
|
||||
|
||||
// These lines are needed because the banner event listeners bug
|
||||
gdjs.adMob.bannerExists = false;
|
||||
gdjs.adMob.bannerShowing = false;
|
||||
admob.banner.remove();
|
||||
};
|
||||
|
||||
// Interstitial
|
||||
export const isInterstitialLoading = function () {
|
||||
return gdjs.adMob.interstitialLoading;
|
||||
};
|
||||
export const isInterstitialReady = function () {
|
||||
return gdjs.adMob.interstitialReady;
|
||||
};
|
||||
export const isInterstitialShowing = function () {
|
||||
return gdjs.adMob.interstitialShowing;
|
||||
};
|
||||
export const loadInterstitial = function (
|
||||
androidID,
|
||||
iosID,
|
||||
displayOnLoading,
|
||||
testMode
|
||||
) {
|
||||
if (typeof admob === 'undefined') {
|
||||
return;
|
||||
}
|
||||
if (
|
||||
gdjs.adMob.interstitialLoading ||
|
||||
gdjs.adMob.interstitialReady ||
|
||||
gdjs.adMob.interstitialShowing
|
||||
) {
|
||||
return;
|
||||
}
|
||||
admob.interstitial.config({
|
||||
id:
|
||||
// Support Android & iOS
|
||||
gdjs.adMob._getPlatformName() === 'android' ? androidID : iosID,
|
||||
autoShow: displayOnLoading,
|
||||
isTesting: testMode,
|
||||
});
|
||||
admob.interstitial.prepare();
|
||||
gdjs.adMob.interstitialLoading = true;
|
||||
gdjs.adMob.interstitialReady = false;
|
||||
};
|
||||
export const showInterstitial = function () {
|
||||
if (typeof admob === 'undefined') {
|
||||
return;
|
||||
}
|
||||
admob.interstitial.show();
|
||||
};
|
||||
|
||||
// Reward video
|
||||
export const isVideoLoading = function () {
|
||||
return gdjs.adMob.videoLoading;
|
||||
};
|
||||
export const isVideoReady = function () {
|
||||
return gdjs.adMob.videoReady;
|
||||
};
|
||||
export const isVideoShowing = function () {
|
||||
return gdjs.adMob.videoShowing;
|
||||
};
|
||||
export const existVideoReward = function (markAsClaimed) {
|
||||
const reward = gdjs.adMob.videoReward;
|
||||
if (markAsClaimed) {
|
||||
gdjs.adMob.videoReward = false;
|
||||
}
|
||||
return reward;
|
||||
};
|
||||
export const loadVideo = function (
|
||||
androidID,
|
||||
iosID,
|
||||
displayOnLoading,
|
||||
testMode
|
||||
) {
|
||||
if (typeof admob === 'undefined') {
|
||||
return;
|
||||
}
|
||||
if (
|
||||
gdjs.adMob.videoLoading ||
|
||||
gdjs.adMob.videoReady ||
|
||||
gdjs.adMob.videoShowing
|
||||
) {
|
||||
return;
|
||||
}
|
||||
admob.rewardvideo.config({
|
||||
id:
|
||||
// Support Android & iOS
|
||||
gdjs.adMob._getPlatformName() === 'android' ? androidID : iosID,
|
||||
autoShow: displayOnLoading,
|
||||
isTesting: testMode,
|
||||
});
|
||||
admob.rewardvideo.prepare();
|
||||
gdjs.adMob.videoLoading = true;
|
||||
gdjs.adMob.videoReady = false;
|
||||
};
|
||||
export const showVideo = function () {
|
||||
if (typeof admob === 'undefined') {
|
||||
return;
|
||||
}
|
||||
admob.rewardvideo.show();
|
||||
};
|
||||
export const claimVideoReward = function () {
|
||||
gdjs.adMob.videoReward = false;
|
||||
};
|
||||
|
||||
// Banner event listeners
|
||||
document.addEventListener(
|
||||
'admob.banner.events.LOAD',
|
||||
function () {
|
||||
gdjs.adMob.bannerReady = true;
|
||||
gdjs.adMob.bannerLoading = false;
|
||||
},
|
||||
false
|
||||
);
|
||||
document.addEventListener(
|
||||
'admob.banner.events.LOAD_FAIL',
|
||||
function () {
|
||||
gdjs.adMob.bannerLoading = false;
|
||||
},
|
||||
false
|
||||
);
|
||||
|
||||
// BUG: These two never get called
|
||||
/*
|
||||
document.addEventListener(
|
||||
"admob.banner.events.OPEN",
|
||||
function() {
|
||||
gdjs.adMob.bannerExists = true;
|
||||
gdjs.adMob.bannerShowing = true;
|
||||
gdjs.adMob.bannerReady = false;
|
||||
},
|
||||
false
|
||||
);
|
||||
document.addEventListener(
|
||||
"admob.banner.events.CLOSE",
|
||||
function() {
|
||||
gdjs.adMob.bannerExists = false;
|
||||
gdjs.adMob.bannerShowing = false;
|
||||
},
|
||||
false
|
||||
);
|
||||
*/
|
||||
|
||||
// Interstitial event listeners
|
||||
document.addEventListener(
|
||||
'admob.interstitial.events.LOAD',
|
||||
function () {
|
||||
gdjs.adMob.interstitialReady = true;
|
||||
gdjs.adMob.interstitialLoading = false;
|
||||
},
|
||||
false
|
||||
);
|
||||
document.addEventListener(
|
||||
'admob.interstitial.events.LOAD_FAIL',
|
||||
function () {
|
||||
gdjs.adMob.interstitialLoading = false;
|
||||
},
|
||||
false
|
||||
);
|
||||
document.addEventListener(
|
||||
'admob.interstitial.events.OPEN',
|
||||
function () {
|
||||
gdjs.adMob.interstitialShowing = true;
|
||||
gdjs.adMob.interstitialReady = false;
|
||||
},
|
||||
false
|
||||
);
|
||||
document.addEventListener(
|
||||
'admob.interstitial.events.CLOSE',
|
||||
function () {
|
||||
gdjs.adMob.interstitialShowing = false;
|
||||
},
|
||||
false
|
||||
);
|
||||
|
||||
// Reward video event listeners
|
||||
document.addEventListener(
|
||||
'admob.rewardvideo.events.LOAD',
|
||||
function () {
|
||||
gdjs.adMob.videoReady = true;
|
||||
gdjs.adMob.videoLoading = false;
|
||||
},
|
||||
false
|
||||
);
|
||||
document.addEventListener(
|
||||
'admob.rewardvideo.events.LOAD_FAIL',
|
||||
function () {
|
||||
gdjs.adMob.videoLoading = false;
|
||||
},
|
||||
false
|
||||
);
|
||||
document.addEventListener(
|
||||
'admob.rewardvideo.events.OPEN',
|
||||
function () {
|
||||
gdjs.adMob.videoShowing = true;
|
||||
gdjs.adMob.videoReady = false;
|
||||
},
|
||||
false
|
||||
);
|
||||
document.addEventListener(
|
||||
'admob.rewardvideo.events.CLOSE',
|
||||
function () {
|
||||
gdjs.adMob.videoShowing = false;
|
||||
},
|
||||
false
|
||||
);
|
||||
document.addEventListener(
|
||||
'admob.rewardvideo.events.REWARD',
|
||||
function () {
|
||||
gdjs.adMob.videoReward = true;
|
||||
},
|
||||
false
|
||||
);
|
||||
}
|
||||
}
|
@@ -1,370 +0,0 @@
|
||||
// @ts-check
|
||||
/**
|
||||
* A set of wrappers around the Electron windowing APIs.
|
||||
* They don't have any effect on non Electron runtimes.
|
||||
*
|
||||
* Docstrings are only used for typing here, for proper
|
||||
* documentation check the electron docs at
|
||||
* https://www.electronjs.org/docs/api.
|
||||
*
|
||||
* @filedescriptor
|
||||
* @author arthuro555
|
||||
*/
|
||||
|
||||
/**
|
||||
* Tools to manipulate the game window positioning and
|
||||
* interactions with the operating system.
|
||||
* @namespace
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow = {
|
||||
/**
|
||||
* The game's BrowserWindow instance (or null on
|
||||
* non-electron platforms).
|
||||
* @type {?Object}
|
||||
*/
|
||||
electronBrowserWindow: null,
|
||||
};
|
||||
|
||||
// @ts-ignore
|
||||
if (typeof require === 'function') {
|
||||
// @ts-ignore
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow = require('electron').remote.getCurrentWindow();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {boolean} activate
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.focus = function (activate) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow) {
|
||||
if (activate) {
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.focus();
|
||||
} else {
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.blur();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {boolean}
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.isFocused = function () {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
return gdjs.evtTools.advancedWindow.electronBrowserWindow.isFocused();
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} activate
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.show = function (activate) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow) {
|
||||
if (activate) {
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.showInactive();
|
||||
} else {
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.hide();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {boolean}
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.isVisible = function () {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
return gdjs.evtTools.advancedWindow.electronBrowserWindow.isVisible();
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} activate
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.maximize = function (activate) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow) {
|
||||
if (activate) {
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.maximize();
|
||||
} else {
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.unmaximize();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {boolean}
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.isMaximized = function () {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
return gdjs.evtTools.advancedWindow.electronBrowserWindow.isMaximized();
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} activate
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.minimize = function (activate) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow) {
|
||||
if (activate) {
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.minimize();
|
||||
} else {
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.restore();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {boolean}
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.isMinimized = function () {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
return gdjs.evtTools.advancedWindow.electronBrowserWindow.isMinimized();
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} activate
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.enable = function (activate) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.setEnabled(activate);
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {boolean}
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.isEnabled = function () {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
return gdjs.evtTools.advancedWindow.electronBrowserWindow.isEnabled();
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} activate
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.setResizable = function (activate) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.setResizable(activate);
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {boolean}
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.isResizable = function () {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
return gdjs.evtTools.advancedWindow.electronBrowserWindow.isResizable();
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} activate
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.setMovable = function (activate) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.setMovable(activate);
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {boolean}
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.isMovable = function () {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
return gdjs.evtTools.advancedWindow.electronBrowserWindow.isMovable();
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} activate
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.setMaximizable = function (activate) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.setMaximizable(activate);
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {boolean}
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.isMaximizable = function () {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
return gdjs.evtTools.advancedWindow.electronBrowserWindow.isMaximizable();
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} activate
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.setMinimizable = function (activate) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.setMinimizable(activate);
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {boolean}
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.isMinimizable = function () {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
return gdjs.evtTools.advancedWindow.electronBrowserWindow.isMinimizable();
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} activate
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.setFullScreenable = function (activate) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.setFullScreenable(
|
||||
activate
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {boolean}
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.isFullScreenable = function () {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
return gdjs.evtTools.advancedWindow.electronBrowserWindow.isFullScreenable();
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} activate
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.setClosable = function (activate) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.setClosable(activate);
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {boolean}
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.isClosable = function () {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
return gdjs.evtTools.advancedWindow.electronBrowserWindow.isClosable();
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} activate
|
||||
* @param {"normal" | "floating" | "torn-off-menu" | "modal-panel" |"main-menu" | "status" | "pop-up-menu" | "screen-saver"} level
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.setAlwaysOnTop = function (activate, level) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.setAlwaysOnTop(
|
||||
activate,
|
||||
level
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {boolean}
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.isAlwaysOnTop = function () {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
return gdjs.evtTools.advancedWindow.electronBrowserWindow.isAlwaysOnTop();
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {number} x
|
||||
* @param {number} y
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.setPosition = function (x, y) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow) {
|
||||
// Convert x and y to (32 bit) integers to avoid Electron errors.
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.setPosition(~~x, ~~y);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {number}
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.getPositionX = function () {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow) {
|
||||
return gdjs.evtTools.advancedWindow.electronBrowserWindow.getPosition()[0];
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {number}
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.getPositionY = function () {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow) {
|
||||
return gdjs.evtTools.advancedWindow.electronBrowserWindow.getPosition()[1];
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} activate
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.setKiosk = function (activate) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.setKiosk(activate);
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {boolean}
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.isKiosk = function () {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
return gdjs.evtTools.advancedWindow.electronBrowserWindow.isKiosk();
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} activate
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.flash = function (activate) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.flashFrame(activate);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} activate
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.setHasShadow = function (activate) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.setHasShadow(activate);
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {boolean}
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.hasShadow = function () {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
return gdjs.evtTools.advancedWindow.electronBrowserWindow.hasShadow();
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {number} opacity
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.setOpacity = function (opacity) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.setOpacity(opacity);
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {number}
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.getOpacity = function () {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
return gdjs.evtTools.advancedWindow.electronBrowserWindow.getOpacity();
|
||||
return 1;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} activate
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.setContentProtection = function (activate) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.setContentProtection(
|
||||
activate
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} activate
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.setFocusable = function (activate) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.setFocusable(activate);
|
||||
};
|
245
Extensions/AdvancedWindow/electron-advancedwindowtools.ts
Normal file
245
Extensions/AdvancedWindow/electron-advancedwindowtools.ts
Normal file
@@ -0,0 +1,245 @@
|
||||
namespace gdjs {
|
||||
/**
|
||||
* Tools to manipulate the game window positioning and
|
||||
* interactions with the operating system.
|
||||
* @author arthuro555
|
||||
*/
|
||||
export namespace evtTools {
|
||||
export namespace advancedWindow {
|
||||
/**
|
||||
* The game's BrowserWindow instance (or null on
|
||||
* non-electron platforms).
|
||||
*/
|
||||
let electronBrowserWindow: any = null;
|
||||
|
||||
if (typeof require === 'function') {
|
||||
electronBrowserWindow = require('electron').remote.getCurrentWindow();
|
||||
}
|
||||
export const focus = function (activate: boolean) {
|
||||
if (electronBrowserWindow) {
|
||||
if (activate) {
|
||||
electronBrowserWindow.focus();
|
||||
} else {
|
||||
electronBrowserWindow.blur();
|
||||
}
|
||||
}
|
||||
};
|
||||
export const isFocused = function (): boolean {
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.isFocused();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
export const show = function (activate: boolean) {
|
||||
if (electronBrowserWindow) {
|
||||
if (activate) {
|
||||
electronBrowserWindow.showInactive();
|
||||
} else {
|
||||
electronBrowserWindow.hide();
|
||||
}
|
||||
}
|
||||
};
|
||||
export const isVisible = function (): boolean {
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.isVisible();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
export const maximize = function (activate: boolean) {
|
||||
if (electronBrowserWindow) {
|
||||
if (activate) {
|
||||
electronBrowserWindow.maximize();
|
||||
} else {
|
||||
electronBrowserWindow.unmaximize();
|
||||
}
|
||||
}
|
||||
};
|
||||
export const isMaximized = function (): boolean {
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.isMaximized();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
export const minimize = function (activate: boolean) {
|
||||
if (electronBrowserWindow) {
|
||||
if (activate) {
|
||||
electronBrowserWindow.minimize();
|
||||
} else {
|
||||
electronBrowserWindow.restore();
|
||||
}
|
||||
}
|
||||
};
|
||||
export const isMinimized = function (): boolean {
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.isMinimized();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
export const enable = function (activate: boolean) {
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.setEnabled(activate);
|
||||
}
|
||||
};
|
||||
export const isEnabled = function (): boolean {
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.isEnabled();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
export const setResizable = function (activate: boolean) {
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.setResizable(activate);
|
||||
}
|
||||
};
|
||||
export const isResizable = function (): boolean {
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.isResizable();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
export const setMovable = function (activate: boolean) {
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.setMovable(activate);
|
||||
}
|
||||
};
|
||||
export const isMovable = function (): boolean {
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.isMovable();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
export const setMaximizable = function (activate: boolean) {
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.setMaximizable(activate);
|
||||
}
|
||||
};
|
||||
export const isMaximizable = function (): boolean {
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.isMaximizable();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
export const setMinimizable = function (activate: boolean) {
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.setMinimizable(activate);
|
||||
}
|
||||
};
|
||||
export const isMinimizable = function (): boolean {
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.isMinimizable();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
export const setFullScreenable = function (activate: boolean) {
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.setFullScreenable(activate);
|
||||
}
|
||||
};
|
||||
export const isFullScreenable = function (): boolean {
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.isFullScreenable();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
export const setClosable = function (activate: boolean) {
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.setClosable(activate);
|
||||
}
|
||||
};
|
||||
export const isClosable = function (): boolean {
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.isClosable();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
export const setAlwaysOnTop = function (
|
||||
activate: boolean,
|
||||
level:
|
||||
| 'normal'
|
||||
| 'floating'
|
||||
| 'torn-off-menu'
|
||||
| 'modal-panel'
|
||||
| 'main-menu'
|
||||
| 'status'
|
||||
| 'pop-up-menu'
|
||||
| 'screen-saver'
|
||||
) {
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.setAlwaysOnTop(activate, level);
|
||||
}
|
||||
};
|
||||
export const isAlwaysOnTop = function (): boolean {
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.isAlwaysOnTop();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
export const setPosition = function (x: float, y: float) {
|
||||
if (electronBrowserWindow) {
|
||||
// Convert x and y to (32 bit) integers to avoid Electron errors.
|
||||
electronBrowserWindow.setPosition(~~x, ~~y);
|
||||
}
|
||||
};
|
||||
export const getPositionX = function (): number {
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.getPosition()[0];
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
export const getPositionY = function (): number {
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.getPosition()[1];
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
export const setKiosk = function (activate: boolean) {
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.setKiosk(activate);
|
||||
}
|
||||
};
|
||||
export const isKiosk = function (): boolean {
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.isKiosk();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
export const flash = function (activate: boolean) {
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.flashFrame(activate);
|
||||
}
|
||||
};
|
||||
export const setHasShadow = function (activate: boolean) {
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.setHasShadow(activate);
|
||||
}
|
||||
};
|
||||
export const hasShadow = function (): boolean {
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.hasShadow();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
export const setOpacity = function (opacity: float) {
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.setOpacity(opacity);
|
||||
}
|
||||
};
|
||||
export const getOpacity = function (): number {
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.getOpacity();
|
||||
}
|
||||
return 1;
|
||||
};
|
||||
export const setContentProtection = function (activate: boolean) {
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.setContentProtection(activate);
|
||||
}
|
||||
};
|
||||
export const setFocusable = function (activate: boolean) {
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.setFocusable(activate);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,182 +0,0 @@
|
||||
/**
|
||||
GDevelop - Anchor Behavior Extension
|
||||
Copyright (c) 2013-2016 Florian Rival (Florian.Rival@gmail.com)
|
||||
*/
|
||||
|
||||
/**
|
||||
* @class AnchorRuntimeBehavior
|
||||
* @constructor
|
||||
*/
|
||||
gdjs.AnchorRuntimeBehavior = function(runtimeScene, behaviorData, owner)
|
||||
{
|
||||
gdjs.RuntimeBehavior.call(this, runtimeScene, behaviorData, owner);
|
||||
|
||||
this._relativeToOriginalWindowSize = !!behaviorData.relativeToOriginalWindowSize;
|
||||
this._leftEdgeAnchor = behaviorData.leftEdgeAnchor;
|
||||
this._rightEdgeAnchor = behaviorData.rightEdgeAnchor;
|
||||
this._topEdgeAnchor = behaviorData.topEdgeAnchor;
|
||||
this._bottomEdgeAnchor = behaviorData.bottomEdgeAnchor;
|
||||
this._invalidDistances = true;
|
||||
this._leftEdgeDistance = 0;
|
||||
this._rightEdgeDistance = 0;
|
||||
this._topEdgeDistance = 0;
|
||||
this._bottomEdgeDistance = 0;
|
||||
};
|
||||
|
||||
gdjs.AnchorRuntimeBehavior.prototype = Object.create( gdjs.RuntimeBehavior.prototype );
|
||||
gdjs.registerBehavior("AnchorBehavior::AnchorBehavior", gdjs.AnchorRuntimeBehavior);
|
||||
|
||||
gdjs.AnchorRuntimeBehavior.HorizontalAnchor = {
|
||||
NONE: 0,
|
||||
WINDOW_LEFT: 1,
|
||||
WINDOW_RIGHT: 2,
|
||||
PROPORTIONAL: 3
|
||||
};
|
||||
|
||||
gdjs.AnchorRuntimeBehavior.VerticalAnchor = {
|
||||
NONE: 0,
|
||||
WINDOW_TOP: 1,
|
||||
WINDOW_BOTTOM: 2,
|
||||
PROPORTIONAL: 3
|
||||
};
|
||||
|
||||
gdjs.AnchorRuntimeBehavior.prototype.updateFromBehaviorData = function(oldBehaviorData, newBehaviorData) {
|
||||
if (oldBehaviorData.leftEdgeAnchor !== newBehaviorData.leftEdgeAnchor) {
|
||||
this._leftEdgeAnchor = newBehaviorData.leftEdgeAnchor;
|
||||
}
|
||||
if (oldBehaviorData.rightEdgeAnchor !== newBehaviorData.rightEdgeAnchor) {
|
||||
this._rightEdgeAnchor = newBehaviorData.rightEdgeAnchor;
|
||||
}
|
||||
if (oldBehaviorData.topEdgeAnchor !== newBehaviorData.topEdgeAnchor) {
|
||||
this._topEdgeAnchor = newBehaviorData.topEdgeAnchor;
|
||||
}
|
||||
if (oldBehaviorData.bottomEdgeAnchor !== newBehaviorData.bottomEdgeAnchor) {
|
||||
this._bottomEdgeAnchor = newBehaviorData.bottomEdgeAnchor;
|
||||
}
|
||||
if (oldBehaviorData.relativeToOriginalWindowSize !== newBehaviorData.relativeToOriginalWindowSize) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
gdjs.AnchorRuntimeBehavior.prototype.onActivate = function() {
|
||||
this._invalidDistances = true;
|
||||
};
|
||||
|
||||
gdjs.AnchorRuntimeBehavior.prototype.doStepPreEvents = function(runtimeScene) {
|
||||
var game = runtimeScene.getGame();
|
||||
var rendererWidth = game.getGameResolutionWidth();
|
||||
var rendererHeight = game.getGameResolutionHeight();
|
||||
var layer = runtimeScene.getLayer(this.owner.getLayer());
|
||||
|
||||
if(this._invalidDistances)
|
||||
{
|
||||
if (this._relativeToOriginalWindowSize) {
|
||||
rendererWidth = game.getOriginalWidth();
|
||||
rendererHeight = game.getOriginalHeight();
|
||||
}
|
||||
|
||||
//Calculate the distances from the window's bounds.
|
||||
var topLeftPixel = layer.convertCoords(
|
||||
this.owner.getDrawableX(),
|
||||
this.owner.getDrawableY()
|
||||
);
|
||||
|
||||
//Left edge
|
||||
if(this._leftEdgeAnchor === gdjs.AnchorRuntimeBehavior.HorizontalAnchor.WINDOW_LEFT)
|
||||
this._leftEdgeDistance = topLeftPixel[0];
|
||||
else if(this._leftEdgeAnchor === gdjs.AnchorRuntimeBehavior.HorizontalAnchor.WINDOW_RIGHT)
|
||||
this._leftEdgeDistance = rendererWidth - topLeftPixel[0];
|
||||
else if(this._leftEdgeAnchor === gdjs.AnchorRuntimeBehavior.HorizontalAnchor.PROPORTIONAL)
|
||||
this._leftEdgeDistance = topLeftPixel[0] / rendererWidth;
|
||||
|
||||
//Top edge
|
||||
if(this._topEdgeAnchor === gdjs.AnchorRuntimeBehavior.VerticalAnchor.WINDOW_TOP)
|
||||
this._topEdgeDistance = topLeftPixel[1];
|
||||
else if(this._topEdgeAnchor === gdjs.AnchorRuntimeBehavior.VerticalAnchor.WINDOW_BOTTOM)
|
||||
this._topEdgeDistance = rendererHeight - topLeftPixel[1];
|
||||
else if(this._topEdgeAnchor === gdjs.AnchorRuntimeBehavior.VerticalAnchor.PROPORTIONAL)
|
||||
this._topEdgeDistance = topLeftPixel[1] / rendererHeight;
|
||||
|
||||
var bottomRightPixel = layer.convertCoords(
|
||||
this.owner.getDrawableX() + this.owner.getWidth(),
|
||||
this.owner.getDrawableY() + this.owner.getHeight()
|
||||
);
|
||||
|
||||
//Right edge
|
||||
if(this._rightEdgeAnchor === gdjs.AnchorRuntimeBehavior.HorizontalAnchor.WINDOW_LEFT)
|
||||
this._rightEdgeDistance = bottomRightPixel[0];
|
||||
else if(this._rightEdgeAnchor === gdjs.AnchorRuntimeBehavior.HorizontalAnchor.WINDOW_RIGHT)
|
||||
this._rightEdgeDistance = rendererWidth - bottomRightPixel[0];
|
||||
else if(this._rightEdgeAnchor === gdjs.AnchorRuntimeBehavior.HorizontalAnchor.PROPORTIONAL)
|
||||
this._rightEdgeDistance = bottomRightPixel[0] / rendererWidth;
|
||||
|
||||
//Bottom edge
|
||||
if(this._bottomEdgeAnchor === gdjs.AnchorRuntimeBehavior.VerticalAnchor.WINDOW_TOP)
|
||||
this._bottomEdgeDistance = bottomRightPixel[1];
|
||||
else if(this._bottomEdgeAnchor === gdjs.AnchorRuntimeBehavior.VerticalAnchor.WINDOW_BOTTOM)
|
||||
this._bottomEdgeDistance = rendererHeight - bottomRightPixel[1];
|
||||
else if(this._bottomEdgeAnchor === gdjs.AnchorRuntimeBehavior.VerticalAnchor.PROPORTIONAL)
|
||||
this._bottomEdgeDistance = bottomRightPixel[1] / rendererHeight;
|
||||
|
||||
this._invalidDistances = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Move and resize the object if needed
|
||||
var leftPixel = 0;
|
||||
var topPixel = 0;
|
||||
|
||||
var rightPixel = 0;
|
||||
var bottomPixel = 0;
|
||||
|
||||
//Left edge
|
||||
if(this._leftEdgeAnchor === gdjs.AnchorRuntimeBehavior.HorizontalAnchor.WINDOW_LEFT)
|
||||
leftPixel = this._leftEdgeDistance;
|
||||
else if(this._leftEdgeAnchor === gdjs.AnchorRuntimeBehavior.HorizontalAnchor.WINDOW_RIGHT)
|
||||
leftPixel = rendererWidth - this._leftEdgeDistance;
|
||||
else if(this._leftEdgeAnchor === gdjs.AnchorRuntimeBehavior.HorizontalAnchor.PROPORTIONAL)
|
||||
leftPixel = this._leftEdgeDistance * rendererWidth;
|
||||
|
||||
//Top edge
|
||||
if(this._topEdgeAnchor === gdjs.AnchorRuntimeBehavior.VerticalAnchor.WINDOW_TOP)
|
||||
topPixel = this._topEdgeDistance;
|
||||
else if(this._topEdgeAnchor === gdjs.AnchorRuntimeBehavior.VerticalAnchor.WINDOW_BOTTOM)
|
||||
topPixel = rendererHeight - this._topEdgeDistance;
|
||||
else if(this._topEdgeAnchor === gdjs.AnchorRuntimeBehavior.VerticalAnchor.PROPORTIONAL)
|
||||
topPixel = this._topEdgeDistance * rendererHeight;
|
||||
|
||||
//Right edge
|
||||
if(this._rightEdgeAnchor === gdjs.AnchorRuntimeBehavior.HorizontalAnchor.WINDOW_LEFT)
|
||||
rightPixel = this._rightEdgeDistance;
|
||||
else if(this._rightEdgeAnchor === gdjs.AnchorRuntimeBehavior.HorizontalAnchor.WINDOW_RIGHT)
|
||||
rightPixel = rendererWidth - this._rightEdgeDistance;
|
||||
else if(this._rightEdgeAnchor === gdjs.AnchorRuntimeBehavior.HorizontalAnchor.PROPORTIONAL)
|
||||
rightPixel = this._rightEdgeDistance * rendererWidth;
|
||||
|
||||
//Bottom edge
|
||||
if(this._bottomEdgeAnchor === gdjs.AnchorRuntimeBehavior.VerticalAnchor.WINDOW_TOP)
|
||||
bottomPixel = this._bottomEdgeDistance;
|
||||
else if(this._bottomEdgeAnchor === gdjs.AnchorRuntimeBehavior.VerticalAnchor.WINDOW_BOTTOM)
|
||||
bottomPixel = rendererHeight - this._bottomEdgeDistance;
|
||||
else if(this._bottomEdgeAnchor === gdjs.AnchorRuntimeBehavior.VerticalAnchor.PROPORTIONAL)
|
||||
bottomPixel = this._bottomEdgeDistance * rendererHeight;
|
||||
|
||||
var topLeftCoord = layer.convertInverseCoords(leftPixel, topPixel);
|
||||
var bottomRightCoord = layer.convertInverseCoords(rightPixel, bottomPixel);
|
||||
|
||||
//Move and resize the object according to the anchors
|
||||
if(this._rightEdgeAnchor !== gdjs.AnchorRuntimeBehavior.HorizontalAnchor.NONE)
|
||||
this.owner.setWidth(bottomRightCoord[0] - topLeftCoord[0]);
|
||||
if(this._bottomEdgeAnchor !== gdjs.AnchorRuntimeBehavior.VerticalAnchor.NONE)
|
||||
this.owner.setHeight(bottomRightCoord[1] - topLeftCoord[1]);
|
||||
if(this._leftEdgeAnchor !== gdjs.AnchorRuntimeBehavior.HorizontalAnchor.NONE)
|
||||
this.owner.setX(topLeftCoord[0] + this.owner.getX() - this.owner.getDrawableX());
|
||||
if(this._topEdgeAnchor !== gdjs.AnchorRuntimeBehavior.VerticalAnchor.NONE)
|
||||
this.owner.setY(topLeftCoord[1] + this.owner.getY() - this.owner.getDrawableY());
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.AnchorRuntimeBehavior.prototype.doStepPostEvents = function(runtimeScene) {
|
||||
};
|
310
Extensions/AnchorBehavior/anchorruntimebehavior.ts
Normal file
310
Extensions/AnchorBehavior/anchorruntimebehavior.ts
Normal file
@@ -0,0 +1,310 @@
|
||||
/**
|
||||
GDevelop - Anchor Behavior Extension
|
||||
Copyright (c) 2013-2016 Florian Rival (Florian.Rival@gmail.com)
|
||||
*/
|
||||
|
||||
namespace gdjs {
|
||||
export class AnchorRuntimeBehavior extends gdjs.RuntimeBehavior {
|
||||
_relativeToOriginalWindowSize: any;
|
||||
_leftEdgeAnchor: any;
|
||||
_rightEdgeAnchor: any;
|
||||
_topEdgeAnchor: any;
|
||||
_bottomEdgeAnchor: any;
|
||||
_invalidDistances: boolean = true;
|
||||
_leftEdgeDistance: number = 0;
|
||||
_rightEdgeDistance: number = 0;
|
||||
_topEdgeDistance: number = 0;
|
||||
_bottomEdgeDistance: number = 0;
|
||||
|
||||
constructor(runtimeScene, behaviorData, owner) {
|
||||
super(runtimeScene, behaviorData, owner);
|
||||
this._relativeToOriginalWindowSize = !!behaviorData.relativeToOriginalWindowSize;
|
||||
this._leftEdgeAnchor = behaviorData.leftEdgeAnchor;
|
||||
this._rightEdgeAnchor = behaviorData.rightEdgeAnchor;
|
||||
this._topEdgeAnchor = behaviorData.topEdgeAnchor;
|
||||
this._bottomEdgeAnchor = behaviorData.bottomEdgeAnchor;
|
||||
}
|
||||
|
||||
updateFromBehaviorData(oldBehaviorData, newBehaviorData): boolean {
|
||||
if (oldBehaviorData.leftEdgeAnchor !== newBehaviorData.leftEdgeAnchor) {
|
||||
this._leftEdgeAnchor = newBehaviorData.leftEdgeAnchor;
|
||||
}
|
||||
if (oldBehaviorData.rightEdgeAnchor !== newBehaviorData.rightEdgeAnchor) {
|
||||
this._rightEdgeAnchor = newBehaviorData.rightEdgeAnchor;
|
||||
}
|
||||
if (oldBehaviorData.topEdgeAnchor !== newBehaviorData.topEdgeAnchor) {
|
||||
this._topEdgeAnchor = newBehaviorData.topEdgeAnchor;
|
||||
}
|
||||
if (
|
||||
oldBehaviorData.bottomEdgeAnchor !== newBehaviorData.bottomEdgeAnchor
|
||||
) {
|
||||
this._bottomEdgeAnchor = newBehaviorData.bottomEdgeAnchor;
|
||||
}
|
||||
if (
|
||||
oldBehaviorData.relativeToOriginalWindowSize !==
|
||||
newBehaviorData.relativeToOriginalWindowSize
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
onActivate() {
|
||||
this._invalidDistances = true;
|
||||
}
|
||||
|
||||
doStepPreEvents(runtimeScene) {
|
||||
const game = runtimeScene.getGame();
|
||||
let rendererWidth = game.getGameResolutionWidth();
|
||||
let rendererHeight = game.getGameResolutionHeight();
|
||||
const layer = runtimeScene.getLayer(this.owner.getLayer());
|
||||
if (this._invalidDistances) {
|
||||
if (this._relativeToOriginalWindowSize) {
|
||||
rendererWidth = game.getOriginalWidth();
|
||||
rendererHeight = game.getOriginalHeight();
|
||||
}
|
||||
|
||||
//Calculate the distances from the window's bounds.
|
||||
const topLeftPixel = layer.convertCoords(
|
||||
this.owner.getDrawableX(),
|
||||
this.owner.getDrawableY()
|
||||
);
|
||||
|
||||
//Left edge
|
||||
if (
|
||||
this._leftEdgeAnchor ===
|
||||
AnchorRuntimeBehavior.HorizontalAnchor.WINDOW_LEFT
|
||||
) {
|
||||
this._leftEdgeDistance = topLeftPixel[0];
|
||||
} else {
|
||||
if (
|
||||
this._leftEdgeAnchor ===
|
||||
AnchorRuntimeBehavior.HorizontalAnchor.WINDOW_RIGHT
|
||||
) {
|
||||
this._leftEdgeDistance = rendererWidth - topLeftPixel[0];
|
||||
} else {
|
||||
if (
|
||||
this._leftEdgeAnchor ===
|
||||
AnchorRuntimeBehavior.HorizontalAnchor.PROPORTIONAL
|
||||
) {
|
||||
this._leftEdgeDistance = topLeftPixel[0] / rendererWidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Top edge
|
||||
if (
|
||||
this._topEdgeAnchor ===
|
||||
AnchorRuntimeBehavior.VerticalAnchor.WINDOW_TOP
|
||||
) {
|
||||
this._topEdgeDistance = topLeftPixel[1];
|
||||
} else {
|
||||
if (
|
||||
this._topEdgeAnchor ===
|
||||
AnchorRuntimeBehavior.VerticalAnchor.WINDOW_BOTTOM
|
||||
) {
|
||||
this._topEdgeDistance = rendererHeight - topLeftPixel[1];
|
||||
} else {
|
||||
if (
|
||||
this._topEdgeAnchor ===
|
||||
AnchorRuntimeBehavior.VerticalAnchor.PROPORTIONAL
|
||||
) {
|
||||
this._topEdgeDistance = topLeftPixel[1] / rendererHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
const bottomRightPixel = layer.convertCoords(
|
||||
this.owner.getDrawableX() + this.owner.getWidth(),
|
||||
this.owner.getDrawableY() + this.owner.getHeight()
|
||||
);
|
||||
|
||||
//Right edge
|
||||
if (
|
||||
this._rightEdgeAnchor ===
|
||||
AnchorRuntimeBehavior.HorizontalAnchor.WINDOW_LEFT
|
||||
) {
|
||||
this._rightEdgeDistance = bottomRightPixel[0];
|
||||
} else {
|
||||
if (
|
||||
this._rightEdgeAnchor ===
|
||||
AnchorRuntimeBehavior.HorizontalAnchor.WINDOW_RIGHT
|
||||
) {
|
||||
this._rightEdgeDistance = rendererWidth - bottomRightPixel[0];
|
||||
} else {
|
||||
if (
|
||||
this._rightEdgeAnchor ===
|
||||
AnchorRuntimeBehavior.HorizontalAnchor.PROPORTIONAL
|
||||
) {
|
||||
this._rightEdgeDistance = bottomRightPixel[0] / rendererWidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Bottom edge
|
||||
if (
|
||||
this._bottomEdgeAnchor ===
|
||||
AnchorRuntimeBehavior.VerticalAnchor.WINDOW_TOP
|
||||
) {
|
||||
this._bottomEdgeDistance = bottomRightPixel[1];
|
||||
} else {
|
||||
if (
|
||||
this._bottomEdgeAnchor ===
|
||||
AnchorRuntimeBehavior.VerticalAnchor.WINDOW_BOTTOM
|
||||
) {
|
||||
this._bottomEdgeDistance = rendererHeight - bottomRightPixel[1];
|
||||
} else {
|
||||
if (
|
||||
this._bottomEdgeAnchor ===
|
||||
AnchorRuntimeBehavior.VerticalAnchor.PROPORTIONAL
|
||||
) {
|
||||
this._bottomEdgeDistance = bottomRightPixel[1] / rendererHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
this._invalidDistances = false;
|
||||
} else {
|
||||
//Move and resize the object if needed
|
||||
let leftPixel = 0;
|
||||
let topPixel = 0;
|
||||
let rightPixel = 0;
|
||||
let bottomPixel = 0;
|
||||
|
||||
//Left edge
|
||||
if (
|
||||
this._leftEdgeAnchor ===
|
||||
AnchorRuntimeBehavior.HorizontalAnchor.WINDOW_LEFT
|
||||
) {
|
||||
leftPixel = this._leftEdgeDistance;
|
||||
} else {
|
||||
if (
|
||||
this._leftEdgeAnchor ===
|
||||
AnchorRuntimeBehavior.HorizontalAnchor.WINDOW_RIGHT
|
||||
) {
|
||||
leftPixel = rendererWidth - this._leftEdgeDistance;
|
||||
} else {
|
||||
if (
|
||||
this._leftEdgeAnchor ===
|
||||
AnchorRuntimeBehavior.HorizontalAnchor.PROPORTIONAL
|
||||
) {
|
||||
leftPixel = this._leftEdgeDistance * rendererWidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Top edge
|
||||
if (
|
||||
this._topEdgeAnchor ===
|
||||
AnchorRuntimeBehavior.VerticalAnchor.WINDOW_TOP
|
||||
) {
|
||||
topPixel = this._topEdgeDistance;
|
||||
} else {
|
||||
if (
|
||||
this._topEdgeAnchor ===
|
||||
AnchorRuntimeBehavior.VerticalAnchor.WINDOW_BOTTOM
|
||||
) {
|
||||
topPixel = rendererHeight - this._topEdgeDistance;
|
||||
} else {
|
||||
if (
|
||||
this._topEdgeAnchor ===
|
||||
AnchorRuntimeBehavior.VerticalAnchor.PROPORTIONAL
|
||||
) {
|
||||
topPixel = this._topEdgeDistance * rendererHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Right edge
|
||||
if (
|
||||
this._rightEdgeAnchor ===
|
||||
AnchorRuntimeBehavior.HorizontalAnchor.WINDOW_LEFT
|
||||
) {
|
||||
rightPixel = this._rightEdgeDistance;
|
||||
} else {
|
||||
if (
|
||||
this._rightEdgeAnchor ===
|
||||
AnchorRuntimeBehavior.HorizontalAnchor.WINDOW_RIGHT
|
||||
) {
|
||||
rightPixel = rendererWidth - this._rightEdgeDistance;
|
||||
} else {
|
||||
if (
|
||||
this._rightEdgeAnchor ===
|
||||
AnchorRuntimeBehavior.HorizontalAnchor.PROPORTIONAL
|
||||
) {
|
||||
rightPixel = this._rightEdgeDistance * rendererWidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Bottom edge
|
||||
if (
|
||||
this._bottomEdgeAnchor ===
|
||||
AnchorRuntimeBehavior.VerticalAnchor.WINDOW_TOP
|
||||
) {
|
||||
bottomPixel = this._bottomEdgeDistance;
|
||||
} else {
|
||||
if (
|
||||
this._bottomEdgeAnchor ===
|
||||
AnchorRuntimeBehavior.VerticalAnchor.WINDOW_BOTTOM
|
||||
) {
|
||||
bottomPixel = rendererHeight - this._bottomEdgeDistance;
|
||||
} else {
|
||||
if (
|
||||
this._bottomEdgeAnchor ===
|
||||
AnchorRuntimeBehavior.VerticalAnchor.PROPORTIONAL
|
||||
) {
|
||||
bottomPixel = this._bottomEdgeDistance * rendererHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
const topLeftCoord = layer.convertInverseCoords(leftPixel, topPixel);
|
||||
const bottomRightCoord = layer.convertInverseCoords(
|
||||
rightPixel,
|
||||
bottomPixel
|
||||
);
|
||||
|
||||
//Move and resize the object according to the anchors
|
||||
if (
|
||||
this._rightEdgeAnchor !== AnchorRuntimeBehavior.HorizontalAnchor.NONE
|
||||
) {
|
||||
this.owner.setWidth(bottomRightCoord[0] - topLeftCoord[0]);
|
||||
}
|
||||
if (
|
||||
this._bottomEdgeAnchor !== AnchorRuntimeBehavior.VerticalAnchor.NONE
|
||||
) {
|
||||
this.owner.setHeight(bottomRightCoord[1] - topLeftCoord[1]);
|
||||
}
|
||||
if (
|
||||
this._leftEdgeAnchor !== AnchorRuntimeBehavior.HorizontalAnchor.NONE
|
||||
) {
|
||||
this.owner.setX(
|
||||
topLeftCoord[0] + this.owner.getX() - this.owner.getDrawableX()
|
||||
);
|
||||
}
|
||||
if (this._topEdgeAnchor !== AnchorRuntimeBehavior.VerticalAnchor.NONE) {
|
||||
this.owner.setY(
|
||||
topLeftCoord[1] + this.owner.getY() - this.owner.getDrawableY()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
doStepPostEvents(runtimeScene) {}
|
||||
|
||||
static HorizontalAnchor = {
|
||||
NONE: 0,
|
||||
WINDOW_LEFT: 1,
|
||||
WINDOW_RIGHT: 2,
|
||||
PROPORTIONAL: 3,
|
||||
};
|
||||
static VerticalAnchor = {
|
||||
NONE: 0,
|
||||
WINDOW_TOP: 1,
|
||||
WINDOW_BOTTOM: 2,
|
||||
PROPORTIONAL: 3,
|
||||
};
|
||||
}
|
||||
gdjs.registerBehavior(
|
||||
'AnchorBehavior::AnchorBehavior',
|
||||
gdjs.AnchorRuntimeBehavior
|
||||
);
|
||||
}
|
@@ -1,122 +0,0 @@
|
||||
/**
|
||||
* The PIXI.js renderer for the BBCode Text runtime object.
|
||||
*
|
||||
* @class BBTextRuntimeObjectPixiRenderer
|
||||
* @constructor
|
||||
* @param {gdjs.BBTextRuntimeObject} runtimeObject The object to render
|
||||
* @param {gdjs.RuntimeScene} runtimeScene The gdjs.RuntimeScene in which the object is
|
||||
*/
|
||||
gdjs.BBTextRuntimeObjectPixiRenderer = function (runtimeObject, runtimeScene) {
|
||||
this._object = runtimeObject;
|
||||
|
||||
// Load (or reset) the text
|
||||
if (this._pixiObject === undefined) {
|
||||
this._pixiObject = new MultiStyleText(runtimeObject._text, {
|
||||
default: {
|
||||
fontFamily: runtimeScene
|
||||
.getGame()
|
||||
.getFontManager()
|
||||
.getFontFamily(runtimeObject._fontFamily),
|
||||
fontSize: runtimeObject._fontSize + 'px',
|
||||
fill: gdjs.rgbToHexNumber(
|
||||
runtimeObject._color[0],
|
||||
runtimeObject._color[1],
|
||||
runtimeObject._color[2]
|
||||
),
|
||||
tagStyle: 'bbcode',
|
||||
wordWrap: runtimeObject._wordWrap,
|
||||
wordWrapWidth: runtimeObject._wrappingWidth,
|
||||
align: runtimeObject._align,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
this.updateColor();
|
||||
this.updateAlignment();
|
||||
this.updateFontFamily();
|
||||
this.updateFontSize();
|
||||
}
|
||||
|
||||
runtimeScene
|
||||
.getLayer('')
|
||||
.getRenderer()
|
||||
.addRendererObject(this._pixiObject, runtimeObject.getZOrder());
|
||||
|
||||
// Set the anchor in the center, so that the object rotates around
|
||||
// its center
|
||||
this._pixiObject.anchor.x = 0.5;
|
||||
this._pixiObject.anchor.y = 0.5;
|
||||
|
||||
this.updateText();
|
||||
this.updatePosition();
|
||||
this.updateAngle();
|
||||
this.updateOpacity();
|
||||
};
|
||||
|
||||
gdjs.BBTextRuntimeObjectRenderer = gdjs.BBTextRuntimeObjectPixiRenderer;
|
||||
|
||||
gdjs.BBTextRuntimeObjectPixiRenderer.prototype.getRendererObject = function () {
|
||||
return this._pixiObject;
|
||||
};
|
||||
|
||||
gdjs.BBTextRuntimeObjectPixiRenderer.prototype.updateWordWrap = function () {
|
||||
this._pixiObject._style.wordWrap = this._object._wordWrap;
|
||||
this._pixiObject.dirty = true;
|
||||
this.updatePosition();
|
||||
};
|
||||
|
||||
gdjs.BBTextRuntimeObjectPixiRenderer.prototype.updateWrappingWidth = function () {
|
||||
this._pixiObject._style.wordWrapWidth = this._object._wrappingWidth;
|
||||
this._pixiObject.dirty = true;
|
||||
this.updatePosition();
|
||||
};
|
||||
|
||||
gdjs.BBTextRuntimeObjectPixiRenderer.prototype.updateText = function () {
|
||||
this._pixiObject.text = this._object._text;
|
||||
this.updatePosition();
|
||||
};
|
||||
|
||||
gdjs.BBTextRuntimeObjectPixiRenderer.prototype.updateColor = function () {
|
||||
this._pixiObject.textStyles.default.fill = gdjs.rgbToHexNumber(
|
||||
this._object._color[0],
|
||||
this._object._color[1],
|
||||
this._object._color[2]
|
||||
);
|
||||
this._pixiObject.dirty = true;
|
||||
};
|
||||
|
||||
gdjs.BBTextRuntimeObjectPixiRenderer.prototype.updateAlignment = function () {
|
||||
this._pixiObject._style.align = this._object._align;
|
||||
this._pixiObject.dirty = true;
|
||||
};
|
||||
gdjs.BBTextRuntimeObjectPixiRenderer.prototype.updateFontFamily = function () {
|
||||
this._pixiObject.textStyles.default.fontFamily = this._object._runtimeScene
|
||||
.getGame()
|
||||
.getFontManager()
|
||||
.getFontFamily(this._object._fontFamily);
|
||||
this._pixiObject.dirty = true;
|
||||
};
|
||||
gdjs.BBTextRuntimeObjectPixiRenderer.prototype.updateFontSize = function () {
|
||||
this._pixiObject.textStyles.default.fontSize = this._object._fontSize + 'px';
|
||||
this._pixiObject.dirty = true;
|
||||
};
|
||||
|
||||
gdjs.BBTextRuntimeObjectPixiRenderer.prototype.updatePosition = function () {
|
||||
this._pixiObject.position.x = this._object.x + this._pixiObject.width / 2;
|
||||
this._pixiObject.position.y = this._object.y + this._pixiObject.height / 2;
|
||||
};
|
||||
|
||||
gdjs.BBTextRuntimeObjectPixiRenderer.prototype.updateAngle = function () {
|
||||
this._pixiObject.rotation = gdjs.toRad(this._object.angle);
|
||||
};
|
||||
|
||||
gdjs.BBTextRuntimeObjectPixiRenderer.prototype.updateOpacity = function () {
|
||||
this._pixiObject.alpha = this._object._opacity / 255;
|
||||
};
|
||||
|
||||
gdjs.BBTextRuntimeObjectPixiRenderer.prototype.getWidth = function () {
|
||||
return this._pixiObject.width;
|
||||
};
|
||||
|
||||
gdjs.BBTextRuntimeObjectPixiRenderer.prototype.getHeight = function () {
|
||||
return this._pixiObject.height;
|
||||
};
|
136
Extensions/BBText/bbtextruntimeobject-pixi-renderer.ts
Normal file
136
Extensions/BBText/bbtextruntimeobject-pixi-renderer.ts
Normal file
@@ -0,0 +1,136 @@
|
||||
declare var MultiStyleText: any;
|
||||
|
||||
namespace gdjs {
|
||||
/**
|
||||
* The PIXI.js renderer for the BBCode Text runtime object.
|
||||
*/
|
||||
export class BBTextRuntimeObjectPixiRenderer {
|
||||
_object: gdjs.BBTextRuntimeObject;
|
||||
_pixiObject: any;
|
||||
|
||||
/**
|
||||
* @param runtimeObject The object to render
|
||||
* @param runtimeScene The gdjs.RuntimeScene in which the object is
|
||||
*/
|
||||
constructor(
|
||||
runtimeObject: gdjs.BBTextRuntimeObject,
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
) {
|
||||
this._object = runtimeObject;
|
||||
|
||||
// Load (or reset) the text
|
||||
if (this._pixiObject === undefined) {
|
||||
this._pixiObject = new MultiStyleText(runtimeObject._text, {
|
||||
default: {
|
||||
fontFamily: runtimeScene
|
||||
.getGame()
|
||||
.getFontManager()
|
||||
.getFontFamily(runtimeObject._fontFamily),
|
||||
fontSize: runtimeObject._fontSize + 'px',
|
||||
fill: gdjs.rgbToHexNumber(
|
||||
runtimeObject._color[0],
|
||||
runtimeObject._color[1],
|
||||
runtimeObject._color[2]
|
||||
),
|
||||
tagStyle: 'bbcode',
|
||||
wordWrap: runtimeObject._wordWrap,
|
||||
wordWrapWidth: runtimeObject._wrappingWidth,
|
||||
align: runtimeObject._align,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
this.updateColor();
|
||||
this.updateAlignment();
|
||||
this.updateFontFamily();
|
||||
this.updateFontSize();
|
||||
}
|
||||
runtimeScene
|
||||
.getLayer('')
|
||||
.getRenderer()
|
||||
.addRendererObject(this._pixiObject, runtimeObject.getZOrder());
|
||||
|
||||
// Set the anchor in the center, so that the object rotates around
|
||||
// its center
|
||||
this._pixiObject.anchor.x = 0.5;
|
||||
this._pixiObject.anchor.y = 0.5;
|
||||
this.updateText();
|
||||
this.updatePosition();
|
||||
this.updateAngle();
|
||||
this.updateOpacity();
|
||||
}
|
||||
|
||||
getRendererObject() {
|
||||
return this._pixiObject;
|
||||
}
|
||||
|
||||
updateWordWrap(): void {
|
||||
this._pixiObject._style.wordWrap = this._object._wordWrap;
|
||||
this._pixiObject.dirty = true;
|
||||
this.updatePosition();
|
||||
}
|
||||
|
||||
updateWrappingWidth(): void {
|
||||
this._pixiObject._style.wordWrapWidth = this._object._wrappingWidth;
|
||||
this._pixiObject.dirty = true;
|
||||
this.updatePosition();
|
||||
}
|
||||
|
||||
updateText(): void {
|
||||
this._pixiObject.text = this._object._text;
|
||||
this.updatePosition();
|
||||
}
|
||||
|
||||
updateColor(): void {
|
||||
this._pixiObject.textStyles.default.fill = gdjs.rgbToHexNumber(
|
||||
this._object._color[0],
|
||||
this._object._color[1],
|
||||
this._object._color[2]
|
||||
);
|
||||
this._pixiObject.dirty = true;
|
||||
}
|
||||
|
||||
updateAlignment(): void {
|
||||
this._pixiObject._style.align = this._object._align;
|
||||
this._pixiObject.dirty = true;
|
||||
}
|
||||
|
||||
updateFontFamily(): void {
|
||||
this._pixiObject.textStyles.default.fontFamily = this._object._runtimeScene
|
||||
.getGame()
|
||||
.getFontManager()
|
||||
.getFontFamily(this._object._fontFamily);
|
||||
this._pixiObject.dirty = true;
|
||||
}
|
||||
|
||||
updateFontSize(): void {
|
||||
this._pixiObject.textStyles.default.fontSize =
|
||||
this._object._fontSize + 'px';
|
||||
this._pixiObject.dirty = true;
|
||||
}
|
||||
|
||||
updatePosition(): void {
|
||||
this._pixiObject.position.x = this._object.x + this._pixiObject.width / 2;
|
||||
this._pixiObject.position.y =
|
||||
this._object.y + this._pixiObject.height / 2;
|
||||
}
|
||||
|
||||
updateAngle(): void {
|
||||
this._pixiObject.rotation = gdjs.toRad(this._object.angle);
|
||||
}
|
||||
|
||||
updateOpacity(): void {
|
||||
this._pixiObject.alpha = this._object._opacity / 255;
|
||||
}
|
||||
|
||||
getWidth(): float {
|
||||
return this._pixiObject.width;
|
||||
}
|
||||
|
||||
getHeight(): float {
|
||||
return this._pixiObject.height;
|
||||
}
|
||||
}
|
||||
|
||||
export const BBTextRuntimeObjectRenderer = BBTextRuntimeObjectPixiRenderer;
|
||||
export type BBTextRuntimeObjectRenderer = BBTextRuntimeObjectPixiRenderer;
|
||||
}
|
@@ -1,264 +0,0 @@
|
||||
/**
|
||||
* @typedef {Object} BBTextObjectDataType Base parameters for {@link gdjs.BBTextRuntimeObject}
|
||||
* @property {Object} content The base parameters of the BBText
|
||||
* @property {number} content.opacity The opacity of the BBText
|
||||
* @property {boolean} content.visible Deprecated - Is the text visible?
|
||||
* @property {string} content.text Content of the text
|
||||
* @property {string} content.color The color of the text
|
||||
* @property {string} content.fontFamily The font of the text
|
||||
* @property {number} content.fontSize The size of the text
|
||||
* @property {boolean} content.wordWrap Activate word wrap if set to true
|
||||
* @property {'left'|'center'|'right'} content.align Alignment of the text: "left", "center" or "right"
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {ObjectData & BBTextObjectDataType} BBTextObjectData
|
||||
*/
|
||||
|
||||
/**
|
||||
* Displays a rich text using BBCode markup (allowing to set parts of the text as bold, italic, use different colors and shadows).
|
||||
* @memberof gdjs
|
||||
* @class BBTextRuntimeObject
|
||||
* @extends RuntimeObject
|
||||
* @param {gdjs.RuntimeScene} runtimeScene The {@link gdjs.RuntimeScene} the object belongs to
|
||||
* @param {BBTextObjectData} objectData The object data used to initialize the object
|
||||
*/
|
||||
gdjs.BBTextRuntimeObject = function(runtimeScene, objectData) {
|
||||
gdjs.RuntimeObject.call(this, runtimeScene, objectData);
|
||||
|
||||
/** @type {number} */
|
||||
this._opacity = parseFloat(objectData.content.opacity);
|
||||
// parseFloat should not be required, but GDevelop 5.0 beta 92 and below were storing it as a string.
|
||||
/** @type {string} */
|
||||
this._text = objectData.content.text;
|
||||
/** @type {number[]} color in format [r, g, b], where each component is in the range [0, 255] */
|
||||
this._color = gdjs.BBTextRuntimeObject.hexToRGBColor(objectData.content.color);
|
||||
/** @type {string} */
|
||||
this._fontFamily = objectData.content.fontFamily;
|
||||
/** @type {number} */
|
||||
this._fontSize = parseFloat(objectData.content.fontSize);
|
||||
// parseFloat should not be required, but GDevelop 5.0 beta 92 and below were storing it as a string.
|
||||
/** @type {boolean} */
|
||||
this._wordWrap = objectData.content.wordWrap;
|
||||
/** @type {number} */
|
||||
this._wrappingWidth = 250; // This value is the default wrapping width of the runtime object.
|
||||
/** @type {string} */
|
||||
this._align = objectData.content.align;
|
||||
|
||||
if (this._renderer)
|
||||
gdjs.BBTextRuntimeObjectRenderer.call(this._renderer, this, runtimeScene);
|
||||
else
|
||||
this._renderer = new gdjs.BBTextRuntimeObjectRenderer(this, runtimeScene);
|
||||
|
||||
// While this should rather be exposed as a property for all objects, honor the "visible"
|
||||
// property that is specific to this object.
|
||||
this.hidden = !objectData.content.visible;
|
||||
|
||||
// *ALWAYS* call `this.onCreated()` at the very end of your object constructor.
|
||||
this.onCreated();
|
||||
};
|
||||
|
||||
gdjs.BBTextRuntimeObject.prototype = Object.create(
|
||||
gdjs.RuntimeObject.prototype
|
||||
);
|
||||
gdjs.registerObject('BBText::BBText', gdjs.BBTextRuntimeObject);
|
||||
|
||||
gdjs.BBTextRuntimeObject.hexToRGBColor = function (hex) {
|
||||
var hexNumber = parseInt(hex.replace('#', ''), 16);
|
||||
return [(hexNumber >> 16) & 0xff, (hexNumber >> 8) & 0xff, hexNumber & 0xff];
|
||||
};
|
||||
|
||||
gdjs.BBTextRuntimeObject.prototype.getRendererObject = function() {
|
||||
return this._renderer.getRendererObject();
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {BBTextObjectDataType} oldObjectData
|
||||
* @param {BBTextObjectDataType} newObjectData
|
||||
*/
|
||||
gdjs.BBTextRuntimeObject.prototype.updateFromObjectData = function(oldObjectData, newObjectData) {
|
||||
if (oldObjectData.content.opacity !== newObjectData.content.opacity) {
|
||||
this.setOpacity(newObjectData.content.opacity);
|
||||
}
|
||||
if (oldObjectData.content.visible !== newObjectData.content.visible) {
|
||||
this.hide(!newObjectData.content.visible);
|
||||
}
|
||||
if (oldObjectData.content.text !== newObjectData.content.text) {
|
||||
this.setBBText(newObjectData.content.text);
|
||||
}
|
||||
if (oldObjectData.content.color !== newObjectData.content.color) {
|
||||
this._color = gdjs.BBTextRuntimeObject.hexToRGBColor(newObjectData.content.color);
|
||||
this._renderer.updateColor();
|
||||
}
|
||||
if (oldObjectData.content.fontFamily !== newObjectData.content.fontFamily) {
|
||||
this.setFontFamily(newObjectData.content.fontFamily);
|
||||
}
|
||||
if (oldObjectData.content.fontSize !== newObjectData.content.fontSize) {
|
||||
this.setFontSize(newObjectData.content.fontSize);
|
||||
}
|
||||
if (oldObjectData.content.wordWrap !== newObjectData.content.wordWrap) {
|
||||
this.setWordWrap(newObjectData.content.wordWrap);
|
||||
}
|
||||
if (oldObjectData.content.align !== newObjectData.content.align) {
|
||||
this.setAlignment(newObjectData.content.align);
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize the extra parameters that could be set for an instance.
|
||||
* @private
|
||||
*/
|
||||
gdjs.BBTextRuntimeObject.prototype.extraInitializationFromInitialInstance = function(initialInstanceData) {
|
||||
if (initialInstanceData.customSize)
|
||||
this.setWrappingWidth(initialInstanceData.width);
|
||||
else
|
||||
this.setWrappingWidth(250); // This value is the default wrapping width of the runtime object.
|
||||
};
|
||||
|
||||
gdjs.BBTextRuntimeObject.prototype.onDestroyFromScene = function(runtimeScene) {
|
||||
gdjs.RuntimeObject.prototype.onDestroyFromScene.call(this, runtimeScene);
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the markup text to display.
|
||||
*/
|
||||
gdjs.BBTextRuntimeObject.prototype.setBBText = function(text) {
|
||||
this._text = text;
|
||||
this._renderer.updateText();
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the markup text displayed by the object.
|
||||
*/
|
||||
gdjs.BBTextRuntimeObject.prototype.getBBText = function() {
|
||||
return this._text;
|
||||
};
|
||||
|
||||
gdjs.BBTextRuntimeObject.prototype.setColor = function(rgbColorString) {
|
||||
const splitValue = rgbColorString.split(';');
|
||||
if (splitValue.length !== 3) return;
|
||||
|
||||
this._color[0] = parseInt(splitValue[0], 10);
|
||||
this._color[1] = parseInt(splitValue[1], 10);
|
||||
this._color[2] = parseInt(splitValue[2], 10);
|
||||
this._renderer.updateColor();
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the base color.
|
||||
* @return {string} The color as a "R;G;B" string, for example: "255;0;0"
|
||||
*/
|
||||
gdjs.BBTextRuntimeObject.prototype.getColor = function() {
|
||||
return this._color[0] + ";" + this._color[1] + ";" + this._color[2];
|
||||
};
|
||||
|
||||
gdjs.BBTextRuntimeObject.prototype.setFontSize = function(fontSize) {
|
||||
this._fontSize = fontSize;
|
||||
this._renderer.updateFontSize();
|
||||
};
|
||||
|
||||
gdjs.BBTextRuntimeObject.prototype.getFontSize = function() {
|
||||
return this._fontSize;
|
||||
};
|
||||
|
||||
gdjs.BBTextRuntimeObject.prototype.setFontFamily = function(fontFamily) {
|
||||
this._fontFamily = fontFamily;
|
||||
this._renderer.updateFontFamily();
|
||||
};
|
||||
|
||||
gdjs.BBTextRuntimeObject.prototype.getFontFamily = function() {
|
||||
return this._fontFamily;
|
||||
};
|
||||
|
||||
gdjs.BBTextRuntimeObject.prototype.setAlignment = function(align) {
|
||||
this._align = align;
|
||||
this._renderer.updateAlignment();
|
||||
};
|
||||
|
||||
gdjs.BBTextRuntimeObject.prototype.getAlignment = function() {
|
||||
return this._align;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set object position on X axis.
|
||||
* @param {number} x The new position X of the object.
|
||||
*/
|
||||
gdjs.BBTextRuntimeObject.prototype.setX = function(x) {
|
||||
gdjs.RuntimeObject.prototype.setX.call(this, x);
|
||||
this._renderer.updatePosition();
|
||||
};
|
||||
|
||||
/**
|
||||
* Set object position on Y axis.
|
||||
* @param {number} y The new position Y of the object.
|
||||
*/
|
||||
gdjs.BBTextRuntimeObject.prototype.setY = function(y) {
|
||||
gdjs.RuntimeObject.prototype.setY.call(this, y);
|
||||
this._renderer.updatePosition();
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the angle of the object.
|
||||
* @param {number} angle The new angle of the object.
|
||||
*/
|
||||
gdjs.BBTextRuntimeObject.prototype.setAngle = function(angle) {
|
||||
gdjs.RuntimeObject.prototype.setAngle.call(this, angle);
|
||||
this._renderer.updateAngle();
|
||||
};
|
||||
|
||||
/**
|
||||
* Set object opacity.
|
||||
* @param {number} opacity The new opacity of the object (0-255).
|
||||
*/
|
||||
gdjs.BBTextRuntimeObject.prototype.setOpacity = function(opacity) {
|
||||
this._opacity = opacity;
|
||||
this._renderer.updateOpacity();
|
||||
};
|
||||
|
||||
/**
|
||||
* Get object opacity.
|
||||
*/
|
||||
gdjs.BBTextRuntimeObject.prototype.getOpacity = function() {
|
||||
return this._opacity;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the width.
|
||||
* @param {number} width The new width in pixels.
|
||||
*/
|
||||
gdjs.BBTextRuntimeObject.prototype.setWrappingWidth = function(width) {
|
||||
this._wrappingWidth = width;
|
||||
this._renderer.updateWrappingWidth();
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the wrapping width of the object.
|
||||
*/
|
||||
gdjs.BBTextRuntimeObject.prototype.getWrappingWidth = function() {
|
||||
return this._wrappingWidth;
|
||||
};
|
||||
|
||||
gdjs.BBTextRuntimeObject.prototype.setWordWrap = function(wordWrap) {
|
||||
this._wordWrap = wordWrap;
|
||||
this._renderer.updateWordWrap();
|
||||
};
|
||||
|
||||
gdjs.BBTextRuntimeObject.prototype.getWordWrap = function(wordWrap) {
|
||||
return this._wordWrap;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the width of the object.
|
||||
*/
|
||||
gdjs.BBTextRuntimeObject.prototype.getWidth = function() {
|
||||
return this._renderer.getWidth();
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the height of the object.
|
||||
*/
|
||||
gdjs.BBTextRuntimeObject.prototype.getHeight = function() {
|
||||
return this._renderer.getHeight();
|
||||
};
|
281
Extensions/BBText/bbtextruntimeobject.ts
Normal file
281
Extensions/BBText/bbtextruntimeobject.ts
Normal file
@@ -0,0 +1,281 @@
|
||||
namespace gdjs {
|
||||
/** Base parameters for {@link gdjs.BBTextRuntimeObject} */
|
||||
export type BBTextObjectDataType = {
|
||||
/** The base parameters of the BBText */
|
||||
content: {
|
||||
/** The opacity of the BBText */
|
||||
opacity: number;
|
||||
/** Deprecated - Is the text visible? */
|
||||
visible: boolean;
|
||||
/** Content of the text */
|
||||
text: string;
|
||||
/** The color of the text */
|
||||
color: string;
|
||||
/** The font of the text */
|
||||
fontFamily: string;
|
||||
/** The size of the text */
|
||||
fontSize: number;
|
||||
/** Activate word wrap if set to true */
|
||||
wordWrap: boolean;
|
||||
/** Alignment of the text: "left", "center" or "right" */
|
||||
align: 'left' | 'center' | 'right';
|
||||
};
|
||||
};
|
||||
export type BBTextObjectData = ObjectData & BBTextObjectDataType;
|
||||
|
||||
/**
|
||||
* Displays a rich text using BBCode markup (allowing to set parts of the text as bold, italic, use different colors and shadows).
|
||||
*/
|
||||
export class BBTextRuntimeObject extends gdjs.RuntimeObject {
|
||||
_opacity: float;
|
||||
|
||||
_text: string;
|
||||
|
||||
/** color in format [r, g, b], where each component is in the range [0, 255] */
|
||||
_color: integer[];
|
||||
_fontFamily: string;
|
||||
_fontSize: number;
|
||||
|
||||
_wordWrap: boolean;
|
||||
_wrappingWidth: float = 250;
|
||||
|
||||
// This value is the default wrapping width of the runtime object.
|
||||
_align: string;
|
||||
_renderer: gdjs.BBTextRuntimeObjectRenderer;
|
||||
|
||||
// While this should rather be exposed as a property for all objects, honor the "visible"
|
||||
// property that is specific to this object.
|
||||
hidden: boolean;
|
||||
|
||||
/**
|
||||
* @param runtimeScene The scene the object belongs to.
|
||||
* @param objectData The object data used to initialize the object
|
||||
*/
|
||||
constructor(runtimeScene: gdjs.RuntimeScene, objectData: BBTextObjectData) {
|
||||
super(runtimeScene, objectData);
|
||||
// @ts-ignore - parseFloat should not be required, but GDevelop 5.0 beta 92 and below were storing it as a string.
|
||||
this._opacity = parseFloat(objectData.content.opacity);
|
||||
this._text = objectData.content.text;
|
||||
this._color = BBTextRuntimeObject.hexToRGBColor(objectData.content.color);
|
||||
this._fontFamily = objectData.content.fontFamily;
|
||||
// @ts-ignore - parseFloat should not be required, but GDevelop 5.0 beta 92 and below were storing it as a string.
|
||||
this._fontSize = parseFloat(objectData.content.fontSize);
|
||||
this._wordWrap = objectData.content.wordWrap;
|
||||
this._align = objectData.content.align;
|
||||
this._renderer = new gdjs.BBTextRuntimeObjectRenderer(this, runtimeScene);
|
||||
this.hidden = !objectData.content.visible;
|
||||
|
||||
// *ALWAYS* call `this.onCreated()` at the very end of your object constructor.
|
||||
this.onCreated();
|
||||
}
|
||||
|
||||
static hexToRGBColor(hex) {
|
||||
const hexNumber = parseInt(hex.replace('#', ''), 16);
|
||||
return [(hexNumber >> 16) & 255, (hexNumber >> 8) & 255, hexNumber & 255];
|
||||
}
|
||||
|
||||
getRendererObject() {
|
||||
return this._renderer.getRendererObject();
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
updateFromObjectData(
|
||||
oldObjectData: BBTextObjectDataType,
|
||||
newObjectData: BBTextObjectDataType
|
||||
): boolean {
|
||||
if (oldObjectData.content.opacity !== newObjectData.content.opacity) {
|
||||
this.setOpacity(newObjectData.content.opacity);
|
||||
}
|
||||
if (oldObjectData.content.visible !== newObjectData.content.visible) {
|
||||
this.hide(!newObjectData.content.visible);
|
||||
}
|
||||
if (oldObjectData.content.text !== newObjectData.content.text) {
|
||||
this.setBBText(newObjectData.content.text);
|
||||
}
|
||||
if (oldObjectData.content.color !== newObjectData.content.color) {
|
||||
this._color = BBTextRuntimeObject.hexToRGBColor(
|
||||
newObjectData.content.color
|
||||
);
|
||||
this._renderer.updateColor();
|
||||
}
|
||||
if (
|
||||
oldObjectData.content.fontFamily !== newObjectData.content.fontFamily
|
||||
) {
|
||||
this.setFontFamily(newObjectData.content.fontFamily);
|
||||
}
|
||||
if (oldObjectData.content.fontSize !== newObjectData.content.fontSize) {
|
||||
this.setFontSize(newObjectData.content.fontSize);
|
||||
}
|
||||
if (oldObjectData.content.wordWrap !== newObjectData.content.wordWrap) {
|
||||
this.setWordWrap(newObjectData.content.wordWrap);
|
||||
}
|
||||
if (oldObjectData.content.align !== newObjectData.content.align) {
|
||||
this.setAlignment(newObjectData.content.align);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the extra parameters that could be set for an instance.
|
||||
*/
|
||||
extraInitializationFromInitialInstance(initialInstanceData: InstanceData) {
|
||||
if (initialInstanceData.customSize) {
|
||||
this.setWrappingWidth(initialInstanceData.width);
|
||||
} else {
|
||||
this.setWrappingWidth(
|
||||
// This value is the default wrapping width of the runtime object.
|
||||
250
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
onDestroyFromScene(runtimeScene): void {
|
||||
super.onDestroyFromScene(runtimeScene);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the markup text to display.
|
||||
*/
|
||||
setBBText(text): void {
|
||||
this._text = text;
|
||||
this._renderer.updateText();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the markup text displayed by the object.
|
||||
*/
|
||||
getBBText() {
|
||||
return this._text;
|
||||
}
|
||||
|
||||
setColor(rgbColorString): void {
|
||||
const splitValue = rgbColorString.split(';');
|
||||
if (splitValue.length !== 3) {
|
||||
return;
|
||||
}
|
||||
this._color[0] = parseInt(splitValue[0], 10);
|
||||
this._color[1] = parseInt(splitValue[1], 10);
|
||||
this._color[2] = parseInt(splitValue[2], 10);
|
||||
this._renderer.updateColor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the base color.
|
||||
* @return The color as a "R;G;B" string, for example: "255;0;0"
|
||||
*/
|
||||
getColor(): string {
|
||||
return this._color[0] + ';' + this._color[1] + ';' + this._color[2];
|
||||
}
|
||||
|
||||
setFontSize(fontSize): void {
|
||||
this._fontSize = fontSize;
|
||||
this._renderer.updateFontSize();
|
||||
}
|
||||
|
||||
getFontSize() {
|
||||
return this._fontSize;
|
||||
}
|
||||
|
||||
setFontFamily(fontFamily): void {
|
||||
this._fontFamily = fontFamily;
|
||||
this._renderer.updateFontFamily();
|
||||
}
|
||||
|
||||
getFontFamily() {
|
||||
return this._fontFamily;
|
||||
}
|
||||
|
||||
setAlignment(align): void {
|
||||
this._align = align;
|
||||
this._renderer.updateAlignment();
|
||||
}
|
||||
|
||||
getAlignment() {
|
||||
return this._align;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set object position on X axis.
|
||||
* @param x The new position X of the object.
|
||||
*/
|
||||
setX(x: float): void {
|
||||
super.setX(x);
|
||||
this._renderer.updatePosition();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set object position on Y axis.
|
||||
* @param y The new position Y of the object.
|
||||
*/
|
||||
setY(y: float): void {
|
||||
super.setY(y);
|
||||
this._renderer.updatePosition();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the angle of the object.
|
||||
* @param angle The new angle of the object.
|
||||
*/
|
||||
setAngle(angle: float): void {
|
||||
super.setAngle(angle);
|
||||
this._renderer.updateAngle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set object opacity.
|
||||
* @param opacity The new opacity of the object (0-255).
|
||||
*/
|
||||
setOpacity(opacity: float): void {
|
||||
this._opacity = opacity;
|
||||
this._renderer.updateOpacity();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get object opacity.
|
||||
*/
|
||||
getOpacity() {
|
||||
return this._opacity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the width.
|
||||
* @param width The new width in pixels.
|
||||
*/
|
||||
setWrappingWidth(width: float): void {
|
||||
this._wrappingWidth = width;
|
||||
this._renderer.updateWrappingWidth();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the wrapping width of the object.
|
||||
*/
|
||||
getWrappingWidth(): float {
|
||||
return this._wrappingWidth;
|
||||
}
|
||||
|
||||
setWordWrap(wordWrap): void {
|
||||
this._wordWrap = wordWrap;
|
||||
this._renderer.updateWordWrap();
|
||||
}
|
||||
|
||||
getWordWrap(wordWrap) {
|
||||
return this._wordWrap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the width of the object.
|
||||
*/
|
||||
getWidth(): float {
|
||||
return this._renderer.getWidth();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the height of the object.
|
||||
*/
|
||||
getHeight(): float {
|
||||
return this._renderer.getHeight();
|
||||
}
|
||||
}
|
||||
// @ts-ignore
|
||||
gdjs.registerObject('BBText::BBText', gdjs.BBTextRuntimeObject);
|
||||
}
|
@@ -48,7 +48,7 @@ module.exports = {
|
||||
.addCodeOnlyParameter("currentScene", "")
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/DebuggerTools/debuggertools.js')
|
||||
.setFunctionName('gdjs.evtTools.debugger.pause');
|
||||
.setFunctionName('gdjs.evtTools.debuggerTools.pause');
|
||||
|
||||
return extension;
|
||||
},
|
||||
|
@@ -1,19 +0,0 @@
|
||||
/**
|
||||
* @file
|
||||
* Tools for interacting with the debugger.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* The namespace containing tools to interact with the debugger.
|
||||
* @namespace
|
||||
*/
|
||||
gdjs.evtTools.debugger = {};
|
||||
|
||||
/**
|
||||
* Stop the game execution.
|
||||
* @param {gdjs.RuntimeScene} runtimeScene - The current scene.
|
||||
*/
|
||||
gdjs.evtTools.debugger.pause = function(runtimeScene) {
|
||||
runtimeScene.getGame().pause(true);
|
||||
}
|
17
Extensions/DebuggerTools/debuggertools.ts
Normal file
17
Extensions/DebuggerTools/debuggertools.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
namespace gdjs {
|
||||
export namespace evtTools {
|
||||
/**
|
||||
* The namespace containing tools to interact with the debugger.
|
||||
* @namespace
|
||||
*/
|
||||
export namespace debuggerTools {
|
||||
/**
|
||||
* Stop the game execution.
|
||||
* @param runtimeScene - The current scene.
|
||||
*/
|
||||
export const pause = function (runtimeScene: gdjs.RuntimeScene) {
|
||||
runtimeScene.getGame().pause(true);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,65 +0,0 @@
|
||||
/**
|
||||
GDevelop - DestroyOutside Behavior Extension
|
||||
Copyright (c) 2013-2016 Florian Rival (Florian.Rival@gmail.com)
|
||||
*/
|
||||
|
||||
/**
|
||||
* The destroyOutsideRuntimeBehavior represents a behavior allowing objects to be
|
||||
* moved using the mouse.
|
||||
*
|
||||
* @class DestroyOutsideRuntimeBehavior
|
||||
* @constructor
|
||||
*/
|
||||
gdjs.DestroyOutsideRuntimeBehavior = function(runtimeScene, behaviorData, owner)
|
||||
{
|
||||
gdjs.RuntimeBehavior.call(this, runtimeScene, behaviorData, owner);
|
||||
|
||||
this._extraBorder = behaviorData.extraBorder || 0;
|
||||
};
|
||||
|
||||
gdjs.DestroyOutsideRuntimeBehavior.prototype = Object.create( gdjs.RuntimeBehavior.prototype );
|
||||
gdjs.registerBehavior("DestroyOutsideBehavior::DestroyOutside", gdjs.DestroyOutsideRuntimeBehavior);
|
||||
|
||||
gdjs.DestroyOutsideRuntimeBehavior.prototype.updateFromBehaviorData = function(oldBehaviorData, newBehaviorData) {
|
||||
if (oldBehaviorData.extraBorder !== newBehaviorData.extraBorder) {
|
||||
this._extraBorder = newBehaviorData.extraBorder;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
gdjs.DestroyOutsideRuntimeBehavior.prototype.doStepPostEvents = function(runtimeScene) {
|
||||
|
||||
// TODO: This would better be done using the object AABB (getAABB), as (`getCenterX`;`getCenterY`) point
|
||||
// is not necessarily in the middle of the object (for sprites for example).
|
||||
var ow = this.owner.getWidth();
|
||||
var oh = this.owner.getHeight();
|
||||
var ocx = this.owner.getDrawableX()+this.owner.getCenterX();
|
||||
var ocy = this.owner.getDrawableY()+this.owner.getCenterY();
|
||||
var layer = runtimeScene.getLayer(this.owner.getLayer());
|
||||
|
||||
var boundingCircleRadius = Math.sqrt(ow*ow+oh*oh)/2.0;
|
||||
if ( ocx+boundingCircleRadius+this._extraBorder < layer.getCameraX()-layer.getCameraWidth()/2
|
||||
|| ocx-boundingCircleRadius-this._extraBorder > layer.getCameraX()+layer.getCameraWidth()/2
|
||||
|| ocy+boundingCircleRadius+this._extraBorder < layer.getCameraY()-layer.getCameraHeight()/2
|
||||
|| ocy-boundingCircleRadius-this._extraBorder > layer.getCameraY()+layer.getCameraHeight()/2 ) {
|
||||
//We are outside the camera area.
|
||||
this.owner.deleteFromScene(runtimeScene);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Set an additional border to the camera viewport as a buffer before the object gets destroyed.
|
||||
* @param {number} val Border in pixels.
|
||||
*/
|
||||
gdjs.DestroyOutsideRuntimeBehavior.prototype.setExtraBorder = function(val) {
|
||||
this._extraBorder = val;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the additional border of the camera viewport buffer which triggers the destruction of an object.
|
||||
* @return {number} The additional border around the camera viewport in pixels
|
||||
*/
|
||||
gdjs.DestroyOutsideRuntimeBehavior.prototype.getExtraBorder = function() {
|
||||
return this._extraBorder;
|
||||
};
|
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
GDevelop - DestroyOutside Behavior Extension
|
||||
Copyright (c) 2013-2016 Florian Rival (Florian.Rival@gmail.com)
|
||||
*/
|
||||
|
||||
namespace gdjs {
|
||||
/**
|
||||
* The DestroyOutsideRuntimeBehavior represents a behavior allowing objects to be
|
||||
* moved using the mouse.
|
||||
*/
|
||||
export class DestroyOutsideRuntimeBehavior extends gdjs.RuntimeBehavior {
|
||||
_extraBorder: any;
|
||||
|
||||
constructor(runtimeScene, behaviorData, owner) {
|
||||
super(runtimeScene, behaviorData, owner);
|
||||
this._extraBorder = behaviorData.extraBorder || 0;
|
||||
}
|
||||
|
||||
updateFromBehaviorData(oldBehaviorData, newBehaviorData): boolean {
|
||||
if (oldBehaviorData.extraBorder !== newBehaviorData.extraBorder) {
|
||||
this._extraBorder = newBehaviorData.extraBorder;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
doStepPostEvents(runtimeScene) {
|
||||
// TODO: This would better be done using the object AABB (getAABB), as (`getCenterX`;`getCenterY`) point
|
||||
// is not necessarily in the middle of the object (for sprites for example).
|
||||
const ow = this.owner.getWidth();
|
||||
const oh = this.owner.getHeight();
|
||||
const ocx = this.owner.getDrawableX() + this.owner.getCenterX();
|
||||
const ocy = this.owner.getDrawableY() + this.owner.getCenterY();
|
||||
const layer = runtimeScene.getLayer(this.owner.getLayer());
|
||||
const boundingCircleRadius = Math.sqrt(ow * ow + oh * oh) / 2.0;
|
||||
if (
|
||||
ocx + boundingCircleRadius + this._extraBorder <
|
||||
layer.getCameraX() - layer.getCameraWidth() / 2 ||
|
||||
ocx - boundingCircleRadius - this._extraBorder >
|
||||
layer.getCameraX() + layer.getCameraWidth() / 2 ||
|
||||
ocy + boundingCircleRadius + this._extraBorder <
|
||||
layer.getCameraY() - layer.getCameraHeight() / 2 ||
|
||||
ocy - boundingCircleRadius - this._extraBorder >
|
||||
layer.getCameraY() + layer.getCameraHeight() / 2
|
||||
) {
|
||||
//We are outside the camera area.
|
||||
this.owner.deleteFromScene(runtimeScene);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an additional border to the camera viewport as a buffer before the object gets destroyed.
|
||||
* @param val Border in pixels.
|
||||
*/
|
||||
setExtraBorder(val: number): void {
|
||||
this._extraBorder = val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the additional border of the camera viewport buffer which triggers the destruction of an object.
|
||||
* @return The additional border around the camera viewport in pixels
|
||||
*/
|
||||
getExtraBorder(): number {
|
||||
return this._extraBorder;
|
||||
}
|
||||
}
|
||||
gdjs.registerBehavior(
|
||||
'DestroyOutsideBehavior::DestroyOutside',
|
||||
gdjs.DestroyOutsideRuntimeBehavior
|
||||
);
|
||||
}
|
@@ -1,215 +0,0 @@
|
||||
/**
|
||||
* @memberof gdjs
|
||||
* @class deviceSensors
|
||||
* @static
|
||||
* @private
|
||||
*/
|
||||
|
||||
gdjs.deviceSensors = {
|
||||
orientation: {
|
||||
_isActive: false,
|
||||
_absolute: 0,
|
||||
_alpha: 0,
|
||||
_beta: 0,
|
||||
_gamma: 0
|
||||
},
|
||||
motion: {
|
||||
_isActive: false,
|
||||
_rotationAlpha: 0,
|
||||
_rotationBeta: 0,
|
||||
_rotationGamma: 0,
|
||||
_accelerationX: 0,
|
||||
_accelerationY: 0,
|
||||
_accelerationZ: 0
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Activate the orientation sensor's listener.
|
||||
* @private
|
||||
*/
|
||||
gdjs.deviceSensors.orientation._activateOrientationListener = function() {
|
||||
window.addEventListener("deviceorientation", gdjs.deviceSensors.orientation._handleOrientation, true);
|
||||
gdjs.deviceSensors.orientation._isActive = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deactivate the orientation sensor's listener.
|
||||
* @private
|
||||
*/
|
||||
gdjs.deviceSensors.orientation._deactivateOrientationListener = function() {
|
||||
window.removeEventListener('deviceorientation', gdjs.deviceSensors.orientation._handleOrientation, true);
|
||||
gdjs.deviceSensors.orientation._isActive = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Orientation sensor event callback function.
|
||||
* @private
|
||||
*/
|
||||
gdjs.deviceSensors.orientation._handleOrientation = function(event) {
|
||||
gdjs.deviceSensors.orientation._absolute = event.absolute ? event.absolute : 0;
|
||||
gdjs.deviceSensors.orientation._alpha = event.alpha ? event.alpha : 0;
|
||||
gdjs.deviceSensors.orientation._beta = event.beta ? event.beta : 0;
|
||||
gdjs.deviceSensors.orientation._gamma = event.gamma ? event.gamma : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Activate the orientation sensor
|
||||
*/
|
||||
gdjs.deviceSensors.orientation.activateOrientationSensor = function() {
|
||||
gdjs.deviceSensors.orientation._activateOrientationListener();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deactivate the orientation sensor
|
||||
*/
|
||||
gdjs.deviceSensors.orientation.deactivateOrientationSensor = function() {
|
||||
gdjs.deviceSensors.orientation._deactivateOrientationListener();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the orientation sensor is currently active
|
||||
* @return {number} The activation state of the orientation sensor (0=false/1=true)
|
||||
*/
|
||||
gdjs.deviceSensors.orientation.isActive = function() {
|
||||
return gdjs.deviceSensors.orientation._isActive;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of the device orientation's absolute as a number
|
||||
* @return {number} The device orientation's absolute value
|
||||
*/
|
||||
gdjs.deviceSensors.orientation.getOrientationAbsolute = function() {
|
||||
return gdjs.deviceSensors.orientation._absolute;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the value of the device orientation's alpha as a number (Range: 0 to 360)
|
||||
* @return {number} The device orientation's alpha value
|
||||
*/
|
||||
gdjs.deviceSensors.orientation.getOrientationAlpha = function() {
|
||||
return gdjs.deviceSensors.orientation._alpha;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the value of the device orientation's beta as a number (Range: -180 to 180)
|
||||
* @return {number} The device orientation's beta value
|
||||
*/
|
||||
gdjs.deviceSensors.orientation.getOrientationBeta = function() {
|
||||
return gdjs.deviceSensors.orientation._beta;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the value of the device orientation's gamma as a number (Range: -90 to 90)
|
||||
* @return {number} The device orientation's gamma value
|
||||
*/
|
||||
gdjs.deviceSensors.orientation.getOrientationGamma = function() {
|
||||
return gdjs.deviceSensors.orientation._gamma;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Activate the motion sensor's listener.
|
||||
* @private
|
||||
*/
|
||||
gdjs.deviceSensors.motion._activateMotionListener = function() {
|
||||
window.addEventListener("devicemotion", gdjs.deviceSensors.motion._handleMotion, true);
|
||||
gdjs.deviceSensors.motion._isActive = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deactivate the motion sensor's listener.
|
||||
* @private
|
||||
*/
|
||||
gdjs.deviceSensors.motion._deactivateMotionListener = function() {
|
||||
window.removeEventListener('devicemotion', gdjs.deviceSensors.motion._handleMotion, true);
|
||||
gdjs.deviceSensors.motion._isActive = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Motion sensor event callback function.
|
||||
* @private
|
||||
*/
|
||||
gdjs.deviceSensors.motion._handleMotion = function(event) {
|
||||
if (event.accelerationIncludingGravity){
|
||||
gdjs.deviceSensors.motion._accelerationX = event.accelerationIncludingGravity.x ? event.accelerationIncludingGravity.x : 0;
|
||||
gdjs.deviceSensors.motion._accelerationY = event.accelerationIncludingGravity.y ? event.accelerationIncludingGravity.y : 0;
|
||||
gdjs.deviceSensors.motion._accelerationZ = event.accelerationIncludingGravity.z ? event.accelerationIncludingGravity.z : 0;
|
||||
}
|
||||
|
||||
if (event.rotationRate){
|
||||
gdjs.deviceSensors.motion._rotationAlpha = event.rotationRate.alpha ? event.rotationRate.alpha : 0;
|
||||
gdjs.deviceSensors.motion._rotationBeta = event.rotationRate.beta ? event.rotationRate.beta : 0;
|
||||
gdjs.deviceSensors.motion._rotationGamma = event.rotationRate.gamma ? event.rotationRate.gamma : 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Activate the motion sensor
|
||||
*/
|
||||
gdjs.deviceSensors.motion.activateMotionSensor = function() {
|
||||
gdjs.deviceSensors.motion._activateMotionListener();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deactivate the motion sensor
|
||||
*/
|
||||
gdjs.deviceSensors.motion.deactivateMotionSensor = function() {
|
||||
gdjs.deviceSensors.motion._deactivateMotionListener();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the motion sensor is currently active
|
||||
* @return {number} The activation state of the motion sensor (0=false/1=true)
|
||||
*/
|
||||
gdjs.deviceSensors.motion.isActive = function() {
|
||||
return gdjs.deviceSensors.motion._isActive;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the alpha rotation rate as a number
|
||||
* @return {number} The rotation alpha value
|
||||
*/
|
||||
gdjs.deviceSensors.motion.getRotationAlpha = function() {
|
||||
return gdjs.deviceSensors.motion._rotationAlpha;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the beta rotation rate as a number
|
||||
* @return {number} The rotation beta value
|
||||
*/
|
||||
gdjs.deviceSensors.motion.getRotationBeta = function() {
|
||||
return gdjs.deviceSensors.motion._rotationBeta;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the gamma rotation rate as a number
|
||||
* @return {number} The rotation gamma value
|
||||
*/
|
||||
gdjs.deviceSensors.motion.getRotationGamma = function() {
|
||||
return gdjs.deviceSensors.motion._rotationGamma;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the acceleration value on the X-axis as a number
|
||||
* @return {number} Acceleration on the X-axis
|
||||
*/
|
||||
gdjs.deviceSensors.motion.getAccelerationX = function() {
|
||||
return gdjs.deviceSensors.motion._accelerationX;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the acceleration value on the Y-axis as a number
|
||||
* @return {number} Acceleration on the Y-axis
|
||||
*/
|
||||
gdjs.deviceSensors.motion.getAccelerationY = function() {
|
||||
return gdjs.deviceSensors.motion._accelerationY;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the acceleration value on the Z-axis as a number
|
||||
* @return {number} Acceleration on the Z-axis
|
||||
*/
|
||||
gdjs.deviceSensors.motion.getAccelerationZ = function() {
|
||||
return gdjs.deviceSensors.motion._accelerationZ;
|
||||
};
|
229
Extensions/DeviceSensors/devicesensortools.ts
Normal file
229
Extensions/DeviceSensors/devicesensortools.ts
Normal file
@@ -0,0 +1,229 @@
|
||||
namespace gdjs {
|
||||
export namespace deviceSensors {
|
||||
export namespace orientation {
|
||||
let _isActive = false;
|
||||
let _absolute = 0;
|
||||
let _alpha = 0;
|
||||
let _beta = 0;
|
||||
let _gamma = 0;
|
||||
|
||||
/**
|
||||
* Activate the orientation sensor's listener.
|
||||
*/
|
||||
export const _activateOrientationListener = function () {
|
||||
window.addEventListener(
|
||||
'deviceorientation',
|
||||
gdjs.deviceSensors.orientation._handleOrientation,
|
||||
true
|
||||
);
|
||||
_isActive = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Deactivate the orientation sensor's listener.
|
||||
*/
|
||||
export const _deactivateOrientationListener = function () {
|
||||
window.removeEventListener(
|
||||
'deviceorientation',
|
||||
gdjs.deviceSensors.orientation._handleOrientation,
|
||||
true
|
||||
);
|
||||
_isActive = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Orientation sensor event callback function.
|
||||
*/
|
||||
export const _handleOrientation = function (event) {
|
||||
_absolute = event.absolute ? event.absolute : 0;
|
||||
_alpha = event.alpha ? event.alpha : 0;
|
||||
_beta = event.beta ? event.beta : 0;
|
||||
_gamma = event.gamma ? event.gamma : 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Activate the orientation sensor
|
||||
*/
|
||||
export const activateOrientationSensor = function () {
|
||||
gdjs.deviceSensors.orientation._activateOrientationListener();
|
||||
};
|
||||
|
||||
/**
|
||||
* Deactivate the orientation sensor
|
||||
*/
|
||||
export const deactivateOrientationSensor = function () {
|
||||
gdjs.deviceSensors.orientation._deactivateOrientationListener();
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the orientation sensor is currently active
|
||||
* @return The activation state of the orientation sensor
|
||||
*/
|
||||
export const isActive = function (): boolean {
|
||||
return _isActive;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the value of the device orientation's absolute as a number
|
||||
* @return The device orientation's absolute value
|
||||
*/
|
||||
export const getOrientationAbsolute = function (): number {
|
||||
return _absolute;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the value of the device orientation's alpha as a number (Range: 0 to 360)
|
||||
* @return The device orientation's alpha value
|
||||
*/
|
||||
export const getOrientationAlpha = function (): number {
|
||||
return _alpha;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the value of the device orientation's beta as a number (Range: -180 to 180)
|
||||
* @return The device orientation's beta value
|
||||
*/
|
||||
export const getOrientationBeta = function (): number {
|
||||
return _beta;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the value of the device orientation's gamma as a number (Range: -90 to 90)
|
||||
* @return The device orientation's gamma value
|
||||
*/
|
||||
export const getOrientationGamma = function (): number {
|
||||
return _gamma;
|
||||
};
|
||||
}
|
||||
|
||||
export namespace motion {
|
||||
let _isActive = false;
|
||||
let _rotationAlpha = 0;
|
||||
let _rotationBeta = 0;
|
||||
let _rotationGamma = 0;
|
||||
let _accelerationX = 0;
|
||||
let _accelerationY = 0;
|
||||
let _accelerationZ = 0;
|
||||
|
||||
/**
|
||||
* Activate the motion sensor's listener.
|
||||
*/
|
||||
export const _activateMotionListener = function () {
|
||||
window.addEventListener(
|
||||
'devicemotion',
|
||||
gdjs.deviceSensors.motion._handleMotion,
|
||||
true
|
||||
);
|
||||
_isActive = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Deactivate the motion sensor's listener.
|
||||
*/
|
||||
export const _deactivateMotionListener = function () {
|
||||
window.removeEventListener(
|
||||
'devicemotion',
|
||||
gdjs.deviceSensors.motion._handleMotion,
|
||||
true
|
||||
);
|
||||
_isActive = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Motion sensor event callback function.
|
||||
*/
|
||||
export const _handleMotion = function (event) {
|
||||
if (event.accelerationIncludingGravity) {
|
||||
_accelerationX = event.accelerationIncludingGravity.x
|
||||
? event.accelerationIncludingGravity.x
|
||||
: 0;
|
||||
_accelerationY = event.accelerationIncludingGravity.y
|
||||
? event.accelerationIncludingGravity.y
|
||||
: 0;
|
||||
_accelerationZ = event.accelerationIncludingGravity.z
|
||||
? event.accelerationIncludingGravity.z
|
||||
: 0;
|
||||
}
|
||||
if (event.rotationRate) {
|
||||
_rotationAlpha = event.rotationRate.alpha
|
||||
? event.rotationRate.alpha
|
||||
: 0;
|
||||
_rotationBeta = event.rotationRate.beta ? event.rotationRate.beta : 0;
|
||||
_rotationGamma = event.rotationRate.gamma
|
||||
? event.rotationRate.gamma
|
||||
: 0;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Activate the motion sensor
|
||||
*/
|
||||
export const activateMotionSensor = function () {
|
||||
gdjs.deviceSensors.motion._activateMotionListener();
|
||||
};
|
||||
|
||||
/**
|
||||
* Deactivate the motion sensor
|
||||
*/
|
||||
export const deactivateMotionSensor = function () {
|
||||
gdjs.deviceSensors.motion._deactivateMotionListener();
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the motion sensor is currently active
|
||||
* @return The activation state of the motion sensor
|
||||
*/
|
||||
export const isActive = function (): boolean {
|
||||
return _isActive;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the alpha rotation rate as a number
|
||||
* @return The rotation alpha value
|
||||
*/
|
||||
export const getRotationAlpha = function (): number {
|
||||
return _rotationAlpha;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the beta rotation rate as a number
|
||||
* @return The rotation beta value
|
||||
*/
|
||||
export const getRotationBeta = function (): number {
|
||||
return _rotationBeta;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the gamma rotation rate as a number
|
||||
* @return The rotation gamma value
|
||||
*/
|
||||
export const getRotationGamma = function (): number {
|
||||
return _rotationGamma;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the acceleration value on the X-axis as a number
|
||||
* @return Acceleration on the X-axis
|
||||
*/
|
||||
export const getAccelerationX = function (): number {
|
||||
return _accelerationX;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the acceleration value on the Y-axis as a number
|
||||
* @return Acceleration on the Y-axis
|
||||
*/
|
||||
export const getAccelerationY = function (): number {
|
||||
return _accelerationY;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the acceleration value on the Z-axis as a number
|
||||
* @return Acceleration on the Z-axis
|
||||
*/
|
||||
export const getAccelerationZ = function (): number {
|
||||
return _accelerationZ;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,43 +0,0 @@
|
||||
/**
|
||||
* @memberof gdjs
|
||||
* @class deviceVibration
|
||||
* @static
|
||||
* @private
|
||||
*/
|
||||
|
||||
gdjs.deviceVibration = {};
|
||||
|
||||
/**
|
||||
* Vibrate the mobile device.
|
||||
* @param {number} duration Value in milliseconds.
|
||||
*/
|
||||
gdjs.deviceVibration.startVibration = function(duration) {
|
||||
if (typeof navigator == "undefined" || !navigator.vibrate) return
|
||||
|
||||
navigator.vibrate([duration]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Vibrate the mobile device in a pattern.
|
||||
* You can add multiple comma separated values where every second one determines the silence between vibrations.
|
||||
* Example: "200,1000,500" (200ms vibration, 1sec silense, 500ms vibration)
|
||||
* @param {string} intervals Comma separated list of values (in ms).
|
||||
*/
|
||||
gdjs.deviceVibration.startVibrationPattern = function(intervals) {
|
||||
const pattern = '^[0-9]+(,[0-9]+)*$'
|
||||
|
||||
if (typeof navigator == "undefined" || !navigator.vibrate) return
|
||||
|
||||
if (intervals.match(pattern)){
|
||||
navigator.vibrate(intervals.split(","));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop the current vibration on the mobile device.
|
||||
*/
|
||||
gdjs.deviceVibration.stopVibration = function() {
|
||||
if (typeof navigator == "undefined" || !navigator.vibrate) return
|
||||
|
||||
navigator.vibrate([]);
|
||||
}
|
42
Extensions/DeviceVibration/devicevibrationtools.ts
Normal file
42
Extensions/DeviceVibration/devicevibrationtools.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
namespace gdjs {
|
||||
export namespace deviceVibration {
|
||||
/**
|
||||
* Vibrate the mobile device.
|
||||
* @param duration Value in milliseconds.
|
||||
*/
|
||||
export const startVibration = function (duration: number) {
|
||||
if (typeof navigator == 'undefined' || !navigator.vibrate) {
|
||||
return;
|
||||
}
|
||||
navigator.vibrate([duration]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Vibrate the mobile device in a pattern.
|
||||
* You can add multiple comma separated values where every second one determines the silence between vibrations.
|
||||
* Example: "200,1000,500" (200ms vibration, 1sec silense, 500ms vibration)
|
||||
* @param intervals Comma separated list of values (in ms).
|
||||
*/
|
||||
export const startVibrationPattern = function (intervals: string) {
|
||||
const pattern = '^[0-9]+(,[0-9]+)*$';
|
||||
if (typeof navigator == 'undefined' || !navigator.vibrate) {
|
||||
return;
|
||||
}
|
||||
if (intervals.match(pattern)) {
|
||||
navigator.vibrate(
|
||||
intervals.split(',').map((duration) => parseFloat(duration))
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Stop the current vibration on the mobile device.
|
||||
*/
|
||||
export const stopVibration = function () {
|
||||
if (typeof navigator == 'undefined' || !navigator.vibrate) {
|
||||
return;
|
||||
}
|
||||
navigator.vibrate([]);
|
||||
};
|
||||
}
|
||||
}
|
@@ -1,735 +0,0 @@
|
||||
/**
|
||||
* @memberof gdjs
|
||||
* @class dialogueTree
|
||||
* @static
|
||||
* @private
|
||||
*/
|
||||
|
||||
gdjs.dialogueTree = {};
|
||||
gdjs.dialogueTree.runner = new bondage.Runner();
|
||||
|
||||
/**
|
||||
* Load the Dialogue Tree data of the game. Initialize The Dialogue Tree, so as it can be used in the game.
|
||||
* @param {gdjs.Variable} sceneVar The variable to load the Dialogue tree data from. The data is a JSON string, created by Yarn.
|
||||
* @param {string} startDialogueNode The Dialogue Branch to start the Dialogue Tree from. If left empty, the data will only be loaded, but can later be initialized via another action
|
||||
*/
|
||||
gdjs.dialogueTree.loadFromSceneVariable = function(
|
||||
sceneVar,
|
||||
startDialogueNode
|
||||
) {
|
||||
this.runner = gdjs.dialogueTree.runner;
|
||||
|
||||
try {
|
||||
this.yarnData = JSON.parse(sceneVar.getAsString());
|
||||
this.runner.load(this.yarnData);
|
||||
|
||||
if (startDialogueNode && startDialogueNode.length > 0) {
|
||||
gdjs.dialogueTree.startFrom(startDialogueNode);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Load the Dialogue Tree data from a JSON resource.
|
||||
*
|
||||
* @param {gdjs.RuntimeScene} runtimeScene The scene where the dialogue is running.
|
||||
* @param {string} jsonResourceName The JSON resource where to load the Dialogue Tree data from. The data is a JSON string usually created with [Yarn Dialogue Editor](https://github.com/InfiniteAmmoInc/Yarn).
|
||||
* @param {string} startDialogueNode The Dialogue Branch to start the Dialogue Tree from. If left empty, the data will only be loaded, but can later be initialized via another action
|
||||
*/
|
||||
gdjs.dialogueTree.loadFromJsonFile = function(
|
||||
runtimeScene,
|
||||
jsonResourceName,
|
||||
startDialogueNode
|
||||
) {
|
||||
runtimeScene
|
||||
.getGame()
|
||||
.getJsonManager()
|
||||
.loadJson(jsonResourceName, function(error, content) {
|
||||
if (error) {
|
||||
console.error('An error happened while loading JSON resource:', error);
|
||||
} else {
|
||||
if (!content) return;
|
||||
gdjs.dialogueTree.yarnData = content;
|
||||
|
||||
try {
|
||||
gdjs.dialogueTree.runner.load(gdjs.dialogueTree.yarnData);
|
||||
} catch (error) {
|
||||
console.error(
|
||||
'An error happened while loading parsing the dialogue tree data:',
|
||||
error
|
||||
);
|
||||
}
|
||||
|
||||
if (startDialogueNode && startDialogueNode.length > 0) {
|
||||
gdjs.dialogueTree.startFrom(startDialogueNode);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Stop the currently running dialogue
|
||||
*/
|
||||
gdjs.dialogueTree.stopRunningDialogue = function() {
|
||||
if (this.dialogueIsRunning) this.dialogueIsRunning = false;
|
||||
if (this.dialogueData) this.dialogueData = null;
|
||||
this.dialogueText = '';
|
||||
this.clipTextEnd = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the Dialogue Tree is currently parsing data.
|
||||
* For example, you can do things like disabling player movement while talking to a NPC.
|
||||
*/
|
||||
gdjs.dialogueTree.isRunning = function() {
|
||||
if (
|
||||
this.dialogueIsRunning &&
|
||||
!this.dialogueData &&
|
||||
this.dialogueText &&
|
||||
this.clipTextEnd >= this.dialogueText.length
|
||||
) {
|
||||
this.dialogueIsRunning = false;
|
||||
}
|
||||
return this.dialogueIsRunning;
|
||||
};
|
||||
|
||||
/**
|
||||
* Scroll the clipped text. This can be combined with a timer and user input to control how fast the dialogue line text is scrolling.
|
||||
*/
|
||||
gdjs.dialogueTree.scrollClippedText = function() {
|
||||
if (this.pauseScrolling || !this.dialogueIsRunning) return;
|
||||
|
||||
// Autoscroll commands so the user doesnt have to press again
|
||||
if (
|
||||
gdjs.dialogueTree._isLineTypeCommand() &&
|
||||
this.dialogueDataType === 'text' &&
|
||||
this.dialogueBranchTitle === this.dialogueData.data.title &&
|
||||
this.lineNum === this.dialogueData.lineNum &&
|
||||
gdjs.dialogueTree.hasClippedScrollingCompleted()
|
||||
) {
|
||||
gdjs.dialogueTree.goToNextDialogueLine();
|
||||
return
|
||||
}
|
||||
|
||||
// Increment scrolling of clipped text
|
||||
if (this.dialogueText && this.dialogueDataType === 'text' && this.clipTextEnd < this.dialogueText.length) {
|
||||
this.clipTextEnd += 1;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Scroll the clipped text to its end, so the entire text is printed. This can be useful in keeping the event sheet logic simpler, while supporting more variation.
|
||||
*/
|
||||
gdjs.dialogueTree.completeClippedTextScrolling = function() {
|
||||
if (this.pauseScrolling || !this.dialogueIsRunning || !this.dialogueText || this.dialogueDataType !== 'text')
|
||||
return;
|
||||
this.clipTextEnd = this.dialogueText.length;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if text scrolling has completed.
|
||||
* Useful to prevent the user from skipping to next line before the current one has been printed fully.
|
||||
*/
|
||||
gdjs.dialogueTree.hasClippedScrollingCompleted = function() {
|
||||
if (!this.dialogueIsRunning || this.dialogueDataType === '') return false;
|
||||
|
||||
if (this.dialogueData && this.dialogueText.length > 0 && this.clipTextEnd >= this.dialogueText.length) {
|
||||
if (gdjs.dialogueTree.getVariable('debug')) console.warn('Scroll completed:', this.clipTextEnd,'/', this.dialogueText.length);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the current dialogue line with a scrolling effect (recommended).
|
||||
* Used with the scrollClippedText to achieve a classic scrolling text, as well as any <<wait>> effects to pause scrolling.
|
||||
*/
|
||||
gdjs.dialogueTree.getClippedLineText = function() {
|
||||
return this.dialogueIsRunning && this.dialogueText.length
|
||||
? this.dialogueText.substring(0, this.clipTextEnd + 1)
|
||||
: '';
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the current complete dialogue line without using any scrolling effects.
|
||||
* Note that using this instead getClippedLineText will skip any <<wait>> commands entirely.
|
||||
*/
|
||||
gdjs.dialogueTree.getLineText = function() {
|
||||
return this.dialogueIsRunning && this.dialogueText.length
|
||||
? this.dialogueText
|
||||
: '';
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the number of command parameters in a command with parameters that has been caught by a isCommandCalled condition
|
||||
*/
|
||||
gdjs.dialogueTree.commandParametersCount = function() {
|
||||
if (this.commandParameters && this.commandParameters.length > 1) {
|
||||
return this.commandParameters.length - 1;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a command parameter in any command with parameters that has been caught by a isCommandCalled condition
|
||||
* @param {number} paramIndex The index of the parameter to get.
|
||||
*/
|
||||
gdjs.dialogueTree.getCommandParameter = function(paramIndex) {
|
||||
if (paramIndex === -1 && this.commandParameters.length > 0) return this.commandParameters[0];
|
||||
if (
|
||||
this.commandParameters &&
|
||||
this.commandParameters.length >= paramIndex + 1
|
||||
) {
|
||||
var returnedParam = this.commandParameters[paramIndex + 1];
|
||||
return returnedParam ? returnedParam : '';
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
/**
|
||||
* Catch <<commands>> and <<commands with parameters>> from the current Dialogue Line.
|
||||
* You can trigger custom logic that relate to the story you are telling during the dialogue.
|
||||
*
|
||||
* @param {string} command The command you want to check for being called. Write it without the `<<>>`.
|
||||
*/
|
||||
gdjs.dialogueTree.isCommandCalled = function(command) {
|
||||
if (!this.dialogueIsRunning) return false;
|
||||
|
||||
var commandCalls = gdjs.dialogueTree.commandCalls;
|
||||
var clipTextEnd = gdjs.dialogueTree.clipTextEnd;
|
||||
var dialogueText = gdjs.dialogueTree.dialogueText;
|
||||
|
||||
if (this.pauseScrolling || !commandCalls) return false;
|
||||
return this.commandCalls.some(function(call, index) {
|
||||
if (clipTextEnd !== 0 && clipTextEnd < call.time) return false;
|
||||
if (call.cmd === 'wait' && (clipTextEnd === 0 || clipTextEnd !== dialogueText.length)) {
|
||||
gdjs.dialogueTree.pauseScrolling = true;
|
||||
setTimeout(function() {
|
||||
gdjs.dialogueTree.pauseScrolling = false;
|
||||
commandCalls.splice(index, 1);
|
||||
if (gdjs.dialogueTree.getVariable('debug')) console.info('CMD:', call);
|
||||
}, parseInt(call.params[1], 10));
|
||||
}
|
||||
if (call.cmd === command) {
|
||||
gdjs.dialogueTree.commandParameters = call.params;
|
||||
commandCalls.splice(index, 1);
|
||||
if (gdjs.dialogueTree.getVariable('debug')) console.info('CMD:', call);
|
||||
|
||||
return true;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Internal method to allow for capping option selection.
|
||||
* @private
|
||||
*/
|
||||
gdjs.dialogueTree._normalizedOptionIndex = function(optionIndex) {
|
||||
if (optionIndex >= this.options.length) optionIndex = this.options.length - 1;
|
||||
if (optionIndex < 0) optionIndex = 0;
|
||||
return optionIndex;
|
||||
};
|
||||
|
||||
/**
|
||||
* Internal method to allow for cycling option selection.
|
||||
* @private
|
||||
*/
|
||||
gdjs.dialogueTree._cycledOptionIndex = function(optionIndex) {
|
||||
if (optionIndex >= this.options.length) optionIndex = 0;
|
||||
if (optionIndex < 0) optionIndex = this.options.length - 1;
|
||||
return optionIndex;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the text of an option the player can select.
|
||||
* Used with getLineOptionsCount to render options for the player when a line of the Options type is parsed
|
||||
* @param {number} optionIndex The index of the option you want to get
|
||||
*/
|
||||
gdjs.dialogueTree.getLineOption = function(optionIndex) {
|
||||
if (!this.dialogueIsRunning || !this.options.length) return [];
|
||||
optionIndex = gdjs.dialogueTree._normalizedOptionIndex(optionIndex);
|
||||
return this.options[optionIndex];
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the text of the options the player can select, along with the selection cursor.
|
||||
* @param {string} optionSelectionCursor The string used to draw the currently selected option's cursor
|
||||
* @param {boolean} addNewLine when true each option is rendered on a new line.
|
||||
*/
|
||||
gdjs.dialogueTree.getLineOptionsText = function(
|
||||
optionSelectionCursor,
|
||||
addNewLine
|
||||
) {
|
||||
if (!this.dialogueIsRunning || !this.options.length) return '';
|
||||
var textResult = '';
|
||||
this.options.forEach(function(optionText, index) {
|
||||
if (index === gdjs.dialogueTree.selectedOption) {
|
||||
textResult += optionSelectionCursor;
|
||||
} else {
|
||||
textResult += optionSelectionCursor.replace(/.*/g, ' ');
|
||||
}
|
||||
textResult += optionText;
|
||||
if (addNewLine) textResult += '\n';
|
||||
});
|
||||
return textResult;
|
||||
};
|
||||
gdjs.dialogueTree.getLineOptionsTextHorizontal = function(
|
||||
optionSelectionCursor
|
||||
) {
|
||||
return this.getLineOptionsText(optionSelectionCursor, false);
|
||||
};
|
||||
gdjs.dialogueTree.getLineOptionsTextVertical = function(optionSelectionCursor) {
|
||||
return this.getLineOptionsText(optionSelectionCursor, true);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the number of options that are presented to the player, during the parsing of an Options type line.
|
||||
* @returns {number} The number of options
|
||||
*/
|
||||
gdjs.dialogueTree.getLineOptionsCount = function() {
|
||||
if (this.dialogueIsRunning && this.options.length) {
|
||||
return this.optionsCount;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Confirm the currently selected option, during the parsing of an Options type line.
|
||||
*
|
||||
* This will advance the dialogue tree to the dialogue branch was selected by the player.
|
||||
*/
|
||||
gdjs.dialogueTree.confirmSelectOption = function() {
|
||||
if (!this.dialogueIsRunning) return;
|
||||
if (
|
||||
this.dialogueData.select &&
|
||||
!this.selectedOptionUpdated &&
|
||||
this.selectedOption !== -1
|
||||
) {
|
||||
this.commandCalls = [];
|
||||
try {
|
||||
this.dialogueData.select(this.selectedOption);
|
||||
this.dialogueData = this.dialogue.next().value;
|
||||
gdjs.dialogueTree.goToNextDialogueLine();
|
||||
} catch (error) {
|
||||
console.error(
|
||||
`An error happened when trying to access the dialogue branch!`,
|
||||
error
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Select next option during Options type line parsing. Hook this to your game input.
|
||||
*/
|
||||
gdjs.dialogueTree.selectNextOption = function() {
|
||||
if (!this.dialogueIsRunning) return;
|
||||
if (this.dialogueData.select) {
|
||||
this.selectedOption += 1;
|
||||
this.selectedOption = gdjs.dialogueTree._cycledOptionIndex(
|
||||
this.selectedOption
|
||||
);
|
||||
this.selectedOptionUpdated = true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Select previous option during Options type line parsing. Hook this to your game input.
|
||||
*/
|
||||
gdjs.dialogueTree.selectPreviousOption = function() {
|
||||
if (!this.dialogueIsRunning) return;
|
||||
if (this.dialogueData.select) {
|
||||
this.selectedOption -= 1;
|
||||
this.selectedOption = gdjs.dialogueTree._cycledOptionIndex(
|
||||
this.selectedOption
|
||||
);
|
||||
this.selectedOptionUpdated = true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Select option by index during Options type line parsing.
|
||||
* @param {number} optionIndex The index of the option to select
|
||||
*/
|
||||
gdjs.dialogueTree.selectOption = function(optionIndex) {
|
||||
if (!this.dialogueIsRunning) return;
|
||||
if (this.dialogueData.select) {
|
||||
this.selectedOption = gdjs.dialogueTree._normalizedOptionIndex(
|
||||
optionIndex
|
||||
);
|
||||
this.selectedOptionUpdated = true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the currently selected option
|
||||
* @returns {number} The index of the currently selected option
|
||||
*/
|
||||
gdjs.dialogueTree.getSelectedOption = function() {
|
||||
if (!this.dialogueIsRunning) return;
|
||||
if (this.dialogueData.select) {
|
||||
return this.selectedOption;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check when the player has changed option selection since the last call to this function.
|
||||
*
|
||||
* Can be used to re-render your displayed dialogue options when needed.
|
||||
*
|
||||
* @returns {boolean} true if the selected option was updated since the last call to this function
|
||||
*/
|
||||
gdjs.dialogueTree.hasSelectedOptionChanged = function() {
|
||||
if (this.selectedOptionUpdated) {
|
||||
this.selectedOptionUpdated = false;
|
||||
if (this.selectedOption === -1) this.selectedOption = 0;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check the type of the Dialogue Line that is being displayed to the player at the moment.
|
||||
*
|
||||
* There are three types:
|
||||
* - text - regular dialogue text is being parsed at the moment
|
||||
* - options - the player has reached a branching choise moment where they must select one of multiple options
|
||||
* - command - a <<command>> was called in the background, that can be used to trigger game events, but will not be displayed in the dialogue box.
|
||||
*
|
||||
* @param {string} type The type you want to check for ( one of the three above )
|
||||
*/
|
||||
gdjs.dialogueTree.isDialogueLineType = function(type) {
|
||||
if (!this.dialogueIsRunning) return false;
|
||||
if (this.commandCalls && type === 'command') {
|
||||
if (
|
||||
this.commandCalls.some(function(call) {
|
||||
return gdjs.dialogueTree.clipTextEnd > call.time && call.cmd === 'wait';
|
||||
})
|
||||
) {
|
||||
return !this.pauseScrolling;
|
||||
}
|
||||
if (this.commandCalls.length > 0 && this.commandParameters.length > 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return this.dialogueDataType === type;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if a branch exists. It is also used internaly whenever you use the start from action.
|
||||
* @param {string} branchName The Dialogue Branch name you want to check.
|
||||
*/
|
||||
gdjs.dialogueTree.hasDialogueBranch = function(branchName) {
|
||||
return (
|
||||
this.runner &&
|
||||
this.runner.yarnNodes &&
|
||||
Object.keys(this.runner.yarnNodes).some(function(node) {
|
||||
return node === branchName;
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Start parsing dialogue from a specified Dialogue tree branch.
|
||||
* Can be used if you want to store multiple dialogues inside a single Dialogue tree data set.
|
||||
* @param {string} startDialogueNode The Dialogue Branch name you want to start parsing from.
|
||||
*/
|
||||
gdjs.dialogueTree.startFrom = function(startDialogueNode) {
|
||||
this.runner = gdjs.dialogueTree.runner;
|
||||
if (!this.hasDialogueBranch(startDialogueNode)) return;
|
||||
this.optionsCount = 0;
|
||||
this.options = [];
|
||||
this.tagParameters = [];
|
||||
this.dialogue = this.runner.run(startDialogueNode);
|
||||
this.dialogueText = '';
|
||||
this.clipTextEnd = 0;
|
||||
this.commandCalls = [];
|
||||
this.commandParameters = [];
|
||||
this.pauseScrolling = false;
|
||||
|
||||
this.dialogueData = this.dialogue.next().value;
|
||||
this.dialogueBranchTags = this.dialogueData.data.tags;
|
||||
this.dialogueBranchTitle = this.dialogueData.data.title;
|
||||
this.dialogueBranchBody = this.dialogueData.data.body;
|
||||
this.lineNum = this.dialogueData.lineNum;
|
||||
if (gdjs.dialogueTree._isLineTypeText()){
|
||||
this.dialogueDataType = 'text';
|
||||
} else if (gdjs.dialogueTree._isLineTypeOptions()){
|
||||
this.dialogueDataType = 'options';
|
||||
} else {
|
||||
this.dialogueDataType = 'command';
|
||||
};
|
||||
|
||||
this.dialogueIsRunning = true;
|
||||
gdjs.dialogueTree.goToNextDialogueLine();
|
||||
};
|
||||
|
||||
/**
|
||||
* Internal methods to check the type of a Dialogue Line
|
||||
*/
|
||||
gdjs.dialogueTree._isLineTypeText = function() {
|
||||
return this.dialogueData instanceof bondage.TextResult;
|
||||
};
|
||||
gdjs.dialogueTree._isLineTypeOptions = function() {
|
||||
return this.dialogueData instanceof bondage.OptionsResult;
|
||||
};
|
||||
gdjs.dialogueTree._isLineTypeCommand = function() {
|
||||
return this.dialogueData instanceof bondage.CommandResult;
|
||||
};
|
||||
|
||||
/**
|
||||
* This is the main lifecycle function.It runs once only when the user is advancing the dialogue to the next line.
|
||||
* Progress Dialogue to the next line. Hook it to your game input.
|
||||
* Note that this action can be influenced by any <<wait>> commands, but they work only if you have at least one isCommandCalled condition.
|
||||
*/
|
||||
gdjs.dialogueTree.goToNextDialogueLine = function() {
|
||||
if (this.pauseScrolling || !this.dialogueIsRunning) return;
|
||||
|
||||
this.optionsCount = 0;
|
||||
this.selectedOption = -1;
|
||||
this.selectedOptionUpdated = false;
|
||||
|
||||
if (gdjs.dialogueTree.getVariable('debug')) console.info('parsing:', this.dialogueData);
|
||||
|
||||
if (!this.dialogueData) {
|
||||
gdjs.dialogueTree.stopRunningDialogue();
|
||||
} else if (gdjs.dialogueTree._isLineTypeText()) {
|
||||
if (this.lineNum === this.dialogueData.lineNum && this.dialogueBranchTitle === this.dialogueData.data.title){
|
||||
this.clipTextEnd = this.dialogueText.length - 1;
|
||||
this.dialogueText +=
|
||||
(this.dialogueText === '' ? '' : ' ') + this.dialogueData.text;
|
||||
} else {
|
||||
this.clipTextEnd = 0;
|
||||
this.dialogueText = this.dialogueData.text;
|
||||
}
|
||||
|
||||
this.dialogueBranchTags = this.dialogueData.data.tags;
|
||||
this.dialogueBranchTitle = this.dialogueData.data.title;
|
||||
this.dialogueBranchBody = this.dialogueData.data.body;
|
||||
this.lineNum = this.dialogueData.lineNum;
|
||||
this.dialogueDataType = 'text';
|
||||
|
||||
this.dialogueData = this.dialogue.next().value;
|
||||
} else if (gdjs.dialogueTree._isLineTypeOptions()) {
|
||||
this.commandCalls = [];
|
||||
this.dialogueDataType = 'options';
|
||||
this.dialogueText = '';
|
||||
this.clipTextEnd = 0;
|
||||
this.optionsCount = this.dialogueData.options.length;
|
||||
this.options = this.dialogueData.options;
|
||||
this.selectedOptionUpdated = true;
|
||||
} else if (gdjs.dialogueTree._isLineTypeCommand()) {
|
||||
this.dialogueDataType = 'command';
|
||||
var command = this.dialogueData.text.split(' ');
|
||||
// If last command was to wait, increase time by one
|
||||
var offsetTime =
|
||||
this.commandCalls.length &&
|
||||
this.commandCalls[this.commandCalls.length - 1].cmd === 'wait'
|
||||
? 1
|
||||
: 0;
|
||||
this.commandCalls.push({
|
||||
cmd: command[0],
|
||||
params: command,
|
||||
time: this.dialogueText.length + offsetTime,
|
||||
});
|
||||
this.dialogueData = this.dialogue.next().value;
|
||||
gdjs.dialogueTree.goToNextDialogueLine();
|
||||
} else {
|
||||
this.dialogueDataType = 'unknown';
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the current Dialogue Tree branch title.
|
||||
* @returns {string} The current branch title.
|
||||
*/
|
||||
gdjs.dialogueTree.getBranchTitle = function() {
|
||||
if (this.dialogueIsRunning) {
|
||||
return this.dialogueBranchTitle;
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the currently parsed Dialogue branch title is a query.
|
||||
* @param {string} title The Dialogue Branch name you want to check for.
|
||||
*/
|
||||
gdjs.dialogueTree.branchTitleIs = function(title) {
|
||||
if (this.dialogueIsRunning) {
|
||||
return this.dialogueBranchTitle === title;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get all the branch tags from the current Dialogue branch as a string. Useful for debugging.
|
||||
* @returns {string} The current branch tags, separated by a comma.
|
||||
*/
|
||||
gdjs.dialogueTree.getBranchTags = function() {
|
||||
if (this.dialogueIsRunning) {
|
||||
return this.dialogueBranchTags.join(',');
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
/**
|
||||
* Get one of the current Dialogue branch tags via index.
|
||||
* @param {number} index The index of the Dialogue Branch tag you want to get.
|
||||
* @returns {string} The branch tag at the specified index, or an empty string if not found.
|
||||
*/
|
||||
gdjs.dialogueTree.getBranchTag = function(index) {
|
||||
if (this.dialogueIsRunning && this.dialogueBranchTags.length) {
|
||||
if (index > this.dialogueBranchTags.length - 1)
|
||||
index = this.dialogueBranchTags.length - 1;
|
||||
return this.dialogueBranchTags[index];
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the current Dialogue branch contains a specific tag.
|
||||
* @param {string} query The name of the Dialogue Branch tag you want to check.
|
||||
*/
|
||||
gdjs.dialogueTree.branchContainsTag = function(query) {
|
||||
this.tagParameters = [];
|
||||
if (this.dialogueIsRunning && this.dialogueBranchTags.length) {
|
||||
return this.dialogueBranchTags.some(function(tag) {
|
||||
var splitTag = tag.match(/([^\(]+)\(([^\)]+)\)/i);
|
||||
gdjs.dialogueTree.tagParameters = splitTag ? splitTag[2].split(',') : [];
|
||||
return splitTag ? splitTag[1] === query : tag === query;
|
||||
});
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get any tag(parameter,anotherParameter) from a tag captured by the branchContainsTag Condition
|
||||
* @param {number} paramIndex The index of the tag parameter you want to get.
|
||||
* Leaving this empty will result in retrieving the first parameter.
|
||||
*/
|
||||
gdjs.dialogueTree.getTagParameter = function(paramIndex) {
|
||||
if (this.dialogueIsRunning && this.tagParameters.length >= paramIndex) {
|
||||
var returnedParam = this.tagParameters[paramIndex];
|
||||
return returnedParam ? returnedParam : '';
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a list of all the titles of visited by the player Branches. Useful for debugging.
|
||||
*/
|
||||
gdjs.dialogueTree.getVisitedBranchTitles = function() {
|
||||
if (this.dialogueIsRunning) {
|
||||
return Object.keys(this.runner.visited).join(',');
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if a player has visited a Dialogue Branch in the past.
|
||||
* @param {string} title The title of the branch to check for.
|
||||
* Leaving this empty will check if the current branch title has been visited in the past.
|
||||
*/
|
||||
gdjs.dialogueTree.branchTitleHasBeenVisited = function(title) {
|
||||
if (!title) title = this.dialogueBranchTitle;
|
||||
return (
|
||||
Object.keys(this.runner.visited).includes(title) &&
|
||||
this.runner.visited[title]
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the entire unparsed text of the current Dialogue Branch
|
||||
*/
|
||||
gdjs.dialogueTree.getBranchText = function() {
|
||||
if (this.dialogueIsRunning) {
|
||||
return this.dialogueBranchBody;
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the value of a variable that was created by the Dialogue parses.
|
||||
* @param {string} key The name of the variable you want to get the value of
|
||||
*/
|
||||
gdjs.dialogueTree.getVariable = function(key) {
|
||||
if (this.dialogueIsRunning && key in this.runner.variables.data) {
|
||||
return this.runner.variables.get(key);
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if a specific variable created by the Dialogue parses exists and is equal to a specific value.
|
||||
* @param {string} key The name of the variable you want to check the value of
|
||||
* @param {string|boolean|number} value The value you want to check against
|
||||
*/
|
||||
gdjs.dialogueTree.compareVariable = function(key, value) {
|
||||
if (this.dialogueIsRunning && key in this.runner.variables.data) {
|
||||
return this.runner.variables.get(key) === value;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set a specific variable created by the Dialogue parser to a specific value.
|
||||
* @param {string} key The name of the variable you want to set the value of
|
||||
* @param {string|boolean|number} value The value you want to set
|
||||
*/
|
||||
gdjs.dialogueTree.setVariable = function(key, value) {
|
||||
if (this.runner.variables) {
|
||||
this.runner.variables.set(key, value);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Store the current State of the Dialogue Parser in a specified variable.
|
||||
* Can be used to implement persistence in dialogue through your game's Load/Save function.
|
||||
* That way you can later load all the dialogue choices the player has made.
|
||||
* @param {gdjs.Variable} outputVariable The variable where to store the State
|
||||
*/
|
||||
gdjs.dialogueTree.saveState = function(outputVariable) {
|
||||
var dialogueState = {
|
||||
variables: gdjs.dialogueTree.runner.variables.data,
|
||||
visited: gdjs.dialogueTree.runner.visited,
|
||||
};
|
||||
gdjs.evtTools.network._objectToVariable(dialogueState, outputVariable);
|
||||
};
|
||||
|
||||
/**
|
||||
* Load the current State of the Dialogue Parser from a specified variable.
|
||||
* Can be used to implement persistence in dialogue through your game's Load/Save function.
|
||||
* That way you can later load all the dialogue choices the player has made.
|
||||
* @param {gdjs.Variable} inputVariable The structured variable where to load the State from.
|
||||
*/
|
||||
gdjs.dialogueTree.loadState = function(inputVariable) {
|
||||
var loadedState = JSON.parse(
|
||||
gdjs.evtTools.network.variableStructureToJSON(inputVariable)
|
||||
);
|
||||
if (!loadedState) {
|
||||
console.error('Load state variable is empty:', inputVariable);
|
||||
return
|
||||
}
|
||||
try {
|
||||
gdjs.dialogueTree.runner.visited = loadedState.visited;
|
||||
gdjs.dialogueTree.runner.variables.data = {};
|
||||
Object.keys(loadedState.variables).forEach(function(key) {
|
||||
var value = loadedState.variables[key];
|
||||
gdjs.dialogueTree.runner.variables.set(key, value);
|
||||
});
|
||||
} catch (e) {
|
||||
console.error('Failed to load state from variable:', inputVariable, e);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Clear the current State of the Dialogue Parser.
|
||||
*/
|
||||
gdjs.dialogueTree.clearState = function() {
|
||||
gdjs.dialogueTree.runner.visited = {};
|
||||
gdjs.dialogueTree.runner.variables.data = {};
|
||||
};
|
824
Extensions/DialogueTree/dialoguetools.ts
Normal file
824
Extensions/DialogueTree/dialoguetools.ts
Normal file
@@ -0,0 +1,824 @@
|
||||
// @ts-nocheck - Weird usage of `this` in this file. Should be refactored.
|
||||
|
||||
namespace gdjs {
|
||||
gdjs.dialogueTree = {};
|
||||
gdjs.dialogueTree.runner = new bondage.Runner();
|
||||
|
||||
/**
|
||||
* Load the Dialogue Tree data of the game. Initialize The Dialogue Tree, so as it can be used in the game.
|
||||
* @param sceneVar The variable to load the Dialogue tree data from. The data is a JSON string, created by Yarn.
|
||||
* @param startDialogueNode The Dialogue Branch to start the Dialogue Tree from. If left empty, the data will only be loaded, but can later be initialized via another action
|
||||
*/
|
||||
gdjs.dialogueTree.loadFromSceneVariable = function (
|
||||
sceneVar: gdjs.Variable,
|
||||
startDialogueNode: string
|
||||
) {
|
||||
this.runner = gdjs.dialogueTree.runner;
|
||||
try {
|
||||
this.yarnData = JSON.parse(sceneVar.getAsString());
|
||||
this.runner.load(this.yarnData);
|
||||
if (startDialogueNode && startDialogueNode.length > 0) {
|
||||
gdjs.dialogueTree.startFrom(startDialogueNode);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Load the Dialogue Tree data from a JSON resource.
|
||||
*
|
||||
* @param runtimeScene The scene where the dialogue is running.
|
||||
* @param jsonResourceName The JSON resource where to load the Dialogue Tree data from. The data is a JSON string usually created with [Yarn Dialogue Editor](https://github.com/InfiniteAmmoInc/Yarn).
|
||||
* @param startDialogueNode The Dialogue Branch to start the Dialogue Tree from. If left empty, the data will only be loaded, but can later be initialized via another action
|
||||
*/
|
||||
gdjs.dialogueTree.loadFromJsonFile = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
jsonResourceName: string,
|
||||
startDialogueNode: string
|
||||
) {
|
||||
runtimeScene
|
||||
.getGame()
|
||||
.getJsonManager()
|
||||
.loadJson(jsonResourceName, function (error, content) {
|
||||
if (error) {
|
||||
console.error(
|
||||
'An error happened while loading JSON resource:',
|
||||
error
|
||||
);
|
||||
} else {
|
||||
if (!content) {
|
||||
return;
|
||||
}
|
||||
gdjs.dialogueTree.yarnData = content;
|
||||
try {
|
||||
gdjs.dialogueTree.runner.load(gdjs.dialogueTree.yarnData);
|
||||
} catch (error) {
|
||||
console.error(
|
||||
'An error happened while loading parsing the dialogue tree data:',
|
||||
error
|
||||
);
|
||||
}
|
||||
if (startDialogueNode && startDialogueNode.length > 0) {
|
||||
gdjs.dialogueTree.startFrom(startDialogueNode);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Stop the currently running dialogue
|
||||
*/
|
||||
gdjs.dialogueTree.stopRunningDialogue = function () {
|
||||
if (this.dialogueIsRunning) {
|
||||
this.dialogueIsRunning = false;
|
||||
}
|
||||
if (this.dialogueData) {
|
||||
this.dialogueData = null;
|
||||
}
|
||||
this.dialogueText = '';
|
||||
this.clipTextEnd = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the Dialogue Tree is currently parsing data.
|
||||
* For example, you can do things like disabling player movement while talking to a NPC.
|
||||
*/
|
||||
gdjs.dialogueTree.isRunning = function () {
|
||||
if (
|
||||
this.dialogueIsRunning &&
|
||||
!this.dialogueData &&
|
||||
this.dialogueText &&
|
||||
this.clipTextEnd >= this.dialogueText.length
|
||||
) {
|
||||
this.dialogueIsRunning = false;
|
||||
}
|
||||
return this.dialogueIsRunning;
|
||||
};
|
||||
|
||||
/**
|
||||
* Scroll the clipped text. This can be combined with a timer and user input to control how fast the dialogue line text is scrolling.
|
||||
*/
|
||||
gdjs.dialogueTree.scrollClippedText = function () {
|
||||
if (this.pauseScrolling || !this.dialogueIsRunning) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Autoscroll commands so the user doesnt have to press again
|
||||
if (
|
||||
gdjs.dialogueTree._isLineTypeCommand() &&
|
||||
this.dialogueDataType === 'text' &&
|
||||
this.dialogueBranchTitle === this.dialogueData.data.title &&
|
||||
this.lineNum === this.dialogueData.lineNum &&
|
||||
gdjs.dialogueTree.hasClippedScrollingCompleted()
|
||||
) {
|
||||
gdjs.dialogueTree.goToNextDialogueLine();
|
||||
return;
|
||||
}
|
||||
|
||||
// Increment scrolling of clipped text
|
||||
if (
|
||||
this.dialogueText &&
|
||||
this.dialogueDataType === 'text' &&
|
||||
this.clipTextEnd < this.dialogueText.length
|
||||
) {
|
||||
this.clipTextEnd += 1;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Scroll the clipped text to its end, so the entire text is printed. This can be useful in keeping the event sheet logic simpler, while supporting more variation.
|
||||
*/
|
||||
gdjs.dialogueTree.completeClippedTextScrolling = function () {
|
||||
if (
|
||||
this.pauseScrolling ||
|
||||
!this.dialogueIsRunning ||
|
||||
!this.dialogueText ||
|
||||
this.dialogueDataType !== 'text'
|
||||
) {
|
||||
return;
|
||||
}
|
||||
this.clipTextEnd = this.dialogueText.length;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if text scrolling has completed.
|
||||
* Useful to prevent the user from skipping to next line before the current one has been printed fully.
|
||||
*/
|
||||
gdjs.dialogueTree.hasClippedScrollingCompleted = function () {
|
||||
if (!this.dialogueIsRunning || this.dialogueDataType === '') {
|
||||
return false;
|
||||
}
|
||||
if (
|
||||
this.dialogueData &&
|
||||
this.dialogueText.length > 0 &&
|
||||
this.clipTextEnd >= this.dialogueText.length
|
||||
) {
|
||||
if (gdjs.dialogueTree.getVariable('debug')) {
|
||||
console.warn(
|
||||
'Scroll completed:',
|
||||
this.clipTextEnd,
|
||||
'/',
|
||||
this.dialogueText.length
|
||||
);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the current dialogue line with a scrolling effect (recommended).
|
||||
* Used with the scrollClippedText to achieve a classic scrolling text, as well as any <<wait>> effects to pause scrolling.
|
||||
*/
|
||||
gdjs.dialogueTree.getClippedLineText = function () {
|
||||
return this.dialogueIsRunning && this.dialogueText.length
|
||||
? this.dialogueText.substring(0, this.clipTextEnd + 1)
|
||||
: '';
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the current complete dialogue line without using any scrolling effects.
|
||||
* Note that using this instead getClippedLineText will skip any <<wait>> commands entirely.
|
||||
*/
|
||||
gdjs.dialogueTree.getLineText = function () {
|
||||
return this.dialogueIsRunning && this.dialogueText.length
|
||||
? this.dialogueText
|
||||
: '';
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the number of command parameters in a command with parameters that has been caught by a isCommandCalled condition
|
||||
*/
|
||||
gdjs.dialogueTree.commandParametersCount = function () {
|
||||
if (this.commandParameters && this.commandParameters.length > 1) {
|
||||
return this.commandParameters.length - 1;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a command parameter in any command with parameters that has been caught by a isCommandCalled condition
|
||||
* @param paramIndex The index of the parameter to get.
|
||||
*/
|
||||
gdjs.dialogueTree.getCommandParameter = function (paramIndex: float) {
|
||||
if (paramIndex === -1 && this.commandParameters.length > 0) {
|
||||
return this.commandParameters[0];
|
||||
}
|
||||
if (
|
||||
this.commandParameters &&
|
||||
this.commandParameters.length >= paramIndex + 1
|
||||
) {
|
||||
const returnedParam = this.commandParameters[paramIndex + 1];
|
||||
return returnedParam ? returnedParam : '';
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
/**
|
||||
* Catch <<commands>> and <<commands with parameters>> from the current Dialogue Line.
|
||||
* You can trigger custom logic that relate to the story you are telling during the dialogue.
|
||||
*
|
||||
* @param command The command you want to check for being called. Write it without the `<<>>`.
|
||||
*/
|
||||
gdjs.dialogueTree.isCommandCalled = function (command: string) {
|
||||
if (!this.dialogueIsRunning) {
|
||||
return false;
|
||||
}
|
||||
const commandCalls = gdjs.dialogueTree.commandCalls;
|
||||
const clipTextEnd = gdjs.dialogueTree.clipTextEnd;
|
||||
const dialogueText = gdjs.dialogueTree.dialogueText;
|
||||
if (this.pauseScrolling || !commandCalls) {
|
||||
return false;
|
||||
}
|
||||
return this.commandCalls.some(function (call, index) {
|
||||
if (clipTextEnd !== 0 && clipTextEnd < call.time) {
|
||||
return false;
|
||||
}
|
||||
if (
|
||||
call.cmd === 'wait' &&
|
||||
(clipTextEnd === 0 || clipTextEnd !== dialogueText.length)
|
||||
) {
|
||||
gdjs.dialogueTree.pauseScrolling = true;
|
||||
setTimeout(function () {
|
||||
gdjs.dialogueTree.pauseScrolling = false;
|
||||
commandCalls.splice(index, 1);
|
||||
if (gdjs.dialogueTree.getVariable('debug')) {
|
||||
console.info('CMD:', call);
|
||||
}
|
||||
}, parseInt(call.params[1], 10));
|
||||
}
|
||||
if (call.cmd === command) {
|
||||
gdjs.dialogueTree.commandParameters = call.params;
|
||||
commandCalls.splice(index, 1);
|
||||
if (gdjs.dialogueTree.getVariable('debug')) {
|
||||
console.info('CMD:', call);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Internal method to allow for capping option selection.
|
||||
*/
|
||||
gdjs.dialogueTree._normalizedOptionIndex = function (optionIndex) {
|
||||
if (optionIndex >= this.options.length) {
|
||||
optionIndex = this.options.length - 1;
|
||||
}
|
||||
if (optionIndex < 0) {
|
||||
optionIndex = 0;
|
||||
}
|
||||
return optionIndex;
|
||||
};
|
||||
|
||||
/**
|
||||
* Internal method to allow for cycling option selection.
|
||||
*/
|
||||
gdjs.dialogueTree._cycledOptionIndex = function (optionIndex) {
|
||||
if (optionIndex >= this.options.length) {
|
||||
optionIndex = 0;
|
||||
}
|
||||
if (optionIndex < 0) {
|
||||
optionIndex = this.options.length - 1;
|
||||
}
|
||||
return optionIndex;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the text of an option the player can select.
|
||||
* Used with getLineOptionsCount to render options for the player when a line of the Options type is parsed
|
||||
* @param optionIndex The index of the option you want to get
|
||||
*/
|
||||
gdjs.dialogueTree.getLineOption = function (optionIndex: float) {
|
||||
if (!this.dialogueIsRunning || !this.options.length) {
|
||||
return [];
|
||||
}
|
||||
optionIndex = gdjs.dialogueTree._normalizedOptionIndex(optionIndex);
|
||||
return this.options[optionIndex];
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the text of the options the player can select, along with the selection cursor.
|
||||
* @param optionSelectionCursor The string used to draw the currently selected option's cursor
|
||||
* @param addNewLine when true each option is rendered on a new line.
|
||||
*/
|
||||
gdjs.dialogueTree.getLineOptionsText = function (
|
||||
optionSelectionCursor: string,
|
||||
addNewLine: boolean
|
||||
) {
|
||||
if (!this.dialogueIsRunning || !this.options.length) {
|
||||
return '';
|
||||
}
|
||||
let textResult = '';
|
||||
this.options.forEach(function (optionText, index) {
|
||||
if (index === gdjs.dialogueTree.selectedOption) {
|
||||
textResult += optionSelectionCursor;
|
||||
} else {
|
||||
textResult += optionSelectionCursor.replace(/.*/g, ' ');
|
||||
}
|
||||
textResult += optionText;
|
||||
if (addNewLine) {
|
||||
textResult += '\n';
|
||||
}
|
||||
});
|
||||
return textResult;
|
||||
};
|
||||
gdjs.dialogueTree.getLineOptionsTextHorizontal = function (
|
||||
optionSelectionCursor
|
||||
) {
|
||||
return this.getLineOptionsText(optionSelectionCursor, false);
|
||||
};
|
||||
gdjs.dialogueTree.getLineOptionsTextVertical = function (
|
||||
optionSelectionCursor
|
||||
) {
|
||||
return this.getLineOptionsText(optionSelectionCursor, true);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the number of options that are presented to the player, during the parsing of an Options type line.
|
||||
* @returns The number of options
|
||||
*/
|
||||
gdjs.dialogueTree.getLineOptionsCount = function (): number {
|
||||
if (this.dialogueIsRunning && this.options.length) {
|
||||
return this.optionsCount;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Confirm the currently selected option, during the parsing of an Options type line.
|
||||
*
|
||||
* This will advance the dialogue tree to the dialogue branch was selected by the player.
|
||||
*/
|
||||
gdjs.dialogueTree.confirmSelectOption = function () {
|
||||
if (!this.dialogueIsRunning) {
|
||||
return;
|
||||
}
|
||||
if (
|
||||
this.dialogueData.select &&
|
||||
!this.selectedOptionUpdated &&
|
||||
this.selectedOption !== -1
|
||||
) {
|
||||
this.commandCalls = [];
|
||||
try {
|
||||
this.dialogueData.select(this.selectedOption);
|
||||
this.dialogueData = this.dialogue.next().value;
|
||||
gdjs.dialogueTree.goToNextDialogueLine();
|
||||
} catch (error) {
|
||||
console.error(
|
||||
`An error happened when trying to access the dialogue branch!`,
|
||||
error
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Select next option during Options type line parsing. Hook this to your game input.
|
||||
*/
|
||||
gdjs.dialogueTree.selectNextOption = function () {
|
||||
if (!this.dialogueIsRunning) {
|
||||
return;
|
||||
}
|
||||
if (this.dialogueData.select) {
|
||||
this.selectedOption += 1;
|
||||
this.selectedOption = gdjs.dialogueTree._cycledOptionIndex(
|
||||
this.selectedOption
|
||||
);
|
||||
this.selectedOptionUpdated = true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Select previous option during Options type line parsing. Hook this to your game input.
|
||||
*/
|
||||
gdjs.dialogueTree.selectPreviousOption = function () {
|
||||
if (!this.dialogueIsRunning) {
|
||||
return;
|
||||
}
|
||||
if (this.dialogueData.select) {
|
||||
this.selectedOption -= 1;
|
||||
this.selectedOption = gdjs.dialogueTree._cycledOptionIndex(
|
||||
this.selectedOption
|
||||
);
|
||||
this.selectedOptionUpdated = true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Select option by index during Options type line parsing.
|
||||
* @param optionIndex The index of the option to select
|
||||
*/
|
||||
gdjs.dialogueTree.selectOption = function (optionIndex: float) {
|
||||
if (!this.dialogueIsRunning) {
|
||||
return;
|
||||
}
|
||||
if (this.dialogueData.select) {
|
||||
this.selectedOption = gdjs.dialogueTree._normalizedOptionIndex(
|
||||
optionIndex
|
||||
);
|
||||
this.selectedOptionUpdated = true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the currently selected option
|
||||
* @returns The index of the currently selected option
|
||||
*/
|
||||
gdjs.dialogueTree.getSelectedOption = function (): number {
|
||||
if (!this.dialogueIsRunning) {
|
||||
return;
|
||||
}
|
||||
if (this.dialogueData.select) {
|
||||
return this.selectedOption;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check when the player has changed option selection since the last call to this function.
|
||||
*
|
||||
* Can be used to re-render your displayed dialogue options when needed.
|
||||
*
|
||||
* @returns true if the selected option was updated since the last call to this function
|
||||
*/
|
||||
gdjs.dialogueTree.hasSelectedOptionChanged = function (): boolean {
|
||||
if (this.selectedOptionUpdated) {
|
||||
this.selectedOptionUpdated = false;
|
||||
if (this.selectedOption === -1) {
|
||||
this.selectedOption = 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check the type of the Dialogue Line that is being displayed to the player at the moment.
|
||||
*
|
||||
* There are three types:
|
||||
* - text - regular dialogue text is being parsed at the moment
|
||||
* - options - the player has reached a branching choise moment where they must select one of multiple options
|
||||
* - command - a <<command>> was called in the background, that can be used to trigger game events, but will not be displayed in the dialogue box.
|
||||
*
|
||||
* @param type The type you want to check for ( one of the three above )
|
||||
*/
|
||||
gdjs.dialogueTree.isDialogueLineType = function (type: string) {
|
||||
if (!this.dialogueIsRunning) {
|
||||
return false;
|
||||
}
|
||||
if (this.commandCalls && type === 'command') {
|
||||
if (
|
||||
this.commandCalls.some(function (call) {
|
||||
return (
|
||||
gdjs.dialogueTree.clipTextEnd > call.time && call.cmd === 'wait'
|
||||
);
|
||||
})
|
||||
) {
|
||||
return !this.pauseScrolling;
|
||||
}
|
||||
if (this.commandCalls.length > 0 && this.commandParameters.length > 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return this.dialogueDataType === type;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if a branch exists. It is also used internaly whenever you use the start from action.
|
||||
* @param branchName The Dialogue Branch name you want to check.
|
||||
*/
|
||||
gdjs.dialogueTree.hasDialogueBranch = function (branchName: string) {
|
||||
return (
|
||||
this.runner &&
|
||||
this.runner.yarnNodes &&
|
||||
Object.keys(this.runner.yarnNodes).some(function (node) {
|
||||
return node === branchName;
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Start parsing dialogue from a specified Dialogue tree branch.
|
||||
* Can be used if you want to store multiple dialogues inside a single Dialogue tree data set.
|
||||
* @param startDialogueNode The Dialogue Branch name you want to start parsing from.
|
||||
*/
|
||||
gdjs.dialogueTree.startFrom = function (startDialogueNode: string) {
|
||||
this.runner = gdjs.dialogueTree.runner;
|
||||
if (!this.hasDialogueBranch(startDialogueNode)) {
|
||||
return;
|
||||
}
|
||||
this.optionsCount = 0;
|
||||
this.options = [];
|
||||
this.tagParameters = [];
|
||||
this.dialogue = this.runner.run(startDialogueNode);
|
||||
this.dialogueText = '';
|
||||
this.clipTextEnd = 0;
|
||||
this.commandCalls = [];
|
||||
this.commandParameters = [];
|
||||
this.pauseScrolling = false;
|
||||
this.dialogueData = this.dialogue.next().value;
|
||||
this.dialogueBranchTags = this.dialogueData.data.tags;
|
||||
this.dialogueBranchTitle = this.dialogueData.data.title;
|
||||
this.dialogueBranchBody = this.dialogueData.data.body;
|
||||
this.lineNum = this.dialogueData.lineNum;
|
||||
if (gdjs.dialogueTree._isLineTypeText()) {
|
||||
this.dialogueDataType = 'text';
|
||||
} else {
|
||||
if (gdjs.dialogueTree._isLineTypeOptions()) {
|
||||
this.dialogueDataType = 'options';
|
||||
} else {
|
||||
this.dialogueDataType = 'command';
|
||||
}
|
||||
}
|
||||
this.dialogueIsRunning = true;
|
||||
gdjs.dialogueTree.goToNextDialogueLine();
|
||||
};
|
||||
|
||||
/**
|
||||
* Internal methods to check the type of a Dialogue Line
|
||||
*/
|
||||
gdjs.dialogueTree._isLineTypeText = function () {
|
||||
return this.dialogueData instanceof bondage.TextResult;
|
||||
};
|
||||
gdjs.dialogueTree._isLineTypeOptions = function () {
|
||||
return this.dialogueData instanceof bondage.OptionsResult;
|
||||
};
|
||||
gdjs.dialogueTree._isLineTypeCommand = function () {
|
||||
return this.dialogueData instanceof bondage.CommandResult;
|
||||
};
|
||||
|
||||
/**
|
||||
* This is the main lifecycle function.It runs once only when the user is advancing the dialogue to the next line.
|
||||
* Progress Dialogue to the next line. Hook it to your game input.
|
||||
* Note that this action can be influenced by any <<wait>> commands, but they work only if you have at least one isCommandCalled condition.
|
||||
*/
|
||||
gdjs.dialogueTree.goToNextDialogueLine = function () {
|
||||
if (this.pauseScrolling || !this.dialogueIsRunning) {
|
||||
return;
|
||||
}
|
||||
this.optionsCount = 0;
|
||||
this.selectedOption = -1;
|
||||
this.selectedOptionUpdated = false;
|
||||
if (gdjs.dialogueTree.getVariable('debug')) {
|
||||
console.info('parsing:', this.dialogueData);
|
||||
}
|
||||
if (!this.dialogueData) {
|
||||
gdjs.dialogueTree.stopRunningDialogue();
|
||||
} else {
|
||||
if (gdjs.dialogueTree._isLineTypeText()) {
|
||||
if (
|
||||
this.lineNum === this.dialogueData.lineNum &&
|
||||
this.dialogueBranchTitle === this.dialogueData.data.title
|
||||
) {
|
||||
this.clipTextEnd = this.dialogueText.length - 1;
|
||||
this.dialogueText +=
|
||||
(this.dialogueText === '' ? '' : ' ') + this.dialogueData.text;
|
||||
} else {
|
||||
this.clipTextEnd = 0;
|
||||
this.dialogueText = this.dialogueData.text;
|
||||
}
|
||||
this.dialogueBranchTags = this.dialogueData.data.tags;
|
||||
this.dialogueBranchTitle = this.dialogueData.data.title;
|
||||
this.dialogueBranchBody = this.dialogueData.data.body;
|
||||
this.lineNum = this.dialogueData.lineNum;
|
||||
this.dialogueDataType = 'text';
|
||||
this.dialogueData = this.dialogue.next().value;
|
||||
} else {
|
||||
if (gdjs.dialogueTree._isLineTypeOptions()) {
|
||||
this.commandCalls = [];
|
||||
this.dialogueDataType = 'options';
|
||||
this.dialogueText = '';
|
||||
this.clipTextEnd = 0;
|
||||
this.optionsCount = this.dialogueData.options.length;
|
||||
this.options = this.dialogueData.options;
|
||||
this.selectedOptionUpdated = true;
|
||||
} else {
|
||||
if (gdjs.dialogueTree._isLineTypeCommand()) {
|
||||
this.dialogueDataType = 'command';
|
||||
const command = this.dialogueData.text.split(' ');
|
||||
|
||||
// If last command was to wait, increase time by one
|
||||
const offsetTime =
|
||||
this.commandCalls.length &&
|
||||
this.commandCalls[this.commandCalls.length - 1].cmd === 'wait'
|
||||
? 1
|
||||
: 0;
|
||||
this.commandCalls.push({
|
||||
cmd: command[0],
|
||||
params: command,
|
||||
time: this.dialogueText.length + offsetTime,
|
||||
});
|
||||
this.dialogueData = this.dialogue.next().value;
|
||||
gdjs.dialogueTree.goToNextDialogueLine();
|
||||
} else {
|
||||
this.dialogueDataType = 'unknown';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the current Dialogue Tree branch title.
|
||||
* @returns The current branch title.
|
||||
*/
|
||||
gdjs.dialogueTree.getBranchTitle = function (): string {
|
||||
if (this.dialogueIsRunning) {
|
||||
return this.dialogueBranchTitle;
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the currently parsed Dialogue branch title is a query.
|
||||
* @param title The Dialogue Branch name you want to check for.
|
||||
*/
|
||||
gdjs.dialogueTree.branchTitleIs = function (title: string) {
|
||||
if (this.dialogueIsRunning) {
|
||||
return this.dialogueBranchTitle === title;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get all the branch tags from the current Dialogue branch as a string. Useful for debugging.
|
||||
* @returns The current branch tags, separated by a comma.
|
||||
*/
|
||||
gdjs.dialogueTree.getBranchTags = function (): string {
|
||||
if (this.dialogueIsRunning) {
|
||||
return this.dialogueBranchTags.join(',');
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
/**
|
||||
* Get one of the current Dialogue branch tags via index.
|
||||
* @param index The index of the Dialogue Branch tag you want to get.
|
||||
* @returns The branch tag at the specified index, or an empty string if not found.
|
||||
*/
|
||||
gdjs.dialogueTree.getBranchTag = function (index: float): string {
|
||||
if (this.dialogueIsRunning && this.dialogueBranchTags.length) {
|
||||
if (index > this.dialogueBranchTags.length - 1) {
|
||||
index = this.dialogueBranchTags.length - 1;
|
||||
}
|
||||
return this.dialogueBranchTags[index];
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the current Dialogue branch contains a specific tag.
|
||||
* @param query The name of the Dialogue Branch tag you want to check.
|
||||
*/
|
||||
gdjs.dialogueTree.branchContainsTag = function (query: string) {
|
||||
this.tagParameters = [];
|
||||
if (this.dialogueIsRunning && this.dialogueBranchTags.length) {
|
||||
return this.dialogueBranchTags.some(function (tag) {
|
||||
const splitTag = tag.match(/([^\(]+)\(([^\)]+)\)/i);
|
||||
gdjs.dialogueTree.tagParameters = splitTag
|
||||
? splitTag[2].split(',')
|
||||
: [];
|
||||
return splitTag ? splitTag[1] === query : tag === query;
|
||||
});
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get any tag(parameter,anotherParameter) from a tag captured by the branchContainsTag Condition
|
||||
* @param paramIndex The index of the tag parameter you want to get.
|
||||
* Leaving this empty will result in retrieving the first parameter.
|
||||
*/
|
||||
gdjs.dialogueTree.getTagParameter = function (paramIndex: float) {
|
||||
if (this.dialogueIsRunning && this.tagParameters.length >= paramIndex) {
|
||||
const returnedParam = this.tagParameters[paramIndex];
|
||||
return returnedParam ? returnedParam : '';
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a list of all the titles of visited by the player Branches. Useful for debugging.
|
||||
*/
|
||||
gdjs.dialogueTree.getVisitedBranchTitles = function () {
|
||||
if (this.dialogueIsRunning) {
|
||||
return Object.keys(this.runner.visited).join(',');
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if a player has visited a Dialogue Branch in the past.
|
||||
* @param title The title of the branch to check for.
|
||||
* Leaving this empty will check if the current branch title has been visited in the past.
|
||||
*/
|
||||
gdjs.dialogueTree.branchTitleHasBeenVisited = function (title: string) {
|
||||
if (!title) {
|
||||
title = this.dialogueBranchTitle;
|
||||
}
|
||||
return (
|
||||
Object.keys(this.runner.visited).includes(title) &&
|
||||
this.runner.visited[title]
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the entire unparsed text of the current Dialogue Branch
|
||||
*/
|
||||
gdjs.dialogueTree.getBranchText = function () {
|
||||
if (this.dialogueIsRunning) {
|
||||
return this.dialogueBranchBody;
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the value of a variable that was created by the Dialogue parses.
|
||||
* @param key The name of the variable you want to get the value of
|
||||
*/
|
||||
gdjs.dialogueTree.getVariable = function (key: string) {
|
||||
if (this.dialogueIsRunning && key in this.runner.variables.data) {
|
||||
return this.runner.variables.get(key);
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if a specific variable created by the Dialogue parses exists and is equal to a specific value.
|
||||
* @param key The name of the variable you want to check the value of
|
||||
* @param value The value you want to check against
|
||||
*/
|
||||
gdjs.dialogueTree.compareVariable = function (
|
||||
key: string,
|
||||
value: string | boolean | number
|
||||
) {
|
||||
if (this.dialogueIsRunning && key in this.runner.variables.data) {
|
||||
return this.runner.variables.get(key) === value;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set a specific variable created by the Dialogue parser to a specific value.
|
||||
* @param key The name of the variable you want to set the value of
|
||||
* @param value The value you want to set
|
||||
*/
|
||||
gdjs.dialogueTree.setVariable = function (
|
||||
key: string,
|
||||
value: string | boolean | number
|
||||
) {
|
||||
if (this.runner.variables) {
|
||||
this.runner.variables.set(key, value);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Store the current State of the Dialogue Parser in a specified variable.
|
||||
* Can be used to implement persistence in dialogue through your game's Load/Save function.
|
||||
* That way you can later load all the dialogue choices the player has made.
|
||||
* @param outputVariable The variable where to store the State
|
||||
*/
|
||||
gdjs.dialogueTree.saveState = function (outputVariable: gdjs.Variable) {
|
||||
const dialogueState = {
|
||||
variables: gdjs.dialogueTree.runner.variables.data,
|
||||
visited: gdjs.dialogueTree.runner.visited,
|
||||
};
|
||||
gdjs.evtTools.network._objectToVariable(dialogueState, outputVariable);
|
||||
};
|
||||
|
||||
/**
|
||||
* Load the current State of the Dialogue Parser from a specified variable.
|
||||
* Can be used to implement persistence in dialogue through your game's Load/Save function.
|
||||
* That way you can later load all the dialogue choices the player has made.
|
||||
* @param inputVariable The structured variable where to load the State from.
|
||||
*/
|
||||
gdjs.dialogueTree.loadState = function (inputVariable: gdjs.Variable) {
|
||||
const loadedState = JSON.parse(
|
||||
gdjs.evtTools.network.variableStructureToJSON(inputVariable)
|
||||
);
|
||||
if (!loadedState) {
|
||||
console.error('Load state variable is empty:', inputVariable);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
gdjs.dialogueTree.runner.visited = loadedState.visited;
|
||||
gdjs.dialogueTree.runner.variables.data = {};
|
||||
Object.keys(loadedState.variables).forEach(function (key) {
|
||||
const value = loadedState.variables[key];
|
||||
gdjs.dialogueTree.runner.variables.set(key, value);
|
||||
});
|
||||
} catch (e) {
|
||||
console.error('Failed to load state from variable:', inputVariable, e);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Clear the current State of the Dialogue Parser.
|
||||
*/
|
||||
gdjs.dialogueTree.clearState = function () {
|
||||
gdjs.dialogueTree.runner.visited = {};
|
||||
gdjs.dialogueTree.runner.variables.data = {};
|
||||
};
|
||||
}
|
@@ -1,161 +0,0 @@
|
||||
/**
|
||||
GDevelop - Draggable Behavior Extension
|
||||
Copyright (c) 2013-2016 Florian Rival (Florian.Rival@gmail.com)
|
||||
*/
|
||||
|
||||
/**
|
||||
* The DraggableRuntimeBehavior represents a behavior allowing objects to be
|
||||
* moved using the mouse.
|
||||
*
|
||||
* @class DraggableRuntimeBehavior
|
||||
* @constructor
|
||||
*/
|
||||
gdjs.DraggableRuntimeBehavior = function(runtimeScene, behaviorData, owner)
|
||||
{
|
||||
gdjs.RuntimeBehavior.call(this, runtimeScene, behaviorData, owner);
|
||||
|
||||
this._dragged = false;
|
||||
this._touchId = null;
|
||||
this._mouse = false;
|
||||
|
||||
this._xOffset = 0;
|
||||
this._yOffset = 0;
|
||||
};
|
||||
|
||||
gdjs.DraggableRuntimeBehavior.prototype = Object.create( gdjs.RuntimeBehavior.prototype );
|
||||
gdjs.registerBehavior("DraggableBehavior::Draggable", gdjs.DraggableRuntimeBehavior);
|
||||
|
||||
gdjs.DraggableRuntimeBehavior.prototype.updateFromBehaviorData = function(oldBehaviorData, newBehaviorData) {
|
||||
// Nothing to update.
|
||||
return true;
|
||||
}
|
||||
|
||||
gdjs.DraggableRuntimeBehavior.prototype.onDeActivate = function() {
|
||||
this._endDrag();
|
||||
};
|
||||
|
||||
gdjs.DraggableRuntimeBehavior.prototype.onDestroy = function() {
|
||||
this.onDeActivate();
|
||||
};
|
||||
|
||||
gdjs.DraggableRuntimeBehavior.prototype._endDrag = function() {
|
||||
if ( this._dragged && this._mouse ) gdjs.DraggableRuntimeBehavior.mouseDraggingSomething = false;
|
||||
if ( this._dragged && this._touchId !== null ) gdjs.DraggableRuntimeBehavior.touchDraggingSomething[this._touchId] = false;
|
||||
|
||||
this._dragged = false;
|
||||
this._mouse = false;
|
||||
this._touchId = null;
|
||||
}
|
||||
|
||||
gdjs.DraggableRuntimeBehavior.prototype._tryBeginDrag = function(runtimeScene) {
|
||||
if (this._dragged) return false;
|
||||
|
||||
var inputManager = runtimeScene.getGame().getInputManager();
|
||||
|
||||
//Try mouse
|
||||
if (inputManager.isMouseButtonPressed(0) &&
|
||||
!gdjs.DraggableRuntimeBehavior.leftPressedLastFrame &&
|
||||
!gdjs.DraggableRuntimeBehavior.mouseDraggingSomething) {
|
||||
|
||||
mousePos = runtimeScene.getLayer(this.owner.getLayer()).convertCoords(
|
||||
inputManager.getMouseX(),
|
||||
inputManager.getMouseY());
|
||||
|
||||
if (this.owner.insideObject(mousePos[0], mousePos[1])) {
|
||||
this._dragged = true;
|
||||
this._mouse = true;
|
||||
this._xOffset = mousePos[0] - this.owner.getX();
|
||||
this._yOffset = mousePos[1] - this.owner.getY();
|
||||
gdjs.DraggableRuntimeBehavior.mouseDraggingSomething = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
} else { //Try touches
|
||||
var touchIds = inputManager.getStartedTouchIdentifiers();
|
||||
for(var i = 0;i<touchIds.length;++i) {
|
||||
if (gdjs.DraggableRuntimeBehavior.touchDraggingSomething[touchIds[i]])
|
||||
continue;
|
||||
|
||||
touchPos = runtimeScene.getLayer(this.owner.getLayer()).convertCoords(
|
||||
inputManager.getTouchX(touchIds[i]),
|
||||
inputManager.getTouchY(touchIds[i]));
|
||||
|
||||
if (this.owner.insideObject(touchPos[0], touchPos[1])) {
|
||||
this._dragged = true;
|
||||
this._touchId = touchIds[i];
|
||||
this._xOffset = touchPos[0] - this.owner.getX();
|
||||
this._yOffset = touchPos[1] - this.owner.getY();
|
||||
gdjs.DraggableRuntimeBehavior.touchDraggingSomething[touchIds[i]] = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
gdjs.DraggableRuntimeBehavior.prototype._shouldEndDrag = function(runtimeScene) {
|
||||
if (!this._dragged) return false;
|
||||
var inputManager = runtimeScene.getGame().getInputManager();
|
||||
|
||||
if (this._mouse)
|
||||
return !inputManager.isMouseButtonPressed(0);
|
||||
else if (this._touchId !== null) {
|
||||
return inputManager.getAllTouchIdentifiers().indexOf(this._touchId) === -1;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
gdjs.DraggableRuntimeBehavior.prototype._updateObjectPosition = function(runtimeScene) {
|
||||
if (!this._dragged) return false;
|
||||
var inputManager = runtimeScene.getGame().getInputManager();
|
||||
|
||||
if (this._mouse) {
|
||||
mousePos = runtimeScene.getLayer(this.owner.getLayer()).convertCoords(
|
||||
inputManager.getMouseX(),
|
||||
inputManager.getMouseY());
|
||||
|
||||
this.owner.setX(mousePos[0] - this._xOffset);
|
||||
this.owner.setY(mousePos[1] - this._yOffset);
|
||||
}
|
||||
else if (this._touchId !== null) {
|
||||
touchPos = runtimeScene.getLayer(this.owner.getLayer()).convertCoords(
|
||||
inputManager.getTouchX(this._touchId),
|
||||
inputManager.getTouchY(this._touchId));
|
||||
|
||||
this.owner.setX(touchPos[0] - this._xOffset);
|
||||
this.owner.setY(touchPos[1] - this._yOffset);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
gdjs.DraggableRuntimeBehavior.prototype.doStepPreEvents = function(runtimeScene) {
|
||||
this._tryBeginDrag(runtimeScene);
|
||||
|
||||
if (this._shouldEndDrag(runtimeScene)) {
|
||||
this._endDrag();
|
||||
}
|
||||
|
||||
this._updateObjectPosition(runtimeScene);
|
||||
};
|
||||
|
||||
gdjs.DraggableRuntimeBehavior.prototype.doStepPostEvents = function(runtimeScene) {
|
||||
gdjs.DraggableRuntimeBehavior.leftPressedLastFrame =
|
||||
runtimeScene.getGame().getInputManager().isMouseButtonPressed(0);
|
||||
};
|
||||
|
||||
gdjs.DraggableRuntimeBehavior.prototype.isDragged = function(runtimeScene) {
|
||||
return this._dragged;
|
||||
};
|
||||
|
||||
//Static property used to avoid start dragging an object while another is dragged.
|
||||
gdjs.DraggableRuntimeBehavior.mouseDraggingSomething = false;
|
||||
|
||||
//Static property used to avoid start dragging an object while another is dragged by the same touch.
|
||||
gdjs.DraggableRuntimeBehavior.touchDraggingSomething = [];
|
||||
|
||||
//Static property used to only start dragging when clicking.
|
||||
gdjs.DraggableRuntimeBehavior.leftPressedLastFrame = false;
|
171
Extensions/DraggableBehavior/draggableruntimebehavior.ts
Normal file
171
Extensions/DraggableBehavior/draggableruntimebehavior.ts
Normal file
@@ -0,0 +1,171 @@
|
||||
/**
|
||||
GDevelop - Draggable Behavior Extension
|
||||
Copyright (c) 2013-2016 Florian Rival (Florian.Rival@gmail.com)
|
||||
*/
|
||||
|
||||
namespace gdjs {
|
||||
/**
|
||||
* The DraggableRuntimeBehavior represents a behavior allowing objects to be
|
||||
* moved using the mouse.
|
||||
*/
|
||||
export class DraggableRuntimeBehavior extends gdjs.RuntimeBehavior {
|
||||
_dragged: boolean = false;
|
||||
_touchId: any = null;
|
||||
_mouse: boolean = false;
|
||||
_xOffset: number = 0;
|
||||
_yOffset: number = 0;
|
||||
|
||||
constructor(runtimeScene, behaviorData, owner) {
|
||||
super(runtimeScene, behaviorData, owner);
|
||||
}
|
||||
|
||||
updateFromBehaviorData(oldBehaviorData, newBehaviorData): boolean {
|
||||
// Nothing to update.
|
||||
return true;
|
||||
}
|
||||
|
||||
onDeActivate() {
|
||||
this._endDrag();
|
||||
}
|
||||
|
||||
onDestroy() {
|
||||
this.onDeActivate();
|
||||
}
|
||||
|
||||
_endDrag() {
|
||||
if (this._dragged && this._mouse) {
|
||||
DraggableRuntimeBehavior.mouseDraggingSomething = false;
|
||||
}
|
||||
if (this._dragged && this._touchId !== null) {
|
||||
DraggableRuntimeBehavior.touchDraggingSomething[this._touchId] = false;
|
||||
}
|
||||
this._dragged = false;
|
||||
this._mouse = false;
|
||||
this._touchId = null;
|
||||
}
|
||||
|
||||
_tryBeginDrag(runtimeScene) {
|
||||
if (this._dragged) {
|
||||
return false;
|
||||
}
|
||||
const inputManager = runtimeScene.getGame().getInputManager();
|
||||
|
||||
//Try mouse
|
||||
if (
|
||||
inputManager.isMouseButtonPressed(0) &&
|
||||
!DraggableRuntimeBehavior.leftPressedLastFrame &&
|
||||
!DraggableRuntimeBehavior.mouseDraggingSomething
|
||||
) {
|
||||
const mousePos = runtimeScene
|
||||
.getLayer(this.owner.getLayer())
|
||||
.convertCoords(inputManager.getMouseX(), inputManager.getMouseY());
|
||||
if (this.owner.insideObject(mousePos[0], mousePos[1])) {
|
||||
this._dragged = true;
|
||||
this._mouse = true;
|
||||
this._xOffset = mousePos[0] - this.owner.getX();
|
||||
this._yOffset = mousePos[1] - this.owner.getY();
|
||||
DraggableRuntimeBehavior.mouseDraggingSomething = true;
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
//Try touches
|
||||
const touchIds = inputManager.getStartedTouchIdentifiers();
|
||||
for (let i = 0; i < touchIds.length; ++i) {
|
||||
if (DraggableRuntimeBehavior.touchDraggingSomething[touchIds[i]]) {
|
||||
continue;
|
||||
}
|
||||
const touchPos = runtimeScene
|
||||
.getLayer(this.owner.getLayer())
|
||||
.convertCoords(
|
||||
inputManager.getTouchX(touchIds[i]),
|
||||
inputManager.getTouchY(touchIds[i])
|
||||
);
|
||||
if (this.owner.insideObject(touchPos[0], touchPos[1])) {
|
||||
this._dragged = true;
|
||||
this._touchId = touchIds[i];
|
||||
this._xOffset = touchPos[0] - this.owner.getX();
|
||||
this._yOffset = touchPos[1] - this.owner.getY();
|
||||
DraggableRuntimeBehavior.touchDraggingSomething[touchIds[i]] = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
_shouldEndDrag(runtimeScene) {
|
||||
if (!this._dragged) {
|
||||
return false;
|
||||
}
|
||||
const inputManager = runtimeScene.getGame().getInputManager();
|
||||
if (this._mouse) {
|
||||
return !inputManager.isMouseButtonPressed(0);
|
||||
} else {
|
||||
if (this._touchId !== null) {
|
||||
return (
|
||||
inputManager.getAllTouchIdentifiers().indexOf(this._touchId) === -1
|
||||
);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
_updateObjectPosition(runtimeScene) {
|
||||
if (!this._dragged) {
|
||||
return false;
|
||||
}
|
||||
const inputManager = runtimeScene.getGame().getInputManager();
|
||||
if (this._mouse) {
|
||||
const mousePos = runtimeScene
|
||||
.getLayer(this.owner.getLayer())
|
||||
.convertCoords(inputManager.getMouseX(), inputManager.getMouseY());
|
||||
this.owner.setX(mousePos[0] - this._xOffset);
|
||||
this.owner.setY(mousePos[1] - this._yOffset);
|
||||
} else {
|
||||
if (this._touchId !== null) {
|
||||
const touchPos = runtimeScene
|
||||
.getLayer(this.owner.getLayer())
|
||||
.convertCoords(
|
||||
inputManager.getTouchX(this._touchId),
|
||||
inputManager.getTouchY(this._touchId)
|
||||
);
|
||||
this.owner.setX(touchPos[0] - this._xOffset);
|
||||
this.owner.setY(touchPos[1] - this._yOffset);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
doStepPreEvents(runtimeScene) {
|
||||
this._tryBeginDrag(runtimeScene);
|
||||
if (this._shouldEndDrag(runtimeScene)) {
|
||||
this._endDrag();
|
||||
}
|
||||
this._updateObjectPosition(runtimeScene);
|
||||
}
|
||||
|
||||
doStepPostEvents(runtimeScene) {
|
||||
DraggableRuntimeBehavior.leftPressedLastFrame = runtimeScene
|
||||
.getGame()
|
||||
.getInputManager()
|
||||
.isMouseButtonPressed(0);
|
||||
}
|
||||
|
||||
isDragged(runtimeScene): boolean {
|
||||
return this._dragged;
|
||||
}
|
||||
|
||||
//Static property used to avoid start dragging an object while another is dragged.
|
||||
static mouseDraggingSomething = false;
|
||||
|
||||
//Static property used to avoid start dragging an object while another is dragged by the same touch.
|
||||
static touchDraggingSomething: Array<boolean> = [];
|
||||
|
||||
//Static property used to only start dragging when clicking.
|
||||
static leftPressedLastFrame = false;
|
||||
}
|
||||
gdjs.registerBehavior(
|
||||
'DraggableBehavior::Draggable',
|
||||
gdjs.DraggableRuntimeBehavior
|
||||
);
|
||||
}
|
@@ -53,25 +53,25 @@ describe('gdjs.DraggableRuntimeBehavior', function () {
|
||||
object.setPosition(450, 500);
|
||||
|
||||
//Drag'n'drop
|
||||
runtimeScene.renderAndStep();
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame.getInputManager().onMouseMove(450, 500);
|
||||
runtimeGame
|
||||
.getInputManager()
|
||||
.onMouseButtonPressed(gdjs.InputManager.MOUSE_LEFT_BUTTON);
|
||||
runtimeScene.renderAndStep();
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame.getInputManager().onMouseMove(750, 600);
|
||||
runtimeScene.renderAndStep();
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame
|
||||
.getInputManager()
|
||||
.onMouseButtonReleased(gdjs.InputManager.MOUSE_LEFT_BUTTON);
|
||||
runtimeScene.renderAndStep();
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
expect(object.getX()).to.be(750);
|
||||
expect(object.getY()).to.be(600);
|
||||
|
||||
//Mouse move with dragging
|
||||
runtimeGame.getInputManager().onMouseMove(600, 600);
|
||||
runtimeScene.renderAndStep();
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
expect(object.getX()).to.be(750);
|
||||
expect(object.getY()).to.be(600);
|
||||
@@ -81,13 +81,13 @@ describe('gdjs.DraggableRuntimeBehavior', function () {
|
||||
runtimeGame
|
||||
.getInputManager()
|
||||
.onMouseButtonPressed(gdjs.InputManager.MOUSE_LEFT_BUTTON);
|
||||
runtimeScene.renderAndStep();
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame.getInputManager().onMouseMove(850, 700);
|
||||
runtimeScene.renderAndStep();
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame
|
||||
.getInputManager()
|
||||
.onMouseButtonReleased(gdjs.InputManager.MOUSE_LEFT_BUTTON);
|
||||
runtimeScene.renderAndStep();
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
expect(object.getX()).to.be(850);
|
||||
expect(object.getY()).to.be(700);
|
||||
@@ -97,16 +97,16 @@ describe('gdjs.DraggableRuntimeBehavior', function () {
|
||||
object.setPosition(450, 500);
|
||||
|
||||
//Drag'n'drop
|
||||
runtimeScene.renderAndStep();
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame.getInputManager().onTouchStart(1, 10, 20);
|
||||
runtimeGame.getInputManager().onTouchStart(0, 450, 500);
|
||||
runtimeScene.renderAndStep();
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame.getInputManager().onFrameEnded();
|
||||
runtimeGame.getInputManager().onTouchMove(0, 750, 600);
|
||||
runtimeScene.renderAndStep();
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame.getInputManager().onFrameEnded();
|
||||
runtimeGame.getInputManager().onTouchEnd(0);
|
||||
runtimeScene.renderAndStep();
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame.getInputManager().onFrameEnded();
|
||||
|
||||
expect(object.getX()).to.be(750);
|
||||
@@ -114,9 +114,9 @@ describe('gdjs.DraggableRuntimeBehavior', function () {
|
||||
|
||||
//Move another unrelated touch
|
||||
runtimeGame.getInputManager().onTouchMove(1, 750, 600);
|
||||
runtimeScene.renderAndStep();
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame.getInputManager().onTouchMove(1, 850, 700);
|
||||
runtimeScene.renderAndStep();
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
expect(object.getX()).to.be(750);
|
||||
expect(object.getY()).to.be(600);
|
||||
@@ -124,11 +124,11 @@ describe('gdjs.DraggableRuntimeBehavior', function () {
|
||||
//Start drag'n'drop with another touch
|
||||
runtimeGame.getInputManager().onTouchEnd(1);
|
||||
runtimeGame.getInputManager().onFrameEnded();
|
||||
runtimeScene.renderAndStep();
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame.getInputManager().onTouchStart(1, 750, 600);
|
||||
runtimeScene.renderAndStep();
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame.getInputManager().onTouchMove(1, 850, 700);
|
||||
runtimeScene.renderAndStep();
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame.getInputManager().onTouchEnd(1);
|
||||
runtimeGame.getInputManager().onFrameEnded();
|
||||
|
||||
@@ -141,14 +141,14 @@ describe('gdjs.DraggableRuntimeBehavior', function () {
|
||||
object2.setPosition(650, 600);
|
||||
|
||||
//Drag'n'drop
|
||||
runtimeScene.renderAndStep();
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame.getInputManager().onTouchStart(2, 450, 500);
|
||||
runtimeGame.getInputManager().onTouchStart(1, 650, 600);
|
||||
runtimeScene.renderAndStep();
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame.getInputManager().onFrameEnded();
|
||||
runtimeGame.getInputManager().onTouchMove(2, 750, 700);
|
||||
runtimeGame.getInputManager().onTouchMove(1, 100, 200);
|
||||
runtimeScene.renderAndStep();
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame.getInputManager().onFrameEnded();
|
||||
runtimeGame.getInputManager().onTouchEnd(2);
|
||||
|
@@ -1,29 +0,0 @@
|
||||
gdjs.PixiFiltersTools.registerFilterCreator('Adjustment', {
|
||||
makePIXIFilter: function(layer, effectData) {
|
||||
var adjustmentFilter = new PIXI.filters.AdjustmentFilter();
|
||||
|
||||
return adjustmentFilter;
|
||||
},
|
||||
update: function(filter, layer) {},
|
||||
updateDoubleParameter: function(filter, parameterName, value) {
|
||||
if (parameterName === 'gamma') {
|
||||
filter.gamma = value;
|
||||
} else if (parameterName === 'saturation') {
|
||||
filter.saturation = value;
|
||||
} else if (parameterName === 'contrast') {
|
||||
filter.contrast = value;
|
||||
} else if (parameterName === 'brightness') {
|
||||
filter.brightness = value;
|
||||
} else if (parameterName === 'red') {
|
||||
filter.red = value;
|
||||
} else if (parameterName === 'green') {
|
||||
filter.green = value;
|
||||
} else if (parameterName === 'blue') {
|
||||
filter.blue = value;
|
||||
} else if (parameterName === 'alpha') {
|
||||
filter.alpha = value;
|
||||
}
|
||||
},
|
||||
updateStringParameter: function(filter, parameterName, value) {},
|
||||
updateBooleanParameter: function(filter, parameterName, value) {},
|
||||
});
|
31
Extensions/Effects/adjustment-pixi-filter.ts
Normal file
31
Extensions/Effects/adjustment-pixi-filter.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
namespace gdjs {
|
||||
gdjs.PixiFiltersTools.registerFilterCreator('Adjustment', {
|
||||
makePIXIFilter: function (layer, effectData) {
|
||||
const adjustmentFilter = new PIXI.filters.AdjustmentFilter();
|
||||
return adjustmentFilter;
|
||||
},
|
||||
update: function (filter, layer) {},
|
||||
updateDoubleParameter: function (filter, parameterName, value) {
|
||||
const adjustmentFilter = filter as PIXI.filters.AdjustmentFilter;
|
||||
if (parameterName === 'gamma') {
|
||||
adjustmentFilter.gamma = value;
|
||||
} else if (parameterName === 'saturation') {
|
||||
adjustmentFilter.saturation = value;
|
||||
} else if (parameterName === 'contrast') {
|
||||
adjustmentFilter.contrast = value;
|
||||
} else if (parameterName === 'brightness') {
|
||||
adjustmentFilter.brightness = value;
|
||||
} else if (parameterName === 'red') {
|
||||
adjustmentFilter.red = value;
|
||||
} else if (parameterName === 'green') {
|
||||
adjustmentFilter.green = value;
|
||||
} else if (parameterName === 'blue') {
|
||||
adjustmentFilter.blue = value;
|
||||
} else if (parameterName === 'alpha') {
|
||||
adjustmentFilter.alpha = value;
|
||||
}
|
||||
},
|
||||
updateStringParameter: function (filter, parameterName, value) {},
|
||||
updateBooleanParameter: function (filter, parameterName, value) {},
|
||||
});
|
||||
}
|
@@ -1,23 +0,0 @@
|
||||
gdjs.PixiFiltersTools.registerFilterCreator('AdvancedBloom', {
|
||||
makePIXIFilter: function(layer, effectData) {
|
||||
var advancedBloomFilter = new PIXI.filters.AdvancedBloomFilter();
|
||||
|
||||
return advancedBloomFilter;
|
||||
},
|
||||
update: function(filter, layer) {},
|
||||
updateDoubleParameter: function(filter, parameterName, value) {
|
||||
if (parameterName === 'threshold') {
|
||||
filter.threshold = value;
|
||||
} else if (parameterName === 'bloomScale') {
|
||||
filter.bloomScale = value;
|
||||
} else if (parameterName === 'brightness') {
|
||||
filter.brightness = value;
|
||||
} else if (parameterName === 'blur') {
|
||||
filter.blur = value;
|
||||
} else if (parameterName === 'quality') {
|
||||
filter.quality = value;
|
||||
}
|
||||
},
|
||||
updateStringParameter: function(filter, parameterName, value) {},
|
||||
updateBooleanParameter: function(filter, parameterName, value) {},
|
||||
});
|
25
Extensions/Effects/advanced-bloom-pixi-filter.ts
Normal file
25
Extensions/Effects/advanced-bloom-pixi-filter.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
namespace gdjs {
|
||||
gdjs.PixiFiltersTools.registerFilterCreator('AdvancedBloom', {
|
||||
makePIXIFilter: function (layer, effectData) {
|
||||
const advancedBloomFilter = new PIXI.filters.AdvancedBloomFilter();
|
||||
return advancedBloomFilter;
|
||||
},
|
||||
update: function (filter, layer) {},
|
||||
updateDoubleParameter: function (filter, parameterName, value) {
|
||||
const advancedBloomFilter = filter as PIXI.filters.AdvancedBloomFilter;
|
||||
if (parameterName === 'threshold') {
|
||||
advancedBloomFilter.threshold = value;
|
||||
} else if (parameterName === 'bloomScale') {
|
||||
advancedBloomFilter.bloomScale = value;
|
||||
} else if (parameterName === 'brightness') {
|
||||
advancedBloomFilter.brightness = value;
|
||||
} else if (parameterName === 'blur') {
|
||||
advancedBloomFilter.blur = value;
|
||||
} else if (parameterName === 'quality') {
|
||||
advancedBloomFilter.quality = value;
|
||||
}
|
||||
},
|
||||
updateStringParameter: function (filter, parameterName, value) {},
|
||||
updateBooleanParameter: function (filter, parameterName, value) {},
|
||||
});
|
||||
}
|
@@ -1,15 +0,0 @@
|
||||
gdjs.PixiFiltersTools.registerFilterCreator('Ascii', {
|
||||
makePIXIFilter: function(layer, effectData) {
|
||||
var asciiFilter = new PIXI.filters.AsciiFilter();
|
||||
|
||||
return asciiFilter;
|
||||
},
|
||||
update: function(filter, layer) {},
|
||||
updateDoubleParameter: function(filter, parameterName, value) {
|
||||
if (parameterName === 'size') {
|
||||
filter.size = value;
|
||||
}
|
||||
},
|
||||
updateStringParameter: function(filter, parameterName, value) {},
|
||||
updateBooleanParameter: function(filter, parameterName, value) {},
|
||||
});
|
17
Extensions/Effects/ascii-pixi-filter.ts
Normal file
17
Extensions/Effects/ascii-pixi-filter.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
namespace gdjs {
|
||||
gdjs.PixiFiltersTools.registerFilterCreator('Ascii', {
|
||||
makePIXIFilter: function (layer, effectData) {
|
||||
const asciiFilter = new PIXI.filters.AsciiFilter();
|
||||
return asciiFilter;
|
||||
},
|
||||
update: function (filter, layer) {},
|
||||
updateDoubleParameter: function (filter, parameterName, value) {
|
||||
const asciiFilter = filter as PIXI.filters.AsciiFilter;
|
||||
if (parameterName === 'size') {
|
||||
asciiFilter.size = value;
|
||||
}
|
||||
},
|
||||
updateStringParameter: function (filter, parameterName, value) {},
|
||||
updateBooleanParameter: function (filter, parameterName, value) {},
|
||||
});
|
||||
}
|
@@ -1,30 +0,0 @@
|
||||
gdjs.PixiFiltersTools.registerFilterCreator('Bevel', {
|
||||
makePIXIFilter: function(layer, effectData) {
|
||||
var bevelFilter = new PIXI.filters.BevelFilter();
|
||||
|
||||
return bevelFilter;
|
||||
},
|
||||
update: function(filter, layer) {},
|
||||
updateDoubleParameter: function(filter, parameterName, value) {
|
||||
if (parameterName === 'rotation') {
|
||||
filter.rotation = value;
|
||||
} else if (parameterName === 'thickness') {
|
||||
filter.thickness = value;
|
||||
} else if (parameterName === 'distance') {
|
||||
filter.distance = value;
|
||||
} else if (parameterName === 'lightAlpha') {
|
||||
filter.lightAlpha = value;
|
||||
} else if (parameterName === 'shadowAlpha') {
|
||||
filter.shadowAlpha = value;
|
||||
}
|
||||
},
|
||||
updateStringParameter: function(filter, parameterName, value) {
|
||||
if (parameterName === 'lightColor') {
|
||||
filter.lightColor = gdjs.PixiFiltersTools.rgbOrHexToHexNumber(value);
|
||||
}
|
||||
if (parameterName === 'shadowColor') {
|
||||
filter.shadowColor = gdjs.PixiFiltersTools.rgbOrHexToHexNumber(value);
|
||||
}
|
||||
},
|
||||
updateBooleanParameter: function(filter, parameterName, value) {},
|
||||
});
|
34
Extensions/Effects/bevel-pixi-filter.ts
Normal file
34
Extensions/Effects/bevel-pixi-filter.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
namespace gdjs {
|
||||
gdjs.PixiFiltersTools.registerFilterCreator('Bevel', {
|
||||
makePIXIFilter: function (layer, effectData) {
|
||||
const bevelFilter = new PIXI.filters.BevelFilter();
|
||||
return bevelFilter;
|
||||
},
|
||||
update: function (filter, layer) {},
|
||||
updateDoubleParameter: function (filter, parameterName, value) {
|
||||
const bevelFilter = filter as PIXI.filters.BevelFilter;
|
||||
if (parameterName === 'rotation') {
|
||||
bevelFilter.rotation = value;
|
||||
} else if (parameterName === 'thickness') {
|
||||
bevelFilter.thickness = value;
|
||||
} else if (parameterName === 'distance') {
|
||||
// @ts-ignore
|
||||
bevelFilter.distance = value;
|
||||
} else if (parameterName === 'lightAlpha') {
|
||||
bevelFilter.lightAlpha = value;
|
||||
} else if (parameterName === 'shadowAlpha') {
|
||||
bevelFilter.shadowAlpha = value;
|
||||
}
|
||||
},
|
||||
updateStringParameter: function (filter, parameterName, value) {
|
||||
const bevelFilter = filter as PIXI.filters.BevelFilter;
|
||||
if (parameterName === 'lightColor') {
|
||||
bevelFilter.lightColor = gdjs.PixiFiltersTools.rgbOrHexToHexNumber(value);
|
||||
}
|
||||
if (parameterName === 'shadowColor') {
|
||||
bevelFilter.shadowColor = gdjs.PixiFiltersTools.rgbOrHexToHexNumber(value);
|
||||
}
|
||||
},
|
||||
updateBooleanParameter: function (filter, parameterName, value) {},
|
||||
});
|
||||
}
|
@@ -1,15 +0,0 @@
|
||||
gdjs.PixiFiltersTools.registerFilterCreator('BlackAndWhite', {
|
||||
makePIXIFilter: function(layer, effectData) {
|
||||
var colorMatrix = new PIXI.filters.ColorMatrixFilter();
|
||||
colorMatrix.blackAndWhite();
|
||||
return colorMatrix;
|
||||
},
|
||||
update: function(filter, layer) {},
|
||||
updateDoubleParameter: function(filter, parameterName, value) {
|
||||
if (parameterName !== 'opacity') return;
|
||||
|
||||
filter.alpha = gdjs.PixiFiltersTools.clampValue(value, 0, 1);
|
||||
},
|
||||
updateStringParameter: function(filter, parameterName, value) {},
|
||||
updateBooleanParameter: function(filter, parameterName, value) {},
|
||||
});
|
19
Extensions/Effects/black-and-white-pixi-filter.ts
Normal file
19
Extensions/Effects/black-and-white-pixi-filter.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
namespace gdjs {
|
||||
gdjs.PixiFiltersTools.registerFilterCreator('BlackAndWhite', {
|
||||
makePIXIFilter: function (layer, effectData) {
|
||||
const colorMatrix = new PIXI.filters.ColorMatrixFilter();
|
||||
colorMatrix.blackAndWhite(false);
|
||||
return colorMatrix;
|
||||
},
|
||||
update: function (filter, layer) {},
|
||||
updateDoubleParameter: function (filter, parameterName, value) {
|
||||
const colorMatrix = filter as PIXI.filters.ColorMatrixFilter;
|
||||
if (parameterName !== 'opacity') {
|
||||
return;
|
||||
}
|
||||
colorMatrix.alpha = gdjs.PixiFiltersTools.clampValue(value, 0, 1);
|
||||
},
|
||||
updateStringParameter: function (filter, parameterName, value) {},
|
||||
updateBooleanParameter: function (filter, parameterName, value) {},
|
||||
});
|
||||
}
|
@@ -1,18 +0,0 @@
|
||||
gdjs.PixiFiltersTools.registerFilterCreator('BlendingMode', {
|
||||
makePIXIFilter: function(layer, effectData) {
|
||||
var blendingModeFilter = new PIXI.filters.AlphaFilter();
|
||||
|
||||
return blendingModeFilter;
|
||||
},
|
||||
update: function(filter, layer) {},
|
||||
updateDoubleParameter: function(filter, parameterName, value) {
|
||||
if (parameterName === 'alpha') {
|
||||
filter.alpha = value;
|
||||
}
|
||||
if (parameterName === 'blendmode') {
|
||||
filter.blendMode = value;
|
||||
}
|
||||
},
|
||||
updateStringParameter: function(filter, parameterName, value) {},
|
||||
updateBooleanParameter: function(filter, parameterName, value) {},
|
||||
});
|
19
Extensions/Effects/blending-mode-pixi-filter.ts
Normal file
19
Extensions/Effects/blending-mode-pixi-filter.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
namespace gdjs {
|
||||
gdjs.PixiFiltersTools.registerFilterCreator('BlendingMode', {
|
||||
makePIXIFilter: function (layer, effectData) {
|
||||
const blendingModeFilter = new PIXI.filters.AlphaFilter();
|
||||
return blendingModeFilter;
|
||||
},
|
||||
update: function (filter, layer) {},
|
||||
updateDoubleParameter: function (filter, parameterName, value) {
|
||||
const blendingModeFilter = filter as PIXI.filters.AlphaFilter;
|
||||
if (parameterName === 'alpha') {
|
||||
blendingModeFilter.alpha = value;
|
||||
} else if (parameterName === 'blendmode') {
|
||||
blendingModeFilter.blendMode = value;
|
||||
}
|
||||
},
|
||||
updateStringParameter: function (filter, parameterName, value) {},
|
||||
updateBooleanParameter: function (filter, parameterName, value) {},
|
||||
});
|
||||
}
|
@@ -1,24 +0,0 @@
|
||||
gdjs.PixiFiltersTools.registerFilterCreator('Blur', {
|
||||
makePIXIFilter: function(layer, effectData) {
|
||||
var blur = new PIXI.filters.BlurFilter();
|
||||
return blur;
|
||||
},
|
||||
update: function(filter, layer) {},
|
||||
updateDoubleParameter: function(filter, parameterName, value) {
|
||||
if (
|
||||
parameterName !== 'blur' &&
|
||||
parameterName !== 'quality' &&
|
||||
parameterName !== 'kernelSize' &&
|
||||
parameterName !== 'resolution'
|
||||
)
|
||||
return;
|
||||
|
||||
if (parameterName === 'kernelSize') {
|
||||
value = gdjs.PixiFiltersTools.clampKernelSize(value, 5, 15);
|
||||
}
|
||||
|
||||
filter[parameterName] = value;
|
||||
},
|
||||
updateStringParameter: function(filter, parameterName, value) {},
|
||||
updateBooleanParameter: function(filter, parameterName, value) {},
|
||||
});
|
25
Extensions/Effects/blur-pixi-filter.ts
Normal file
25
Extensions/Effects/blur-pixi-filter.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
namespace gdjs {
|
||||
gdjs.PixiFiltersTools.registerFilterCreator('Blur', {
|
||||
makePIXIFilter: function (layer, effectData) {
|
||||
const blur = new PIXI.filters.BlurFilter();
|
||||
return blur;
|
||||
},
|
||||
update: function (filter, layer) {},
|
||||
updateDoubleParameter: function (filter, parameterName, value) {
|
||||
if (
|
||||
parameterName !== 'blur' &&
|
||||
parameterName !== 'quality' &&
|
||||
parameterName !== 'kernelSize' &&
|
||||
parameterName !== 'resolution'
|
||||
) {
|
||||
return;
|
||||
}
|
||||
if (parameterName === 'kernelSize') {
|
||||
value = gdjs.PixiFiltersTools.clampKernelSize(value, 5, 15);
|
||||
}
|
||||
filter[parameterName] = value;
|
||||
},
|
||||
updateStringParameter: function (filter, parameterName, value) {},
|
||||
updateBooleanParameter: function (filter, parameterName, value) {},
|
||||
});
|
||||
}
|
@@ -1,15 +0,0 @@
|
||||
gdjs.PixiFiltersTools.registerFilterCreator('Brightness', {
|
||||
makePIXIFilter: function(layer, effectData) {
|
||||
var brightness = new PIXI.filters.ColorMatrixFilter();
|
||||
brightness.brightness(1);
|
||||
return brightness;
|
||||
},
|
||||
update: function(filter, layer) {},
|
||||
updateDoubleParameter: function(filter, parameterName, value) {
|
||||
if (parameterName !== 'brightness') return;
|
||||
|
||||
filter.brightness(gdjs.PixiFiltersTools.clampValue(value, 0, 1));
|
||||
},
|
||||
updateStringParameter: function(filter, parameterName, value) {},
|
||||
updateBooleanParameter: function(filter, parameterName, value) {},
|
||||
});
|
19
Extensions/Effects/brightness-pixi-filter.ts
Normal file
19
Extensions/Effects/brightness-pixi-filter.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
namespace gdjs {
|
||||
gdjs.PixiFiltersTools.registerFilterCreator('Brightness', {
|
||||
makePIXIFilter: function (layer, effectData) {
|
||||
const brightness = new PIXI.filters.ColorMatrixFilter();
|
||||
brightness.brightness(1, false);
|
||||
return brightness;
|
||||
},
|
||||
update: function (filter, layer) {},
|
||||
updateDoubleParameter: function (filter, parameterName, value) {
|
||||
const brightnessFilter = filter as PIXI.filters.ColorMatrixFilter;
|
||||
if (parameterName !== 'brightness') {
|
||||
return;
|
||||
}
|
||||
brightnessFilter.brightness(gdjs.PixiFiltersTools.clampValue(value, 0, 1), false);
|
||||
},
|
||||
updateStringParameter: function (filter, parameterName, value) {},
|
||||
updateBooleanParameter: function (filter, parameterName, value) {},
|
||||
});
|
||||
}
|
@@ -1,27 +0,0 @@
|
||||
gdjs.PixiFiltersTools.registerFilterCreator('BulgePinch', {
|
||||
makePIXIFilter: function(layer, effectData) {
|
||||
var bulgePinchFilter = new PIXI.filters.BulgePinchFilter();
|
||||
|
||||
return bulgePinchFilter;
|
||||
},
|
||||
update: function(filter, layer) {
|
||||
},
|
||||
updateDoubleParameter: function(filter, parameterName, value) {
|
||||
if (parameterName === 'centerX') {
|
||||
filter.center[0] = value;
|
||||
}
|
||||
else if (parameterName === 'centerY') {
|
||||
filter.center[1] = value;
|
||||
}
|
||||
else if (parameterName === 'radius') {
|
||||
filter.radius = value;
|
||||
}
|
||||
else if (parameterName === 'strength') {
|
||||
filter.strength = gdjs.PixiFiltersTools.clampValue(value, -1, 1);
|
||||
}
|
||||
},
|
||||
updateStringParameter: function(filter, parameterName, value) {
|
||||
},
|
||||
updateBooleanParameter: function(filter, parameterName, value) {
|
||||
},
|
||||
});
|
23
Extensions/Effects/bulge-pinch-pixi-filter.ts
Normal file
23
Extensions/Effects/bulge-pinch-pixi-filter.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
namespace gdjs {
|
||||
gdjs.PixiFiltersTools.registerFilterCreator('BulgePinch', {
|
||||
makePIXIFilter: function (layer, effectData) {
|
||||
const bulgePinchFilter = new PIXI.filters.BulgePinchFilter();
|
||||
return bulgePinchFilter;
|
||||
},
|
||||
update: function (filter, layer) {},
|
||||
updateDoubleParameter: function (filter, parameterName, value) {
|
||||
const bulgePinchFilter = filter as PIXI.filters.BulgePinchFilter;
|
||||
if (parameterName === 'centerX') {
|
||||
bulgePinchFilter.center[0] = value;
|
||||
} else if (parameterName === 'centerY') {
|
||||
bulgePinchFilter.center[1] = value;
|
||||
} else if (parameterName === 'radius') {
|
||||
bulgePinchFilter.radius = value;
|
||||
} else if (parameterName === 'strength') {
|
||||
bulgePinchFilter.strength = gdjs.PixiFiltersTools.clampValue(value, -1, 1);
|
||||
}
|
||||
},
|
||||
updateStringParameter: function (filter, parameterName, value) {},
|
||||
updateBooleanParameter: function (filter, parameterName, value) {},
|
||||
});
|
||||
}
|
@@ -1,34 +0,0 @@
|
||||
gdjs.PixiFiltersTools.registerFilterCreator("ColorMap", {
|
||||
makePIXIFilter: function(layer, effectData) {
|
||||
const colorMapTexture = layer
|
||||
.getRuntimeScene()
|
||||
.getGame()
|
||||
.getImageManager()
|
||||
.getPIXITexture(effectData.stringParameters.colorMapTexture);
|
||||
|
||||
const colorMapSprite = new PIXI.Sprite(colorMapTexture);
|
||||
const colorMapFilter = new PIXI.filters.ColorMapFilter(
|
||||
colorMapTexture,
|
||||
effectData.booleanParameters.nearest,
|
||||
gdjs.PixiFiltersTools.clampValue(
|
||||
effectData.doubleParameters.mix / 100,
|
||||
0,
|
||||
1
|
||||
)
|
||||
);
|
||||
|
||||
return colorMapFilter;
|
||||
},
|
||||
update: function(filter, layer) {},
|
||||
updateDoubleParameter: function(filter, parameterName, value) {
|
||||
if (parameterName === "mix") {
|
||||
filter.mix = gdjs.PixiFiltersTools.clampValue(value / 100, 0, 1);
|
||||
}
|
||||
},
|
||||
updateStringParameter: function(filter, parameterName, value) {},
|
||||
updateBooleanParameter: function(filter, parameterName, value) {
|
||||
if (parameterName === "nearest") {
|
||||
filter.nearest = value;
|
||||
}
|
||||
}
|
||||
});
|
36
Extensions/Effects/color-map-pixi-filter.ts
Normal file
36
Extensions/Effects/color-map-pixi-filter.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
namespace gdjs {
|
||||
gdjs.PixiFiltersTools.registerFilterCreator('ColorMap', {
|
||||
makePIXIFilter: function (layer, effectData) {
|
||||
const colorMapTexture = layer
|
||||
.getRuntimeScene()
|
||||
.getGame()
|
||||
.getImageManager()
|
||||
.getPIXITexture(effectData.stringParameters.colorMapTexture);
|
||||
const colorMapSprite = new PIXI.Sprite(colorMapTexture);
|
||||
const colorMapFilter = new PIXI.filters.ColorMapFilter(
|
||||
colorMapTexture,
|
||||
effectData.booleanParameters.nearest,
|
||||
gdjs.PixiFiltersTools.clampValue(
|
||||
effectData.doubleParameters.mix / 100,
|
||||
0,
|
||||
1
|
||||
)
|
||||
);
|
||||
return colorMapFilter;
|
||||
},
|
||||
update: function (filter, layer) {},
|
||||
updateDoubleParameter: function (filter, parameterName, value) {
|
||||
const colorMapFilter = filter as PIXI.filters.ColorMapFilter;
|
||||
if (parameterName === 'mix') {
|
||||
colorMapFilter.mix = gdjs.PixiFiltersTools.clampValue(value / 100, 0, 1);
|
||||
}
|
||||
},
|
||||
updateStringParameter: function (filter, parameterName, value) {},
|
||||
updateBooleanParameter: function (filter, parameterName, value) {
|
||||
const colorMapFilter = filter as PIXI.filters.ColorMapFilter;
|
||||
if (parameterName === 'nearest') {
|
||||
colorMapFilter.nearest = value;
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
@@ -1,22 +0,0 @@
|
||||
gdjs.PixiFiltersTools.registerFilterCreator('ColorReplace', {
|
||||
makePIXIFilter: function(layer, effectData) {
|
||||
var colorReplaceFilter = new PIXI.filters.ColorReplaceFilter();
|
||||
|
||||
return colorReplaceFilter;
|
||||
},
|
||||
update: function(filter, layer) {},
|
||||
updateDoubleParameter: function(filter, parameterName, value) {
|
||||
if (parameterName === 'epsilon') {
|
||||
filter.epsilon = value;
|
||||
}
|
||||
},
|
||||
updateStringParameter: function(filter, parameterName, value) {
|
||||
if (parameterName === 'originalColor') {
|
||||
filter.originalColor = gdjs.PixiFiltersTools.rgbOrHexToHexNumber(value);
|
||||
}
|
||||
else if (parameterName === 'newColor') {
|
||||
filter.newColor = gdjs.PixiFiltersTools.rgbOrHexToHexNumber(value);
|
||||
}
|
||||
},
|
||||
updateBooleanParameter: function(filter, parameterName, value) {},
|
||||
});
|
24
Extensions/Effects/color-replace-pixi-filter.ts
Normal file
24
Extensions/Effects/color-replace-pixi-filter.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
namespace gdjs {
|
||||
gdjs.PixiFiltersTools.registerFilterCreator('ColorReplace', {
|
||||
makePIXIFilter: function (layer, effectData) {
|
||||
const colorReplaceFilter = new PIXI.filters.ColorReplaceFilter();
|
||||
return colorReplaceFilter;
|
||||
},
|
||||
update: function (filter, layer) {},
|
||||
updateDoubleParameter: function (filter, parameterName, value) {
|
||||
const colorReplaceFilter = filter as PIXI.filters.ColorReplaceFilter;
|
||||
if (parameterName === 'epsilon') {
|
||||
colorReplaceFilter.epsilon = value;
|
||||
}
|
||||
},
|
||||
updateStringParameter: function (filter, parameterName, value) {
|
||||
const colorReplaceFilter = filter as PIXI.filters.ColorReplaceFilter;
|
||||
if (parameterName === 'originalColor') {
|
||||
colorReplaceFilter.originalColor = gdjs.PixiFiltersTools.rgbOrHexToHexNumber(value);
|
||||
} else if (parameterName === 'newColor') {
|
||||
colorReplaceFilter.newColor = gdjs.PixiFiltersTools.rgbOrHexToHexNumber(value);
|
||||
}
|
||||
},
|
||||
updateBooleanParameter: function (filter, parameterName, value) {},
|
||||
});
|
||||
}
|
@@ -1,49 +0,0 @@
|
||||
gdjs.PixiFiltersTools.registerFilterCreator('CRT', {
|
||||
makePIXIFilter: function(layer, effectData) {
|
||||
var crtFilter = new PIXI.filters.CRTFilter();
|
||||
crtFilter._animationTimer = 0;
|
||||
return crtFilter;
|
||||
},
|
||||
update: function(filter, layer) {
|
||||
if (filter.animationSpeed !== 0) {
|
||||
// Multiply by 10 so that the default value is a sensible speed
|
||||
filter.time += layer.getElapsedTime() / 1000 * 10 * filter.animationSpeed;
|
||||
}
|
||||
if (filter.animationFrequency !== 0) {
|
||||
filter._animationTimer += layer.getElapsedTime() / 1000;
|
||||
if (filter._animationTimer >= 1 / filter.animationFrequency) {
|
||||
filter.seed = Math.random();
|
||||
filter._animationTimer = 0;
|
||||
}
|
||||
}
|
||||
},
|
||||
updateDoubleParameter: function(filter, parameterName, value) {
|
||||
if (parameterName === 'lineWidth') {
|
||||
filter.lineWidth = value;
|
||||
} else if (parameterName === 'lineContrast') {
|
||||
filter.lineContrast = value;
|
||||
} else if (parameterName === 'noise') {
|
||||
filter.noise = value;
|
||||
} else if (parameterName === 'curvature') {
|
||||
filter.curvature = value;
|
||||
} else if (parameterName === 'noiseSize') {
|
||||
filter.noiseSize = value;
|
||||
} else if (parameterName === 'vignetting') {
|
||||
filter.vignetting = value;
|
||||
} else if (parameterName === 'vignettingAlpha') {
|
||||
filter.vignettingAlpha = value;
|
||||
} else if (parameterName === 'vignettingBlur') {
|
||||
filter.vignettingBlur = value;
|
||||
} else if (parameterName === 'animationSpeed') {
|
||||
filter.animationSpeed = value;
|
||||
} else if (parameterName === 'animationFrequency') {
|
||||
filter.animationFrequency = value;
|
||||
}
|
||||
},
|
||||
updateStringParameter: function(filter, parameterName, value) {},
|
||||
updateBooleanParameter: function(filter, parameterName, value) {
|
||||
if (parameterName === 'verticalLine') {
|
||||
filter.verticalLine = value;
|
||||
}
|
||||
},
|
||||
});
|
54
Extensions/Effects/crt-pixi-filter.ts
Normal file
54
Extensions/Effects/crt-pixi-filter.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
// @ts-nocheck - TODO: fix typings in this file
|
||||
|
||||
namespace gdjs {
|
||||
gdjs.PixiFiltersTools.registerFilterCreator('CRT', {
|
||||
makePIXIFilter: function (layer, effectData) {
|
||||
const crtFilter = new PIXI.filters.CRTFilter();
|
||||
crtFilter._animationTimer = 0;
|
||||
return crtFilter;
|
||||
},
|
||||
update: function (filter, layer) {
|
||||
if (filter.animationSpeed !== 0) {
|
||||
// Multiply by 10 so that the default value is a sensible speed
|
||||
filter.time +=
|
||||
(layer.getElapsedTime() / 1000) * 10 * filter.animationSpeed;
|
||||
}
|
||||
if (filter.animationFrequency !== 0) {
|
||||
filter._animationTimer += layer.getElapsedTime() / 1000;
|
||||
if (filter._animationTimer >= 1 / filter.animationFrequency) {
|
||||
filter.seed = Math.random();
|
||||
filter._animationTimer = 0;
|
||||
}
|
||||
}
|
||||
},
|
||||
updateDoubleParameter: function (filter, parameterName, value) {
|
||||
if (parameterName === 'lineWidth') {
|
||||
filter.lineWidth = value;
|
||||
} else if (parameterName === 'lineContrast') {
|
||||
filter.lineContrast = value;
|
||||
} else if (parameterName === 'noise') {
|
||||
filter.noise = value;
|
||||
} else if (parameterName === 'curvature') {
|
||||
filter.curvature = value;
|
||||
} else if (parameterName === 'noiseSize') {
|
||||
filter.noiseSize = value;
|
||||
} else if (parameterName === 'vignetting') {
|
||||
filter.vignetting = value;
|
||||
} else if (parameterName === 'vignettingAlpha') {
|
||||
filter.vignettingAlpha = value;
|
||||
} else if (parameterName === 'vignettingBlur') {
|
||||
filter.vignettingBlur = value;
|
||||
} else if (parameterName === 'animationSpeed') {
|
||||
filter.animationSpeed = value;
|
||||
} else if (parameterName === 'animationFrequency') {
|
||||
filter.animationFrequency = value;
|
||||
}
|
||||
},
|
||||
updateStringParameter: function (filter, parameterName, value) {},
|
||||
updateBooleanParameter: function (filter, parameterName, value) {
|
||||
if (parameterName === 'verticalLine') {
|
||||
filter.verticalLine = value;
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
@@ -1,30 +0,0 @@
|
||||
gdjs.PixiFiltersTools.registerFilterCreator("Displacement", {
|
||||
makePIXIFilter: function(layer, effectData) {
|
||||
const displacementMapTexture = layer
|
||||
.getRuntimeScene()
|
||||
.getGame()
|
||||
.getImageManager()
|
||||
.getPIXITexture(effectData.stringParameters.displacementMapTexture);
|
||||
|
||||
displacementMapTexture.baseTexture.wrapMode = PIXI.WRAP_MODES.REPEAT;
|
||||
|
||||
const displacementSprite = new PIXI.Sprite(displacementMapTexture);
|
||||
const displacementFilter = new PIXI.filters.DisplacementFilter(
|
||||
displacementSprite
|
||||
);
|
||||
|
||||
return displacementFilter;
|
||||
},
|
||||
update: function(filter, layer) {},
|
||||
updateDoubleParameter: function(filter, parameterName, value) {
|
||||
if (parameterName === "scaleX") {
|
||||
filter.scale.x = value;
|
||||
}
|
||||
|
||||
if (parameterName === "scaleY") {
|
||||
filter.scale.y = value;
|
||||
}
|
||||
},
|
||||
updateStringParameter: function(filter, parameterName, value) {},
|
||||
updateBooleanParameter: function(filter, parameterName, value) {}
|
||||
});
|
29
Extensions/Effects/displacement-pixi-filter.ts
Normal file
29
Extensions/Effects/displacement-pixi-filter.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
namespace gdjs {
|
||||
gdjs.PixiFiltersTools.registerFilterCreator('Displacement', {
|
||||
makePIXIFilter: function (layer, effectData) {
|
||||
const displacementMapTexture = layer
|
||||
.getRuntimeScene()
|
||||
.getGame()
|
||||
.getImageManager()
|
||||
.getPIXITexture(effectData.stringParameters.displacementMapTexture);
|
||||
displacementMapTexture.baseTexture.wrapMode = PIXI.WRAP_MODES.REPEAT;
|
||||
const displacementSprite = new PIXI.Sprite(displacementMapTexture);
|
||||
const displacementFilter = new PIXI.filters.DisplacementFilter(
|
||||
displacementSprite
|
||||
);
|
||||
return displacementFilter;
|
||||
},
|
||||
update: function (filter, layer) {},
|
||||
updateDoubleParameter: function (filter, parameterName, value) {
|
||||
const displacementFilter = filter as PIXI.filters.DisplacementFilter;
|
||||
if (parameterName === 'scaleX') {
|
||||
displacementFilter.scale.x = value;
|
||||
}
|
||||
if (parameterName === 'scaleY') {
|
||||
displacementFilter.scale.y = value;
|
||||
}
|
||||
},
|
||||
updateStringParameter: function (filter, parameterName, value) {},
|
||||
updateBooleanParameter: function (filter, parameterName, value) {},
|
||||
});
|
||||
}
|
@@ -1,18 +0,0 @@
|
||||
gdjs.PixiFiltersTools.registerFilterCreator('Dot', {
|
||||
makePIXIFilter: function(layer, effectData) {
|
||||
var dotFilter = new PIXI.filters.DotFilter();
|
||||
|
||||
return dotFilter;
|
||||
},
|
||||
update: function(filter, layer) {},
|
||||
updateDoubleParameter: function(filter, parameterName, value) {
|
||||
if (parameterName === 'scale') {
|
||||
filter.scale = value;
|
||||
}
|
||||
else if (parameterName === 'angle') {
|
||||
filter.angle = value;
|
||||
}
|
||||
},
|
||||
updateStringParameter: function(filter, parameterName, value) {},
|
||||
updateBooleanParameter: function(filter, parameterName, value) {},
|
||||
});
|
19
Extensions/Effects/dot-pixi-filter.ts
Normal file
19
Extensions/Effects/dot-pixi-filter.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
namespace gdjs {
|
||||
gdjs.PixiFiltersTools.registerFilterCreator('Dot', {
|
||||
makePIXIFilter: function (layer, effectData) {
|
||||
const dotFilter = new PIXI.filters.DotFilter();
|
||||
return dotFilter;
|
||||
},
|
||||
update: function (filter, layer) {},
|
||||
updateDoubleParameter: function (filter, parameterName, value) {
|
||||
const dotFilter = filter as PIXI.filters.DotFilter;
|
||||
if (parameterName === 'scale') {
|
||||
dotFilter.scale = value;
|
||||
} else if (parameterName === 'angle') {
|
||||
dotFilter.angle = value;
|
||||
}
|
||||
},
|
||||
updateStringParameter: function (filter, parameterName, value) {},
|
||||
updateBooleanParameter: function (filter, parameterName, value) {},
|
||||
});
|
||||
}
|
@@ -1,31 +0,0 @@
|
||||
gdjs.PixiFiltersTools.registerFilterCreator('DropShadow', {
|
||||
makePIXIFilter: function(layer, effectData) {
|
||||
var dropShadowFilter = new PIXI.filters.DropShadowFilter();
|
||||
|
||||
return dropShadowFilter;
|
||||
},
|
||||
update: function(filter, layer) {},
|
||||
updateDoubleParameter: function(filter, parameterName, value) {
|
||||
if (parameterName === 'blur') {
|
||||
filter.blur = value;
|
||||
} else if (parameterName === 'quality') {
|
||||
filter.quality = value;
|
||||
} else if (parameterName === 'alpha') {
|
||||
filter.alpha = value;
|
||||
} else if (parameterName === 'distance') {
|
||||
filter.distance = value;
|
||||
} else if (parameterName === 'rotation') {
|
||||
filter.rotation = value;
|
||||
}
|
||||
},
|
||||
updateStringParameter: function(filter, parameterName, value) {
|
||||
if (parameterName === 'color') {
|
||||
filter.color = gdjs.PixiFiltersTools.rgbOrHexToHexNumber(value);
|
||||
}
|
||||
},
|
||||
updateBooleanParameter: function(filter, parameterName, value) {
|
||||
if (parameterName === 'shadowOnly') {
|
||||
filter.shadowOnly = value;
|
||||
}
|
||||
},
|
||||
});
|
35
Extensions/Effects/drop-shadow-pixi-filter.ts
Normal file
35
Extensions/Effects/drop-shadow-pixi-filter.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
namespace gdjs {
|
||||
gdjs.PixiFiltersTools.registerFilterCreator('DropShadow', {
|
||||
makePIXIFilter: function (layer, effectData) {
|
||||
const dropShadowFilter = new PIXI.filters.DropShadowFilter();
|
||||
return dropShadowFilter;
|
||||
},
|
||||
update: function (filter, layer) {},
|
||||
updateDoubleParameter: function (filter, parameterName, value) {
|
||||
const dropShadowFilter = filter as PIXI.filters.DropShadowFilter;
|
||||
if (parameterName === 'blur') {
|
||||
dropShadowFilter.blur = value;
|
||||
} else if (parameterName === 'quality') {
|
||||
dropShadowFilter.quality = value;
|
||||
} else if (parameterName === 'alpha') {
|
||||
dropShadowFilter.alpha = value;
|
||||
} else if (parameterName === 'distance') {
|
||||
dropShadowFilter.distance = value;
|
||||
} else if (parameterName === 'rotation') {
|
||||
dropShadowFilter.rotation = value;
|
||||
}
|
||||
},
|
||||
updateStringParameter: function (filter, parameterName, value) {
|
||||
const dropShadowFilter = filter as PIXI.filters.DropShadowFilter;
|
||||
if (parameterName === 'color') {
|
||||
dropShadowFilter.color = gdjs.PixiFiltersTools.rgbOrHexToHexNumber(value);
|
||||
}
|
||||
},
|
||||
updateBooleanParameter: function (filter, parameterName, value) {
|
||||
const dropShadowFilter = filter as PIXI.filters.DropShadowFilter;
|
||||
if (parameterName === 'shadowOnly') {
|
||||
dropShadowFilter.shadowOnly = value;
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
@@ -1,64 +0,0 @@
|
||||
gdjs.PixiFiltersTools.registerFilterCreator('Glitch', {
|
||||
makePIXIFilter: function(layer, effectData) {
|
||||
var glitchFilter = new PIXI.filters.GlitchFilter();
|
||||
glitchFilter._animationTimer = 0;
|
||||
return glitchFilter;
|
||||
},
|
||||
update: function(filter, layer) {
|
||||
if (filter.animationFrequency !== 0) {
|
||||
filter._animationTimer += layer.getElapsedTime() / 1000;
|
||||
if (filter._animationTimer >= 1 / filter.animationFrequency) {
|
||||
filter.seed = Math.random();
|
||||
filter._animationTimer = 0;
|
||||
}
|
||||
}
|
||||
},
|
||||
updateDoubleParameter: function(filter, parameterName, value) {
|
||||
if (parameterName === 'slices') {
|
||||
filter.slices = value;
|
||||
}
|
||||
else if (parameterName === 'offset') {
|
||||
filter.offset = value;
|
||||
}
|
||||
else if (parameterName === 'direction') {
|
||||
filter.direction = value;
|
||||
}
|
||||
else if (parameterName === 'fillMode') {
|
||||
filter.fillMode = value;
|
||||
}
|
||||
else if (parameterName === 'minSize') {
|
||||
filter.minSize = value;
|
||||
}
|
||||
else if (parameterName === 'sampleSize') {
|
||||
filter.sampleSize = value;
|
||||
}
|
||||
else if (parameterName === 'redX') {
|
||||
filter.red.x = value;
|
||||
}
|
||||
else if (parameterName === 'redY') {
|
||||
filter.red.y = value;
|
||||
}
|
||||
else if (parameterName === 'greenX') {
|
||||
filter.green.x = value;
|
||||
}
|
||||
else if (parameterName === 'greenY') {
|
||||
filter.green.y = value;
|
||||
}
|
||||
else if (parameterName === 'blueX') {
|
||||
filter.blue.x = value;
|
||||
}
|
||||
else if (parameterName === 'blueY') {
|
||||
filter.blue.y = value;
|
||||
}
|
||||
else if (parameterName === 'animationFrequency') {
|
||||
filter.animationFrequency = value;
|
||||
}
|
||||
|
||||
},
|
||||
updateStringParameter: function(filter, parameterName, value) {},
|
||||
updateBooleanParameter: function(filter, parameterName, value) {
|
||||
if (parameterName === 'average') {
|
||||
filter.average = value;
|
||||
}
|
||||
},
|
||||
});
|
55
Extensions/Effects/glitch-pixi-filter.ts
Normal file
55
Extensions/Effects/glitch-pixi-filter.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
// @ts-nocheck - TODO: fix typings in this file
|
||||
|
||||
namespace gdjs {
|
||||
gdjs.PixiFiltersTools.registerFilterCreator('Glitch', {
|
||||
makePIXIFilter: function (layer, effectData) {
|
||||
const glitchFilter = new PIXI.filters.GlitchFilter();
|
||||
glitchFilter._animationTimer = 0;
|
||||
return glitchFilter;
|
||||
},
|
||||
update: function (filter, layer) {
|
||||
if (filter.animationFrequency !== 0) {
|
||||
filter._animationTimer += layer.getElapsedTime() / 1000;
|
||||
if (filter._animationTimer >= 1 / filter.animationFrequency) {
|
||||
filter.seed = Math.random();
|
||||
filter._animationTimer = 0;
|
||||
}
|
||||
}
|
||||
},
|
||||
updateDoubleParameter: function (filter, parameterName, value) {
|
||||
if (parameterName === 'slices') {
|
||||
filter.slices = value;
|
||||
} else if (parameterName === 'offset') {
|
||||
filter.offset = value;
|
||||
} else if (parameterName === 'direction') {
|
||||
filter.direction = value;
|
||||
} else if (parameterName === 'fillMode') {
|
||||
filter.fillMode = value;
|
||||
} else if (parameterName === 'minSize') {
|
||||
filter.minSize = value;
|
||||
} else if (parameterName === 'sampleSize') {
|
||||
filter.sampleSize = value;
|
||||
} else if (parameterName === 'redX') {
|
||||
filter.red.x = value;
|
||||
} else if (parameterName === 'redY') {
|
||||
filter.red.y = value;
|
||||
} else if (parameterName === 'greenX') {
|
||||
filter.green.x = value;
|
||||
} else if (parameterName === 'greenY') {
|
||||
filter.green.y = value;
|
||||
} else if (parameterName === 'blueX') {
|
||||
filter.blue.x = value;
|
||||
} else if (parameterName === 'blueY') {
|
||||
filter.blue.y = value;
|
||||
} else if (parameterName === 'animationFrequency') {
|
||||
filter.animationFrequency = value;
|
||||
}
|
||||
},
|
||||
updateStringParameter: function (filter, parameterName, value) {},
|
||||
updateBooleanParameter: function (filter, parameterName, value) {
|
||||
if (parameterName === 'average') {
|
||||
filter.average = value;
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
@@ -1,23 +0,0 @@
|
||||
gdjs.PixiFiltersTools.registerFilterCreator('Glow', {
|
||||
makePIXIFilter: function(layer, effectData) {
|
||||
var glowFilter = new PIXI.filters.GlowFilter();
|
||||
|
||||
return glowFilter;
|
||||
},
|
||||
update: function(filter, layer) {},
|
||||
updateDoubleParameter: function(filter, parameterName, value) {
|
||||
if (parameterName === 'innerStrength') {
|
||||
filter.innerStrength = value;
|
||||
} else if (parameterName === 'outerStrength') {
|
||||
filter.outerStrength = value;
|
||||
} else if (parameterName === 'distance') {
|
||||
filter.distance = value;
|
||||
}
|
||||
},
|
||||
updateStringParameter: function(filter, parameterName, value) {
|
||||
if (parameterName === 'color') {
|
||||
filter.color = gdjs.PixiFiltersTools.rgbOrHexToHexNumber(value);
|
||||
}
|
||||
},
|
||||
updateBooleanParameter: function(filter, parameterName, value) {},
|
||||
});
|
27
Extensions/Effects/glow-pixi-filter.ts
Normal file
27
Extensions/Effects/glow-pixi-filter.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
namespace gdjs {
|
||||
gdjs.PixiFiltersTools.registerFilterCreator('Glow', {
|
||||
makePIXIFilter: function (layer, effectData) {
|
||||
const glowFilter = new PIXI.filters.GlowFilter();
|
||||
return glowFilter;
|
||||
},
|
||||
update: function (filter, layer) {},
|
||||
updateDoubleParameter: function (filter, parameterName, value) {
|
||||
const glowFilter = filter as PIXI.filters.GlowFilter;
|
||||
if (parameterName === 'innerStrength') {
|
||||
glowFilter.innerStrength = value;
|
||||
} else if (parameterName === 'outerStrength') {
|
||||
glowFilter.outerStrength = value;
|
||||
} else if (parameterName === 'distance') {
|
||||
// @ts-ignore
|
||||
glowFilter.distance = value;
|
||||
}
|
||||
},
|
||||
updateStringParameter: function (filter, parameterName, value) {
|
||||
const glowFilter = filter as PIXI.filters.GlowFilter;
|
||||
if (parameterName === 'color') {
|
||||
glowFilter.color = gdjs.PixiFiltersTools.rgbOrHexToHexNumber(value);
|
||||
}
|
||||
},
|
||||
updateBooleanParameter: function (filter, parameterName, value) {},
|
||||
});
|
||||
}
|
@@ -1,35 +0,0 @@
|
||||
gdjs.PixiFiltersTools.registerFilterCreator('Godray', {
|
||||
makePIXIFilter: function(layer, effectData) {
|
||||
var godrayFilter = new PIXI.filters.GodrayFilter();
|
||||
|
||||
return godrayFilter;
|
||||
},
|
||||
update: function(filter, layer) {
|
||||
if (filter.animationSpeed !== 0) {
|
||||
filter.time += layer.getElapsedTime() / 1000 * filter.animationSpeed;
|
||||
}
|
||||
},
|
||||
updateDoubleParameter: function(filter, parameterName, value) {
|
||||
if (parameterName === 'lacunarity') {
|
||||
filter.lacunarity = value;
|
||||
} else if (parameterName === 'angle') {
|
||||
filter.angle = value;
|
||||
} else if (parameterName === 'gain') {
|
||||
filter.gain = value;
|
||||
} else if (parameterName === 'light') {
|
||||
filter.light = value;
|
||||
} else if (parameterName === 'x') {
|
||||
filter.x = value;
|
||||
} else if (parameterName === 'y') {
|
||||
filter.y = value;
|
||||
} else if (parameterName === 'animationSpeed') {
|
||||
filter.animationSpeed = value;
|
||||
}
|
||||
},
|
||||
updateStringParameter: function(filter, parameterName, value) {},
|
||||
updateBooleanParameter: function(filter, parameterName, value) {
|
||||
if (parameterName === 'parallel') {
|
||||
filter.parallel = value;
|
||||
}
|
||||
},
|
||||
});
|
38
Extensions/Effects/godray-pixi-filter.ts
Normal file
38
Extensions/Effects/godray-pixi-filter.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
// @ts-nocheck - TODO: fix typings in this file
|
||||
|
||||
namespace gdjs {
|
||||
gdjs.PixiFiltersTools.registerFilterCreator('Godray', {
|
||||
makePIXIFilter: function (layer, effectData) {
|
||||
const godrayFilter = new PIXI.filters.GodrayFilter();
|
||||
return godrayFilter;
|
||||
},
|
||||
update: function (filter, layer) {
|
||||
if (filter.animationSpeed !== 0) {
|
||||
filter.time += (layer.getElapsedTime() / 1000) * filter.animationSpeed;
|
||||
}
|
||||
},
|
||||
updateDoubleParameter: function (filter, parameterName, value) {
|
||||
if (parameterName === 'lacunarity') {
|
||||
filter.lacunarity = value;
|
||||
} else if (parameterName === 'angle') {
|
||||
filter.angle = value;
|
||||
} else if (parameterName === 'gain') {
|
||||
filter.gain = value;
|
||||
} else if (parameterName === 'light') {
|
||||
filter.light = value;
|
||||
} else if (parameterName === 'x') {
|
||||
filter.x = value;
|
||||
} else if (parameterName === 'y') {
|
||||
filter.y = value;
|
||||
} else if (parameterName === 'animationSpeed') {
|
||||
filter.animationSpeed = value;
|
||||
}
|
||||
},
|
||||
updateStringParameter: function (filter, parameterName, value) {},
|
||||
updateBooleanParameter: function (filter, parameterName, value) {
|
||||
if (parameterName === 'parallel') {
|
||||
filter.parallel = value;
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
@@ -1,27 +0,0 @@
|
||||
gdjs.PixiFiltersTools.registerFilterCreator('KawaseBlur', {
|
||||
makePIXIFilter: function(layer, effectData) {
|
||||
var kawaseBlurFilter = new PIXI.filters.KawaseBlurFilter();
|
||||
|
||||
return kawaseBlurFilter;
|
||||
},
|
||||
update: function(filter, layer) {
|
||||
},
|
||||
updateDoubleParameter: function(filter, parameterName, value) {
|
||||
if (parameterName === 'pixelizeX') {
|
||||
filter.pixelizeX = value;
|
||||
}
|
||||
else if (parameterName === 'pixelizeY') {
|
||||
filter.pixelizeY = value;
|
||||
}
|
||||
else if (parameterName === 'blur') {
|
||||
filter.blur = value;
|
||||
}
|
||||
else if (parameterName === 'quality') {
|
||||
filter.quality = value;
|
||||
}
|
||||
},
|
||||
updateStringParameter: function(filter, parameterName, value) {
|
||||
},
|
||||
updateBooleanParameter: function(filter, parameterName, value) {
|
||||
},
|
||||
});
|
25
Extensions/Effects/kawase-blur-pixi-filter.ts
Normal file
25
Extensions/Effects/kawase-blur-pixi-filter.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
namespace gdjs {
|
||||
gdjs.PixiFiltersTools.registerFilterCreator('KawaseBlur', {
|
||||
makePIXIFilter: function (layer, effectData) {
|
||||
const kawaseBlurFilter = new PIXI.filters.KawaseBlurFilter();
|
||||
return kawaseBlurFilter;
|
||||
},
|
||||
update: function (filter, layer) {},
|
||||
updateDoubleParameter: function (filter, parameterName, value) {
|
||||
const kawaseBlurFilter = filter as PIXI.filters.KawaseBlurFilter;
|
||||
if (parameterName === 'pixelizeX') {
|
||||
// @ts-ignore: fix these wrong parameters
|
||||
kawaseBlurFilter.pixelizeX = value;
|
||||
} else if (parameterName === 'pixelizeY') {
|
||||
// @ts-ignore: fix these wrong parameters
|
||||
kawaseBlurFilter.pixelizeY = value;
|
||||
} else if (parameterName === 'blur') {
|
||||
kawaseBlurFilter.blur = value;
|
||||
} else if (parameterName === 'quality') {
|
||||
kawaseBlurFilter.quality = value;
|
||||
}
|
||||
},
|
||||
updateStringParameter: function (filter, parameterName, value) {},
|
||||
updateBooleanParameter: function (filter, parameterName, value) {},
|
||||
});
|
||||
}
|
@@ -1,40 +0,0 @@
|
||||
gdjs.LightNightPixiFilter = function() {
|
||||
var vertexShader = null;
|
||||
var fragmentShader = [
|
||||
'precision mediump float;',
|
||||
'',
|
||||
'varying vec2 vTextureCoord;',
|
||||
'uniform sampler2D uSampler;',
|
||||
'uniform float opacity;',
|
||||
'',
|
||||
'void main(void)',
|
||||
'{',
|
||||
' mat3 nightMatrix = mat3(0.6, 0, 0, 0, 0.7, 0, 0, 0, 1.3);',
|
||||
' gl_FragColor = texture2D(uSampler, vTextureCoord);',
|
||||
' gl_FragColor.rgb = mix(gl_FragColor.rgb, nightMatrix * gl_FragColor.rgb, opacity);',
|
||||
'}',
|
||||
].join('\n');
|
||||
var uniforms = {
|
||||
opacity: { type: '1f', value: 1 },
|
||||
};
|
||||
|
||||
PIXI.Filter.call(this, vertexShader, fragmentShader, uniforms);
|
||||
};
|
||||
|
||||
gdjs.LightNightPixiFilter.prototype = Object.create(PIXI.Filter.prototype);
|
||||
gdjs.LightNightPixiFilter.prototype.constructor = gdjs.LightNightPixiFilter;
|
||||
|
||||
gdjs.PixiFiltersTools.registerFilterCreator('LightNight', {
|
||||
makePIXIFilter: function(layer, effectData) {
|
||||
var filter = new gdjs.LightNightPixiFilter();
|
||||
return filter;
|
||||
},
|
||||
update: function(filter, layer) {},
|
||||
updateDoubleParameter: function(filter, parameterName, value) {
|
||||
if (parameterName !== 'opacity') return;
|
||||
|
||||
filter.uniforms.opacity = gdjs.PixiFiltersTools.clampValue(value, 0, 1);
|
||||
},
|
||||
updateStringParameter: function(filter, parameterName, value) {},
|
||||
updateBooleanParameter: function(filter, parameterName, value) {},
|
||||
});
|
39
Extensions/Effects/light-night-pixi-filter.ts
Normal file
39
Extensions/Effects/light-night-pixi-filter.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
namespace gdjs {
|
||||
export class LightNightPixiFilter extends PIXI.Filter {
|
||||
constructor() {
|
||||
const vertexShader = undefined;
|
||||
const fragmentShader = [
|
||||
'precision mediump float;',
|
||||
'',
|
||||
'varying vec2 vTextureCoord;',
|
||||
'uniform sampler2D uSampler;',
|
||||
'uniform float opacity;',
|
||||
'',
|
||||
'void main(void)',
|
||||
'{',
|
||||
' mat3 nightMatrix = mat3(0.6, 0, 0, 0, 0.7, 0, 0, 0, 1.3);',
|
||||
' gl_FragColor = texture2D(uSampler, vTextureCoord);',
|
||||
' gl_FragColor.rgb = mix(gl_FragColor.rgb, nightMatrix * gl_FragColor.rgb, opacity);',
|
||||
'}',
|
||||
].join('\n');
|
||||
const uniforms = { opacity: { type: '1f', value: 1 } };
|
||||
super(vertexShader, fragmentShader, uniforms);
|
||||
}
|
||||
}
|
||||
LightNightPixiFilter.prototype.constructor = gdjs.LightNightPixiFilter;
|
||||
gdjs.PixiFiltersTools.registerFilterCreator('LightNight', {
|
||||
makePIXIFilter: function (layer, effectData) {
|
||||
const filter = new gdjs.LightNightPixiFilter();
|
||||
return filter;
|
||||
},
|
||||
update: function (filter, layer) {},
|
||||
updateDoubleParameter: function (filter, parameterName, value) {
|
||||
if (parameterName !== 'opacity') {
|
||||
return;
|
||||
}
|
||||
filter.uniforms.opacity = gdjs.PixiFiltersTools.clampValue(value, 0, 1);
|
||||
},
|
||||
updateStringParameter: function (filter, parameterName, value) {},
|
||||
updateBooleanParameter: function (filter, parameterName, value) {},
|
||||
});
|
||||
}
|
@@ -1,46 +0,0 @@
|
||||
gdjs.NightPixiFilter = function() {
|
||||
var vertexShader = null;
|
||||
var fragmentShader = [
|
||||
'precision mediump float;',
|
||||
'',
|
||||
'varying vec2 vTextureCoord;',
|
||||
'uniform sampler2D uSampler;',
|
||||
'uniform float intensity;',
|
||||
'uniform float opacity;',
|
||||
'',
|
||||
'void main(void)',
|
||||
'{',
|
||||
' mat3 nightMatrix = mat3(-2.0 * intensity, -1.0 * intensity, 0, -1.0 * intensity, 0, 1.0 * intensity, 0, 1.0 * intensity, 2.0 * intensity);',
|
||||
' gl_FragColor = texture2D(uSampler, vTextureCoord);',
|
||||
' gl_FragColor.rgb = mix(gl_FragColor.rgb, nightMatrix * gl_FragColor.rgb, opacity);',
|
||||
'}',
|
||||
].join('\n');
|
||||
var uniforms = {
|
||||
intensity: { type: '1f', value: 1 },
|
||||
opacity: { type: '1f', value: 1 },
|
||||
};
|
||||
|
||||
PIXI.Filter.call(this, vertexShader, fragmentShader, uniforms);
|
||||
};
|
||||
|
||||
gdjs.NightPixiFilter.prototype = Object.create(PIXI.Filter.prototype);
|
||||
gdjs.NightPixiFilter.prototype.constructor = gdjs.NightPixiFilter;
|
||||
|
||||
gdjs.PixiFiltersTools.registerFilterCreator('Night', {
|
||||
makePIXIFilter: function(layer, effectData) {
|
||||
var filter = new gdjs.NightPixiFilter();
|
||||
return filter;
|
||||
},
|
||||
update: function(filter, layer) {},
|
||||
updateDoubleParameter: function(filter, parameterName, value) {
|
||||
if (parameterName !== 'intensity' && parameterName !== 'opacity') return;
|
||||
|
||||
filter.uniforms[parameterName] = gdjs.PixiFiltersTools.clampValue(
|
||||
value,
|
||||
0,
|
||||
1
|
||||
);
|
||||
},
|
||||
updateStringParameter: function(filter, parameterName, value) {},
|
||||
updateBooleanParameter: function(filter, parameterName, value) {},
|
||||
});
|
47
Extensions/Effects/night-pixi-filter.ts
Normal file
47
Extensions/Effects/night-pixi-filter.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
namespace gdjs {
|
||||
export class NightPixiFilter extends PIXI.Filter {
|
||||
constructor() {
|
||||
const vertexShader = undefined;
|
||||
const fragmentShader = [
|
||||
'precision mediump float;',
|
||||
'',
|
||||
'varying vec2 vTextureCoord;',
|
||||
'uniform sampler2D uSampler;',
|
||||
'uniform float intensity;',
|
||||
'uniform float opacity;',
|
||||
'',
|
||||
'void main(void)',
|
||||
'{',
|
||||
' mat3 nightMatrix = mat3(-2.0 * intensity, -1.0 * intensity, 0, -1.0 * intensity, 0, 1.0 * intensity, 0, 1.0 * intensity, 2.0 * intensity);',
|
||||
' gl_FragColor = texture2D(uSampler, vTextureCoord);',
|
||||
' gl_FragColor.rgb = mix(gl_FragColor.rgb, nightMatrix * gl_FragColor.rgb, opacity);',
|
||||
'}',
|
||||
].join('\n');
|
||||
const uniforms = {
|
||||
intensity: { type: '1f', value: 1 },
|
||||
opacity: { type: '1f', value: 1 },
|
||||
};
|
||||
super(vertexShader, fragmentShader, uniforms);
|
||||
}
|
||||
}
|
||||
NightPixiFilter.prototype.constructor = gdjs.NightPixiFilter;
|
||||
gdjs.PixiFiltersTools.registerFilterCreator('Night', {
|
||||
makePIXIFilter: function (layer, effectData) {
|
||||
const filter = new gdjs.NightPixiFilter();
|
||||
return filter;
|
||||
},
|
||||
update: function (filter, layer) {},
|
||||
updateDoubleParameter: function (filter, parameterName, value) {
|
||||
if (parameterName !== 'intensity' && parameterName !== 'opacity') {
|
||||
return;
|
||||
}
|
||||
filter.uniforms[parameterName] = gdjs.PixiFiltersTools.clampValue(
|
||||
value,
|
||||
0,
|
||||
1
|
||||
);
|
||||
},
|
||||
updateStringParameter: function (filter, parameterName, value) {},
|
||||
updateBooleanParameter: function (filter, parameterName, value) {},
|
||||
});
|
||||
}
|
@@ -1,14 +0,0 @@
|
||||
gdjs.PixiFiltersTools.registerFilterCreator('Noise', {
|
||||
makePIXIFilter: function(layer, effectData) {
|
||||
var noise = new PIXI.filters.NoiseFilter();
|
||||
return noise;
|
||||
},
|
||||
update: function(filter, layer) {},
|
||||
updateDoubleParameter: function(filter, parameterName, value) {
|
||||
if (parameterName !== 'noise') return;
|
||||
|
||||
filter.noise = gdjs.PixiFiltersTools.clampValue(value, 0, 1);
|
||||
},
|
||||
updateStringParameter: function(filter, parameterName, value) {},
|
||||
updateBooleanParameter: function(filter, parameterName, value) {},
|
||||
});
|
18
Extensions/Effects/noise-pixi-filter.ts
Normal file
18
Extensions/Effects/noise-pixi-filter.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
namespace gdjs {
|
||||
gdjs.PixiFiltersTools.registerFilterCreator('Noise', {
|
||||
makePIXIFilter: function (layer, effectData) {
|
||||
const noiseFilter = new PIXI.filters.NoiseFilter();
|
||||
return noiseFilter;
|
||||
},
|
||||
update: function (filter, layer) {},
|
||||
updateDoubleParameter: function (filter, parameterName, value) {
|
||||
const noiseFilter = filter as PIXI.filters.NoiseFilter;
|
||||
if (parameterName !== 'noise') {
|
||||
return;
|
||||
}
|
||||
noiseFilter.noise = gdjs.PixiFiltersTools.clampValue(value, 0, 1);
|
||||
},
|
||||
updateStringParameter: function (filter, parameterName, value) {},
|
||||
updateBooleanParameter: function (filter, parameterName, value) {},
|
||||
});
|
||||
}
|
@@ -1,50 +0,0 @@
|
||||
gdjs.PixiFiltersTools.registerFilterCreator('OldFilm', {
|
||||
makePIXIFilter: function(layer, effectData) {
|
||||
var oldFilmFilter = new PIXI.filters.OldFilmFilter();
|
||||
oldFilmFilter._animationTimer = 0;
|
||||
return oldFilmFilter;
|
||||
},
|
||||
update: function(filter, layer) {
|
||||
if (filter.animationFrequency !== 0) {
|
||||
filter._animationTimer += layer.getElapsedTime() / 1000;
|
||||
if (filter._animationTimer >= 1 / filter.animationFrequency) {
|
||||
filter.seed = Math.random();
|
||||
filter._animationTimer = 0;
|
||||
}
|
||||
}
|
||||
},
|
||||
updateDoubleParameter: function(filter, parameterName, value) {
|
||||
if (parameterName === 'sepia') {
|
||||
filter.sepia = value;
|
||||
}
|
||||
else if (parameterName === 'noise') {
|
||||
filter.noise = value;
|
||||
}
|
||||
else if (parameterName === 'noiseSize') {
|
||||
filter.noiseSize = value;
|
||||
}
|
||||
else if (parameterName === 'scratch') {
|
||||
filter.scratch = value;
|
||||
}
|
||||
else if (parameterName === 'scratchDensity') {
|
||||
filter.scratchDensity = value;
|
||||
}
|
||||
else if (parameterName === 'scratchWidth') {
|
||||
filter.scratchWidth = value;
|
||||
}
|
||||
else if (parameterName === 'vignetting') {
|
||||
filter.vignetting = value;
|
||||
}
|
||||
else if (parameterName === 'vignettingAlpha') {
|
||||
filter.vignettingAlpha = value;
|
||||
}
|
||||
else if (parameterName === 'vignettingBlur') {
|
||||
filter.vignettingBlur = value;
|
||||
}
|
||||
else if (parameterName === 'animationFrequency') {
|
||||
filter.animationFrequency = value;
|
||||
}
|
||||
},
|
||||
updateStringParameter: function(filter, parameterName, value) {},
|
||||
updateBooleanParameter: function(filter, parameterName, value) {},
|
||||
});
|
45
Extensions/Effects/old-film-pixi-filter.ts
Normal file
45
Extensions/Effects/old-film-pixi-filter.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
// @ts-nocheck - TODO: fix typings in this file
|
||||
|
||||
namespace gdjs {
|
||||
gdjs.PixiFiltersTools.registerFilterCreator('OldFilm', {
|
||||
makePIXIFilter: function (layer, effectData) {
|
||||
const oldFilmFilter = new PIXI.filters.OldFilmFilter();
|
||||
oldFilmFilter._animationTimer = 0;
|
||||
return oldFilmFilter;
|
||||
},
|
||||
update: function (filter, layer) {
|
||||
if (filter.animationFrequency !== 0) {
|
||||
filter._animationTimer += layer.getElapsedTime() / 1000;
|
||||
if (filter._animationTimer >= 1 / filter.animationFrequency) {
|
||||
filter.seed = Math.random();
|
||||
filter._animationTimer = 0;
|
||||
}
|
||||
}
|
||||
},
|
||||
updateDoubleParameter: function (filter, parameterName, value) {
|
||||
if (parameterName === 'sepia') {
|
||||
filter.sepia = value;
|
||||
} else if (parameterName === 'noise') {
|
||||
filter.noise = value;
|
||||
} else if (parameterName === 'noiseSize') {
|
||||
filter.noiseSize = value;
|
||||
} else if (parameterName === 'scratch') {
|
||||
filter.scratch = value;
|
||||
} else if (parameterName === 'scratchDensity') {
|
||||
filter.scratchDensity = value;
|
||||
} else if (parameterName === 'scratchWidth') {
|
||||
filter.scratchWidth = value;
|
||||
} else if (parameterName === 'vignetting') {
|
||||
filter.vignetting = value;
|
||||
} else if (parameterName === 'vignettingAlpha') {
|
||||
filter.vignettingAlpha = value;
|
||||
} else if (parameterName === 'vignettingBlur') {
|
||||
filter.vignettingBlur = value;
|
||||
} else if (parameterName === 'animationFrequency') {
|
||||
filter.animationFrequency = value;
|
||||
}
|
||||
},
|
||||
updateStringParameter: function (filter, parameterName, value) {},
|
||||
updateBooleanParameter: function (filter, parameterName, value) {},
|
||||
});
|
||||
}
|
@@ -1,19 +0,0 @@
|
||||
gdjs.PixiFiltersTools.registerFilterCreator('Outline', {
|
||||
makePIXIFilter: function(layer, effectData) {
|
||||
var outlineFilter = new PIXI.filters.OutlineFilter();
|
||||
|
||||
return outlineFilter;
|
||||
},
|
||||
update: function(filter, layer) {},
|
||||
updateDoubleParameter: function(filter, parameterName, value) {
|
||||
if (parameterName === 'thickness') {
|
||||
filter.thickness = value;
|
||||
}
|
||||
},
|
||||
updateStringParameter: function(filter, parameterName, value) {
|
||||
if (parameterName === 'color') {
|
||||
filter.color = gdjs.PixiFiltersTools.rgbOrHexToHexNumber(value);
|
||||
}
|
||||
},
|
||||
updateBooleanParameter: function(filter, parameterName, value) {},
|
||||
});
|
22
Extensions/Effects/outline-pixi-filter.ts
Normal file
22
Extensions/Effects/outline-pixi-filter.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
namespace gdjs {
|
||||
gdjs.PixiFiltersTools.registerFilterCreator('Outline', {
|
||||
makePIXIFilter: function (layer, effectData) {
|
||||
const outlineFilter = new PIXI.filters.OutlineFilter();
|
||||
return outlineFilter;
|
||||
},
|
||||
update: function (filter, layer) {},
|
||||
updateDoubleParameter: function (filter, parameterName, value) {
|
||||
const outlineFilter = filter as PIXI.filters.OutlineFilter;
|
||||
if (parameterName === 'thickness') {
|
||||
outlineFilter.thickness = value;
|
||||
}
|
||||
},
|
||||
updateStringParameter: function (filter, parameterName, value) {
|
||||
const outlineFilter = filter as PIXI.filters.OutlineFilter;
|
||||
if (parameterName === 'color') {
|
||||
outlineFilter.color = gdjs.PixiFiltersTools.rgbOrHexToHexNumber(value);
|
||||
}
|
||||
},
|
||||
updateBooleanParameter: function (filter, parameterName, value) {},
|
||||
});
|
||||
}
|
@@ -1,17 +0,0 @@
|
||||
gdjs.PixiFiltersTools.registerFilterCreator("Pixelate", {
|
||||
makePIXIFilter: function(layer, effectData) {
|
||||
const PixelateFilter = new PIXI.filters.PixelateFilter(
|
||||
effectData.doubleParameters.size
|
||||
);
|
||||
|
||||
return PixelateFilter;
|
||||
},
|
||||
update: function(filter, layer) {},
|
||||
updateDoubleParameter: function(filter, parameterName, value) {
|
||||
if (parameterName === "size") {
|
||||
filter.size = value;
|
||||
}
|
||||
},
|
||||
updateStringParameter: function(filter, parameterName, value) {},
|
||||
updateBooleanParameter: function(filter, parameterName, value) {}
|
||||
});
|
19
Extensions/Effects/pixelate-pixi-filter.ts
Normal file
19
Extensions/Effects/pixelate-pixi-filter.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
namespace gdjs {
|
||||
gdjs.PixiFiltersTools.registerFilterCreator('Pixelate', {
|
||||
makePIXIFilter: function (layer, effectData) {
|
||||
const pixelateFilter = new PIXI.filters.PixelateFilter(
|
||||
effectData.doubleParameters.size
|
||||
);
|
||||
return pixelateFilter;
|
||||
},
|
||||
update: function (filter, layer) {},
|
||||
updateDoubleParameter: function (filter, parameterName, value) {
|
||||
const pixelateFilter = filter as PIXI.filters.PixelateFilter;
|
||||
if (parameterName === 'size') {
|
||||
pixelateFilter.size = value;
|
||||
}
|
||||
},
|
||||
updateStringParameter: function (filter, parameterName, value) {},
|
||||
updateBooleanParameter: function (filter, parameterName, value) {},
|
||||
});
|
||||
}
|
29
Extensions/Effects/pixi-filters/types/adjustment/types.d.ts
vendored
Normal file
29
Extensions/Effects/pixi-filters/types/adjustment/types.d.ts
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
|
||||
declare namespace PIXI.filters {
|
||||
export class AdjustmentFilter extends PIXI.Filter {
|
||||
constructor(options?: AdjustmentOptions);
|
||||
gamma: number;
|
||||
contrast: number;
|
||||
saturation: number;
|
||||
brightness: number;
|
||||
red: number;
|
||||
green: number;
|
||||
blue: number;
|
||||
alpha: number;
|
||||
}
|
||||
export interface AdjustmentOptions {
|
||||
gamma?: number;
|
||||
contrast?: number;
|
||||
saturation?: number;
|
||||
brightness?: number;
|
||||
red?: number;
|
||||
green?: number;
|
||||
blue?: number;
|
||||
alpha?: number;
|
||||
}
|
||||
}
|
||||
|
||||
declare module "@pixi/filter-adjustment" {
|
||||
export import AdjustmentFilter = PIXI.filters.AdjustmentFilter;
|
||||
export import AdjustmentOptions = PIXI.filters.AdjustmentOptions;
|
||||
}
|
30
Extensions/Effects/pixi-filters/types/advanced-bloom/types.d.ts
vendored
Normal file
30
Extensions/Effects/pixi-filters/types/advanced-bloom/types.d.ts
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
|
||||
declare namespace PIXI.filters {
|
||||
export class AdvancedBloomFilter extends PIXI.Filter {
|
||||
constructor(options?: AdvancedBloomOptions);
|
||||
constructor(threshold?: number);
|
||||
threshold: number;
|
||||
bloomScale: number;
|
||||
brightness: number;
|
||||
kernels: number[];
|
||||
blur: number;
|
||||
quality: number;
|
||||
pixelSize:number|PIXI.Point|number[];
|
||||
resolution: number;
|
||||
}
|
||||
export interface AdvancedBloomOptions {
|
||||
threshold?: number;
|
||||
bloomScale?: number;
|
||||
brightness?: number;
|
||||
kernels?: number[];
|
||||
blur?: number;
|
||||
quality?: number;
|
||||
pixelSize?: number|PIXI.Point|number[];
|
||||
resolution?: number;
|
||||
}
|
||||
}
|
||||
|
||||
declare module "@pixi/filter-advanced-bloom" {
|
||||
export import AdvancedBloomFilter = PIXI.filters.AdvancedBloomFilter;
|
||||
export import AdvancedBloomOptions = PIXI.filters.AdvancedBloomOptions;
|
||||
}
|
11
Extensions/Effects/pixi-filters/types/ascii/types.d.ts
vendored
Normal file
11
Extensions/Effects/pixi-filters/types/ascii/types.d.ts
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
|
||||
declare namespace PIXI.filters {
|
||||
export class AsciiFilter extends PIXI.Filter {
|
||||
constructor(size?:number);
|
||||
size:number;
|
||||
}
|
||||
}
|
||||
|
||||
declare module "@pixi/filter-ascii" {
|
||||
export import AsciiFilter = PIXI.filters.AsciiFilter;
|
||||
}
|
25
Extensions/Effects/pixi-filters/types/bevel/types.d.ts
vendored
Normal file
25
Extensions/Effects/pixi-filters/types/bevel/types.d.ts
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
|
||||
declare namespace PIXI.filters {
|
||||
export class BevelFilter extends PIXI.Filter {
|
||||
constructor(options?:BevelOptions);
|
||||
rotation:number;
|
||||
thickness:number;
|
||||
lightColor:number;
|
||||
lightAlpha:number;
|
||||
shadowColor:number;
|
||||
shadowAlpha:number;
|
||||
}
|
||||
export interface BevelOptions {
|
||||
rotation:number;
|
||||
thickness:number;
|
||||
lightColor:number;
|
||||
lightAlpha:number;
|
||||
shadowColor:number;
|
||||
shadowAlpha:number;
|
||||
}
|
||||
}
|
||||
|
||||
declare module "@pixi/filter-bevel" {
|
||||
export import BevelFilter = PIXI.filters.BevelFilter;
|
||||
export import BevelOptions = PIXI.filters.BevelOptions;
|
||||
}
|
13
Extensions/Effects/pixi-filters/types/bloom/types.d.ts
vendored
Normal file
13
Extensions/Effects/pixi-filters/types/bloom/types.d.ts
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
|
||||
declare namespace PIXI.filters {
|
||||
export class BloomFilter extends PIXI.Filter {
|
||||
constructor(blur?:number|PIXI.Point|number[], quality?:number, resolution?:number, kernelSize?:number);
|
||||
blur:number;
|
||||
blurX:number;
|
||||
blurY:number;
|
||||
}
|
||||
}
|
||||
|
||||
declare module "@pixi/filter-bloom" {
|
||||
export import BloomFilter = PIXI.filters.BloomFilter;
|
||||
}
|
20
Extensions/Effects/pixi-filters/types/bulge-pinch/types.d.ts
vendored
Normal file
20
Extensions/Effects/pixi-filters/types/bulge-pinch/types.d.ts
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
|
||||
declare namespace PIXI.filters {
|
||||
export interface BulgePinchFilterOptions {
|
||||
center?:PIXI.Point|[number, number];
|
||||
radius?:number;
|
||||
strength?:number;
|
||||
}
|
||||
export class BulgePinchFilter extends PIXI.Filter {
|
||||
constructor(options?:BulgePinchFilterOptions);
|
||||
constructor(center?:PIXI.Point|[number, number], radius?:number, strength?:number);
|
||||
center:PIXI.Point;
|
||||
radius:number;
|
||||
strength:number;
|
||||
}
|
||||
}
|
||||
|
||||
declare module "@pixi/filter-bulge-pinch" {
|
||||
export import BulgePinchFilterOptions = PIXI.filters.BulgePinchFilterOptions;
|
||||
export import BulgePinchFilter = PIXI.filters.BulgePinchFilter;
|
||||
}
|
14
Extensions/Effects/pixi-filters/types/color-map/types.d.ts
vendored
Normal file
14
Extensions/Effects/pixi-filters/types/color-map/types.d.ts
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
|
||||
declare namespace PIXI.filters {
|
||||
export class ColorMapFilter extends PIXI.Filter {
|
||||
constructor(colorMap?:HTMLImageElement|HTMLCanvasElement|PIXI.BaseTexture|PIXI.Texture, nearest?:boolean, mix?:number);
|
||||
colorMap:PIXI.Texture;
|
||||
nearest:boolean;
|
||||
mix:number;
|
||||
readonly colorSize:number;
|
||||
}
|
||||
}
|
||||
|
||||
declare module "@pixi/filter-color-map" {
|
||||
export import ColorMapFilter = PIXI.filters.ColorMapFilter;
|
||||
}
|
11
Extensions/Effects/pixi-filters/types/color-overlay/types.d.ts
vendored
Normal file
11
Extensions/Effects/pixi-filters/types/color-overlay/types.d.ts
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
|
||||
declare namespace PIXI.filters {
|
||||
export class ColorOverlayFilter extends PIXI.Filter {
|
||||
constructor(color?:number|[number, number, number]);
|
||||
color:number|[number, number, number];
|
||||
}
|
||||
}
|
||||
|
||||
declare module "@pixi/filter-color-overlay" {
|
||||
export import ColorOverlayFilter = PIXI.filters.ColorOverlayFilter;
|
||||
}
|
13
Extensions/Effects/pixi-filters/types/color-replace/types.d.ts
vendored
Normal file
13
Extensions/Effects/pixi-filters/types/color-replace/types.d.ts
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
|
||||
declare namespace PIXI.filters {
|
||||
export class ColorReplaceFilter extends PIXI.Filter {
|
||||
constructor(originalColor?:number|number[], newColor?:number|number[], epsilon?:number);
|
||||
epsilon:number;
|
||||
originalColor:number|number[];
|
||||
newColor:number|number[];
|
||||
}
|
||||
}
|
||||
|
||||
declare module "@pixi/filter-color-replace" {
|
||||
export import ColorReplaceFilter = PIXI.filters.ColorReplaceFilter;
|
||||
}
|
13
Extensions/Effects/pixi-filters/types/convolution/types.d.ts
vendored
Normal file
13
Extensions/Effects/pixi-filters/types/convolution/types.d.ts
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
|
||||
declare namespace PIXI.filters {
|
||||
export class ConvolutionFilter extends PIXI.Filter {
|
||||
constructor(matrix:number[], width:number, height:number);
|
||||
height:number;
|
||||
width:number;
|
||||
matrix:number[];
|
||||
}
|
||||
}
|
||||
|
||||
declare module "@pixi/filter-convolution" {
|
||||
export import ConvolutionFilter = PIXI.filters.ConvolutionFilter;
|
||||
}
|
10
Extensions/Effects/pixi-filters/types/cross-hatch/types.d.ts
vendored
Normal file
10
Extensions/Effects/pixi-filters/types/cross-hatch/types.d.ts
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
declare namespace PIXI.filters {
|
||||
class CrossHatchFilter extends PIXI.Filter {
|
||||
constructor();
|
||||
}
|
||||
}
|
||||
|
||||
declare module "@pixi/filter-cross-hatch" {
|
||||
export import CrossHatchFilter = PIXI.filters.CrossHatchFilter;
|
||||
}
|
35
Extensions/Effects/pixi-filters/types/crt/types.d.ts
vendored
Normal file
35
Extensions/Effects/pixi-filters/types/crt/types.d.ts
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
|
||||
declare namespace PIXI.filters {
|
||||
export class CRTFilter extends PIXI.Filter {
|
||||
constructor(options?: CRTFilterOptions);
|
||||
curvature: number;
|
||||
lineWidth: number;
|
||||
lineContrast: number;
|
||||
verticalLine: number;
|
||||
noise: number;
|
||||
noiseSize: number;
|
||||
seed: number;
|
||||
vignetting: number;
|
||||
vignettingAlpha: number;
|
||||
vignettingBlur: number;
|
||||
time: number;
|
||||
}
|
||||
export interface CRTFilterOptions {
|
||||
curvature?: number;
|
||||
lineWidth?: number;
|
||||
lineContrast?: number;
|
||||
verticalLine?: number;
|
||||
noise?: number;
|
||||
noiseSize?: number;
|
||||
seed?: number;
|
||||
vignetting?: number;
|
||||
vignettingAlpha?: number;
|
||||
vignettingBlur?: number;
|
||||
time?: number;
|
||||
}
|
||||
}
|
||||
|
||||
declare module "@pixi/filter-crt" {
|
||||
export import CRTFilter = PIXI.filters.CRTFilter;
|
||||
export import CRTFilterOptions = PIXI.filters.CRTFilterOptions;
|
||||
}
|
12
Extensions/Effects/pixi-filters/types/dot/types.d.ts
vendored
Normal file
12
Extensions/Effects/pixi-filters/types/dot/types.d.ts
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
declare namespace PIXI.filters {
|
||||
export class DotFilter extends PIXI.Filter {
|
||||
constructor(scale?:number, angle?:number);
|
||||
angle:number;
|
||||
scale:number;
|
||||
}
|
||||
}
|
||||
|
||||
declare module "@pixi/filter-dot" {
|
||||
export import DotFilter = PIXI.filters.DotFilter;
|
||||
}
|
33
Extensions/Effects/pixi-filters/types/drop-shadow/types.d.ts
vendored
Normal file
33
Extensions/Effects/pixi-filters/types/drop-shadow/types.d.ts
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
|
||||
declare namespace PIXI.filters {
|
||||
export class DropShadowFilter extends PIXI.Filter {
|
||||
constructor(options?:DropShadowFilterOptions);
|
||||
alpha:number;
|
||||
blur:number;
|
||||
color:number;
|
||||
distance:number;
|
||||
kernels:number[];
|
||||
pixelSize:number|number[]|PIXI.Point;
|
||||
quality:number;
|
||||
resolution:number;
|
||||
rotation:number;
|
||||
shadowOnly:boolean;
|
||||
}
|
||||
export interface DropShadowFilterOptions {
|
||||
alpha?:number;
|
||||
blur?:number;
|
||||
color?:number;
|
||||
distance?:number;
|
||||
kernels?:number[];
|
||||
pixelSize?:number|number[]|PIXI.Point;
|
||||
quality?:number;
|
||||
resolution?:number;
|
||||
rotation?:number;
|
||||
shadowOnly?:boolean;
|
||||
}
|
||||
}
|
||||
|
||||
declare module "@pixi/filter-drop-shadow" {
|
||||
export import DropShadowFilter = PIXI.filters.DropShadowFilter;
|
||||
export import DropShadowFilterOptions = PIXI.filters.DropShadowFilterOptions;
|
||||
}
|
11
Extensions/Effects/pixi-filters/types/emboss/types.d.ts
vendored
Normal file
11
Extensions/Effects/pixi-filters/types/emboss/types.d.ts
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
|
||||
declare namespace PIXI.filters {
|
||||
export class EmbossFilter extends PIXI.Filter {
|
||||
constructor(strength?:number);
|
||||
strength:number;
|
||||
}
|
||||
}
|
||||
|
||||
declare module "@pixi/filter-emboss" {
|
||||
export import EmbossFilter = PIXI.filters.EmbossFilter;
|
||||
}
|
38
Extensions/Effects/pixi-filters/types/glitch/types.d.ts
vendored
Normal file
38
Extensions/Effects/pixi-filters/types/glitch/types.d.ts
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
|
||||
declare namespace PIXI.filters {
|
||||
export class GlitchFilter extends PIXI.Filter {
|
||||
constructor(options?:GlitchFilterOptions);
|
||||
slices:number;
|
||||
offset:number;
|
||||
direction:number;
|
||||
fillMode:number;
|
||||
seed:number;
|
||||
red:PIXI.Point;
|
||||
green:PIXI.Point;
|
||||
blue:PIXI.Point;
|
||||
sizes:Float32Array|number[];
|
||||
offsets:Float32Array|number[];
|
||||
refresh(): void;
|
||||
shuffle(): void;
|
||||
redraw(): void;
|
||||
readonly texture:PIXI.Texture;
|
||||
}
|
||||
export interface GlitchFilterOptions {
|
||||
slices:number;
|
||||
offset:number;
|
||||
direction:number;
|
||||
fillMode:number;
|
||||
average:boolean;
|
||||
seed:number;
|
||||
red:PIXI.Point;
|
||||
green:PIXI.Point;
|
||||
blue:PIXI.Point;
|
||||
minSize:number;
|
||||
sampleSize:number;
|
||||
}
|
||||
}
|
||||
|
||||
declare module "@pixi/filter-glitch" {
|
||||
export import GlitchFilter = PIXI.filters.GlitchFilter;
|
||||
export import GlitchFilterOptions = PIXI.filters.GlitchFilterOptions;
|
||||
}
|
23
Extensions/Effects/pixi-filters/types/glow/types.d.ts
vendored
Normal file
23
Extensions/Effects/pixi-filters/types/glow/types.d.ts
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
|
||||
declare namespace PIXI.filters {
|
||||
export class GlowFilter extends PIXI.Filter {
|
||||
constructor(options?:GlowFilterOptions);
|
||||
color:number;
|
||||
innerStrength:number;
|
||||
outerStrength:number;
|
||||
knockout:boolean;
|
||||
}
|
||||
export interface GlowFilterOptions {
|
||||
color?:number;
|
||||
distance?:number;
|
||||
innerStrength?:number;
|
||||
outerStrength?:number;
|
||||
quality?:number;
|
||||
knockout?:boolean;
|
||||
}
|
||||
}
|
||||
|
||||
declare module "@pixi/filter-glow" {
|
||||
export import GlowFilter = PIXI.filters.GlowFilter;
|
||||
export import GlowFilterOptions = PIXI.filters.GlowFilterOptions;
|
||||
}
|
27
Extensions/Effects/pixi-filters/types/godray/types.d.ts
vendored
Normal file
27
Extensions/Effects/pixi-filters/types/godray/types.d.ts
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
|
||||
declare namespace PIXI.filters {
|
||||
export class GodrayFilter extends PIXI.Filter {
|
||||
constructor(options?:GodrayFilterOptions);
|
||||
angle:number;
|
||||
center:PIXI.Point|Array<number>;
|
||||
parallel:boolean;
|
||||
gain:number;
|
||||
lacunarity:number;
|
||||
time:number;
|
||||
alpha:number;
|
||||
}
|
||||
export interface GodrayFilterOptions {
|
||||
angle:number;
|
||||
center:PIXI.Point|Array<number>;
|
||||
parallel:boolean;
|
||||
gain:number;
|
||||
lacunarity:number;
|
||||
time:number;
|
||||
alpha:number;
|
||||
}
|
||||
}
|
||||
|
||||
declare module "@pixi/filter-godray" {
|
||||
export import GodrayFilter = PIXI.filters.GodrayFilter;
|
||||
export import GodrayFilterOptions = PIXI.filters.GodrayFilterOptions;
|
||||
}
|
15
Extensions/Effects/pixi-filters/types/kawase-blur/types.d.ts
vendored
Normal file
15
Extensions/Effects/pixi-filters/types/kawase-blur/types.d.ts
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
|
||||
declare namespace PIXI.filters {
|
||||
export class KawaseBlurFilter extends PIXI.Filter {
|
||||
constructor(blur?:number|number[], quality?:number, clamp?:boolean);
|
||||
kernels:number[];
|
||||
pixelSize:number|PIXI.Point|number[];
|
||||
quality:number;
|
||||
blur:number;
|
||||
readonly clamp:boolean;
|
||||
}
|
||||
}
|
||||
|
||||
declare module "@pixi/filter-kawase-blur" {
|
||||
export import KawaseBlurFilter = PIXI.filters.KawaseBlurFilter;
|
||||
}
|
13
Extensions/Effects/pixi-filters/types/motion-blur/types.d.ts
vendored
Normal file
13
Extensions/Effects/pixi-filters/types/motion-blur/types.d.ts
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
|
||||
declare namespace PIXI.filters {
|
||||
export class MotionBlurFilter extends PIXI.Filter {
|
||||
constructor(velocity:PIXI.ObservablePoint|PIXI.Point|number[], kernelSize?:number, offset?:number);
|
||||
velocity:PIXI.ObservablePoint;
|
||||
kernelSize:number;
|
||||
offset:number;
|
||||
}
|
||||
}
|
||||
|
||||
declare module "@pixi/filter-motion-blur" {
|
||||
export import MotionBlurFilter = PIXI.filters.MotionBlurFilter;
|
||||
}
|
14
Extensions/Effects/pixi-filters/types/multi-color-replace/types.d.ts
vendored
Normal file
14
Extensions/Effects/pixi-filters/types/multi-color-replace/types.d.ts
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
|
||||
declare namespace PIXI.filters {
|
||||
export class MultiColorReplaceFilter extends PIXI.Filter {
|
||||
constructor(replacements:Array<number[]|number[][]>, epsilon?:number, maxColors?:number);
|
||||
replacements:Array<number[]|number[][]>;
|
||||
epsilon:number;
|
||||
readonly maxColors:number;
|
||||
refresh():void;
|
||||
}
|
||||
}
|
||||
|
||||
declare module "@pixi/filter-multi-color-replace" {
|
||||
export import MultiColorReplaceFilter = PIXI.filters.MultiColorReplaceFilter;
|
||||
}
|
33
Extensions/Effects/pixi-filters/types/old-film/types.d.ts
vendored
Normal file
33
Extensions/Effects/pixi-filters/types/old-film/types.d.ts
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
|
||||
declare namespace PIXI.filters {
|
||||
export class OldFilmFilter extends PIXI.Filter {
|
||||
constructor(options?: OldFilmFilterOptions, seed?: number);
|
||||
constructor(seed?: number);
|
||||
sepia: number;
|
||||
noise: number;
|
||||
noiseSize: number;
|
||||
scratch: number;
|
||||
scratchDensity: number;
|
||||
scratchWidth: number;
|
||||
vignetting: number;
|
||||
vignettingAlpha: number;
|
||||
vignettingBlur: number;
|
||||
seed: number;
|
||||
}
|
||||
export interface OldFilmFilterOptions {
|
||||
sepia?: number;
|
||||
noise?: number;
|
||||
noiseSize?: number;
|
||||
scratch?: number;
|
||||
scratchDensity?: number;
|
||||
scratchWidth?: number;
|
||||
vignetting?: number;
|
||||
vignettingAlpha?: number;
|
||||
vignettingBlur?: number;
|
||||
}
|
||||
}
|
||||
|
||||
declare module "@pixi/filter-old-film" {
|
||||
export import OldFilmFilter = PIXI.filters.OldFilmFilter;
|
||||
export import OldFilmFilterOptions = PIXI.filters.OldFilmFilterOptions;
|
||||
}
|
13
Extensions/Effects/pixi-filters/types/outline/types.d.ts
vendored
Normal file
13
Extensions/Effects/pixi-filters/types/outline/types.d.ts
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
|
||||
declare namespace PIXI.filters {
|
||||
export class OutlineFilter extends PIXI.Filter {
|
||||
constructor(thickness?:number, color?:number, quality?:number);
|
||||
color:number;
|
||||
thickness:number;
|
||||
readonly quality:number;
|
||||
}
|
||||
}
|
||||
|
||||
declare module "@pixi/filter-outline" {
|
||||
export import OutlineFilter = PIXI.filters.OutlineFilter;
|
||||
}
|
11
Extensions/Effects/pixi-filters/types/pixelate/types.d.ts
vendored
Normal file
11
Extensions/Effects/pixi-filters/types/pixelate/types.d.ts
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
|
||||
declare namespace PIXI.filters {
|
||||
export class PixelateFilter extends PIXI.Filter {
|
||||
constructor(size?:PIXI.Point|number[]|number);
|
||||
size:PIXI.Point|number[]|number;
|
||||
}
|
||||
}
|
||||
|
||||
declare module "@pixi/filter-pixelate" {
|
||||
export import PixelateFilter = PIXI.filters.PixelateFilter;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user