[英]Drawing line with infinity length in the direction of cursor in Pygame
我正在尋找有關pygame的幫助。 我正在用Python開發簡單的游戲來學習Pygame。 我想做一個可以旋轉並可以用激光線射擊的太空飛船。 我已經完成了箭頭鍵的控制,我們也可以用鼠標的位置旋轉飛船,但是拍攝時遇到了問題。 我想用從飛船位置到鼠標方向的無限長的線。 我該怎么做? 這是我的代碼:
def draw_objects(self):
SCREEN.fill(BLACK)
self.target = pygame.mouse.get_pos()
self.x = self.player.position[0] #player x position
self.y = self.player.position[1] #player y position
self.mx = self.target[0] #mouse x position
self.my = self.target[1] #mouse y position
self.slope=float(float(self.y-self.my)/float(self.x-self.mx+0.1)) #slope
self.x_new = DISPLAY_WIDTH #ray length
self.y_new = self.y + self.slope * (self.x_new - self.x)
self.player.draw()
self.draw_columns()
for agent in self.all_agents:
agent.draw()
agent.draw_vectors()
if self.player.shoot == True:
pygame.draw.line(SCREEN, GREEN, self.player.position,(self.x_new, self.y_new), 2)
pygame.display.update()
它工作不正常,因為它只能在飛船的右邊工作。 在其他情況下,它會向光標反射出一條線。
感謝您的幫助。
slope
不能保持方向。
您必須獲得player_x - mouse_x + 0.1
符號並與x_new
使用
dx = player_x - mouse_x + 0.1
reversed_sign_x = 1 if dx < 0 else -1
x_new = reversed_sign_x * DISPLAY_WIDTH
完整的工作示例:
。
import pygame
# --- constants ---
BLACK = (0, 0, 0)
GREEN = (0, 255, 0)
DISPLAY_WIDTH = 800
DISPLAY_HEIGHT = 600
# --- functions ---
def calculate(player_x, player_y, mouse_x, mouse_y):
dx = player_x - mouse_x + 0.1
dy = player_y - mouse_y
reversed_sign_x = 1 if dx < 0 else -1
#reversed_sign_y = 1 if dy < 0 else -1
slope = dy/dx
x_new = reversed_sign_x * DISPLAY_WIDTH
y_new = player_y + slope * (x_new - player_x)
return x_new, y_new
# --- main ---
# - init -
pygame.init()
SCREEN = pygame.display.set_mode((DISPLAY_WIDTH, DISPLAY_HEIGHT))
# - objects -
player_x = DISPLAY_WIDTH // 2
player_y = DISPLAY_HEIGHT // 2
mouse_x = player_x
mouse_y = player_y
x_new, y_new = calculate(player_x, player_y, mouse_x, mouse_y)
# - mainloop -
clock = pygame.time.Clock()
running = True
while running:
# - events -
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.MOUSEBUTTONDOWN:
player_x, player_y = event.pos
elif event.type == pygame.MOUSEMOTION:
x_new, y_new = calculate(player_x, player_y, event.pos[0], event.pos[1])
# - updates -
# empty
# - draws -
SCREEN.fill(BLACK)
pygame.draw.line(SCREEN, GREEN, (player_x, player_y), (x_new, y_new), 2)
pygame.display.flip()
# - FPS -
clock.tick(25)
# - end -
pygame.quit()
furas在右邊,您必須檢查鼠標是在播放器的左側還是右側,如果DISPLAY_WIDTH
在左側,則取反。 我來到了一個類似的解決方案:
def target_coords(position):
x, y = position # Unpack player position into x, y.
mx, my = pygame.mouse.get_pos() # Unpack mouse pos into mx, my.
slope = (y-my) / (x-mx+0.1)
# This is a conditional expression, similar to `if condition: ... `else: ... `.
x_new = DISPLAY_WIDTH if x < mx else -DISPLAY_WIDTH
y_new = y + slope * (x_new - x)
return x_new, y_new
請注意,此函數僅計算目標坐標並返回它們(函數最好只做一件事)。 畫線以及其他功能。
還有另一種解決方案:您可以使用pygame向量,然后首先將向量計算到目標,對其進行規范化並按所需的長度( DISPLAY_WIDTH
)進行縮放。
import pygame
from pygame.math import Vector2
pygame.init()
DISPLAY_WIDTH = 640
GREEN = pygame.Color('aquamarine1')
screen = pygame.display.set_mode((640, 480))
clock = pygame.time.Clock()
position = Vector2(300, 200) # A pygame.math.Vector2 as the position.
done = False
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
screen.fill((30, 30, 30))
pygame.draw.circle(screen, GREEN, (int(position.x), int(position.y)), 7)
# Calculate the vector to the target by subtracting pos from mouse pos.
# Normalizing it gives you a unit vector which you can scale
# by multiplying it with the DISPLAY_WIDTH.
target_vec = (pygame.mouse.get_pos()-position).normalize() * DISPLAY_WIDTH
pygame.draw.line(screen, GREEN, position, position+target_vec, 2)
pygame.display.flip()
clock.tick(30)
pygame.quit()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.