I'm searching for some help with pygame. I'm developing simple game in Python to learn 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.
You have to get sign of player_x - mouse_x + 0.1
and use with 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:
.
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. 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
).
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()
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.