首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >敌人AI碰撞检测不起作用

敌人AI碰撞检测不起作用
EN

Stack Overflow用户
提问于 2018-10-01 14:41:30
回答 1查看 68关注 0票数 0

我的敌人人工智能没有探测到碰撞。我一直在使用用于我的玩家碰撞检测的代码。我调整它以适应敌人,但它不起作用:

代码语言:javascript
复制
class Enemy(Entity):
    def __init__(self, x, y,player):
        pygame.sprite.Sprite.__init__(self)
        self.image = Surface((32, 32))
        self.xvel = 0
        self.yvel = 0
        self.image.fill(Color("#FF0000"))    #Enemy is red
        self.onGorund = False
            #Enemy is 32 * 32 pixels
        self.image.convert()
        self.rect = Rect(x, y, 32, 32)
        self.counter = 0    #counter variable
        self.player = player



    def move(self, speed = 5):    # chase movement
        if self.rect.x > self.player.rect.x:    # Movement along x direction 
            self.rect.x -= speed
        elif self.rect.x < self.player.rect.x:
            self.rect.x += speed
        if self.rect.y < self.player.rect.y:    # Movement along y direction
            self.rect.y += speed
        elif self.rect.y > self.player.rect.y:
            self.rect.y -= speed

    def collide(self, xvel, yvel, platforms):
        for p in platforms:
            if pygame.sprite.collide_rect(self, p):
                if isinstance(p, Player_class):
                    pygame.quit()
                    sys.exit()
                if xvel > 0:
                    self.rect.right = p.rect.left
                    print ("collide right")
                if xvel < 0:
                    self.rect.left = p.rect.right
                    print ("collide left")
                if yvel > 0:
                    self.rect.bottom = p.rect.top
                    self.onGround = True
                    self.yvel = 0
                if yvel < 0:
                    self.rect.top = p.rect.bottom

    def update(self, platforms):
        if up:

            if self.onGround: self.yvel -= 10    #only jump if player is on the ground
        if down:
            pass
        if running:
            self.xvel = 12
        if left:
            self.xvel = -8
        if right:
            self.xvel = 8
        if not self.onGround:

            self.yvel += 0.3    #only accelerate with gravity if in the air

            if self.yvel > 100: self.yvel = 100    #terminal velocity = 100
        if not(left or right):
            self.xvel = 0

        self.rect.left += self.xvel    #falls or jumps

        self.collide(self.xvel, 0, platforms)    #creates collisions along the x axis

        self.rect.top += self.yvel    #creates collisions along the y axis

        self.onGround = False;    #assumes that the player is in the air
        # do y-axis collisions
        self.collide(0, self.yvel, platforms)

每当敌人接触到玩家时,我都试图关闭窗口,问题是,如果敌人不知道它在触摸玩家,它就不能关闭窗口。请询问是否需要更多代码。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-10-01 15:38:46

有几件事需要改变。

  • move方法中,您应该设置速度(self.xvelself.yvel),而不是直接移动rect。
  • 然后在move方法中调用update方法,移动sprite的rect并处理冲突。另外,现在需要调用main函数中的main方法,而不是move,并传递platforms列表: Enemy_list.draw(屏幕)e in enemy_list: e.update(平台)
  • 在对撞方法中,检查其中一个平台是否是player实例: 对于平台中的p: if pygame.sprite.collide_rect(self,p):if isinstance(p,Player_class):pygame.quit() sys.exit() 然而,玩家精灵不在这个列表中,所以它不能碰撞。 敌人实际上有一个对玩家(self.player)的引用,所以您可以这样做来检查它们是否碰撞: 如果pygame.sprite.collide_rect(self,self.player): 或者: if self.rect.colliderect(self.player.rect):

下面是一个完整的示例(我从前面的问题中提取了代码,并试图改进更多的东西):

代码语言:javascript
复制
import sys

import pygame
from pygame.locals import *


win_height = 750    #height of window is 750 pixles
win_width = 1050    #height of window is 1050 pixels
half_win_width = int(win_width / 2)    #will be used to centre camera
half_win_height = int(win_height / 2)

display = (win_width, win_height)    #creates the window as 500*500 pixels
depth = 32    #prevents infinate recursion
flags = 0    #message to Les: I don't really know what this does, however I have seen it in many places being used, therefore I assumed that it was important
camera_slack = 30    #how many pixels the player can move before the camera moves with them

pygame.init()


def main():    #main game function
    global cameraX, cameraY
    pygame.init()
    screen = pygame.display.set_mode(display, flags, depth)
    pygame.display.set_caption("Super Castlevania Man")
    timer = pygame.time.Clock()

    move_cameraX = 0
    move_cameraY = 0

    up = down = left = right = running = False
    background = pygame.Surface((32,32))    #the background takes up space on the screen
    background.convert()
    background.fill(pygame.Color("#000000"))    #background is black
    entities = pygame.sprite.Group()
    player = Player_class(32, 32*15)    #the player is 32*32 pixels large
    platforms = []

    x = y = 0
    level = [
        "PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP",
        "P                               P",
        "P         E                     P",
        "P                               P",
        "P                    PPPPPPPPP  P",
        "P                               P",
        "P                               P",
        "P                               P",
        "P    PPPPPPPP                   P",
        "P                               P",
        "P                          PPPP P",
        "P                 PPPPPP        P",
        "P         PPPPPPP               P",
        "P                               P",
        "P                     PPPPPP    P",
        "P                               P",
        "P   PPPPPPPPPPP                 P",
        "P                               P",
        "P                 PPPPPPPPPPP   P",
        "P                               P",
        "P                               P",
        "P                               P",
        "P                               P",
        "PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP",    
        ]
    #builds the level
    for row in level:
        for col in row:
            if col == "P":
                p = Platform(x, y)    #makes P a solid object
                platforms.append(p)
                entities.add(p)
            if col == "E":
                e = Exit_block(x, y)
                platforms.append(e)
                entities.add(e)
            x += 32
        y += 32
        x = 0

    entities.add(player)
    enemy = Enemy(60, 200, player)    #Spawns enemy
    enemy_list = pygame.sprite.Group()    #creates an enemy group
    enemy_list.add(enemy)    #Add an enemy to the group

    while 1:
        timer.tick(60)    #makes game run at 60 frames per second

        for e in pygame.event.get():    #shortens event to e
            if e.type == QUIT:
                return
            if e.type == KEYDOWN and e.key == K_ESCAPE:
                return
            if e.type == KEYDOWN and e.key == K_UP:
                up = True
                move_cameraY = -10
            if e.type == KEYDOWN and e.key == K_DOWN:
                down = True
                move_cameraY = 10
            if e.type == KEYDOWN and e.key == K_LEFT:
                left = True
                move_cameraX = -10
            if e.type == KEYDOWN and e.key == K_RIGHT:
                right = True
                move_cameraX = 10
            if e.type == KEYDOWN and e.key == K_SPACE:
                running = True

            if e.type == KEYUP and e.key == K_UP:
                up = False
                move_cameraY = 0
            if e.type == KEYUP and e.key == K_DOWN:
                down = False
                move_cameraY = 0
            if e.type == KEYUP and e.key == K_RIGHT:
                right = False
                move_cameraX = 0
            if e.type == KEYUP and e.key == K_LEFT:
                left = False
                move_cameraX = 0
            if e.type == KEYUP and e.key == K_RIGHT:
                right = False        

        # Update the game.
        for e in enemy_list:
            e.update(platforms)
        player.update(up, down, left, right, running, platforms)

        # Draw everything.
        for y in range(32):    #draws the background
            for x in range(32):
                screen.blit(background, (x * 32, y * 32))
        entities.draw(screen)
        enemy_list.draw(screen)
        pygame.display.flip()  # You need only one flip or update call per frame.


class Entity(pygame.sprite.Sprite):    #makes player a sprite
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)    #sets sprite to initiate


