Space sample source code

Sample page

<html>
<head>
    <title>Axis Engine Space game sample</title>
    
    <script type="text/javascript" src="https://www.palitri.com/vault/axis/engine/web/current/AxisEngine-min.js"></script>
    
    <script type="text/javascript">
        function Initialize()
        {
            var minShipToGateProximity = 2.0;
            var cameraTailingDistance = 10.0;
            var cameraResponsiveness = 2.0;
            var cameraTurnResponsiveness = 5.0;
            var cameraTransform = null;
            var shipTransform = null;
            var cameraRotation = new AxVector3();
            var gates = [];
            var viewport = new AxAnimationElement("viewport");
            var axis = new Axis(viewport.canvas);
            viewport.OnRender = function() { 
                axis.RenderScene(); 
                
                // Make camera trail behind the ship and follow its position
                var cameraPos = cameraTransform.GetPositionExtrinsic();
                var shipPos = shipTransform.GetPositionExtrinsic();
                var camVector = shipPos.Subtract(cameraPos);
                var spherical = camVector.Invert().CartesianToSpherical();
                camVector = camVector.OfLength(camVector.GetLength() - cameraTailingDistance);
                cameraRotation = cameraRotation.LerpSpherical(new AxVector3(spherical.y, AxMath.Pi * 1.5 -spherical.x, 0.0), axis.timer.time * cameraTurnResponsiveness);
                cameraTransform.SetPositionExtrinsic(cameraPos.Lerp(cameraPos.Add(camVector), axis.timer.time * cameraResponsiveness));
                cameraTransform.SetRotationIntrinsic(cameraRotation);
                
                // Check if the ship is close enough to a gate and if so, enable the green material for the gate and disable the arrows
                for (var i = 0; i < gates.length; i++) {
                    if (gates[i].gate.GetPositionExtrinsic().DistanceTo(shipPos) < minShipToGateProximity) {
                        gates[i].checkedMaterialSet.properties.Get(AxResource.propertyIndex_Enabled).SetBool(true);
                        gates[i].arrows.properties.Get(AxResource.propertyIndex_Enabled).SetBool(false);
                    }
                }
                
            };
            
            axis.ImportScene("Space.axs"
                function() {
                    // Store relevant scene entities
                    shipTransform = axis.FindResource("Ship", AxResourceType.Transform);
                    cameraTransform = axis.FindResource("Camera", AxResourceType.Transform);
                    
                    for (var asteroidIndex = 0; axis.FindResource("Asteroid00" + asteroidIndex.toString(), AxResourceType.EntitySet) !== null; asteroidIndex++) {
                        for (var gateIndex = 0; axis.FindResource("Gate0" + asteroidIndex.toString() + gateIndex.toString(), AxResourceType.Transform) !== null; gateIndex++) {
                            gates.push( {
                                gate : axis.FindResource("Gate0" + asteroidIndex.toString() + gateIndex.toString(), AxResourceType.Transform),
                                arrows : axis.FindResource("Arrows0" + asteroidIndex.toString() + gateIndex.toString(), AxResourceType.EntitySet),
                                checkedMaterialSet : axis.FindResource("GateInsideChecked0" + asteroidIndex.toString() + gateIndex.toString(), AxResourceType.EntitySet)
                            });
                        }
                    }
                    
                    // Create an input model for the ship
                    axis.inputModels.Add(new AxFlightInputModel(axis, shipTransform, 400.0, 5.0, 0.4, 5.0,
                        "Mouse Left,Key Space,Pad Analog Y right,Pad A""""""""""""",
                        "Mouse Y,Pad Analog Y left,Key W""Key S""Key A""Mouse X,Pad Analog X left,Key D""Pad Trigger analog left,Key Q""Pad Trigger analog right,Key E,Mouse Right",
                        "Mouse Left,Mouse Right,Pad Analog Y left,Pad Analog X left,Pad Trigger analog left,Pad Trigger analog right,Key A,Key D,Key W,Key S,Key Q,Key E"));
                    viewport.StartRendering();
                });
        }
</script>
</head>
<body onload="Initialize();" style="margin:0;">
    <canvas id="viewport" style="width:100%; height:100%;"></canvas>
</body>
</html>

Html

This example consists of a single canvas element inside of the body of the page.

The body element has its onload event set to call the Initialize() method and the canvas element has its id set to viewport so that it can be identified by Axis and used for rendering.

JavaScript

The whole setup of the 3d scene and rendering is performed in the Initialize() method.
First, a few parameter values are set and some variables are initialized. The cameraTransform and the shipTransform variables will hold references respectively to the camera's and the ship's transforms for convenience. The cameraRotation variable is used for the inertial rotation of the camera toward the ship.
The gates variable is an array, which will hold references to all the relevant gate-related objects in the scene. For each gate, these are:

  • The gate's transform, used to get its location and thus determine if the ship is passing through the gate
  • The entity set which contains the arrows above the gate. When the ship passes through the gate, we disable this set and thus the arrows disappear
  • The entity set which contains a green colored material for the inner ring of the gate. When the ship passes through the gate, we enable it, thus lighting the gate green

For a better understanding of the example, open the Space scene in the Editor and check out how it's structured.

A viewport object for utilizing the HTML canvas element and an axis object which is an instance of the engine are created

The OnRender() method of the viewport object is continuously called each frame and serves as the main loop. It renders the whole scene and performs the game-specific logic, in this case moves and orients the camera appropriately and checks if the ship is passing through a gate.

The camera's position is set in such a way, that it inertly trails at some distance behind the ship. That is achieved by simply interpolating between the line of its current position and the ship's position.
In addition, this line is shortened a bit (by the value of cameraTailingDistance, so that it doesn't reach the exact location of the ship, but just a little bit behind it.

The camera's orientation is determined by getting the spherical coordinates of the ship's location in respect to the camera's location.
Having the spherical coordinates, it's just a matter of rotating the camera by their value to get it oriented towards the ship. For more info on spherical coordinates, take a look at Wikipedia the wiki article
Finally, to make the turning of the camera inert and smooth, the same linear interpolation approach is used as with its positioning.

The ImportScene() method of axis loads the whole scene and invokes a callback method when done. In this callback, we get all the needed references to scene objects and set up an input model, which controls the ship.
The viewport's StartRendering() method is then called, which causes OnRender() to be continuously invoked and run the game.