Skip to content
This repository was archived by the owner on Jul 24, 2022. It is now read-only.

Commit 4d7ac94

Browse files
committed
added flags and gained/lost positions mode in the leaderboard
1 parent af75591 commit 4d7ac94

16 files changed

+116
-45
lines changed

README.md

+8-3
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@ Can be tweaked for other championships using the "teams.ini" file.
66

77
During the race a file is saved, that will be read by the app during a race replay to be able to load the whole UI again. However currently **it only saves different files for each combination of track and car**.
88

9-
## STILL A WORK IN PROGRESS!!
10-
11-
129
## teams.ini configuration
1310

1411
Each line contains the following information about each driver in order separated by a colon "`:`"
@@ -32,3 +29,11 @@ QUALIFYING
3229
FASTEST LAP
3330

3431
![im2](/screenshots/screen2.png)
32+
33+
DRIVER TIME GAP COMPARISON (sort of useless)
34+
35+
![im4](/screenshots/screen4.png)
36+
37+
GAINED LOST POSITIONS (click on the information panel to switch between time games and this mode)
38+
39+
![im5](/screenshots/screen5.png)

apps/python/F12020Leaderboard/F12020Leaderboard.py

+60-31
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
from utils import get_image_size, time_to_string
1818
from DriverWidget import DriverWidget
1919
from DriverComparisonWidget import DriverComparisonWidget
20-
from LeaderboardRow import LeaderboardRow
20+
from LeaderboardRow import LeaderboardRow, INFO_TYPE
2121
from FastestLapBanner import FastestLapBanner
2222

2323

@@ -37,8 +37,6 @@
3737
replay_started = False
3838
quali_started = False
3939

40-
leaderboard_displayed = False
41-
4240
qualify_session_time = 0
4341

4442
# REPLAY FILE
@@ -57,6 +55,7 @@
5755
leaderboardBaseLabel = None
5856
leaderboardInfoBackgroundLabel = None
5957
leaderboardBackgroundLabel = None
58+
flagLabel = None
6059

6160
class Driver: # class to hold driver information
6261
def __init__(self, id, n_splits):
@@ -87,6 +86,7 @@ def acMain(ac_version):
8786
# LABELS
8887
global leaderboard
8988
global lapCountTimerLabel, leaderboardBaseLabel, leaderboardInfoBackgroundLabel, leaderboardBackgroundLabel
89+
global flagLabel
9090

9191
totalDrivers = ac.getCarsCount()
9292
n_splits = ac.getTrackLength(0) / FC.TRACK_SECTION_LENGTH
@@ -113,7 +113,7 @@ def acMain(ac_version):
113113
ac.setPosition(leaderboardBackgroundLabel, 0, h)
114114
ac.setSize(leaderboardBackgroundLabel, w, totalDrivers*LeaderboardRow.ROW_HEIGHT + 2)
115115
ac.setBackgroundTexture(leaderboardBackgroundLabel, FC.LEADERBOARD_BACKGROUND);
116-
116+
117117
# ===============================
118118
# Lap Counter / Time
119119
lapCountTimerLabel = ac.addLabel(leaderboardWindow, "")
@@ -123,13 +123,27 @@ def acMain(ac_version):
123123
ac.setFontAlignment(lapCountTimerLabel, "center")
124124
ac.setFontColor(lapCountTimerLabel, 0.86, 0.86, 0.86, 1)
125125

126+
# ===============================
127+
# Flags
128+
flagLabel = ac.addLabel(leaderboardWindow, "")
129+
ac.setPosition(flagLabel, w, 8)
130+
ac.setSize(flagLabel, 110, h-8)
131+
ac.setVisible(flagLabel, 0)
132+
126133
# ===============================
127134
# Info Background
128135
leaderboardInfoBackgroundLabel = ac.addLabel(leaderboardWindow, "")
129136
ac.setPosition(leaderboardInfoBackgroundLabel, w, h)
130137
ac.setSize(leaderboardInfoBackgroundLabel, 110, totalDrivers*LeaderboardRow.ROW_HEIGHT + 2)
131138
ac.setBackgroundTexture(leaderboardInfoBackgroundLabel, FC.LEADERBOARD_INFO_BACKGROUNG)
132139

