【问题标题】:Pygame sprite collision random movementPygame精灵碰撞随机运动
【发布时间】:2014-05-23 04:34:35
【问题描述】:

我正在尝试创建一个游戏 (pygame),其中有一个精灵,当玩家碰撞到该精灵时,它会随机移动到表面上的另一个地方,我不知道该怎么做,因为我有非常基础的知识,我的一个猜测是将 random.randint 分配给精灵,但是我从那里去哪里呢?非常感谢,我将不胜感激。代码如下:)

    import pygame, sys
from pygame.locals import *
import random

pygame.init()

game=0
width=450
height=613

blue=(100,149,237)
white=(255,255,255)
purple =(128,0,128)

Level=pygame.image.load("level.jpg")
background=pygame.image.load("background.jpg")
startscreen=pygame.image.load("ocean.jpg")
gamescreen=pygame.image.load("screengame.jpg")
Display=pygame.display.set_mode((width,height))
pygame.display.set_caption("Ocean")

movex = 100

movey = 100

DirectX = 0
DirectY = 0

game = 0

MoveEnemy1X = 150
MoveEnemy1Y = 50
rectDirectX = 10
rectDirectY = 9

MoveEnemy2X = 300
MoveEnemy2Y = 100
rectDirect2X = 30
rectDirect2Y = 10

MoveEnemy3X = 400
MoveEnemy3Y = 200
rectDirect3X = 12
rectDirect3Y = 10

clock = pygame.time.Clock()

gameScore = 0
scorefont = pygame.font.SysFont("Arial",30)
score = scorefont.render("Score: " +str(gameScore),True,white)

##pygame.mixer.music.load('ocean.mp3')
##pygame.mixer.music.play(-1,0.0)

direc1 = 5
direc2 =  5

class Player(pygame.sprite.Sprite):
    def __init__(self,x,y,width,height):
        pygame.sprite.Sprite.__init__(self)
        self.x = x
        self.y = y
        self.width  = width
        self.height = height
        self.rect = pygame.Rect(x,y,width,height)

    def RenderPlayer(self):
        pygame.draw.rect(Display,blue,(self.x,self.y,self.width,self.height))
        self.rect = pygame.Rect(self.x,self.y,self.width,self.height)

class EnemySprite(pygame.sprite.Sprite):
    def __init__(self,x,y,width,height):
        pygame.sprite.Sprite.__init__(self)
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.rect = pygame.Rect(x,y,width,height)

    def RenderEnemy(self):
        pygame.draw.rect(Display,white,(MoveEnemy1X,MoveEnemy1Y,30,30))
        self.rect = pygame.Rect(MoveEnemy1X,MoveEnemy1Y,self.width,self.height)

class EnemySprite2(pygame.sprite.Sprite):
    def __init__(self,x,y,width,height):
        pygame.sprite.Sprite.__init__(self)
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.rect = pygame.Rect(x,y,width,height)

    def RenderEnemy2(self):
        pygame.draw.rect(Display,white,(MoveEnemy2X,MoveEnemy2Y,40,10))
        self.rect = pygame.Rect(MoveEnemy2X,MoveEnemy2Y, self.width,self.height)

class EnemySprite3(pygame.sprite.Sprite):
    def __init__(self,x,y,width,height):
        pygame.sprite.Sprite.__init__(self)
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.rect = pygame.Rect(x,y,width,height)

    def RenderEnemy3(self):
        pygame.draw.rect(Display, white,(MoveEnemy3X,MoveEnemy3Y,10,10))
        self.rect = pygame.Rect(MoveEnemy3X,MoveEnemy3Y, self.width,self.height)


class GoodSprite(pygame.sprite.Sprite):
    def __init__(self,x,y,width,height):
        pygame.sprite.Sprite.__init__(self)
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.rect = pygame.Rect(x,y,width,height)

    def RenderGoodSprite(self):
        pygame.draw.rect(Display,purple,(100,100,10,10))
        self.rect = pygame.Rect(100,100,self.width,self.height)


