Python을 기반으로 개발을 진행하였습니다.
1. TELEMETRY 정보 불러오기
get_img 함수를 실행하면 이름을 입력하라고 합니다. 그때 user_name(닉네임)을 입력하면 해당 유저의 이동경로를 판별로 확인할 수 있습니다.
def get_img(username, api_key, header):
url = f'https://api.pubg.com/shards/kakao/players?filter[playerNames]={username}'
response = requests.get(url, headers=header)
json_data = response.json()
player_match_ids_df = pd.DataFrame(json_data['data'][0]['relationships']['matches']['data'])
url_list = []
positions = []
for index in range(len(player_match_ids_df)):
match_url = f'https://api.pubg.com/shards/kakao/matches/{player_match_ids_df["id"][index]}'
match_response = requests.get(match_url, headers=header)
match = match_response.json()
for item in range(len(match['included'])):
if match['included'][item]['type'] == "asset":
url_list.append(match['included'][item]['attributes']['URL'])
이동경로 정보를 추출하기 위해서는 TELEMETRY API의 정보를 가져오는 방법은 다음과 같습니다.
1. PLAYERS API DAT를 통해 matche_ids 정보를 가져옵니다.
2. 불러온 matche_ids 정보를 통해 MATCHES API DATA를 가져옵니다.
3. MATCHES API DATA에서 TELEMETRY의 URL 정보를 추출합니다.
4. URL을 통해 TELEMETRY API DATA를 가져옵니다.
이때 player당 하나의 경기만 있는 것이 아니기 때문에 반복작업을 생각하여 모든 url을 url_list에 넣어줍니다.
match 하나 당 하나의 TELEMETRY URL 정보를 가지기 때문에 url_list의 길이는 경기 수와 동일합니다.
2. TELEMETRY에서 맵이름, 위치 정보 가져오기
for index in range(len(url_list)):#range(3):
sub_positions = []
response = requests.get(url_list[index])
telemetry_json = response.json()
map_image_path = "C:/Users/Admin/Desktop/pubg_maps/"
for event in telemetry_json:
if event["_T"] == "LogMatchStart":
map_name = event["mapName"]
map_dict = {
"Baltic_Main": "Erangel_Main_High_Res.png",
"Erangel_Main": "Erangel_Main_High_Res.png",
"Chimera_Main": "Paramo_Main_High_Res.png",
"DihorOtok_Main": "Vikendi_Main_High_Res.png",
"Heaven_Main": "Haven_Main_High_Res.png",
"Kiki_Main": "Deston_Main_High_Res.png",
"Range_Main": "Camp_Jackal_Main_High_Res.png",
"Savage_Main": "Sanhok_Main_High_Res.png",
"Summerland_Main": "Karakin_Main_High_Res.png",
"Tiger_Main": "Taego_Main_High_Res.png"
}
plt_map_name = map_dict.get(map_name).split("_")[0]
map_image_path += map_dict.get(map_name, map_name)
if event["_T"] in ("LogPlayerPosition", "LogParachuteLanding"):
if event["character"]["name"] == username:
sub_positions.append({
"player_name": event["character"]["name"],
"location_x": event["character"]["location"]["x"],
"location_y": event["character"]["location"]["y"],
})
positions.append(sub_positions)
TELEMETRY의 mapName은 우리가 기존에 알고 있는 mapName과 다르기 때문에 공식 github에서 게시한 정보를 참고합니다.
mapName 키값일때 value 값으로 바꿔서 map_image_path에 추가로 넣습니다.
이는 플레이한 맵에 따라 맵 이미지를 달리 출력하기 위한 방법으로 실제로 다른 경기를 매판 달리했다면 해당 맵의 이미지가 나타납니다.
plt_map_name에는 맵의 이름을 제목으로 출력하기 위해 첫 번째 _ 뒤의 문자열을 모두 제거하여 저장하게 하였습니다.
그리고 높이 정보(z)를 제외한 x, y좌표를 빈 리스트 positions에 저장하게 하였습니다.
3. 이동경로 그리기 및 출력
scale_factor = 0.01
for position in positions:
map_image = cv2.imread(map_image_path)
for index in range(len(position) - 1):
x = int(position[index]["location_x"] * scale_factor)
y = int(position[index]["location_y"] * scale_factor)
x1 = int(position[index + 1]["location_x"] * scale_factor)
y1 = int(position[index + 1]["location_y"] * scale_factor)
cv2.line(map_image, (x, y), (x1, y1), (255, 0, 0), 50)
plt.figure(figsize=(8, 8))
plt.title(plt_map_name)
plt.imshow(cv2.cvtColor(map_image, cv2.COLOR_BGR2RGB))
plt.show()
if __name__ == "__main__":
username = input("user name를 입력하세요: ")
api_key = "your_api_kei"
header = {
"Authorization": api_key,
"Accept": "application/vnd.api+json"
}
get_img(username, api_key, header)
scale_factor은 이미지 크기 와를 저장된 x, y좌표와의 사이즈를 맞추기 위해 설정한 값입니다.
게임이 불러와졌을 때 좌표를 통해 조금씩 그림을 그려나가고 다 그렸다면 한판에 해당하는 이미지를 출력하는 형식입니다.
이는 150판의 게임을 진행했다면 150개의 이동 경로를 그린 맵 이미지가 나타나게 됩니다.
4. 코드 실행하기
이미지를 보게 되면 일직선으로 반듯하게 그려진 부분은 게임 시작 시 비행기에서 내리기 전까지 비행기에 탑승한 경로로 보입니다.
위의 이미지들은 경기에서 검색한 유저의 이동경로를 출력했습니다.
5. 이슈
1. 새로운 맵이 추가 될때 마다 맵 이미지와 이름을 각각 폴더와 코드에 추가 해야합니다.
6. 추가 개발 사항
추가적으로 해볼 수 있는것으로는 다음과 같겠습니다.
1. top10안에 드는 팀원 들의 이동경로를 출력하는 방법
2. 죽은 위치 표시
3. 비행기 길 표시
4. 낙하 까지 위치 표시
5. 자기장의 위치, 레드존의 위치
6. DB에 data를 담기
'게임 데이터 분석' 카테고리의 다른 글
[게임 데이터 분석 #6] Mysql 설치, 연동 및 DB에서 데이터 가져오기 (0) | 2023.07.01 |
---|---|
[게임 데이터 분석 #5] MongoDB를 사용한 데이터 저장 (1) | 2023.06.30 |
[게임 데이터 분석 #4] TELEMETRY API를 활용해 MAP 이미지 위에 이동 경로 그리기 (0) | 2023.06.19 |
[게임 데이터 분석 #3] chicken-dinner를 활용한 리플레이 애니메이션 출력하기 (0) | 2023.06.14 |
[게임 데이터 분석 #2] PUBG API를 활용한 판별, 팀별 통계 (0) | 2023.06.11 |