@@ -1,3 +0,6 @@ | ||
| import { AbstractLevel } from '../level/abstract-level'; | ||
| export class AbstractBody { | ||
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.AbstractBody = void 0; | ||
| const abstract_level_1 = require("../level/abstract-level"); | ||
| class AbstractBody { | ||
| static getZ(body, x = body.x, y = body.y) { | ||
@@ -7,4 +10,5 @@ return body.userData.level.getZ(x, y); | ||
| static stepToZ(step = 0) { | ||
| return step * AbstractLevel.STEP; | ||
| return step * abstract_level_1.AbstractLevel.STEP; | ||
| } | ||
| } | ||
| exports.AbstractBody = AbstractBody; |
@@ -1,9 +0,12 @@ | ||
| import { Circle } from 'check2d'; | ||
| import { Math_Double_PI } from '../utils/view-utils'; | ||
| import { AbstractBody } from './abstract-body'; | ||
| export class DynamicBody extends Circle { | ||
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.DynamicBody = void 0; | ||
| const check2d_1 = require("check2d"); | ||
| const view_utils_1 = require("../utils/view-utils"); | ||
| const abstract_body_1 = require("./abstract-body"); | ||
| class DynamicBody extends check2d_1.Circle { | ||
| constructor(x, y, level, radius = DynamicBody.RADIUS, padding = DynamicBody.PADDING) { | ||
| super({ x, y }, radius, { padding, userData: { level } }); | ||
| this.z = 0; | ||
| this.angle = Math.random() * Math_Double_PI; | ||
| this.angle = Math.random() * view_utils_1.Math_Double_PI; | ||
| } | ||
@@ -14,3 +17,3 @@ separate(scale = 1) { | ||
| if (b.isStatic) { | ||
| const wallStep = AbstractBody.stepToZ(b.userData.step); | ||
| const wallStep = abstract_body_1.AbstractBody.stepToZ(b.userData.step); | ||
| if (this.z < wallStep) { | ||
@@ -30,3 +33,4 @@ this.setPosition(this.x - x * scale, this.y - y * scale); | ||
| } | ||
| exports.DynamicBody = DynamicBody; | ||
| DynamicBody.RADIUS = 0.2; | ||
| DynamicBody.PADDING = 0.15; |
@@ -1,3 +0,6 @@ | ||
| import { AbstractBody } from './abstract-body'; | ||
| export class StaticBody { | ||
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.StaticBody = void 0; | ||
| const abstract_body_1 = require("./abstract-body"); | ||
| class StaticBody { | ||
| constructor(x, y, level) { | ||
@@ -12,5 +15,6 @@ this.z = 0; | ||
| this.y = y; | ||
| this.z = AbstractBody.getZ(this); | ||
| this.z = abstract_body_1.AbstractBody.getZ(this); | ||
| return this; | ||
| } | ||
| } | ||
| exports.StaticBody = StaticBody; |
+19
-15
@@ -1,10 +0,13 @@ | ||
| import { PerspectiveCamera, Vector3 } from 'three'; | ||
| import { AbstractBody } from '../body/abstract-body'; | ||
| import { AbstractLevel } from '../level/abstract-level'; | ||
| import { state } from '../state'; | ||
| import { DeviceDetector } from '../utils/detect-mobile'; | ||
| import { Math_Half_PI } from '../utils/view-utils'; | ||
| export class Camera extends PerspectiveCamera { | ||
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.Camera = void 0; | ||
| const three_1 = require("three"); | ||
| const abstract_body_1 = require("../body/abstract-body"); | ||
| const abstract_level_1 = require("../level/abstract-level"); | ||
| const state_1 = require("../state"); | ||
| const detect_mobile_1 = require("../utils/detect-mobile"); | ||
| const view_utils_1 = require("../utils/view-utils"); | ||
| class Camera extends three_1.PerspectiveCamera { | ||
| static getFar() { | ||
| return state.renderer.camera.far / Camera.FAR; | ||
| return state_1.state.renderer.camera.far / Camera.FAR; | ||
| } | ||
@@ -32,3 +35,3 @@ constructor(fov = Camera.FOV, near = Camera.NEAR, far = Camera.FAR) { | ||
| getPositionBehind({ x = 0, y = 0, angle = 0 } = {}) { | ||
| const adjustedAngle = Math_Half_PI - angle; | ||
| const adjustedAngle = view_utils_1.Math_Half_PI - angle; | ||
| const offsetX = Math.sin(adjustedAngle) * this.distance; | ||
@@ -48,3 +51,3 @@ const offsetY = Math.cos(adjustedAngle) * this.distance; | ||
| const [x, y] = this.getPositionBehind(this.target.body); | ||
| const z = AbstractBody.getZ(this.target.body, x, y); | ||
| const z = abstract_body_1.AbstractBody.getZ(this.target.body, x, y); | ||
| Camera.cameraGoal.set(x, Math.max(z, this.target.body.z) + Camera.HEIGHT, y); | ||
@@ -57,2 +60,3 @@ } | ||
| } | ||
| exports.Camera = Camera; | ||
| Camera.HEIGHT = 0.75; | ||
@@ -63,6 +67,6 @@ Camera.DISTANCE = 2; | ||
| Camera.NEAR = 0.01; | ||
| Camera.FAR = DeviceDetector.HIGH_END ? 32 : 16; | ||
| Camera.MIN_HEIGHT = AbstractLevel.HEIGHT_MAX * AbstractLevel.STEP; | ||
| Camera.cameraGoal = new Vector3(0, Camera.MIN_HEIGHT + Camera.HEIGHT, 0); | ||
| Camera.cameraLookAt = new Vector3(0, Camera.MIN_HEIGHT, 0); | ||
| Camera.projection = new Vector3(); | ||
| Camera.FAR = detect_mobile_1.DeviceDetector.HIGH_END ? 32 : 16; | ||
| Camera.MIN_HEIGHT = abstract_level_1.AbstractLevel.HEIGHT_MAX * abstract_level_1.AbstractLevel.STEP; | ||
| Camera.cameraGoal = new three_1.Vector3(0, Camera.MIN_HEIGHT + Camera.HEIGHT, 0); | ||
| Camera.cameraLookAt = new three_1.Vector3(0, Camera.MIN_HEIGHT, 0); | ||
| Camera.projection = new three_1.Vector3(); |
+21
-17
@@ -1,4 +0,7 @@ | ||
| import { Vector2 } from 'three'; | ||
| import { state } from '../state'; | ||
| export class Mouse extends Vector2 { | ||
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.mouse = exports.Mouse = void 0; | ||
| const three_1 = require("three"); | ||
| const state_1 = require("../state"); | ||
| class Mouse extends three_1.Vector2 { | ||
| constructor() { | ||
@@ -12,11 +15,11 @@ super(...arguments); | ||
| this.onPointerMove(event); | ||
| state.mouseDown = true; | ||
| if (state.player) { | ||
| state_1.state.mouseDown = true; | ||
| if (state_1.state.player) { | ||
| const now = Date.now(); | ||
| if (now - state.player.clickTime > Mouse.DBL_CLICK) { | ||
| state.player.clickTime = now; | ||
| if (now - state_1.state.player.clickTime > Mouse.DBL_CLICK) { | ||
| state_1.state.player.clickTime = now; | ||
| } | ||
| else { | ||
| state.player.jumpStart().then(() => { | ||
| state.player.jumpEnd(); | ||
| state_1.state.player.jumpStart().then(() => { | ||
| state_1.state.player.jumpEnd(); | ||
| }); | ||
@@ -28,8 +31,8 @@ } | ||
| this.preventEvent(event); | ||
| state.mouseDown = false; | ||
| state.keys.up = false; | ||
| state.keys.down = false; | ||
| state.keys.left = false; | ||
| state.keys.right = false; | ||
| state.player?.jumpEnd(); | ||
| state_1.state.mouseDown = false; | ||
| state_1.state.keys.up = false; | ||
| state_1.state.keys.down = false; | ||
| state_1.state.keys.left = false; | ||
| state_1.state.keys.right = false; | ||
| state_1.state.player?.jumpEnd(); | ||
| } | ||
@@ -44,3 +47,3 @@ onPointerMove(event) { | ||
| const HALF_HEIGHT = innerHeight / 2; | ||
| const playerY = state.player?.getWorldY() || 0; | ||
| const playerY = state_1.state.player?.getWorldY() || 0; | ||
| const y = (playerY + 1) * HALF_HEIGHT; | ||
@@ -58,3 +61,4 @@ this.x = this.clampNumber((this.pageX - HALF_WIDTH) / HALF_WIDTH); | ||
| } | ||
| exports.Mouse = Mouse; | ||
| Mouse.DBL_CLICK = 300; | ||
| export const mouse = new Mouse(); | ||
| exports.mouse = new Mouse(); |
+27
-23
@@ -1,20 +0,23 @@ | ||
| import { Stats } from 'pixi-stats'; | ||
| import { Color, Fog, LinearSRGBColorSpace, Scene, WebGLRenderer } from 'three'; | ||
| import { state } from '../state'; | ||
| import { queryParams } from '../utils/query-params'; | ||
| import { Ocean } from '../view/ocean'; | ||
| import { Skybox } from '../view/skybox'; | ||
| import { Camera } from './camera'; | ||
| export class Renderer extends WebGLRenderer { | ||
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.Renderer = void 0; | ||
| const pixi_stats_1 = require("pixi-stats"); | ||
| const three_1 = require("three"); | ||
| const state_1 = require("../state"); | ||
| const query_params_1 = require("../utils/query-params"); | ||
| const ocean_1 = require("../view/ocean"); | ||
| const skybox_1 = require("../view/skybox"); | ||
| const camera_1 = require("./camera"); | ||
| class Renderer extends three_1.WebGLRenderer { | ||
| static create({ canvas, ocean, skybox }) { | ||
| if (!state.renderer) { | ||
| state.renderer = new Renderer(canvas); | ||
| if (!state_1.state.renderer) { | ||
| state_1.state.renderer = new Renderer(canvas); | ||
| } | ||
| if (!state.renderer.ocean && ocean) { | ||
| state.renderer.ocean = new Ocean(ocean); | ||
| if (!state_1.state.renderer.ocean && ocean) { | ||
| state_1.state.renderer.ocean = new ocean_1.Ocean(ocean); | ||
| } | ||
| if (!state.renderer.skybox) { | ||
| state.renderer.skybox = new Skybox(skybox); | ||
| if (!state_1.state.renderer.skybox) { | ||
| state_1.state.renderer.skybox = new skybox_1.Skybox(skybox); | ||
| } | ||
| return state.renderer; | ||
| return state_1.state.renderer; | ||
| } | ||
@@ -28,4 +31,4 @@ constructor(canvas) { | ||
| }); | ||
| this.scene = new Scene(); | ||
| this.camera = new Camera(); | ||
| this.scene = new three_1.Scene(); | ||
| this.camera = new camera_1.Camera(); | ||
| this.children = []; | ||
@@ -54,4 +57,4 @@ this.now = Date.now(); | ||
| onCreate() { | ||
| this.outputColorSpace = LinearSRGBColorSpace; | ||
| this.scene.background = new Color(Renderer.backgroundColor); | ||
| this.outputColorSpace = three_1.LinearSRGBColorSpace; | ||
| this.scene.background = new three_1.Color(Renderer.backgroundColor); | ||
| this.onResize(); | ||
@@ -66,4 +69,4 @@ this.createFog(); | ||
| } | ||
| if ('fps' in queryParams) { | ||
| this.stats = new Stats(this); | ||
| if ('fps' in query_params_1.queryParams) { | ||
| this.stats = new pixi_stats_1.Stats(this); | ||
| } | ||
@@ -104,6 +107,7 @@ } | ||
| createFog() { | ||
| const far = this.camera.far - Camera.DISTANCE; | ||
| return new Fog(Renderer.backgroundColor, far * 0.8, far); | ||
| const far = this.camera.far - camera_1.Camera.DISTANCE; | ||
| return new three_1.Fog(Renderer.backgroundColor, far * 0.8, far); | ||
| } | ||
| } | ||
| exports.Renderer = Renderer; | ||
| Renderer.backgroundColor = 0x44ccf0; |
+15
-10
@@ -1,4 +0,7 @@ | ||
| import { mouse } from './core/mouse'; | ||
| import { state } from './state'; | ||
| export const setKey = (value, keys = state.keys) => { | ||
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.Events = exports.setKey = void 0; | ||
| const mouse_1 = require("./core/mouse"); | ||
| const state_1 = require("./state"); | ||
| const setKey = (value, keys = state_1.state.keys) => { | ||
| return (event) => { | ||
@@ -27,3 +30,4 @@ switch (event.key) { | ||
| }; | ||
| export class Events { | ||
| exports.setKey = setKey; | ||
| class Events { | ||
| static addEventListeners() { | ||
@@ -51,8 +55,9 @@ if (Events.eventListenersAdded) | ||
| } | ||
| Events.keyDown = setKey(true); | ||
| Events.keyUp = setKey(false); | ||
| Events.click = mouse.onPointerDown.bind(mouse); | ||
| Events.release = mouse.onPointerUp.bind(mouse); | ||
| Events.move = mouse.onPointerMove.bind(mouse); | ||
| Events.cancel = mouse.preventEvent.bind(mouse); | ||
| exports.Events = Events; | ||
| Events.keyDown = (0, exports.setKey)(true); | ||
| Events.keyUp = (0, exports.setKey)(false); | ||
| Events.click = mouse_1.mouse.onPointerDown.bind(mouse_1.mouse); | ||
| Events.release = mouse_1.mouse.onPointerUp.bind(mouse_1.mouse); | ||
| Events.move = mouse_1.mouse.onPointerMove.bind(mouse_1.mouse); | ||
| Events.cancel = mouse_1.mouse.preventEvent.bind(mouse_1.mouse); | ||
| Events.events = { | ||
@@ -59,0 +64,0 @@ pointerdown: Events.click, |
+41
-25
@@ -1,25 +0,41 @@ | ||
| export * from './level/index'; | ||
| export * from './level/box-mesh'; | ||
| export * from './level/model'; | ||
| export * from './level/abstract-level'; | ||
| export * from './utils/view-utils'; | ||
| export * from './utils/debug'; | ||
| export * from './utils/texture-utils'; | ||
| export * from './utils/detect-mobile'; | ||
| export * from './utils/query-params'; | ||
| export * from './state/index'; | ||
| export * from './events'; | ||
| export * from './loader'; | ||
| export * from './core/renderer'; | ||
| export * from './core/mouse'; | ||
| export * from './core/camera'; | ||
| export * from './body/dynamic-body'; | ||
| export * from './body/abstract-body'; | ||
| export * from './body/static-body'; | ||
| export * from './view/sprite'; | ||
| export * from './view/npc'; | ||
| export * from './view/player'; | ||
| export * from './view/skybox'; | ||
| export * from './view/ocean'; | ||
| export * from './view/billboard'; | ||
| export * from './model'; | ||
| "use strict"; | ||
| var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
| if (k2 === undefined) k2 = k; | ||
| var desc = Object.getOwnPropertyDescriptor(m, k); | ||
| if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { | ||
| desc = { enumerable: true, get: function() { return m[k]; } }; | ||
| } | ||
| Object.defineProperty(o, k2, desc); | ||
| }) : (function(o, m, k, k2) { | ||
| if (k2 === undefined) k2 = k; | ||
| o[k2] = m[k]; | ||
| })); | ||
| var __exportStar = (this && this.__exportStar) || function(m, exports) { | ||
| for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| __exportStar(require("./level/index"), exports); | ||
| __exportStar(require("./level/box-mesh"), exports); | ||
| __exportStar(require("./level/model"), exports); | ||
| __exportStar(require("./level/abstract-level"), exports); | ||
| __exportStar(require("./utils/view-utils"), exports); | ||
| __exportStar(require("./utils/debug"), exports); | ||
| __exportStar(require("./utils/texture-utils"), exports); | ||
| __exportStar(require("./utils/detect-mobile"), exports); | ||
| __exportStar(require("./utils/query-params"), exports); | ||
| __exportStar(require("./state/index"), exports); | ||
| __exportStar(require("./events"), exports); | ||
| __exportStar(require("./loader"), exports); | ||
| __exportStar(require("./core/renderer"), exports); | ||
| __exportStar(require("./core/mouse"), exports); | ||
| __exportStar(require("./core/camera"), exports); | ||
| __exportStar(require("./body/dynamic-body"), exports); | ||
| __exportStar(require("./body/abstract-body"), exports); | ||
| __exportStar(require("./body/static-body"), exports); | ||
| __exportStar(require("./view/sprite"), exports); | ||
| __exportStar(require("./view/npc"), exports); | ||
| __exportStar(require("./view/player"), exports); | ||
| __exportStar(require("./view/skybox"), exports); | ||
| __exportStar(require("./view/ocean"), exports); | ||
| __exportStar(require("./view/billboard"), exports); | ||
| __exportStar(require("./model"), exports); |
@@ -1,6 +0,9 @@ | ||
| import { Map } from 'rot-js'; | ||
| import { physics } from '../state'; | ||
| import { DeviceDetector } from '../utils/detect-mobile'; | ||
| import { queryParams } from '../utils/query-params'; | ||
| export class AbstractLevel { | ||
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.AbstractLevel = void 0; | ||
| const rot_js_1 = require("rot-js"); | ||
| const state_1 = require("../state"); | ||
| const detect_mobile_1 = require("../utils/detect-mobile"); | ||
| const query_params_1 = require("../utils/query-params"); | ||
| class AbstractLevel { | ||
| static zToStep(z = 0) { | ||
@@ -14,3 +17,3 @@ return Math.round(z / AbstractLevel.STEP); | ||
| return Array.from({ length: max }, () => { | ||
| const map = new Map.Cellular(cols, rows); | ||
| const map = new rot_js_1.Map.Cellular(cols, rows); | ||
| map.randomize(fill); | ||
@@ -56,3 +59,3 @@ for (let i = 0; i < iterations; i++) { | ||
| const { x, y } = this.getXY(col, row); | ||
| return physics.createBox({ x, y }, 1, 1, { | ||
| return state_1.physics.createBox({ x, y }, 1, 1, { | ||
| isStatic: true, | ||
@@ -63,12 +66,13 @@ userData: { step: AbstractLevel.zToStep(z) } | ||
| } | ||
| exports.AbstractLevel = AbstractLevel; | ||
| AbstractLevel.STEP = 0.25; | ||
| AbstractLevel.COLS = DeviceDetector.HIGH_END ? 32 : 24; | ||
| AbstractLevel.ROWS = DeviceDetector.HIGH_END ? 32 : 24; | ||
| AbstractLevel.COLS = detect_mobile_1.DeviceDetector.HIGH_END ? 32 : 24; | ||
| AbstractLevel.ROWS = detect_mobile_1.DeviceDetector.HIGH_END ? 32 : 24; | ||
| AbstractLevel.FILL = 0.5; | ||
| AbstractLevel.POND = 0.36; | ||
| AbstractLevel.ITERATIONS = 4; | ||
| AbstractLevel.HEIGHT_MAX = 'height' in queryParams | ||
| ? Number(queryParams.height) | ||
| : DeviceDetector.HIGH_END | ||
| AbstractLevel.HEIGHT_MAX = 'height' in query_params_1.queryParams | ||
| ? Number(query_params_1.queryParams.height) | ||
| : detect_mobile_1.DeviceDetector.HIGH_END | ||
| ? 16 | ||
| : 12; |
@@ -1,8 +0,11 @@ | ||
| import { BoxGeometry, InstancedMesh, MeshBasicMaterial } from 'three'; | ||
| import { TextureUtils } from '../utils/texture-utils'; | ||
| export class BoxMesh extends InstancedMesh { | ||
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.BoxMesh = void 0; | ||
| const three_1 = require("three"); | ||
| const texture_utils_1 = require("../utils/texture-utils"); | ||
| class BoxMesh extends three_1.InstancedMesh { | ||
| constructor(textures, cols, rows = cols) { | ||
| const geometry = new BoxGeometry(1, 1, 1); | ||
| const materials = textures.map((texture) => new MeshBasicMaterial({ | ||
| ...TextureUtils.PROPS, | ||
| const geometry = new three_1.BoxGeometry(1, 1, 1); | ||
| const materials = textures.map((texture) => new three_1.MeshBasicMaterial({ | ||
| ...texture_utils_1.TextureUtils.PROPS, | ||
| map: texture | ||
@@ -14,1 +17,2 @@ })); | ||
| } | ||
| exports.BoxMesh = BoxMesh; |
+24
-20
@@ -1,13 +0,16 @@ | ||
| import { Vector3 } from 'three'; | ||
| import { Renderer } from '../core/renderer'; | ||
| import { Events } from '../events'; | ||
| import { state } from '../state'; | ||
| import { getMatrix } from '../utils/view-utils'; | ||
| import { AbstractLevel } from './abstract-level'; | ||
| import { BoxMesh } from './box-mesh'; | ||
| import { Billboard } from '../view/billboard'; | ||
| import { TextureUtils } from '../utils/texture-utils'; | ||
| export class Level extends AbstractLevel { | ||
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.Level = void 0; | ||
| const three_1 = require("three"); | ||
| const renderer_1 = require("../core/renderer"); | ||
| const events_1 = require("../events"); | ||
| const state_1 = require("../state"); | ||
| const view_utils_1 = require("../utils/view-utils"); | ||
| const abstract_level_1 = require("./abstract-level"); | ||
| const box_mesh_1 = require("./box-mesh"); | ||
| const billboard_1 = require("../view/billboard"); | ||
| const texture_utils_1 = require("../utils/texture-utils"); | ||
| class Level extends abstract_level_1.AbstractLevel { | ||
| static async create(canvas, { sides, floor, ocean, objects = Level.DEFAULT_OBJECTS } = {}) { | ||
| const [sidesTex, floorTex, oceanTex] = await TextureUtils.load([ | ||
| const [sidesTex, floorTex, oceanTex] = await texture_utils_1.TextureUtils.load([ | ||
| sides || Level.SIDES, | ||
@@ -22,3 +25,3 @@ floor || Level.FLOOR, | ||
| ocean: oceanTex, | ||
| textures: TextureUtils.mapToCube({ | ||
| textures: texture_utils_1.TextureUtils.mapToCube({ | ||
| up: floorTex, | ||
@@ -34,4 +37,4 @@ down: floorTex, | ||
| constructor({ textures, canvas, ocean, skybox, objects = {} }, setLevel = true) { | ||
| Renderer.create({ canvas, ocean, skybox }); | ||
| Events.addEventListeners(); | ||
| renderer_1.Renderer.create({ canvas, ocean, skybox }); | ||
| events_1.Events.addEventListeners(); | ||
| super(); | ||
@@ -46,7 +49,7 @@ this.mesh = this.createBoxMesh(textures); | ||
| if (setLevel) { | ||
| state.renderer.setLevel(this); | ||
| state_1.state.renderer.setLevel(this); | ||
| } | ||
| } | ||
| createBoxMesh(textures) { | ||
| const box = new BoxMesh(textures, Level.COLS, Level.ROWS); | ||
| const box = new box_mesh_1.BoxMesh(textures, Level.COLS, Level.ROWS); | ||
| box.position.set(-Level.COLS / 2, 0, -Level.ROWS / 2); | ||
@@ -57,4 +60,4 @@ return box; | ||
| Object.entries(this.objects).forEach(([texturePath, { minHeight, maxHeight, fill = 0.5, chance = 0.5, iterations = 1, spread = 1, scale = 1 }]) => { | ||
| const textureName = TextureUtils.getName(texturePath); | ||
| if (!TextureUtils.hasTexture(textureName)) | ||
| const textureName = texture_utils_1.TextureUtils.getName(texturePath); | ||
| if (!texture_utils_1.TextureUtils.hasTexture(textureName)) | ||
| return; | ||
@@ -78,3 +81,3 @@ const heights = Level.createMatrix({ | ||
| const { x, y } = this.getXY(col, row); | ||
| new Billboard({ | ||
| new billboard_1.Billboard({ | ||
| textureName, | ||
@@ -92,6 +95,7 @@ scale, | ||
| setMeshHeight(col, row, height) { | ||
| const matrix = getMatrix(new Vector3(col, height / 2 - 0.75, row), new Vector3(1, height, 1)); | ||
| const matrix = (0, view_utils_1.getMatrix)(new three_1.Vector3(col, height / 2 - 0.75, row), new three_1.Vector3(1, height, 1)); | ||
| this.mesh.setMatrixAt(row * Level.ROWS + col, matrix); | ||
| } | ||
| } | ||
| exports.Level = Level; | ||
| Level.SIDES = 'sides.webp'; | ||
@@ -98,0 +102,0 @@ Level.FLOOR = 'floor.webp'; |
@@ -1,1 +0,2 @@ | ||
| export {}; | ||
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); |
+15
-11
@@ -1,7 +0,10 @@ | ||
| import { LoadingManager, TextureLoader } from 'three'; | ||
| import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js'; | ||
| import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader.js'; | ||
| import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'; | ||
| import { TGALoader } from 'three/examples/jsm/loaders/TGALoader.js'; | ||
| export class Loader extends LoadingManager { | ||
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.Loader = void 0; | ||
| const three_1 = require("three"); | ||
| const DRACOLoader_js_1 = require("three/examples/jsm/loaders/DRACOLoader.js"); | ||
| const FBXLoader_js_1 = require("three/examples/jsm/loaders/FBXLoader.js"); | ||
| const GLTFLoader_js_1 = require("three/examples/jsm/loaders/GLTFLoader.js"); | ||
| const TGALoader_js_1 = require("three/examples/jsm/loaders/TGALoader.js"); | ||
| class Loader extends three_1.LoadingManager { | ||
| constructor(onLoad, onProgress, onError) { | ||
@@ -16,5 +19,5 @@ super(onLoad, onProgress, onError); | ||
| if (!this.gltfLoader) { | ||
| const dracoLoader = new DRACOLoader(); | ||
| const dracoLoader = new DRACOLoader_js_1.DRACOLoader(); | ||
| dracoLoader.setDecoderPath(Loader.DRACO_LOADER_PATH); | ||
| this.gltfLoader = new GLTFLoader(); | ||
| this.gltfLoader = new GLTFLoader_js_1.GLTFLoader(); | ||
| this.gltfLoader.setDRACOLoader(dracoLoader); | ||
@@ -25,3 +28,3 @@ } | ||
| if (!this.fbxLoader) { | ||
| this.fbxLoader = new FBXLoader(this); | ||
| this.fbxLoader = new FBXLoader_js_1.FBXLoader(this); | ||
| } | ||
@@ -32,3 +35,3 @@ return this.fbxLoader.load(path, resolve); | ||
| this.tgaLoader = true; | ||
| this.addHandler(/\.tga$/i, new TGALoader()); | ||
| this.addHandler(/\.tga$/i, new TGALoader_js_1.TGALoader()); | ||
| } | ||
@@ -38,3 +41,3 @@ break; | ||
| if (!this.textureLoader) { | ||
| this.textureLoader = new TextureLoader(this); | ||
| this.textureLoader = new three_1.TextureLoader(this); | ||
| } | ||
@@ -45,2 +48,3 @@ return this.textureLoader.load(path, resolve); | ||
| } | ||
| exports.Loader = Loader; | ||
| Loader.DRACO_LOADER_PATH = 'https://www.gstatic.com/draco/versioned/decoders/1.5.7/'; |
+2
-1
@@ -1,1 +0,2 @@ | ||
| export {}; | ||
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); |
@@ -1,4 +0,7 @@ | ||
| import { System } from 'check2d'; | ||
| export const physics = new System(); | ||
| export const state = { | ||
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.state = exports.physics = void 0; | ||
| const check2d_1 = require("check2d"); | ||
| exports.physics = new check2d_1.System(); | ||
| exports.state = { | ||
| keys: {}, | ||
@@ -5,0 +8,0 @@ renderer: null, |
@@ -1,2 +0,5 @@ | ||
| export class Debug { | ||
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.Debug = void 0; | ||
| class Debug { | ||
| static set(innerHTML) { | ||
@@ -19,1 +22,2 @@ Debug.get().innerHTML = innerHTML; | ||
| } | ||
| exports.Debug = Debug; |
@@ -1,7 +0,11 @@ | ||
| import { queryParams } from './query-params'; | ||
| export class DeviceDetector { | ||
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.DeviceDetector = void 0; | ||
| const query_params_1 = require("./query-params"); | ||
| class DeviceDetector { | ||
| } | ||
| exports.DeviceDetector = DeviceDetector; | ||
| DeviceDetector.IS_MOBILE = /Mobi|Android/i.test(navigator.userAgent); | ||
| DeviceDetector.IS_TV = /Android TV|SmartTV|AppleTV|Tizen|webOS|NetCast|Roku|PhilipsTV|SonyTV|HbbTV|LGTV|Viera|Aquos/i.test(navigator.userAgent); | ||
| DeviceDetector.LOW_END = DeviceDetector.IS_MOBILE || DeviceDetector.IS_TV || 'lowend' in queryParams; | ||
| DeviceDetector.LOW_END = DeviceDetector.IS_MOBILE || DeviceDetector.IS_TV || 'lowend' in query_params_1.queryParams; | ||
| DeviceDetector.HIGH_END = !DeviceDetector.LOW_END; |
@@ -1,2 +0,5 @@ | ||
| export const getQueryParams = () => { | ||
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.queryParams = exports.getQueryParams = void 0; | ||
| const getQueryParams = () => { | ||
| if (typeof location === 'undefined') { | ||
@@ -11,2 +14,3 @@ return {}; | ||
| }; | ||
| export const queryParams = getQueryParams(); | ||
| exports.getQueryParams = getQueryParams; | ||
| exports.queryParams = (0, exports.getQueryParams)(); |
@@ -1,4 +0,7 @@ | ||
| import { FrontSide, MeshBasicMaterial, NearestFilter, NearestMipMapLinearFilter } from 'three'; | ||
| import { Loader } from '../loader'; | ||
| export class TextureUtils { | ||
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.TextureUtils = void 0; | ||
| const three_1 = require("three"); | ||
| const loader_1 = require("../loader"); | ||
| class TextureUtils { | ||
| static hasTexture(textureName) { | ||
@@ -19,3 +22,3 @@ return !!TextureUtils.textures[textureName]; | ||
| static createMaterial(map, props = TextureUtils.ALPHA_PROPS) { | ||
| return new MeshBasicMaterial({ | ||
| return new three_1.MeshBasicMaterial({ | ||
| ...props, | ||
@@ -54,4 +57,4 @@ map | ||
| texture.matrixAutoUpdate = false; | ||
| texture.magFilter = NearestFilter; | ||
| texture.minFilter = NearestMipMapLinearFilter; | ||
| texture.magFilter = three_1.NearestFilter; | ||
| texture.minFilter = three_1.NearestMipMapLinearFilter; | ||
| } | ||
@@ -62,7 +65,8 @@ static mapToCube({ left, right, up, down, front, back }) { | ||
| } | ||
| TextureUtils.loader = new Loader(); | ||
| exports.TextureUtils = TextureUtils; | ||
| TextureUtils.loader = new loader_1.Loader(); | ||
| TextureUtils.textures = {}; | ||
| TextureUtils.materials = {}; | ||
| TextureUtils.PROPS = { | ||
| side: FrontSide | ||
| side: three_1.FrontSide | ||
| }; | ||
@@ -69,0 +73,0 @@ TextureUtils.ALPHA_PROPS = { |
+19
-11
@@ -1,8 +0,14 @@ | ||
| import { Matrix4, Quaternion, Vector3 } from 'three'; | ||
| export const Math_Half_PI = Math.PI * 0.5; | ||
| export const Math_Double_PI = Math.PI * 2; | ||
| export const normalizeAngle = (angle) => (Math_Double_PI + angle) % Math_Double_PI; | ||
| export const normalize = (n) => Math.min(1, Math.max(-1, n)); | ||
| export const randomOf = (array) => array[Math.floor(Math.random() * array.length)]; | ||
| export const distanceSq = (a, b) => { | ||
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.getMatrix = exports.distanceSq = exports.randomOf = exports.normalize = exports.normalizeAngle = exports.Math_Double_PI = exports.Math_Half_PI = void 0; | ||
| const three_1 = require("three"); | ||
| exports.Math_Half_PI = Math.PI * 0.5; | ||
| exports.Math_Double_PI = Math.PI * 2; | ||
| const normalizeAngle = (angle) => (exports.Math_Double_PI + angle) % exports.Math_Double_PI; | ||
| exports.normalizeAngle = normalizeAngle; | ||
| const normalize = (n) => Math.min(1, Math.max(-1, n)); | ||
| exports.normalize = normalize; | ||
| const randomOf = (array) => array[Math.floor(Math.random() * array.length)]; | ||
| exports.randomOf = randomOf; | ||
| const distanceSq = (a, b) => { | ||
| const x = a.x - b.x; | ||
@@ -12,8 +18,10 @@ const y = a.z - b.z; | ||
| }; | ||
| export const getMatrix = (position, scale) => { | ||
| const matrix = new Matrix4(); | ||
| const quaternion = new Quaternion(); | ||
| const offset = new Vector3(0.5, 0.5, 0.5); | ||
| exports.distanceSq = distanceSq; | ||
| const getMatrix = (position, scale) => { | ||
| const matrix = new three_1.Matrix4(); | ||
| const quaternion = new three_1.Quaternion(); | ||
| const offset = new three_1.Vector3(0.5, 0.5, 0.5); | ||
| matrix.compose(position.add(offset), quaternion, scale); | ||
| return matrix; | ||
| }; | ||
| exports.getMatrix = getMatrix; |
+32
-28
@@ -1,12 +0,15 @@ | ||
| import { Mesh, Object3D, PlaneGeometry, Texture, Vector3 } from 'three'; | ||
| import { StaticBody } from '../body/static-body'; | ||
| import { Camera } from '../core/camera'; | ||
| import { AbstractLevel } from '../level/abstract-level'; | ||
| import { state } from '../state'; | ||
| import { TextureUtils } from '../utils/texture-utils'; | ||
| import { normalizeAngle } from '../utils/view-utils'; | ||
| export class Billboard { | ||
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.Billboard = void 0; | ||
| const three_1 = require("three"); | ||
| const static_body_1 = require("../body/static-body"); | ||
| const camera_1 = require("../core/camera"); | ||
| const abstract_level_1 = require("../level/abstract-level"); | ||
| const state_1 = require("../state"); | ||
| const texture_utils_1 = require("../utils/texture-utils"); | ||
| const view_utils_1 = require("../utils/view-utils"); | ||
| class Billboard { | ||
| static async create(level, { texture, ...props }, Class = Billboard) { | ||
| await TextureUtils.load([texture]); | ||
| const textureName = TextureUtils.getName(texture); | ||
| await texture_utils_1.TextureUtils.load([texture]); | ||
| const textureName = texture_utils_1.TextureUtils.getName(texture); | ||
| return new Class({ level, textureName, ...props }); | ||
@@ -29,3 +32,3 @@ } | ||
| this.spawn(level, x, y); | ||
| state.renderer.add(this); | ||
| state_1.state.renderer.add(this); | ||
| } | ||
@@ -35,7 +38,7 @@ update(_) { | ||
| this.mesh.position.set(this.body.x, this.body.z + this.centerOffset, this.body.y); | ||
| const playerPos = state.player?.mesh.position; | ||
| const playerPos = state_1.state.player?.mesh.position; | ||
| if (!playerPos) { | ||
| return; | ||
| } | ||
| const cameraPos = state.renderer.camera.position; | ||
| const cameraPos = state_1.state.renderer.camera.position; | ||
| const x = cameraPos.x - (playerPos.x - cameraPos.x) * 2; | ||
@@ -55,6 +58,6 @@ const z = cameraPos.z - (playerPos.z - cameraPos.z) * 2; | ||
| getProjection() { | ||
| if (state.renderer?.camera) { | ||
| this.mesh.getWorldPosition(Camera.projection); | ||
| Camera.projection.project(state.renderer.camera); | ||
| return Camera.projection; | ||
| if (state_1.state.renderer?.camera) { | ||
| this.mesh.getWorldPosition(camera_1.Camera.projection); | ||
| camera_1.Camera.projection.project(state_1.state.renderer.camera); | ||
| return camera_1.Camera.projection; | ||
| } | ||
@@ -64,3 +67,3 @@ } | ||
| try { | ||
| const mat = TextureUtils.getMaterial(textureName, this.cols, this.rows); | ||
| const mat = texture_utils_1.TextureUtils.getMaterial(textureName, this.cols, this.rows); | ||
| const image = mat.map.image; | ||
@@ -72,13 +75,13 @@ const w = image.width / this.cols; | ||
| const height = (this.scaleY * h) / max; | ||
| return new Mesh(new PlaneGeometry(width, height), mat); | ||
| return new three_1.Mesh(new three_1.PlaneGeometry(width, height), mat); | ||
| } | ||
| catch (materialError) { | ||
| console.error({ textureName, materialError }); | ||
| return new Object3D(); | ||
| return new three_1.Object3D(); | ||
| } | ||
| } | ||
| createBody(x, y, level) { | ||
| return new StaticBody(x, y, level); | ||
| return new static_body_1.StaticBody(x, y, level); | ||
| } | ||
| spawn(level, x = (Math.random() - 0.5) * (AbstractLevel.COLS * 0.5), y = (Math.random() - 0.5) * (AbstractLevel.ROWS * 0.5)) { | ||
| spawn(level, x = (Math.random() - 0.5) * (abstract_level_1.AbstractLevel.COLS * 0.5), y = (Math.random() - 0.5) * (abstract_level_1.AbstractLevel.ROWS * 0.5)) { | ||
| this.body = this.createBody(x, y, level); | ||
@@ -88,3 +91,3 @@ this.mesh.position.set(x, this.body.z, y); | ||
| updateTexture() { | ||
| if (this.mesh instanceof Mesh) { | ||
| if (this.mesh instanceof three_1.Mesh) { | ||
| const frameIndex = Math.floor(this.frame); | ||
@@ -98,3 +101,3 @@ const row = this.getRow(this.direction); | ||
| materials.forEach((material) => { | ||
| if (material.map instanceof Texture) { | ||
| if (material.map instanceof three_1.Texture) { | ||
| material.map.offset.set(x * this.invCols, y * this.invRows); | ||
@@ -107,5 +110,5 @@ material.map.updateMatrix(); | ||
| getDirection() { | ||
| const bodyAngle = normalizeAngle(this.body.angle); | ||
| const camAngle = normalizeAngle(state.player?.body.angle || state.renderer.camera.rotation.y); | ||
| const angle = normalizeAngle(bodyAngle - camAngle); | ||
| const bodyAngle = (0, view_utils_1.normalizeAngle)(this.body.angle); | ||
| const camAngle = (0, view_utils_1.normalizeAngle)(state_1.state.player?.body.angle || state_1.state.renderer.camera.rotation.y); | ||
| const angle = (0, view_utils_1.normalizeAngle)(bodyAngle - camAngle); | ||
| const directionIndex = Math.floor((2 * angle) / Math.PI); | ||
@@ -120,4 +123,5 @@ return Billboard.DIRECTIONS[directionIndex]; | ||
| } | ||
| exports.Billboard = Billboard; | ||
| Billboard.DIRECTIONS = ['up', 'right', 'down', 'left']; | ||
| Billboard.compensateGroupZ = 0.2; | ||
| Billboard.tempVector = new Vector3(); | ||
| Billboard.tempVector = new three_1.Vector3(); |
+14
-10
@@ -1,6 +0,9 @@ | ||
| import { AbstractLevel } from '../level/abstract-level'; | ||
| import { DeviceDetector } from '../utils/detect-mobile'; | ||
| import { queryParams } from '../utils/query-params'; | ||
| import { Sprite } from './sprite'; | ||
| export class NPC extends Sprite { | ||
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.NPC = void 0; | ||
| const abstract_level_1 = require("../level/abstract-level"); | ||
| const detect_mobile_1 = require("../utils/detect-mobile"); | ||
| const query_params_1 = require("../utils/query-params"); | ||
| const sprite_1 = require("./sprite"); | ||
| class NPC extends sprite_1.Sprite { | ||
| constructor() { | ||
@@ -17,3 +20,3 @@ super(...arguments); | ||
| static async create(level, props, Class = NPC) { | ||
| return Sprite.create(level, props, Class); | ||
| return sprite_1.Sprite.create(level, props, Class); | ||
| } | ||
@@ -26,3 +29,3 @@ static randomProp() { | ||
| const dy = this.mesh.position.z; | ||
| const radius = (AbstractLevel.COLS + AbstractLevel.ROWS) / 2; | ||
| const radius = (abstract_level_1.AbstractLevel.COLS + abstract_level_1.AbstractLevel.ROWS) / 2; | ||
| const diff = Math.sqrt(dx * dx + dy * dy) - radius; | ||
@@ -51,8 +54,9 @@ if (diff > 0 && Math.random() < diff / radius) { | ||
| } | ||
| exports.NPC = NPC; | ||
| NPC.MAX_SPEED = 0; | ||
| NPC.MAX_ROTATION = 100; | ||
| NPC.DEFAULT_COUNT = 'limit' in queryParams | ||
| ? Number(queryParams.limit) | ||
| : DeviceDetector.HIGH_END | ||
| NPC.DEFAULT_COUNT = 'limit' in query_params_1.queryParams | ||
| ? Number(query_params_1.queryParams.limit) | ||
| : detect_mobile_1.DeviceDetector.HIGH_END | ||
| ? 64 | ||
| : 48; |
+23
-19
@@ -1,15 +0,18 @@ | ||
| import { CircleGeometry, Group, Mesh, MeshBasicMaterial, RepeatWrapping, Vector3 } from 'three'; | ||
| import { AbstractLevel } from '../level/abstract-level'; | ||
| import { state } from '../state'; | ||
| import { TextureUtils } from '../utils/texture-utils'; | ||
| import { Math_Half_PI } from '../utils/view-utils'; | ||
| export class Ocean { | ||
| constructor(texture, scale = AbstractLevel.STEP * 2) { | ||
| this.mesh = new Group(); | ||
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.Ocean = void 0; | ||
| const three_1 = require("three"); | ||
| const abstract_level_1 = require("../level/abstract-level"); | ||
| const state_1 = require("../state"); | ||
| const texture_utils_1 = require("../utils/texture-utils"); | ||
| const view_utils_1 = require("../utils/view-utils"); | ||
| class Ocean { | ||
| constructor(texture, scale = abstract_level_1.AbstractLevel.STEP * 2) { | ||
| this.mesh = new three_1.Group(); | ||
| this.animations = []; | ||
| this.startTime = Date.now(); | ||
| this.cols = AbstractLevel.COLS; | ||
| this.rows = AbstractLevel.ROWS; | ||
| texture.wrapS = RepeatWrapping; | ||
| texture.wrapT = RepeatWrapping; | ||
| this.cols = abstract_level_1.AbstractLevel.COLS; | ||
| this.rows = abstract_level_1.AbstractLevel.ROWS; | ||
| texture.wrapS = three_1.RepeatWrapping; | ||
| texture.wrapT = three_1.RepeatWrapping; | ||
| texture.repeat.set(this.cols * scale, this.rows * scale); | ||
@@ -19,6 +22,6 @@ texture.updateMatrix(); | ||
| this.mesh.add(this.createWater(texture, 1)); | ||
| state.renderer.add(this); | ||
| state_1.state.renderer.add(this); | ||
| } | ||
| update(ms = 0) { | ||
| const { x, y } = state.renderer.camera?.target?.body || { x: 0, y: 0 }; | ||
| const { x, y } = state_1.state.renderer.camera?.target?.body || { x: 0, y: 0 }; | ||
| this.mesh.position.set(x, Ocean.DEEP_WATER_Z, y); | ||
@@ -30,5 +33,5 @@ this.animations.forEach((animation) => animation(ms)); | ||
| const radius = Math.hypot(this.cols, this.rows) / 2; | ||
| const geometry = new CircleGeometry(radius); | ||
| const material = new MeshBasicMaterial({ | ||
| ...TextureUtils.ALPHA_PROPS, | ||
| const geometry = new three_1.CircleGeometry(radius); | ||
| const material = new three_1.MeshBasicMaterial({ | ||
| ...texture_utils_1.TextureUtils.ALPHA_PROPS, | ||
| alphaTest: opacity, | ||
@@ -38,5 +41,5 @@ opacity, | ||
| }); | ||
| const mesh = new Mesh(geometry, material); | ||
| const mesh = new three_1.Mesh(geometry, material); | ||
| const scale = level + 1; | ||
| mesh.setRotationFromAxisAngle(new Vector3(1, 0, 0), -Math_Half_PI); | ||
| mesh.setRotationFromAxisAngle(new three_1.Vector3(1, 0, 0), -view_utils_1.Math_Half_PI); | ||
| mesh.position.set(0, -0.25 + 0.25 * level, 0); | ||
@@ -54,2 +57,3 @@ mesh.scale.set(scale, scale, scale); | ||
| } | ||
| exports.Ocean = Ocean; | ||
| Ocean.DEEP_WATER_Z = -0.2; |
+13
-9
@@ -1,14 +0,17 @@ | ||
| import { mouse } from '../core/mouse'; | ||
| import { state } from '../state'; | ||
| import { Sprite } from './sprite'; | ||
| export class Player extends Sprite { | ||
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.Player = void 0; | ||
| const mouse_1 = require("../core/mouse"); | ||
| const state_1 = require("../state"); | ||
| const sprite_1 = require("./sprite"); | ||
| class Player extends sprite_1.Sprite { | ||
| static async create(level, props = { texture: 'player.webp' }, Class = Player) { | ||
| return Sprite.create(level, props, Class); | ||
| return sprite_1.Sprite.create(level, props, Class); | ||
| } | ||
| constructor({ level, ...props }, setTarget = true) { | ||
| super({ ...Player.DEFAULT_PROPS, level, ...props }, state); | ||
| super({ ...Player.DEFAULT_PROPS, level, ...props }, state_1.state); | ||
| if (setTarget) { | ||
| state.mouse = mouse; | ||
| state.player = this; | ||
| state.renderer.setTarget(this); | ||
| state_1.state.mouse = mouse_1.mouse; | ||
| state_1.state.player = this; | ||
| state_1.state.renderer.setTarget(this); | ||
| } | ||
@@ -32,2 +35,3 @@ } | ||
| } | ||
| exports.Player = Player; | ||
| Player.DIRECTIONS = ['left', 'right', 'down', 'up']; | ||
@@ -34,0 +38,0 @@ Player.DEFAULT_PROPS = { |
+45
-8
@@ -1,14 +0,51 @@ | ||
| import * as THREE from 'three'; | ||
| import { state } from '../state'; | ||
| import { TextureUtils } from '../utils/texture-utils'; | ||
| export class Skybox { | ||
| "use strict"; | ||
| var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
| if (k2 === undefined) k2 = k; | ||
| var desc = Object.getOwnPropertyDescriptor(m, k); | ||
| if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { | ||
| desc = { enumerable: true, get: function() { return m[k]; } }; | ||
| } | ||
| Object.defineProperty(o, k2, desc); | ||
| }) : (function(o, m, k, k2) { | ||
| if (k2 === undefined) k2 = k; | ||
| o[k2] = m[k]; | ||
| })); | ||
| var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { | ||
| Object.defineProperty(o, "default", { enumerable: true, value: v }); | ||
| }) : function(o, v) { | ||
| o["default"] = v; | ||
| }); | ||
| var __importStar = (this && this.__importStar) || (function () { | ||
| var ownKeys = function(o) { | ||
| ownKeys = Object.getOwnPropertyNames || function (o) { | ||
| var ar = []; | ||
| for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; | ||
| return ar; | ||
| }; | ||
| return ownKeys(o); | ||
| }; | ||
| return function (mod) { | ||
| if (mod && mod.__esModule) return mod; | ||
| var result = {}; | ||
| if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); | ||
| __setModuleDefault(result, mod); | ||
| return result; | ||
| }; | ||
| })(); | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.Skybox = void 0; | ||
| const THREE = __importStar(require("three")); | ||
| const state_1 = require("../state"); | ||
| const texture_utils_1 = require("../utils/texture-utils"); | ||
| class Skybox { | ||
| constructor(textures = Skybox.DEFAULT_TEXTURES, callback = Skybox.DEFAULT_CALLBACK) { | ||
| const loader = new THREE.CubeTextureLoader(TextureUtils.loader); | ||
| const skyboxTextures = TextureUtils.mapToCube(textures); | ||
| const loader = new THREE.CubeTextureLoader(texture_utils_1.TextureUtils.loader); | ||
| const skyboxTextures = texture_utils_1.TextureUtils.mapToCube(textures); | ||
| loader.load(skyboxTextures, callback); | ||
| } | ||
| } | ||
| exports.Skybox = Skybox; | ||
| Skybox.DEFAULT_CALLBACK = (skyBox) => { | ||
| TextureUtils.pixelate(skyBox); | ||
| state.renderer.scene.background = skyBox; | ||
| texture_utils_1.TextureUtils.pixelate(skyBox); | ||
| state_1.state.renderer.scene.background = skyBox; | ||
| }; | ||
@@ -15,0 +52,0 @@ Skybox.DEFAULT_TEXTURES = { |
+18
-14
@@ -1,10 +0,13 @@ | ||
| import { AbstractBody } from '../body/abstract-body'; | ||
| import { DynamicBody } from '../body/dynamic-body'; | ||
| import { Mouse } from '../core/mouse'; | ||
| import { physics } from '../state'; | ||
| import { normalizeAngle } from '../utils/view-utils'; | ||
| import { Billboard } from './billboard'; | ||
| export class Sprite extends Billboard { | ||
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.Sprite = void 0; | ||
| const abstract_body_1 = require("../body/abstract-body"); | ||
| const dynamic_body_1 = require("../body/dynamic-body"); | ||
| const mouse_1 = require("../core/mouse"); | ||
| const state_1 = require("../state"); | ||
| const view_utils_1 = require("../utils/view-utils"); | ||
| const billboard_1 = require("./billboard"); | ||
| class Sprite extends billboard_1.Billboard { | ||
| static async create(level, props, Class = Sprite) { | ||
| return Billboard.create(level, props, Class); | ||
| return billboard_1.Billboard.create(level, props, Class); | ||
| } | ||
@@ -16,3 +19,3 @@ constructor(props, state) { | ||
| this.velocity = 0; | ||
| this.state = state || { keys: {}, mouse: new Mouse() }; | ||
| this.state = state || { keys: {}, mouse: new mouse_1.Mouse() }; | ||
| } | ||
@@ -78,7 +81,7 @@ update(scale) { | ||
| if (scaleX !== 0) { | ||
| this.body.angle = normalizeAngle(this.body.angle + speed * scaleX); | ||
| this.body.angle = (0, view_utils_1.normalizeAngle)(this.body.angle + speed * scaleX); | ||
| } | ||
| } | ||
| updateFall(scale) { | ||
| const floor = AbstractBody.getZ(this.body); | ||
| const floor = abstract_body_1.AbstractBody.getZ(this.body); | ||
| const isOnGround = this.body.z === floor || this.velocity === 0; | ||
@@ -130,11 +133,12 @@ const isJumping = isOnGround && this.state.keys.space; | ||
| super.spawn(level, x, y); | ||
| this.body.z = AbstractBody.getZ(this.body); | ||
| this.body.z = abstract_body_1.AbstractBody.getZ(this.body); | ||
| this.body.separate(1); | ||
| } | ||
| createBody(x, y, level) { | ||
| const body = new DynamicBody(x, y, level); | ||
| physics.insert(body); | ||
| const body = new dynamic_body_1.DynamicBody(x, y, level); | ||
| state_1.physics.insert(body); | ||
| return body; | ||
| } | ||
| } | ||
| exports.Sprite = Sprite; | ||
| Sprite.JUMP_SPEED = 1.05; | ||
@@ -141,0 +145,0 @@ Sprite.ANIM_SPEED = 0.002; |
+1
-1
| { | ||
| "name": "make3d", | ||
| "description": "Game FrameWork for JavaScript 3D WebGL Games", | ||
| "version": "1.26.4", | ||
| "version": "1.26.5", | ||
| "main": "./dist/index.js", | ||
@@ -6,0 +6,0 @@ "types": "./dist/index.d.ts", |
+101
-8
| # make3d | ||
| # [<img src="https://img.shields.io/npm/dw/make3d.svg?style=for-the-badge&color=success" alt="npm downloads per week" />](https://www.npmjs.com/package/make3d) @ [<img src="https://img.shields.io/npm/v/make3d?style=for-the-badge&color=success" alt="npm version" />](https://www.npmjs.com/package/make3d?activeTab=versions) | ||
| ## [<img valign="middle" src="https://img.shields.io/npm/dw/make3d.svg?style=for-the-badge&color=success" alt="npm downloads per week" />](https://www.npmjs.com/package/make3d) @ [<img valign="middle" src="https://img.shields.io/npm/v/make3d?style=for-the-badge&color=success" alt="npm version" />](https://www.npmjs.com/package/make3d?activeTab=versions) | ||
| Game FrameWork for JavaScript 3D WebGL Games. | ||
| **make3d** is a lightweight framework for building **3D WebGL games in JavaScript**, built on top of **Three.js**. | ||
| - efficient and mobile friendly drawing ✔️ (threejs) | ||
| - efficient collision detection ✔️ (make2d) | ||
| It focuses on providing **game-oriented primitives** (levels, players, NPCs, physics helpers, input, rendering utilities), while leaving **scene hierarchy and lifecycle management to Three.js itself**. | ||
| ### highlights | ||
| - efficient, mobile-friendly rendering (Three.js) | ||
| - ready-to-use game abstractions (Level, Player, NPC) | ||
| - simple physics integration (powered by check2d) | ||
| - input, camera, rendering, and debug utilities included | ||
| - minimal structure, low abstraction overhead | ||
| --- | ||
| ## demo | ||
| https://nenjack.github.io/make3d/demo/ | ||
| 👉 https://nenjack.github.io/make3d/demo/ | ||
| --- | ||
| ## demo code | ||
| ```ts | ||
| import { Level, Player } from 'make3d' | ||
| import { Level, Player, NPC } from 'make3d' | ||
| Level.create().then(async (level) => { | ||
| await Player.create(level) | ||
| Array.from({ length: 50 }, () => new NPC({ level, ...Player.DEFAULT_PROPS })) | ||
@@ -25,8 +37,89 @@ }) | ||
| ## docs | ||
| --- | ||
| https://nenjack.github.io/make3d/hierarchy.html | ||
| ## design philosophy | ||
| make3d relies on Three.js for scene hierarchy and object lifecycle, instead of introducing a separate entity system. | ||
| - Scene graph and transforms are managed by **Three.js** | ||
| - Game logic is built around **Level**, **Player**, and **NPC** | ||
| - Utilities are exposed as composable modules, not enforced patterns | ||
| --- | ||
| ## exports | ||
| make3d exposes a focused set of modules, grouped by responsibility: | ||
| ### core | ||
| - **AbstractLevel** – base class for custom levels | ||
| - **Level** – main game level abstraction | ||
| ### rendering | ||
| - **Renderer** – Three.js renderer wrapper | ||
| - **Camera** – camera helper | ||
| - **BoxMesh** – basic mesh helper | ||
| - **Sprite** – sprite helper | ||
| - **Skybox** – skybox utility | ||
| - **Ocean** – ocean / water surface | ||
| - **Billboard** – camera-facing objects | ||
| ### entities | ||
| - **Player** – player entity | ||
| - **NPC** – non-player character | ||
| ### physics | ||
| - **DynamicBody** – movable physics body | ||
| - **StaticBody** – static physics body | ||
| - **AbstractBody** – base physics body | ||
| - **physics** – shared physics instance (powered by check2d) | ||
| ### input | ||
| - **Mouse** – mouse input handler | ||
| - **mouse** – shared mouse instance | ||
| ### state & events | ||
| - **state** – shared state container | ||
| - **Events** – event bus | ||
| ### loading & assets | ||
| - **Loader** – asset loader | ||
| - **TextureUtils** – texture helpers | ||
| ### environment & debug | ||
| - **Debug** – debug helpers | ||
| - **DeviceDetector** – device detection | ||
| - **getQueryParams** – get query params from current url | ||
| --- | ||
| ## documentation | ||
| - API & architecture | ||
| https://nenjack.github.io/make3d/hierarchy.html | ||
| --- | ||
| ## installation | ||
| ```bash | ||
| yarn add make3d | ||
| ``` | ||
| --- | ||
| ## license | ||
| MIT | ||
| ``` | ||
| ``` |
Sorry, the diff of this file is too big to display
6386926
0.15%53494
0.28%125
290.63%