Player1=Player(100,100,20,20)
Enemy1=EnemySprite(200,200,30,30)
Enemy2=EnemySprite2(300,200,40,10)
Enemy3=EnemySprite3(240,190,30,20)
Good=GoodSprite(150,400,10,10)

TheGameLoop = True

while TheGameLoop:

    for event in pygame.event.get():
        if (event.type==pygame.QUIT):
            TheGameLoop=False

        if (event.type==pygame.KEYDOWN):

            if (event.key==pygame.K_LEFT):
                direc1 = -4
                gameScore+=1
            score = scorefont.render("Score: " +str(gameScore),True,white)

            if (event.key==pygame.K_RIGHT):
                direc1 = 4
                gameScore+=1

            score = scorefont.render("Score: " +str(gameScore),True,white)

            if (event.key==pygame.K_DOWN):
                direc2 = 4
                gameScore+=1
            score = scorefont.render("Score: " +str(gameScore),True,white)

            if (event.key==pygame.K_UP):
                direc2 = -4
                gameScore+=1
            score = scorefont.render("Score: " +str(gameScore),True,white)

        if (event.type==pygame.KEYUP):

            if (event.key==pygame.K_LEFT):
                direc1 = 0

            if (event.key==pygame.K_RIGHT):
                direc1 = 0

            if (event.key==pygame.K_UP):
                direc2 = 0

            if (event.key==pygame.K_DOWN):
                direc2 = 0

    if MoveEnemy1X > 430:
        MoveEnemy1X = 425
        rectDirectX = -5

    elif MoveEnemy1X < 0:
        MoveEnemy1X = 10
        rectDirectX = 5

    elif MoveEnemy1Y > 613:
        MoveEnemy1Y = 600
        rectDirectY = -9

    elif MoveEnemy1Y < 0:
        MoveEnemy1Y = 0
        rectDirectY = 11

    if MoveEnemy2X > 430:
        MoveEnemy2X = 425
        rectDirect2X = -5

    elif MoveEnemy2X < 0:
        MoveEnemy2X = 11
        rectDirect2X = 6

    elif MoveEnemy2Y > 613:
        MoveEnemy2Y = 600
        rectDirect2Y = -12

    elif MoveEnemy2Y < 0:
        MoveEnemy2Y = 0
        rectDirect2Y = 8

    if MoveEnemy3X > 430:
        MoveEnemy3X = 422
        rectDirect3X = -7
    elif MoveEnemy3X < 0:
        MoveEnemy3X = 11
        rectDirect3X = 8
    elif MoveEnemy3Y > 613:
        MoveEnemy3Y = 600
        rectDirect3X = -12
    elif MoveEnemy3Y < 0:
        MoveEnemy3Y = 0
        rectDirect3Y = 5

    if direc1 > 430:
        Display.blit(Level,(0,0))


    pygame.display.update()



    if game==0:
        Display.blit(startscreen,(0,0))

        if event.type==pygame.KEYDOWN:
            if event.key==pygame.K_SPACE:
                game=1
                Display.blit(gamescreen,(0,0))
            elif event.key==pygame.K_ESCAPE:
                pygame.quit()

        pygame.display.update()

    if game==1:
        Display.blit(gamescreen,(0,0))
        Display.blit(score,(220,10))
        Player1.RenderPlayer()
        Enemy1.RenderEnemy()
        Enemy2.RenderEnemy2()
        Enemy3.RenderEnemy3()
        Good.RenderGoodSprite()
        Player1.x +=direc1
        Player1.y +=direc2
        MoveEnemy1X +=rectDirectX
        MoveEnemy1Y +=rectDirectY
        MoveEnemy2X +=rectDirect2X
        MoveEnemy2Y +=rectDirect2Y
        MoveEnemy3X + rectDirect3X
        MoveEnemy3Y += rectDirectY
