为什么碰撞检测功能不正常?

时间:2017-08-17 23:37:53

标签: python pygame

import random, pygame, sys, json, time, os
import colours as c
import xml.etree.ElementTree as ET

pygame.init()

with open('CONFIG.json') as config_file:
    CONFIG = json.load(config_file)

gameDisplay = pygame.display.set_mode((CONFIG['screen_resolution']))
pygame.display.set_caption('BEE RPG TYCOON')

pygame.display.update()


#Collisions


gameExit = False


x = 300
y = 300
x_change = 0
y_change = 0

clock = pygame.time.Clock()

class Spritesheet:
    #Loads an atlas image
    def __init__(self, imgFile, dataFile):
        self.spritesheet = pygame.image.load(imgFile).convert()
        if dataFile:
            tree = ET.parse(dataFile)
            self.map = {}
            for node in tree.iter():
                if node.attrib.get('name'):
                    name = node.attrib.get('name')
                    self.map[name]={}
                    self.map[name]['x'] = int(node.attrib.get('x'))
                    self.map[name]['y'] = int(node.attrib.get('y'))
                    self.map[name]['width'] = int(node.attrib.get('width'))
                    self.map[name]['height'] = int(node.attrib.get('height'))
    def getImageRect(self, x, y, w, h):
        return self.spritesheet.subsurface(pygame.Rect(x,y,w,h))


    def getImageName(self, name):
        rect = pygame.Rect(self.map[name]['x'], self.map[name]['y'],
            self.map[name]['width'], self.map[name]['height'])

        return self.spritesheet.subsurface(rect)

#Spritesg
sheet = Spritesheet("walkRight.png", "charSprite.xml")


class player():
    def __init__(self, x, y, sprite, width, height):
        self.x=x
        self.y=y
        self.sprite = sprite
        self.sprite.set_colorkey(c.green)
        self.width = width
        self.height = height
        self.rect = self.sprite.get_rect()


player = player(300, 300, sheet.getImageName("walkRightIdle.png"), 20, 22)

class enemy():

    def __init__(self,x,y,bx,by,sprite,movement,trackRad, lock, movRange,mv,width,height):
        #Basic Properties
        self.x=x
        self.y=y
        self.bx=bx
        self.by=by
        self.sprite = sprite
        self.width = width
        self.height = height
        self.rect = self.sprite.get_rect()
        #Artificial Intelligence
        self.movement = movement #How far it moves per frame.
        self.trackRad = trackRad #The radius in which the enemy can move
        self.lock = lock #Locks the enemy into a pattern
        self.movRange = movRange #When lock = 1 this determines how far it can go from it's base position, when lock = 2 this determines how far it goes in a square
        self.mv = mv #The Random generator that decides which direction it moves.
        #Lock Mechanics
        #0 - The enemy goes anywhere randomly (Looks janky)
        #1 - The enemy goes anywhere randomly, but if it leaves it's movRange it goes back (also looks janky)
        #2 - The enemy patrols in a square
        #3 - The enemy chases the player
        #4 - The enemy patrols and chases the player

basicEnemy = enemy(310,310,310,310, sheet.getImageName("walkRightIdleE.png"),5,10,1,50,random.randint(0,3), 20,22)
basicEnemy1 = enemy(250,250,250,250, sheet.getImageName("walkRightIdleE.png"),5,10,0,0,random.randint(0,3), 20 ,22)
basicEnemy2 = enemy(100,100,100,100, sheet.getImageName("walkRightIdleE.png"),5,10,2,2,random.randint(0,3),20,22)


class hive():

    def __init__(self, x, y, sprite):

        self.x = x
        self.y = y
        self.sprite = sprite

mv = random.randint(0,3)
def enemyAi(enemy, player):
    enemy.mv = random.randint(0,50)
    #Collisions
    if enemy.rect.colliderect(player.rect):
        print("stopped")
    elif enemy.lock == 0:
        if enemy.mv == 0:
            enemy.x = enemy.x + enemy.movement
        elif enemy.mv == 1:
            enemy.y = enemy.y + enemy.movement
        elif enemy.mv == 2:
            enemy.x = enemy.x - enemy.movement
        elif enemy.mv == 3:
            enemy.y = enemy.y - enemy.movement
        else:
            print("Nothing")
    elif enemy.lock == 1:
        if enemy.mv == 0:
            if enemy.x > enemy.bx + enemy.movRange:
                    enemy.x = enemy.x - enemy.movement
            else:
                enemy.x = enemy.x + enemy.movement
        elif enemy.mv == 1:
            if enemy.y > enemy.by + enemy.movRange:
                    enemy.y = enemy.y - enemy.movement
            else:
                enemy.y = enemy.y + enemy.movement
        elif enemy.mv == 2:
            if enemy.x < enemy.bx - enemy.movement:
                enemy.x = enemy.x - enemy.movement
            else:
                enemy.x = enemy.x - enemy.movement
        elif enemy.mv == 3:
            if enemy.y < enemy.by - enemy.movRange:
                enemy.y = enemy.y + enemy.movement
            else:
                enemy.y = enemy.y - enemy.movement
    elif enemy.lock == 2:
        enemy.x = enemy.x + enemy.movement
        enemy.y = enemy.y + enemy.movement
        enemy.x = enemy.x - enemy.movement
        enemy.y = enemy.y - enemy.movement











