Advertisement
Faschz

DKR - Velocity Simulator

May 17th, 2020 (edited)
1,452
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.83 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 = 0
  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.         if is_using_boost:
  56.             self.boost_timer = 45
  57.  
  58.         if self.boost_timer > 0:
  59.             self.throttle = 1.0
  60.  
  61.         self.boost_timer -= framerate
  62.  
  63.         if self.boost_timer < 0:
  64.             self.boost_timer = 0
  65.  
  66.     def update_velocity(self, is_holding_a: bool) -> None:
  67.         """Update the kart's velocity"""
  68.  
  69.         self.velocity -= self.calculate_drag_from_traction(is_holding_a)
  70.  
  71.         acceleration = self.calculate_interpolated_stats()
  72.  
  73.         self.velocity += self.calculate_thrust(acceleration)
  74.         self.velocity -= self.calculate_drag_from_brake(acceleration)
  75.  
  76.         if self.velocity < 0.0:
  77.             self.velocity = 0.0
  78.  
  79.     def calculate_drag_from_traction(self, is_holding_a: bool) -> float:
  80.         """Return the drag calculated from traction"""
  81.  
  82.         if is_holding_a:
  83.             return 1.0 * 0.004 * self.velocity * self.velocity
  84.  
  85.         return 8.0 * 0.004 * self.velocity
  86.  
  87.     def calculate_drag_from_brake(self, acceleration: float) -> float:
  88.         """Return the drag calculated from braking"""
  89.  
  90.         return 0.32 * 1.7 * self.brake * acceleration
  91.  
  92.     def calculate_thrust(self, acceleration: float) -> float:
  93.         """Return the thrust calculated from throttle"""
  94.  
  95.         if self.boost_timer > 0:
  96.             return 2.0
  97.  
  98.         return 1.7 * self.throttle * acceleration
  99.  
  100.     def calculate_interpolated_stats(self) -> float:
  101.         """Calculate the acceleration based on the character's stats"""
  102.  
  103.         character_acceleration = [
  104.             [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
  105.             [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
  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], # Bumper
  107.             [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
  108.             [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
  109.             [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
  110.             [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
  111.             [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
  112.             [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
  113.             [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
  114.         ]
  115.  
  116.         idx = int(self.velocity)
  117.         remainder = self.velocity - idx
  118.  
  119.         if idx > 12:
  120.             idx = 12
  121.  
  122.         lower_acceleration = character_acceleration[self.character][idx]
  123.         upper_acceleration = character_acceleration[self.character][idx + 1]
  124.  
  125.         #TODO: Add bananas + drifting
  126.  
  127.         return lower_acceleration * (1.0 - remainder) + upper_acceleration * remainder
  128.  
  129. def main():
  130.     # Constants for the simulation
  131.     FRAMERATE = 2 # 30 FPS (60 / 30 = 2)
  132.     IS_HOLDING_A = True
  133.     IS_HOLDING_B = False
  134.     IS_USING_BOOST = False
  135.  
  136.     velocity_widget = pg.plot(title="DKR Velocity vs Time")
  137.     velocity_widget.addLegend()
  138.     velocity_widget.setLabel("left", "Velocity")
  139.     velocity_widget.setLabel("bottom", "Vertical Interrupts")
  140.  
  141.     distance_widget = pg.plot(title="DKR Distance vs Time")
  142.     distance_widget.addLegend()
  143.     distance_widget.setLabel("left", "Distance")
  144.     distance_widget.setLabel("bottom", "Vertical Interrupts")
  145.  
  146.     for character in list(Character):
  147.         kart = Kart(character)
  148.         distance = 0.0
  149.  
  150.         frames = []
  151.         velocities = []
  152.         distances = []
  153.  
  154.         # Go for 5 seconds at this framerate
  155.         for frame in range(0, 5 * 60, FRAMERATE):
  156.             kart.update(FRAMERATE, IS_HOLDING_A, IS_HOLDING_B, IS_USING_BOOST)
  157.             distance += kart.velocity * FRAMERATE
  158.             frames.append(frame)
  159.             velocities.append(kart.velocity)
  160.             distances.append(distance)
  161.  
  162.         # To differentiate colors, add this
  163.         # symbol=int(character), symbolPen=int(character),
  164.         velocity_widget.plot(frames, velocities, pen=int(character), name=character.name)
  165.         distance_widget.plot(frames, distances, pen=int(character), name=character.name)
  166.  
  167.     pg.exec()
  168.  
  169. if __name__ == "__main__":
  170.     main()
  171.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement