PyGame Collsion麻烦

时间:2017-01-29 02:08:51

标签: python pygame

我正在尝试建立一个基于不接触电线的小游戏(你必须在电线/线周围操纵一个圆圈)。我不太清楚从哪里开始编程导线和圆边缘之间的碰撞,因为导线随机移动。我是否必须创建一个存储该行所有坐标的列表? 这是代码:

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)

1 个答案:

答案 0 :(得分:0)

我计算角度(参见图像上的红色和绿色角度)并进行比较。如果它们几乎相同则点在线 - 所以存在碰撞。

因为float给出了不理想的结果所以我必须比较角度是否几乎相同。

if -0.01 < tanges_angle - tanges_angle_p1 < 0.01:

它可能需要比0.01

更小或更大的值

要计算第一个天使(绿色),我只需要黑线的底点和顶点。要计算第二个角度,我需要黑线的底点和圆圈上的点。

enter image description here

#!/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