pygame碰撞检测函数python3中的语法错误[重复]

Posted

技术标签:

【中文标题】pygame碰撞检测函数python3中的语法错误[重复]【英文标题】:Syntax error in the pygame collision detection function python3 [duplicate] 【发布时间】:2022-01-21 09:00:37 【问题描述】:

所以我尝试编写一个像太空入侵者这样的 2d 游戏平台,但问题出在碰撞中,当我尝试定义碰撞时,我在她的特性中使用它,类的特性(敌人坐标和子弹坐标),代码不会启动。这就是结果:`

    def isc (eneemy.x, eneemy.y, Bulllet.x, Bulllet.y ):
               ^
SyntaxError: invalid syntax

如果您需要,这是代码:

    ############# LIBRARIES ####################
import pygame, sys, random
import math
from pygame.constants import SYSTEM_CURSOR_WAITARROW 
from pygame import mixer


pygame.init()

############ WINDOW OPTIONS ################
Swidth = 800 
Sheight =600
screen = pygame.display.set_mode((Swidth, Sheight))
pygame.display.set_caption("Space Invader By Mal4D")
icon = pygame.image.load('places/favicon.png')
pygame.display.set_icon(icon)


############# COLORS #######################
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED   = (255, 0, 0)
YELLOW = (255 , 255 , 0)

###########  VARIANTS ######################
isJumping= False
LevelJump = 0.25
rocket = pygame.image.load("rocket/rocket.png")
space = pygame.image.load("places/bg.png")
bullet = pygame.image.load("rocket/bullet.png")
Sound =  pygame.mixer.music.load("Sounds/laser.mp3")
Bgsound= pygame.mixer.music.load("Sounds/bg.mp3")
enemy = pygame.image.load("Enemy/enemy.png")
ax=random.randint(0,700)
by=random.randint(20,120)
Bgsound1 = mixer.Sound("Sounds/bg.mp3")
BullletSound = mixer.Sound("Sounds/laser.mp3")


############## Class Players ##########################
class Player():
    def __init__(self,x,y,width,height):
        self.x=x
        self.y=y
        self.width=width
        self.height=height
        self.step=10
        self.speed=10
        self.isJumping= False
        

    def drawplayer (self,screen):
        screen.blit(rocket, (rockeet.x, rockeet.y))

    def drawscreen (self,screen):
        screen.blit(space, (0,0))
    

rockeet = Player(350,500,50,50)


########### Bullet #####################
class Bullet():
    def __init__(self, x, y , y_change, x_change, state):
        self.x=x
        self.y= y
        self.y_change=y_change
        self.x_change= x_change
        self.state= state


    def fire(x,y):
        Bulllet.state = "fire"
        screen.blit(bullet,(x+16, y+10))


Bulllet=Bullet(350,500,20,0,"ready")

**def isCollision (ax1, by1, cx, dy):
    distance = math.sqrt(math.pow(ax1 - cx, 2) + (math.pow(by1- dy, 2)))

    if distance <27:
        return True
    else:
        return False**

    
################## Enemy ########################
class Enemy():
    def __init__(self, x ,y, stepx,stepy):
        self.x = x
        self.y=y
        self.stepx=stepx
        self.stepy=stepy


    def drawenemy(screen):
        screen.blit(enemy,(ax,by))


eneemy = Enemy(random.randint(0,700),random.randint(20,120),3,35)


################# Clussion#########################
score = 0


def isc (eneemy.x, eneemy.y, Bulllet.x, Bulllet.y ):
    distance = math.sqrt(math.pow(eneemy.x - Bulllet.x, 2) + (math.pow(eneemy.y- Bulllet.y, 2)))

    if distance <27:
        return True
    else:
        return False


################### Game Loop #####################################
#Bgsound1.play(180)




while 1:
    pygame.time.delay(10)
    for event in pygame.event.get():
        if event.type == pygame.QUIT: sys.exit()

    keys=pygame.key.get_pressed()
    rockeet.drawscreen(screen)
    Enemy.drawenemy(screen)



    if keys[pygame.K_SPACE]:
        if Bulllet.state == "ready":
            BullletSound.play()

            Bulllet.x=rockeet.x
            Bulllet.y=rockeet.y
            Bullet.fire(Bulllet.x, Bulllet.y)



    if keys[pygame.K_LEFT] and rockeet.x - rockeet.step >= 0:
        rockeet.x =rockeet.x-rockeet.step
    
    if keys[pygame.K_RIGHT] and rockeet.x + rockeet.width +rockeet.step <= Swidth :
        rockeet.x =rockeet.x+rockeet.step

    if Bulllet.y <= 0:
        Bulllet.y= 500
        Bulllet.state = "ready"


    if Bulllet.state == "fire":
        Bullet.fire(Bulllet.x, Bulllet.y)
        Bulllet.y -= Bulllet.y_change



########### Enemy Mouvement #########################################
    collision = isCollision( eneemy.x, eneemy.y, Bulllet.x, Bulllet.y)

    ax+= eneemy.stepx
    if ax<= 0:
        eneemy.stepx=3
        by+= eneemy.stepy

    elif ax >= 750:
        eneemy.stepx=-3
        by+= eneemy.stepy

    if collision:
        Bulllet.y= 500
        Bulllet.state="ready"
        eneemy.x= random.randint(0,700)
        eneemy.y=random.randint(20,)

################## Collision ######################








################## OUTRO #######################################
    rockeet.drawplayer(screen)

    pygame.display.update()

结果:

def isCollision (eneemy.x, eneemy.y, Bulllet.x, Bulllet.y ):
               ^
SyntaxError: invalid syntax

【问题讨论】:

【参考方案1】:

为了完成而添加到@Rabbid76的答案......


您不想通过简单地测量矩形左上角之间的距离来测试矩形碰撞(即敌人与子弹之间的碰撞)。考虑下图:

您可以看到矩形重叠,即使在红色圆圈内似乎没有碰撞,这是您在检查碰撞时扫描的距离区域。

改为使用 Pygame 的内置 Rect 对象及其碰撞检测功能(例如,pygame.Rect.colliderect)。


我还注意到您为资产使用了相似的名称,并使用了相应的游戏类(enemyeneemybulletBulllet,...)。这是一个糟糕的主意,因为一个错字很快就会发生,你甚至不知道发生了什么事。值得花一些时间来正确命名变量!


您已经使用了很多class methods,其中对象方法(在其参数列表中包含关键字self 的方法)会更合适。您可能需要花一些时间来更新您的面向对象编程知识。


完全有效的解决方案:

############# LIBRARIES ####################
import pygame, sys, random
import math
from pygame.constants import SYSTEM_CURSOR_WAITARROW 
from pygame import mixer


pygame.init()

############ WINDOW OPTIONS ################
Swidth = 800 
Sheight = 600
screen = pygame.display.set_mode((Swidth, Sheight))
pygame.display.set_caption("Space Invader By Mal4D")
icon = pygame.image.load('places/favicon.png')
pygame.display.set_icon(icon)


############# COLORS #######################
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
YELLOW = (255, 255, 0)

###########  VARIANTS ######################
isJumping = False
LevelJump = 0.25
rocket = pygame.image.load("rocket/rocket.png")
space = pygame.image.load("places/bg.png")
bullet = pygame.image.load("rocket/bullet.png")
Sound = pygame.mixer.music.load("Sounds/laser.mp3")
Bgsound = mixer.Sound("Sounds/bg.mp3")
enemy = pygame.image.load("Enemy/enemy.png")
bulletObjectSound = mixer.Sound("Sounds/laser.mp3")


############## Class Players ##########################
class Player():
    def __init__(self, x, y, width, height):
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.step = 10
        self.speed = 10
        self.isJumping = False
        

    def drawplayer (self, screen):
        screen.blit(rocket, (rocketObject.x, rocketObject.y))

    def drawscreen (self, screen):
        screen.blit(space, (0, 0))
    

rocketObject = Player(350, 500, 50, 50)


########### Bullet #####################
class Bullet():
    def __init__(self, x, y, y_change, x_change, state):
        self.x = x
        self.y = y
        self.y_change = y_change
        self.x_change = x_change
        self.state = state


    def fire(self):
        self.state = "fire"
        screen.blit(bullet, (self.x + 16, self.y + 10))


bulletObject = Bullet(350, 500, 20, 0, "ready")

def isCollision(enemyX, enemyY, bulletX, bulletY):
    r1 = pygame.Rect(enemyX, enemyY, enemy.get_width(), enemy.get_height())
    r2 = pygame.Rect(bulletX, bulletY, bullet.get_width(), bullet.get_height())

    return r1.colliderect(r2)

    
################## Enemy ########################
class Enemy():
    def __init__(self, x, y, stepx, stepy):
        self.x = x
        self.y = y
        self.stepx = stepx
        self.stepy = stepy

    def drawenemy(self, screen):
        screen.blit(enemy, (self.x, self.y))


enemyObject = Enemy(random.randint(0, 700), 20, 3, 35)

################# Clussion#########################
score = 0

################### Game Loop #####################################
Bgsound.play(180)




while 1:
    pygame.time.delay(10)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:sys.exit()

    keys = pygame.key.get_pressed()
    rocketObject.drawscreen(screen)
    enemyObject.drawenemy(screen)



    if keys[pygame.K_SPACE]:
        if bulletObject.state == "ready":
            bulletObjectSound.play()

            bulletObject.x = rocketObject.x
            bulletObject.y = rocketObject.y
            bulletObject.fire()



    if keys[pygame.K_LEFT] and rocketObject.x - rocketObject.step >= 0:
        rocketObject.x = rocketObject.x - rocketObject.step
    
    if keys[pygame.K_RIGHT] and rocketObject.x + rocketObject.width + rocketObject.step <= Swidth:
        rocketObject.x = rocketObject.x + rocketObject.step

    if bulletObject.y <= 0:
        bulletObject.y = 500
        bulletObject.state = "ready"


    if bulletObject.state == "fire":
        bulletObject.fire()
        bulletObject.y -= bulletObject.y_change



########### Enemy Movement #########################################
    collision = isCollision(enemyObject.x, enemyObject.y, bulletObject.x, bulletObject.y)

    enemyObject.x += enemyObject.stepx
    if enemyObject.x <= 0:
        enemyObject.stepx = 3
        enemyObject.y += enemyObject.stepy

    elif enemyObject.x >= 750:
        enemyObject.stepx = -3
        enemyObject.y += enemyObject.stepy

    if collision:
        bulletObject.y = 500
        bulletObject.state = "ready"
        enemyObject.x = random.randint(0, 700)
        enemyObject.y = 20

################## Collision ######################








################## OUTRO #######################################
    rocketObject.drawplayer(screen)

    pygame.display.update()

【讨论】:

【参考方案2】:

函数的形参不能是eneemy.x这样的结构元素。要么更改参数的名称:

def isc (enemy_x, enemy_y, bullet_x, bullet_y):
    distance = math.sqrt(math.pow(enemy_x - bullet_x, 2) + (math.pow(enemy_y- bullet_y, 2)))

    if distance <27:
        return True
    else:
        return False

或者将对象传递给函数:

def isc (enemy, bullet):
    distance = math.sqrt(math.pow(enemy.x - bullet.x, 2) + (math.pow(enemy.y- bullet.y, 2)))

    if distance <27:
        return True
    else:
        return False

collision = isCollision( eneemy.x, eneemy.y, Bulllet.x, Bulllet.y)

collision = isCollision(eneemy, Bulllet)

注意,您可以使用math.hypot 代替math.sqrtmath.pow

distance = math.sqrt(math.pow(enemy_x - bullet_x, 2) + (math.pow(enemy_y- bullet_y, 2)))

distance = math.hypot(enemy_x - bullet_x, enemy_y - bullet_y)

【讨论】:

thannnnnnnnnnnnnnnks @AhmadAL-Saoud 谢谢。不客气。

以上是关于pygame碰撞检测函数python3中的语法错误[重复]的主要内容,如果未能解决你的问题,请参考以下文章

pygame游戏检测矩形是否碰撞指定颜色的自定义函数(仅5行代码)

pygame游戏检测矩形是否碰撞指定颜色的自定义函数(仅5行代码)

如何检测pygame中的碰撞?

碰撞检测不适用于pygame

Pygame碰撞检测

Python进阶篇十一Pygame的精灵和碰撞检测