bullno1
Mr & Ms Pac-Man
- 22/4/06
- 221
- 0
Game mạng với GameMaker
Download hai cái này
example trong bài:http://forums.gamevn.com/attachment.php?attachmentid=44227&stc=1&d=1156673354
39dll:http://forums.gamemaker.nl/index.php?showtopic=90437
Extract hai cái vào cùng một thư mục
Trước đây bullno1 đã từng nói “bâng quơ” là sẽ hướng dẫn mọi người làm multiplayer với GM,một số người cũng giục làm đi.Tục ngữ có câu “bullno1 ko nói chơi” thế nên trước khi ra đi,phải thực hiện lời nói đó.
GameMaker bản thân nó đã hỗ trợ multiplayer,(ở đây hiểu là qua mạng,chứ ko phải hai thằng chơi một máy).Nó có 4 kiểu kết nối
-IPX: cái này lỗi thời,chả thấy dùng,chả thấy tài liệu hướng dẫn nữa -> vứt đi
-Serial connection:Kết nối qua cổng serial,chả lẽ cứ chơi game là phải cầm dây nối vào máy đối thủ? -> vứt đi
-Modem connection:Kết nối nhờ modem,tức là truyền dữ liệu qua đường điện thoại bằng modem
-> vừa chậm vừa tốn tiền,vứt đi
-TCP/IP: Kiểu này đc,game thời nay toàn dùng kiểu này.Nhưng mà GM chơi direct play T_T ,đơn giản thì có đơn giản,nhưng :
1)Chậm,khi tìm server thì còn tưởng là game treo -> gây bực mình
2)Dùng quá nhiều cổng
->cũng nên vứt đi.
Thế thì học cái *** gì?
Có thể bài hướng dẫn này hơi cắt bớt giai đoạn,nhưng thực ra làm multiplayer với mấy lệnh bắt đầu bằng chữ mplay_ thì trên web của GM đã có rồi,tôi chả hơi đâu mà dịch và cũng ghet cái mplay đấy lắm.Chúng ta sẽ làm bằng socket,bằng 39dll.dll .Tuy hơi khó hơn,nhưng có tốc độ,khả năng tùy biến cao.Ko gây bực mình cho người chơi :P .Và thực ra tôi học về socket trước khi biết đến GM nên chắc mọi người cũng học đc.
Thế socket là cái *** gì?
Từ điển dịch là ổ cắm.Ổ cắm cắm vào lỗ để truyền điện,thì trong máy tính socket cắm vào port để truyền dữ liệu.Tạm thời chỉ cần biết sơ sơ về hai loại socket
-TCP :Tranmission control protocol, hiểu là nó truyền dữ liệu tuy chậm,nhưng chính xác.Trong game thì những dữ liệu ít truyền,đòi hỏi chính xác như dữ liệu về đồ,chat thường đc dùng cái này
-UDP:User defined packet ,nhỏ hơn và nhanh hơn TCP,đương nhiên là kém chính xác.Nên những dự liệu lặp nhiều,ko cần chính xác lắm thì hay dùng cái này vd: tọa độ người chơi.
Socket nó còn kiểu chia nữa là:
-Blocking socket: socket sẽ block(nghĩa là dừng) chương trình khi chưa có dữ liệu đc truyền
-Non-blocking socket: ko thèm block,ko quan tâm là có dữ liệu hay ko
Do Gamemaker ko có khả năng về lập trình socket,nên có các dll để bổ trợ về socket như
-39
-SOC
-GMsock
3 dll trên thực ra là cũng gần như nhau,nhưng nhiều người thích 39 và SOC hơn.
Tôi chỉ hướng dẫn về 39.
Chú ý về sử dụng
-Các dll viết ra cho gm đều đi cùng wrapper script(script để sử dụng nó) và hướng dẫn,phải RTFM(read the fu***ing manual -> đọc kỹ hướng dẫn sử dụng :P )
-Cần có file dll đó ở cùng thư mục với file gm6 để test game.
-Khi chuyển thành exe thì cũng cần file dll đó đi kèm.
Chú ý về làm game multiplayer:
-Đây là công việc ko đơn giản,đòi hỏi kiên nhẫn,code viết ra phải áp dụng đc cho mọi người chơi.
-Kinh nghiệm của tôi là khi test game,tạo một excutable rồi chạy nó,và chạy debug mode trong GM.
-Cần có một sniffer vì nhiều khi mình ko biết chương trình nó send cái quái gì.
Bắt đầu về 39:
Hướng dẫn sơ sơ một số lệnh trong 39(dịch từ hướng dẫn chính gốc của nó)
-dllinit(path,use file?,use ultilites?):cần gọi một lần trước khi sử dụng mọi lệnh khác trong 39.
Path là đường dẫn đến file 39dll,cứ cho một con số bất kì vào là nó tự tìm trong thư mục hiện tại,đỡ mệt
Usefile:true hoặc false: có sử dụng chức năng đọc ghi file của 39 ko.Chức năng của nó khá tốt,hay hơn GM nên bạn nên dùng
Use ultilité:true hoặc false: có sử dụng các tiện ích khác như mã hóa,tìm ip … ko? Nên dùng
-> trong game start event hoặc create event của một object có chức năng điều khiển chung,ta dùng lệnh: dllinit(1,1,1);
-dllfree:cần gọi khi game kết thúc để giải phóng tài nguyên.
-> trong game end event ta dùng dllfree();
-tcpconnect(ip,port,blocking mode):tạo kết nối đến địa chỉ ip,và cổng port và trả về mã số của nó.Nếu mã số <=0 là ko kết nối đc.IP là địa chỉ để xác định máy tính trong mạng.Port: là cái ổ để mà socket nó cắm vào.Bịa ra một con số vd: 1234 chẳng hạn.Lưu ý là cần tránh một số cổng đặc biệt như 139,80,23… vì bị sử dụng rồi.Giá trị của port có thể trong khỏang 1->65536( 2^16) .Cần lưu giá trị trả về vào 1 biến global để sử dụng sau này
Blocking mode là chế độ blocking/non-blocking đã nói ở trên,nhận các giá trị 0->2
0:blocking
1:non-blocking(nhưng khi đang thực hiện kết nối thì vẫn block,nên sử dụng loại này)
2:non-blocking++,chương trình chạy tiếp tục ngay,kể cả khi chưa kết nối xong hoặc kết nối hỏng.
-tcplisten(port,max,mode):lắng nghe trên một cổng để chờ kết nối.Bạn chỉ kết nối đc vào một cổng của máy tính nếu máy đó đã lắng nghe trên cổng đó. Port:cổng để nối.Max:số người tối đa đc chờ kết nối,chú ý là đc chờ chứ ko phải là đc kết nối.Giống như khi xếp hang,cho tối đa là 5 thằng đứng trong hàng nhưng bao nhiêu thằng vào cũng đc.Mode :blocking,non blocking ,nên để giá trị 1.
-tcpaccept(listening socket,blocking mode): chấp nhận một kết nối khách (đc tạo bằng tcpconnect) vào kết nổi chủ(đc tạo bằng tcplisten) và trả lại mã số của nó để liên lạc sau này.Việc này giống như cho thằng đang xếp hàng vào nhà mình.Blocking mode: thôi ko nói nữa,dùng 1.
-setnaggle(socket,mode) :chỉ dùng cho tcp socket,nếu để mode là 1 thì tốc độ truyền dữ liệu trên socket đó sẽ nhanh hơn,cứ hiểu đơn giản là vậy.
-udpconnect(port,mode) :cũng giống tcp connect,nhưng ko cần ip vì udp là một connectionless protocol,nghĩa là thực ra nó ko kết nối gì sất.
-closesocket(socket): ngắt kết nối
Về việc truyền dữ liệu:
39 dùng buffer để truyền dữ liệu.Nó giống như viết thư vào giấy(buffer) rồi gửi tờ giấy đi.
Để gửi thì có:
sendmessage(socket,[ip],[port]) gửi nội dung trong buffer qua một socket.ip và port chỉ cần thiết khi đó là udp,vì udp như đã nói,nó vốn ko kết nối.Trả lại dung lượng đã gửi,<=0 là gửi bị lỗi.
receivemessage(socket) trả lại dung lượng nhận đc và copy nó và buffer để đọc.Nếu <=0 là ko nhận đc gì.
Buffer:
Buffer như đã nói là dùng để ghi ,nhận dữ liệu.Sử dụng nó cũng giống như sử dụng file.Có các lệnh:
clearbuffer()
óa hết nội dung trong đó,đưa con trỏ về 0.Rất cần khi phải gửi dữ liệu mới
writebyte,writestring,writeshort....:các lệnh để viết dữ liệu với các kiểu khác nhau vào buffer.Chính vì vậy mà 39 nhanh hơn mplay vì mplay chỉ có 2 kiểu dữ liệu là real và string-> rất tốn bandwidth.
readbyte,readstring,readshort: đọc dữ liệu với các kiểu tương ứng.
Bây giờ chúng ta chỉ cần vài lệnh đó đã,nâng cao mới cần hơn.Bắt đầu ví dụ:
Chương trình chat dành cho hai người.
Tạo một project mới trong GM,merge nó với file 39.gm6 rồi save vào cùng thư mục với file 39dll.dll .
Tạo một object,đặt tên là chat.
Trong create event gõ đoạn lệnh:
dllinit(0,1,1);
ishost=show_question(“Do you want to host?”);//hỏi xem có muốn host ko,nếu ko là join
if ishost //nếu host
{
global.server=tcplisten(12345,1,1)//lắng nghe cổng 12345
global.client=-1;//chưa có ai connect
}
else
global.client=tcpconnect(get_string(“Connect to”,’’),12345,1);//join
Trong step event:
if ishost and global.client<=0 //nếu mình host và chưa có ai connect
global.client=tcpaccept(global.server,1)//chấp nhận kết nối,non-blocking socket
if global.client//nếu đã kết nối
{
if receivemessage(global.client) //nếu nhận đc thông điệp
show_message(readstring());//đọc thông điệp rồi báo
}
Trong draw event:
draw_text(x,y,keyboard_string);//viết ra nội dung chat
Trong keypress enter event:
clearbuffer();//xóa hết nội dung trong buffer
writestring(keyboard_string,1);//viết nội dung vào buffer
sendmessage(global.client);//gửi đi
keyboard_string=’’;//xóa hết dòng chat cũ
Trong game end event:
dllfree();
Vứt object chat vào một cái room.Tạo một excutable,chạy nó,đồng thời chạy game bằng gm.Một cái chọn host(yes) cái kia chọn join(no),địa chỉ là 127.0.0.1,bạn đang chat một mình :) .
Nếu định phát hành cái chương trình chat này thì hãy mở game information ra và gõ vào đó
Credit:
-39ster(39dll)
Phần một dừng ở đây,dự kiến các phần sau là:
-Chat nhiều người
-Game đơn giản,có mấy hình tròn hình vuông chạy lung tung
-Broadcast,server list,lobby
-Game online
Bài tập về nhà
mọi người thử làm thêm mấy cái sau.
-Nickname,gợi ý: chỉ cần thêm vào đầu message
-Giao diện đẹp hơn
-Chức năng buzz(dùng một message đặc biệt chẳng hạn)
Download hai cái này
example trong bài:http://forums.gamevn.com/attachment.php?attachmentid=44227&stc=1&d=1156673354
39dll:http://forums.gamemaker.nl/index.php?showtopic=90437
Extract hai cái vào cùng một thư mục
Trước đây bullno1 đã từng nói “bâng quơ” là sẽ hướng dẫn mọi người làm multiplayer với GM,một số người cũng giục làm đi.Tục ngữ có câu “bullno1 ko nói chơi” thế nên trước khi ra đi,phải thực hiện lời nói đó.
GameMaker bản thân nó đã hỗ trợ multiplayer,(ở đây hiểu là qua mạng,chứ ko phải hai thằng chơi một máy).Nó có 4 kiểu kết nối
-IPX: cái này lỗi thời,chả thấy dùng,chả thấy tài liệu hướng dẫn nữa -> vứt đi
-Serial connection:Kết nối qua cổng serial,chả lẽ cứ chơi game là phải cầm dây nối vào máy đối thủ? -> vứt đi
-Modem connection:Kết nối nhờ modem,tức là truyền dữ liệu qua đường điện thoại bằng modem
-> vừa chậm vừa tốn tiền,vứt đi
-TCP/IP: Kiểu này đc,game thời nay toàn dùng kiểu này.Nhưng mà GM chơi direct play T_T ,đơn giản thì có đơn giản,nhưng :
1)Chậm,khi tìm server thì còn tưởng là game treo -> gây bực mình
2)Dùng quá nhiều cổng
->cũng nên vứt đi.
Thế thì học cái *** gì?
Có thể bài hướng dẫn này hơi cắt bớt giai đoạn,nhưng thực ra làm multiplayer với mấy lệnh bắt đầu bằng chữ mplay_ thì trên web của GM đã có rồi,tôi chả hơi đâu mà dịch và cũng ghet cái mplay đấy lắm.Chúng ta sẽ làm bằng socket,bằng 39dll.dll .Tuy hơi khó hơn,nhưng có tốc độ,khả năng tùy biến cao.Ko gây bực mình cho người chơi :P .Và thực ra tôi học về socket trước khi biết đến GM nên chắc mọi người cũng học đc.
Thế socket là cái *** gì?
Từ điển dịch là ổ cắm.Ổ cắm cắm vào lỗ để truyền điện,thì trong máy tính socket cắm vào port để truyền dữ liệu.Tạm thời chỉ cần biết sơ sơ về hai loại socket
-TCP :Tranmission control protocol, hiểu là nó truyền dữ liệu tuy chậm,nhưng chính xác.Trong game thì những dữ liệu ít truyền,đòi hỏi chính xác như dữ liệu về đồ,chat thường đc dùng cái này
-UDP:User defined packet ,nhỏ hơn và nhanh hơn TCP,đương nhiên là kém chính xác.Nên những dự liệu lặp nhiều,ko cần chính xác lắm thì hay dùng cái này vd: tọa độ người chơi.
Socket nó còn kiểu chia nữa là:
-Blocking socket: socket sẽ block(nghĩa là dừng) chương trình khi chưa có dữ liệu đc truyền
-Non-blocking socket: ko thèm block,ko quan tâm là có dữ liệu hay ko
Do Gamemaker ko có khả năng về lập trình socket,nên có các dll để bổ trợ về socket như
-39
-SOC
-GMsock
3 dll trên thực ra là cũng gần như nhau,nhưng nhiều người thích 39 và SOC hơn.
Tôi chỉ hướng dẫn về 39.
Chú ý về sử dụng
-Các dll viết ra cho gm đều đi cùng wrapper script(script để sử dụng nó) và hướng dẫn,phải RTFM(read the fu***ing manual -> đọc kỹ hướng dẫn sử dụng :P )
-Cần có file dll đó ở cùng thư mục với file gm6 để test game.
-Khi chuyển thành exe thì cũng cần file dll đó đi kèm.
Chú ý về làm game multiplayer:
-Đây là công việc ko đơn giản,đòi hỏi kiên nhẫn,code viết ra phải áp dụng đc cho mọi người chơi.
-Kinh nghiệm của tôi là khi test game,tạo một excutable rồi chạy nó,và chạy debug mode trong GM.
-Cần có một sniffer vì nhiều khi mình ko biết chương trình nó send cái quái gì.
Bắt đầu về 39:
Hướng dẫn sơ sơ một số lệnh trong 39(dịch từ hướng dẫn chính gốc của nó)
-dllinit(path,use file?,use ultilites?):cần gọi một lần trước khi sử dụng mọi lệnh khác trong 39.
Path là đường dẫn đến file 39dll,cứ cho một con số bất kì vào là nó tự tìm trong thư mục hiện tại,đỡ mệt
Usefile:true hoặc false: có sử dụng chức năng đọc ghi file của 39 ko.Chức năng của nó khá tốt,hay hơn GM nên bạn nên dùng
Use ultilité:true hoặc false: có sử dụng các tiện ích khác như mã hóa,tìm ip … ko? Nên dùng
-> trong game start event hoặc create event của một object có chức năng điều khiển chung,ta dùng lệnh: dllinit(1,1,1);
-dllfree:cần gọi khi game kết thúc để giải phóng tài nguyên.
-> trong game end event ta dùng dllfree();
-tcpconnect(ip,port,blocking mode):tạo kết nối đến địa chỉ ip,và cổng port và trả về mã số của nó.Nếu mã số <=0 là ko kết nối đc.IP là địa chỉ để xác định máy tính trong mạng.Port: là cái ổ để mà socket nó cắm vào.Bịa ra một con số vd: 1234 chẳng hạn.Lưu ý là cần tránh một số cổng đặc biệt như 139,80,23… vì bị sử dụng rồi.Giá trị của port có thể trong khỏang 1->65536( 2^16) .Cần lưu giá trị trả về vào 1 biến global để sử dụng sau này
Blocking mode là chế độ blocking/non-blocking đã nói ở trên,nhận các giá trị 0->2
0:blocking
1:non-blocking(nhưng khi đang thực hiện kết nối thì vẫn block,nên sử dụng loại này)
2:non-blocking++,chương trình chạy tiếp tục ngay,kể cả khi chưa kết nối xong hoặc kết nối hỏng.
-tcplisten(port,max,mode):lắng nghe trên một cổng để chờ kết nối.Bạn chỉ kết nối đc vào một cổng của máy tính nếu máy đó đã lắng nghe trên cổng đó. Port:cổng để nối.Max:số người tối đa đc chờ kết nối,chú ý là đc chờ chứ ko phải là đc kết nối.Giống như khi xếp hang,cho tối đa là 5 thằng đứng trong hàng nhưng bao nhiêu thằng vào cũng đc.Mode :blocking,non blocking ,nên để giá trị 1.
-tcpaccept(listening socket,blocking mode): chấp nhận một kết nối khách (đc tạo bằng tcpconnect) vào kết nổi chủ(đc tạo bằng tcplisten) và trả lại mã số của nó để liên lạc sau này.Việc này giống như cho thằng đang xếp hàng vào nhà mình.Blocking mode: thôi ko nói nữa,dùng 1.
-setnaggle(socket,mode) :chỉ dùng cho tcp socket,nếu để mode là 1 thì tốc độ truyền dữ liệu trên socket đó sẽ nhanh hơn,cứ hiểu đơn giản là vậy.
-udpconnect(port,mode) :cũng giống tcp connect,nhưng ko cần ip vì udp là một connectionless protocol,nghĩa là thực ra nó ko kết nối gì sất.
-closesocket(socket): ngắt kết nối
Về việc truyền dữ liệu:
39 dùng buffer để truyền dữ liệu.Nó giống như viết thư vào giấy(buffer) rồi gửi tờ giấy đi.
Để gửi thì có:
sendmessage(socket,[ip],[port]) gửi nội dung trong buffer qua một socket.ip và port chỉ cần thiết khi đó là udp,vì udp như đã nói,nó vốn ko kết nối.Trả lại dung lượng đã gửi,<=0 là gửi bị lỗi.
receivemessage(socket) trả lại dung lượng nhận đc và copy nó và buffer để đọc.Nếu <=0 là ko nhận đc gì.
Buffer:
Buffer như đã nói là dùng để ghi ,nhận dữ liệu.Sử dụng nó cũng giống như sử dụng file.Có các lệnh:
clearbuffer()
óa hết nội dung trong đó,đưa con trỏ về 0.Rất cần khi phải gửi dữ liệu mớiwritebyte,writestring,writeshort....:các lệnh để viết dữ liệu với các kiểu khác nhau vào buffer.Chính vì vậy mà 39 nhanh hơn mplay vì mplay chỉ có 2 kiểu dữ liệu là real và string-> rất tốn bandwidth.
readbyte,readstring,readshort: đọc dữ liệu với các kiểu tương ứng.
Bây giờ chúng ta chỉ cần vài lệnh đó đã,nâng cao mới cần hơn.Bắt đầu ví dụ:
Chương trình chat dành cho hai người.

