Skip to content

Commit

Permalink
Added a README file.
Browse files Browse the repository at this point in the history
Added the network client samples.
Added an empty structure for the bin\ folder and subfolders.
Reorganized the position of the bin\ folder.
  • Loading branch information
astrofra committed Dec 19, 2021
1 parent 6f4e588 commit 54ec2aa
Show file tree
Hide file tree
Showing 29 changed files with 1,052 additions and 5 deletions.
60 changes: 60 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Dogfight 2 (Air to air combat Sandbox)

Air to air combat sandbox, created in Python 3 using the [HARFANG 3D 2 framework](https://www.harfang3d.com).

The game features :
* Ocean / terrain shader
* Skydome shader
* Clouds
* AI (Take-off, landing, fight)
* Network mode

The source code and the graphics assets are made available for studying purpose. However, you are free to fork this repository, extend the game or release anything that is based on it.

## How to run Dogfight
1. Clone/download this repository
1. run *start_game.bat*

## Network mode overview

The "Network" mode allows you to control the planes from a third party machine.
### Startup:
1. On the server machine:
* Start the DogFight SandBox (start.bat file)
* Choose the **Network mode** mission
![ServerID](screenshots/network_mode.png)
* Note the IP and port number of the server, in the upper left corner of the screen
![ServerID](screenshots/server_ids.png)

1. On the client machine:
* Make sure you have a version of python 3 installed
* Copy the content of the directory `network_client_example`.
* Open the file `client_sample.py` with a text editor.
* Enter the server ids in the "df.connect ()" function.
![ServerID](screenshots/server_ids_client.png)

* Start the file `client_sample.py`

## Contributors
* Code & design:
* Eric Kernin
* 3D graphics:
* Jean-Marie Lamarche &
* Bruno Lequitte
* Technology & design advisory:
* Michel Nault
* Thomas Simonnet

## Screenshots

![screenshot](screenshots/screenshot_4.png)

![screenshot](screenshots/screenshot_0.png)

![screenshot](screenshots/screenshot_1.png)

![screenshot](screenshots/screenshot_2.png)

![screenshot](screenshots/screenshot_5.png)

![screenshot](screenshots/screenshot_3.png)
9 changes: 9 additions & 0 deletions bin/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Run the Dogfight in standalone mode

The `bin\` includes several external modules allowing the Dogfight Sandbox to run as a standalone application (on Windows especially).

The `bin\`folder includes several other folders:
* `assetc\`, the [HARFANG asset compiler](https://www.harfang3d.com/releases).
* `harfang\`, the [HARFANG engine](https://www.harfang3d.com/releases) (unpacked wheel).
* `python\`, Python (3.8, 3.9, 3.10) [Windows embeddable package](https://www.python.org/downloads/release/python-383/).
* `tqdm\`, a [progress bar](https://pypi.org/project/tqdm/#files) Python module (unpacked wheel).
12 changes: 12 additions & 0 deletions bin/assetc/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Run the Dogfight in standalone mode

## Content of bin\assetc

```
toolchains\
assetc.exe
glfw3.dll
harfang.dll
lua.exe
lua53.dll
```
11 changes: 11 additions & 0 deletions bin/harfang/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Run the Dogfight in standalone mode

## Content of bin\harfang

```
glfw3.dll
harfang.pyd
lua53.dll
openvr_api.dll
__init__.py
```
19 changes: 19 additions & 0 deletions bin/python/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Run the Dogfight in standalone mode

## Content of bin\python

Copy here the content of an embeddable Python package, directly into this folder. It should include a
`pythonXX._pth` file to list the following search paths (the exact content may vary according to the Python version):

```
python38.zip
.
..\
..\..\
..\harfang\
..\tqdm\
..\..\source\
# Uncomment to run site.main() automatically
#import site
```
10 changes: 10 additions & 0 deletions bin/python/python38._pth
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
python38.zip
.
..\
..\..\
..\harfang\
..\tqdm\
..\..\source\

# Uncomment to run site.main() automatically
#import site
5 changes: 5 additions & 0 deletions bin/tqdm/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Run the Dogfight in standalone mode

## Content of bin\tqdm

Copy here the content of an the `tqdm` wheel.
90 changes: 90 additions & 0 deletions documentation_network.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# Dogfight Sandbox - Network documentation

## Network API

The "Network" mode allows you to control the planes from a third party machine or program.

### Globals functions

* **disable_log**()
* **enable_log**()
* dict = **get_running**()
* **set_renderless_mode**(bool flag)
* **set_display_radar_in_renderless_mode**(bool flag)
* **set_timestep**(float timestep)
* dict = **get_timestep**()
* **set_client_update_mode**(bool flag)
* **update_scene**()
* **display_vector**(list position[3], list direction[3], string label, list label_offset2D[2], list color[4], float label_size)
* **display_2DText**(list position[3], string text, float size, list color[4])

### Common Machines functions

* list = **get_machine_missiles_liste**(string machine_id)
* list = **get_targets_list**(string machine_id)
* dict = **get_health**(string machine_id)
* **set_health**(string machine_id, float health_level)
* **activate_autopilot**(string machine_id)
* **deactivate_autopilot**(string machine_id)
* **activate_IA**(string machine_id)
* **deactivate_IA**(string machine_id)
* dict = **get_machine_gun_state**(string machine_id)
* **activate_machine_gun**(string machine_id)
* **deactivate_machine_gun**(string machine_id)
* dict = **get_missiles_device_slots_state**(string machine_id)
* **fire_missile**(string machine_id, int slot_id)
* **rearm_machine**(string machine_id)
* dict = **get_target_idx**(string machine_id)
* **set_target_id**(string machine_id, string target_id)
* **reset_machine_matrix**(string machine_id, float x, float y, float z, float rx, float ry, float rz)
* **set_machine_custom_physics_mode**(string machine_id, bool flag)
* dict = **get_machine_custom_physics_mode**(string machine_id)
* **update_machine_kinetics**(string machine_id, list matrix_3_4[12], list speed_vector[3])
* list = **get_mobile_parts_list**(string machine_id)
* list = **is_autopilot_activated**(string machine_id)
* **activate_autopilot**(string machine_id)
* **deactivate_autopilot**(string machine_id)
* list = **is_ia_activated**(string machine_id)
* **activate_IA**(string machine_id)
* **deactivate_IA**(string machine_id)
* list = **is_user_control_activated**(string machine_id)
* **activate_user_control**(string machine_id)
* **deactivate_user_control**(string machine_id)

### Aircrafts functions

* list = **get_planes_list**()
* dict = **get_plane_state(string plane_id)
* **set_plane_thrust**(string plane_id)
* dict = **get_plane_thrust**(string plane_id)
* **activate_pc**(string plane_id)
* **deactivate_pc**(string plane_id)
* **set_plane_brake**(string plane_id, float level)
* **set_plane_flaps**(string plane_id, float level)
* **set_plane_pitch**(string plane_id, float level)
* **set_plane_roll**(string plane_id, float level)
* **set_plane_yaw**(string plane_id, float level)
* **stabilize_plane**(string plane_id)
* **deploy_gear**(string plane_id)
* **retract_gear**(string plane_id)
* **set_plane_autopilot_speed**(string plane_id, float level)
* **set_plane_autopilot_heading**(string plane_id, float level)
* **set_plane_autopilot_altitude**(string plane_id, float level)
* **activate_plane_easy_steering**(string plane_id)
* **deactivate_plane_easy_steering**(string plane_id)
* **set_plane_linear_speed**(string plane_id, float speed)
* **reset_gear**(string plane_id)
* **record_plane_start_state**(string plane_id)

### Missiles functions

* list = **get_missiles_list**()
* dict = **get_missile_state**()
* **set_missile_life_delay**(string missile_id, float_life_delay)
* list = **get_missile_targets_list**(string missile_id)
* **set_missile_target**(string missile_id, string target_id)

### Missile launchers functions

* list = **get_missile_launchers_list**()
* dict = **get_missile_launcher_state**(string machine_id)
19 changes: 19 additions & 0 deletions network_client_example/client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from aero_model import derivatives
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt

alpha = 5
beta = 0
deltaE = 0
deltaA = 0
deltaR = 0

cx, cxQ, cy, cyP, cyR, cz, czQ, cl, clP, clR, clDeltaA, clDeltaR, cm, cmQ, cn, cnP, cnR, cnDeltaA, cnDeltaR = derivatives(alpha, beta, deltaE, deltaA, deltaR)


alpha_range = np.linspace(-10, 45, 275)
cx_range = [derivatives(alpha, beta, deltaE, deltaA, deltaR)[12] for alpha in alpha_range]

sns.lineplot(x=alpha_range, y=cx_range)
plt.show()
143 changes: 143 additions & 0 deletions network_client_example/client_sample.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@

# Dogfight Sandbox client example
# This script show how to use the network mode to controls aircrafts.
# Before starts this script, Dogfight Sandbox must be running in "Network mode"
3
# dogfight_client.py is the library needed to communicate with DogFight sandbox

import dogfight_client as df
import time

# Print fps function, to check the network client frequency.

t = 0
t0 = 0
t1 = 0

def print_fps():
global t, t0, t1
t1 = time.time()
dt = t1 - t0
t0 = t1
if dt > 0:
print(str(1 / dt))

# Enter the IP and port displayed in top-left corner of DogFight screen
df.connect("192.168.1.19", 50888)

time.sleep(2)

# Get the whole planes list in DogFight scene
# returns a list that contains planes id
planes = df.get_planes_list()
print(str(planes))

df.disable_log()

# Get the id of the plane you want to control
plane_id = planes[0]

# Reset the plane at its start state
df.reset_machine(plane_id)

# Set plane thrust level (0 to 1)
df.set_plane_thrust(plane_id, 1)

# Set client update mode ON: the scene update must be done by client network, calling "update_scene()"
df.set_client_update_mode(True)

# Wait until plane thrust = 1

while t < 1:
plane_state = df.get_plane_state(plane_id)
# Display text & vector - !!! Must be called before update_scene() !!!
# !!! Display text & vector only works in Client Update Mode !!!
df.display_2DText([0.25, 0.75], "Plane speed: " + str(plane_state["linear_speed"]), 0.04, [1, 0.5, 0, 1])
df.display_vector(plane_state["position"], plane_state["move_vector"], "Linear speed: " + str(plane_state["linear_speed"]), [0, 0.02], [0, 1, 0, 1], 0.02)
# Update frame:
df.update_scene()
print_fps()
t = plane_state["thrust_level"]


# Activate the post-combustion (increases thrust power)
df.activate_post_combustion(plane_id)

# Set broomstick pitch level (<0 : aircraft pitch up, >0 : aircraft pitch down)
df.set_plane_pitch(plane_id, -0.5)

# Wait until plane pitch attitude >= 15
p = 0
while p < 15:
# Timer to 1/20 s.
# As Client update mode is ON, the renderer runs to 20 FPS until pitch >= 15°
time.sleep(1/20)
plane_state = df.get_plane_state(plane_id)
df.display_2DText([0.25, 0.75], "Plane speed: " + str(plane_state["linear_speed"]), 0.04, [1, 0.5, 0, 1])
df.display_vector(plane_state["position"], plane_state["move_vector"], "Linear speed: " + str(plane_state["linear_speed"]), [0, 0.02], [0, 1, 0, 1], 0.02)
df.update_scene()
p = plane_state["pitch_attitude"]

# Reset broomstick to 0
df.stabilize_plane(plane_id)

# Retract landing gear
df.retract_gear(plane_id)

# Wait until linear speed >= 500 km/h
s = 0
while s < 500 / 3.6: # Linear speed is given in m/s. To translate in km/h, just divide it by 3.6
plane_state = df.get_plane_state(plane_id)
df.display_2DText([0.25, 0.75], "Plane speed: " + str(plane_state["linear_speed"]), 0.04, [1, 0.5, 0, 1])
df.display_vector(plane_state["position"], plane_state["move_vector"], "Linear speed: " + str(plane_state["linear_speed"]), [0, 0.02], [0, 1, 0, 1], 0.02)
df.update_scene()
s = plane_state["linear_speed"]

# When speed is around 500 km/h, post-combustion booster is turned off
df.deactivate_post_combustion(plane_id)

# Set Renderless mode ON
df.set_renderless_mode(True)

# Wait while Renderless mode setting up:
f = False
while not f:
f = df.get_running()["running"]

print("RenderLess running")

# Wait until plane altitude >= 5000 m
a = 0

while a < 5000:
print_fps()
df.display_2DText([0.25, 0.75], "Plane speed: " + str(plane_state["linear_speed"]), 0.04, [1, 0.5, 0, 1])
df.update_scene()
plane_state = df.get_plane_state(plane_id)
a = plane_state["altitude"]

# When cruising speed & altitude are OK, setups and starts the autopilot
df.set_plane_autopilot_altitude(plane_id, 200)
df.set_plane_autopilot_heading(plane_id, 360-90)
df.set_plane_autopilot_speed(plane_id, 500 / 3.6)
df.activate_autopilot(plane_id)

# Renderless mode OFF
df.set_renderless_mode(False)


df.set_machine_custom_physics_mode(plane_id, False)

# Wait while Renderless mode setting up
f = False
while not f:
f = df.get_running()["running"]

# Client update mode OFF
df.set_client_update_mode(False)

# Disconnect from the Dogfight server

df.disconnect()


Loading

0 comments on commit 54ec2aa

Please sign in to comment.