Advertisement
Faschz

DKR - Velocity Simulator

May 17th, 2020 (edited)
1,392
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.79 KB | None | 0 0
  1. from enum import IntEnum
  2.  
  3. import pyqtgraph as pg
  4.  
  5. class Character(IntEnum):
  6.     KRUNCH = 0,
  7.     DIDDY = 1,
  8.     BUMPER = 2,
  9.     BANJO = 3,
  10.     CONKER = 4,
  11.     TIPTUP = 5,
  12.     PIPSY = 6,
  13.     TIMBER = 7,
  14.     DRUMSTICK = 8,
  15.     TICKTOCK = 9
  16.  
  17. class Kart:
  18.     def __init__(self, character: Character):
  19.         self.character = character
  20.         self.velocity = 0.0
  21.         self.throttle = 0.0
  22.         self.brake = 0.0
  23.         self.boost_timer = 30
  24.  
  25.     def update(self, framerate: int, is_holding_a: bool, is_holding_b: bool, is_using_boost: bool) -> None:
  26.         """Update the kart's properties for a single frame"""
  27.  
  28.         self.update_throttle(is_holding_a)
  29.         self.update_brake(is_holding_b)
  30.         self.update_boost(framerate, is_using_boost)
  31.         self.update_velocity(is_holding_a)
  32.  
  33.     def update_throttle(self, is_holding_a: bool) -> None:
  34.         """Update the kart's throttle"""
  35.  
  36.         if self.throttle > 0.0:
  37.             self.throttle -= 0.1
  38.  
  39.         if is_holding_a:
  40.             self.throttle = 1.0
  41.  
  42.     def update_brake(self, is_holding_b: bool) -> None:
  43.         """Update the kart's brakes"""
  44.  
  45.         if is_holding_b:
  46.             if self.brake < 1.0:
  47.                 self.brake += 0.2
  48.         else:
  49.             if self.brake > 0.05:
  50.                 self.brake -= 0.1
  51.  
  52.     def update_boost(self, framerate: int, is_using_boost: bool) -> None:
  53.         """Update the kart's boost timer"""
  54.  
  55.         self.boost_timer -= framerate
  56.  
  57.         if self.boost_timer < 0:
  58.             self.boost_timer = 0
  59.  
  60.         if is_using_boost:
  61.             self.boost_timer = 0
  62.             self.throttle = 1.0
  63.  
  64.     def update_velocity(self, is_holding_a: bool) -> None:
  65.         """Update the kart's velocity"""
  66.  
  67.         self.velocity -= self.calculate_drag_from_traction(is_holding_a)
  68.  
  69.         acceleration = self.calculate_interpolated_stats()
  70.  
  71.         self.velocity += self.calculate_thrust(acceleration)
  72.         self.velocity -= self.calculate_drag_from_brake(acceleration)
  73.  
  74.         if self.velocity < 0.0:
  75.             self.velocity = 0.0
  76.  
  77.     def calculate_drag_from_traction(self, is_holding_a: bool) -> float:
  78.         """Return the drag calculated from traction"""
  79.  
  80.         if is_holding_a:
  81.             return 1.0 * 0.004 * self.velocity * self.velocity
  82.  
  83.         return 8.0 * 0.004 * self.velocity
  84.  
  85.     def calculate_drag_from_brake(self, acceleration: float) -> float:
  86.         """Return the drag calculated from braking"""
  87.  
  88.         return 0.32 * 1.7 * self.brake * acceleration
  89.  
  90.     def calculate_thrust(self, acceleration: float) -> float:
  91.         """Return the thrust calculated from throttle"""
  92.  
  93.         if self.boost_timer > 0:
  94.             return 2.0
  95.  
  96.         return 1.7 * self.throttle * acceleration
  97.  
  98.     def calculate_interpolated_stats(self) -> float:
  99.         """Calculate the acceleration based on the character's stats"""
  100.  
  101.         character_acceleration = [
  102.             [0.10, 0.10, 0.15, 0.12, 0.13, 0.14, 0.15, 0.18, 0.20, 0.26, 0.31, 0.37, 0.39, 0.39], # Krunch
  103.             [0.10, 0.12, 0.15, 0.17, 0.19, 0.21, 0.25, 0.28, 0.29, 0.30, 0.32, 0.34, 0.34, 0.34], # Diddy
  104.             [0.10, 0.12, 0.14, 0.16, 0.18, 0.20, 0.24, 0.28, 0.29, 0.30, 0.32, 0.34, 0.35, 0.35], # Bumper
  105.             [0.10, 0.12, 0.13, 0.15, 0.17, 0.19, 0.21, 0.23, 0.29, 0.30, 0.32, 0.34, 0.36, 0.36], # Banjo
  106.             [0.10, 0.12, 0.14, 0.16, 0.18, 0.20, 0.24, 0.28, 0.29, 0.30, 0.32, 0.34, 0.35, 0.35], # Conker
  107.             [0.10, 0.15, 0.20, 0.21, 0.24, 0.26, 0.28, 0.29, 0.30, 0.31, 0.32, 0.32, 0.34, 0.34], # Tiptup
  108.             [0.10, 0.20, 0.22, 0.25, 0.26, 0.27, 0.28, 0.29, 0.29, 0.30, 0.30, 0.31, 0.34, 0.34], # Pipsy
  109.             [0.10, 0.12, 0.15, 0.17, 0.19, 0.21, 0.25, 0.28, 0.29, 0.30, 0.32, 0.34, 0.35, 0.35], # Timber
  110.             [0.10, 0.12, 0.14, 0.16, 0.17, 0.19, 0.21, 0.24, 0.26, 0.29, 0.31, 0.33, 0.41, 0.41], # Drumstick
  111.             [0.10, 0.20, 0.22, 0.25, 0.26, 0.27, 0.28, 0.29, 0.30, 0.32, 0.35, 0.38, 0.43, 0.43]  # Ticktock
  112.         ]
  113.  
  114.         idx = int(self.velocity)
  115.         remainder = self.velocity - idx
  116.  
  117.         if idx > 12:
  118.             idx = 12
  119.  
  120.         lower_acceleration = character_acceleration[self.character][idx]
  121.         upper_acceleration = character_acceleration[self.character][idx + 1]
  122.  
  123.         #TODO: Add bananas + drifting
  124.  
  125.         return lower_acceleration * (1.0 - remainder) + upper_acceleration * remainder
  126.  
  127. def main():
  128.     # Constants for the simulation
  129.     FRAMERATE = 2 # 30 FPS (60 / 30 = 2)
  130.     IS_HOLDING_A = True
  131.     IS_HOLDING_B = False
  132.     IS_USING_BOOST = False
  133.  
  134.     velocity_widget = pg.plot(title="DKR Velocity vs Time")
  135.     velocity_widget.addLegend()
  136.     velocity_widget.setLabel("left", "Velocity")
  137.     velocity_widget.setLabel("bottom", "Vertical Interrupts")
  138.  
  139.     distance_widget = pg.plot(title="DKR Distance vs Time")
  140.     distance_widget.addLegend()
  141.     distance_widget.setLabel("left", "Distance")
  142.     distance_widget.setLabel("bottom", "Vertical Interrupts")
  143.  
  144.     for character in list(Character):
  145.         kart = Kart(character)
  146.         distance = 0.0
  147.  
  148.         frames = []
  149.         velocities = []
  150.         distances = []
  151.  
  152.         # Go for 5 seconds at this framerate
  153.         for frame in range(0, 5 * 60, FRAMERATE):
  154.             kart.update(FRAMERATE, IS_HOLDING_A, IS_HOLDING_B, IS_USING_BOOST)
  155.             distance += kart.velocity * FRAMERATE
  156.             frames.append(frame)
  157.             velocities.append(kart.velocity)
  158.             distances.append(distance)
  159.  
  160.         # To differentiate colors, add this
  161.         # symbol=int(character), symbolPen=int(character),
  162.         velocity_widget.plot(frames, velocities, pen=int(character), name=character.name)
  163.         distance_widget.plot(frames, distances, pen=int(character), name=character.name)
  164.  
  165.     pg.exec()
  166.  
  167. if __name__ == "__main__":
  168.     main()
  169.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement