2016-10-19 14 views
0

私はufoとミサイルの画像を持っています。私はミサイルがufoに当たって両方とも爆発して消滅し、その後数秒後にもう一度ufoが復活するが、衝突コードは機能していない場所に到達しようとしている。誰かがコードを動作させる方法を私に説明することができますか?2つのスプライトの衝突 - Python 3.5.2

pygame.display.init() 
pygame.font.init() 
screen = pygame.display.set_mode((800, 600)) 
clock = pygame.time.Clock() 
ufo = pygame.image.load("ufo.png") 
rocket = pygame.image.load("rocket.png") 
done = False 
debug = False 
fontObj = pygame.font.SysFont("Courier New", 20) 

#Making my Empty Lists 
missiles = [] #[x,y] 
ufo_list = [] #[x,y,hspeed] 
particle_list = [] 

#UFO Respawn Info 
ufoRespawn = True 
ufoHits = 0 
ufoSpawnTimer = 0.0 
ufoSpeed = 500.0 

#MISSILE Info 
launchX = 400 
launchY = 550 
missileSpeed = 100.0 
missileDirection = 0 

#creating the Starfield 
myStars = []   # An (initially) empty list 
for i in range(1000): 
    x = random.randint(0, 800) 
    y = random.randint(0, 600) 
    newStar = [x, y] # A 2-element list 
    myStars.append(newStar) 
starSpeed = 100.0  # Rate of star movement (px/s) 
starDirection = 0  # 0 = not moving, -1 = left, +1 = right 

#input 
while not done: 
    event = pygame.event.poll() 
    if event.type == pygame.QUIT: 
     done = True 

    keys = pygame.key.get_pressed() 
    if keys[pygame.K_ESCAPE]: 
     done = True 

    if event.type == pygame.KEYDOWN: 
     if event.key == pygame.K_d: 
      debug = not debug 


    dt = clock.tick() /1000.0 

#the missile range (making it disappear after it hits the top) 
    for missile in missiles: 
     missile[1] -= missileSpeed * dt 
     if missile[1] < 0: missiles.remove(missle) 


#triangle following mouse position 
    mx, my = pygame.mouse.get_pos() 
    if mx > launchX: 
     launchX += .3 
    if mx < launchX: 
     launchX -= .3 


#bullets firing when pressing with mouse 
    mbuttons = pygame.mouse.get_pressed() 
    if mbuttons [0]: 
     x = launchX 
     y = launchY 
     newMissiles = [x,y] 
     missiles.append(newMissiles) 

#Creating the UFOs 
    ufoSpawnTimer -= dt 
    if ufoSpawnTimer <= 0: 
     if random.choice (("head", "tail")) == "head": 
      x = 0 
      hspeed = random.randint (10,50) 
     else: 
      x = 800 
      hspeed = random.randint (-50, -10) 
     y = random.randint (0,300) 
     new_ufo = [x,y,hspeed] 
     ufo_list.append(new_ufo) 
     ufoSpawnTimer = 5.0 


#Moving the Starfield 
    for i in range(len(myStars)): 
     myStars[i][0] += starSpeed * dt * starDirection 
     if myStars[i][0] < 0:  myStars[i][0] = 800 
     if myStars[i][0] > 800:  myStars[i][0] = 0 



    screen.fill ((0,0,0)) 
#drawing the triangle a.k.a missle launcher :D 
    pygame.draw.polygon(screen, (255,255,255), [[launchX, launchY], [launchX + 10, launchY + 10], \ 
         [launchX - 10, launchY + 10]], 3) 

    for missile in missiles: 
     x = int(missile[0]) 
     y = int(missile[1]) 
     screen.blit(rocket, (x,y)) 


    #drawing the ufo 
    for v in ufo_list: 
     v[0] += v[2] * dt 
     screen.blit(ufo,(v[0],v[1])) 


    #Missle distance from UFO - NEED HELP ON THIS PORTION 
    #Hit Detection 
    missileDist = ((x - v[0]) ** 2 + (y - v[1]) ** 2) ** 0.5 
    if **????** : 
     ufoRespawn = True 
     ufoHits += 10 

    #drawing th starfield 
    for star in myStars: 
     x = int(star[0]) 
     y = int(star[1]) 
     pygame.draw.circle(screen, (255,255,255), (x,y), 2) 



    pygame.display.flip() 
pygame.font.quit() 
pygame.display.quit() 

答えて

2

はよく衝突を検出するためのさまざまな方法があります、そして、それはそうでしょう図書館を見て価値があるかもしれないが、はるかに最も簡単な方法は、pygame.sprite.spritecollide()を使用することです。

しかし、私はこの関数の使い方を示す前に、pygame.sprite.Group()が何で、スプライトクラスが何であるかを知る必要があります。

