Start multiplayer work

This commit is contained in:
pjht 2018-08-26 12:57:36 -05:00
parent eb57742379
commit df0c880c01
8 changed files with 227 additions and 6 deletions

View File

@ -34,10 +34,11 @@ make_block("BlockStone","stone")
make_block("BlockTree","tree",False,("wood",8))
make_block("BlockGrass","grass",True)
make_block("BlockWood","wood")
make_block("BlockCoal","coal")
make_block("BlockCoal","coal_ore")
GameRegistry.registerFuel("coal",8)
make_block("BlockIron","iron")
make_block("BlockIron","iron_ore")
make_block("ItemIronIngot","iron_ingot",False)
#make_block("ItemCoal","coal",False)
class BlockDoor(Block):
unlocalisedName="door"
openDoor=pygame.image.load(os.path.join("tiles","door_open.png"))

143
client.py Normal file
View File

@ -0,0 +1,143 @@
import pygame
import os
import random
import recipes
import sys
import select
import blocks
import socket
import pickle
import lib.constants as constants
from lib.gameregistry import GameRegistry
from lib.map import Map
from lib.character import Character
from lib.block import Block
from player import *
from time import sleep
def recv_str(sock,print_str=True):
str=""
ch=""
while True:
ch=sock.recv(1).decode("utf-8")
if ch=="\n":
break
str+=ch
if print_str:
print(str)
return str
def send_str(sock,str):
print(str)
sock.send((str+"\n").encode("utf-8"))
def recv_hash(sock):
hash={}
len=int(recv_str(sock,False))
for _ in range(len):
key=recv_str(sock,False)
val=recv_str(sock,False)
hash[key]=val
print(hash)
return hash
def recvall(sock):
BUFF_SIZE=4096
data=b''
while True:
part=sock.recv(BUFF_SIZE)
data+=part
if len(part)<BUFF_SIZE:
break
return data
UNAME=input("UNAME:")
pygame.init()
Block.init()
recipes.init()
pygame.display.set_caption(UNAME)
screen=pygame.display.set_mode((constants.WINDWIDTH,constants.WINDHEIGHT))
sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(("localhost",2000))
send_str(sock,"ADD_USR")
send_str(sock,UNAME)
my_uid=int(recv_str(sock))
uid_map={}
send_str(sock,"GET_MAP")
data=recvall(sock)
map=pickle.loads(data)
sleep(0.5)
# The server's generated map does not have a screen. We fix that here.
map.screen=screen
for s in map.sprites():
s.screen=screen
send_str(sock,"GET_POS_FOR_UID")
send_str(sock,str(my_uid))
x=int(recv_str(sock))*constants.TILESIZE
y=int(recv_str(sock))*constants.TILESIZE
player=Player(x,y,map,screen,UNAME,"player")
others={}
running=True
move=False
inv=False
helvetica_neue=pygame.font.SysFont('Helvetica Neue',constants.FONTSIZE)
key_to_dir={
pygame.K_UP:"up",
pygame.K_DOWN:"down",
pygame.K_LEFT:"left",
pygame.K_RIGHT:"right"
}
while running:
send_str(sock,"GET_UID_MAP")
uid_map=recv_hash(sock)
# Will be filled with usernames of connected players
connected=[]
for uname,uid in uid_map.items():
if uname!=UNAME:
print("Getting {}'s position".format(uname))
send_str(sock,"GET_POS_FOR_UID")
send_str(sock,uid)
x=int(recv_str(sock))*constants.TILESIZE
y=int(recv_str(sock))*constants.TILESIZE
if uname in others:
others[uname].x=x
others[uname].y=y
else:
others[uname]=Player(x,y,map,screen,uname,"slime")
connected.append(uname)
# Remove all disconnected players
others_copy=others.copy()
for uname,uid in others_copy.items():
if not uname in connected:
del others[uname]
for event in pygame.event.get():
if event.type==pygame.QUIT:
running=False
if move:
player.move(dir)
if inv:
screen.fill([255,255,255])
text=[]
label=[]
for item, count in player.inv.inv.items():
text.append("{} {}".format(count,item))
for line in text:
label.append(helvetica_neue.render(line, True, (0,0,0)))
for line in range(len(label)):
screen.blit(label[line],(1,(line*constants.FONTSIZE)+(2*line)))
pygame.display.flip()
else:
screen.fill([0,0,0])
map.draw()
player.draw()
selected=player.inv.selected
if selected!="":
texture=Block.textures[selected]
screen.blit(texture,(0*constants.TILESIZE,32*constants.TILESIZE))
for uname,other in others.items():
other.draw()
pygame.display.flip()
sleep(0.5)
send_str(sock,"CLOSE")
send_str(sock,UNAME)
sock.close()

View File

@ -19,7 +19,8 @@ recipes.init()
pygame.display.set_caption("game")
screen=pygame.display.set_mode((constants.WINDWIDTH,constants.WINDHEIGHT))
map=Map(screen)
player=Player(0,0,map,screen)
player=Player(0,0,map,screen,"PJHT","player")
player.inv.addTile("workbench",1)
if __name__ == '__main__':
running=True

View File

@ -2,9 +2,10 @@ from lib.character import Character
import lib.constants as constants
from lib.inventory import Inventory
class Player(Character):
def __init__(self,x,y,map,screen,*groups):
super().__init__(x,y,"player",map,screen,*groups)
def __init__(self,x,y,map,screen,uname,type,*groups):
super().__init__(x,y,type,map,screen,*groups)
self.inv=Inventory()
self.uname=uname
def facingTile(self):
x=self.x/constants.TILESIZE

75
serv.py Normal file
View File

@ -0,0 +1,75 @@
import pygame
import os
import random
import recipes
import sys
import select
import blocks
import socket
import _thread
import pickle
import lib.constants as constants
from lib.gameregistry import GameRegistry
from lib.map import Map
from lib.character import Character
from lib.block import Block
from player import *
from time import sleep
uid_map={}
next_uid=0
def recv_str(sock):
str=""
ch=""
while True:
ch=sock.recv(1).decode("utf-8")
if ch=="\n":
break
str+=ch
return str
def send_str(sock,str):
sock.send((str+"\n").encode("utf-8"))
def send_hash(sock,hash):
send_str(sock,str(len(hash)))
for key,val in hash.items():
send_str(sock,str(key))
send_str(sock,str(val))
def on_new_client(sock):
global uid_map
global next_uid
while True:
msg=recv_str(sock)
if msg=="CLOSE":
uname=recv_str(sock)
del uid_map[uname]
elif msg=="ADD_USR":
uname=recv_str(sock)
uid_map[uname]=next_uid
resp=str(next_uid)
send_str(sock,resp)
next_uid+=1
elif msg=="GET_UID_MAP":
send_hash(sock,uid_map)
elif msg=="GET_MAP":
data_string=pickle.dumps(map)
sock.send(data_string)
elif msg=="GET_POS_FOR_UID":
uid=recv_str(sock)
send_str(sock,uid)
send_str(sock,"0")
clientsocket.close()
map=Map(None)
global s
s=socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
host="localhost"
port=2000
s.bind((host, port))
s.listen(5)
while True:
c,addr=s.accept()
_thread.start_new_thread(on_new_client,(c,))
s.close()

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
tiles/iron_ingot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB