Heim  >  Artikel  >  Backend-Entwicklung  >  So erstellen Sie ein Spielskript in Python

So erstellen Sie ein Spielskript in Python

(*-*)浩
(*-*)浩Original
2019-07-04 10:44:188820Durchsuche

In diesem Artikel wird das 4399-Minispiel „Pet Lianliankan Classic Edition 2“ als Testfall verwendet. Durch die Identifizierung kleiner Symbole und die Simulation von Mausklicks kann die Kopplung schnell abgeschlossen werden, um das Spielskript zu vervollständigen.

So erstellen Sie ein Spielskript in PythonDer Browser öffnet das Spielfenster (Einzelfenster). Der Screenshot der Hauptoberfläche des Spiels erfordert im Allgemeinen zwei Koordinaten (Koordinaten der oberen linken Ecke und Koordinaten der unteren rechten Ecke). Die obere linke Ecke des Bildschirms und die Koordinaten sind unsicher. Schüler, die auf den Wert klicken, können einen Vollbild-Screenshot erstellen und eine Bildbearbeitungssoftware verwenden, um die Koordinatenwerte anzuzeigen. (Empfohlenes Lernen: Python-Video-Tutorial)

Holen Sie sich das Fensterhandle, hier ist der Titel der Browser-Titelleiste (Rechtsklick - Quellcode anzeigen - Titel, plus Softwarename) Für Beispiel: „Pet Lianliankan Classic 2, Pet Lianliankan Classic Edition 2 Minispiele, 4399 Minispiele www.4399.com – Google Chrome“. Schnappen Sie sich den Fenstergriff und schon kann es losgehen.

Gesamtentwicklungsidee: Das Hauptbild des Spiels abfangen ---> jedes kleine Bild vergleichen, die Vertrautheit des Bildes vergleichen und die Zahl in der Matrix speichern-- -> Paarmatrix Führen Sie verknüpfbare Berechnungen durch --->

Holen Sie sich das Fensterhandle und platzieren Sie das Fenster oben

Python kann das Win32gui-Modul verwenden, um die Windows-API aufzurufen, um das Fenster zu bedienen, und FindWindow() verwenden Um das Fensterhandle (Handle) zu erhalten, müssen Sie zwei Parameter übergeben. Der erste ist das übergeordnete Fensterhandle (geben Sie hier einfach 0 ein) und der zweite Parameter ist der Name des Fensters (Beschriftungstitel – Google Chrome). ). Nachdem Sie das Handle erhalten haben, legen Sie das Fenster über SetForegroundWindows() fest. Hier können Sie den Bericht des Spielfensters übergeben:

import win32gui

class GameAssist:

    def __init__(self, wdname):
        """初始化"""

        # 取得窗口句柄
        self.hwnd = win32gui.FindWindow(0, wdname)
        if not self.hwnd:
            print("窗口找不到,请确认窗口句柄名称:【%s】" % wdname )
            exit()
        # 窗口显示最前面
        win32gui.SetForegroundWindow(self.hwnd)


if __name__ == "__main__":
    # wdname 为连连看窗口的名称,必须写完整
    wdname = u'宠物连连看经典版2,宠物连连看经典版2小游戏,4399小游戏 www.4399.com - Google Chrome'

    demo = GameAssist(wdname)
    demo.start()

Intercept the game interface, split the Symbol und vergleichen Sie die Bilder

Die Überprüfung des Programms dauert einige Zeit. Wenn das aufgenommene Bild nicht gut ist, wirkt sich dies auf nachfolgende Vorgänge aus. Daher ist es am wichtigsten, es zu bestätigen Koordinatenwerte der oberen linken Ecke und der unteren rechten Ecke des Spiels sowie jeweils die Breite und Höhe des kleinen Symbols. Wie in der folgenden Abbildung gezeigt, fangen Sie zuerst das gesamte Spielschnittstellendiagramm ab, teilen Sie dann die kleinen Symbole auf, vergleichen Sie dann jedes Symbol und ersetzen Sie dann das Symbol durch eine Zahl und speichern Sie es in der Matrix (die Zahlenmatrix stimmt hier nicht mit dem Spiel überein). Diagramm, das Prinzip ist das gleiche).

So erstellen Sie ein Spielskript in PythonVerwenden Sie die Methode ImageGrab.grab(), um einen Screenshot basierend auf den beiden durch die Initialisierung festgelegten Koordinaten der oberen linken Ecke und der unteren rechten Ecke zu erstellen. Übergeben Sie einfach ein Tupel und teilen Sie es dann auf Schneiden Sie das große Bild nacheinander in kleine Symbole im Array images_list.

