Pygame 按键应该只调用一次函数
Pygame keypress should call function just once
嗨,标题说的基本上都是...
再描述一下:
它是一个 2D 随机瓦片地图,你可以在上面移动玩家,他可以开采煤炭。
问题是,如果他站在煤上并按 space 不止一次,那么煤就会被多次添加到他的库存中,那就是 problem.He 可以开采更多的煤,甚至没有更多.
我搜索了 google 但我唯一发现的是我必须使用标志,一些布尔值......但是如何?
我知道代码写的很脏,很丑等等...可以优化...
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()
你的代码有很多问题,但让我们专注于你的问题:
aba=playerRect.collidelist(coalRect_list)
aba
现在包含 coalRect_list
中与 playerRect
或 -1
.
冲突的第一个 Rect
的索引
if aba!=1:
if sSpace==True:
minedCoal.append(aba)
mapO.mineCoalAt(aba)
else:
pass
我猜你想在这里检查 aba != -1
,因为 -1
表示没有发生碰撞:
if aba != -1 and sSpace:
...
现在怎么办取决于你,但我想你想从地图上移除煤炭,所以你可以简单地从 coalRect_list
中移除 Rect
if aba != -1 and sSpace:
minedCoal.append(aba)
mapO.mineCoalAt(aba)
del coalRect_list[aba]
因为你只用coalRect_list
检查煤炭是否可以开采,这应该足够了。
嗨,标题说的基本上都是... 再描述一下: 它是一个 2D 随机瓦片地图,你可以在上面移动玩家,他可以开采煤炭。 问题是,如果他站在煤上并按 space 不止一次,那么煤就会被多次添加到他的库存中,那就是 problem.He 可以开采更多的煤,甚至没有更多. 我搜索了 google 但我唯一发现的是我必须使用标志,一些布尔值......但是如何?
我知道代码写的很脏,很丑等等...可以优化...
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()
你的代码有很多问题,但让我们专注于你的问题:
aba=playerRect.collidelist(coalRect_list)
aba
现在包含 coalRect_list
中与 playerRect
或 -1
.
Rect
的索引
if aba!=1:
if sSpace==True:
minedCoal.append(aba)
mapO.mineCoalAt(aba)
else:
pass
我猜你想在这里检查 aba != -1
,因为 -1
表示没有发生碰撞:
if aba != -1 and sSpace:
...
现在怎么办取决于你,但我想你想从地图上移除煤炭,所以你可以简单地从 coalRect_list
Rect
if aba != -1 and sSpace:
minedCoal.append(aba)
mapO.mineCoalAt(aba)
del coalRect_list[aba]
因为你只用coalRect_list
检查煤炭是否可以开采,这应该足够了。