├── .gitpod.yml ├── README.md ├── game.py ├── network.py ├── requirements.txt ├── run.py └── server.py /.gitpod.yml: -------------------------------------------------------------------------------- 1 | image: gitpod/workspace-full-vnc 2 | ports: 3 | - port: 5900 4 | onOpen: ignore 5 | - port: 6080 6 | onOpen: open-preview 7 | tasks: 8 | - command: python3 server.py 9 | - init: pip3 install -r requirements.txt 10 | command: python3 run.py 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Network Game Tutorial 2 | 3 | This is the code for my network game tutorial series on YouTube. 4 | 5 | You can view the video tutorial on YouTube here: https://www.youtube.com/watch?v=_fx7FQ3SP0U&list=PLzMcBGfZo4-kR7Rh-7JCVDN8lm3Utumvq 6 | 7 | # Running The Game 8 | To run the game you will need to run an instane of *server.py* on one machine. Then you can run instances of *run.py* on other machines to connect. 9 | 10 | You will need to change the **server** address in both *server.py* and *network.py* to be the IPV4 address of your machine or the server ips you'll be using. 11 | 12 | # 💻 Launch Your Software Development Career Today! 13 | 14 | 🎓 **No degree? No problem!** My program equips you with everything you need to break into tech and land an entry-level software development role. 15 | 16 | 🚀 **Why Join?** 17 | - 💼 **$70k+ starting salary potential** 18 | - 🕐 **Self-paced:** Complete on your own time 19 | - 🤑 **Affordable:** Low risk compared to expensive bootcamps or degrees 20 | - 🎯 **45,000+ job openings** in the market 21 | 22 | 👉 **[Start your journey today!](https://techwithtim.net/dev)** 23 | No experience needed—just your determination. Future-proof your career and unlock six-figure potential like many of our students have! 24 | -------------------------------------------------------------------------------- /game.py: -------------------------------------------------------------------------------- 1 | import pygame 2 | from network import Network 3 | 4 | 5 | class Player(): 6 | width = height = 50 7 | 8 | def __init__(self, startx, starty, color=(255,0,0)): 9 | self.x = startx 10 | self.y = starty 11 | self.velocity = 2 12 | self.color = color 13 | 14 | def draw(self, g): 15 | pygame.draw.rect(g, self.color ,(self.x, self.y, self.width, self.height), 0) 16 | 17 | def move(self, dirn): 18 | """ 19 | :param dirn: 0 - 3 (right, left, up, down) 20 | :return: None 21 | """ 22 | 23 | if dirn == 0: 24 | self.x += self.velocity 25 | elif dirn == 1: 26 | self.x -= self.velocity 27 | elif dirn == 2: 28 | self.y -= self.velocity 29 | else: 30 | self.y += self.velocity 31 | 32 | 33 | class Game: 34 | 35 | def __init__(self, w, h): 36 | self.net = Network() 37 | self.width = w 38 | self.height = h 39 | self.player = Player(50, 50) 40 | self.player2 = Player(100,100) 41 | self.canvas = Canvas(self.width, self.height, "Testing...") 42 | 43 | def run(self): 44 | clock = pygame.time.Clock() 45 | run = True 46 | while run: 47 | clock.tick(60) 48 | 49 | for event in pygame.event.get(): 50 | if event.type == pygame.QUIT: 51 | run = False 52 | 53 | if event.type == pygame.K_ESCAPE: 54 | run = False 55 | 56 | keys = pygame.key.get_pressed() 57 | 58 | if keys[pygame.K_RIGHT]: 59 | if self.player.x <= self.width - self.player.velocity: 60 | self.player.move(0) 61 | 62 | if keys[pygame.K_LEFT]: 63 | if self.player.x >= self.player.velocity: 64 | self.player.move(1) 65 | 66 | if keys[pygame.K_UP]: 67 | if self.player.y >= self.player.velocity: 68 | self.player.move(2) 69 | 70 | if keys[pygame.K_DOWN]: 71 | if self.player.y <= self.height - self.player.velocity: 72 | self.player.move(3) 73 | 74 | # Send Network Stuff 75 | self.player2.x, self.player2.y = self.parse_data(self.send_data()) 76 | 77 | # Update Canvas 78 | self.canvas.draw_background() 79 | self.player.draw(self.canvas.get_canvas()) 80 | self.player2.draw(self.canvas.get_canvas()) 81 | self.canvas.update() 82 | 83 | pygame.quit() 84 | 85 | def send_data(self): 86 | """ 87 | Send position to server 88 | :return: None 89 | """ 90 | data = str(self.net.id) + ":" + str(self.player.x) + "," + str(self.player.y) 91 | reply = self.net.send(data) 92 | return reply 93 | 94 | @staticmethod 95 | def parse_data(data): 96 | try: 97 | d = data.split(":")[1].split(",") 98 | return int(d[0]), int(d[1]) 99 | except: 100 | return 0,0 101 | 102 | 103 | class Canvas: 104 | 105 | def __init__(self, w, h, name="None"): 106 | self.width = w 107 | self.height = h 108 | self.screen = pygame.display.set_mode((w,h)) 109 | pygame.display.set_caption(name) 110 | 111 | @staticmethod 112 | def update(): 113 | pygame.display.update() 114 | 115 | def draw_text(self, text, size, x, y): 116 | pygame.font.init() 117 | font = pygame.font.SysFont("comicsans", size) 118 | render = font.render(text, 1, (0,0,0)) 119 | 120 | self.screen.draw(render, (x,y)) 121 | 122 | def get_canvas(self): 123 | return self.screen 124 | 125 | def draw_background(self): 126 | self.screen.fill((255,255,255)) 127 | -------------------------------------------------------------------------------- /network.py: -------------------------------------------------------------------------------- 1 | import socket 2 | 3 | 4 | class Network: 5 | 6 | def __init__(self): 7 | self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 8 | self.host = "localhost" # For this to work on your machine this must be equal to the ipv4 address of the machine running the server 9 | # You can find this address by typing ipconfig in CMD and copying the ipv4 address. Again this must be the servers 10 | # ipv4 address. This feild will be the same for all your clients. 11 | self.port = 5555 12 | self.addr = (self.host, self.port) 13 | self.id = self.connect() 14 | 15 | def connect(self): 16 | self.client.connect(self.addr) 17 | return self.client.recv(2048).decode() 18 | 19 | def send(self, data): 20 | """ 21 | :param data: str 22 | :return: str 23 | """ 24 | try: 25 | self.client.send(str.encode(data)) 26 | reply = self.client.recv(2048).decode() 27 | return reply 28 | except socket.error as e: 29 | return str(e) 30 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | pygame 2 | -------------------------------------------------------------------------------- /run.py: -------------------------------------------------------------------------------- 1 | import game 2 | 3 | if __name__ == "__main__": 4 | g = game.Game(500,500) 5 | g.run() 6 | -------------------------------------------------------------------------------- /server.py: -------------------------------------------------------------------------------- 1 | import socket 2 | from _thread import * 3 | import sys 4 | 5 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 6 | 7 | server = 'localhost' 8 | port = 5555 9 | 10 | server_ip = socket.gethostbyname(server) 11 | 12 | try: 13 | s.bind((server, port)) 14 | 15 | except socket.error as e: 16 | print(str(e)) 17 | 18 | s.listen(2) 19 | print("Waiting for a connection") 20 | 21 | currentId = "0" 22 | pos = ["0:50,50", "1:100,100"] 23 | def threaded_client(conn): 24 | global currentId, pos 25 | conn.send(str.encode(currentId)) 26 | currentId = "1" 27 | reply = '' 28 | while True: 29 | try: 30 | data = conn.recv(2048) 31 | reply = data.decode('utf-8') 32 | if not data: 33 | conn.send(str.encode("Goodbye")) 34 | break 35 | else: 36 | print("Recieved: " + reply) 37 | arr = reply.split(":") 38 | id = int(arr[0]) 39 | pos[id] = reply 40 | 41 | if id == 0: nid = 1 42 | if id == 1: nid = 0 43 | 44 | reply = pos[nid][:] 45 | print("Sending: " + reply) 46 | 47 | conn.sendall(str.encode(reply)) 48 | except: 49 | break 50 | 51 | print("Connection Closed") 52 | conn.close() 53 | 54 | while True: 55 | conn, addr = s.accept() 56 | print("Connected to: ", addr) 57 | 58 | start_new_thread(threaded_client, (conn,)) --------------------------------------------------------------------------------