def screenshot(self):
        """屏幕截图"""

        # 1、用grab函数截图,参数为左上角和右下角左标
        # image = ImageGrab.grab((417, 257, 885, 569))
        image = ImageGrab.grab(self.scree_left_and_right_point)

        # 2、分切小图
        # exit()
        image_list = {}
        offset = self.im_width  # 39

        # 8行12列
        for x in range(8):
            image_list[x] = {}
            for y in range(12):
                # print("show",x, y)
                # exit()
                top = x * offset
                left = y * offset
                right = (y + 1) * offset
                bottom = (x + 1) * offset

                # 用crop函数切割成小图标,参数为图标的左上角和右下角左边
                im = image.crop((left, top, right, bottom))
                # 将切割好的图标存入对应的位置
                image_list[x][y] = im

        return image_list

Das durch den obigen Code ausgeschnittene kleine Symbol wird in eine numerische Matrix umgewandelt. Wenn das Symbol in image_type_list gespeichert wurde, wird der Index zurückgegeben. Wenn er nicht vorhanden ist, wird er angehängt Die aktuelle Länge ist die Nummer des neu hinzugefügten Symbols. Der Code lautet wie folgt:

def image2num(self, image_list):
        """将图标矩阵转换成数字矩阵"""

        # 1、创建全零矩阵和空的一维数组
        arr = np.zeros((10, 14), dtype=np.int32)    # 以数字代替图片
        image_type_list = []

        # 2、识别出不同的图片,将图片矩阵转换成数字矩阵
        for i in range(len(image_list)):
            for j in range(len(image_list[0])):
                im = image_list[i][j]
                
                # 验证当前图标是否已存入
                index = self.getIndex(im, image_type_list)

                # 不存在image_type_list
                if index <p>Der obige getIndex dient zum Vergleichen der Bilder, um festzustellen, ob das Symbol angezeigt wurde (ob es bereits in der image_type_list vorhanden ist). Wenn nicht, wird es hinzugefügt.) Hier wird der Hamming-Abstand verwendet, um die Bekanntheit der beiden Bilder zu bestimmen. Stellen Sie den Schwellenwert auf 10 ein. Wenn er kleiner als der Schwellenwert ist, wird davon ausgegangen, dass es sich um dasselbe Bild handelt. Der spezifische Code lautet wie folgt: </p><pre class="brush:php;toolbar:false"># 检查数组中是否有图标,如果有则返回索引下表
    def getIndex(self,im, im_list):
        for i in range(len(im_list)):
            if self.isMatch(im, im_list[i]):
                return i

        return -1

    # 汉明距离判断两个图标是否一样
    def isMatch(self, im1, im2):

        # 缩小图标,转成灰度
        image1 = im1.resize((20, 20), Image.ANTIALIAS).convert("L")
        image2 = im2.resize((20, 20), Image.ANTIALIAS).convert("L")

        # 将灰度图标转成01串,即系二进制数据
        pixels1 = list(image1.getdata())
        pixels2 = list(image2.getdata())

        avg1 = sum(pixels1) / len(pixels1)
        avg2 = sum(pixels2) / len(pixels2)
        hash1 = "".join(map(lambda p: "1" if p > avg1 else "0", pixels1))
        hash2 = "".join(map(lambda p: "1" if p > avg2 else "0", pixels2))

        # 统计两个01串不同数字的个数
        match = sum(map(operator.ne, hash1, hash2))

        # 阀值设为10
        return match <p>Programmkern-Symbol-Verbindungsalgorithmus (Pfadfindung)</p><p>Hier ist nur der Algorithmuscode Führen Sie eine einfache Analyse durch, wenn Sie das Programm nicht verstehen Nun, Sie können eine Nachricht hinterlassen und anschließend eine grafische Analyse durchführen. </p><p>Durch den obigen Entwicklungsprozess können Sie im Grunde eine Matrix wie die folgende erhalten. Vergleichen Sie einfach zwei Werte mit derselben Zahl, um verbindbare Pfade zu finden. Hier ist eine kurze Einführung in die Spielregeln: 8 Zeilen mal 12 Spalten des Spielsymbolbereichs. Die 0 in der Peripherie bedeutet tatsächlich, dass bei der Suche nach einem Pfad beispielsweise die Koordinaten (1, 1) übergeben werden können verbunden mit (1, 10), (7, 1) Mit (7,2) verbinden. Die Idee der </p><pre class="brush:php;toolbar:false">arr = [
    [ 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0],
    [ 0,  1,  2,  3,  4,  5,  4,  6,  7,  2,  1,  1,  8,  0],
    [ 0,  9,  3,  3, 10,  4,  7, 11,  7,  2,  3,  1,  6,  0],
    [ 0,  6,  7,  4, 11,  5,  8,  1,  6,  5,  4,  2,  8,  0],
    [ 0,  6,  2,  9,  6,  8,  9,  7, 12, 11,  3, 11, 11,  0],
    [ 0,  5,  9,  8,  9,  2,  6, 11, 11,  3,  9,  2, 12,  0],
    [ 0, 12,  5, 12,  5, 10,  5,  6,  5,  7, 12,  4,  3,  0],
    [ 0,  1,  8, 10, 12,  9, 10,  4,  3,  7,  2,  1, 10,  0],
    [ 0,  1,  4, 10,  8, 12, 10, 10,  9, 12,  8,  7, 11,  0],
    [ 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0]
]

