我试图在鼠标点击时射箭,但是在鼠标的方向上。我已经完成了拍摄部分,但是我无法向鼠标拍摄。我在下面列出了我的代码,我非常感谢所有的帮助!
与箭头射击相关的代码部分是:
for shot in daggers:
index = 0
shotx = math.cos(shot[0])*35
shoty = math.sin(shot[0])*35
shot[1] += shotx
shot[1] += shoty
if shot[1] < -40 or shot[1] > 900 or shot[1] < -40 or shot[1]> 600:
daggers.pop(index)
index =+ 1
for shoot in daggers:
daggerOne = pygame.transform.rotate(daggerPlayer, 360 - shoot[0]*57.29)
screen.blit(daggerOne, (shoot[1], shoot[1]))
pygame.display.update()
编辑 - 整个代码:
#Import the necessary modules
import pygame
import sys
import os
import math
#Initialize pygame
pygame.init()
# Set the size for the surface (screen)
screenSize = (900,600)
screen = pygame.display.set_mode((screenSize),0)
# Set the caption for the screen
pygame.display.set_caption("Neverland")
#Define Colours
WHITE = (255,255,255)
BLUE = (0,0,255)
BLACK = (0,0,0)
GRAY = (128, 128, 128)
MAROON = (128, 0, 0)
NAVYBLUE = (0, 0, 128)
OLIVE = (128, 128, 0)
PURPLE = (128, 0, 128)
TEAL = (0,128,128)
PINK = (226,132,164)
MUTEDBLUE = (155,182,203)
PLUM = (221,160,221)
#Clock Setup
clock = pygame.time.Clock()
#Load Images
peterPlayer = pygame.image.load('pixelPirateOne.png')
nightBackground = pygame.image.load ('skyTwo_1.png')
daggerPlayer = pygame.image.load('daggerPlayer.png')
#Settting Variables for Moving Character
xPlayer = 200
yPlayer = 275
dxPlayer = 0
dyPlayer = 0
playerPosition = (200,275)
accuracyShot = [0,0]
daggers = []
angle = 0
def quitGame():
pygame.quit()
sys.exit()
def outOfBounds(shot):
return shot[0] < -40 or shot[0] > 900 or shot[1] < -40 or shot[1] > 600
go = True
while go:
#Quit Game
for event in pygame.event.get():
if event.type == pygame.QUIT:
quitGame()
#Move Player
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
dxPlayer -= 25
elif event.key == pygame.K_RIGHT:
dxPlayer += 25
elif event.key == pygame.K_UP:
dyPlayer -= 25
elif event.key == pygame.K_DOWN:
dyPlayer += 25
elif event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
dxPlayer = 0
elif event.key == pygame.K_UP or event.key == pygame.K_DOWN:
dyPlayer = 0
elif event.type == pygame.MOUSEBUTTONDOWN:
mousePosition = pygame.mouse.get_pos()
velx = math.cos(angle)*6
vely = math.sin(angle)*6
daggers.append([math.atan2(mousePosition[1]-(playerPositionNew[1]+32), mousePosition[0]-(playerPositionNew[0]+26)), playerPositionNew[1]+32])
#Update move player
xPlayer = xPlayer + dxPlayer
yPlayer = yPlayer + dyPlayer
pygame.display.update()
#Learned about atan2 from --> https://docs.python.org/2/library/math.html
#Allows To Rotate Player With Mouse
mousePosition = pygame.mouse.get_pos()
angle = math.atan2(mousePosition[1]-(yPlayer+32),mousePosition[0]-(xPlayer+26))
playerRotate = pygame.transform.rotate(peterPlayer, 360-angle*57.29)
playerPositionNew = (xPlayer-playerRotate.get_rect().width/2, yPlayer-playerRotate.get_rect().height/2)
pygame.display.update()
#Learned about cos and sin in python from --> https://docs.python.org/2/library/math.html
#Learned about .pop from --> https://docs.python.org/2/tutorial/datastructures.html
#Draw daggers to screen
filtered_daggers = []
for shot in daggers:
if not outOfBounds(shot[0]):
filtered_daggers.append(shot)
daggers = filtered_daggers
for shot in daggers:
shot[0][0] += shot[1][0]
shot[0][1] += shot[1][1]
screen.blit(nightBackground, (0,0))
screen.blit(playerRotate, playerPositionNew)
for shot in daggers:
x, y = shot[0]
screen.blit(daggerPlayer, (shot[2], shot[0]))
pygame.display.update()
clock.tick(30)
答案 0 :(得分:1)
要计算射弹的速度,请使用math.cos
并使用math.sin
作为x速度,使用math.degrees
作为y速度,通过相乘将其缩放到所需的速度他们有一个任意数字。
将射弹的位置和速度存储在列表或其他数据结构中(我建议为射弹创建一个类),将此射弹列表附加到你的匕首列表中并在while循环中迭代匕首以更新通过增加速度来定位。
更多说明:
要将角度转换为度数,请调用pygame.display.update()
,而不是将其乘以57.29。这使代码更具可读性。
请勿在{{1}}循环中调用for shot in daggers
。它应该每帧只调用一次。
在迭代它时,永远不要修改列表(或其他迭代),否则会得到意想不到的结果。而是建立一个新的过滤列表。
使用pygame.time.Clock
限制帧速率。
再次I recommend using vectors,pygame精灵和精灵组,因为它们有助于使您的代码更清晰,更易于阅读。
import sys
import math
import pygame as pg
def out_of_bounds(position):
"""Check if the position of a projectile is out of bounds.
Args:
position (list): The coordinates of the projectile.
Returns:
bool: True if out of bounds, False if not.
"""
x, y = position # You can unpack a list or tuple like so.
return x < -40 or x > 500 or y < -40 or y > 400
pg.init()
screen = pg.display.set_mode((640, 480))
PLAYER_IMG = pg.Surface((50, 30), pg.SRCALPHA)
pg.draw.polygon(PLAYER_IMG, (30, 150, 90), ((0, 0), (50, 15), (0, 30)))
DAGGER_IMG = pg.Surface((30, 20), pg.SRCALPHA)
pg.draw.polygon(DAGGER_IMG, (190, 150, 90), ((0, 0), (30, 10), (0, 20)))
# Player variables. I store the position in a rect.
player = pg.Rect(200, 275, 50, 30)
velocity_x = 0 # The x-speed of the player.
velocity_y = 0 # The y-speed of the player.
angle = 0
# In this list I'll store the data for the projectiles,
# i.e. lists of the positions and the velocities.
daggers = []
clock = pg.time.Clock() # Use a clock to limit the frame rate.
while True:
for event in pg.event.get():
if event.type == pg.QUIT:
pg.quit()
sys.exit()
# Move the player.
elif event.type == pg.KEYDOWN:
if event.key == pg.K_LEFT:
velocity_x -= 5
elif event.key == pg.K_RIGHT:
velocity_x += 5
elif event.key == pg.K_UP:
velocity_y -= 5
elif event.key == pg.K_DOWN:
velocity_y += 5
elif event.type == pg.KEYUP:
if event.key == pg.K_LEFT or event.key == pg.K_RIGHT:
velocity_x = 0
elif event.key == pg.K_UP or event.key == pg.K_DOWN:
velocity_y = 0
# Here I create the projectiles and add them to the daggers list.
elif event.type == pg.MOUSEBUTTONDOWN:
# Use sine and cosine to get the velocity of the projectile.
# To make it move faster, you need to scale the velocity
# (i.e. multiply it by a number).
vel_x = math.cos(angle) * 3
vel_y = math.sin(angle) * 3
# Now rotate the original image by the negative angle (because
# pygame's y-axis is flipped).
dagger_img = pg.transform.rotate(DAGGER_IMG, -math.degrees(angle))
width, height = dagger_img.get_size()
# The projectile data consists of position, velocity and the
# rotated image. -width/2 and -height/2 to center them.
daggers.append(
[[player.centerx-width/2, player.centery-height/2], # Pos
[vel_x, vel_y], # Velocity
dagger_img # Image
])
# Update the game.
# Move the player by adding the velocity to the x- and y-coords
# of the player rect.
player.x += velocity_x
player.y += velocity_y
# Rotate player toward the mouse.
mouse_position = pg.mouse.get_pos()
# Distances to the mouse position.
rise = mouse_position[1] - player.centery
run = mouse_position[0] - player.centerx
angle = math.atan2(rise, run) # atan2 gives you the angle to the target.
# Rotate the player image.
player_rotated = pg.transform.rotate(PLAYER_IMG, -math.degrees(angle))
player = player_rotated.get_rect(center=player.center)
# Filter the daggers list.
filtered_daggers = []
for shot in daggers:
if not out_of_bounds(shot[0]):
filtered_daggers.append(shot)
daggers = filtered_daggers
# The 5 lines above can be reduced to this list comprehension.
# daggers = [shot for shot in daggers if not out_of_bounds(shot[0])]
# Move the daggers by adding the velocity to the position.
# shot[0] is the pos, shot[1] the velocity.
for shot in daggers:
shot[0][0] += shot[1][0]
shot[0][1] += shot[1][1]
# Draw everything.
screen.fill((30, 40, 50))
screen.blit(player_rotated, player)
# Blit the projectiles in a for loop.
for shot in daggers:
screen.blit(shot[2], shot[0])
pg.display.update()
clock.tick(30) # Limit frame rate to 30 fps.