Tạo một project mới trong GM,merge nó với file 39.gm6 rồi save vào cùng thư mục với file 39dll.dll .
Tạo một object,đặt tên là chat.
Trong create event gõ đoạn lệnh:
dllinit(0,1,1);
ishost=show_question(“Do you want to host?”);//hỏi xem có muốn host ko,nếu ko là join
if ishost //nếu host
{
global.server=tcplisten(12345,1,1)//lắng nghe cổng 12345
global.client=-1;//chưa có ai connect
}
else
global.client=tcpconnect(get_string(“Connect to”,’’),12345,1);//join
Trong step event:
if ishost and global.client<=0 //nếu mình host và chưa có ai connect
global.client=tcpaccept(global.server,1)//chấp nhận kết nối,non-blocking socket
if global.client//nếu đã kết nối
{
if receivemessage(global.client) //nếu nhận đc thông điệp
show_message(readstring());//đọc thông điệp rồi báo
}
Trong draw event:
draw_text(x,y,keyboard_string);//viết ra nội dung chat
Trong keypress enter event:
clearbuffer();//xóa hết nội dung trong buffer
writestring(keyboard_string,1);//viết nội dung vào buffer
sendmessage(global.client);//gửi đi
keyboard_string=’’;//xóa hết dòng chat cũ
Trong game end event:
dllfree();
Vứt object chat vào một cái room.Tạo một excutable,chạy nó,đồng thời chạy game bằng gm.Một cái chọn host(yes) cái kia chọn join(no),địa chỉ là 127.0.0.1,bạn đang chat một mình :) .
Nếu định phát hành cái chương trình chat này thì hãy mở game information ra và gõ vào đó
Credit:
-39ster(39dll)
Phần một dừng ở đây,dự kiến các phần sau là:
-Chat nhiều người
-Game đơn giản,có mấy hình tròn hình vuông chạy lung tung
-Broadcast,server list,lobby
-Game online
Bài tập về nhà
mọi người thử làm thêm mấy cái sau.-Nickname,gợi ý: chỉ cần thêm vào đầu message
-Giao diện đẹp hơn
-Chức năng buzz(dùng một message đặc biệt chẳng hạn)