-Methode: Um einen Pfad zu finden, suchen Sie zunächst einen Satz von Koordinaten, die horizontal und vertikal direkt verbunden werden können. Beispielsweise hat ein Satz wie die Koordinate p1 (1,1). [ (0,1), ( 1,0)] und der verbindbare Satz einer anderen Koordinate p2 (1,10) ist [(0,10)], und vergleichen Sie dann die verbindbaren Koordinatensätze von p1 und p2 Die Koordinaten im Satz sind ebenfalls verbindbar. Dies bedeutet, dass p1 und p2 verbunden werden können. Offensichtlich liegen (0,1) und (0,10) auf derselben Linie und können verbunden werden p1 und p2. Der Code lautet wie folgt:

Eine kurze Analyse des Code-Implementierungsprozesses: Übergeben Sie zwei Koordinatenwerte, die in isReachable() verglichen werden müssen, und erhalten Sie dann die möglichen Koordinatensätze Verbinden Sie die beiden Punkte in horizontaler und vertikaler Richtung (isRowConnect(), isColConnect()) und durchlaufen Sie schließlich die Sammlung und vergleichen Sie, ob es eine verknüpfbare gibt. Wenn sie vorhanden ist, bedeutet dies, dass die beiden eingehenden Koordinaten verbunden werden können.

# 是否为同行或同列且可连
    def isReachable(self, x1, y1, x2, y2):
        # 1、先判断值是否相同
        if self.im2num_arr[x1][y1] != self.im2num_arr[x2][y2]:
            return False

        # 1、分别获取两个坐标同行或同列可连的坐标数组
        list1 = self.getDirectConnectList(x1, y1)
        list2 = self.getDirectConnectList(x2, y2)
        # print(x1, y1, list1)
        # print(x2, y2, list2)

        # exit()

        # 2、比较坐标数组中是否可连
        for x1, y1 in list1:
            for x2, y2 in list2:
                if self.isDirectConnect(x1, y1, x2, y2):
                    return True
        return False

    # 获取同行或同列可连的坐标数组
    def getDirectConnectList(self, x, y):

        plist = []
        for px in range(0, 10):
            for py in range(0, 14):
                # 获取同行或同列且为0的坐标
                if self.im2num_arr[px][py] == 0 and self.isDirectConnect(x, y, px, py):
                    plist.append([px, py])

        return plist

    # 是否为同行或同列且可连
    def isDirectConnect(self, x1, y1, x2, y2):
        # 1、位置完全相同
        if x1 == x2 and y1 == y2:
            return False

        # 2、行列都不同的
        if x1 != x2 and y1 != y2:
            return False

        # 3、同行
        if x1 == x2 and self.isRowConnect(x1, y1, y2):
            return True

        # 4、同列
        if y1 == y2 and self.isColConnect(y1, x1, x2):
            return True

        return False

    # 判断同行是否可连
    def isRowConnect(self, x, y1, y2):
        minY = min(y1, y2)
        maxY = max(y1, y2)

        # 相邻直接可连
        if maxY - minY == 1:
            return True

        # 判断两个坐标之间是否全为0
        for y0 in range(minY + 1, maxY):
            if self.im2num_arr[x][y0] != 0:
                return False
        return True

    # 判断同列是否可连
    def isColConnect(self, y, x1, x2):
        minX = min(x1, x2)
        maxX = max(x1, x2)

        # 相邻直接可连
        if maxX - minX == 1:
            return True

        # 判断两个坐标之间是否全为0
        for x0 in range(minX + 1, maxX):
            if self.im2num_arr[x0][y] != 0:
                return False
        return True

Das Erlernen eines solchen Spielhilfsskripts ist auch für Einzelpersonen sehr hilfreich, um ihr Interesse am Programmieren zu wecken. Es kann als guter Zeitvertreib nach der Arbeit angesehen werden. Ich werde diese Richtungen in Zukunft studieren und lernen.

Weitere technische Artikel zum Thema Python finden Sie in der Spalte Python-Tutorial, um mehr darüber zu erfahren!

Das obige ist der detaillierte Inhalt vonSo erstellen Sie ein Spielskript in Python. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Vorheriger Artikel:Was bedeutet int in Python?Nächster Artikel:Was bedeutet int in Python?