Compare commits

..

5 Commits

13 changed files with 1068 additions and 82 deletions

28
.gitignore vendored
View File

@@ -1,3 +1,31 @@
# Godot 4+ specific ignores
.godot/
/android/
.temp
.nomedia
.TMP
*~libgit*
exported_binarys
# Godot-specific ignores
.import/
export.cfg
export_credentials.cfg
export_presets.cfg
# Imported translations (automatically generated from CSV files)
*.translation
# Mono-specific ignores
.mono/
data_*/
mono_crash.*.json
mono_crash.*.json
# Blender temp files
*.blend[1-9]*
*.blend~
# Draw.IO temp files
*.bkp

View File

@@ -14,3 +14,7 @@ config/name="dujorak"
run/main_scene="res://src/scenes/game.tscn"
config/features=PackedStringArray("4.4", "Forward Plus")
config/icon="res://icon.svg"
[autoload]
Globals="*res://src/scripts/globals.gd"

BIN
src/assets/card2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

BIN
src/assets/card2_bump.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

916
src/assets/card_atlas.pdn Normal file

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 378 KiB

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dpahjbok4tj31"
path="res://.godot/imported/card_atlas_sprites.png-999525584d336e8b1ecafef7f7df1d0a.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://src/assets/card_atlas_sprites.png"
dest_files=["res://.godot/imported/card_atlas_sprites.png-999525584d336e8b1ecafef7f7df1d0a.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

BIN
src/assets/cards.blend Normal file

Binary file not shown.

3
src/scenes/card.tscn Normal file
View File

@@ -0,0 +1,3 @@
[gd_scene format=3 uid="uid://kah10l7jtv2p"]
[node name="Card" type="Node3D"]

View File

@@ -1,17 +1,11 @@
extends Node2D
enum Suits {HEARTS, DIAMONDS, CLUBS, SPADES}
enum Values {SIX = 6, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING, ACE}
enum GameState {SETUP, ATTACK, DEFEND, DRAW_PHASE, GAME_OVER}
enum JokerType {DOUBLE_ATTACK, TRUMP_CHANGE, DRAW_BLOCK}
class Player:
var hand: Array = []
var jokers_hand: Array = []
var coins: int = 100
var is_attacker: bool = false
func add_joker_to_hand(joker_type: JokerType):
func add_joker_to_hand(joker_type: Globals.JokerType):
jokers_hand.append(joker_type)
func has_jokers_in_hand() -> bool:
@@ -28,19 +22,19 @@ class Player:
# Game Variables
var deck: Array = []
var trump_suit: Suits
var trump_suit: Globals.Suits
var player1: Player
var player2: Player
var current_attacker: Player
var current_defender: Player
var game_phase: GameState = GameState.SETUP
var game_phase: Globals.GameState = Globals.GameState.SETUP
var active_jokers: Array = []
var MAX_JOKERS: int = 3
# Battle Variables
var attacking_cards: Array = []
var defending_cards: Array = []
var table_pairs: Array = [] # [{attack: card, defend: card}]
var table_pairs: Array = [] # [{attack: card, defend: card}]
var can_add_attack: bool = false
# UI Reference
@@ -68,14 +62,14 @@ func start_new_game():
shuffle_deck()
deal_cards()
set_trump()
game_phase = GameState.ATTACK
game_phase = Globals.GameState.ATTACK
update_ui()
print("Spiel gestartet! ", current_attacker, " greift an")
func create_deck():
deck.clear()
for suit in [Suits.HEARTS, Suits.DIAMONDS, Suits.CLUBS, Suits.SPADES]:
for value in [Values.SIX, Values.SEVEN, Values.EIGHT, Values.NINE, Values.TEN, Values.JACK, Values.QUEEN, Values.KING, Values.ACE]:
for suit in [Globals.Suits.HEARTS, Globals.Suits.DIAMONDS, Globals.Suits.CLUBS, Globals.Suits.SPADES]:
for value in [Globals.Values.SIX, Globals.Values.SEVEN, Globals.Values.EIGHT, Globals.Values.NINE, Globals.Values.TEN, Globals.Values.JACK, Globals.Values.QUEEN, Globals.Values.KING, Globals.Values.ACE]:
deck.append({"suit": suit, "value": value, "is_joker": false})
func setup_initial_jokers():
@@ -109,9 +103,9 @@ func set_trump():
# MAIN GAME LOGIC
func _on_card_played(card):
match game_phase:
GameState.ATTACK:
Globals.GameState.ATTACK:
handle_attack(card)
GameState.DEFEND:
Globals.GameState.DEFEND:
handle_defense(card)
func handle_attack(card):
@@ -127,7 +121,7 @@ func handle_attack(card):
print("Angriff mit: ", card)
# Wechsel zu Verteidigung
game_phase = GameState.DEFEND
game_phase = Globals.GameState.DEFEND
update_ui()
func handle_defense(card):
@@ -135,7 +129,7 @@ func handle_defense(card):
print("Nichts zu verteidigen!")
return
var attack_card = attacking_cards[-1] # Letzte Angriffskarte
var attack_card = attacking_cards[-1] # Letzte Angriffskarte
if can_beat_card(attack_card, card):
# Erfolgreiche Verteidigung
@@ -160,14 +154,14 @@ func can_attack_with_card(card) -> bool:
return true
# Weitere Angriffe: Nur Werte die schon auf dem Tisch liegen
var table_values = []
var table_Globals = []
for pair in table_pairs:
table_values.append(pair.attack.value)
table_values.append(pair.defend.value)
table_Globals.Values.append(pair.attack.value)
table_Globals.Values.append(pair.defend.value)
for attack in attacking_cards:
table_values.append(attack.value)
table_Globals.Values.append(attack.value)
return card.value in table_values
return card.value in table_Globals.Values
func can_beat_card(attacking_card, defending_card) -> bool:
# Trump schlägt alles außer höheren Trump
@@ -185,7 +179,7 @@ func check_round_end():
if attacking_cards.size() == 0:
if can_add_attack and current_attacker.hand.size() > 0:
# Angreifer kann weitere Karten spielen
game_phase = GameState.ATTACK
game_phase = Globals.GameState.ATTACK
print("Weitere Angriffe möglich")
else:
# Runde erfolgreich verteidigt
@@ -241,7 +235,7 @@ func swap_roles():
print("Rollen getauscht: ", current_attacker, " greift an")
func draw_phase():
game_phase = GameState.DRAW_PHASE
game_phase = Globals.GameState.DRAW_PHASE
# Angreifer zieht zuerst auf 6 Karten
draw_cards_to_six(current_attacker)
@@ -254,7 +248,7 @@ func draw_phase():
return
# Nächste Runde starten
game_phase = GameState.ATTACK
game_phase = Globals.GameState.ATTACK
update_ui()
func draw_cards_to_six(player: Player):
@@ -267,23 +261,23 @@ func draw_cards_to_six(player: Player):
else:
player.hand.append(card)
func show_joker_dialog(player: Player, joker_type: JokerType):
if player == player1: # Nur für menschlichen Spieler
func show_joker_dialog(player: Player, joker_type: Globals.JokerType):
if player == player1: # Nur für menschlichen Spieler
ui.show_joker_choice(joker_type)
func _on_joker_choice(play_immediately: bool, joker_type: JokerType):
func _on_joker_choice(play_immediately: bool, joker_type: Globals.JokerType):
if play_immediately:
play_joker_to_field(player1, joker_type)
# Sonst bleibt Joker auf der Hand (Risiko!)
# UI Event Handlers
func _on_defend_complete():
if game_phase == GameState.DEFEND:
if game_phase == Globals.GameState.DEFEND:
# Verteidiger gibt auf, nimmt alle Karten
end_round_taken()
func _on_take_cards():
if game_phase == GameState.DEFEND:
if game_phase == Globals.GameState.DEFEND:
end_round_taken()
func _on_joker_played(joker_type):
@@ -306,27 +300,27 @@ func check_game_end() -> bool:
if player1.hand.size() == 0:
if player1.has_jokers_in_hand():
print("Spieler 1 verliert - Joker auf der Hand!")
game_phase = GameState.GAME_OVER
game_phase = Globals.GameState.GAME_OVER
return true
else:
print("Spieler 1 gewinnt!")
game_phase = GameState.GAME_OVER
game_phase = Globals.GameState.GAME_OVER
return true
if player2.hand.size() == 0:
if player2.has_jokers_in_hand():
print("Spieler 2 verliert - Joker auf der Hand!")
game_phase = GameState.GAME_OVER
game_phase = Globals.GameState.GAME_OVER
return true
else:
print("Spieler 2 gewinnt!")
game_phase = GameState.GAME_OVER
game_phase = Globals.GameState.GAME_OVER
return true
return false
# Joker System
func play_joker_to_field(player: Player, joker_type: JokerType) -> bool:
func play_joker_to_field(player: Player, joker_type: Globals.JokerType) -> bool:
if active_jokers.size() >= MAX_JOKERS:
print("Maximale Joker-Anzahl erreicht!")
return false
@@ -339,15 +333,15 @@ func play_joker_to_field(player: Player, joker_type: JokerType) -> bool:
return true
return false
func apply_joker_effect(joker_type: JokerType):
func apply_joker_effect(joker_type: Globals.JokerType):
match joker_type:
JokerType.TRUMP_CHANGE:
Globals.JokerType.TRUMP_CHANGE:
print("Trump-Wechsel verfügbar!")
# UI für Trump-Auswahl
JokerType.DOUBLE_ATTACK:
Globals.JokerType.DOUBLE_ATTACK:
print("Doppel-Angriff möglich!")
# Ermöglicht 2 Karten gleichzeitig
JokerType.DRAW_BLOCK:
Globals.JokerType.DRAW_BLOCK:
print("Zieh-Block aktiv!")
# Gegner kann nicht ziehen
@@ -358,7 +352,7 @@ func buy_booster(player: Player, cost: int = 50) -> Array:
for i in range(3):
if randf() < 0.3:
var joker_types = [JokerType.DOUBLE_ATTACK, JokerType.TRUMP_CHANGE, JokerType.DRAW_BLOCK]
var joker_types = [Globals.JokerType.DOUBLE_ATTACK, Globals.JokerType.TRUMP_CHANGE, Globals.JokerType.DRAW_BLOCK]
var random_joker = joker_types[randi() % joker_types.size()]
booster_content.append({"type": "joker", "joker_type": random_joker})
else:
@@ -376,7 +370,7 @@ func update_ui():
ui.update_table(table_pairs, attacking_cards)
ui.update_game_state(game_phase, current_attacker == player1)
if deck.size() > 0:
if deck.is_empty():
ui.update_trump(deck[0])
# Input for testing
@@ -385,5 +379,5 @@ func _input(event):
_on_booster_bought()
if event.is_action_pressed("ui_cancel"):
if game_phase == GameState.DEFEND:
if game_phase == Globals.GameState.DEFEND:
_on_take_cards()

6
src/scripts/globals.gd Normal file
View File

@@ -0,0 +1,6 @@
extends Node
enum Suits {HEARTS, DIAMONDS, CLUBS, SPADES}
enum Values {SIX = 6, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING, ACE}
enum GameState {SETUP, ATTACK, DEFEND, DRAW_PHASE, GAME_OVER}
enum JokerType {DOUBLE_ATTACK, TRUMP_CHANGE, DRAW_BLOCK}

View File

@@ -0,0 +1 @@
uid://cp7yt3d324xiv