简体   繁体   English

在Pygame中以光标方向绘制无限长的线

[英]Drawing line with infinity length in the direction of cursor in Pygame

I'm searching for some help with pygame. 我正在寻找有关pygame的帮助。 I'm developing simple game in Python to learn Pygame. 我正在用Python开发简单的游戏来学习Pygame。 I want to make spaceship which we can rotate and we can shooting with laser line. 我想做一个可以旋转并可以用激光线射击的太空飞船。 I have done controlling by arrow keys, we can also rotating spaceship with mouse position, but I've got a problem with shooting. 我已经完成了箭头键的控制,我们也可以用鼠标的位置旋转飞船,但是拍摄时遇到了问题。 I want to make a line with infinity length from spaceship position to mouse direction. 我想用从飞船位置到鼠标方向的无限长的线。 How I can do that? 我该怎么做? Here is my code: 这是我的代码:

  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()

在此处输入图片说明

It's not working properly, because it's work only to the right of spaceship. 它工作不正常,因为它只能在飞船的右边工作。 In other cases it draws a line in reflection to cursor. 在其他情况下,它会向光标反射出一条线。

在此处输入图片说明

I will be grateful for your help. 感谢您的帮助。

slope doesn't keep direction. slope不能保持方向。
You have to get sign of player_x - mouse_x + 0.1 and use with x_new 您必须获得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

Full working example: 完整的工作示例:

  • move mouse to move line, 移动鼠标移动线,
  • click left button to set player new position. 单击左按钮设置玩家新位置。

.

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 is right, you have to check whether the mouse is on the left or right side of the player and negate the DISPLAY_WIDTH if it's on the left. furas在右边,您必须检查鼠标是在播放器的左侧还是右侧,如果DISPLAY_WIDTH在左侧,则取反。 I came to a similar solution: 我来到了一个类似的解决方案:

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

Note that this function only computes the target coordinates and returns them (functions should preferably do only one thing). 请注意,此函数仅计算目标坐标并返回它们(函数最好只做一件事)。 Draw the line and everything else in another function. 画线以及其他功能。

There's also an alternative solution: You could use pygame vectors and first calculate the vector to the target, normalize it and scale it by the desired length (the DISPLAY_WIDTH ). 还有另一种解决方案:您可以使用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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM