1 module player;
2 
3 import liberty.engine;
4 
5 /**
6  * Example class for player.
7 **/
8 final class Player : Actor {
9   mixin(NodeBody);
10 
11   private {
12     WorldObject tree;
13     Material squareMaterial;
14     Camera camera;
15     BSPCube[2] playerBody;
16 
17     float gravity = -80.0f;
18     float jumpPower = 20.0f;
19     float upSpeed = 0;
20     float moveSpeed = 5.0f;
21     bool onGround;
22     int killZ = -10;
23   }
24 
25   /**
26    * Optional.
27    * If declared, it is called after all objects instantiation.
28   **/
29   override void start() {
30     tree = getScene().getTree();
31     squareMaterial = new Material("res/textures/default2.bmp");
32 
33     (camera = spawn!Camera("MyCam"))
34       .setPreset(CameraPreset.getEmpty())
35       .lockMouseMove()
36       .registerToScene();
37 
38     foreach (i; 0..2)
39       (playerBody[i] = spawn!BSPCube("Body" ~ i.to!string))
40         .build()
41         .getTransform()
42         .setLocalPositionY(i)
43         .setPivotY(0.5f);
44 
45     foreach (i; 0..50)
46       tree.spawn!BSPCube("Block" ~ i.to!string)
47         .build()
48         .getTransform()
49         .setWorldPositionX(uniform!"[]"(-19, 19))
50         .setWorldPositionZ(uniform!"[]"(-19, 19))
51         .setPivotY(0.5f);
52   }
53 
54   /**
55    * Optional.
56    * If declared, it is called every frame.
57   **/
58   override void update() {
59     if (Input.isKeyDown(KeyCode.T))
60       GfxEngine.toggleWireframe();
61 
62     updateMouseMode();
63     updateBody();
64     updatePhysics();
65 
66     if (getTransform().getWorldPosition().y < killZ)
67       CoreEngine.pause();
68 
69     if (Input.isKeyDown(KeyCode.F))
70       Platform.getWindow().toggleFullscreen();
71   }
72 
73   private void updateMouseMode() {
74     if (Input.isMouseButtonHold(MouseButton.RIGHT)) {
75       camera.unlockMouseMove();
76       Input.setMode(CursorType.DISABLED);
77     }
78     
79     if (Input.isMouseButtonUp(MouseButton.RIGHT)) {
80       camera.lockMouseMove();
81       Input.setMode(CursorType.NORMAL);
82     }
83   }
84 
85   private void updateBody() {
86     const float deltaTime = Time.getDelta();
87 
88     if (Input.isKeyHold(KeyCode.A))
89       getTransform().setWorldPositionX!"+="(-moveSpeed * deltaTime);
90 
91     if (Input.isKeyHold(KeyCode.D))
92       getTransform().setWorldPositionX!"+="(moveSpeed * deltaTime);
93     
94     if (Input.isKeyHold(KeyCode.W))
95       getTransform().setWorldPositionZ!"+="(-moveSpeed * deltaTime);
96 
97     if (Input.isKeyHold(KeyCode.S))
98       getTransform().setWorldPositionZ!"+="(moveSpeed * deltaTime);
99 
100     if (Input.isKeyHold(KeyCode.SPACE) && onGround)
101       upSpeed = jumpPower;
102   }
103 
104   private void updatePhysics() {
105     const float deltaTime = Time.getDelta();
106     upSpeed += gravity * deltaTime;
107     getTransform().setWorldPositionY!"+="(upSpeed * deltaTime);
108     const Vector3F worldPos = getTransform().getWorldPosition();
109 
110     const float terrainHeight = tree.getChild!Terrain("DemoTerrain")
111       .getHeight(worldPos.x, worldPos.z);
112 
113     onGround = false;
114     
115     if (worldPos.y < terrainHeight) {
116       onGround = true;
117       upSpeed = 0;
118       getTransform().setWorldPositionY(terrainHeight);
119     }
120   }
121 }