1

ゲームの UI を作成しようとしていますが、UI にいくつかの曲線があります。これで、2 つのサーフェス間の衝突を検出できます。2 つのスプライト間をピクセル単位で検出できますが、ピクセル単位のマウス検出が暗示されているようです。基本的に、マウスが UI の上にあることを検出し、UI を取得している間はその下のすべてを無視したいと考えています。

これは私がこれまでに持っているものの写真です。ピンクの四角が GUI の上にあり、黄色のセレクター ボックスがタイルの上にある場合。黄色のセレクターは、タイルの上のボックス フレームです。

私はopenGLでpygameを使用していますが、現時点ではこれに対する解決策を探しています。私はプログラミングが初めてではなく、解決策をほとんど探しているので、非常に簡単に適応できます。また、コードを投稿しますが、投稿するコードが多いため、特定のものが必要な場合はお知らせください。

注意すべきことの 1 つは、左上の領域がスライドインおよびスライドアウトするという点で、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)

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

パイゲーム

4

3 に答える 3

2

UI のマスクを作成し (これは、UI が 1 つのサーフェスに含まれており、それが画面サーフェスに適用される場合に最も簡単です)、マスクのしきい値を適切な値に設定して、透明ピクセルが0マスクで。

http://www.pygame.org/docs/ref/mask.html#pygame.mask.from_surface

マスク オブジェクトのget_at((x,y))関数を使用すると、マスクの特定のピクセルが設定されているかどうかをテストできます (ピクセルが設定されている場合は、0 以外の値が返されます)。

http://www.pygame.org/docs/ref/mask.html#pygame.mask.Mask.get_at

マウスの位置を渡すと、0 以外の値を受け取った場合に UI の表示部分の上にあることを確認できます。

于 2013-06-07T13:59:50.927 に答える
1

考えられる答えは 2 つあります。

1) 画面と同じ大きさの True または False の 2D 配列を静的に作成します。ここをクリックすると UI がクリックされる場合は True、ここをクリックしても UI がクリックされない場合は False です。この配列の位置に対してクリックをテストします。

2) 「ペイント アンド チェック」アルゴリズムを使用します (実際の名前は思い出さないでください)。画面に描画するときに、背景、背景オブジェクト、前景オブジェクトの順に描画する方法を知っていますか? 同様のトリックを使用して、クリックしたオブジェクトを検出できます。背景を 1 つの単色で描画し、各オブジェクトを別の単色で描画し、各 UI 要素を別の単色で描画します。このバッファー内のカーソルの下にある色のピクセルをテストし、それを使用して、マウスで表示およびクリックされたものを判断できます。

于 2013-06-07T05:15:46.110 に答える