Hi all,
Please check Part 1 before continuing to this section
In the last section, we covered board generation, leaving the actual network connectivity creation to this section.
Part 2 : Connecting to the server
Step 1 : Configure the game server
The given server (included in the github link), is made in C# as a Visual Studio Solution. Thus to run it
1) Download and extract the source
2) Install Visual Studio
3) Open lk.ac.mrt.cse.pc11/Tanks_server.sln
4) Once done, run the solution to open up the UI and the CLI
NOTE: IF you need to access the server from another machine, you need to make it listen to an interface IP. For that open up App.config and change the IP Address to something you get from ipconfig command.
Now with some analysis of the code and structure of the game server, the following can be seen.
1) We need to initialize a socket connection to the game server on the port 6000
2) As soon as we initialize and send the command "JOIN#" to game server, server will reply back to port 7000/
3) Thus, before sending the Join command we need to start a server on our client side that listens to port 7000.
4) Once that is initialized, our server continue to listen to the commands from the game server, through which various updates are taken.
Step 2 : Initialize socket connection
To ease everyone's life, I came up with a ServerClient class that handles all the things mentioned above. So in order to connect, all you need is to import the class and call the methods accordingly.
First save the socketclient.py which contains the ServerClient .
Now we use this class to connect to the server,
Note: Here the IP I have added is an external one since my server is running on a different machine. If you have both your client and Game server in the same machine, use 127.0.0.1 instead.
Save the below code as the new tank.py and run it. (Make sure the game server is running first). If all goes okay, you will see a string in the form "I:P:0...." printing on your console output. And the game server CLI output will show some text that says you have connected.
Step 3 : Drawing the board
Now that we can connect to the Game server and properly talk with it, next is to decode the board explanation given by the game server into graphical interface itself.
The format of the initialization code is
I:P0:<list of brick cordinates>:<list of stone wall cordinates>:<list of water cordinates>
So we simply do some splits and get cordinates of each element and draw them on our board. Since we have only implemented Brick walls in the sample I will show how to draw in the following code.
Once you run the tanks.py (remember that you need to close the game server and re run it before running your tanks.py, EVERYTIME), you will see that the Brick walls are shown on your interface in the same places as shown in the game server UI.
Okaaaay, so now you have the basic connectivity working, and I believe that you can continue building from here onwards. First make sure you add the logic to show all 4 different terrain types. Then make new Sprites, Coin and Lifepack and add them the same way we have used before.
I will try to update some future posts on the development, like auto vanishing coins and animations, but I guess this would work for now.
Cyah all
Please check Part 1 before continuing to this section
In the last section, we covered board generation, leaving the actual network connectivity creation to this section.
Part 2 : Connecting to the server
Step 1 : Configure the game server
The given server (included in the github link), is made in C# as a Visual Studio Solution. Thus to run it
1) Download and extract the source
2) Install Visual Studio
3) Open lk.ac.mrt.cse.pc11/Tanks_server.sln
4) Once done, run the solution to open up the UI and the CLI
NOTE: IF you need to access the server from another machine, you need to make it listen to an interface IP. For that open up App.config and change the IP Address to something you get from ipconfig command.
Now with some analysis of the code and structure of the game server, the following can be seen.
1) We need to initialize a socket connection to the game server on the port 6000
2) As soon as we initialize and send the command "JOIN#" to game server, server will reply back to port 7000/
3) Thus, before sending the Join command we need to start a server on our client side that listens to port 7000.
4) Once that is initialized, our server continue to listen to the commands from the game server, through which various updates are taken.
Step 2 : Initialize socket connection
To ease everyone's life, I came up with a ServerClient class that handles all the things mentioned above. So in order to connect, all you need is to import the class and call the methods accordingly.
First save the socketclient.py which contains the ServerClient .
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import socket | |
import threading | |
import SocketServer | |
class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer): | |
pass | |
class ServerClient(): | |
def __init__(self, requestHandler): | |
self.server = ThreadedTCPServer(("0.0.0.0", 7000), requestHandler) | |
self.server_thread = threading.Thread(target=self.server.serve_forever) | |
self.server_thread.daemon = True | |
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |
def start_server(self): | |
self.server_thread.start() | |
def connect_client(self,ip,port): | |
self.sock.connect((ip, port)) | |
def send_message(self,message): | |
try: | |
self.sock.sendall(message) | |
finally: | |
self.sock.close() | |
def stop_server(self): | |
self.server.shutdown() | |
self.server.server_close() |
Note: Here the IP I have added is an external one since my server is running on a different machine. If you have both your client and Game server in the same machine, use 127.0.0.1 instead.
Save the below code as the new tank.py and run it. (Make sure the game server is running first). If all goes okay, you will see a string in the form "I:P:0...." printing on your console output. And the game server CLI output will show some text that says you have connected.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import pygame | |
from pygame.locals import * | |
import sys | |
from board import Board | |
from socketclient import ServerClient | |
import SocketServer | |
#initialie the pygame engine | |
pygame.init() | |
#first we need a screen to display all the thins, 800x800 is the resolution | |
screen = pygame.display.set_mode((800, 800)) | |
#This class is a request handler | |
#It has the handle method that fires when we recieve something from game server | |
class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler): | |
def handle(self): | |
try: | |
data = self.request.recv(1024) | |
print data | |
except: | |
print "Exception at server" | |
#Make new instance of the serverclient class | |
sc = ServerClient(ThreadedTCPRequestHandler) | |
#start our listening server on port 7000 | |
sc.start_server() | |
#connect to the game server, remember to replace the IP with 127.0.0.1 | |
#if you are using the same machine | |
sc.connect_client("192.168.1.5", 6000) | |
#send the JOIN command | |
sc.send_message("JOIN#") | |
#create a new board instane | |
board = Board() | |
board.set_terrain([(0,0),(0,1),(0,2),(0,3), | |
(10,0),(11,15),(11,16),(10,12), | |
(17,17),(18,18),(19,19),(1,1),],-1) | |
board.draw_board() | |
board.cells.draw(screen) | |
#This is called the Game Loop [VERY IMPORTANT] | |
#This is where all the game updates, input handling happends | |
while 1: | |
#Here's how we handle keyboard input | |
#This code simply check if we pressed something and end the program | |
for event in pygame.event.get(): | |
if event.type in (QUIT, KEYDOWN): | |
sys.exit() | |
#THIS LINE IS CRITICAL | |
#if you dont include this line, nothing will be printed on screen | |
pygame.display.update() |
Step 3 : Drawing the board
Now that we can connect to the Game server and properly talk with it, next is to decode the board explanation given by the game server into graphical interface itself.
The format of the initialization code is
I:P0:<list of brick cordinates>:<list of stone wall cordinates>:<list of water cordinates>
So we simply do some splits and get cordinates of each element and draw them on our board. Since we have only implemented Brick walls in the sample I will show how to draw in the following code.
Once you run the tanks.py (remember that you need to close the game server and re run it before running your tanks.py, EVERYTIME), you will see that the Brick walls are shown on your interface in the same places as shown in the game server UI.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import pygame | |
from pygame.locals import * | |
import sys | |
from board import Board | |
from socketclient import ServerClient | |
import SocketServer | |
pygame.init() | |
screen = pygame.display.set_mode((800, 800)) | |
#we keep 2 variables to get messages from the server listen thread to | |
#our main thread | |
hasUpdate = False | |
updateData = None | |
#This class is a request handler | |
#It has the handle method that fires when we recieve something from game server | |
class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler): | |
def handle(self): | |
global hasUpdate | |
global updateData | |
try: | |
data = self.request.recv(1024) | |
updateData = data | |
hasUpdate = True | |
except: | |
print "Exception at server" | |
#Make new instance of the serverclient class | |
sc = ServerClient(ThreadedTCPRequestHandler) | |
#start our listening server on port 7000 | |
sc.start_server() | |
#connect to the game server, remember to replace the IP with 127.0.0.1 | |
#if you are using the same machine | |
sc.connect_client("192.168.1.5", 6000) | |
#send the JOIN command | |
sc.send_message("JOIN#") | |
#once we are connected,we wait for the initialiation message | |
while not hasUpdate: | |
pass | |
hasUpdate = False | |
#now we has a message, should be the init message | |
#first split by : to get components | |
comps = updateData[:-1].split(":") | |
print comps | |
#second component of the message gives our player number | |
playerNum = int(comps[1][1]) | |
#let's extract the bricks list | |
brickList = list() | |
for c in comps[2].split(";"): | |
tmp = c.split(",") | |
brickList.append(( int(tmp[1]), int(tmp[0]) )) | |
#now we use this bricks list to generate the bricks on the board | |
#create a new board instane | |
board = Board() | |
#see how our set_terrain method is useful | |
board.set_terrain(brickList,-1) | |
board.draw_board() | |
board.cells.draw(screen) | |
while 1: | |
for event in pygame.event.get(): | |
if event.type in (QUIT, KEYDOWN): | |
sys.exit() | |
pygame.display.update() |
I will try to update some future posts on the development, like auto vanishing coins and animations, but I guess this would work for now.
Cyah all
wonderful post and very helpful, thanks for all this information. You are including better information regarding this topic in an effective way.Thank you so much
ReplyDeleteself employment tax
text preparation services
tax accountant
tax consultant
this is a very useful post... i get a step by step idea for building a 2D board game
ReplyDeleteBest Interior Designers in Chennai
I Have Done PYTHON Training In Automation Minds In Course In Useful Really For Thank You Automation Minds
ReplyDeletehttp://www.automationminds.com/course/pythontraininginsholinganallur/