Я пишу основной сценарий, чтобы имитировать движение бота вокруг препятствий.
Ожидается, что бот посетит все доступные точки в пределах границ, прежде чем остановится (немного похоже на iRobot Roomba robovac).
Мне нужно визуализировать все места, где он былрисование тени и «раскраска» всей области в границах по мере ее перемещения.
Код ниже был обрезан, чтобы показать только рендеринг движения, но тень работает только в направлениях вверх / вниз.Тем не менее, поворот не отрисовывается должным образом.
import pygame
import math
import numpy as np
pygame.init()
win_w = 600
win_h = 800
win = pygame.display.set_mode((win_w, win_h))
travelled_region = pygame.Surface((win_w, win_h), pygame.SRCALPHA)
size_scale = 50 # Divisor. 1 = 1px/mm, 10 = 1px/cm, 100 = 1px/m
canvas_clock = pygame.time.Clock()
boundary_lines = np.array(
[[[313., 343.],
[313., 441.]],
[[313., 441.],
[209., 441.]],
[[209., 441.],
[207., 343.]],
[[207., 343.],
[313., 343.]]])
class VehicleObject(object):
def __init__(self):
w, h = pygame.display.get_surface().get_size()
self.velocity = 5
self.width = 35
self.height = 50
self.x = w//2 - (self.width // size_scale) // 2
self.y = h//2 - (self.height // size_scale) // 2
def draw(self, win):
pygame.draw.rect(win, (200, 200, 200), (self.x, self.y, self.width, self.height))
pygame.draw.rect(travelled_region, (150, 150, 150), (self.x, self.y, self.width, self.height))
def redraw_game_window():
win.fill((255, 255, 255))
win.blit(travelled_region, (0, 0))
car.draw(win)
draw_boundaries(win)
pygame.display.update()
def draw_boundaries(win):
for i, line in enumerate(boundary_lines):
pygame.draw.line(win, (0, 0, 255), (line[0]), (line[1]), 2)
def rotate_around_point_highperf(xy, radians, origin=(0, 0)):
"""Rotate a point around a given point.
Source: https://gist.github.com/LyleScott/e36e08bfb23b1f87af68c9051f985302
I call this the "high performance" version since we're caching some
values that are needed >1 time. It's less readable than the previous
function but it's faster.
"""
x, y = xy
offset_x, offset_y = origin
adjusted_x = (x - offset_x)
adjusted_y = (y - offset_y)
cos_rad = math.cos(radians)
sin_rad = math.sin(radians)
qx = offset_x + cos_rad * adjusted_x + sin_rad * adjusted_y
qy = offset_y + -sin_rad * adjusted_x + cos_rad * adjusted_y
return qx, qy
car = VehicleObject()
run = True
while run:
canvas_clock.tick_busy_loop(100) # Run at 100 fps
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
boundary_lines[:, :, 0], boundary_lines[:, :, 1] = rotate_around_point_highperf(
(boundary_lines[:, :, 0], boundary_lines[:, :, 1]), -0.01, (car.x, car.y))
travelled_region = pygame.transform.rotate(travelled_region, -1)
if keys[pygame.K_RIGHT]:
boundary_lines[:, :, 0], boundary_lines[:, :, 1] = rotate_around_point_highperf(
(boundary_lines[:, :, 0], boundary_lines[:, :, 1]), 0.01, (car.x, car.y))
travelled_region = pygame.transform.rotate(travelled_region, 1)
if keys[pygame.K_UP]:
boundary_lines[:, :, 1] = boundary_lines[:, :, 1] + 1
travelled_region.scroll(0, 1)
if keys[pygame.K_DOWN]:
boundary_lines[:, :, 1] = boundary_lines[:, :, 1] - 1
travelled_region.scroll(0, -1)
if keys[pygame.K_ESCAPE]:
run = False
redraw_game_window()
pygame.quit()
Сложность заключается в решении отрисовать игру от POV автомобиля, поэтому границы (и тень) вращаются вокруг центральной осимашина.
Так, каков был бы лучший способ нарисовать тень предыдущих позиций автомобиля, если мир движется вокруг машины, а не наоборот?