Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # tk_Racing_Pseudo_3D_Road.py ZZZ looks like a whole lot more work is needed
- import math
- import time
- import tkinter as tk
- from PIL import Image, ImageTk
- WW = 1200
- HH = 600
- roadW = 5000
- segL = 250
- camD = 0.84
- show_N_seg = 300
- max_speed = 270
- sky_blue = "#94D9EB"
- dark_grass = "#009A00"
- light_grass = "#10C810"
- white_rumble = "#FFFFFF"
- black_rumble = "#000000"
- dark_road = "#595959"
- light_road = "#6B6B6B"
- # Sections format: [(X: (A, C), Y: (B, C)), ...]
- # A: X-curve (-5 to 5), B: Y-height (0 to 10), C: length (1=short, 2=medium, 3=long)
- selected_sections = [
- ((2, 3), (0, 1)),
- ((0, 2), (2, 2)),
- ((-5, 3), (0, 1)),
- ((0, 1), (3, 3)),
- ((5, 3), (7, 3)),
- ((4, 2), (1, 2)),
- ((-1, 3), (5, 1)),
- ((0, 2), (9, 2)),
- ((3, 1), (0, 1)),
- ]
- root = tk.Tk()
- root.title("Racing Pseudo 3D Road")
- canvas = tk.Canvas(root, width=WW, height=HH, bg=dark_grass)
- root.geometry("+0+0")
- canvas.pack()
- def project(line, camX, camY, camZ):
- scale = camD / (line[2] - camZ)
- X = (1 + scale * (line[0] - camX)) * WW / 2
- Y = (1 - scale * (line[1] - camY)) * HH / 2
- W = scale * roadW * WW / 2
- return X, Y, W, scale
- def drawQuad(color, x1, y1, w1, x2, y2, w2):
- if color:
- canvas.create_polygon(x1-w1, y1, x2-w2, y2, x2+w2, y2, x1+w1, y1, fill=color, outline="")
- def drawSprite(sprite, line, spriteX, clip):
- if sprite is None:
- return
- w = sprite.width()
- h = sprite.height()
- X, Y, W, scale = line
- destX = X + scale * spriteX * WW / 2
- destY = Y + 4
- destW = w * W / 266
- destH = h * W / 266
- destX += destW * spriteX
- destY += destH * -1
- clipH = destY + destH - clip
- if clipH < 0:
- clipH = 0
- if clipH >= destH:
- return
- if destW > w:
- return
- canvas.create_image(destX, destY, image=sprite, anchor=tk.NW)
- keys = {'Up': False, 'Down': False, 'Left': False, 'Right': False}
- def drive():
- global speed, turn
- speed_percent = min(1, speed * 0.04)
- print(speed_percent)
- if keys['Up']:
- speed = min(max_speed, speed + 1)
- elif keys['Down']:
- speed = max(0, speed - 10)
- if keys['Right']:
- turn = min(roadW * 1.5, turn + 500 * speed_percent)
- elif keys['Left']:
- turn = max(-roadW * 1.5, turn - 500 * speed_percent)
- def keydown(event):
- if event.keysym in keys:
- keys[event.keysym] = True
- def keyup(event):
- if event.keysym in keys:
- keys[event.keysym] = False
- root.bind_all('<KeyPress>', keydown)
- root.bind_all('<KeyRelease>', keyup)
- def generate_road():
- lines = []
- segment_index = 0
- def ease_value(t):
- return t * t * (3 - 2 * t)
- def smooth_interpolate(start, end, steps, i):
- t = i / steps
- eased_t = ease_value(t)
- return start + (end - start) * eased_t
- last_curve = 0
- last_height = 0
- for section_idx, ((curve_value, curve_length), (height_value, height_length)) in enumerate(sections):
- target_curve = curve_value * 0.5
- target_height = height_value * 5000
- num_segments = curve_length * 500
- for i in range(num_segments):
- transition_zone = int(num_segments * 0.5)
- if i < transition_zone:
- current_curve = smooth_interpolate(last_curve, target_curve, transition_zone, i)
- current_height = smooth_interpolate(last_height, target_height, transition_zone, i)
- else:
- current_curve = target_curve
- current_height = target_height
- is_checkered = (section_idx == 1) and (i < 10)
- grass_color = light_grass if (segment_index // 10) % 2 else dark_grass
- rumble_color = white_rumble if ((segment_index // 10) % 6) >= 3 else black_rumble
- if is_checkered:
- road_color = "white"
- else:
- road_color = light_road if ((segment_index // 10) % 10) >= 5 else dark_road
- z = segment_index * segL + 0.000001
- lines.append([0, current_height, z, 0, 0, 0, current_curve, 0, None,
- grass_color, rumble_color, road_color])
- segment_index += 1
- last_curve = target_curve
- last_height = target_height
- return lines
- while 1:
- sections = selected_sections[:]
- t = ((0, 1), (0, 2))
- sections = [t, *sections, t]
- lines = generate_road()
- N = len(lines)
- pos = 0
- playerX = 0
- playerY = 1500
- speed = 0
- turn = 0
- while 1:
- drive()
- pos = int(pos + (speed * 60))
- playerX = turn
- while pos >= N * segL:
- pos -= N * segL
- while pos < 0:
- pos += N * segL
- startPos = pos // segL
- x = dx = 0.0
- camH = lines[startPos][1] + playerY
- maxy = HH
- canvas.delete("all")
- for n in range(startPos, startPos + show_N_seg):
- current = lines[n % N]
- p = project(current, playerX - x, camH, pos - (N * segL if n >= N else 0))
- x += dx
- dx += current[6]
- maxy = p[1]
- prev = lines[(n - 1) % N]
- pp = project(prev, playerX - x + dx, camH, pos - (N * segL if n >= N else 0))
- drawQuad(current[9], 0, pp[1], WW, 0, p[1], WW) # grass
- drawQuad(current[10], pp[0], pp[1], pp[2] * 1.2, p[0], p[1], p[2] * 1.2) # shoulder
- drawQuad(current[11], pp[0], pp[1], pp[2], p[0], p[1], p[2]) # road
- canvas.create_rectangle(0, 0, WW, maxy, fill=sky_blue)
- canvas.create_text(10, 10, text=f"Speed: {int(speed)} km/h", font="verdana 24", anchor=tk.NW)
- root.update()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement