Advertisement
here2share

# tk_Racing_Pseudo_3D_Road.py

Mar 2nd, 2025
177
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.52 KB | None | 0 0
  1. # tk_Racing_Pseudo_3D_Road.py ZZZ looks like a whole lot more work is needed
  2.  
  3. import math
  4. import time
  5. import tkinter as tk
  6. from PIL import Image, ImageTk
  7.  
  8. WW = 1200
  9. HH = 600
  10. roadW = 5000
  11. segL = 250
  12. camD = 0.84
  13. show_N_seg = 300
  14. max_speed = 270
  15. sky_blue = "#94D9EB"
  16. dark_grass = "#009A00"
  17. light_grass = "#10C810"
  18. white_rumble = "#FFFFFF"
  19. black_rumble = "#000000"
  20. dark_road = "#595959"
  21. light_road = "#6B6B6B"
  22.  
  23. # Sections format: [(X: (A, C), Y: (B, C)), ...]
  24. # A: X-curve (-5 to 5), B: Y-height (0 to 10), C: length (1=short, 2=medium, 3=long)
  25. selected_sections = [
  26.     ((2, 3), (0, 1)),
  27.     ((0, 2), (2, 2)),
  28.     ((-5, 3), (0, 1)),
  29.     ((0, 1), (3, 3)),
  30.     ((5, 3), (7, 3)),
  31.     ((4, 2), (1, 2)),
  32.     ((-1, 3), (5, 1)),
  33.     ((0, 2), (9, 2)),
  34.     ((3, 1), (0, 1)),
  35. ]
  36.  
  37. root = tk.Tk()
  38. root.title("Racing Pseudo 3D Road")
  39. canvas = tk.Canvas(root, width=WW, height=HH, bg=dark_grass)
  40. root.geometry("+0+0")
  41. canvas.pack()
  42.  
  43. def project(line, camX, camY, camZ):
  44.     scale = camD / (line[2] - camZ)
  45.     X = (1 + scale * (line[0] - camX)) * WW / 2
  46.     Y = (1 - scale * (line[1] - camY)) * HH / 2
  47.     W = scale * roadW * WW / 2
  48.     return X, Y, W, scale
  49.  
  50. def drawQuad(color, x1, y1, w1, x2, y2, w2):
  51.     if color:
  52.         canvas.create_polygon(x1-w1, y1, x2-w2, y2, x2+w2, y2, x1+w1, y1, fill=color, outline="")
  53.  
  54. def drawSprite(sprite, line, spriteX, clip):
  55.     if sprite is None:
  56.         return
  57.     w = sprite.width()
  58.     h = sprite.height()
  59.     X, Y, W, scale = line
  60.     destX = X + scale * spriteX * WW / 2
  61.     destY = Y + 4
  62.     destW = w * W / 266
  63.     destH = h * W / 266
  64.     destX += destW * spriteX
  65.     destY += destH * -1
  66.     clipH = destY + destH - clip
  67.     if clipH < 0:
  68.         clipH = 0
  69.     if clipH >= destH:
  70.         return
  71.     if destW > w:
  72.         return
  73.     canvas.create_image(destX, destY, image=sprite, anchor=tk.NW)
  74.  
  75. keys = {'Up': False, 'Down': False, 'Left': False, 'Right': False}
  76. def drive():
  77.     global speed, turn
  78.     speed_percent = min(1, speed * 0.04)
  79.     print(speed_percent)
  80.  
  81.     if keys['Up']:
  82.         speed = min(max_speed, speed + 1)
  83.     elif keys['Down']:
  84.         speed = max(0, speed - 10)
  85.  
  86.     if keys['Right']:
  87.         turn = min(roadW * 1.5, turn + 500 * speed_percent)
  88.     elif keys['Left']:
  89.         turn = max(-roadW * 1.5, turn - 500 * speed_percent)
  90.  
  91.        
  92. def keydown(event):
  93.     if event.keysym in keys:
  94.         keys[event.keysym] = True
  95.  
  96. def keyup(event):
  97.     if event.keysym in keys:
  98.         keys[event.keysym] = False
  99.  
  100. root.bind_all('<KeyPress>', keydown)
  101. root.bind_all('<KeyRelease>', keyup)
  102.  
  103. def generate_road():
  104.     lines = []
  105.     segment_index = 0
  106.    
  107.     def ease_value(t):
  108.         return t * t * (3 - 2 * t)
  109.    
  110.     def smooth_interpolate(start, end, steps, i):
  111.         t = i / steps
  112.         eased_t = ease_value(t)
  113.         return start + (end - start) * eased_t
  114.    
  115.     last_curve = 0
  116.     last_height = 0
  117.    
  118.     for section_idx, ((curve_value, curve_length), (height_value, height_length)) in enumerate(sections):
  119.         target_curve = curve_value * 0.5
  120.        
  121.         target_height = height_value * 5000
  122.        
  123.         num_segments = curve_length * 500
  124.        
  125.         for i in range(num_segments):
  126.             transition_zone = int(num_segments * 0.5)
  127.             if i < transition_zone:
  128.                 current_curve = smooth_interpolate(last_curve, target_curve, transition_zone, i)
  129.                 current_height = smooth_interpolate(last_height, target_height, transition_zone, i)
  130.             else:
  131.                 current_curve = target_curve
  132.                 current_height = target_height
  133.            
  134.             is_checkered = (section_idx == 1) and (i < 10)
  135.             grass_color = light_grass if (segment_index // 10) % 2 else dark_grass
  136.             rumble_color = white_rumble if ((segment_index // 10) % 6) >= 3 else black_rumble
  137.            
  138.             if is_checkered:
  139.                 road_color = "white"
  140.             else:
  141.                 road_color = light_road if ((segment_index // 10) % 10) >= 5 else dark_road
  142.            
  143.             z = segment_index * segL + 0.000001
  144.             lines.append([0, current_height, z, 0, 0, 0, current_curve, 0, None,
  145.                          grass_color, rumble_color, road_color])
  146.             segment_index += 1
  147.        
  148.         last_curve = target_curve
  149.         last_height = target_height
  150.    
  151.     return lines
  152.  
  153. while 1:
  154.     sections = selected_sections[:]
  155.     t = ((0, 1), (0, 2))
  156.     sections = [t, *sections, t]
  157.     lines = generate_road()
  158.     N = len(lines)
  159.     pos = 0
  160.     playerX = 0
  161.     playerY = 1500
  162.     speed = 0
  163.     turn = 0
  164.    
  165.     while 1:
  166.         drive()
  167.        
  168.         pos = int(pos + (speed * 60))
  169.         playerX = turn
  170.        
  171.         while pos >= N * segL:
  172.             pos -= N * segL
  173.         while pos < 0:
  174.             pos += N * segL
  175.            
  176.         startPos = pos // segL
  177.         x = dx = 0.0
  178.         camH = lines[startPos][1] + playerY
  179.         maxy = HH
  180.    
  181.         canvas.delete("all")
  182.        
  183.         for n in range(startPos, startPos + show_N_seg):
  184.             current = lines[n % N]
  185.             p = project(current, playerX - x, camH, pos - (N * segL if n >= N else 0))
  186.             x += dx
  187.             dx += current[6]
  188.                
  189.             maxy = p[1]
  190.             prev = lines[(n - 1) % N]
  191.             pp = project(prev, playerX - x + dx, camH, pos - (N * segL if n >= N else 0))
  192.            
  193.             drawQuad(current[9], 0, pp[1], WW, 0, p[1], WW)  # grass
  194.             drawQuad(current[10], pp[0], pp[1], pp[2] * 1.2, p[0], p[1], p[2] * 1.2)  # shoulder
  195.             drawQuad(current[11], pp[0], pp[1], pp[2], p[0], p[1], p[2])  # road
  196.            
  197.         canvas.create_rectangle(0, 0, WW, maxy, fill=sky_blue)
  198.         canvas.create_text(10, 10, text=f"Speed: {int(speed)} km/h", font="verdana 24", anchor=tk.NW)
  199.            
  200.         root.update()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement