pygame发现一个正方形是否在另一个正方形的200像素范围内

时间:2017-01-01 19:33:30

标签: python pygame collision-detection collision

我想知道我的敌人是否在防御塔的200像素范围内,以便我可以开始夺取敌人的生命。敌人正在移动,防御仍然是FYI。如果有人能给我建议怎么做这将是惊人的。如果我把我的代码放在一边,它会让每个人都感到困惑,因为我的代码非常混乱所以请给我一些关于如何做的建议谢谢。缺口。我已经添加了我的代码,因为我知道如果有人有时间阅读它并告诉我我做错了什么,那可能是错误的,这可能是我非常感激的事情。

import pygame
import math
from pygame.locals import *

def text():
    font = pygame.font.SysFont("monospace", 14)
    text = font.render("Start Round", True, black)
    textpos = text.get_rect()
    textpos.center = (790,675)
    Background.blit(text, textpos)

def newRound():
    pos = pygame.mouse.get_pos()
    click = pygame.mouse.get_pressed()
    if 730 < pos[0] < 850 and 650 < pos[1] < 800:
        pygame.draw.rect(Background, (150,150,150), (730,650,120,50))
        if click[0] == 1:
            startGame()        
    else:
        pygame.draw.rect(Background, (100,100,100), (730,650,120,50))

def startGame():
    global startRound, endRound, intro
    intro = 0
    createRound()
    intro = 1
    startRound = True
    endRound = False

def lifeText(lifes):
    font = pygame.font.SysFont("monospace", 20)
    text = font.render("Lives %s" % (lifes) , True, black)
    textpos = text.get_rect()
    textpos.center = (60,30)
    Background.blit(text, textpos)

def life(self):
    global hit, endRound, startRound, noEnemies, lifes
    if noEnemies == 0 and lifes > 0:
        startRound = False
        endRound = True

    if self.rect.x == 960:
        hit = hit + 1
        lifes = lifes - 1
        if lifes == 0:
            print("You have 0 lives Game Over")
            pygame.quit()
    if hit == 4:
        startRound = False
        endRound = True
        hit = 0
        noEnemies = noEnemies + 1


def createRound():
    global enemies, noEnemies

    enemies = []

    x = -40
    y = 210
    for e in range(noEnemies):
        x = x - 80
        enemies.append(yellowEnemy(x, y, Background))
    noEnemies = len(enemies)

def displayTower():
    for tower in towers:
        Background.blit(redtower, (tower))


class yellowEnemy(object):

    image1 = pygame.image.load("enemySpriteFullHealth.jpg")
    image2 = pygame.image.load("enemySpriteHalfHealth.jpg")
    image3 = pygame.image.load("enemySpriteDead.jpg")

    def __init__(self, x, y, Background):
        self.Background = Background
        self.Background_rect = Background.get_rect()
        self.rect = self.image1.get_rect()
        self.rect = self.image2.get_rect()
        self.rect = self.image3.get_rect()
        self.rect.x = x
        self.rect.y = y
        self.health = 20
        self.dist_x = 2
        self.dist_y = 0

    def update(self):
        self.rect.x += self.dist_x
        self.rect.y += self.dist_y

    def draw(self, Background):
        timeDead = 0
        if self.health > 9 and self.health < 21:
            Background.blit(self.image1, self.rect)
        elif self.health < 10 and self.health > 1:
            Background.blit(self.image2, self.rect)
        elif self.health < 1:
            Background.blit(self.image3, self.rect)
            self.dist_x = 0
        life(self)

pygame.init()

width = 960
height = 720

black = (0,0,0)
lifes = 10
hit = 0
intro = 1
FPS = 200
noEnemies = 4
bx = 1000
by = 1000
towers = []

endRound = True
startRound = False
clicked = False
mx, my = pygame.mouse.get_pos()
clock = pygame.time.Clock()

test= False
mapImg = pygame.image.load("mapimage.jpg")
redtower = pygame.image.load("redTower.jpg")

Background = pygame.display.set_mode((width, height))
Background_rect = Background.get_rect()

while intro == 1:
    mousePos = pygame.mouse.get_pos()
    mousePressed = pygame.mouse.get_pressed()
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()

        if 530 < mousePos[0] < 590 and 650 < mousePos[1] < 710:
            if mousePressed[0] == 1:
                clicked = True

        if clicked == True:
            mx, my = pygame.mouse.get_pos()
            pygame.display.update()
            bx = 30
            by = 30
            if mousePressed[0] == 0:
                clicked = False
                tx = mx - bx
                ty = my - by
                towerCords = tx, ty
                towers.append(towerCords)  

    if endRound == True:
        Background.blit(mapImg, (0,0))
        newRound()
        text()

    if startRound == True:
        for enemy in enemies:
            enemy.update()
        Background.blit(mapImg, (0,0))
        for enemy in enemies:
            enemy.draw(Background)

    Background.blit(redtower, (mx-bx, my-by))
    if clicked == True:
        pygame.draw.circle(Background, (220, 0, 0), (mx, my), 200, 4)
    displayTower()
    lifeText(lifes)
    Background.blit(redtower, (530,650))
    pygame.display.update()
    clock.tick(FPS)

3 个答案:

答案 0 :(得分:0)

如果他们是精灵,你可以简单地做:

import math

defense_rect = defense.get_rect()

if math.abs(enemy.rect.center - defense_rect.rect.center) <= 200:
    # *do something*

逻辑是从任何位置看敌人的中心距离防守中心200像素(因此math.abs()的使用是绝对值)。如果是,请用您的代码替换注释。为什么这样做? 检查here

答案 1 :(得分:0)

要查找2点之间的距离,您可以使用以下代码:

def get_dist(pos1,pos2):              
    return math.hypot(pos1[0] - pos2[0], pos1[1] - pos2[1])

这还要求您在程序开头import math

答案 2 :(得分:0)

Pygame有pygame.Rect()来保持对象的位置和大小。

位于200x200

点左上角的(0,0)
tower_rect = pygame.Rect(0,0, 300, 300)

或者您可以移动它以使(0,0)位于中心

tower_rect = pygame.Rect(0,0, 300, 300)
tower_rect.center = (0, 0)

检查其他Rect()是否完全在塔内

enemy_rect = pygame.Rect(10, 10, 50, 50)

if tower_rect.contains(enemy_rect):

或者如果它完全或仅部分在塔中(它与塔冷却)

if tower_rect.colliderect(enemy_rect):

您可以使用敌人列表进行事件测试

if tower_rect.collidelistall(list_of_enemies_rect):

或检查所有塔的敌人

if enemy_rect.collidelistall(list_of_towers_rect):