class Player_class(Entity):    #defines player class
    def __init__(self, x, y):    #x is the player x coordinate, y is the player y coordinate
        Entity.__init__(self)    #the player is an entity
        self.xvel = 0    #how fast the player is moving left and right
        self.yvel = 0    #how fast the player is moving up and down
        self.onGround = False    #assumes the player is in the air
        self.image = pygame.Surface((32,32))    #the player is 32*32 pixels
        self.image.fill(pygame.Color("#0000FF"))    #makes the player blue
        self.rect = pygame.Rect(x, y, 32, 32)
        self.x = x
        self.y = y

    def update(self, up, down, left, right, running, platforms):
        if up:
            if self.onGround:
                self.yvel -= 10    #only jump if player is on the ground
        if down:
            pass
        if running:
            self.xvel = 12
        if left:
            self.xvel = -8
        if right:
            self.xvel = 8
        if not self.onGround:

            self.yvel += 0.3    #only accelerate with gravity if in the air

            if self.yvel > 100: self.yvel = 100    #terminal velocity = 100
        if not(left or right):
            self.xvel = 0

        self.rect.left += self.xvel    #falls or jumps

        self.collide(self.xvel, 0, platforms)    #creates collisions along the x axis

        self.rect.top += self.yvel    #creates collisions along the y axis

        self.onGround = False;    #assumes that the player is in the air
        # do y-axis collisions
        self.collide(0, self.yvel, platforms)

    def collide(self, xvel, yvel, platforms):
        for p in platforms:
            if pygame.sprite.collide_rect(self, p):
                if isinstance(p, Exit_block):
                    pygame.quit()
                    sys.exit()
                if xvel > 0:
                    self.rect.right = p.rect.left
                if xvel < 0:
                    self.rect.left = p.rect.right
                if yvel > 0:
                    self.rect.bottom = p.rect.top
                    self.onGround = True
                    self.yvel = 0
                if yvel < 0:
                    self.rect.top = p.rect.bottom


class Platform(Entity):
    def __init__(self, x, y):
        Entity.__init__(self)
        self.image = pygame.Surface((32, 32))
        self.image.fill(pygame.Color("#FFFFFF"))
        self.rect = pygame.Rect(x, y, 32, 32)


class Exit_block(Platform):
    def __init__(self, x, y):
        Platform.__init__(self, x, y)
        self.image.fill(pygame.Color("#FF7700"))#exit block is orange


class Enemy(Entity):
    def __init__(self, x, y,player):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface((32, 32))
        self.xvel = 0
        self.yvel = 0
        self.image.fill(pygame.Color("#FF0000"))    #Enemy is red
        self.rect = pygame.Rect(x, y, 32, 32)
        self.player = player

    def move(self, speed=5):    # chase movement
        if self.rect.x > self.player.rect.x:    # Movement along x direction 
            self.xvel = -speed
        elif self.rect.x < self.player.rect.x:
            self.xvel = speed
        if self.rect.y < self.player.rect.y:    # Movement along y direction
            self.yvel = speed
        elif self.rect.y > self.player.rect.y:
            self.yvel = -speed

    def collide(self, xvel, yvel, platforms):
        # Check if the enemy collides with the player.
        if self.rect.colliderect(self.player.rect):
            pygame.quit()
            sys.exit()
        for p in platforms:
            if pygame.sprite.collide_rect(self, p):
                if xvel > 0:
                    self.rect.right = p.rect.left
                if xvel < 0:
                    self.rect.left = p.rect.right
                if yvel > 0:
                    self.rect.bottom = p.rect.top
                if yvel < 0:
                    self.rect.top = p.rect.bottom

    def update(self, platforms):
        self.move()  # Set the velocity.

        self.rect.left += self.xvel
        self.collide(self.xvel, 0, platforms)    #creates collisions along the x axis

        self.rect.top += self.yvel    #creates collisions along the y axis
        self.collide(0, self.yvel, platforms)


if __name__ == "__main__":
    main()
    pygame.quit()
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52593554

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档