【问题标题】:Making a pacman game and not sure how to remove pac pellets after colliding with制作吃豆人游戏,但不知道如何在碰撞后移除 pac 颗粒
【发布时间】:2017-08-29 11:46:21
【问题描述】:

我目前正在制作一个吃豆人游戏,并且正在努力弄清楚如何在与屏幕碰撞后从屏幕上移除一个小球。我尝试将颜色更改为黑色,但无法使其正常工作。我接下来尝试del 元素索引,但这也没有用。

import pygame
import os
import sys


#initialise the game 
pygame.init()
screen = pygame.display.set_mode((448, 576))
done = False

y = 416
x = 232

#sets up clock and loads pacman image
clock = pygame.time.Clock()
PACMANSPRITE = pygame.image.load("pacman.png").convert_alpha()
PACMAN_MAP = pygame.image.load("pacman_map.png").convert_alpha()

#gets pacman intro music, sets music to lower volume then plays it
pygame.mixer.music.load('pacman_beginning.WAV')
pygame.mixer.music.set_volume(0.01)
pygame.mixer.music.play(0)


#box class, used for boxes to border pacmans map
class boxcollisions(pygame.sprite.Sprite):
    def __init__(self, x, y):
        self.y = y
        self.x = x
        self.rect = pygame.Rect(self.x, self.y, 12, 12)
        self.colour = (0, 128, 255)

    def draw(self, screen):
        pygame.draw.rect(screen, self.color, self.rect)

class pointclass(pygame.sprite.Sprite):
    def __init__(self, x, y):
        self.y = y
        self.x = x
        self.rect = pygame.Rect(self.x, self.y, 12, 12)
        self.colour = (255, 204, 153)
        self.score=0

    def draw(self, screen):
        pygame.draw.rect(screen, self.colour, self.rect)

    def addpoint(self):
        self.score+=1
        print(self.score)
        self.colour= (0,0,0)
        print('why isnt it working')

#pacmans class
class pacman(pygame.sprite.Sprite):
    def __init__(self, image, x, y):
        self.image = image
        self.y=416
        self.x=216
        self.currentx=self.x
        self.currenty=self.y
        self.rect = self.image.get_rect()
        self.rect.left = self.x
        self.rect.top = self.y
        self.rect.width=16
        self.rect.height=16

    # move pacman 
    def movement(self):
        pressed= pygame.key.get_pressed()
        if pressed[pygame.K_UP]:
            self.y -= 2
        if pressed[pygame.K_DOWN]:
            self.y += 2
        if pressed[pygame.K_LEFT]:
            self.x -= 2
        if pressed[pygame.K_RIGHT]:
            self.x += 2
        self.rect.left = self.x
        self.rect.top = self.y

    def draw(self, surface):
        # blit yourself at your current position
        surface.blit(self.image, (self.x, self.y))
        self.currentx=self.x
        self.currenty=self.y

    def outofbounds(self):
        self.y=self.currenty
        self.x=self.currentx
        self.rect.left = self.x
        self.rect.top = self.y

#instances the pacman class
sprite = pacman(PACMANSPRITE, x ,y)


