I am attempting to shoot an arrow on mouse click, however in the direction of the mouse. I've accomplished the shooting part, however I am not able to have it shoot towards the mouse. I've listed my code below and I really appreciate all help!
The portion of the code which is relevant to the arrow shooting is:
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()
EDIT- Entire Code:
#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)
To calculate the velocity of the projectiles, take the
angle
and usemath.cos
for the x-velocity andmath.sin
for the y-velocity, scale them to the desired speed by multiplying them with an arbitrary number.Store the position and the velocity of the projectile in a list or other data structure (I recommend creating a class for the projectiles), append this projectile list to your daggers list and in the while loop iterate over the daggers to update the positions by adding the velocities.
Some more notes:
To convert the angle to degrees, call
math.degrees
instead of multiplying it by 57.29. This makes the code more readable.Don't call
pygame.display.update()
in thefor shot in daggers
loop. It should be called only once per frame.Never modify a list (or other iterables) while you're iterating over it or you'll get unexpected results. Build a new filtered list instead.
Use a
pygame.time.Clock
to limit the frame rate.And again I recommend using vectors, pygame sprites and sprite groups, since they'll help to make your code cleaner and easier to read.