// Copyright (c) 2026 Dominic Masters // // This software is released under the MIT License. // https://opensource.org/licenses/MIT var scene = {}; var player = require('player.js'); var assets = AssetBatch([ { path: 'test.png', type: Asset.TYPE_TEXTURE, format: Texture.FORMAT_RGBA } ]); // Pokemon DS-style camera: ~34 degrees elevation (atan(6/9)). // CAM_HEIGHT / CAM_DIST ratio controls the tilt — keep it under 0.7 for // the characteristically shallow DS angle. const CAM_HEIGHT = 6; const CAM_DIST = 9; var cam, camPos; var floorEntity; function updateCamera() { var pp = player.getPosition().worldPosition; // Position is offset above and behind the player; lookAt the exact player // world position so the player projects to the center pixel every frame. camPos.localPosition = new Vec3(pp.x, pp.y + CAM_HEIGHT, pp.z + CAM_DIST); camPos.lookAt(new Vec3(pp.x, pp.y, pp.z)); } scene.init = async function() { assets.lock(); await assets.loaded(); var texEntry = assets.entry(0); // Camera cam = Entity.create(); camPos = cam.add(Component.POSITION); cam.add(Component.CAMERA); // Floor — infinite static plane at Y=0. Rendered as a large flat blue // slab using the default SHADER_MATERIAL (no texture needed). floorEntity = Entity.create(); var floorPos = floorEntity.add(Component.POSITION); var floorPhysics = floorEntity.add(Component.PHYSICS); floorPhysics.bodyType = Physics.STATIC; floorPhysics.shape = Physics.SHAPE_PLANE; var floorR = floorEntity.add(Component.RENDERABLE); floorR.color = Color.BLUE; floorPos.localScale = new Vec3(16, 0.2, 16); floorPos.localPosition = new Vec3(0, -0.1, 0); // Player — spawns 1 unit above the floor so physics drops it cleanly. player.create(texEntry); // Initialise camera at the correct angle from the player's spawn position. updateCamera(); }; scene.update = function() { player.update(); updateCamera(); }; scene.dispose = function() { player.dispose(); Entity.dispose(floorEntity); Entity.dispose(cam); assets.unlock(); }; module.exports = scene;