Python 如何在蒙版图像上单击鼠标事件[Pygame]

Python 如何在蒙版图像上单击鼠标事件[Pygame],python,python-3.x,pygame,Python,Python 3.x,Pygame,所以我对编程非常陌生,我正在开发一款类似于饼干点击器的游戏,但有点扭曲(挖掘)。它是用python/pygame制作的。无论如何,我有一个巨石的形象,我想添加一块石头到我的库存在游戏中,每次我点击它 有人帮我在班上设置了“碰撞点”。我承认,我不完全理解它是如何工作的,但它应该能检测到我的鼠标是否在我的岩石图像的不透明部分 我希望游戏只给你一块石头,如果你点击我在屏幕中间闪动的巨石图像的不透明部分 简短问题:如何设置游戏,使其仅在我的蒙面图像上注册点击 PS:我知道最好先学习编程的基础知识,但我通

所以我对编程非常陌生,我正在开发一款类似于饼干点击器的游戏,但有点扭曲(挖掘)。它是用python/pygame制作的。无论如何,我有一个巨石的形象,我想添加一块石头到我的库存在游戏中,每次我点击它

有人帮我在班上设置了“碰撞点”。我承认,我不完全理解它是如何工作的,但它应该能检测到我的鼠标是否在我的岩石图像的不透明部分

我希望游戏只给你一块石头,如果你点击我在屏幕中间闪动的巨石图像的不透明部分

简短问题:如何设置游戏,使其仅在我的蒙面图像上注册点击

PS:我知道最好先学习编程的基础知识,但我通过直接投入一个项目学到了很多东西(它让我继续前进,比读书更有趣)

链接到代码:

守则:

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

if (__name__ == "__main__"):

pygame.init()
pygame.font.init()
pygame.display.set_caption("Miner Click")

clock = pygame.time.Clock()
screen = pygame.display.set_mode((960,600))
width = 960
height = 600

GREEN = (0,255,0)
RED = (255,0,0)
BLUE = (0,0,255)
BLACK = (0,0,0)
WHITE = (255,255,255)
BROWN = (84,27,1) 
GREY = (198,198,198)

greenbg = pygame.image.load("greenbg.jpg").convert()
rockbutton = pygame.image.load("rockbutton.png").convert_alpha()
woodbutton = pygame.image.load("woodbutton.png").convert_alpha()

pygame.mouse.set_visible(True)
pick = pygame.image.load("pick.png").convert_alpha()
axe = pygame.image.load("axesmall.png").convert_alpha()

rockwidth = 544
rockheight = 274

clicks = 0
wood = 0

stonefont = pygame.font.SysFont("verdana", 29, True)
woodfont = pygame.font.SysFont("verdana", 29, True)
clicktext = stonefont.render('Rock: ' +str(clicks), 2, (GREY))
woodtext = woodfont.render('Wood: ' +str(wood), 2, (BROWN))
boxsize = clicktext.get_rect()
RocksX = 125
WoodX = 113

class Rock(pygame.sprite.Sprite):

def __init__(self, color = BLUE, width = 544, height = 274):
    super(Rock, self ).__init__()

    self.image = pygame.Surface((width, height))
    self.set_properties()
    self.image.fill(color)

def set_properties(self):
    self.rect = self.image.get_rect()
    self.origin_x = self.rect.centerx
    self.origin_y = self.rect.centery

def set_position(self, x, y):
    self.rect.x = 250
    self.rect.y = 230

def set_image(self, filename = None):
    if (filename != None):
        self.image = pygame.image.load(filename).convert_alpha()

def point_collide(self, point):
    x, y = point
    x -= self.rect.x
    y -= self.rect.y
    try:
        return self.mask.get_at((x,y))
    except IndexError:
        return False

#below is my clueless attempt at getting it to work
def checkForCursorPressed(x,y):
    if pygame.mouse.get_pressed() and pygame.mouse.get_pos() == (x,y):
        clicks+=1

coordfont = pygame.font.SysFont("verdana", 12, True)
rock_group = pygame.sprite.Group()
rock = Rock()
rock.set_image("rock.png")
rock.set_position(width/2, height/2)
rock_group.add(rock)

while True:
    clock.tick(60)
    screen.fill((255,255,255))
    screen.blit(greenbg, (0,0))
    x,y = pygame.mouse.get_pos()
    coords = x,y
    now = datetime.now()
    date = '%s/%s/%s' % (now.month, now.day, now.year)
    label = coordfont.render("Coordinates: "+str(coords), 1, (GREY))
    date = coordfont.render("Date: "+str(date), 1, (GREY))
    screen.blit(date, (650,10))
    screen.blit(label, (790, 10))
    screen.blit(rockbutton, (25,25))
    screen.blit(woodbutton, (25,100))
    clicktext = stonefont.render(' ' +str(clicks), 2, (GREY))
    woodtext = woodfont.render(' ' +str(wood), 2, (BROWN))
    screen.blit(clicktext, [RocksX,38])
    screen.blit(woodtext, [139,WoodX])
    rock_group.draw(screen)
    screen.blit(pick, (x-10,y-50))
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
           sys.exit()
        elif event.type == KEYDOWN and event.key == K_ESCAPE: 
           sys.exit()


        pygame.display.update()

   #in case i need the below again
   #if x>249 and x<(795) and y>210 and y<(484): 
import pygame,sys
从pygame.locals导入*
从日期时间导入日期时间
如果(\uuuuu name\uuuuuu==“\uuuuuu main\uuuuuu”):
pygame.init()
pygame.font.init()
pygame.display.set_标题(“矿工点击”)
clock=pygame.time.clock()
screen=pygame.display.set_模式((960600))
宽度=960
高度=600
绿色=(0255,0)
红色=(255,0,0)
蓝色=(0,0255)
黑色=(0,0,0)
白色=(255255)
布朗=(84,27,1)
灰色=(198)
greenbg=pygame.image.load(“greenbg.jpg”).convert()
rockbutton=pygame.image.load(“rockbutton.png”).convert_alpha()
woodbutton=pygame.image.load(“woodbutton.png”).convert_alpha()
pygame.mouse.set_可见(True)
pick=pygame.image.load(“pick.png”).convert_alpha()
axe=pygame.image.load(“axesmall.png”).convert_alpha()
岩石宽度=544
岩石高度=274
点击次数=0
木材=0
stonefont=pygame.font.SysFont(“verdana”,29,True)
woodfont=pygame.font.SysFont(“verdana”,29,True)
clicktext=stonefont.render('Rock:'+str(点击),2,(灰色))
woodtext=woodfont.render('Wood:'+str(Wood),2,(BROWN))
boxsize=clicktext.get_rect()
岩石x=125
WoodX=113
摇滚类(pygame.sprite.sprite):
def uuu init uuuuuuu(自,颜色=蓝色,宽度=544,高度=274):
超级(摇滚,自我)。\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
self.image=pygame.Surface((宽度、高度))
self.set_属性()
self.image.fill(颜色)
def集合_属性(自身):
self.rect=self.image.get_rect()
self.origin_x=self.rect.centerx
self.origin\u y=self.rect.centery
def设置位置(自身、x、y):
自校正x=250
自校正y=230
def set_图像(自身,文件名=无):
如果(文件名!=无):
self.image=pygame.image.load(文件名).convert_alpha()
def点_碰撞(自身,点):
x、 y=点
x-=self.rect.x
y-=自校正y
尝试:
返回self.mask.get_在((x,y))
除索引器外:
返回错误
#下面是我让它工作的愚蠢尝试
def CHECKFORCURSOR压缩(x,y):
如果pygame.mouse.get_pressed()和pygame.mouse.get_pos()==(x,y):
单击次数+=1
coordfont=pygame.font.SysFont(“verdana”,12,True)
rock_group=pygame.sprite.group()
岩石
rock.set_图像(“rock.png”)
岩石。设置位置(宽度/2,高度/2)
岩石组。添加(岩石)
尽管如此:
时钟滴答(60)
屏幕填充((255255))
屏幕光点(绿色背景,(0,0))
x、 y=pygame.mouse.get_pos()
坐标=x,y
now=datetime.now()
日期=“%s/%s/%s%”(now.month,now.day,now.year)
label=coordfont.render(“坐标:+str(coords),1,(灰色))
date=coordfont.render(“日期:+str(日期),1,(灰色))
屏幕显示(日期(650,10))
屏幕。blit(标签,(790,10))
屏幕blit(rockbutton,(25,25))
屏幕blit(woodbutton,(25100))
clicktext=stonefont.render(“”+str(点击),2,(灰色))
woodtext=woodfont.render(“”+str(wood),2,(BROWN))
blit(点击文本,[RocksX,38])
blit(woodtext,[139,WoodX])
rock_group.draw(屏幕)
屏幕光点(拾取,(x-10,y-50))
对于pygame.event.get()中的事件:
如果event.type==pygame.QUIT:
sys.exit()
elif event.type==KEYDOWN和event.key==K_转义:
sys.exit()
pygame.display.update()
#以防我再次需要下面的

