Pygame按键应该只调用一次函数

时间:2015-02-16 08:47:54

标签: python function pygame key-events

你好标题说它基本上都是...... 再描述一下: 它是一个2D随机的瓷砖地图,你可以移动一个玩家,他可以开采煤炭。 问题在于,如果他站在煤炭上并多次挤压空间,煤炭会被多次添加到他的库存中,这就是问题所在。他可以开采更多煤炭,甚至不再有煤炭。 我搜索了谷歌,但我发现的唯一的事情是我必须使用标志,一些布尔值......但如何?

我知道编写的代码很脏,很难等......可以优化......

import random
import pygame
import Images_raw
from colors import *
from timeit import default_timer as timer


pygame.init()
#----------------------------------------------------------------------------------------------------------------------
#pygame Display settings
display_width=704;  display_height=512
gameDisplay=pygame.display.set_mode((display_width,display_height))
pygame.display.set_caption('2D Coal miner')

# Misc
clock = pygame.time.Clock()
font = pygame.font.SysFont(None, 25)
mouseX=int;    mouseY=int

class Map:
    def __init__(self):
        global mapp,mapSize,mappSurfaces,QD_array,inventory,ammount,minedCoal
        mapSize=100
        ammount=0
        mapp=[[random.randint(0,1) for i in range(mapSize)] for i in range(mapSize)]
        mappSurfaces=mapp
        QD_array=[[random.randint(0,1) for i in range(mapSize)] for i in range(mapSize)]
        inventory=[[{'item':ammount} for i in range(5)] for i in range(5)]
        minedCoal=[]

    def createMap(self):
        global tileImage,recti,coalRect_list,chacheList
        tileImage=pygame.Surface
        coalRect=pygame.Surface
        coalRect_list=[]
        chacheList=[]

        for i in range(mapSize):
            for j in range(mapSize):
                randNum=random.randint(0,11)
                randNum2=random.randint(0,1)

                if randNum == 0 and randNum2==1:
                    tileImage= Images_raw.coal_img
                    QD_array[i][j]=0

                elif randNum== 2 and randNum2<= 9:
                    tileImage= Images_raw.water_img
                    QD_array[i][j]=1

                elif randNum>= 3 or randNum2>= 12:
                    tileImage= Images_raw.grass_img
                    QD_array[i][j]=2

                elif randNum== 5 or randNum2== 5:
                    tileImage= Images_raw.stone_img
                    QD_array[i][j]=3
                else:
                    tileImage= Images_raw.dirt_img
                    QD_array[i][j]=4

                mappSurfaces[i][j]=tileImage

        for k in range(mapSize):
            for l in range(mapSize):
                if QD_array[k][l]==0:
                    coalRect=pygame.Rect(k*32,l*32,32,32)
                    coalRect_list.append(coalRect)
                else:
                    pass

    def mineCoalAt(self,noCoal):

        for i in range(mapSize):
            for j in range(mapSize):
                if QD_array[i][j]==0:
                    chacheList.append((i,j))

        x=chacheList[noCoal][0]
        y=chacheList[noCoal][1]

        QD_array[x][y]=10

        inventory[0][0]['item']+=1

    def update(self,x_dif,y_dif):
        for i in range(mapSize):
            for j in range(mapSize):
                if QD_array[i][j] == 0:
                    tileImage= Images_raw.coal_img

                elif QD_array[i][j]== 1:
                    tileImage= Images_raw.water_img

                elif QD_array[i][j]== 2:
                    tileImage= Images_raw.grass_img

                elif QD_array[i][j]== 3:
                    tileImage= Images_raw.stone_img

                elif QD_array[i][j]== 10:
                    tileImage= Images_raw.coalUsed_img
                else:
                    tileImage= Images_raw.dirt_img

                mappSurfaces[i][j]=tileImage
                gameDisplay.blit(mappSurfaces[i][j],(x_dif+(i*32),y_dif+(j*32)),None,0)


#----------------------------------------------------------------------------------------------------------------------

# Main game function
#----------------------------------------------------------------------------------------------------------------------
def gameLoop():
    gameExit=False; outRight=False
    player_X=11;   player_Y=8
    allowMovement=False
    moveRight,moveLeft,moveUp,moveDown=False,False,False,False
    Space,sSpace=False,False
    x_difference,y_difference=0,0
    mapO=Map()
    mapO.createMap()
    counter=0
    allowMovement=True


    while not gameExit:
#-----------event loop---------------------------------------------------------
        for event in pygame.event.get():

            if event.type == pygame.QUIT:
                gameExit = True

            elif event.type == pygame.KEYDOWN:
                if (event.key == pygame.K_DOWN):
                    moveDown=True
                elif(event.key == pygame.K_UP):
                    moveUp=True
                elif(event.key == pygame.K_LEFT):
                    moveLeft=True
                elif(event.key == pygame.K_RIGHT):
                    moveRight=True
                elif(event.key == pygame.K_p):
                    print(player_X*32,player_Y*32)
                elif(event.key == pygame.K_SPACE):
                    Space=True
                elif(event.key == pygame.K_i):
                    print(inventory)

            elif event.type == pygame.KEYUP:
                if (event.key == pygame.K_DOWN):
                    moveDown=False
                elif(event.key == pygame.K_UP):
                    moveUp=False
                elif(event.key == pygame.K_LEFT):
                    moveLeft=False
                elif(event.key == pygame.K_RIGHT):
                    moveRight=False
                elif(event.key == pygame.K_SPACE):
                    Space=False


#-----------event loop END-----------------------------------------------------
        a=len(coalRect_list)

        #Logical/Main part

        if allowMovement==True:
            if moveRight==True:
                player_X+=1
                x_difference-=32
                for i in range(a):
                    coalRect_list[i].x-=32

            elif moveLeft==True:
                player_X-=1
                x_difference+=32
                for i in range(a):
                    coalRect_list[i].x+=32

            elif moveDown==True:
                 player_Y+=1
                 y_difference-=32
                 for i in range(a):
                    coalRect_list[i].y-=32

            elif moveUp==True:
                player_Y-=1
                y_difference+=32
                for i in range(a):
                    coalRect_list[i].y+=32

            else:
                player_X+=0;player_Y+=0
                y_difference+=0;x_difference+=0

            if Space==True:
                sSpace=True
            else:
                sSpace=False
        else:
            pass

        #Drawing objects to screen part
        gameDisplay.fill(white)  #Backgroundcolor

        mapO.update(x_difference,y_difference)
        playerRect=gameDisplay.blit(Images_raw.man_img,(player_X*0+352,player_Y*0+256),None,0)

        aba=playerRect.collidelist(coalRect_list)



        '''
        if aba!=-1 and sSpace==True:
            counter+=1


            if counter==1:
                minedCoal.append(aba)
                mapO.mineCoalAt(aba)
                inventory[0][0]['item']+=1
            elif counter==2:
                counter=0

            else:
                pass
        '''

        if aba!=1:
            if sSpace==True:
                minedCoal.append(aba)
                mapO.mineCoalAt(aba)

            else:
                pass

        #Update everything and set FPS-timer
        pygame.display.update()
        clock.tick(20)

    #Needed so that the program gets closed properly
    pygame.quit()
    quit()
#----------------------------------------------------------------------------------------------------------------------
#End of the Main game function
#---Normal coding goes on

#call the gameLoop
gameLoop()

1 个答案:

答案 0 :(得分:2)

您的代码存在很多问题,但请关注您的问题:

aba=playerRect.collidelist(coalRect_list)

aba现在包含Rect中与coalRect_listplayerRect发生碰撞的第一个-1的索引。

if aba!=1:
    if sSpace==True:
         minedCoal.append(aba)
         mapO.mineCoalAt(aba)
     else:
         pass

我想你想在这里查看aba != -1,因为-1表示没有发生碰撞:

if aba != -1 and sSpace:
    ...

现在发生的事情取决于您,但我想您要从地图中移除煤炭,因此您只需从Rect

中移除coalRect_list即可
if aba != -1 and sSpace:
    minedCoal.append(aba)
    mapO.mineCoalAt(aba)
    del coalRect_list[aba]

由于您只使用coalRect_list检查煤炭是否可以开采,这应该足够了。