hive1 = hive(250, 300, "hive.png")

spriteAnim = 0
player.sprite = sheet.getImageName("walkRightIdle.png")
while not gameExit: # Game loop
    enemyAi(basicEnemy, player)
    enemyAi(basicEnemy1,player)
    enemyAi(basicEnemy2,player)
    for event in pygame.event.get(): #Event handling
        if event.type == pygame.QUIT: #Game closes when cross is X ye
            gameExit = True # Ends the loop
        #Movement
        #print(event)

        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                if spriteAnim == 0:
                    player.sprite = sheet.getImageName("walkLeft1.png")
                else:
                    player.sprite = sheet.getImageName("walkLeft2.png")
                    spriteAnim = 0
                x_change += -5

            if event.key == pygame.K_RIGHT:
                player.sprite = sheet.getImageName("walkRight1.png")
                x_change += 5
                player.sprite = sheet.getImageName("walkRight2.png")
            if event.key == pygame.K_UP:
                player.sprite = sheet.getImageName("walkUp1.png")
                y_change += -5
                player.sprite = sheet.getImageName("walkUp2.png")
            if event.key == pygame.K_DOWN:
                player.sprite = sheet.getImageName("walkDown1.png")
                y_change += 5
                player.sprite = sheet.getImageName("walkDown2.png")
        if event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT:
                x_change = 0
                player.sprite = sheet.getImageName("walkLeftIdle.png")
            if event.key == pygame.K_RIGHT:
                x_change = 0
                player.sprite = sheet.getImageName("walkRightIdle.png")
            if event.key == pygame.K_UP:
                y_change = 0
                player.sprite = sheet.getImageName("walkUpIdle.png")
            if event.key == pygame.K_DOWN:
                player.sprite = sheet.getImageName("walkDownIdle.png")
                y_change = 0




    hiveSprite = pygame.image.load(hive1.sprite)

    player.x += x_change
    player.y += y_change

    zone = pygame.image.load("Untitled.png")

    gameDisplay.fill(c.white)
    gameDisplay.blit(zone, (310, 310))
    gameDisplay.blit(player.sprite, (player.x, player.y))
    gameDisplay.blit(basicEnemy.sprite,(basicEnemy.x, basicEnemy.y))
    gameDisplay.blit(basicEnemy1.sprite,(basicEnemy1.x, basicEnemy1.y))
    gameDisplay.blit(basicEnemy2.sprite,(basicEnemy2.x, basicEnemy2.y))
    pygame.display.update()


    clock.tick(int(CONFIG['framesPerSecond']))

















#Code Goes Here

pygame.quit()
quit()

我最近添加了代码:

if enemy.rect.colliderect(player.rect):

到我的程序,它会导致所有敌人精灵在游戏加载时冻结,而不是当他们触摸玩家精灵时,我不知道为什么这样做以及任何阻止它并使其正常工作的方法(非常感谢,只有当被另一个精灵接触时停止,我可以提供xml和json文件,但我怀疑它们会不会。

先谢谢。

1 个答案:

答案 0 :(得分:1)

如果碰撞检测出现问题,请打印所有相关对象的部分。如果你这样做,你很快就会发现所有的位置都在同一个位置(0,0),因此它们会在游戏开始后立即发生碰撞。

您必须在班级中设置rects的位置:

self.rect.topleft = (self.x, self.y)
# Or
self.rect.x = self.x
self.rect.y = self.y
# Or
self.rect = self.sprite.get_rect(topleft=(self.x, self.y))

您还可以使用self.rect.center或其他属性。

另外,不要忘记在主循环中移动物体的部分,否则它们将保持在相同的起始位置。在您的情况下,您只需将topleft设置为enemy.x.y(或者只删除x和y属性并直接更新rect.xrect.y) :

enemy.rect.topleft = (enemy.x, enemy.y)