我正在尝试建立一个基于不接触电线的小游戏(你必须在电线/线周围操纵一个圆圈)。我不太清楚从哪里开始编程导线和圆边缘之间的碰撞,因为导线随机移动。我是否必须创建一个存储该行所有坐标的列表? 这是代码:
import pygame
from random import randint
pygame.init()
white = (255, 255, 255)
black = (0, 0, 0)
red = (255, 0, 0)
green = (0, 255, 0)
blue = (0, 0, 255)
display_width = 600
display_height = 600
gameDisplay = pygame.display.set_mode((display_width, display_height))
pygame.display.set_caption("Wire")
font = pygame.font.SysFont("aerial", 20)
clock = pygame.time.Clock()
pygame.display.update()
def text_objects(text, colour):
textSurface = font.render(text, True, colour)
return textSurface, textSurface.get_rect()
def message_to_screen(msg, colour, xpos, ypos):
textSurf, textRect = text_objects(msg, colour)
textRect.center = (xpos), (ypos)
gameDisplay.blit(textSurf, textRect)
def gameLoop(FPS):
start = 0
from math import pi
gameExit = False
gameOver = False
num_top = 300
num_bot = 300
pygame.mouse.set_pos(display_width / 2, display_height / 2)
line_array =[]
line_thickness = 8
while not gameExit:
mouse = pygame.mouse.get_pos()
# print(mouse)
if (start == 0):
print("Game Started")
elif(mouse[0] <= 48) or (mouse[0] >= 547) or (mouse[1] <= 25) or (mouse[1] >=585):
gameOver = True
start += 1
if gameOver == True:
gameDisplay.fill(white)
message_to_screen("You Lost", red, 300, 300)
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_q:
gameExit = True
rand_nums = [randint(-3, 3), randint(-3, 3)]
num_top += rand_nums[0]
num_bot += rand_nums[1]
message_to_screen("Press q or the x button to quit", blue, 100, 40)
pygame.display.update()
gameDisplay.fill(white)
pygame.draw.arc(gameDisplay, red, [mouse[0]-48, mouse[1]-25, 100, 40], 0, pi, 3)
pygame.draw.line(gameDisplay, black, [num_top, 0], [num_bot, 600], line_thickness)
pygame.draw.arc(gameDisplay, red, [mouse[0]-48, mouse[1]-25, 100, 40], 3 * pi, 2 * pi, 3)
clock.tick(FPS)
pygame.quit()
quit()
gameLoop(100)
答案 0 :(得分:0)
我计算角度(参见图像上的红色和绿色角度)并进行比较。如果它们几乎相同则点在线 - 所以存在碰撞。
因为float
给出了不理想的结果所以我必须比较角度是否几乎相同。
if -0.01 < tanges_angle - tanges_angle_p1 < 0.01:
它可能需要比0.01
要计算第一个天使(绿色),我只需要黑线的底点和顶点。要计算第二个角度,我需要黑线的底点和圆圈上的点。
#!/usr/bin/env python3
import pygame
from random import randint
from math import pi
# --- constants --- (UPPER_CASE names)
WHITE = (255, 255, 255)
BLACK = ( 0, 0, 0)
RED = (255, 0, 0)
GREEN = ( 0, 255, 0)
BLUE = ( 0, 0, 255)
DISPLAY_WIDTH = 600
DISPLAY_HEIGHT = 600
CENTER_X = DISPLAY_WIDTH//2
CENTER_Y = DISPLAY_HEIGHT//2
FPS = 30
LINE_THICKNESS = 8
PI_2 = 2*pi
PI_3 = 3*pi
# --- functions --- (lower_cas names)
def render_text(text, colour):
image = font.render(text, True, colour)
rect = image.get_rect()
return image, rect
def message(screen, msg, colour, x, y):
image, rect = render_text(msg, colour)
rect.center = (x, y)
screen.blit(image, rect)
def gameloop():
num_top = 300
num_bot = 300
pygame.mouse.set_pos(CENTER_X, CENTER_Y)
start = True
game_exit = False
game_over = False
while not game_exit:
# - events -
for event in pygame.event.get():
if event.type == pygame.QUIT:
game_exit = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_q:
game_exit = True
# - updates -
m_x, m_y = pygame.mouse.get_pos()
if start:
print("Game Started")
start = False
elif (m_x <= 48) or (m_x >= 547) or (m_y <= 25) or (m_y >= 585):
game_over = True
if game_over == True:
screen.fill(WHITE)
message(screen, "You Lost", RED, 300, 300)
num_top += randint(-3, 3)
num_bot += randint(-3, 3)
# proportion
dx = num_bot - num_top
dy = DISPLAY_HEIGHT
tanges_angle = dx/dy
dx_p1 = num_bot - (m_x-48) # or smaller ie. m_x-46
dy_p1 = DISPLAY_HEIGHT - m_y
tanges_angle_p1 = dx_p1/dy_p1
if -0.01 < tanges_angle - tanges_angle_p1 < 0.01:
print('Collide left')
dx_p2 = num_bot - (m_x+48) # or smaller ie. m_x+46
dy_p2 = DISPLAY_HEIGHT - m_y
tanges_angle_p2 = dx_p2/dy_p2
if -0.01 < tanges_angle - tanges_angle_p2 < 0.01:
print('Collide right')
# - draws -
screen.fill(WHITE)
pygame.draw.arc(screen, RED, (m_x-48, m_y-25, 100, 40), 0, pi, 3)
pygame.draw.line(screen, BLACK, (num_top, 0), (num_bot, 600), LINE_THICKNESS)
pygame.draw.arc(screen, RED, (m_x-48, m_y-25, 100, 40), PI_3, PI_2, 3)
message(screen, "Press q or the x button to quit", BLUE, 100, 40)
pygame.display.update()
# - FPS -
clock.tick(FPS)
# - end -
pygame.quit()
quit()
# --- main ---
pygame.init()
screen = pygame.display.set_mode((DISPLAY_WIDTH, DISPLAY_HEIGHT))
pygame.display.set_caption("Wire")
font = pygame.font.SysFont("aerial", 20)
clock = pygame.time.Clock()
gameloop()
它使用基于od 拦截定理的比较dx/dy == dx_p1/dy_p1
,也称为Thales' theorem