140+
info_button = ac.addButton(leaderboardWindow, "")
141+
ac.setPosition(info_button, w, h)
142+
ac.setSize(info_button, 110, totalDrivers*LeaderboardRow.ROW_HEIGHT + 2)
143+
ac.addOnClickedListener(info_button, on_click_info)
144+
ac.setBackgroundOpacity(info_button, 0)
145+
ac.drawBorder(info_button, 0)
146+
133147
# ===============================
134148
# Driver Widget
135149
driverWidget = DriverWidget(FC.APP_NAME+" Driver")
@@ -175,6 +189,7 @@ def acUpdate(deltaT):
175189
# LABELS
176190
global leaderboard
177191
global lapCountTimerLabel, leaderboardBaseLabel, leaderboardInfoBackgroundLabel, leaderboardBackgroundLabel
192+
global flagLabel
178193

179194
# ============================
180195
# UPDATE TIMERS
@@ -260,6 +275,20 @@ def acUpdate(deltaT):
260275
fastest_lap_banner.timer -= timer1
261276
fastest_lap_banner.hide()
262277

278+
# ============================
279+
# FLAGS
280+
if info.graphics.flag == 1:
281+
ac.setBackgroundTexture(flagLabel, FC.BLUE_FLAG)
282+
ac.setVisible(flagLabel, 1)
283+
elif info.graphics.flag == 2:
284+
ac.setBackgroundTexture(flagLabel, FC.YELLOW_FLAG)
285+
ac.setVisible(flagLabel, 1)
286+
elif info.graphics.flag == 5:
287+
ac.setBackgroundTexture(flagLabel, FC.CHECKERED_FLAG)
288+
ac.setVisible(flagLabel, 1)
289+
elif info.graphics.flag == 0:
290+
ac.setVisible(flagLabel, 0)
291+
263292
timer1 = 0
264293

265294
# Once per second
@@ -284,17 +313,22 @@ def acUpdate(deltaT):
284313
# ===========================
285314
# CALCULATE TIME DIFERENCES
286315
dPosition = sorted(drivers, key=lambda x: x.position)
287-
for i in range(1, len(dPosition)):
288-
driver_ahead, driver = dPosition[i-1], dPosition[i]
289-
timeDiff = driver.split_times[driver.current_split - 1] - driver_ahead.split_times[driver.current_split - 1]
290-
if timeDiff < 0: continue # ignore these times, happens on overtakes
291-
if driver.position > totalDrivers: continue # might try to update before it is possible
292-
driver.timeDiff = timeDiff
293-
if timeDiff > 60:
294-
leaderboard[driver.position].update_time("+1 MIN")
295-
else:
296-
leaderboard[driver.position].update_time("+" + time_to_string(timeDiff*1000))
297-
leaderboard[0].update_time("Interval") # Force it
316+
if LeaderboardRow.update_type == INFO_TYPE.GAPS:
317+
for i in range(1, len(dPosition)):
318+
driver_ahead, driver = dPosition[i-1], dPosition[i]
319+
timeDiff = driver.split_times[driver.current_split - 1] - driver_ahead.split_times[driver.current_split - 1]
320+
if timeDiff < 0: continue # ignore these times, happens on overtakes
321+
if driver.position > totalDrivers: continue # might try to update before it is possible
322+
driver.timeDiff = timeDiff
323+
if timeDiff > 60:
324+
leaderboard[driver.position].update_time("+1 MIN")
325+
else:
326+
leaderboard[driver.position].update_time("+" + time_to_string(timeDiff*1000))
327+
leaderboard[0].update_time("Interval") # Force it
328+
elif LeaderboardRow.update_type == INFO_TYPE.POSITIONS:
329+
for d in dPosition:
330+
posDiff = d.starting_position - d.position - 1
331+
leaderboard[d.position].update_positions(posDiff)
298332

299333
# ============================
300334
# MARK FASTEST LAP
@@ -561,9 +595,13 @@ def acUpdate(deltaT):
561595
# UPDATE TIMES
562596
if replay_data:
563597
for row in leaderboard:
564-
row.update_time("+" + time_to_string(drivers[row.driverId].timeDiff*1000))
565-
if row.row == 0:
566-
row.update_time("Interval") # Force it
598+
if LeaderboardRow.update_type == INFO_TYPE.GAPS:
599+
row.update_time("+" + time_to_string(drivers[row.driverId].timeDiff*1000))
600+
if row.row == 0:
601+
row.update_time("Interval") # Force it
602+
elif LeaderboardRow.update_type == INFO_TYPE.POSITIONS:
603+
posDiff = drivers[row.driverId].starting_position - drivers[row.driverId].position - 1
604+
row.update_positions(posDiff)
567605

568606
# END UPDATE
569607

