Jun 20, 2011
Monday, June 20, 2011

เขียนบอทเกมด้วย AutoIt : Bot 3 การค้นหาสีในหน้าจอ

     เมื่อคุณเล่นเกม มองเห็นมอนเตอร์หรือศัตรูในเกม คุณคลิกไปยังเป้าหมายเพื่อโจมตี การกระทำดังกล่าวผ่านความคิดเพียงพริบตา หากคุณต้องการนำเอาความคิดดังกล่าวมาแปลงเป็นคำสั่งสคริปต์ AutoIt จะต้องใช้คำสั่ง PixelSearch ซึ่งเป็นคำสั่งสำหรับช่วยค้นหาพิกเซลสีภายในหน้าจอเข้าช่วย

#หลักการทำงานของคำสั่ง PixelSearch

     ก่อนจะเริ่มใช้งานคำสั่ง PixelSearch คุณต้องทำความเข้าใจเสียก่อนว่า คำสั่งนี้ใช้งานอย่างไร คำสั่งนี้เป็นคำสั่งสำหรับค้นหาสีบนพิกเซล (Pixel) ภายในขอบเขตที่กำหนด ซึ่งขอบเขตดังกล่าวจะมีอาณาบริเวณเป็นพื้นที่ 4 เหลี่ยมมุมฉาก การกำหนดพื้นเพื่อค้นหาพิกเซลสีจะเหมือนการสร้างรูป 4 เหลี่ยมมุมฉากทั่วไปในโปรแกรมวาดรูป วิธีการสร้างรูป 4 เหลี่ยมในโปรแกรมวาดรูป จะต้องทำตามขั้นตอนนี้คือ

[[1]] กำหนดจุดมุมซ้ายบน (ดูรูปประกอบ)

[[2]] ทำการลากเม้าส์ไปยังมุมขวาล่าง เท่านี้ก็จะได้รูปสี่เหลี่ยมมุมฉากตามต้องการ
   


     ถ้าจะสร้างขอบเขตเพื่อค้นหาสีในเกมด้วยคำสั่ง PixelSearch ก็จะใช้หลักการเดียวกัน คือกำหนดขอบเขตพื้นที่ 4 เหลี่ยมมุมฉากขึ้นมาเสียก่อน วิธีการกำหนดขอบเขตจะใช้ตัววัดพิกัด คือ AutoIt Window Info เพื่อดึงเอาพิกัดแกน X Y ของมุมซ้ายบนและขวาล่างมาเขียนคำสั่ง (วิธีใช้บอกไว้แล้วในบท 2 ) การทำมีดังนี้

[[1]] ลากเป้าที่ Finder Tool ไปยังมุมซ้ายบน จากนั้นก็จดพิกัดจุดดังกล่าวเอาไว้ (ดูตัวเลข 3) ตามตัวอย่างนี้คือ 339,624

[[2]] ลากเป้าที่ Finder Tool ไปยังมุมขวาล่าง จากนั้นก็จดพิกัดจุดดังกล่าวเอาไว้ (ดูตัวเลข 3) ตามตัวอย่างนี้คือ 660,717



เมื่อได้ขอบเขตการค้นหาสีเรียบร้อยแล้ว ต่อไปก็จะต้องกำหนดสีทีจะค้นหา ก็ใช้วิธีเดียวกันคือ

[[1]] ลากเป้าที่ Finder Tool ไปวางยังสีที่ใช้ค้นหา ตามตัวอย่างนี้ลูกบอลสีเขียว

[[2]] จดรหัสสีเพื่อนำไปเขียนสคริปต์ ตามตัวอย่างนี้คือ 0x377233




ข้อมูลสำหรับนำมาเขียนสคริปต์มีครบแล้วนะครับ วิธีการเขียนสคริปต์จะใส่ข้อมูลดังนี้

