From 37c7c89d1e1edf8daaccc6302420fff5dec05e79 Mon Sep 17 00:00:00 2001 From: Aidan Haas Date: Mon, 23 Jun 2025 15:34:41 -0400 Subject: [PATCH] add cluster graphics and transmission simulation --- .gitignore | 2 + __pycache__/engine.cpython-311.pyc | Bin 1886 -> 0 bytes __pycache__/engine.cpython-313.pyc | Bin 4582 -> 0 bytes changelog.md | 10 +++ changelog/changelog.md | 12 ++++ changelog/image.png | Bin 0 -> 67681 bytes engine.py | 15 ++-- main.py | 112 ++++++++++++++++++++++------- transmission.py | 28 ++++++++ 9 files changed, 150 insertions(+), 29 deletions(-) create mode 100644 .gitignore delete mode 100644 __pycache__/engine.cpython-311.pyc delete mode 100644 __pycache__/engine.cpython-313.pyc create mode 100644 changelog.md create mode 100644 changelog/changelog.md create mode 100644 changelog/image.png create mode 100644 transmission.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3072e6f --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.pyc +*.pyo \ No newline at end of file diff --git a/__pycache__/engine.cpython-311.pyc b/__pycache__/engine.cpython-311.pyc deleted file mode 100644 index c22f8796ab82ff993bac831ceebe622f4d4c19eb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1886 zcmb7EJ#5=X6h2CnOi7d_OS1e^BsSW@iGU)3iw=bm6t%6^ZX4J`(4m3=f)-B_9f@>~ zN7oi)fI|ik9ulB{J9Kb|rf!oVLx&C>I%bRl0VWP8AfQv0LWMhd>bs+**l?FV@_W4Z zbMM}}cgG)-$v6U9da+nvml67t3j+dK(CJP193lf5QUjGx2(2I^^bi^0Cn1EM0s<;Y zhI9`V-cy2@DPqM&OG|Aww#K0Wu&0hyq3ciV-TsjBqIq;{-qjBmtv< z6d(;417rYMKn^et$O9$-lZN~dm8Ogc@M$9oIgPOBCsxh0FyYyne*rg*DTFG6#CU#u z90r{79f5MCJxCHJht^)7f#xR|G1w4UL~vYU(W9)OVO-8V#($kpt1R*a+x^6b&M< zRMmwkxLP$UCblZOEG860rmhZd}945nwUAt zJ+_Z?CxwMqg@s=~`0c|^q1Y`HJLARQX?LaE887e0eMQ|@4wOfqA7vh|ca(Ry@JBZP zh<>y8L*@A0XE&c0f4SS4TkOs)cCt&|>=Fc5dim*-{Eb)n8^`i9rIVlU=I5WUcJgJK9s!6J`39GX3rQ9p!pgx&CtS65isq!dpzyG)r${ zO=EFQYubhj8?P}{(;m2bBd~~8UD&}<(}KHfQSH1Nat-T*WFR2PahB%{el>`N^(tX% z#kL#59U8(E+iZx|u#{P|OlsPeMos8)jj4Kb1KJ63g`?h}CUp%AjuzGLV{MCI$8iZ} z>Nc*M6-czHI}S@3#N5V|=%%GLY*46tiJ^0Xx@5!FHf-CWEOa08!8>)`b%JFGKlUC%pCEQ1rRz3-OI1ll8vvV{vau82Yjl$-t2tuxL6m(??fXkUdYF z|F@eu+&@vp<;u>KJ3*g6BJ<$N|9;NL!1`fHl6;i##M75=OR&gQ_BYr4^B)GW`oGh7 B$W;IU diff --git a/__pycache__/engine.cpython-313.pyc b/__pycache__/engine.cpython-313.pyc deleted file mode 100644 index 9b4582f6fd3fe15cf4a4e2ae519c0862671da87f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4582 zcmc&&PfQ!x8Gkmm8NgtY5MqptjZI*^g}^S^lxCqM4Wx9FB`YRrky>dq*n^p7Y?C)* znnX&wmsTW8L{{3U&`VPF(Cn${soUH3)btcar1I#s2TMIvT&gH()k~%H``(PlOhhWR zmp-ib-tYbSzVH3}zTfb&y}gw{>b!Mv<;NX_`~^Wh1)R#u6jbgLk%+zvgpw#p6VV?d zV$*wmdj$0reA&Prg87`?Wamylc{vIAKKUM@K9Nwr=%Y=2r12*TVpEKK-$w&tAVz3V z3_>0fLy$L%%~UA(vn?z%TPmm}Wv_{AY2K#>wP5SZccFHlEOu&cr|7#vG+!NZRJRG% z1ARD;C(#e6zG7G#pkTcZB!=92N^^BDj%kA1enx9?>mO-+R}o(cP5It(I`UycQlNFA zyFRi}fU2>vphGS~DTiHzD>~vL?CbKNqaNg1$Za|1 z>5F<$j|as(sMmwy9+dE)J`YNIP|Ab)Jt*x#84nuppyM7iSVskt73Tk1N0-l2ydQgb z^n1U+49_k*#G2@8kqO2MEgOcWuz*&U^DIzMWXc4!P*M%GTw)=rtevYE(2~~_31>7H zN& zSD|YP3wuz9TG9=xnA zTihA#eDN-9;gHIP!kXk|%KTR;>oC+Jm>|jdHMx{iSfsw^lHI|=%JmhwqQhRG);6O; zm&(#oxvU#3EEktxQ=KkB)(q9CE?@3@WQ7Nh|Am zwwVQVMO&u$z$m^eiqDDSE28*#D83RMokPk_?CsH&a#0zT)x2C9ohj!kMKD7jwRd?$ zSBp;d#Oe(uNN^ccLy}lzmY>{-dILHoeH5J7$K?58(iPtjtZ46gV58mYItE3H)fMGM zG|n5lv9GNbO~HU;eH&q`ckr1IwNhixgoKqm@l1$Y@wck+*+($)w(e-z>`Vc$s3b@u?!iSs}) z4;2g)3sAnEM%oA|`M=u;3_b`Aez9o;T)G$-0f#>V-a!nGz{Gk093a`yJjJ8m``4>i zuL`!z+VmcGCK!LRetuA%Lmt8IEs1j}t9mh^|z^vD~3I{oZ zb1*2Z^Wi$HK-N?j_FhNhj z6wj`pjeJ*9P=PRyAroqL@&-_Fmj3z6uoetJ6n!?-aV^ZBH*^%_n9qXTYp}4h0FJ&1 z{W=CKu-Lh*Sln&5ZNhtAPgv(R-GQ1nq%Wo#0Ubi={#nlKdbpKuLii;Mcr33aXoYip zJ-vqq1*sHRJhR{iaJvn2e(pXzci1795P&QLF4I>cv zb$^439BixTKm8dYGEfdqRoq)H21;;#2T6xkmnbwWIt`9Yh8+@-R=CY?lmMe&Puvca zfK-e0^LKoExVkuFy-(dfV~w3yep_T4>1E~y2Qy9OzJz5AL1ii`qUWlMvX3= zYK+DEg?Fgb%vS?+@IUF4K?02UAKnL-4ixgBy}A-W3!u+Ek$v`I4?oK*Aw1Fl|2w+k zbF6g<=xf&Qqu1d5TITm~S?UgKnoSi8KikIi+v&@DdFa`D0$KJDMVCO~w%J~iQv>er zDNYfftD4`Pm7tL_8md@;ila8!|HqH#kYsnOBUoDw=aBKV4&git6oc?m4`i%t>e#wQMZ>wgX zx})7R`)(pF>b1IK)$Xj>okbRR)`Va8+4WXS2yY5^gnJ)+ddUp2G@w}Xe=>>vfVLnyKcioS{tV3xrwjoCYx@jJ<{Bi zU%Z_Z&q+X85gVzlz2)KxV}0h5e4Q2$5aWVa&!b z!_UraNc|f`K6Mcum70eZ=P_pss_itzRlQ;kX diff --git a/changelog.md b/changelog.md new file mode 100644 index 0000000..0aa6ea1 --- /dev/null +++ b/changelog.md @@ -0,0 +1,10 @@ +6/23/25 +* Added visual accelerator pedal +* Scale accelerator pedal to new screen +* Parabolic curve for better feeling accelerator pedal +* Added numbers to RPM gauge +* Added Fuel gauge +* Added gauge cluster background +* Visual tweaks +* Added simple clutch simulation +* Added simple transmission simulation \ No newline at end of file diff --git a/changelog/changelog.md b/changelog/changelog.md new file mode 100644 index 0000000..1d79453 --- /dev/null +++ b/changelog/changelog.md @@ -0,0 +1,12 @@ +6/23/25 +* Added visual accelerator pedal +* Scale accelerator pedal to new screen +* Parabolic curve for better feeling accelerator pedal +* Added numbers to RPM gauge +* Added Fuel gauge +* Added gauge cluster background +* Visual tweaks +* Added simple clutch simulation +* Added simple transmission simulation + +![alt text](image.png) \ No newline at end of file diff --git a/changelog/image.png b/changelog/image.png new file mode 100644 index 0000000000000000000000000000000000000000..88452914e1f6e1ba575b2759c7164e78a549219e GIT binary patch literal 67681 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 R1;&=zzgJB$b+_@Q{{zo&wFm$J literal 0 HcmV?d00001 diff --git a/engine.py b/engine.py index 93b5607..7eb8fa7 100644 --- a/engine.py +++ b/engine.py @@ -24,7 +24,6 @@ class Engine: self.fuel_efficiency = fuel_efficiency self.torque_curve = torque_curve or self.default_torque_curve self.instant_torque = 0 - self.wheel_speed = 0 self.engineFriction = 5 self.peak_torque = 163 # Nm -> 120 ft/lb self.engine_brake_strength = 40 # Nm @@ -40,7 +39,8 @@ class Engine: self.coolant_pressure = 0 self.coolant_capacity = 0 - self.fuel_capacity = 0 + self.max_fuel_capacity = 68 # Liter + self.fuel_capacity = self.max_fuel_capacity # Fuel @@ -63,6 +63,7 @@ class Engine: self.vehicle_mass = 0 self.drivetrain_loss = 0 + # Just a parabolic curve for now def default_torque_curve(self, rpm): rpm_ratio = rpm / self.max_rpm @@ -70,8 +71,7 @@ class Engine: def start(self, dt): self.ignition = True - self.starting = True - + self.starting = True def update(self, throttle, load, dt): self.throttle = throttle @@ -107,11 +107,15 @@ class Engine: friction_force = 0 # Engine braking torque (If throttle closed) - if self.throttle < 0.1 and self.rpm > self.idle_rpm + 200 or not self.ignition: + if self.throttle == 0 and self.rpm > self.idle_rpm + 200 or not self.ignition: engine_brake_torque = self.engine_brake_strength * (self.rpm / self.max_rpm) else: engine_brake_torque = 0 + # Transmission Load + + + # Calculate torque if self.ignition: available_torque = self.torque_curve(self.rpm) @@ -123,5 +127,6 @@ class Engine: self.rpm += rpm_change * dt self.fuel_rate = self.rpm * throttle * self.fuel_efficiency + # self.fuel_capacity -= self.fuel_rate #self._update_temps(dt) diff --git a/main.py b/main.py index c4c906f..911642e 100644 --- a/main.py +++ b/main.py @@ -2,24 +2,25 @@ import pygame import math from engine import Engine +from transmission import Transmission # pygame setup pygame.init() +pygame.display.set_caption('Engine Sim') screen = pygame.display.set_mode((1280, 720)) clock = pygame.time.Clock() running = True dt = 0 -player_pos = pygame.Vector2(screen.get_width() / 2, screen.get_height() / 2) - # Text Setup pygame.font.init() font = pygame.font.SysFont(None, 64) +gauge_font = pygame.font.SysFont(None, 24) # Gauge Setup -rpm_pos = pygame.Vector2(screen.get_width() * 0.25, screen.get_height() / 2) -spd_pos = pygame.Vector2(screen.get_width() * 0.75, screen.get_height() / 2) +rpm_pos = pygame.Vector2(screen.get_width() * 0.30, screen.get_height() / 2) +spd_pos = pygame.Vector2(screen.get_width() * 0.70, screen.get_height() / 2) gauge_radius = screen.get_height() / 5 @@ -36,14 +37,33 @@ offset_vector = pygame.Vector2( ) e = Engine() +t = Transmission(e) throttle = 0 def map_value_to_angle(value, min_val, max_val): - clamped = max(min_val, min(value, max_val)) # Can change this later + clamped = max(min_val, value) return math.radians(150 + 270 * (clamped - min_val) / (max_val - min_val)) while running: + screen.fill("white") + sX, sY = screen.get_width(), screen.get_height() mX, mY = pygame.mouse.get_pos() + + # Gauge Cluster + cluster_padding = (sX / sY) * (sX / 64) + cluster_padding_x = (sX / sY) * (sX / 64) + cluster_y = min(rpm_pos.y, spd_pos.y) - gauge_radius - cluster_padding + cluster_bottom = max(rpm_pos.y, spd_pos.y) + gauge_radius + cluster_padding + cluster_x = rpm_pos.x - gauge_radius - cluster_padding - cluster_padding_x + cluster_right = spd_pos.x + gauge_radius + cluster_padding + cluster_padding_x + + cluster_width = cluster_right - cluster_x + cluster_height = cluster_bottom - cluster_y + + cluster_rect = pygame.Rect(cluster_x, cluster_y, cluster_width, cluster_height) + pygame.draw.rect(screen, (50, 50, 50), cluster_rect, border_radius=30) # dark gray with rounded corners + + # poll for events # pygame.QUIT event means the user clicked X to close your window for event in pygame.event.get(): @@ -53,57 +73,101 @@ while running: e.ignition = False else: e.start(dt) + if (pygame.key.name(event.key) == 'x'): + t.upshift() + if (pygame.key.name(event.key) == 'z'): + t.downshift() + if (pygame.key.name(event.key) == 'left shift'): + t.clutch_pressure = 1 + if event.type == pygame.KEYUP: + if (pygame.key.name(event.key) == 'left shift'): + t.clutch_pressure = 0 + if event.type == pygame.QUIT: running = False - # fill the screen with a color to wipe away anything from last frame - screen.fill("white") - rpm_text = font.render(f"RPM: {int(e.rpm)}", True, (0, 0, 0)) rpm_rect = rpm_text.get_rect(center=(screen.get_width() // 2, screen.get_height() // 4)) screen.blit(rpm_text, rpm_rect) - rpm_text = font.render(f"Torque: {int(e.instant_torque)}", True, (0, 0, 0)) + rpm_text = font.render(f"Torque: {int(e.instant_torque)}", True, (255, 0, 0)) rpm_rect = rpm_text.get_rect(center=(screen.get_width() // 2, screen.get_height() // 4 +100)) screen.blit(rpm_text, rpm_rect) rpm_angle = map_value_to_angle(e.rpm, 0, 8000) # RPM Gauge - speed_angle = map_value_to_angle(e.wheel_speed, 0, 160) rpm_vector = pygame.Vector2(math.cos(rpm_angle), math.sin(rpm_angle)) * gauge_radius pygame.draw.circle(screen, "black", rpm_pos, gauge_radius) pygame.draw.line(screen, needle_color, rpm_pos, rpm_pos + rpm_vector, needle_width) + for rpm_tick in range(0, 9000, 1000): # 1000 to 8000 + angle = map_value_to_angle(rpm_tick, 0, 8000) + direction = pygame.Vector2(math.cos(angle), math.sin(angle)) + label_pos = rpm_pos + direction * (gauge_radius - 20) # slight inward offset - # Trans Gauge + label_text = gauge_font.render(str(rpm_tick // 1000), True, (255, 255, 255)) + text_rect = label_text.get_rect(center=(label_pos.x, label_pos.y)) + screen.blit(label_text, text_rect) + + # Speed Gauge + + speed_angle = map_value_to_angle(t.get_velocity(), 0, 160) speed_vector = pygame.Vector2(math.cos(speed_angle), math.sin(speed_angle)) * gauge_radius - pygame.draw.circle(screen, "red", spd_pos, gauge_radius) - spd_tip = spd_pos + offset_vector - pygame.draw.line(screen, needle_color, spd_pos, spd_tip, needle_width) - pygame.draw.circle(screen, needle_color, spd_tip, tip_radius) + pygame.draw.circle(screen, "black", spd_pos, gauge_radius) + pygame.draw.line(screen, needle_color, spd_pos, spd_pos + speed_vector, needle_width) - pygame.draw.circle(screen, "red", player_pos, 40) + for speed_tick in range(0, 180, 20): # 1000 to 8000 + angle = map_value_to_angle(speed_tick, 0, 160) + direction = pygame.Vector2(math.cos(angle), math.sin(angle)) + label_pos = spd_pos + direction * (gauge_radius - 20) # slight inward offset + + label_text = gauge_font.render(str(speed_tick), True, (255, 255, 255)) + text_rect = label_text.get_rect(center=(label_pos.x, label_pos.y)) + screen.blit(label_text, text_rect) + + # Fuel Gauge - 10 Steps + fuel_steps = math.ceil((e.fuel_capacity / e.max_fuel_capacity) * 10) + + fuel_x = cluster_x + (cluster_padding / 1.5) + fuel_y = cluster_bottom - cluster_padding * 2 + fuel_width = cluster_padding / 1.5 + fuel_height = cluster_height / 20 + + fuel_step = cluster_height / 16 + + #fuel_rect = pygame.rect() Make this a rect as a backdrop for fuel + + for i in range(fuel_steps): + fuel_rect = pygame.Rect(fuel_x, fuel_y, fuel_width, fuel_height) + pygame.draw.rect(screen, "white", fuel_rect, border_radius=2) + fuel_y -= fuel_step + + + + # Temp Gauge - 10 Steps + + # Throttle + throttle_text = font.render(f"Throttle", True, (0, 0, 0)) + throttle_text_rect = throttle_text.get_rect(center=((sX - sX // 16), screen.get_height() // 4.5)) + screen.blit(throttle_text, throttle_text_rect) + throttle_rect = pygame.Rect((sX - sX / 16), sY / 4, sX / 16, sY / 2) + pygame.draw.rect(screen, "red", throttle_rect) keys = pygame.key.get_pressed() if keys[pygame.K_w]: e.rpm += 600 * dt if keys[pygame.K_s]: e.rpm -= 600 * dt - if keys[pygame.K_a]: - player_pos.x -= 300 * dt - if keys[pygame.K_d]: - player_pos.x += 300 * dt if keys[pygame.K_r]: e.rpm = e.idle_rpm + # Throttle (Using mouse pos) - throttle = 1 - (mY / screen.get_height()) - #print(throttle) + throttle = pow(max(0, min(1 - (((mY - (sY / 4)) / 2) / (sY / 4)), 1)),2) # Clamp value between 0 and 1 + # print(mX, mY) - - # flip() the display to put your work on screen pygame.display.flip() # limits FPS to 60 diff --git a/transmission.py b/transmission.py new file mode 100644 index 0000000..35c030a --- /dev/null +++ b/transmission.py @@ -0,0 +1,28 @@ +from engine import Engine + +class Transmission: + def __init__(self, engine): + self.clutch_pressure = 0 + self.gear_ratios = [0,216,108,72,54,43,36] + self.selected_gear = 0 + self.max_gear = 6 + self.min_gear = -1 + self.inertia = 0 + + self.engine = engine + + def upshift(self): + self.selected_gear = min(self.selected_gear + 1, self.max_gear) + print(self.selected_gear) + + def downshift(self): + self.selected_gear = max(self.selected_gear - 1, self.min_gear) + print(self.selected_gear) + + def get_velocity(self): + if (self.selected_gear == 0): + return 0 + return self.engine.rpm / self.gear_ratios[self.selected_gear] + + def calculate_load(self): + return \ No newline at end of file