3. lol 미니맵 애니메이션 만들기

chaechae·2023년 5월 23일
0
post-thumbnail

저번 글에 이어서 유저의 이동경로를 파이썬 image plot 과 Functionanimation 을 이용해서 표현 해보겠습니다.

들어가기 전

위 기능을 통해 유저가 죽은위치, 머무른 위치가 어디인지 미니맵을 통해 대략적으로 확인 할 수 있습니다.
사실 여러 상황과 이유가 있겠지만, 유저가 본인의 라인에 서지 않고 팀원들의 라인을 방해하는 경우가 족족 있는데, 영상을 다시보기는 귀찮고 1분마다 찍히는 좌표와 죽었을 때 남는 좌표데이터들로 간단하게 만들어 보면 어떨까 해서 재미로 만들어봤습니다ㅎㅎ.

하지만 아무래도 좌표 데이터만 갖고는 해당 유저가 방해를 했는지 안했는지 섣불리 판단하기는 어렵습니다. 그래도 탈주나/자리비움 한 경우에는 비교적 명확하게 확인이 가능한것 같아 대시보드에 추가했습니다.

처음에는 모든 참가자들이 남긴 position 데이터들을 가져와서 좌표가 남은 모든 이벤트들을 표현 하려고 했는데.. 아무래도 image plot에 frame을 계속 추가하다보니 용량이 많이 들어가고, 파이썬으로 하기 너무 비효율적이고(어렵다..) 또 굳이 그렇게 까지 할 필요가 있나 생각했습니다. 그래서 신고를 받은 유저를 기준으로만 하도록 했습니다!

다시말해 이번에 표현하고자 하는 것은 1분마다 남는 모든 참가자들의 position 데이터와 유저가 죽은 위치를 timestamp순으로 나타내는 것입니다!

RIOT api 에서 position 데이터가 남는 경우


frame_df = pd.DataFrame(first_match_data_log['info']['frames'])
events_df = pd.DataFrame(frame_df['events'])
events = events_df['events'].tolist()

events_all_participant_ids = []

for event in events:
    for event_dict in event:
        events_all_participant_ids.append(event_dict)

all_events = pd.DataFrame(events_all_participant_ids)


position_ok = all_events[all_events['position'].notnull()] # 좌표가 있는 데이터만 
print(position_ok["type"].unique()) # position 이 남는 type

여러번 데이터를 불러보고 , events 값들 중 position이 남는 TYPE 의 경우만 뽑아보면 다음과 같습니다.

기본적으로 1분마다 찍히는 position +
['CHAMPION_KILL' 'CHAMPION_SPECIAL_KILL' 'TURRET_PLATE_DESTROYED'
'ELITE_MONSTER_KILL' 'BUILDING_KILL']
일 때 입니다.

한마디로 챔피언/타워/엘리트 몬스터(바론,드래곤)를 킬했을 경우 좌표가 남습니다.

여기서 주의할점은 데이터를 보시면 'TYPE' 이 KILL 과 관련된 데이터들은 'participantId' 로 남는게 아니라 'killId' 와 'victimId'에 참가자들의 번호가 남습니다.(그렇기 때문에 참가자 각각의 participantId 를 따로 정리해두는게 편합니다!)

1번 유저가 6번유저를 kill 했다는 내용이네요.
제가 필요한건 해당유저의 participantId인 1번 데이터, 그 중에서도 해당 유저가 죽은 경우 이기 때문에

victimId == summoner_participantId # 1인경우의 데이터만 가져오도록 하겠습니다

df = position_ok[position_ok['victimId'] == summoner_participantId] # 죽은 위치/시간
death = df[['victimId','position','timestamp']] # 필요한 컬럼만

death['death'] = 1 # 죽은경우 1 표시 왜냐하면 image plot 만들 때 죽은경우 다르게 표현하기 위함입니다.
death.rename(columns={'victimId':'participantId'}, inplace=True) # 컬럼명을 바꿔줍니다. 저번에 불러온 1분간격으로 남는 position 데이터와 합쳐주기위해서
death = death.sort_values(by='participantId',ascending=True)
death['participantId'] = death['participantId'].astype(int)

그리고 death 컬럼을 추가해서 죽은 데이터의 경우 '1' 값을 표시해주고
저번에 불러온 moving 데이터 (1분간격으로 기록된 position) 와 컬럼이름을 일치하게 만든 뒤 합쳐주면 아래와 같이

1분간격 position + 유저가 죽은 position 의 데이터가 완성됩니다.

미니맵 애니메이션

이제 위 데이터와 , champion_info (각 participantId 별 챔피언 이름이 정리된데이터)를 만들어 놓고 img를 불러들여와서 timestamp 별로 각 position을 update 해서 나타내면 됩니다.
Alpha 값을 조절해서 다른 유저들의 챔피언은 희미하게 나타냈고 death 가 1인 경우 채도를 낮춰서 죽었다는 걸 표현했습니다.

챔피언 이미지는 ddragon champion url 을 이용해서 불러오고 미니맵 사진은 따로 구했습니다!

~~# 전체코드 수정~~

ani.save('Animation.gif', writer='imagemagick', fps=5, dpi=100) gif로 변환해서 가져왔습니다. 실제로는 버튼을 클릭해서 한 프레임씩 조절하실 수 있습니다.

허허.. TOP 에서 2데스하고 우물잠수한 그레이브즈가 보이는군요.
(지금 보니 RED 팀 BLUE 팀 구분했으면 더 좋았겠다는 생각이 드네요)

아래는 functionanimate 를 쓰는데 참고한 자료입니다.

profile
게임 혹은 다양한 컨텐츠가 있는 곳을 좋아합니다. 시리즈를 참고하시면 편하게 글을 보실 수 있습니다🫠

0개의 댓글