merged rework -> master

This commit is contained in:
2024-02-28 20:47:49 +01:00
248 changed files with 1969 additions and 508 deletions

View File

@ -0,0 +1,85 @@
import os
import pygame
class BoardField(pygame.sprite.Sprite):
__fieldID:str
__name:str
__side:str
__type:str
__pos:pygame.Vector2
__size:tuple
__color:tuple = (255,255,255)
__holdsCard = None
image:pygame.image
rect:pygame.rect
def __init__(self, name:str, side:str, type:str, pos:pygame.Vector2, imagePath:str, fid:str):
pygame.sprite.Sprite.__init__(self)
self.__name = name
self.__side = side
self.__type = type
self.__pos = pos
self.__holdsCard = None
self.__fieldID = fid
# Überprüfen des Dateipfads
if not os.path.exists(imagePath):
print("Der Dateipfad zur Bilddatei ist ungültig oder die Datei existiert nicht.")
else:
# Wenn der Pfad gültig ist, versuchen Sie, das Bild zu laden
self.image = pygame.image.load(imagePath).convert_alpha()
self.rect = self.image.get_rect()
self.rect.center = self.__pos
def getName(self) -> str:
return self.__name
def getSide(self) -> str:
return self.__side
def getType(self) -> str:
return self.__type
def getPos(self) -> pygame.Vector2:
return self.__pos
def getSize(self) -> tuple:
return self.__size
def getColor(self) -> tuple:
return self.__color
def getRect(self) -> pygame.Rect:
return self.rect
def getImage(self) -> pygame.image:
return self.image
def getHoldingCard(self):
return self.__holdsCard
def setName(self, name:str) -> str:
self.__name = name
return self.__name
def setType(self,type:str) -> str:
self.__type = type
return self.__type
def setPos(self, pos:pygame.Vector2) -> pygame.Vector2:
self.pos = pos
return self.__pos
def setSize(self, size:tuple) -> tuple:
self.__size = size
return self.__size
def setColor(self, color:tuple) -> tuple:
self.__color = color
return self.__color
def setCardHolding(self, card):
self.__holdsCard = card
def getFieldID(self) -> str:
return self.__fieldID

View File

@ -0,0 +1,110 @@
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 = "Monster"
__pos:pygame.Vector2
__dragging:bool = False
__offset:pygame.Vector2 = pygame.Vector2(0,0)
__inputHandler: InputHandler
__owner:Player
__state:str
__dragable:bool = True
image:pygame.image
rect:pygame.rect
def __init__(self, pos: pygame.Vector2, assetDir: str, inputHandler: InputHandler, owner: Player, dragable:bool=True):
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.__type = "Monster"
self.__attacks = []
for attack in data.get("attacks", []):
self.__attacks.append(attack)
def update(self):
if self.__dragging:
if self.__dragable:
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 getDragable(self):
return self.__dragable
def getOffset(self):
return self.__offset
def getPos(self) -> pygame.Vector2:
return self.__pos
def getX(self) -> int:
return self.__pos.x
def getY(self) -> int:
return self.__pos.y
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

View File

