Python pygame检测鼠标是否位于曲面的不透明部分上
我正在尝试为我的游戏制作一个UI,UI上有一些曲线。现在我可以检测两个曲面之间的碰撞。我可以通过像素在两个精灵之间进行检测,但似乎通过像素检测鼠标暗指我。基本上,我想检测鼠标何时在UI上,然后在获取UI时忽略鼠标下方的所有内容 这是一张到目前为止我所拥有的照片。如果您注意到粉红色的方块,则鼠标位于GUI上方,而黄色的选择器框位于平铺上方。黄色选择器是瓷砖上方的框框 我在openGL中使用pygame,但目前我正在寻找解决方案。我可以很容易地适应,因为我对编程并不陌生,而且我也在寻找解决方案。 我也会发布代码,但要发布的代码太多,所以如果需要特定的东西,请让我知道Python pygame检测鼠标是否位于曲面的不透明部分上,python,opengl,python-2.7,pygame,Python,Opengl,Python 2.7,Pygame,我正在尝试为我的游戏制作一个UI,UI上有一些曲线。现在我可以检测两个曲面之间的碰撞。我可以通过像素在两个精灵之间进行检测,但似乎通过像素检测鼠标暗指我。基本上,我想检测鼠标何时在UI上,然后在获取UI时忽略鼠标下方的所有内容 这是一张到目前为止我所拥有的照片。如果您注意到粉红色的方块,则鼠标位于GUI上方,而黄色的选择器框位于平铺上方。黄色选择器是瓷砖上方的框框 我在openGL中使用pygame,但目前我正在寻找解决方案。我可以很容易地适应,因为我对编程并不陌生,而且我也在寻找解决方案。 我
需要注意的一点是,GUI是可伸缩的,因为左上角区域将滑入滑出。此外,白色只是占位符,因此不使用最终颜色,很难检查。按z顺序单击时,是否可以在鼠标下获取曲面元素 纹理
import pygame
from OpenGL.GL import *
from OpenGL.GLU import *
class Texture(object):
image = None
rect = None
src = ''
x = 0
y = 0
'''
zOrder Layers
0 - background
1 -
2 -
3 - Tile Selector
s - Tiles
5 -
6 -
7 - Panels
8 - Main Menu
9 - GUI Buttons
10 -
'''
def __init__(self, src):
self.src = src
self.image = pygame.image.load(src)
self.image.set_colorkey(pygame.Color(255,0,255,0))
self.rect = self.image.get_rect()
texdata = pygame.image.tostring(self.image,"RGBA",0)
# create an object textures
self.texid = glGenTextures(1)
# bind object textures
glBindTexture(GL_TEXTURE_2D, self.texid)
# set texture filters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
# Create texture image
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,self.rect.w,self.rect.h,0,GL_RGBA,GL_UNSIGNED_BYTE,texdata)
self.newList = glGenLists(2)
glNewList(self.newList, GL_COMPILE)
glBindTexture(GL_TEXTURE_2D, self.texid)
glBegin(GL_QUADS)
glTexCoord2f(0, 0); glVertex3f(0, 0 ,0)
glTexCoord2f(0, 1); glVertex3f(0, self.rect.h, 0)
glTexCoord2f(1, 1); glVertex3f(self.rect.w, self.rect.h, 0)
glTexCoord2f(1, 0); glVertex3f(self.rect.w, 0, 0)
glEnd()
glEndList()
def getImg(self):
return self.image
def getPos(self):
rect = self.getImg().get_rect()
pos = dict(x=self.x,y=self.y,w=rect[2],h=rect[3])
return pos
def draw(self,x,y,rotate=0):
glLoadIdentity()
self.x = int(x)
self.y = int(y-self.rect.h+32)
glTranslatef(x,y-self.rect.h+32,0)
glPushAttrib(GL_TRANSFORM_BIT)
glMatrixMode(GL_TEXTURE)
glLoadIdentity()
glRotatef(rotate,0,0,1)
glPopAttrib()
if glIsList(self.newList):
glCallList(self.newList)
def getCordInImage(self, x, y, t):
return [x - t.x, y - t.y]
gui类
import hashlib, string, pygame
from classes.texture import Texture
'''
Created on Jun 2, 2013
@author: Joel
'''
class gui(object):
INSTANCES = 0 # Count of instances of buildings
ID = 0 # Building ID
TYPE = 0 # Building type
NAME = '' # name of Building
DESCRIPTION = '' # Description of building
IMAGE = '' # Image name of building
zOrder = 0
clickable = True
def __init__(self, Game, name = 'Building', description = '', image = 'panel'):
self.INSTANCES += 1
self.setName(name)
self.setDescription(description)
self.setImage(Game, Game.SETTING["DIR"]["IMAGES"] + Game.SETTING["THEME"] + '\\gui\\'+image+'.png')
self.setType(name.lower())
self.setZ(6)
def getDescription(self):
return self.DESCRIPTION
def setDescription(self, description):
self.DESCRIPTION = description
def getID(self):
return self.ID
def setID(self, i):
allchr = string.maketrans('','')
nodigits = allchr.translate(allchr, string.digits)
s = hashlib.sha224(i).hexdigest()
s = s.translate(allchr, nodigits)
self.ID = s[-16:]
def getImage(self):
return self.IMAGE
def setImage(self, Game, i):
self.IMAGE = Texture(Game.CWD + '\\' + i)
def getName(self):
return self.NAME
def setName(self, name):
self.NAME = name
def getType(self):
return self.TYPE
def setType(self, t):
self.TYPE = t
def click(self, x, y):
if pygame.mouse.get_pressed()[0] == 1:
if x > self.x and x < (self.x + self.rect.w):
if y > self.y and y < (self.y + self.rect.h):
print("Clicked: " + str(self.x) + ', ' + str(self.y) + ', ' + str(self.rect.w) + ', ' + str(self.rect.y))
def getClickable(self):
return self.clickable
def setClickable(self, c):
self.clickable = c
def getZ(self):
return self.zOrder
def setZ(self, z):
self.zOrder = z
导入hashlib、string、pygame
从class.texture导入纹理
'''
创建于2013年6月2日
@作者:乔尔
'''
类gui(对象):
实例=0#建筑物实例计数
ID=0#建筑物ID
类型=0#建筑类型
名称=“”#建筑物名称
描述=''#建筑物描述
图像=“”#建筑物的图像名称
zOrder=0
可点击=真
def uuu init uuuuuu(自我,游戏,名称='Building',描述='',图像='panel'):
self.INSTANCES+=1
self.setName(名称)
self.setDescription(描述)
self.setImage(Game,Game.SETTING[“DIR”][“IMAGES”]+Game.SETTING[“THEME”]+'\\gui\\\'+image+'.png')
self.setType(name.lower())
self.setZ(6)
def getDescription(自我):
返回自我描述
def setDescription(自我,描述):
self.DESCRIPTION=描述
def getID(自身):
返回self.ID
def setID(自我,i):
allchr=string.maketrans(“”,“”)
nodigits=allchr.translate(allchr,string.digits)
s=hashlib.sha224(i).hexdigest()
s=s.translate(所有chr、nodigits)
self.ID=s[-16:]
def getImage(自我):
回归自我形象
def setImage(自我、游戏、i):
self.IMAGE=纹理(Game.CWD+'\\'+i)
def getName(self):
返回self.NAME
def setName(自我,名称):
self.NAME=名称
def getType(self):
返回自我类型
def设置类型(自身,t):
self.TYPE=t
def单击(自身、x、y):
如果pygame.mouse.get_pressed()[0]==1:
如果x>self.x和x<(self.x+self.rect.w):
如果y>self.y和y<(self.y+self.rect.h):
打印(“单击:”+str(self.x)+'、“+str(self.y)+'、“+str(self.rect.w)+'、“+str(self.rect.y))
def可点击(自身):
返回self.clickable
def设置可点击(自身,c):
self.clickable=c
def getZ(自我):
返回self.zOrder
def setZ(自身,z):
self.zOrder=z
两个可能的答案:
1) 静态地创建一个与屏幕一样大的二维真或假数组-如果单击此处将单击UI,则为真;如果单击此处将不单击UI,则为假。针对此阵列中的位置进行测试单击
2) 使用“绘制并检查”算法(不要回忆起真实姓名)。你知道当你在屏幕上画图时,你是如何画背景的,然后是背景对象,然后是前景对象的吗?您可以使用类似的技巧来检测您单击的对象-以一种纯色绘制背景,以另一种纯色绘制每个对象,以另一种纯色绘制每个UI元素,等等。。。只要每种纯色都是唯一的,您就可以测试此缓冲区中光标下的颜色像素,并使用它来确定鼠标单击的可见颜色。两种可能的答案:
1) 静态地创建一个与屏幕一样大的二维真或假数组-如果单击此处将单击UI,则为真;如果单击此处将不单击UI,则为假。针对此阵列中的位置进行测试单击
2) 使用“绘制并检查”算法(不要回忆起真实姓名)。你知道当你在屏幕上画图时,你是如何画背景的,然后是背景对象,然后是前景对象的吗?您可以使用类似的技巧来检测您单击的对象-以一种纯色绘制背景,以另一种纯色绘制每个对象,以另一种纯色绘制每个UI元素,等等。。。只要每种纯色都是唯一的,您就可以测试此缓冲区中光标下的颜色像素,并使用它来确定鼠标可以看到和点击的内容。您可以创建UI的遮罩(如果UI包含在一个表面中,然后应用于屏幕表面,这将是最简单的),并将遮罩的阈值设置为适当的值,以便在遮罩中将透明像素设置为
0
使用遮罩对象的get_at((x,y))
功能,您可以测试是否设置了遮罩的特定像素(如果设置了像素,则返回非零值)
如果在鼠标位置传递,如果收到非零值,则可以验证鼠标是否位于UI的可见部分上。可以创建UI的掩码(如果UI包含在一个曲面中,然后应用到屏幕曲面上,这将是最简单的),并将遮罩的阈值设置为适当的值,以便在遮罩中将透明像素设置为
0
使用掩码对象的get_at((x,y))
函数,您可以测试特定的p
def getCordInImage(self, x, y, t):
return [x - t.x, y - t.y]
def getAlphaOfPixel(self, t):
mx,my = pygame.mouse.get_pos()
x,y = self.getCordInImage(mx,my,t.IMAGE)
#mask = pygame.mask.from_surface(t.IMAGE.image)
return t.IMAGE.image.get_at([x,y])[3]
def screen2iso(self, x, y):
x = x / 2
xx = (y + x) / (self.SETTING['TILE_WIDTH'] / 2)
yy = (y - x) / (self.SETTING['TILE_WIDTH'] / 2)
return xx, yy
def iso2screen(self, x, y):
xx = (x - y) * (self.SETTING['TILE_WIDTH'] / 2)
yy = (x + y) * (self.SETTING['TILE_HEIGHT'] / 2)
return xx, yy