merged broken branches client with master branch and added first statehandling for card placement
This commit is contained in:
parent
8f90633b16
commit
677552a617
@ -7,13 +7,21 @@ class Player:
|
|||||||
__mana:int
|
__mana:int
|
||||||
__name:str
|
__name:str
|
||||||
__handCards:list
|
__handCards:list
|
||||||
|
__deck:list
|
||||||
|
|
||||||
def __init__(self, name:str, hp:int=1000, mana:int=0):
|
def __init__(self, name:str, deck:list, hp:int=1000, mana:int=0):
|
||||||
self.__hp = hp
|
self.__hp = hp
|
||||||
self.__name = name
|
self.__name = name
|
||||||
self.__handCards = []
|
self.__handCards = []
|
||||||
|
self.__deck = deck
|
||||||
self.__id = random.randint(3, 99999)
|
self.__id = random.randint(3, 99999)
|
||||||
|
|
||||||
|
def shuffleDeck(self):
|
||||||
|
self.__deck = random.shuffle(self.__deck)
|
||||||
|
|
||||||
|
def getDeck(self) -> list:
|
||||||
|
return self.__deck
|
||||||
|
|
||||||
def getName(self) -> str:
|
def getName(self) -> str:
|
||||||
return self.__name
|
return self.__name
|
||||||
|
|
||||||
@ -40,6 +48,9 @@ class Player:
|
|||||||
self.__handCards.append(card)
|
self.__handCards.append(card)
|
||||||
return self.__handCards
|
return self.__handCards
|
||||||
|
|
||||||
|
def setHand(self, hand:list):
|
||||||
|
self.__handCards = hand
|
||||||
|
|
||||||
def removeFromHand(self, pos:int) -> list:
|
def removeFromHand(self, pos:int) -> list:
|
||||||
self.__handCards.remove(pos)
|
self.__handCards.remove(pos)
|
||||||
return self.__handCards
|
return self.__handCards
|
Binary file not shown.
@ -1,3 +1,4 @@
|
|||||||
|
import json
|
||||||
import socket
|
import socket
|
||||||
from Classes.Game.Player import Player
|
from Classes.Game.Player import Player
|
||||||
|
|
||||||
@ -38,23 +39,28 @@ class GameManager:
|
|||||||
# this section mostly only used by the networking and event handling classes
|
# this section mostly only used by the networking and event handling classes
|
||||||
# other parts should never need to interface with this unless really required
|
# other parts should never need to interface with this unless really required
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
def startGame(self):
|
def startGame(self, tcpSocket:socket):
|
||||||
self.__state = "running"
|
self.__state = "running"
|
||||||
|
|
||||||
print("game starts")
|
print("game starts")
|
||||||
for userAddr in self.__users.keys():
|
for userAddr in self.__users.keys():
|
||||||
try:
|
try:
|
||||||
user = self.__serverWorld.getPlayers[userAddr]
|
user = self.__serverWorld.getPlayers[userAddr]["player"]
|
||||||
user.addMana(1000)
|
user.addMana(1000)
|
||||||
user.adjustHP(1000)
|
user.adjustHP(1000)
|
||||||
|
user.shuffleDeck()
|
||||||
|
cards = user.getDeck()
|
||||||
|
user.setHand(cards[:5])
|
||||||
|
|
||||||
payload = {
|
payload = {
|
||||||
"event":"startgame",
|
"event":"startgame",
|
||||||
"mana": user.getMana(),
|
"playermana": user.getMana(),
|
||||||
"hp": user.getHP()
|
"playerhp": user.getHP(),
|
||||||
|
"playername": user.getName(),
|
||||||
|
"hand": user.getHand()
|
||||||
}
|
}
|
||||||
|
|
||||||
self.send(payload, userAddr)
|
tcpSocket.send(json.dumps(payload).encode())
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"failed to start game due to error: {e}")
|
print(f"failed to start game due to error: {e}")
|
||||||
break
|
break
|
||||||
@ -84,6 +90,6 @@ class GameManager:
|
|||||||
|
|
||||||
# counts participating players and starts the game if enough have joined
|
# counts participating players and starts the game if enough have joined
|
||||||
if len(self.__players) == 2:
|
if len(self.__players) == 2:
|
||||||
self.startGame()
|
self.startGame(socket)
|
||||||
|
|
||||||
return self.__players
|
return self.__players
|
@ -1,5 +1,6 @@
|
|||||||
import json
|
import json
|
||||||
import socket
|
import socket
|
||||||
|
import sys
|
||||||
import threading
|
import threading
|
||||||
from Classes.Game.Player import Player
|
from Classes.Game.Player import Player
|
||||||
from Classes.System.GameManager import GameManager
|
from Classes.System.GameManager import GameManager
|
||||||
@ -9,82 +10,84 @@ from Classes.System.World import World
|
|||||||
|
|
||||||
class NetworkManager:
|
class NetworkManager:
|
||||||
|
|
||||||
class UDP:
|
#class UDP:
|
||||||
__Addr:str
|
# __Addr:str
|
||||||
__Port:str
|
# __Port:str
|
||||||
__BufferSize:int = 1024
|
# __BufferSize:int = 1024
|
||||||
__udpSocket:socket
|
# __udpSocket:socket
|
||||||
__users:dict
|
# __users:dict
|
||||||
__eventHandler: UDPEventHandler
|
# __eventHandler: UDPEventHandler
|
||||||
__UDPClientThread:threading.Thread
|
# __UDPClientThread:threading.Thread
|
||||||
__gameManager:GameManager
|
# __gameManager:GameManager
|
||||||
|
#
|
||||||
def __init__(self, Addr:str, Port:str, gameManager:GameManager):
|
# def __init__(self, Addr:str, Port:str, gameManager:GameManager):
|
||||||
self.__Addr = Addr
|
# self.__Addr = Addr
|
||||||
self.__Port = int(Port)
|
# self.__Port = int(Port)
|
||||||
self.__gameManager = gameManager
|
# self.__gameManager = gameManager
|
||||||
self.__users = {}
|
# self.__users = {}
|
||||||
self.__eventHandler = {}
|
# self.__eventHandler = {}
|
||||||
self.__udpSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
# self.__udpSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||||
|
#
|
||||||
try:
|
# try:
|
||||||
self.__udpSocket.bind((self.__Addr, self.__Port))
|
# self.__udpSocket.bind((self.__Addr, self.__Port))
|
||||||
except OSError as e:
|
# except OSError as e:
|
||||||
print(f"Error binding UDP socket: {e}")
|
# print(f"Error binding UDP socket: {e}")
|
||||||
|
#
|
||||||
self.__UDPClientThread = threading.Thread(target=self.receive)
|
# self.__UDPClientThread = threading.Thread(target=self.receive)
|
||||||
self.__UDPClientThread.start()
|
# self.__UDPClientThread.start()
|
||||||
|
#
|
||||||
# handles incoming udp data
|
# # handles incoming udp data
|
||||||
def receive(self):
|
# def receive(self):
|
||||||
while True:
|
# while True:
|
||||||
data, address = self.__udpSocket.recvfrom(self.__BufferSize)
|
# data, address = self.__udpSocket.recvfrom(self.__BufferSize)
|
||||||
message = data.decode()
|
# message = data.decode()
|
||||||
messageJson = json.loads(message)
|
# messageJson = json.loads(message)
|
||||||
user = messageJson.get("user")
|
# user = messageJson.get("user")
|
||||||
|
#
|
||||||
if user not in self.__users:
|
# if user not in self.__users:
|
||||||
self.__users[user] = address # Storing new user in dictionary
|
# self.__users[user] = address # Storing new user in dictionary
|
||||||
|
#
|
||||||
# Process the message and handle accordingly
|
# # Process the message and handle accordingly
|
||||||
self.__eventHandler.handleUDPEvents(messageJson, self.__serverWorld)
|
# self.__eventHandler.handleUDPEvents(messageJson, self.__serverWorld)
|
||||||
print(f"Received message from {address}: {message}")
|
# print(f"Received message from {address}: {message}")
|
||||||
|
#
|
||||||
def broadcast(self, payload:dict):
|
# def broadcast(self, payload:dict):
|
||||||
for user_address in self.__users.values():
|
# for user_address in self.__users.values():
|
||||||
self.__udpSocket.sendto(json.dumps(payload).encode(), user_address)
|
# self.__udpSocket.sendto(json.dumps(payload).encode(), user_address)
|
||||||
|
#
|
||||||
def send(self, payload:dict, user:str):
|
# def send(self, payload:dict, user:str):
|
||||||
if user in self.__users:
|
# if user in self.__users:
|
||||||
self.__udpSocket.sendto(json.dumps(payload).encode(), self.__users[user])
|
# self.__udpSocket.sendto(json.dumps(payload).encode(), self.__users[user])
|
||||||
|
#
|
||||||
class TCP:
|
class TCP:
|
||||||
__Addr:str
|
__Addr:str
|
||||||
__Port:str
|
__Port:str
|
||||||
__BufferSize:int = 1024
|
__BufferSize:int = 1024
|
||||||
__tcpSocket:socket
|
__tcpSocket:socket
|
||||||
__eventHandler: dict
|
__eventHandler: dict
|
||||||
|
__users: dict
|
||||||
__TCPClientThread:threading.Thread
|
__TCPClientThread:threading.Thread
|
||||||
__gameManager:GameManager
|
__gameManager:GameManager
|
||||||
|
|
||||||
def __init__(self, Addr:str, Port:str, gameManager:GameManager):
|
def __init__(self, Addr:str, Port:str, gameManager:GameManager):
|
||||||
|
self.running = True
|
||||||
self.__Addr = Addr
|
self.__Addr = Addr
|
||||||
self.__Port = int(Port)
|
self.__Port = int(Port)
|
||||||
self.__gameManager = gameManager
|
self.__gameManager = gameManager
|
||||||
self.__eventHandler = {}
|
self.__eventHandler = {}
|
||||||
self.__tcpSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
self.__tcpSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
self.__tcpSocket.bind((self.__Addr, self.__Port))
|
self.__tcpSocket.bind((self.__Addr, self.__Port))
|
||||||
self.__tcpSocket.listen(2)
|
self.__tcpSocket.listen()
|
||||||
|
|
||||||
self.__TCPClientThread = threading.Thread(target=self.accept_connections)
|
self.__TCPClientThread = threading.Thread(target=self.accept_connections)
|
||||||
self.__TCPClientThread.start()
|
self.__TCPClientThread.start()
|
||||||
|
|
||||||
def accept_connections(self):
|
def accept_connections(self):
|
||||||
while True:
|
while self.running:
|
||||||
try:
|
try:
|
||||||
client_tcp_socket, client_address = self.__tcpSocket.accept()
|
client_tcp_socket, client_address = self.__tcpSocket.accept()
|
||||||
print(f"Connected with {client_address}")
|
print(f"Connected with {client_address}")
|
||||||
self.__users[client_address] = client_tcp_socket
|
self.__gameManager.getPlayers()[client_address] = client_tcp_socket
|
||||||
self.__eventHandler[client_address] = TCPEventHandler(client_tcp_socket)
|
self.__eventHandler[client_address] = TCPEventHandler(client_tcp_socket)
|
||||||
client_handler_thread = threading.Thread(
|
client_handler_thread = threading.Thread(
|
||||||
target=self.receive,
|
target=self.receive,
|
||||||
@ -96,7 +99,7 @@ class NetworkManager:
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def receive(self, client_socket, client_address):
|
def receive(self, client_socket, client_address):
|
||||||
while True:
|
while self.running:
|
||||||
try:
|
try:
|
||||||
data = client_socket.recv(self.__BufferSize)
|
data = client_socket.recv(self.__BufferSize)
|
||||||
if not data:
|
if not data:
|
||||||
@ -109,10 +112,10 @@ class NetworkManager:
|
|||||||
|
|
||||||
# creates a user and counts how many currently are connected to the server
|
# creates a user and counts how many currently are connected to the server
|
||||||
# if enough users for a round are connected the server has to start the game
|
# if enough users for a round are connected the server has to start the game
|
||||||
if user not in self.__users:
|
if user not in self.__gameManager.getPlayers():
|
||||||
if messageJson["event"] == "login":
|
if messageJson["event"] == "login":
|
||||||
self.__gameManager.addPlayers(Player(messageJson["username"]), self.__tcpSocket, client_address)
|
self.__gameManager.addPlayers(Player(messageJson["username"], messageJson["deck"]), client_socket, client_address)
|
||||||
print(f"connected users {len(self.__users)}")
|
print(f"connected users {len(self.__gameManager.getPlayers())}")
|
||||||
|
|
||||||
self.__eventHandler[client_address].handleTCPEvents(messageJson, self.__gameManager, client_address)
|
self.__eventHandler[client_address].handleTCPEvents(messageJson, self.__gameManager, client_address)
|
||||||
print(f"Received message from {client_address}: {message}")
|
print(f"Received message from {client_address}: {message}")
|
||||||
@ -140,8 +143,8 @@ class NetworkManager:
|
|||||||
print(f"user '{user}' or socket was not found 'socket' failed to send data.")
|
print(f"user '{user}' or socket was not found 'socket' failed to send data.")
|
||||||
|
|
||||||
tcp: TCP
|
tcp: TCP
|
||||||
udp: UDP
|
# udp: UDP
|
||||||
|
|
||||||
def __init__(self, Addr:str, TCPPort:str, UDPPort:str, gameManager:GameManager):
|
def __init__(self, Addr:str, TCPPort:str, UDPPort:str, gameManager:GameManager):
|
||||||
self.tcp = self.TCP(Addr, TCPPort, gameManager)
|
self.tcp = self.TCP(Addr, TCPPort, gameManager)
|
||||||
self.udp = self.UDP(Addr, UDPPort, gameManager)
|
# self.udp = self.UDP(Addr, UDPPort, gameManager)
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,4 +1,5 @@
|
|||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
from Classes.System.Server import Server
|
from Classes.System.Server import Server
|
||||||
|
|
||||||
@ -9,6 +10,7 @@ def main():
|
|||||||
UDPPORT = "54323"
|
UDPPORT = "54323"
|
||||||
|
|
||||||
Server(HOST, TCPPORT, UDPPORT)
|
Server(HOST, TCPPORT, UDPPORT)
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"id": 1,
|
"id": 1,
|
||||||
|
"type":"MonsterCard",
|
||||||
"name": "Test Monster",
|
"name": "Test Monster",
|
||||||
"image": "Assets/Cards/1/cards.png",
|
"image": "Assets/Cards/1/cards.png",
|
||||||
"description": "can attack other monsters",
|
"description": "can attack other monsters",
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
{
|
{
|
||||||
"name": "testspell",
|
"name": "testspell",
|
||||||
|
"type":"EffectCard",
|
||||||
"image":"Assets/Cards/2/artwork.png",
|
"image":"Assets/Cards/2/artwork.png",
|
||||||
"costs": 30,
|
"costs": 30,
|
||||||
"description":"this is a test spell card"
|
"defense": 0,
|
||||||
|
"description":"this is a test spell card",
|
||||||
|
"attacks": []
|
||||||
}
|
}
|
@ -1,6 +1,9 @@
|
|||||||
{
|
{
|
||||||
"name": "testtrap",
|
"name": "testtrap",
|
||||||
|
"type":"EffectCard",
|
||||||
"image":"Assets/Cards/3/artwork.png",
|
"image":"Assets/Cards/3/artwork.png",
|
||||||
"costs": 30,
|
"costs": 30,
|
||||||
"description":"this is a test trap card"
|
"defense": 0,
|
||||||
|
"description":"this is a test trap card",
|
||||||
|
"attacks": []
|
||||||
}
|
}
|
98
Game_Client/Classes/Game/Cards/Card.py
Normal file
98
Game_Client/Classes/Game/Cards/Card.py
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
import json
|
||||||
|
import pygame
|
||||||
|
|
||||||
|
from Classes.System.Components.InputHandler import InputHandler
|
||||||
|
from Classes.Game.Player import Player
|
||||||
|
|
||||||
|
class Card(pygame.sprite.Sprite):
|
||||||
|
__name:str
|
||||||
|
__id:int
|
||||||
|
__description:str
|
||||||
|
__attacks = []
|
||||||
|
__type:str = "MonsterCard"
|
||||||
|
__pos:pygame.Vector2
|
||||||
|
__dragging:bool = False
|
||||||
|
__offset:pygame.Vector2 = pygame.Vector2(0,0)
|
||||||
|
__inputHandler: InputHandler
|
||||||
|
__owner:Player
|
||||||
|
__state:str
|
||||||
|
image:pygame.image
|
||||||
|
rect:pygame.rect
|
||||||
|
|
||||||
|
def __init__(self, pos: pygame.Vector2, assetDir: str, inputHandler: InputHandler, owner: Player):
|
||||||
|
if assetDir == "":
|
||||||
|
raise ValueError("Card: imagePath cannot be empty")
|
||||||
|
|
||||||
|
pygame.sprite.Sprite.__init__(self)
|
||||||
|
|
||||||
|
with open(assetDir + "/card.json", 'r') as file:
|
||||||
|
data = json.load(file)
|
||||||
|
|
||||||
|
self.__owner = owner
|
||||||
|
self.__id = int(data["id"])
|
||||||
|
self.__pos = pos
|
||||||
|
self.__name = data["name"]
|
||||||
|
self.__type = data.get("type")
|
||||||
|
self.image = pygame.image.load(assetDir + "/card.png").convert_alpha()
|
||||||
|
self.rect = self.image.get_rect()
|
||||||
|
self.__inputHandler = inputHandler
|
||||||
|
self.rect.center = self.__pos
|
||||||
|
self.__description = data["description"]
|
||||||
|
self.original_size = self.image.get_size()
|
||||||
|
self.original_position = self.rect.center
|
||||||
|
self.__state = "onHand"
|
||||||
|
|
||||||
|
self.__attacks = []
|
||||||
|
for attack in data.get("attacks", []):
|
||||||
|
self.__attacks.append(attack)
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
if self.__dragging:
|
||||||
|
mouse_pos = self.__inputHandler.getMousePos()
|
||||||
|
self.__pos = mouse_pos
|
||||||
|
self.rect.center = self.__pos
|
||||||
|
|
||||||
|
def attacks(self):
|
||||||
|
return self.__attacks
|
||||||
|
|
||||||
|
def getName(self) -> str:
|
||||||
|
return self.__name
|
||||||
|
|
||||||
|
def getCardSprite(self) -> pygame.image:
|
||||||
|
return self.__cardSprite
|
||||||
|
|
||||||
|
def getDescription(self):
|
||||||
|
return self.__description
|
||||||
|
|
||||||
|
def getDragging(self):
|
||||||
|
return self.__dragging
|
||||||
|
|
||||||
|
def getOffset(self):
|
||||||
|
return self.__offset
|
||||||
|
|
||||||
|
def getPos(self):
|
||||||
|
return self.__pos
|
||||||
|
|
||||||
|
def getType(self):
|
||||||
|
return self.__type
|
||||||
|
|
||||||
|
def getID(self) -> int:
|
||||||
|
return self.__id
|
||||||
|
|
||||||
|
def getOwner(self) -> Player:
|
||||||
|
return self.__owner
|
||||||
|
|
||||||
|
def getState(self) -> str:
|
||||||
|
return self.__state
|
||||||
|
|
||||||
|
def setDragging(self, dragging:bool):
|
||||||
|
self.__dragging = dragging
|
||||||
|
|
||||||
|
def setOffset(self, offset:pygame.Vector2):
|
||||||
|
self.__offset = offset
|
||||||
|
|
||||||
|
def setPos(self, pos:pygame.Vector2):
|
||||||
|
self.__pos = pos
|
||||||
|
|
||||||
|
def setState(self, state:str):
|
||||||
|
self.__state = state
|
BIN
Game_Client/Classes/Game/Cards/__pycache__/Card.cpython-311.pyc
Normal file
BIN
Game_Client/Classes/Game/Cards/__pycache__/Card.cpython-311.pyc
Normal file
Binary file not shown.
BIN
Game_Client/Classes/Game/Cards/__pycache__/Card.cpython-312.pyc
Normal file
BIN
Game_Client/Classes/Game/Cards/__pycache__/Card.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,8 +1,16 @@
|
|||||||
|
import pygame
|
||||||
from Classes.Game.World import World
|
from Classes.Game.World import World
|
||||||
|
from Classes.Game.Cards.Card import Card
|
||||||
|
from Classes.Game.Player import Player
|
||||||
|
from Classes.System.Components.InputHandler import InputHandler
|
||||||
|
|
||||||
|
|
||||||
# send from the server to tell the player the game starts
|
# send from the server to tell the player the game starts
|
||||||
# gives the client its and the opponents stats (not cards!!)
|
# gives the client its and the opponents stats (not cards!!)
|
||||||
def GameStart(world: World):
|
def GameStart(world: World, handCards:list, inputHandler:InputHandler, owner:Player, opponent:Player):
|
||||||
print("game starts")
|
index:int = 0
|
||||||
pass
|
world.setEnemy(opponent)
|
||||||
|
|
||||||
|
for card in handCards:
|
||||||
|
world.AddToPlayerHand(Card(pygame.Vector2(500 + (index + 100), 1050), f"Assets/Cards/{card}/", inputHandler, owner))
|
||||||
|
|
@ -1,20 +1,22 @@
|
|||||||
|
import json
|
||||||
import pygame
|
import pygame
|
||||||
from Classes.System.Network.NetworkManager import NetworkManager
|
from Classes.System.Network.TCPClient import TCPClient
|
||||||
from Classes.Game.World import World
|
from Classes.Game.World import World
|
||||||
|
from Classes.Game.Player import Player
|
||||||
|
|
||||||
|
|
||||||
# event the client sends to let the server know it logged in
|
# event the client sends to let the server know it logged in
|
||||||
def Login(networkManager:NetworkManager):
|
def Login(tcpClient:TCPClient):
|
||||||
payload = {
|
payload = {
|
||||||
"event":"login",
|
"event":"login",
|
||||||
"username": "player"
|
"username": "player",
|
||||||
|
"deck": [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
|
||||||
}
|
}
|
||||||
|
|
||||||
networkManager.tcp.send(payload)
|
tcpClient.send(payload)
|
||||||
|
|
||||||
# server response for login event
|
# server response for login event
|
||||||
def LoginResponse(networkManager:NetworkManager, gameWorld: World):
|
def LoginResponse(message:json):
|
||||||
# todo: get labels from world
|
# checks if the response on the login request is successfull
|
||||||
# todo: get name for enemy
|
if message["status"] != "success":
|
||||||
# todo: adjust enemy name label
|
print("login failed")
|
||||||
pass
|
|
@ -1,9 +1,9 @@
|
|||||||
import pygame
|
import pygame
|
||||||
from Classes.Game.World import World
|
from Classes.Game.World import World
|
||||||
from Classes.System.Network.NetworkManager import NetworkManager
|
from Classes.System.Components.InputHandler import InputHandler
|
||||||
|
|
||||||
# the event the client sends to the server when it places a card
|
# the event the client sends to the server when it places a card
|
||||||
def PlaceCard(networkManager: NetworkManager, card):
|
def PlaceCard(tcpClient, card):
|
||||||
# todo: send card information to the server
|
# todo: send card information to the server
|
||||||
# todo: required info is:
|
# todo: required info is:
|
||||||
# - position
|
# - position
|
||||||
@ -12,12 +12,24 @@ def PlaceCard(networkManager: NetworkManager, card):
|
|||||||
payload = {
|
payload = {
|
||||||
"event":"placecard",
|
"event":"placecard",
|
||||||
"card": card.getID(),
|
"card": card.getID(),
|
||||||
|
"type": card.getType(),
|
||||||
"pos": card.getPos(),
|
"pos": card.getPos(),
|
||||||
}
|
}
|
||||||
|
|
||||||
networkManager.udp.send(payload)
|
tcpClient.send(payload)
|
||||||
|
|
||||||
# the event send from the server to display a card on the field
|
# the event send from the server to display a card on the field
|
||||||
def CardPlaced(world:World, card:int, pos:pygame.Vector2):
|
def CardPlaced(world:World, card:int, type:str, owner:str, pos:pygame.Vector2, inputHandler:InputHandler):
|
||||||
|
if type == "MonsterCard":
|
||||||
|
world.spawnMonsterCard(f"Assets/Cards/{card}/", pos, inputHandler, owner)
|
||||||
|
pass
|
||||||
|
elif type == "SpellCard":
|
||||||
|
world.spawnSpellCard(f"Assets/Cards/{card}/", pos, inputHandler, owner)
|
||||||
|
pass
|
||||||
|
elif type == "TrapCard":
|
||||||
|
world.spawmTrapCard(f"Assets/Cards/{card}/", pos, inputHandler, owner)
|
||||||
|
pass
|
||||||
|
pass
|
||||||
|
|
||||||
|
def MovedCard(world:World, card:int, type:str, owner:str, oldPos:pygame.Vector2, newPos:pygame.Vector2, inputHandler:InputHandler):
|
||||||
pass
|
pass
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -6,6 +6,7 @@ from Classes.Game.Cards.SpellCard import SpellCard
|
|||||||
from Classes.Game.Cards.TrapCard import TrapCard
|
from Classes.Game.Cards.TrapCard import TrapCard
|
||||||
from Classes.System.Components.InputHandler import InputHandler
|
from Classes.System.Components.InputHandler import InputHandler
|
||||||
from Classes.Game.Player import Player
|
from Classes.Game.Player import Player
|
||||||
|
from Classes.Game.Cards.Card import Card
|
||||||
|
|
||||||
class World():
|
class World():
|
||||||
__boardFields:list
|
__boardFields:list
|
||||||
@ -113,18 +114,8 @@ class World():
|
|||||||
label.setText(player.getName())
|
label.setText(player.getName())
|
||||||
self.__enemy = player
|
self.__enemy = player
|
||||||
|
|
||||||
def spawnMonsterCard(self, asset:str, pos:pygame.Vector2, inputHandler:InputHandler, owner:Player) -> MonsterCard:
|
def spawnCard(self, asset:str, pos:pygame.Vector2, inputHandler:InputHandler, owner:Player) -> Card:
|
||||||
card = MonsterCard(pos, asset, inputHandler, owner)
|
card = Card(pos, asset, inputHandler, owner)
|
||||||
self.__cards.add(card)
|
|
||||||
return card
|
|
||||||
|
|
||||||
def spawnSpellCard(self, asset:str, pos:pygame.Vector2, inputHandler:InputHandler, owner:Player) -> SpellCard:
|
|
||||||
card = SpellCard(pos, asset, inputHandler, owner)
|
|
||||||
self.__cards.add(card)
|
|
||||||
return card
|
|
||||||
|
|
||||||
def spawnTrapCard(self, asset:str, pos:pygame.Vector2, inputHandler:InputHandler, owner:Player) -> TrapCard:
|
|
||||||
card = TrapCard(pos, asset, inputHandler, owner)
|
|
||||||
self.__cards.add(card)
|
self.__cards.add(card)
|
||||||
return card
|
return card
|
||||||
|
|
||||||
@ -132,5 +123,5 @@ class World():
|
|||||||
for card in cards:
|
for card in cards:
|
||||||
self.__cards.add(card)
|
self.__cards.add(card)
|
||||||
|
|
||||||
def AddToPlayerHand(self, Card):
|
def AddToPlayerHand(self, Card:Card):
|
||||||
self.__PlayerHandCards.add(Card)
|
self.__PlayerHandCards.add(Card)
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Game_Client/Classes/Game/__pycache__/Player.cpython-312.pyc
Normal file
BIN
Game_Client/Classes/Game/__pycache__/Player.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -5,10 +5,11 @@ from Classes.Game.Cards.MonsterCard import MonsterCard
|
|||||||
from Classes.System.Components.Window import Window
|
from Classes.System.Components.Window import Window
|
||||||
from Classes.System.Components.InputHandler import InputHandler
|
from Classes.System.Components.InputHandler import InputHandler
|
||||||
from Classes.Game.World import World
|
from Classes.Game.World import World
|
||||||
from Classes.System.Network.NetworkManager import NetworkManager
|
from Classes.System.Network.TCPClient import TCPClient
|
||||||
from Classes.Game.Events.Login import Login
|
from Classes.Game.Events.Login import Login
|
||||||
from Classes.Game.Events.PlaceCard import PlaceCard
|
from Classes.Game.Events.PlaceCard import PlaceCard
|
||||||
from Classes.Game.Player import Player
|
from Classes.Game.Player import Player
|
||||||
|
from Classes.Game.Cards.Card import Card
|
||||||
|
|
||||||
class App:
|
class App:
|
||||||
|
|
||||||
@ -19,7 +20,7 @@ class App:
|
|||||||
__myFont:pygame.font
|
__myFont:pygame.font
|
||||||
__world:World
|
__world:World
|
||||||
__inputHandler: InputHandler
|
__inputHandler: InputHandler
|
||||||
__networkManager: NetworkManager
|
__tcpClient: TCPClient
|
||||||
|
|
||||||
def __init__(self, width:int=1920, height:int=1080, title:str="default title"):
|
def __init__(self, width:int=1920, height:int=1080, title:str="default title"):
|
||||||
pygame.font.init()
|
pygame.font.init()
|
||||||
@ -27,17 +28,17 @@ class App:
|
|||||||
self.__window = Window(width=width, height=height, title=title)
|
self.__window = Window(width=width, height=height, title=title)
|
||||||
self.__inputHandler = InputHandler()
|
self.__inputHandler = InputHandler()
|
||||||
|
|
||||||
|
# game word
|
||||||
|
self.__world = World(self.__window.getScreen())
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.__networkManager = NetworkManager("127.0.0.1", "54322", "54323")
|
self.__tcpClient = TCPClient("127.0.0.1", "54322", self.__world, self.__inputHandler)
|
||||||
Login(self.__networkManager) # will login to the server
|
Login(self.__tcpClient) # will login to the server
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"failed to login due to error {e}")
|
print(f"failed to login due to error {e}")
|
||||||
print("server connection failed or got refused")
|
print("server connection failed or got refused")
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# game word
|
|
||||||
self.__world = World(self.__window.getScreen())
|
|
||||||
|
|
||||||
self.startGameLoop()
|
self.startGameLoop()
|
||||||
self.onCleanup()
|
self.onCleanup()
|
||||||
|
|
||||||
@ -46,12 +47,12 @@ class App:
|
|||||||
# create sprite groups
|
# create sprite groups
|
||||||
# todo: remove these and let server handle card creation instead
|
# todo: remove these and let server handle card creation instead
|
||||||
# blocker: server - client communication [WIP]
|
# blocker: server - client communication [WIP]
|
||||||
self.__world.spawnMonsterCard("Assets/Cards/1/", pygame.Vector2(500, 1050), self.__inputHandler, Player(1000, 0, "test"))
|
self.__world.spawnCard("Assets/Cards/1/", pygame.Vector2(500, 1050), self.__inputHandler, Player(1000, 0, "test"))
|
||||||
self.__world.spawnMonsterCard("Assets/Cards/1/", pygame.Vector2(600, 1050), self.__inputHandler, Player(1000, 0, "test"))
|
self.__world.spawnCard("Assets/Cards/1/", pygame.Vector2(600, 1050), self.__inputHandler, Player(1000, 0, "test"))
|
||||||
self.__world.spawnMonsterCard("Assets/Cards/1/", pygame.Vector2(700, 1050), self.__inputHandler, Player(1000, 0, "test"))
|
self.__world.spawnCard("Assets/Cards/1/", pygame.Vector2(700, 1050), self.__inputHandler, Player(1000, 0, "test"))
|
||||||
self.__world.spawnMonsterCard("Assets/Cards/1/", pygame.Vector2(800, 1050), self.__inputHandler, Player(1000, 0, "test"))
|
self.__world.spawnCard("Assets/Cards/1/", pygame.Vector2(800, 1050), self.__inputHandler, Player(1000, 0, "test"))
|
||||||
self.__world.spawnMonsterCard("Assets/Cards/1/", pygame.Vector2(900, 1050), self.__inputHandler, Player(1000, 0, "test"))
|
self.__world.spawnCard("Assets/Cards/1/", pygame.Vector2(900, 1050), self.__inputHandler, Player(1000, 0, "test"))
|
||||||
self.__world.spawnMonsterCard("Assets/Cards/1/", pygame.Vector2(1000, 1050), self.__inputHandler, Player(1000, 0, "test"))
|
self.__world.spawnCard("Assets/Cards/1/", pygame.Vector2(1000, 1050), self.__inputHandler, Player(1000, 0, "test"))
|
||||||
|
|
||||||
while self.__running:
|
while self.__running:
|
||||||
self.__clock.tick(self.__FPS)
|
self.__clock.tick(self.__FPS)
|
||||||
@ -63,6 +64,7 @@ class App:
|
|||||||
|
|
||||||
# updates all cards inside the cards Spritegroup at each step the gameloops does
|
# updates all cards inside the cards Spritegroup at each step the gameloops does
|
||||||
self.__world.getCards().update()
|
self.__world.getCards().update()
|
||||||
|
self.__world.getHandCards().update()
|
||||||
|
|
||||||
# draw groups
|
# draw groups
|
||||||
self.__window.drawSpriteGroup(self.__world.getCards())
|
self.__window.drawSpriteGroup(self.__world.getCards())
|
||||||
@ -88,22 +90,24 @@ class App:
|
|||||||
|
|
||||||
for card in self.__world.getCards():
|
for card in self.__world.getCards():
|
||||||
if card.rect.collidepoint(mouse_pos) and selectedCard == None:
|
if card.rect.collidepoint(mouse_pos) and selectedCard == None:
|
||||||
card.setDragging(True)
|
if card.getState() == "onHand":
|
||||||
selectedCard = card
|
card.setDragging(True)
|
||||||
|
selectedCard = card
|
||||||
|
for field in self.__world.getBoardFields():
|
||||||
|
if field.getRect().collidepoint(mouse_pos):
|
||||||
|
if field.getSide() == "Player":
|
||||||
|
if field.getType() == "MonsterField" and card.getType() == "MonsterCard":
|
||||||
|
# todo: resize card so that it fits into the card field
|
||||||
|
card.rect.center = field.rect.center
|
||||||
|
field.image = card.image.copy()
|
||||||
|
card.setDragging(False)
|
||||||
|
elif field.getType() == "EffectField" and card.getType() == "EffectCard" or field.getType() == "EffectField" and card.getType() == "EffectCard":
|
||||||
|
# todo: resize card so that it fits into the card field
|
||||||
|
card.rect.center = field.rect.center
|
||||||
|
field.image = card.image.copy()
|
||||||
|
card.setDragging(False)
|
||||||
|
|
||||||
|
|
||||||
for field in self.__world.getBoardFields():
|
|
||||||
if field.getRect().collidepoint(mouse_pos):
|
|
||||||
if field.getSide() == "Player":
|
|
||||||
if field.getType() == "MonsterField" and card.getType() == "MonsterCard":
|
|
||||||
# todo: resize card so that it fits into the card field
|
|
||||||
card.rect.center = field.rect.center
|
|
||||||
field.image = card.image.copy()
|
|
||||||
card.setDragging(False)
|
|
||||||
elif field.getType() == "EffectField" and card.getType() == "SpellCard" or field.getType() == "EffectField" and card.getType() == "TrapCard":
|
|
||||||
# todo: resize card so that it fits into the card field
|
|
||||||
card.rect.center = field.rect.center
|
|
||||||
field.image = card.image.copy()
|
|
||||||
card.setDragging(False)
|
|
||||||
elif self.__inputHandler.getPressed()[pygame.K_SPACE]:
|
elif self.__inputHandler.getPressed()[pygame.K_SPACE]:
|
||||||
print("card spawned")
|
print("card spawned")
|
||||||
self.__world.spawnMonsterCard("Assets/Cards/MonsterCards/testmonstercard/", self.__inputHandler.getMousePos(), self.__inputHandler)
|
self.__world.spawnMonsterCard("Assets/Cards/MonsterCards/testmonstercard/", self.__inputHandler.getMousePos(), self.__inputHandler)
|
||||||
@ -113,9 +117,14 @@ class App:
|
|||||||
if event.button == 1: # Wenn linke Maustaste losgelassen wird
|
if event.button == 1: # Wenn linke Maustaste losgelassen wird
|
||||||
for card in self.__world.getCards():
|
for card in self.__world.getCards():
|
||||||
card.setDragging(False)
|
card.setDragging(False)
|
||||||
|
card.setState("placed")
|
||||||
# TODO: send place card event to server
|
# TODO: send place card event to server
|
||||||
# resets the currently selected card in order to prevent it getting moved
|
# resets the currently selected card in order to prevent it getting moved
|
||||||
PlaceCard(self.__networkManager, card) # tells the server that the player placed this card
|
try:
|
||||||
|
PlaceCard(self.__tcpClient, card) # tells the server that the player placed this card
|
||||||
|
except Exception as e:
|
||||||
|
print(f"failed to place card on server due to error: {e}")
|
||||||
|
|
||||||
if not card == None:
|
if not card == None:
|
||||||
card = None
|
card = None
|
||||||
|
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,27 +1,37 @@
|
|||||||
import socket
|
import socket
|
||||||
|
|
||||||
|
import pygame
|
||||||
|
|
||||||
|
from Classes.Game.Events.PlaceCard import CardPlaced
|
||||||
|
from Classes.System.Components.InputHandler import InputHandler
|
||||||
|
from Classes.Game.World import World
|
||||||
|
from Classes.Game.Events.GameStart import GameStart
|
||||||
|
from Classes.Game.Player import Player
|
||||||
|
|
||||||
class TCPEventHandler:
|
class TCPEventHandler:
|
||||||
def __init__(self, socket:socket):
|
def __init__(self, socket:socket):
|
||||||
self.tcp_socket = socket
|
self.tcp_socket = socket
|
||||||
|
|
||||||
def handleEvents(self, message):
|
def handleEvents(self, message, inputHandler:InputHandler, world:World):
|
||||||
if message["event"] == "login":
|
if message["event"] == "login":
|
||||||
# todo: handle login response here
|
# todo: handle login response here
|
||||||
pass
|
pass
|
||||||
elif message["event"] == "startgame":
|
elif message["event"] == "startgame":
|
||||||
# todo: handle starting the game here
|
print("gamestart")
|
||||||
print("game starts")
|
GameStart(world, message["hand"], inputHandler, world.getPlayer())
|
||||||
pass
|
pass
|
||||||
|
elif message["event"] == "PlaceCard":
|
||||||
class UDPEventHandler:
|
CardPlaced(world, message["card"], message["type"], message["owner"], pygame.Vector2(int(message["x"]), int(message["y"]), inputHandler))
|
||||||
def __init__(self, socket:socket):
|
|
||||||
self.udp_socket = socket
|
|
||||||
|
|
||||||
def handleEvents(self, message):
|
|
||||||
if message["event"] == "PlaceCard":
|
|
||||||
pass
|
pass
|
||||||
elif message["event"] == "MoveCard":
|
elif message["event"] == "MoveCard":
|
||||||
|
CardMoved(
|
||||||
|
world,
|
||||||
|
message["card"],
|
||||||
|
message["type"],
|
||||||
|
message["owner"],
|
||||||
|
pygame.Vector2(int(message["old_x"]), int(message["old_y"])),
|
||||||
|
pygame.Vector2(int(message["new_x"]), int(message["new_y"])),
|
||||||
|
inputHandler)
|
||||||
pass
|
pass
|
||||||
elif message["event"] == "RemoveCard":
|
elif message["event"] == "RemoveCard":
|
||||||
pass
|
pass
|
||||||
|
@ -1,85 +0,0 @@
|
|||||||
import json
|
|
||||||
import socket
|
|
||||||
import threading
|
|
||||||
|
|
||||||
from Classes.System.Network.EventHandler import TCPEventHandler, UDPEventHandler
|
|
||||||
|
|
||||||
class NetworkManager:
|
|
||||||
class UDP:
|
|
||||||
def __init__(self, addr: str, port: str):
|
|
||||||
self.addr = addr
|
|
||||||
self.port = int(port)
|
|
||||||
self.udpSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
||||||
self.eventHandler = UDPEventHandler(self.udpSocket)
|
|
||||||
|
|
||||||
try:
|
|
||||||
self.udpSocket.bind((self.addr, self.port))
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error binding UDP socket: {e}")
|
|
||||||
|
|
||||||
# start listener thread
|
|
||||||
self.listen()
|
|
||||||
|
|
||||||
def send(self, message: dict):
|
|
||||||
try:
|
|
||||||
self.udpSocket.sendto(json.dumps(message).encode(), (self.addr, self.port))
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error sending UDP data: {e}")
|
|
||||||
|
|
||||||
# starts a listener thread for udp data
|
|
||||||
def receive(self):
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
data, addr = self.udpSocket.recvfrom(1024)
|
|
||||||
if data:
|
|
||||||
decoded_data = json.loads(data.decode())
|
|
||||||
self.eventHandler.handleEvents(decoded_data)
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error receiving UDP data: {e}")
|
|
||||||
break
|
|
||||||
|
|
||||||
def listen(self):
|
|
||||||
udpThread = threading.Thread(target=self.receive)
|
|
||||||
udpThread.daemon = True
|
|
||||||
udpThread.start()
|
|
||||||
|
|
||||||
class TCP:
|
|
||||||
def __init__(self, addr: str, port: str):
|
|
||||||
self.addr = addr
|
|
||||||
self.port = int(port)
|
|
||||||
self.tcpSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
||||||
self.eventHandler = TCPEventHandler(self.tcpSocket)
|
|
||||||
|
|
||||||
try:
|
|
||||||
self.tcpSocket.connect((self.addr, self.port))
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error connecting TCP socket: {e}")
|
|
||||||
|
|
||||||
# Starten des Listener-Threads
|
|
||||||
self.listen()
|
|
||||||
|
|
||||||
def send(self, message: dict):
|
|
||||||
try:
|
|
||||||
self.tcpSocket.sendall(json.dumps(message).encode())
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error sending TCP data: {e}")
|
|
||||||
|
|
||||||
def receive(self):
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
data = self.tcpSocket.recv(1024)
|
|
||||||
if data:
|
|
||||||
decoded_data = json.loads(data.decode())
|
|
||||||
self.eventHandler.handleEvents(decoded_data)
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error receiving TCP data: {e}")
|
|
||||||
break
|
|
||||||
|
|
||||||
def listen(self):
|
|
||||||
tcpThread = threading.Thread(target=self.receive)
|
|
||||||
tcpThread.daemon = True
|
|
||||||
tcpThread.start()
|
|
||||||
|
|
||||||
def __init__(self, addr: str, tcpport: str, udpport: str):
|
|
||||||
self.tcp = self.TCP(addr, tcpport)
|
|
||||||
self.udp = self.UDP(addr, udpport)
|
|
46
Game_Client/Classes/System/Network/TCPClient.py
Normal file
46
Game_Client/Classes/System/Network/TCPClient.py
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import json
|
||||||
|
import socket
|
||||||
|
import threading
|
||||||
|
|
||||||
|
from Classes.System.Network.EventHandler import TCPEventHandler
|
||||||
|
from Classes.Game.World import World
|
||||||
|
from Classes.System.Components.InputHandler import InputHandler
|
||||||
|
|
||||||
|
class TCPClient:
|
||||||
|
def __init__(self, addr: str, port: str, world:World, inputHandler:InputHandler):
|
||||||
|
self.addr = addr
|
||||||
|
self.port = int(port)
|
||||||
|
self.tcpSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
self.eventHandler = TCPEventHandler(self.tcpSocket)
|
||||||
|
self.world = world
|
||||||
|
self.inputHandler = inputHandler
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.tcpSocket.connect((self.addr, self.port))
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error connecting TCP socket: {e}")
|
||||||
|
|
||||||
|
# Starten des Listener-Threads
|
||||||
|
self.listen()
|
||||||
|
|
||||||
|
def send(self, message: dict):
|
||||||
|
try:
|
||||||
|
self.tcpSocket.sendall(json.dumps(message).encode())
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error sending TCP data: {e}")
|
||||||
|
|
||||||
|
def receive(self):
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
data = self.tcpSocket.recv(1024)
|
||||||
|
if data:
|
||||||
|
decoded_data = json.loads(data.decode())
|
||||||
|
self.eventHandler.handleEvents(decoded_data, self.inputHandler, self.world)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error receiving TCP data: {e}")
|
||||||
|
break
|
||||||
|
|
||||||
|
def listen(self):
|
||||||
|
tcpThread = threading.Thread(target=self.receive)
|
||||||
|
tcpThread.daemon = True
|
||||||
|
tcpThread.start()
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user