#如果x>249、x210和y单击将创建一个MOUSEBUTTONDOWN事件,那么您应该能够在事件处理循环中处理单击,例如:

for event in pygame.event.get():
    if event.type == pygame.QUIT:
       sys.exit()
    elif event.type == KEYDOWN and event.key == K_ESCAPE:
       sys.exit()
    elif event.type == MOUSEBUTTONDOWN:
        click_position = event.pos
        if rock.point_collide(click_position):
            print('Clicked within the rock')
            clicks += 1
            # Any other events that have to happen
            #   when the rock is clicked

我也不明白point_collide()是如何工作的,我得到了一个AttributeError:“Rock”没有属性“mask”。 所以我将使用另一种可能性来检测是否有人点击了图像的不透明部分,使用colorkey

colorkey定义闪烁时的透明颜色。就我而言,它是白色的:

def set_image(self, filename = None):
    ...
    #sets colorkey to white, depends on the image
    self.image.set_colorkey((255,255,255))
point_collide()的新版本:

def point_碰撞(自身,点):
x、 y=点
x-=self.rect.x
y-=自校正y
#检测单击是否命中图像
如果0正常,我让它工作:)

如果有人想做类似的事情,我会在这里解释

在代码中输入以下内容(这解决了我遇到的“Rock没有属性掩码”错误)

这里是我把它放在代码中的地方(在我的set_image def中)


现在把这段代码和马吕斯结合起来,它就完美地工作了

嘿,谢谢!这就是我一直在寻找的:)虽然我得到了一个错误行72“岩石”对象没有属性“面具”看起来像一个很好的替代品,但还没有测试它,所以我不知道它是否适合我。我确实找到了AttributeError的解决方案:“Rock”没有属性“mask”(在下面的回答中解释)感谢您的帮助,如果我遇到更多问题,我将尝试此方法:)
def point_collide(self, point):
   x, y = point
   x -= self.rect.x
   y -= self.rect.y
   #detects if click hits the image
   if 0 <= x < self.image.get_width():
       if 0 <= y < self.image.get_height():
           #detects if color at clicking position != colorkey-color(transparent)
           if self.image.get_at((x,y))[0:3] != self.image.get_colorkey()[0:3]:
               return True
   return False
self.mask = pygame.mask.from_surface(self.image)
def set_image(self, filename = None):
    if (filename != None):
        self.image = pygame.image.load(filename).convert_alpha()
        self.mask = pygame.mask.from_surface(self.image)