基本的には、pygame.sprite.Group()とは何ですか、複数のスプライトを追跡して保持する方法です。あなたのケースでは、あなたのミサイルのミサイルグループを最善の選択にするようです。

私はあなたのミサイルを保持するグループを作成します: missiles_group = pygame.sprite.Group()。グループにミサイルを追加するには、missiles_group.add(<sprite instance name>)と言ってください。

スプライトクラスについては、私が質問に与えたこの回答をご覧ください。簡潔にするために、Spriteクラスはスプライトを作成するモジュール式の方法です。スプライトクラスは、単純なイメージを使用する代わりに、スプライトの必要なメソッドと属性を保持します。下の例ではスプライトクラスを使用しますので、詳細が必要な場合は上記のリンク先の答えをお読みください。


このように、あまりにも詳細には触れることなく、上記の関数に各関数パラメータを入力する方法は次のとおりです。

  • sprite:これは、スプライト
  • groupの群に対して試験するスプライトである:これは、スプライトでテストするために使用される基です。
  • dokill:これはブール値です。 trueに設定すると、パラメータがgroupパラメータのパラメータと衝突するたびに、groupパラメータのオブジェクトが削除されます。また、dokill引数がfalseに設定されている場合は逆も同様です。 これは関数がとるもう1つのパラメータですが、何をしようとしているのかは必要ありません。

上記の情報を組み込んだ例を示します。この例では、スプライトとスプライトのリストを作成します。

import pygame #import the pygame module into the namespace <module> 

WIDTH = 640 # define a constant width for our window 
HEIGHT = 480 # define a constant height for our window 

#create a pygame window, and 
#initialize it with our WIDTH and HEIGHT constants 
display = pygame.display.set_mode((WIDTH, HEIGHT)) 
clock = pygame.time.Clock() # create a game clock 

class Sprite(pygame.sprite.Sprite): 
    def __init__(self): 
     pygame.sprite.Sprite.__init__(self) 
     self.image = pygame.Surface((20, 20)) 
     self.image.fill((255, 0, 0)) 
     self.rect = self.image.get_rect() 
     self.rect.x = WIDTH/2 
     self.rect.y = HEIGHT/2 
     self.vx = 0 
     self.vy = 0 

    def update(self): 
     self.vx = 0 
     self.vy = 0 
     key = pygame.key.get_pressed() 
     if key[pygame.K_LEFT]: 
      self.vx = -1 
     elif key[pygame.K_RIGHT]: 
      self.vx = 1 
     if key[pygame.K_UP]: 
      self.vy = -1 
     elif key[pygame.K_DOWN]: 
      self.vy = 1 
     self.rect.x += self.vx 
     self.rect.y += self.vy 

# cretae a player sprite 
player = Sprite() 

# create a group to hold all of our sprites 
sprites = pygame.sprite.Group() 

# create a group to hold sprites we want to 
# test collions against. These sprites will 
# still be added to the sprites list 
# but we need a seperate group to test for 
# collisions against 
collision_sprites = pygame.sprite.Group() 

# add a sprite to out collison sprite group 
# We also add the sprite to our sprites group 
# that holds all sprites 
tmp = Sprite() 
tmp.update = lambda: None 
sprites.add(tmp) 
collision_sprites.add(tmp) 

# add a player sprites to the player group 
player.rect.x = 10 
sprites.add(player) 


running = True # our variable for controlling our game loop 
while running: 
    for e in pygame.event.get(): # iterate ofver all the events pygame is tracking 
     clock.tick(60) # make our clock keep pour game at 60 FPS 
     if e.type == pygame.QUIT: # is the user trying to close the window? 
      running = False # if so break the loop 
      pygame.quit() # quit the pygame module 
      quit() # quit is for IDLE friendliness 

    sprites.update() 

    # here is where we test for collision 
    if pygame.sprite.spritecollide(player, collision_sprites, False): 
     print("HIT!") 

    display.fill((180, 180, 180)) # fill the pygame screen with white 
    sprites.draw(display) 
    pygame.display.flip() # update the screen 

私の例でかなり大きい場合は、慎重にそれを介してあなたの時間と歩を踏み出す:スプライトがグループからのスプライトと衝突するたびに、HITが画面に出力されます。私はできるだけ多くの良いコメントを追加しようとしました。がんばろう!

+1

@Allison [Sprites](http://www.pygame.org/docs/ref/sprite.html)を使いたくない場合でも、少なくとも[pygame.Rect()](http: //www.pygame.org/docs/ref/rect.html)と 'pygame.Rect.colliderect()' – furas

+1

@furasええ、彼はできると思います。しかし、彼はすでに画像を読み込んでいたので、私はSpritesを使うかもしれないと考えました。 –

+0

はい、遅かれ早かれOPはスプライトを学ばなくてはなりません - あなたの例では今すぐOPを開始できます。 – furas

関連する問題