What I am trying to do is collect Keyboard and mouse input data while I play a first person shooter game. I can record this data with SerpentAI and save it to a file.
I then want to draw my trajectory as I move through the map in the game. So my inputs are the 'w', 'a', 's' and 'd' keys on the keyboard with 'w' representing one movement forward, 's' representing one movement backward, 'a' one movement to the left and 'd' one movement to the right.
My Issue is that I also have mouse inputs that change the direction of what 'forward' is. For example: I press 'w' to move in a straight line in the game, then move my mouse a certain distance to make a 90 degree turn and then press the 'w' again. I am still moving forward but in a new direction. This will happen many times in my data and I do not know how to plot it.
To make things simpler I created a dummy dataset with a few inputs that should result in the drawing of a square:
Keyboard | MouseTurnAngle | TimeStamp |
---|---|---|
w | 1657161124 | |
w | 1657161125 | |
w | 1657161126 | |
90 | 1657161127 | |
w | 1657161128 | |
w | 1657161129 | |
w | 1657161130 | |
90 | 1657161131 | |
w | 1657161132 | |
w | 1657161133 | |
w | 1657161134 | |
90 | 1657161135 | |
w | 1657161136 | |
w | 1657161137 | |
w | 1657161138 |
So far I have used pandas to create coordinates for each timestamp and then matplotlib to draw a scatterplot of the coordinates but the coordinates I have been generating are incorrect and my python geometric visualization knowledge is not up to par on this task. I do not have a way to generate the correct coordinates.
I have been experimenting with the shapely library, specifically shapely.affinity.rotate to help get the correct coordinates but no luck so far.
Since your timestamps are equidistant and your keyboard and mouse inputs are mutually exclusive, you could simplify this task to an interpretation of a list of actions:
import numpy as np
from matplotlib import pyplot as plt
actions = ["w", "a", "s", "d", 90, "w", "a", "a", -180, "s", "d", "w", 90, "w", "w", "a", "a", "a"]
delta_times = [1,2,5,3,5,1,1, 2, 3, 2, 2, 1, 1, 1, 4, 2, 1, 1]
# initial direction and position
direction = np.array((0,1)) # moving in +y
position = np.array((0,0))
# change relative direction
movement_translator = {
"w": lambda pos, direction: pos + direction,
"s": lambda pos, direction: pos - direction,
"a": lambda pos, direction: pos - np.flip(direction),
"d": lambda pos, direction: pos + np.flip(direction),
}
# change direction
def rotatation_matrix(deg):
theta = np.deg2rad(deg)
return np.array([[np.cos(theta), -np.sin(theta)], [np.sin(theta), np.cos(theta)]])
# show live movement
def plot_movement(x_pos, y_pos, position, direction):
plt.cla()
plt.plot(x_pos, y_pos, '.-')
plt.plot(x_pos[-1], y_pos[-1], 'xr') # show current position as red x
plt.show(block=False)
plt.title(f"Position: {np.round(position)}, Direction: {np.round(direction)}")
plt.pause(1)
# initialize position lists
x_pos = [position[0]]
y_pos = [position[1]]
for action, delta_time in zip(actions, delta_times):
try: # to apply movement, i.e. w,a,s,d
for _ in range(delta_time):
# keep moving in same direction
position = movement_translator[action](position, direction)
x_pos.append(position[0])
y_pos.append(position[1])
plot_movement(x_pos, y_pos, position, direction)
except KeyError: # it is not a movement, so apply rotation instead
direction = np.dot(rotatation_matrix(action), direction)
for _ in range(delta_time):
plt.pause(1) # just wait
plt.show()