Search code examples
pythonpygamecollision-detectioncollision

pygame finding out if a square is within 200 pixels of another square


I want to know if my enemy is within 200 pixels of a defense tower so that I can start taking lives of the enemy. The enemy is moving and the defense is still FYI. if anyone can give me advice on how to do this that would be amazing. If I put my code up it will just confuse everyone because my code is very messy so just give me advice on how to do it thanks. Nick. I have added my code because I know I have done something wrong if anyone has the time to read through it and tell me what I am doing wrong which is probably everything that would be much appreciated.

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)

Solution

  • To find the distance between 2 points, you can use this code:

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

    This also requires you to import math at the beginning of your program.