@ -0,0 +1,88 @@
import json
import pygame
from Classes.System.Components.InputHandler import InputHandler
from Classes.Game.Player import Player
class MonsterCard(pygame.sprite.Sprite):
__name:str
__id:int
__description:str
__attacks = []
__type:str = "Monster"
__pos:pygame.Vector2
__dragging:bool = False
__offset:pygame.Vector2 = pygame.Vector2(0,0)
__inputHandler: InputHandler
__owner:Player
image:pygame.image
rect:pygame.rect
def __init__(self, pos:pygame.Vector2, assetDir:str, inputHandler:InputHandler, owner:Player):
if assetDir == "":
return ValueError.add_note("Card: imagePath cannot be empty")
pygame.sprite.Sprite.__init__(self)
data = json.load(open(assetDir + "/card.json"))
self.__owner = owner
self.__id = int(data["id"])
self.__pos = pos
self.__name = data["name"]
self.image = pygame.image.load(assetDir + "/card.png").convert_alpha()
self.rect = self.image.get_rect()
self.dragging = False
self.offset = pygame.Vector2(0, 0) # Offset zwischen der Karte und der Mausposition
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
for attack in data["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 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

View File

@ -0,0 +1,72 @@
import json
from typing import Any
import pygame
from Classes.System.Components.InputHandler import InputHandler
class SpellCard(pygame.sprite.Sprite):
__name:str
__description:str
__pos:pygame.Vector2
__dragging:bool = False
__offset:pygame.Vector2 = pygame.Vector2(0,0)
__inputHandler: InputHandler
__type:str = "Effect"
image:pygame.image
rect:pygame.rect
def __init__(self, pos:pygame.Vector2, assetDir:str, inputHandler:InputHandler):
if assetDir == "":
return ValueError.add_note("Card: imagePath cannot be empty")
pygame.sprite.Sprite.__init__(self)
data = json.load(open(assetDir + "/card.json"))
self.__pos = pos
self.__name = data["name"]
self.image = pygame.image.load(assetDir + "/card.png").convert_alpha()
self.rect = self.image.get_rect()
self.dragging = False
self.offset = pygame.Vector2(0, 0) # Offset zwischen der Karte und der Mausposition
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
def update(self):
if self.getDragging():
mouse_pos = self.__inputHandler.getMousePos()
self.__pos = mouse_pos
self.rect.center = self.__pos
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 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

View File

@ -0,0 +1,72 @@
import json
from typing import Any
import pygame
from Classes.System.Components.InputHandler import InputHandler
class TrapCard(pygame.sprite.Sprite):
__name:str
__description:str
__pos:pygame.Vector2
__dragging:bool = False
__offset:pygame.Vector2 = pygame.Vector2(0,0)
__inputHandler: InputHandler
__type:str = "Effect"
image:pygame.image
rect:pygame.rect
def __init__(self, pos:pygame.Vector2, assetDir:str, inputHandler:InputHandler):
if assetDir == "":
return ValueError.add_note("Card: imagePath cannot be empty")
pygame.sprite.Sprite.__init__(self)
data = json.load(open(assetDir + "/card.json"))
self.__pos = pos
self.__name = data["name"]
self.__inputHandler = inputHandler
self.__description = data["description"]
self.original_size = self.image.get_size()
self.original_position = self.rect.center
self.offset = pygame.Vector2(0, 0) # Offset zwischen der Karte und der Mausposition
self.rect = self.image.get_rect()
self.rect.center = self.__pos
self.image = pygame.image.load(assetDir + "/card.png").convert_alpha()
self.__dragging = False
def update(self):
if self.getDragging():
mouse_pos = self.__inputHandler.getMousePos()
self.__pos = mouse_pos
self.rect.center = self.__pos
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 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

View File

@ -0,0 +1,17 @@
import pygame
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
from Classes.System.Utils.Path import PathUtil
# send from the server to tell the player the game starts
# gives the client its and the opponents stats (not cards!!)
def GameStart(world: World, handCards:list, inputHandler:InputHandler, owner:Player):
index:int = 0
for card in handCards:
#world.AddToPlayerHand(Card(pygame.Vector2(500 + (index * 100), 1050), PathUtil.getAbsolutePathTo(f"Assets/Cards/{card}/"), inputHandler, Player(1000, 0, "test"), dragable=True))
world.spawnCard(PathUtil.getAbsolutePathTo(f"Assets/Cards/{card}"), pygame.Vector2(500 + (index * 100), 1050), inputHandler, world.getPlayer())
index=index+1

View File

@ -0,0 +1,25 @@
import json
import pygame
from Classes.Game.World import World
from Classes.Game.Player import Player
# event the client sends to let the server know it logged in
def Login(tcpClient):
payload = {
"event":"login",
"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]
}
tcpClient.send(payload)
# server response for login event
def LoginResponse(message:dict, world:World):
print("LoginResponse called")
# checks if the response on the login request is successfull
if message["status"] != "success":
print("login failed")
else:
print("receiving login confirmation from server")
world.setPlayer(Player(0,0,message["name"], message["id"]))

View File

@ -0,0 +1,32 @@
import pygame
from Classes.Game.World import World
from Classes.System.Components.InputHandler import InputHandler
from Classes.Game.Cards.Card import Card
from Classes.System.Utils.Path import PathUtil
# the event the client sends to the server when it places a card
def PlaceCard(tcpClient, card:Card, player):
# todo: send card information to the server
# todo: required info is:
# - position
# - field type (used for validating what field the card is played in will be compared on server side)
# - card id (server will do the rest to fetch card info)
payload = {
"event":"placecard",
"card": card.getID(),
"type": card.getType(),
"user": player.getID(),
"x": card.getX(),
"y": card.getY(),
}
tcpClient.send(payload)
# the event send from the server to display a card on the field
def CardPlaced(world:World, card:int, owner:str, pos:pygame.Vector2, inputHandler:InputHandler):
# todo: make this work with all cardtypes
print("placing enemy card")
world.spawnEnemyCard(PathUtil.getAbsolutePathTo(f"Assets/Cards/{card}"), pos, inputHandler, owner)
def MovedCard(world:World, card:int, type:str, owner:str, oldPos:pygame.Vector2, newPos:pygame.Vector2, inputHandler:InputHandler):
pass

View File

@ -0,0 +1,46 @@
import pygame
class Player:
__id:int
__hp:int
__mana:int
__name:str
__handCards:pygame.sprite.Group
def __init__(self, hp:int, mana:int, name:str, id:int=0):
self.__hp = hp
self.__mana = mana
self.__name = name
self.__id = id
def setID(self, id:int):
self.__id = id
def getID(self) -> int:
return self.__id
def getName(self) -> str:
return self.__name
def getHP(self) -> int:
return self.__hp
def getMana(self) -> int:
return self.__mana
def adjustHP(self, hp:int) -> int:
self.__hp = self.__hp + hp
def getHand(self) -> pygame.sprite.Group:
return self.__handCards
def AddToHand(self, card) -> pygame.sprite.Group:
self.__handCards.add(card)
return self.__handCards
def removeFromHand(self, pos:int) -> pygame.sprite.Group:
self.__handCards.remove(pos)
return self.__handCards
def setMana(self, mana:int):
self.__mana = mana

View File

@ -0,0 +1,145 @@
import pygame
from Classes.Game.BoardField import BoardField
from Classes.System.Components.Label import Label
from Classes.Game.Cards.MonsterCard import MonsterCard
from Classes.Game.Cards.SpellCard import SpellCard
from Classes.Game.Cards.TrapCard import TrapCard
from Classes.System.Components.InputHandler import InputHandler
from Classes.Game.Player import Player
from Classes.Game.Cards.Card import Card
from Classes.System.Utils.Path import PathUtil
class World():
__boardFields:list
player:Player
enemy:Player
__labels:list
__cards:pygame.sprite.Group()
__PlayerHandCards:pygame.sprite.Group()
screen:pygame.surface
__cardWidth:int = 150
__cardHeight:int = 200
__cardOffset:int = 400
def __init__(self, screen:pygame.surface, cardWidth:int=200, cardHeight:int=250, cardOffset:int=400):
self.__boardFields = []
self.__labels = []
self.__cards = pygame.sprite.Group()
self.__PlayerHandCards = pygame.sprite.Group()
self.__screen = screen
self.__cardWidth = cardWidth
self.__cardHeight = cardHeight
self.__cardOffset = cardOffset
self.player = None
self.enemy = None
self.buildGameWorld()
def buildGameWorld(self):
# construct elements arround the playerfield
# Todo add lifepoint label for player and enemy and make them scriptable move to player class
# presets the y position later passed down to the vector2
eRow1Height = 85
eRow2Height = (self.__cardHeight + 45)
pRow1Height = ((2 * self.__cardHeight) + 75)
pRow2Height = ((2 * self.__cardHeight) + self.__cardHeight + 30)
eDeckPos = pygame.Vector2((self.__cardOffset + ((self.__cardWidth + 10) * 0)), eRow1Height)
eGravePos = pygame.Vector2((self.__cardOffset + ((self.__cardWidth + 10) * 0)), eRow2Height)
eNamePos = pygame.Vector2(15, 45)
eHPPos = pygame.Vector2(15, 75)
pGravePos = pygame.Vector2((self.__cardOffset + (((self.__cardWidth + 10) - 30 ) * 5)), pRow1Height)
pDeckPos = pygame.Vector2((self.__cardOffset + (((self.__cardWidth + 10) - 30 ) * 5)), pRow2Height)
pNamePos = pygame.Vector2(20, pRow2Height + 195)
pHPPos = pygame.Vector2(20, pRow2Height + 225)
pManaPos = pygame.Vector2(20, pRow2Height + 255)
# labeling
<<<<<<< HEAD:Game_Client/Classes/Game/World.py
self.__labels.append(Label("PlayerHP", self.__screen, "0 / 0", pHPPos))
self.__labels.append(Label("PlayerName", self.__screen, "Not Connected", pNamePos))
self.__labels.append(Label("PlayerMana", self.__screen, "0", pManaPos))
self.__labels.append(Label("EnemyHP", self.__screen, "0 / 0", eHPPos))
=======
self.__labels.append(Label("PlayerHP", self.__screen, "1000 / 1000", pHPPos))
self.__labels.append(Label("PlayerName", self.__screen, "Not Connected", pNamePos))
self.__labels.append(Label("PlayerName", self.__screen, "0", pManaPos))
self.__labels.append(Label("EnemyHP", self.__screen, "1000 / 1000", eHPPos))
>>>>>>> 18dcd6cc42f1f23e221702147a36f650f6aae6ac:Client/Classes/Game/World.py
self.__labels.append(Label("EnemyName", self.__screen, "Not Connected", eNamePos))
self.__boardFields.append(BoardField("EnemyDeck", "Enemy", "Deck", eDeckPos, PathUtil.getAbsolutePathTo("Assets/Cards/0/field.png"), "e-deck"))
self.__boardFields.append(BoardField("EnemyGraveyard", "Enemy", "Grave", eGravePos, PathUtil.getAbsolutePathTo("Assets/Cards/0/field.png"), "e-grave"))
self.__boardFields.append(BoardField("PlayerDeck", "Player", "Deck", pDeckPos, PathUtil.getAbsolutePathTo("Assets/Cards/0/field.png"), "P-deck"))
self.__boardFields.append(BoardField("PlayerGraveyard", "Player", "Grave", pGravePos, PathUtil.getAbsolutePathTo("Assets/Cards/0/field.png"), "p-grave"))
# handle field creation
for i in range(5):
pMonsterPos = pygame.Vector2((self.__cardOffset + (((self.__cardWidth + 10) - 30) * i)), pRow1Height)
pEffectPos = pygame.Vector2((self.__cardOffset + (((self.__cardWidth + 10) - 30) * i)), pRow2Height)
eMonsterPos = pygame.Vector2((self.__cardOffset + (((self.__cardWidth + 10) - 30) * (i+1)), eRow1Height))
eEffectPos = pygame.Vector2((self.__cardOffset + (((self.__cardWidth + 10) - 30) * (i+1))), eRow2Height)
self.__boardFields.append(BoardField("PlayerMonsterField-"+str(i), "Player", "Monster", pMonsterPos, PathUtil.getAbsolutePathTo("Assets/Cards/0/field.png"), "pm"+str(id)))
self.__boardFields.append(BoardField("PlayerEffectField-"+str(i), "Player", "Effect", pEffectPos, PathUtil.getAbsolutePathTo("Assets/Cards/0/field.png"), "pe"+str(id)))
self.__boardFields.append(BoardField("EnemyMonsterField-"+str(i), "Enemy", "Monster", eMonsterPos, PathUtil.getAbsolutePathTo("Assets/Cards/0/field.png"), "em"+str(id)))
self.__boardFields.append(BoardField("EnemySpellTrapField-"+str(i), "Enemy", "Effect", eEffectPos, PathUtil.getAbsolutePathTo("Assets/Cards/0/field.png"), "ee"+str(id)))
def getBoardFields(self) -> list:
return self.__boardFields
def getLabels(self) -> list:
return self.__labels
def getCardWidth(self) -> int:
return self.__cardWidth
def getCardHeight(self) -> int:
return self.__cardHeight
def getCards(self) -> pygame.sprite.Group:
return self.__cards
def getHandCards(self) -> pygame.sprite.Group:
return self.__PlayerHandCards
def getPlayer(self) -> Player:
return self.player
def getEnemy(self) -> Player:
return self.__enemy
def setPlayer(self, player:Player):
print(f"setting player {player}")
self.player = player
for label in self.__labels:
if label.getName() == "PlayerName":
label.setText(player.getName())
def setEnemy(self, player:Player):
self.enemy = player
for label in self.__labels:
if label.getName() == "EnemyName":
label.setText(player.getName())
def spawnCard(self, asset:str, pos:pygame.Vector2, inputHandler:InputHandler, owner:Player) -> Card:
card = Card(pos, asset, inputHandler, owner)
self.__cards.add(card)
return card
def spawnEnemyCard(self, asset:str, pos:pygame.Vector2, inputHandler:InputHandler, owner:str) -> Card:
pos.y = (self.__cardHeight + 45)
card = Card(pos, asset, inputHandler, self.enemy, dragable=False)
self.__cards.add(card)
print(f"new card collection {self.__cards}")
return card
def spawnCards(self, cards:pygame.sprite.Group):
for card in cards:
self.__cards.add(card)
def AddToPlayerHand(self, Card:Card):
self.__PlayerHandCards.add(Card)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,141 @@
import pygame
from pygame.locals import *
from Classes.Game.Cards.MonsterCard import MonsterCard
from Classes.System.Components.Window import Window
from Classes.System.Components.InputHandler import InputHandler
from Classes.Game.World import World
from Classes.System.Network.TCPClient import TCPClient
from Classes.Game.Events.Login import Login
from Classes.Game.Events.PlaceCard import PlaceCard
from Classes.Game.Player import Player
from Classes.Game.Cards.Card import Card
from Classes.System.Utils.Path import PathUtil
class App:
__window:Window
__running:bool = True
__FPS = 60
__clock = pygame.time.Clock()
__myFont:pygame.font
__world:World
__inputHandler: InputHandler
__tcpClient: TCPClient
def __init__(self, width:int=1920, height:int=1080, title:str="default title"):
pygame.font.init()
self.__myFont = pygame.font.SysFont('Comic Sans MS', 30)
self.__window = Window(width=width, height=height, title=title)
self.__inputHandler = InputHandler()
self.selectedCard = None
# game word
self.__world = World(self.__window.getScreen())
try:
self.__tcpClient = TCPClient("127.0.0.1", "54322", self.__world, self.__inputHandler)
Login(self.__tcpClient) # will login to the server
except Exception as e:
print(f"failed to login due to error {e}")
print("server connection failed or got refused")
pass
self.startGameLoop()
self.onCleanup()
def startGameLoop(self):
# create sprite groups
# todo: remove these and let server handle card creation instead
# blocker: server - client communication [WIP]
# self.__world.spawnCard(PathUtil.getAbsolutePathTo("Assets/Cards/1/"), pygame.Vector2(500, 1050), self.__inputHandler, Player(1000, 0, "test"))
# self.__world.spawnCard(PathUtil.getAbsolutePathTo("Assets/Cards/1/"), pygame.Vector2(600, 1050), self.__inputHandler, Player(1000, 0, "test"))
# self.__world.spawnCard(PathUtil.getAbsolutePathTo("Assets/Cards/1/"), pygame.Vector2(700, 1050), self.__inputHandler, Player(1000, 0, "test"))
# self.__world.spawnCard(PathUtil.getAbsolutePathTo("Assets/Cards/1/"), pygame.Vector2(800, 1050), self.__inputHandler, Player(1000, 0, "test"))
# self.__world.spawnCard(PathUtil.getAbsolutePathTo("Assets/Cards/1/"), pygame.Vector2(900, 1050), self.__inputHandler, Player(1000, 0, "test"))
# self.__world.spawnCard(PathUtil.getAbsolutePathTo("Assets/Cards/1/"), pygame.Vector2(1000, 1050), self.__inputHandler, Player(1000, 0, "test"))
while self.__running:
self.__clock.tick(self.__FPS)
self.__window.getScreen().fill((0,0,0))
# render world
self.__window.drawWorld(self.__world)
# updates all cards inside the cards Spritegroup at each step the gameloops does
self.__world.getCards().update()
self.__world.getHandCards().update()
# draw groups
self.__window.drawSpriteGroup(self.__world.getCards())
self.__window.drawSpriteGroup(self.__world.getHandCards())
# event handler
self.handleEvent(pygame.event.get())
# emits update to the game
pygame.display.update()
# handles incoming event queue
def handleEvent(self, events):
# TODO: fix bug that stacks cards when dragging them around
try:
for event in events:
if event.type == pygame.QUIT:
self.onCleanup()
elif self.__inputHandler.getMousePressed()[0]:
for card in self.__world.getCards():
if card.getDragable() == True:
if card.rect.collidepoint(self.__inputHandler.getMousePos()):
#self.__logger.info(f"dragging card {card}")
self.selectedCard = card
# failsafe to prevent NoneType errors
if self.selectedCard != None:
#self.__logger.info(f"working with card: {self.selectedCard}")
self.selectedCard.setDragging(True)
elif event.type == pygame.MOUSEBUTTONUP:
print("left mousebutton")
if event.button == 1:
if self.selectedCard != None:
self.selectedCard.setDragging(False)
print(self.selectedCard)
for field in self.__world.getBoardFields():
print(f"checking field {field} is field mathinc? {field.getRect().collidepoint(self.__inputHandler.getMousePos())}")
if field.getRect().collidepoint(self.__inputHandler.getMousePos()):
print(f"is position valid? {field.getSide() == 'Player' and field.getType() == self.selectedCard.getType()} ")
print(f"side {field.getSide()} fieldtype {field.getType()} card type {self.selectedCard.getType()}")
if field.getSide() == "Player" and field.getType() == self.selectedCard.getType():
print(f"found field {field}")
try:
print(f"placing card {self.selectedCard} in field {field}")
# snap card into the correct field
self.selectedCard.rect.center = field.rect.center
self.selectedCard.setDragging(False)
print(self.selectedCard)
# TODO: adapt this into the new game engine version
PlaceCard(self.__tcpClient, self.selectedCard, self.__world.getPlayer()) # tells te server that the player placed this card
self.selectedCard = None
except Exception as e:
print(f"failed to place card on server due to error: {e}")
if self.selectedCard != None:
self.selectedCard = None
else:
raise ValueError("selected card in event handler was found empty this should never happen!")
pass
except:
pass
# sets the running state for the gameloop
def setRunning(self, running:bool):
self.__running = running
# ensures the gameloop stops running and the pygame instance is stopped properly
def onCleanup(self):
self.__running = False
pygame.quit()

View File

@ -0,0 +1,53 @@
import pygame
from Classes.Game.BoardField import BoardField
class InputHandler:
# returns pressed key
@staticmethod
def getPressed():
return pygame.key.get_pressed()
# returns pressed key
@staticmethod
def getMousePressed():
return pygame.mouse.get_pressed()
# takes in movement inputs and maps them to x and y axis
@staticmethod
def getInputAxis() -> tuple:
xvel = 0
yvel = 0
# construct x and y velocity input axis
if InputHandler.getPressed()[pygame.K_a] or InputHandler.getPressed()[pygame.K_LEFT]:
xvel = -1
if InputHandler.getPressed()[pygame.K_d] or InputHandler.getPressed()[pygame.K_RIGHT]:
xvel = 1
if InputHandler.getPressed()[pygame.K_w] or InputHandler.getPressed()[pygame.K_UP]:
yvel = -1
if InputHandler.getPressed()[pygame.K_s] or InputHandler.getPressed()[pygame.K_DOWN]:
yvel = 1
return tuple((xvel, yvel))
@staticmethod
def getMousePos() -> pygame.Vector2:
return pygame.Vector2(pygame.mouse.get_pos())
# get field under mousbutton
@staticmethod
def getMouseHover(mouse_pos: pygame.Vector2, world_card_width: int, world_card_height: int, board_fields: list) -> BoardField:
x_pos = mouse_pos.x / world_card_width
y_pos = mouse_pos.y / world_card_height
for field in board_fields:
field_x = field.getPos().x
field_y = field.getPos().y
field_width = world_card_width # Annahme: Jedes Feld hat eine Breite von 1 Einheit
field_height = world_card_height # Annahme: Jedes Feld hat eine Höhe von 1 Einheit
if field_x <= x_pos < field_x + field_width and field_y <= y_pos < field_y + field_height:
return field
return None

View File

@ -0,0 +1,47 @@
import pygame
class Label:
rect:pygame.rect
image:pygame.image
__screen:pygame.surface
__text:str
__pos:pygame.Vector2
__font:pygame.font
font:pygame.font
__name:str
def __init__(self, name:str, screen:pygame.surface, text:str, pos:pygame.Vector2, size:float=20, color:str="white"):
self.__font = pygame.font.SysFont("Arial", size)
self.font = pygame.font.SysFont("Arial", size)
self.image = self.font.render(text, 1, color)
_, _, w, h = self.image.get_rect()
self.__pos = pos
self.rect = pygame.Rect(self.__pos.x, self.__pos.y, w, h)
self.__screen = screen
self.__text = text
self.__name = name
def getText(self) -> str:
return self.__text
def getFont(self) -> pygame.font:
return self.__font
def getPos(self) -> pygame.Vector2:
return self.__pos
def getName(self) -> str:
return self.__name
def setText(self, newtext:str, color:str="white"):
self.image = self.font.render(newtext, 1, color)
def setFont(self, font:pygame.font, size:float, color:str="white"):
self.__font = pygame.font.SysFont(font, size)
self.change_text(self.text, color)
def setPos(self, pos:pygame.Vector2):
self.__pos = pos
def draw(self):
self.__screen.blit(self.image, (self.rect))

View File

@ -0,0 +1,54 @@
import pygame
from pygame.locals import *
from Classes.Game.BoardField import BoardField
from Classes.Game.World import World
class Window:
__width:int = 800
__height:int = 600 # takes 80% of width which tranlates to 640
__title:str = "python game engine"
__screen:pygame.Surface
__clock:pygame.time.Clock
def __init__(self, width:int=800, height:int=600, title:str="python game engine"):
self.__width = width
self.__height = height
self.__title = title
pygame.init()
self.__screen = pygame.display.set_mode((self.__width, self.__height))
self.__screen.fill((236, 240, 241)) # Hier liegt der Fehler, es muss eine Tuple übergeben werden
pygame.display.set_caption(self.__title)
self.__clock = pygame.time.Clock()
self.__framerate = 60 # Framerate auf 60 FPS festlegen
# set framerate (where the fuck is it?)
def Render(self):
# dear future me figure out what past me did!
pass
def setWidth(self, width:int):
self.__width = width
def setHeight(self, height:int):
self.__height = height
def setTitle(self, title:str):
self.__title = title
def getScreen(self) -> pygame.surface:
return self.__screen
# draws a passed sprite group to the screen
def drawSpriteGroup(self, group:pygame.sprite.Group):
group.draw(self.__screen)
# draws a given group of rectangles onto the screen
def drawWorld(self, world:World):
for field in world.getBoardFields():
pygame.draw.rect(self.__screen, field.getColor(), field.getRect())
for label in world.getLabels():
label.draw()

View File

@ -0,0 +1,23 @@
from Classes.Game.Player import Player
from Classes.Game.World import World
class GameManager:
player:Player
enemy:Player
world:World
def __init__(self, world):
self.world = world
def getPlayer(self) -> Player:
return self.player
def getEnemy(self) -> Player:
return self.enemy
def setPlayer(self, player:Player):
self.player = player
def setEnemy(self, enemy:Player):
self.enemy = enemy

View File

@ -0,0 +1,58 @@
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
from Classes.Game.Events.Login import LoginResponse
class TCPEventHandler:
def __init__(self, socket:socket):
self.tcp_socket = socket
<<<<<<< HEAD:Game_Client/Classes/System/Network/EventHandler.py
def handleEvents(self, message:dict, inputHandler:InputHandler, world:World):
if message["event"] == "loginresponse":
# todo: handle login response here
=======
def handleEvents(self, message, inputHandler:InputHandler, world:World):
print(message)
if message["event"] == "loginresponse":
>>>>>>> 18dcd6cc42f1f23e221702147a36f650f6aae6ac:Client/Classes/System/Network/EventHandler.py
LoginResponse(message, world)
pass
elif message["event"] == "startgame":
print(world.player)
# world.player.setMana(message["player"]["mana"])
# world.player.setHp(message["player"]["hp"])
GameStart(world, message["player"]["hand"], inputHandler, world.getPlayer(), Player(message["enemy"]["hp"],0,message["enemy"]["name"], message["enemy"]["id"]))
pass
elif message["event"] == "placecard":
CardPlaced(world, message["card"], message["type"], message["owner"], pygame.Vector2(int(message["x"]), int(message["y"]), inputHandler))
pass
elif message["event"] == "MoveCard":
<<<<<<< HEAD:Game_Client/Classes/System/Network/EventHandler.py
# 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, world)
=======
>>>>>>> 18dcd6cc42f1f23e221702147a36f650f6aae6ac:Client/Classes/System/Network/EventHandler.py
pass
elif message["event"] == "RemoveCard":
pass
elif message["event"] == "AttackCard":
pass
elif message["event"] == "AttackPlayer":
pass
elif message["event"] == "ActivateEffectCard":
pass
elif message["event"] == "ActivateMonsterCard":
pass

View File

@ -0,0 +1,69 @@
import json
import socket
import threading
import pygame
from Classes.Game.World import World
from Classes.System.Components.InputHandler import InputHandler
from Classes.Game.Events.GameStart import GameStart
from Classes.Game.Events.Login import LoginResponse
from Classes.Game.Events.PlaceCard import CardPlaced
from Classes.Game.Player import Player
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.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.handleEvents(decoded_data)
except Exception as e:
print(f"Error receiving TCP data: {e}")
break
def handleEvents(self, message):
print(message)
if message["event"] == "loginresponse":
if message["status"] != "success":
print("login failed")
else:
print("receiving login confirmation from server")
self.world.setPlayer(Player(0,0,message["name"], message["id"]))
elif message["event"] == "startgame":
print(self.world.player)
# world.player.setMana(message["player"]["mana"])
# world.player.setHp(message["player"]["hp"])
self.world.setEnemy(Player(message["enemy"]["hp"],0,message["enemy"]["name"], message["enemy"]["id"]))
GameStart(self.world, message["player"]["hand"], self.inputHandler, self.world.getPlayer())
pass
elif message["event"] == "PlacedCard":
CardPlaced(self.world, message["card"], message["owner"], pygame.Vector2(message["x"], message["y"]), self.inputHandler)
pass
def listen(self):
tcpThread = threading.Thread(target=self.receive)
tcpThread.daemon = True
tcpThread.start()

View File

@ -0,0 +1,6 @@
import os
class PathUtil:
def getAbsolutePathTo(notAbsolutPath:str) -> str:
return os.path.abspath("Client/" + notAbsolutPath)

View File

@ -0,0 +1,11 @@
import random
import string
class StringUtils:
def get_random_string(length) -> str:
# choose from all lowercase letter
letters = string.ascii_lowercase
result_str = ''.join(random.choice(letters) for i in range(length))
print("Random string of length", length, "is:", result_str)
return result_str

Binary file not shown.

Binary file not shown.