#main game loop
while not done:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
                    done = True
                    pygame.quit()
                    sys.exit()


    screen.fill((0,0,0))
    screen.blit(PACMAN_MAP, (0, 0))

    #co-ordinates for boxes to set up map boundaries
    boxboundaries=[   
        [],
        [],
        [],
        [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28],
        [1,14,15,28], #5
        [1,3,4,5,6,8,9,10,11,12,14,15,17,18,19,20,21,23,24,25,26,28],
        [1,3,4,5,6,8,9,10,11,12,14,15,17,18,19,20,21,23,24,25,26,28],
        [1,3,4,5,6,8,9,10,11,12,14,15,17,18,19,20,21,23,24,25,26,28],
        [1,28],
        [1,3,4,5,6,8,9,11,12,13,14,15,16,17,18,20,21,23,24,25,26,28], #10
        [1,3,4,5,6,8,9,11,12,13,14,15,16,17,18,20,21,23,24,25,26,28],
        [1,8,9,14,15,20,21,28],
        [1,2,3,4,5,6,8,9,10,11,12,14,15,17,18,19,20,21,23,24,25,26,27,28],
        [1,2,3,4,5,6,8,9,10,11,12,14,15,17,18,19,20,21,23,24,25,26,27,28],
        [6,8,9,20,21,23], #15
        [6,8,9,11,12,13,14,15,16,17,18,20,21,23],
        [1,2,3,4,5,6,8,9,11,12,13,14,15,16,17,18,20,21,23,24,25,26,27,28],
        [1,11,12,13,14,15,16,17,18,28],
        [1,2,3,4,5,6,8,9,11,12,13,14,15,16,17,18,20,21,23,24,25,26,27,28],
        [6,8,9,11,12,13,14,15,16,17,18,20,21,23,24,25,26,27,28], #20
        [6,8,9,20,21,23],
        [6,8,9,11,12,13,14,15,16,17,18,20,21,23],
        [1,2,3,4,5,6,8,9,11,12,13,14,15,16,17,18,20,21,23,24,25,26,27,28],
        [1,14,15,28],
        [1,3,4,5,6,8,9,10,11,12,14,15,17,18,19,20,21,23,24,25,26,28], #25
        [1,3,4,5,6,8,9,10,11,12,14,15,17,18,19,20,21,23,24,25,26,28],
        [1,5,6,23,24,28],
        [1,2,3,5,6,8,9,11,12,13,14,15,16,17,18,20,21,23,24,26,27,28],
        [1,2,3,5,6,8,9,11,12,13,14,15,16,17,18,20,21,23,24,26,27,28],
        [1,8,9,14,15,20,21,28], # 30
        [1,3,4,5,6,7,8,9,10,11,12,14,15,17,18,19,20,21,22,23,24,25,26,28],
        [1,3,4,5,6,7,8,9,10,11,12,14,15,17,18,19,20,21,22,23,24,25,26,28],
        [1,28],
        [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28],                   
      ]


    #point spawn locations
    pointspawns=[ 
        [],
        [],
        [],
        [],
        [2,3,4,5,6,7,8,9,10,11,12,13,16,17,18,19,20,21,22,23,24,25,26,27], #5
        [2,7,13,16,22,27],
        [2,7,13,16,22,27],
        [2,7,13,16,22,27],
        [2,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27], 
        [2,7,10,19,22,27], #10
        [2,7,10,19,22,27],
        [2,3,4,5,6,7,10,11,12,13,16,17,18,19,22,23,24,25,26,27],
        [7,22],
        [7,22],
        [7,22], #15
        [7,22],
        [7,22],
        [7,22],
        [7,22],
        [7,22], #20
        [7,22],
        [7,22],
        [7,22],
        [2,3,4,5,6,7,8,9,10,11,12,13,16,17,18,19,20,21,22,23,24,25,26,27],
        [2,7,13,16,22,27], #25
        [2,7,13,16,22,27],
        [2,3,4,7,8,9,10,11,12,13,16,17,18,19,20,21,22,25,26,27],
        [4,7,10,19,22,25],
        [4,7,10,19,22,25],
        [2,3,4,5,6,7,10,11,12,13,16,17,18,19,22,23,24,25,26,27],
        [2,13,16,27], # 30
        [2,13,16,27],
        [2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27],                       
      ]

    #moves pacman
    sprite.movement()

    px=0
    py=-16

    for row in pointspawns:
        #y co ordinate
        py=py+16    
        for n in row:
            #x co ordinate
            n=n-1
            px=n*16
            point=(pointclass(px, py))
            #used to draw points
            point.draw(screen)
            if pygame.sprite.collide_rect(sprite, point):
                point.addpoint()


    #builds the boxes
    bx=0
    by=-16


    for row in boxboundaries:
        #y co ordinate
        by=by+16    
        for n in row:
            #x co ordinate
            n=n-1
            bx=n*16
            box=(boxcollisions(bx, by))
            #used to draw boxes for visual repsentation
            #box.draw(screen)
            if pygame.sprite.collide_rect(sprite, box):
                sprite.outofbounds()



    #draws pacman
    sprite.draw(screen)


    pygame.display.flip()
    clock.tick(60)