##        pygame.mixer.music.load("ocean.mp3")
##        pygame.mixer.music.play(-1,0.0)

        pygame.display.update()

        if pygame.sprite.collide_rect(Player1,Enemy1):
            game=2
            Display.blit(background,(0,0))
            pygame.mixer.music.load("untitled.mp3")
            pygame.mixer.music.play(1,0.0)

        if pygame.sprite.collide_rect(Player1,Enemy2):
            game=2
            Display.blit(background,(0,0))
            pygame.mixer.music.load("untitled.mp3")
            pygame.mixer.music.play(1,0.0)

        if pygame.sprite.collide_rect(Player1,Good):
            gameScore+=1
            Good.x=random.randint(0,500)
            Good.y=random.randint(0,600)
            pygame.display.update()


    if game==2:
        Display.blit(background,(0,0))
        Display.blit(score,(200,20))
        gameScore=0
        pygame.display.update()
        pygame.mixer.music.stop()

        if event.type==pygame.KEYDOWN:
            if event.key==pygame.K_SPACE:
                game=1


    pygame.display.update()
    clock.tick(50)

【问题讨论】:

    标签: pygame sprite collision


    【解决方案1】:

    专注于代码的这一部分:

        if pygame.sprite.collide_rect(Player1,Enemy1):
            game=2
            Display.blit(background,(0,0))
            pygame.mixer.music.load("untitled.mp3")
            pygame.mixer.music.play(1,0.0)
    

    我通常使用 pygame.sprite.spritecollide()。

    我不确定“collide_rect”是否也能做到这一点,但诀窍是:

    pygame.sprite.spritecollide() 返回一个碰撞列表。这非常有帮助。

    (另外,我会将你想要以这种方式表现的所有精灵都放在一个列表中。)

    --所以如果我在你的情况下使用所有这些:

    for each_enemy in enemy_list:
    
       # see if player hit an enemy; 
       # the 'False' flag means DON'T delete anything in the event of a collision
        enemy_touched_list = pygame.sprite.spritecollide(each_enemy, Player1, False)
    
        # good, now each enemy that was touching a player is in this list
        # now we will iterate through this list and find a random place for the enemy.
    
        for enemy_touched in enemy_touched_list:
            enemy_touched.render(random.randint(0,width), random.randint(0,height))
    

    好的,这样代码将遍历敌人列表中的每个敌人,检查它是否正在接触玩家,如果是敌人,将使用 Enemy 类的 .render() 方法重置敌人的位置。

    为了让最后一行起作用,我们需要稍微调整一下你的类。\

    课程:

    看起来您了解设置类的语法,但您错过了它们的强大功能。

    没有理由你应该拥有 4 个敌方职业!它们几乎完全相同。唯一的区别是几个值!这对我来说听起来像是一个对象!

    你应该有一个敌人精灵类,然后根据你的心愿从那个类中制作尽可能多的对象。这就是为什么类是最好的。如果你想要在精灵之间进行任何细微的定制,请设置你的类,以便在创建对象时将它们传递进去。

    --如果您需要更多帮助来更改课程内容,请告诉我。--

    --也许你是 OOP 的新手,这些课程来自教程,如果是这样,我可以提供更多信息--

    就像我之前说的,为了让我的代码版本能够正常工作,我们需要更改你的(即将成为单一的)敌人类的 .render() 方法:

    原文:

    def RenderEnemy3(self):
        pygame.draw.rect(Display, white,(MoveEnemy3X,MoveEnemy3Y,10,10))
        self.rect = pygame.Rect(MoveEnemy3X,MoveEnemy3Y, self.width,self.height)
    

    修改:

    def RenderEnemy3(self,xpos,ypos):
        pygame.draw.rect(Display, white,(MoveEnemy3X,MoveEnemy3Y,xpos,ypos))
        self.rect = pygame.Rect(MoveEnemy3X,MoveEnemy3Y, self.width,self.height)
    

    如果你愿意,我可以编辑这个答案以包含整个“EnemySprite”类,修改后可以很好地与自身通信,并且只需要一个类。

    希望这会有所帮助。如果您需要澄清任何事情,请发表评论。 Pygame 很有趣。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-25
      • 2017-09-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-26
      • 1970-01-01
      相关资源
      最近更新 更多