This commit is contained in:
Oleksandr Vlasiuk
2026-08-07 12:29:32 +03:00
commit 5b953edf17
36 changed files with 1331 additions and 0 deletions
+153
View File
@@ -0,0 +1,153 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*
# Diagnostic reports (https: //nodejs.org/api/report.html)
report.[
0-9
]*.[
0-9
]*.[
0-9
]*.[
0-9
]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https: //gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https: //bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https: //nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Snowpack dependency directory (https: //snowpack.dev/)
web_modules/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional stylelint cache
.stylelintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variable files
.env
.env.development.local
.env.test.local
.env.production.local
.env.local
# parcel-bundler cache (https: //parceljs.org/)
.cache
.parcel-cache
# Next.js build output
.next
out
# Nuxt.js build / generate output
.nuxt
dist
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https: //nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# vuepress v2.x temp and cache directory
.temp
.cache
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
# Stores VSCode versions used for testing VSCode extensions
.vscode-test
# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*
.vscode/
.vs/
package-lock.json
.other_files/
zip/
output/js/
temp/
export/
dist/
export_test/
extra_compress/
preview_dist/
build/
+33
View File
@@ -0,0 +1,33 @@
{
"name": "my-game-playable",
"version": "0.1.0",
"description": "24play playable",
"publishConfig": {
"access": "restricted"
},
"scripts": {
"start": "vite",
"export": "node templateLibs/export.cjs",
"preview": "vite preview",
"build": "node templateLibs/zip.cjs",
"update": "npm i @hitplay/ads_common@latest @hitplay/playable_template@latest && node templateLibs/update.cjs"
},
"dependencies": {
"@hitplay/ads_common": "^0.21.1",
"@hitplay/playable_template": "^0.21.1",
"@tweenjs/tween.js": "^25.0.0",
"bytebrew-web-sdk": "^1.0.1",
"cannon-es": "^0.20.0",
"cannon-es-debugger": "^1.0.0",
"howler": "^2.2.4",
"nipplejs": "^1.0.4",
"three": "^0.185.1"
},
"devDependencies": {
"@types/howler": "^2.2.13",
"@types/three": "^0.185.4",
"rollup": "^4.62.4",
"typescript": "^7.0.2",
"vite": "^6.4.3"
}
}
+50
View File
@@ -0,0 +1,50 @@
import { ConfigUiParamsCategories } from "@hitplay/ads_common";
export const analytics: ConfigUiParamsCategories[] = [
{
name: "Analytics params",
id: "analytics_params",
params: [
{
id: "bite_brew",
name: "Byte Brew",
type: "group",
params: [
{
name: "Enabled",
id: "isAnalyticsBB_Enabled",
type: "bool",
values: [false],
},
{
name: "App ID",
id: "AnalyticsBB_AppID",
type: "string",
values: [""],
uneditable: true,
dontIncludeToLocalisation: true,
disable: ["isAnalyticsBB_Enabled", "values !== true"],
},
{
name: "Key",
id: "AnalyticsBB_Key",
type: "string",
values: [""],
uneditable: true,
dontIncludeToLocalisation: true,
disable: ["isAnalyticsBB_Enabled", "values !== true"],
},
{
name: "version",
id: "AppVersion",
type: "string",
values: ["1.0.0"],
dontIncludeToLocalisation: true,
disable: ["isAnalyticsBB_Enabled", "values !== true"],
regExp: "^d+.d+.d+$",
},
],
},
],
},
];
+17
View File
@@ -0,0 +1,17 @@
import { ConfigUiParamsCategories } from "@hitplay/ads_common";
import { sounds } from "./sounds";
//@ts-ignore
import { analytics } from "./analytics";
//@ts-ignore
import { installBanner } from "./installBanner";
//@ts-ignore
import { screenOrientation } from "./orientation";
import { globalSettings } from "./globalSettings";
export const configUIParams: ConfigUiParamsCategories[][] = [
analytics,
installBanner,
globalSettings,
sounds,
screenOrientation,
];
+144
View File
@@ -0,0 +1,144 @@
import { ConfigUiParamsCategories } from "@hitplay/ads_common";
export const globalSettings: ConfigUiParamsCategories[] = [
{
id: "global",
name: "Scene settings",
params: [
{
id: "light_intensity",
name: "Light intensity",
type: "float",
values: [
0,
5,
1
]
},
{
id: "light_color",
name: "Main light color",
type: "color",
values: [
"0xFFFFFF"
]
},
{
id: "camera_fov_p",
name: "Camera FOV (portrait)",
type: "int",
values: [
30,
150,
60
]
},
{
id: "camera_position_p",
name: "Camera position (portrait)",
type: "float",
array: true,
visible: "position",
values: [
[
-10,
10,
0
],
[
-10,
10,
1
],
[
-10,
10,
5
]
]
},
{
id: "camera_rotation_p",
name: "Camera rotation (portrait)",
type: "int",
array: true,
visible: "position",
values: [
[
-360,
360,
0
],
[
-360,
360,
0
],
[
-360,
360,
0
]
]
},
{
id: "camera_fov_l",
name: "Camera FOV (landscape)",
type: "int",
values: [
30,
150,
60
]
},
{
id: "camera_position_l",
name: "Camera position (landscape)",
type: "float",
array: true,
visible: "position",
values: [
[
-10,
10,
0
],
[
-10,
10,
1
],
[
-10,
10,
5
]
]
},
{
id: "camera_rotation_l",
name: "Camera rotation (landscape)",
type: "int",
array: true,
visible: "position",
values: [
[
-360,
360,
0
],
[
-360,
360,
0
],
[
-360,
360,
0
]
]
}
]
}
]
File diff suppressed because one or more lines are too long
+20
View File
@@ -0,0 +1,20 @@
import { ConfigUiParamsCategories } from "@hitplay/ads_common";
export const screenOrientation: ConfigUiParamsCategories[] = [
{
id: "screen_orientation",
name: "Screen Orientation",
params: [
{
id: "orientation_lock",
name: "Orientation",
type: "select",
values: [
["Adaptive", "adaptive", true],
["Portrait Lock", "portrait"],
["Landscape Lock", "landscape"],
],
},
],
},
];
+35
View File
@@ -0,0 +1,35 @@
import { ConfigUiParamsCategories } from "@hitplay/ads_common";
export const sounds: ConfigUiParamsCategories[] = [
{
name: "Audio Settings",
id: "sounds",
params: [
{
id: "global_volume",
name: "Global, %",
type: "int",
values: [0, 100, 80],
},
{
id: "background_head",
name: "Background",
type: "group",
params: [
{
id: "background_volume",
name: "Background, %",
type: "int",
values: [0, 100, 50],
},
{
id: "upload_background_music",
name: "Upload background music",
type: "upload_file",
file_type: "sound",
},
],
},
],
},
];
+26
View File
@@ -0,0 +1,26 @@
import { CameraC_internal, Helper, Template } from "@hitplay/playable_template";
import { PerspectiveCamera } from "three";
export class CameraC extends CameraC_internal {
static setCamera(portraitOrientation: boolean) {
const CATEGORY = Template.getCategory("global");
if (this.camera !== null) {
let position = portraitOrientation
? Helper.returnVectorCamera(CATEGORY["camera_position_p"] as number[])
: Helper.returnVectorCamera(CATEGORY["camera_position_l"] as number[]);
const rotation = portraitOrientation
? Helper.returnEulerCamera(CATEGORY["camera_rotation_p"] as number[])
: Helper.returnEulerCamera(CATEGORY["camera_rotation_l"] as number[]);
this.camera.rotation.x = rotation.x;
this.camera.rotation.y = rotation.y;
this.camera.rotation.z = rotation.z;
this.camera.position.copy(position.clone());
if (this.camera instanceof PerspectiveCamera) {
this.camera.fov = portraitOrientation
? Number(CATEGORY["camera_fov_p"])
: Number(CATEGORY["camera_fov_l"]);
this.camera.updateProjectionMatrix();
}
}
}
}
+129
View File
@@ -0,0 +1,129 @@
import {
Delegate,
Physics_internal,
UpdateController,
} from "@hitplay/playable_template";
import { Box3, Object3D, Vector3 } from "three";
import { Body, Box, Quaternion, Sphere, Vec3 } from "cannon-es";
export enum PhysicsLayer {
Player = 1,
Wall = 2,
Trigger = 4,
Enemy = 8,
}
export class PhysicsBody {
private body: Body;
private pair: PhysicsObjPair | null = null;
constructor(
threeObj: Object3D,
trigger: boolean,
mass: number,
col_group: PhysicsLayer,
col_mask: PhysicsLayer,
player_sphere: number = 0.3
) {
let isPlayer = col_group === PhysicsLayer.Player;
let oldQuaternion = threeObj.quaternion.clone();
let nullQuaternion = new Quaternion();
threeObj.quaternion.copy(nullQuaternion);
let bbox = new Box3().setFromObject(threeObj);
let size = new Vector3();
bbox.getSize(size);
// if you need custom size
// if (col_group === PhysicsLayer.wall) {
// size.x = size.z = 1;
// size.y = 1;
// }
threeObj.quaternion.copy(oldQuaternion);
this.body = new Body({
isTrigger: trigger,
mass: mass,
//shape: shape,
shape: isPlayer
? new Sphere(player_sphere)
: new Box(new Vec3(size.x / 2, size.y / 2, size.z / 2)),
collisionFilterGroup: col_group,
collisionFilterMask: col_mask,
});
let worldPos = threeObj.getWorldPosition(new Vector3());
this.body.position.set(worldPos.x, worldPos.y, worldPos.z);
this.body.quaternion.setFromEuler(
threeObj.rotation.x,
threeObj.rotation.y,
threeObj.rotation.z,
"XYZ"
);
// if you need sync three obj and physics body
// if (isEnemy) {
// let pair = new PhysicsObjPair(threeObj, this.body);
// PhysicsC_Instance.addPhysicsPair(pair);
// this.pair = pair;
// }
Physics_internal.physicsWorld &&
Physics_internal.physicsWorld.addBody(this.body);
return this;
}
disablePhysicsPair() {
if (this.pair) {
this.pair.destroyed = true;
}
}
getPhysicsBody() {
return this.body;
}
destroy() {
if (!Physics_internal.physicsWorld) return;
Physics_internal.physicsWorld.removeBody(this.body);
(this.body as any) = null;
}
}
export class PhysicsObjPair {
threeObj: Object3D;
physicsObj: Body;
destroyed: boolean;
delegateId: null | Delegate<number>;
constructor(threeObj: Object3D, physicsObj: Body) {
this.threeObj = threeObj;
this.physicsObj = physicsObj;
this.destroyed = false;
this.delegateId = UpdateController.Instance.onUpdate.addDelegate(() => {
this.update();
});
}
update() {
if (this.destroyed) return;
if (this.threeObj && this.physicsObj) {
// @ts-ignore
this.threeObj.position.copy(this.physicsObj.position);
// @ts-ignore
this.threeObj.quaternion.copy(this.physicsObj.quaternion);
}
}
}
+42
View File
@@ -0,0 +1,42 @@
import { BoxGeometry, Mesh, MeshStandardMaterial, Vector3 } from "three";
import { ThreeC } from "./ThreeC";
import { InputC, JoystickC } from "@hitplay/playable_template";
export class TestSceneC {
static init() {
this.createPrimitive();
// example of using InputC events
InputC.onTouchDown.addDelegate((event) => {
console.log("onMouseDown", event);
});
// if you have update in your controller
// UpdateController.Instance.onUpdate.addDelegate(() => {
// this.update();
// });
}
private static createPrimitive() {
const geometry = new BoxGeometry(1, 1, 1);
const material = new MeshStandardMaterial({ color: 0xcc0000 });
const cube = new Mesh(geometry, material);
const geometryPlane = new BoxGeometry(5, 0.1, 7);
const materialPlane = new MeshStandardMaterial({ color: 0xaaaaaa });
const plane = new Mesh(geometryPlane, materialPlane);
let planePosition = plane.position.clone();
ThreeC.setShadowsStateForChildren(cube, true, false);
ThreeC.setShadowsStateForChildren(plane, false, true);
plane.position.copy(
new Vector3(planePosition.x, planePosition.y - 0.5, planePosition.z - 1.5)
);
ThreeC.addToScene(cube);
ThreeC.addToScene(plane);
}
}
+68
View File
@@ -0,0 +1,68 @@
import { ColorFormat } from "@hitplay/ads_common";
import { ThreeC_internal, Template } from "@hitplay/playable_template";
import { AmbientLight, DirectionalLight } from "three";
import { Color } from "three/src/math/Color";
export class ThreeC extends ThreeC_internal {
static createBaseLights() {
this.defaultDirectionalLight = new DirectionalLight(0xffffff, 3.5);
this.defaultAmbientLight = new AmbientLight(0xffffff, 1);
this.defaultAmbientLight.color = new Color().setHex(
Number(Template.getValue<ColorFormat>("global", "light_color"))
);
this.defaultAmbientLight.intensity =
Template.getValue<number>("global", "light_intensity")
}
static setupDirectionalLightFromScene(dirLightObj:DirectionalLight) {
if (!dirLightObj) return;
ThreeC.removeFromScene(this.defaultDirectionalLight);
let light = dirLightObj;
let d = 15;
light.shadow.camera.left = -10;
light.shadow.camera.right = d;
light.shadow.camera.top = d;
light.shadow.camera.bottom = -2;
light.castShadow = true;
light.shadow.normalBias = 0.04;
light.intensity = 1;
light.shadow.mapSize.width = 1024;
light.shadow.mapSize.height = 1024;
const ambLight = new AmbientLight(0xffffff, 0.4); // soft white light
this.addToScene(ambLight);
this.addToScene(light);
this.defaultDirectionalLight = light;
}
static setupDirectionalLight() {
let dirLight = this.defaultDirectionalLight;
dirLight.position.set(8, 10, 4); //default; light shining from top
let d = 10;
dirLight.shadow.camera.left = -d;
dirLight.shadow.camera.right = d;
dirLight.shadow.camera.top = d;
dirLight.shadow.camera.bottom = -d;
dirLight.target.position.set(0, 0, 0);
dirLight.castShadow = true;
this.addToScene(dirLight);
this.addToScene(this.defaultAmbientLight);
this.addToScene(dirLight.target);
dirLight.shadow.mapSize.width = 1024;
dirLight.shadow.mapSize.height = 1024;
dirLight.shadow.camera.near = 0.5;
dirLight.shadow.camera.far = 200;
}
}
+137
View File
@@ -0,0 +1,137 @@
html,
body {
overflow-x: hidden;
overflow-y: hidden;
-moz-user-select: none;
-khtml-user-select: none;
user-select: none;
}
* {
touch-action: none;
/* mintegral problem */
user-select: none;
-webkit-touch-callout: none;
/* iOS Safari */
-webkit-user-select: none;
/* Chrome/Safari/Opera */
-khtml-user-select: none;
/* Konqueror */
-moz-user-select: none;
/* Firefox */
-ms-user-select: none;
-webkit-tap-highlight-color: transparent;
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
margin: 0;
background: #ffffff;
}
html {
font-size: 10vw;
font-family: gameFont, sans-serif;
position: fixed;
}
canvas {
width: 100%;
height: 100%;
}
#debug_label {
position: absolute;
top: 5%;
left: 30%;
width: 40%;
text-align: center;
font-size: 5vw;
color: black;
}
#ui_screen {
position: fixed;
left: 0;
top: 0;
bottom: 0;
right: 0;
z-index: 2;
display: flex;
flex-direction: column;
justify-content: space-between;
padding-top: 0vh;
padding-bottom: 0vh;
}
#constructor {
position: fixed;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
}
#videoPlayable {
height: auto;
width: 100vw;
}
#interactive {
z-index: 10;
position: fixed;
inset: 0;
width: 100%;
height: 100%;
opacity: 0;
transition: opacity 500ms ease-out;
background-color: whitesmoke;
display: flex;
justify-content: center;
align-items: center;
padding: 20px;
}
#editor {
pointer-events: none;
}
#ui,
#editor {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: calc(100vh * 9 / 16);
height: 100vh;
}
#modal {
z-index: 10000;
}
.interactive-text {
color: rgb(83, 38, 0);
font-size: 5vh;
font-family: Arial, Helvetica, sans-serif;
text-align: center;
}
#joystick_zone {
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
z-index: 900;
}
@media (orientation: landscape) {
#videoPlayable {
height: 100vh;
width: auto;
}
}
+4
View File
@@ -0,0 +1,4 @@
#ui {
/* flex-basis: 60%; */
flex-grow: 1;
}
+3
View File
@@ -0,0 +1,3 @@
import { FontFamily, formFontFamily } from "@hitplay/ads_common";
export const customFont: undefined | Promise<FontFamily> = undefined
+46
View File
@@ -0,0 +1,46 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width,user-scalable=no,initial-scale=1.0, minimum-scale=1.0,maximum-scale=1.0"
/>
<meta name="ad.orientation" content="portrait,landscape" />
<title>Playable</title>
<link href="./css/main.css" rel="stylesheet" />
<link href="./css/ui.css" rel="stylesheet" />
<style id="animations"></style>
<!-- ⛔ DO NOT EDIT: critical loader cover. Full-screen opaque so the game
never flashes before @hitplay/playable_template paints the loader.
Deliberately a neutral solid — the real design (colors, gradient,
animation) lives ONLY in the npm package; ads_common's loaderBakePlugin
replaces this style with the packaged loader.css at build time. -->
<style>.loader{position:fixed;inset:0;z-index:5000;background:#08314a}</style>
</head>
<body>
<!-- ⛔ DO NOT EDIT: loader hook. The loader (markup, styles, animation) is
injected at runtime by @hitplay/playable_template. Per-game you only
change the icon (resources/images/icon.webp) and the game name (config). -->
<div class="loader"></div>
<div id="interactive">
<h3 class="interactive-text">Redirected to store...</h3>
</div>
<div id="constructor">
<div id="ui"></div>
<div id="editor"></div>
</div>
<script id="dev-start">
window.onload = function () {
window.setupConfig();
};
window.openStorePage = function (url) {
console.log("openStorePage:", url);
};
</script>
<script type="module" src="./index.ts"></script>
</body>
</html>
+37
View File
@@ -0,0 +1,37 @@
import { formConfigForPlayable, formConfigUI, formConfigUIParams, TemplateType } from "@hitplay/ads_common";
import { resources } from "./resources/resources";
import { resizeCb } from "./templateConfig/resizeCb";
import { gameRedirectedCb } from "./templateConfig/gameRedirectedCb";
import { playableIsVisibleCb } from "./templateConfig/playableIsVisibleCb";
import { beforeResourcesLoadedCb } from "./templateConfig/beforeResourcesLoadedCb";
import { afterResourcesLoadedCb } from "./templateConfig/afterResourcesLoadedCb";
import { customFont } from "./fonts/customFont";
import { configUIParams } from "./configUIParams/configUIParams";
import { Template, Template3d } from "@hitplay/playable_template";
import { firstClickCb } from "./templateConfig/firstClickCb";
Template.set24ADSControls();
window.setupConfig = async function (config) {
Template.initConfig({
templateType: TemplateType["3d"],
redirectOptions: {},
ticker: Template3d.ticker,
debug: {
physics: false,
// set true if you want to enable physics debugger
logger: false // set true if you want to enable logger
}
}).init({
config: config || formConfigForPlayable(formConfigUI({
type_default: Template.templateType,
params_categories: formConfigUIParams(...configUIParams),
font_custom_default: await customFont
})),
resources,
afterResourcesLoadedCb,
beforeResourcesLoadedCb,
resizeCb,
playableIsVisibleCb,
gameRedirectedCb,
firstClickCb
});
};
Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

+14
View File
@@ -0,0 +1,14 @@
// import { ConvertToBase64WhenRelease } from "@hitplay/ads_common";
import { ConvertResourceType, Template3d } from "@hitplay/playable_template";
export const meshes : ConvertResourceType = {
type: "mesh",
resources: [
// {
// name: "scene",
// value: ConvertToBase64WhenRelease("./SceneСombo.glb"),
// },
],
loader: Template3d.meshLoader
}
+5
View File
@@ -0,0 +1,5 @@
import { ConvertResourcesType } from "@hitplay/playable_template";
import { meshes } from "./meshes/meshes";
import { sounds } from "./sounds/sounds";
export const resources: ConvertResourcesType = [meshes, sounds];
+13
View File
@@ -0,0 +1,13 @@
// import { ConvertToBase64WhenRelease } from "@hitplay/ads_common";
import { ConvertResourceType } from "@hitplay/playable_template";
export const sounds : ConvertResourceType = {
type: "sounds",
resources: [
// {
// name: "background",
// value: ConvertToBase64WhenRelease(`./background.mp3`),
// },
],
}
@@ -0,0 +1,8 @@
import { TestSceneC } from "../controllers/TestSceneC";
import { SoundC, Template } from "@hitplay/playable_template";
export const afterResourcesLoadedCb: (() => void) | undefined = () => {
TestSceneC.init();
SoundC.init();
Template.disableLoader();
};
@@ -0,0 +1,74 @@
import {
CameraC_internal,
CameraType,
// JoystickC,
Physics_internal,
Template,
Template3d,
ThreeC_internal,
FilterScene,
InstallBanner,
} from "@hitplay/playable_template";
import { CameraC } from "../controllers/CameraC";
import { ThreeC } from "../controllers/ThreeC";
import { Color } from "three";
import { Vec3 } from "cannon-es";
export const beforeResourcesLoadedCb = () => {
FilterScene.init();
InstallBanner.init();
Template3d.init();
CameraC_internal.init(CameraType.perspective);
CameraC.setCamera(window.screenSize.portrait);
ThreeC_internal.init();
ThreeC.createBaseLights();
ThreeC.setupDirectionalLight();
Physics_internal.init(new Vec3(0, -9.81, 0));
// example of using joystick. Uncomment if you need joystick
// JoystickC.init({
// zone: document.getElementById("joystick_zone") as HTMLDivElement,
// fadeTime: 0,
// mode: "dynamic",
// restJoystick: true,
// catchDistance: 1,
// restOpacity: 0,
// follow: false,
// });
// JoystickC.onJoysticMove.addDelegate(({event, data}) => {
// console.log('onJoysticMove', event, data);
// })
Template.updateVariableConfig.addDelegate(([category, variable, value]) => {
if (category === "global") {
switch (variable) {
case "light_intensity":
ThreeC_internal.defaultAmbientLight.intensity = Number(value);
break;
case "light_color":
ThreeC_internal.defaultAmbientLight.color = new Color(value as any);
break;
default:
if (
[
"camera_fov_p",
"camera_position_p",
"camera_rotation_p",
"camera_fov_l",
"camera_position_l",
"camera_rotation_l",
].includes(variable)
) {
CameraC.setCamera(window.screenSize.portrait);
}
break;
}
return;
}
});
};
+3
View File
@@ -0,0 +1,3 @@
export const firstClickCb: () => void = () => {
console.log("First click");
};
+1
View File
@@ -0,0 +1 @@
export const gameRedirectedCb : (() => void) | undefined = undefined
@@ -0,0 +1 @@
export const playableIsVisibleCb : (() => void) | undefined = undefined
+5
View File
@@ -0,0 +1,5 @@
import { Template3d } from "@hitplay/playable_template";
export const resizeCb = () => {
Template3d.resize();
};
+37
View File
@@ -0,0 +1,37 @@
import type { ConvertResourcesType, RedirectOptions, screenSize } from '@hitplay/playable_template';
import { ConfigCreative } from '@hitplay/ads_common';
declare global {
interface Window extends Window {
CustomizationRedirectCallback: any;
registerRedirectCallback: (el: any) => void;
updateVariableConfig: (
category: string,
variable: string,
value: any
) => void;
setupConfig: (config?: ConfigCreative) => void;
soundConfig: (
category: "setMute" | "getMute" | "setVolume" | "getVolume",
value?: boolean | number
) => boolean | number | undefined;
isStarted?: boolean;
CONFIG: ConfigCreative;
gameStart: () => void;
gameClose: () => void;
gameReady: () => void;
gameEnd: () => void;
screenSize: screenSize;
showLoader: (state: boolean) => void;
setRedirectOptions: (option: RedirectOptions | null) => void;
openGameStorePage: (cb: () => void) => void;
start: () => void
mraid: any
convertResources: ConvertResourcesType
startTime: number
updateVideoState: (cbUpdate: (state: "play" | "pause") => void) => void;
updateCurrentStep: (cbUpdate: (videoStep: VideoStep) => void) => void;
}
}
export {};
+6
View File
@@ -0,0 +1,6 @@
#!/usr/bin/env node
const { localExporter } = require("@hitplay/ads_common");
const { resolve } = require("path");
localExporter(resolve(__dirname, "../")).parse(process.argv);
+4
View File
@@ -0,0 +1,4 @@
const { templateUpdater } = require("@hitplay/ads_common");
const { resolve } = require("path");
templateUpdater(resolve(__dirname, "../"));
+4
View File
@@ -0,0 +1,4 @@
const { createBuildFor24ADS } = require("@hitplay/ads_common");
const { resolve } = require("path");
createBuildFor24ADS(resolve(__dirname, "../"));
+19
View File
@@ -0,0 +1,19 @@
{
"compilerOptions": {
"target": "ESNext",
"useDefineForClassFields": true,
"module": "ESNext",
"moduleResolution": "Node",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"noEmit": false,
"removeComments": true,
"noUnusedLocals": false,
"noUnusedParameters": false,
"noImplicitAny": false,
"allowJs": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist", "templateLibs", "build", "zip"]
}
+15
View File
@@ -0,0 +1,15 @@
import { defineConfig } from "vite";
import { defineConfigTemplate} from "@hitplay/ads_common";
import { dependencies } from "./package.json";
const rootDev = "src";
const rootBuild = "src";
export default defineConfig((config) => {
return defineConfigTemplate({
rootDev,
rootBuild,
config,
dependenciesArr: Object.keys(dependencies),
});
});