【问题讨论】:

    标签: python list pygame element del


    【解决方案1】:

    我知道(而且我知道的不多)最简单的方法是使用pygame.sprite.Group()pygame.sprite.spritecollide

    这里的基本逻辑是,为颗粒创建一个精灵组,将每个颗粒创建为一个精灵并将其添加到组中。在游戏循环的每次迭代中,将精灵组绘制到屏幕上,并使用spritecollide 验证玩家角色与颗粒组中的任何颗粒之间是否存在碰撞。

    spritecollide 有一个参数可以在发生碰撞时消除弹丸,因此您需要将其设置为 true,以避免在下一个循环中绘制它。

    #Basic logic as example.
    
    pellets = pygame.sprite.Group()
    #CREATE PELLETS AND ADD THEM TO THE pellets sprite group.
    
    player = Sprite()
    
    ...
    
    #IN THE GAME LOOP
    
        #Validate if there was a collision.
        pellets_hit = pygame.sprite.spritecollide(player, pellets, True) #True indicates that, if there were any hit, remove the pellet from the group.
    
        if len(pellet_hit):
            #Increment score or something.
    
        ...
    
        #Updating the display
        player.draw(screen)
        pellets.draw(screen) #If there were any hit, the pellet won't be in this group and won't be drawn
    

    这是一个使用精灵和精灵组的项目示例: Snake game

    【讨论】:

    • 我尝试在 10 分钟内完成,谢谢您的帮助
    • 它根本不起作用,是 IF len(pellet_hit): 意味着就这样吗?另外,我究竟如何使我的颗粒成为一个组,我是否将颗粒声明为一个组,然后在每次绘制时添加颗粒或其他什么?也感谢您的帮助
    • if 声明是的,它的意思是这样。请参阅spritecollide 从您的弹丸组中取出命中的弹丸并将它们添加到pellets_hit 列表中,因此if len(pellets_hit): 的意思是“如果弹丸击中列表中有东西”或“如果击中任何弹丸”。对于第二部分,在您的情况下,您在开头(游戏循环之前)添加颗粒,每次调用 pellets.draw 时,它都会绘制精灵组内的所有精灵。
    • 我明白了,我不确定我的代码是否会这样工作,尽管我有一个要绘制的颗粒的坐标列表,我不确定我是否能够只绘制我的颗粒所以很容易,但我会试一试,再次感谢
    • 看,当你使用精灵时,每个精灵都有一个rect 属性,其中包含xy 值。因此,当您创建每个颗粒时,您定义每个xy 值,然后将颗粒添加到组中,然后调用组的绘制方法。我将使用教程和示例代码更新我的答案。
    【解决方案2】:

    经过大量的努力我想通了

    #spawn pellets function
    def spawnpellets(pointspawns):
        abc=0
        efg=0
        px=0
        py=-16
        for row in pointspawns:
            #y co ordinate
            py=py+16    
            for n in row:
                #x co ordinate
                n=n-1
                px=n*16
                point=(pointclass(px, py))
                #used to draw points
                point.draw(screen)
                if pygame.sprite.collide_rect(sprite, point):
                    tempfunc(pointspawns, row, n , py)
    
    def tempfunc(pointspawns, row, n, py):
        abc=n+1
        efg=py/16
        efg=int(efg)
        tempindex=row.index(abc)
        del pointspawns[efg][tempindex]
        pointspawns[int(efg)].insert(abc,0)
    

    本质上,我必须将产生的颗粒放入一个函数中,然后将碰撞检测作为另一个函数,然后在我的 for 循环中使用 vaules 或 row 和 n 计算出我需要的确切列表和索引使用,然后我将元素替换为 0,以便在任何地方都重新绘制。抱歉,如果代码看起来有点乱,并且我知道我的变量名很糟糕,但我确实在 2 小时后才完成了这个,所以我现在要好好休息一下

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-28
      相关资源
      最近更新 更多