@@ -572,18 +610,6 @@ def acShutdown():
572610
if replay_file:
573611
replay_file.close()
574612

575-
def hide_leaderboard():
576-
global leaderboard_displayed
577-
global leaderboard
578-
global lapCountTimerLabel, leaderboardBaseLabel, leaderboardInfoBackgroundLabel, leaderboardBackgroundLabel
579-
if not leaderboard_displayed: return
580-
581-
def show_leaderboard():
582-
global leaderboard_displayed
583-
global leaderboard
584-
global lapCountTimerLabel, leaderboardBaseLabel, leaderboardInfoBackgroundLabel, leaderboardBackgroundLabel
585-
if leaderboard_displayed: return
586-
587613
def write_driver_info(replay_file, laps, time, drivers):
588614
data = "U %d %d " % (laps, time)
589615
for d in drivers:
@@ -676,5 +702,8 @@ def lookup_fastest_lap(lap, time, replay_data):
676702
return replay_data['FL'][lap][it-1]
677703
return None
678704

679-
705+
def on_click_info(*args):
706+
# cycle through types
707+
LeaderboardRow.update_type += 1
708+
LeaderboardRow.update_type %= INFO_TYPE.N_TYPES
680709

apps/python/F12020Leaderboard/LeaderboardRow.py

+45-9
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,22 @@
33

44
from constants import FC
55

6+
class INFO_TYPE:
7+
GAPS = 0
8+
POSITIONS = 1
9+
10+
# amount of types, used to cycle between them
11+
N_TYPES = 2
12+
613
class LeaderboardRow:
714
X_BASE = 5
815
Y_BASE = 84
916
ROW_HEIGHT = 37
1017
FASTEST_LAP_ID = -1
1118
HIGHLIGHT_ID = -1
19+
20+
update_type = INFO_TYPE.GAPS # false for timings, true for positions lost or gained
21+
1222
def __init__(self, leaderboardWindow, row):
1323
# SET SOME VARIABLES
1424
self.row = row
@@ -56,19 +66,24 @@ def __init__(self, leaderboardWindow, row):
5666
ac.setFontColor(self.infoLabel, 0.86, 0.86, 0.86, 1)
5767
ac.setFontAlignment(self.infoLabel, "right")
5868

69+
self.positionChangeLabel = ac.addLabel(leaderboardWindow, "")
70+
ac.setPosition(self.positionChangeLabel, 205, py + 4)
71+
ac.setSize(self.positionChangeLabel, 18, 18)
72+
ac.setVisible(self.positionChangeLabel, 0)
73+
5974
self.fastestLapLabel = ac.addLabel(leaderboardWindow, "")
6075
ac.setPosition(self.fastestLapLabel, px-41, py-6)
6176
ac.setSize(self.fastestLapLabel, 37, 37)
6277
ac.setBackgroundTexture(self.fastestLapLabel, FC.LEADERBOARD_FASTEST_LAP);
6378
ac.setVisible(self.fastestLapLabel, 0)
6479

65-
self.button = ac.addButton(leaderboardWindow, "")
66-
ac.setPosition(self.button, px, py-7)
67-
ac.setSize(self.button, 140, 38)
68-
self.on_click_func = functools.partial(self.on_click, row=self)
69-
ac.addOnClickedListener(self.button, self.on_click_func)
70-
ac.setBackgroundOpacity(self.button, 0)
71-
ac.drawBorder(self.button, 0)
80+
self.focus_button = ac.addButton(leaderboardWindow, "")
81+
ac.setPosition(self.focus_button, px, py-7)
82+
ac.setSize(self.focus_button, 140, 38)
83+
self.on_click_focus_func = functools.partial(self.on_click_focus, row=self)
84+
ac.addOnClickedListener(self.focus_button, self.on_click_focus_func)
85+
ac.setBackgroundOpacity(self.focus_button, 0)
86+
ac.drawBorder(self.focus_button, 0)
7287

7388
def update_name(self, id):
7489
if id == ac.getFocusedCar():
@@ -87,7 +102,21 @@ def update_name(self, id):
87102

88103
def update_time(self, time):
89104
if self.out or self.pit: return # no need to update
90-
ac.setText(self.infoLabel, time)
105+
if self.update_type == INFO_TYPE.GAPS:
106+
ac.setVisible(self.positionChangeLabel, 0)
107+
ac.setText(self.infoLabel, time)
108+
109+
def update_positions(self, pos_diff):
110+
if self.out or self.pit: return # no need to update
111+
if self.update_type == INFO_TYPE.POSITIONS:
112+
ac.setVisible(self.positionChangeLabel, 1)
113+
if pos_diff > 0:
114+
ac.setBackgroundTexture(self.positionChangeLabel, FC.POSITION_GAINED)
115+
elif pos_diff < 0:
116+
ac.setBackgroundTexture(self.positionChangeLabel, FC.POSITION_LOST)
117+
else:
118+
ac.setBackgroundTexture(self.positionChangeLabel, FC.POSITION_MAINTAINED)
119+
ac.setText(self.infoLabel, str(abs(pos_diff)))
91120

92121
def mark_red_position(self):
93122
if self.out or self.positionLabelId == 1: return # no need to update
@@ -107,6 +136,8 @@ def mark_white_position(self):
107136
def mark_in(self):
108137
if not self.out: return
109138
self.out = False
139+
if LeaderboardRow.update_type == INFO_TYPE.POSITIONS:
140+
ac.setVisible(self.positionChangeLabel, 1)
110141
ac.setVisible(self.positionLabel, 1)
111142
ac.setPosition(self.teamLabel, self.px + 47, self.py + 2)
112143
ac.setPosition(self.nameLabel, self.px + 65, self.py+4)
@@ -117,6 +148,7 @@ def mark_out(self):
117148
if self.out: return
118149
self.out = True
119150
ac.setVisible(self.positionLabel, 0)
151+
ac.setVisible(self.positionChangeLabel, 0)
120152
ac.setPosition(self.teamLabel, self.px + 12, self.py + 2)
121153
ac.setPosition(self.nameLabel, self.px + 30, self.py+4)
122154
ac.setFontColor(self.nameLabel, .58,.53,.53, 1)
@@ -126,12 +158,15 @@ def mark_out(self):
126158
def mark_enter_pits(self):
127159
if self.out or self.pit: return
128160
self.pit = True
161+
ac.setVisible(self.positionChangeLabel, 0)
129162
ac.setText(self.infoLabel, "IN PIT")
130163
ac.setFontColor(self.infoLabel, 0,.84,1, 1)
131164

132165
def mark_left_pits(self):
133166
if self.out or not self.pit: return
134167
self.pit = False
168+
if LeaderboardRow.update_type == INFO_TYPE.POSITIONS:
169+
ac.setVisible(self.positionChangeLabel, 1)
135170
if self.driverId == 0:
136171
ac.setText(self.infoLabel, "Interval")
137172
ac.setFontColor(self.infoLabel, 0.86, 0.86, 0.86, 1)
@@ -143,6 +178,7 @@ def mark_fastest_lap(self):
143178
ac.setVisible(self.fastestLapLabel, 0)
144179

145180
@staticmethod
146-
def on_click(*args, row=None):
181+
def on_click_focus(*args, row=None):
147182
if row:
148183
ac.focusCar(row.driverId)
184+

apps/python/F12020Leaderboard/constants.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,12 @@ class FC:
3333

3434
# FLAGS
3535
YELLOW_FLAG = "apps/python/%s/ui/yellow_flag.png" % APP_NAME
36+
BLUE_FLAG = "apps/python/%s/ui/blue_flag.png" % APP_NAME
3637
YELLOW_FLAG_SECTOR1 = "apps/python/%s/ui/yellow_flag_s1.png" % APP_NAME
3738
YELLOW_FLAG_SECTOR2 = "apps/python/%s/ui/yellow_flag_s2.png" % APP_NAME
3839
YELLOW_FLAG_SECTOR3 = "apps/python/%s/ui/yellow_flag_s3.png" % APP_NAME
39-
GREEN_FLAG = "apps/python/%s/ui/green_flag.png" % APP_NAME
40-
RACE_FLAG = "apps/python/%s/ui/race_flag.png" % APP_NAME
40+
# GREEN_FLAG = "apps/python/%s/ui/green_flag.png" % APP_NAME
41+
CHECKERED_FLAG = "apps/python/%s/ui/race_flag.png" % APP_NAME
4142

4243
# POSITION CHANGED INDICATOR
4344
POSITION_GAINED = "apps/python/%s/ui/position_gained.png" % APP_NAME
15.8 KB
Loading
-1.05 KB
Binary file not shown.
Loading
23.7 KB
Loading
-2.87 KB
Binary file not shown.
Binary file not shown.
13.9 KB
Loading
Loading
Loading
Loading

screenshots/screen4.png

1.9 MB
Loading

screenshots/screen5.png

368 KB
Loading

0 commit comments

Comments
 (0)