PixelSearch ( พิกัดซ้าย, พิกัดบน,พิกัดขวา, พิกัดล่าง,รหัสสีที่จะค้นหา [, ระดับความผิดเพี้ยนของสี [, กำหนดการข้ามพิกเซลที่ค้นหา [,ค่า Handle ของหน้าต่าง]]] )

     เห็นคำสั่งเยอะอย่าเพิ่งงงครับ รูปแบบการใช้คำสั่งนี้จะมีพารามิเตอร์ร่วม  เพื่อใช้กำหนดรูปแบบค้นหาพิกเซลได้ละเอียดขึ้น (อยู่หลังเครื่องหมาย [ ) ซึ่งจะใส่ก็ได้ไม่ใส่ก็ได้ ในตัวอย่างนี้ ผมจะใส่แค่พิกัดและสีสำหรับค้นหาเท่านั้นก็พอ คือ

$coord = PixelSearch( พิกัดซ้าย,พิกัดบน,พิกัดขวา ,พิกัดล่าง,รหัสสี )

ตัวอย่าง การเขียนคำสั่งจากข้อมูลที่เก็บมา

$coord = PixelSearch( 339,624, 660,717, 0x377233 )

อธิบายคำสั่ง
    เมื่อคุณรันสคริปต์นี้ โปรแกรมจะเริ่มตรวจหาสีบนพิกเซลที่ขอบเขต 4 เหลี่ยม 339,624 และ  660,717  หากเจอสีจะส่งค่าพิกัดแกน x และ y ของพิกเซลนั้น ไปเก็บไว้ในตัวแปร $coord ซึ่งตัวแปรจะเปลี่ยนเป็นตัวแปรแบบอาร์เรย์ทันที โดย $coord[0] เก็บค่าแกน x และ $coord[1] เก็บค่าแกน y
     พิกัดที่ได้มาจะนำมาใช้เขียนคำสั่ง เพื่อสั่งคลิกเม้าส์ไปยังพิกัดดังกล่าว หรือเขียนคำสั่งอื่นเพิ่มเติมภายหลัง

#เขียนสคริปต์สำหรับคลิกเม้าส์ไปยังจุดที่เจอสี

     วิธีการเขียนสคริปต์ AutoIt เพื่อให้คลิกเม้าส์ไปยังจุดที่เจอสี เขียนเพิ่มเติมได้ดังนี้

$coord = PixelSearch( 339,624, 660,717, 0x377233 )
If Not @error Then
MouseClick("",$coord[0] ,$coord[1],1,0)
EndIf

อธิบายคำสั่ง

$coord = PixelSearch(339, 624, 660, 717, 0x377233)
; ใช้คำสั่ง PixelSearch ค้นหาสีรหัส 0x377233 เมื่อเจอก็เก็บไว้ในตัวแปร $coord
If Not @error Then
;ใส่เงื่อไข ถ้าค้นหาสำเร็จ (ไม่มีเออเรอร์) ก็จะทำงานในบรรทัดถัดไป
    MouseClick("", $coord[0], $coord[1], 1, 0)
;สั่งคลิกเม้าส์ซ้ายในพิกัดที่เก็บอยู่ในตัวแปร $coord[0] และ $coord[1] จำนวน 1 ครั้ง
EndIf
จบเงื่อนไข


     การทำงานของคำสั่งด้านบนจะทำงานเพียงครั้งเดียว หากคุณต้องการให้คำสั่งทำงานอยู่ตลอดเวลา ต้องเพิ่มคำสั่ง While 1 และ WEnd ครอบเอาไว้ดังนี้

While 1
$coord = PixelSearch( 339,624, 660,717, 0x377233 )
If Not @error Then
MouseClick("",$coord[0] ,$coord[1],1,0)
EndIf
    Sleep(100)
WEnd

     จะเห็นว่าผมใส่คำสั่ง Sleep(100) เพิ่มไปด้วย ซึ่งคุณต้องใส่ด้วยทุกครั้ง เพื่อป้องกันการดึงพลังประมวลผล CPU มากเกินไป และสำคัญมากคืออย่าลืมใส่คำสั่งเพื่อปิดสคริปต์ เพราะการวนลูปโดยเฉพาะการสั่งคลิกเม้าส์ อาจจะทำให้คุณขยับเม้าส์ไปปิดโปรแกรมไม่ได้ คำสั่งสำหรับปิดสคริปต์ เมื่อกดปุ่ม ESC เขียนได้ดังนี้ (นำไปวางไว้ด้านบนสุดของสคริปต์)

HotKeySet("{ESC}", "stop")


Func stop()
ToolTip('หยุดการทำงาน', 0, 0)
Sleep(500)
Exit
EndFunc


#กำหนดทิศทางการค้นหาสี

     คำสั่ง PixelSearch จะมีรูปแบบการค้นหาสี โดยไล่ค้นหาสีทีละพิกเซล (จุดบนหน้าจอ) คุณต้องเข้าใจก่อนว่า ภาพที่เห็นบนหน้าจอคอมพิวเตอร์ เกิดจากสีที่เปล่งออกมาจากจุดสีเล็กๆ มาอยู่รวมกัน (ใช้แว่นขยายจาก AutoIt Window Info มาส่องดูก็ได้) สีแต่ละจุดก็คือพิกเซล 1 พิกเซลนั่นเอง ดังรูปตัวอย่างด้านล่างนี้



      คำสั่ง PixelSearch จะเป็นการหาสีจากจุดพิกเซลที่ว่าไล่ไปทีละจุด โดยจะหาสีจากพิกเซลด้านซ้ายแถวบนสุดก่อน จากนั้นก็หาที่พิกเซลถัดไปด้านขวา ทีนี้ถ้าหากไม่เจอก็เลื่อนแถวพิกเซลลงมาอีกหนึ่งแถว ทำการหาจากซ้ายไปขวาอีก ทำอย่างนี้เรื่อยๆ จนถึงแถวสุดท้ายที่อยู่ด้านล่างสุดของขอบเขตที่คุณกำหนด ในคำสั่ง PixelSearch

      เพื่อให้เข้าใจยิ่งขึ้นผมขอให้คุณหาสีนำเงินในรูปด้านล่างนี้ ลองใช้โปรแกรม AutoIt Window Info กำหนดขอบเขต และเก็บรหัสสีมาก่อน จากนั้นนำข้อมูลที่ได้มาเขียนโค้ดใส่เพิ่มเข้าไปตรงข้อความที่เป็นสีฟ้าด้านล่างนี้ ลองกดปุ่ม F5 รันดู จะเห็นว่าลูกศรของเม้าส์วิ่งไปคลิกที่สีนำเงินมุม 1 เพราะสีน้ำเงินที่มุม 1 อยู่ ณ ตำแหน่งซ้ายบนสุดนั่นเอง





HotKeySet("{ESC}", "stop")


While 1
$coord = PixelSearch(179, 171, 534, 482,ใส่รหัสสี ) ;ซ้ายไปขวา  บนลงล่าง
If Not @error Then
MouseClick("",$coord[0] ,$coord[1],1,10)
Sleep(1000)
EndIf
    Sleep(100)
WEnd


Func stop()
     ToolTip('หยุดการทำงาน', 0, 0)
    Sleep(500)
    Exit
EndFunc


     การจะเปลี่ยนทิศทางการค้นหาสีนั้นก็ต้องเข้าใจรูปแบบของคำสั่ง PixelSearch ตามปกติ  คือ

PixelSearch ( left, top, right, bottom, color [, shade-variation [, step [, hwnd]]] )


ถ้าจะเปลี่ยนทิศทาง การเริ่มค้นหาสีจากพิกเซลก็ต้องดูสูตรด้านล่างนี้ วิธีการเปลี่ยนทิศทางก็คือ การสลับตำแหน่งพิกัด left, top, right, bottom ที่กำหนดขอบเขตในตอนแรกนั่นเองครับ การสลับตำแหน่ง (ตัวเลขพิกัด) แต่ละตำแหน่งจะให้ผลดังนี้

Left มาก่อน Right -  ค้นหาพิกเซลจาก ซ้ายไปขวา (เป็นการค้นหาแบบปกติของสคริปต์)
Right มาก่อน Left - ค้นหาพิกเซลจาก ขวาไปซ้าย
Top มาก่อน Bottom - ค้นหาพิกเซลจาก บนลงล่าง (เป็นการค้นหาแบบปกติของสคริปต์)
Bottom มาก่อน Top - ค้นหาพิกเซลจาก ล่างขึ้นบน

สมมุติการหาค่าสีปกติคือ
$coord = PixelSearch(179, 171, 534, 482,0x0000FF ) ;ซ้ายไปขวา  บนลงล่าง (ค้นหาตามปกติ)


เปลี่ยนจาก ขวา ไปซ้าย บนลงล่าง ก็จะเขียนสลับได้ดังนี้
$coord = PixelSearch(534, 171, 179, 482,0x0000FF )

เปลี่ยนจาก ล่างขึ้นบน ซ้ายไปขวา ก็จะเขียนสลับได้ดังนี้
$coord = PixelSearch(179, 482, 534, 171,0x0000FF )

เปลี่ยนจาก ล่างขึ้นบน ขวาไปซ้าย ก็จะเขียนสลับได้ดังนี้
$coord = PixelSearch(534, 482, 179, 171,0x0000FF )

    อ่านจากตรงนี้อาจจะไม่เข้าใจ ขอให้คุณทดลองเปลี่ยนทิศทางการค้นหาจากโค้ดก่อนหน้านี้ แล้วสั่งค้นหาสีน้ำเงินในรูปดูครับ สังเกตดูจะเห็นว่าเม้าส์วิ่งไปคลิกในตำแหน่งที่่ต่างกันทันที หลังเปลี่ยนทิศทางค้นหาพิกเซล


#จะสั่งให้ตรวจหาสีทั้งหน้าจอทำอย่างไร
     ตัวอย่างที่ผ่านมาผมได้แนะนำวิธีการตรวจหาสีเฉพาะขอบเขตที่ต้องการ หากคุณต้องการตรวจหาสีทั้งหน้าจอก็ทำได้ แต่ขอให้ระลึกไว้ว่าการตรวจสีทั้งหน้าจอจะทำให้สคริปต์ทำงานช้ากว่าการหาแบบกำหนดขอบเขต เพราะต้องค้นหาพิกเซลทั้งหมดที่อยู่ในหน้าจอ และในเกมที่มีการประมวลผลทางภาพเร็วๆ สคริปต์จะมีประสิทธิภาพด้อยกว่าการค้นหาพิกเซลแบบกำหนดขอบเขตอย่างเห็นได้ชัด โค้ดค้นหาพิกเซลทั้งหน้าจอคือ

$coord = PixelSearch(0, 0, @DesktopWidth,@DesktopHeight,0x0000FF )

; รหัสสี 0x0000FF คือรหัสสีที่คุณต้องเปลี่ยน เพื่อให้ค้นหาสีที่คุณกำหนดเอง

     การใช้คำสั่ง PixelSearch ยังมีพารามิเตอร์อื่นอยู่อีก เพื่อใช้อำนวยความสะดวกในการใช้คำสั่ง หากอยากทราบก็ลองคลิกที่คำสั่งใน SciTE  แล้วกดปุ่ม F1 จะมีคำอธิบายออกมาครับ มีข้อสงสัยอื่นสามารถเข้าไปตั้งคำถามได้ที่ฟอรั่ม เพื่อให้ได้คำตอบที่รวดเร็ว ควรนำโค้ดที่คุณเขียนแล้วเกิดปัญหามาใส่เข้าไปด้วยเวลาตั้งคำถาม

###จบแล้วครับ###

0 comments:

Post a Comment

    ส่วนนี้สำหรับแสดงความคิดเห็นทั่วไป สอบถามปัญหาตั้งถามได้ที่ฟอรั่ม


>>> [โปรดอ่าน] เนื่องจาก บทความการใช้งานบางโปรแกรมได้โฟสไปนานแล้ว
โปรแกรมอาจมีการอัปเดท วิธีการใช้งาน อาจใช้ไม่ได้ หรือมีวิธีที่ง่ายกว่าในเวอร์ชั่นใหม่
หากคุณพบว่าวิธีการใช้งานไม่ตรงกับบทความในบล็อกนี้ สามารถแนะนำเพิ่มเติมได้ครับ