2017-06-09 38 views
1

マウスのクリックで矢印を発射しようとしていますが、マウスの方向に向かっています。私は射撃部分を達成しましたが、私はそれをマウスに向かって撃つことはできません。私は下に私のコードを記載して、本当にすべての助けに感謝!マウスの方向に矢を撃つ方法は?

矢印撮影に関連するコードの一部は次のとおりです。

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) 

答えて

1

、発射の速度を計算angleを取り、使用するにはx速度の場合はmath.cos、y速度の場合はmath.sinとし、任意の数を掛けて希望の速度に合わせます。発射体の位置と速度をリストまたは他のデータ構造体に格納する(私は発射体のクラスを作成することを推奨する)、この発射体リストを短剣リストに追加し、whileループでは短剣を反復して位置を更新する速度を加える。

いくつかのより多くのノート:

  • 代わりに57.29を掛けることのmath.degreesを呼び出し、度に角度を変換します。これにより、コードが読みやすくなります。

  • for shot in daggersループでpygame.display.update()を呼び出しないでください。フレームごとに1回のみ呼び出される必要があります。

  • 繰り返し処理中にリストやその他の繰り返し可能プログラムを変更しないと、予期しない結果が発生します。フィルタリングされた新しいリストを作成します。

  • pygame.time.Clockを使用してフレームレートを制限します。

  • また、012gの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) 
dxPlayer = 0 
dyPlayer = 0 
angle = 0 
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: 
       dxPlayer -= 5 
      elif event.key == pg.K_RIGHT: 
       dxPlayer += 5 
      elif event.key == pg.K_UP: 
       dyPlayer -= 5 
      elif event.key == pg.K_DOWN: 
       dyPlayer += 5 
     elif event.type == pg.KEYUP: 
      if event.key == pg.K_LEFT or event.key == pg.K_RIGHT: 
       dxPlayer = 0 
      elif event.key == pg.K_UP or event.key == pg.K_DOWN: 
       dyPlayer = 0 
     elif event.type == pg.MOUSEBUTTONDOWN: 
      # Velocity scaled by 3 arbitrarily to adjust the speed. 
      vel_x = math.cos(angle) * 3 
      vel_y = math.sin(angle) * 3 
      dagger_img = pg.transform.rotate(DAGGER_IMG, -math.degrees(angle)) 
      width, height = dagger_img.get_size() 
      # Shots consist of position, velocity and rotated image. 
      daggers.append([[player.centerx-width/2, player.centery-height/2], 
          [vel_x, vel_y], dagger_img]) 

    # Update the game. 
    player.x += dxPlayer 
    player.y += dyPlayer 
    # Rotate player toward mouse. 
    mousePosition = pg.mouse.get_pos() 
    rise = mousePosition[1] - player.centery 
    run = mousePosition[0] - player.centerx 
    angle = math.atan2(rise, run) 
    playerRotate = pg.transform.rotate(PLAYER_IMG, -math.degrees(angle)) 
    player = playerRotate.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])] 

    # Update the daggers. 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(playerRotate, player) 

    for shot in daggers: 
     x, y = shot[0] 
     screen.blit(shot[2], shot[0]) 

    pg.display.update() 
    clock.tick(30) # Limit frame rate to 30 fps. 
+0

私は私の元のコードにこれを組み込むしかしとき、どうもありがとうございました。戻りショット[0] <-40またはショット[0]> 900またはショット[1] <-40またはショット[1]> 600 TypeError: 'float 'オブジェクトはサブスクリプトではありません' – Student

+0

つまり、浮動小数点を 'outOfBounds'関数に渡していますが、' shot [0] 'のような角括弧を使うことができるように、サブスクリプト化可能なタプルやリストが必要です。関数内のshot [0] 'はx座標で、' shot [1] 'はy座標です。変数out_of_bounds内の変数/パラメータ名を編集して明確にします。 – skrx

関連する問題