Skip to content

Commit 6db8fca

Browse files
committed
Merge branch 'feature/gioco-4-lezione'
2 parents 5948767 + a215b81 commit 6db8fca

File tree

4 files changed

+291
-53
lines changed

4 files changed

+291
-53
lines changed

game11/harry_potter.py

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
import random
2+
import polars as pl
3+
import pgzrun
4+
from types import SimpleNamespace
5+
6+
WIDTH = 800
7+
HEIGHT = 600
8+
TITLE = "Wizarding Duel: The Final Battle"
9+
10+
# --- State ---
11+
hp = {"Harry": 100, "Voldemort": 100}
12+
display = SimpleNamespace(Harry=100, Voldemort=100)
13+
14+
# Sprites (Ensure harry.png and voldemort.png are in the 'images' folder)
15+
harry_sprite = Actor('harry', (200, 320))
16+
voldy_sprite = Actor('voldemort', (600, 150))
17+
18+
message = "A wild VOLDEMORT appeared!"
19+
sub_message = "What will HARRY do?"
20+
waiting_for_input = True
21+
game_active = True
22+
23+
# --- Load Data ---
24+
spells_df = pl.read_csv(r"C:\Users\alema\Desktop\pythonbiella\LearningPythonWithGames\game11\spells.csv")
25+
26+
def get_options(character):
27+
return spells_df.filter(pl.col("character") == character)
28+
29+
# --- Visual Effects ---
30+
31+
def flash_hurt(sprite):
32+
"""Blinks the sprite and shakes it slightly."""
33+
original_x = sprite.x
34+
# Quick shake
35+
animate(sprite, duration=0.1, x=original_x + 10, tween='bounce_end')
36+
# Blink
37+
for i in range(3):
38+
clock.schedule_unique(lambda: setattr(sprite, 'opacity', 0), i * 0.2)
39+
clock.schedule_unique(lambda: setattr(sprite, 'opacity', 255), i * 0.2 + 0.1)
40+
# Reset position
41+
clock.schedule_unique(lambda: setattr(sprite, 'x', original_x), 0.3)
42+
43+
# --- Logic Core ---
44+
45+
def execute_move(attacker_name, defender_name, spell_df, spell_index):
46+
global message, sub_message, game_active
47+
48+
dmg = float(spell_df[spell_index, "damage"])
49+
precision = float(spell_df[spell_index, "precision"])
50+
message = f"{attacker_name.upper()} used {spell_df[spell_index, 'spell'].upper()}!"
51+
a = random.random()
52+
spell_successful = a < precision
53+
print(a, precision)
54+
if spell_successful:
55+
if dmg < 0: # Healing
56+
amt = abs(dmg)
57+
hp[attacker_name] = min(100, hp[attacker_name] + amt)
58+
sub_message = f"It recovered {amt} HP!"
59+
animate(display, duration=0.6, **{attacker_name: hp[attacker_name]})
60+
else: # Attacking
61+
hp[defender_name] = max(0, hp[defender_name] - dmg)
62+
sub_message = f"It dealt {dmg} damage!"
63+
# Visual hurt effect
64+
target_sprite = voldy_sprite if defender_name == "Voldemort" else harry_sprite
65+
flash_hurt(target_sprite)
66+
animate(display, duration=0.6, **{defender_name: hp[defender_name]})
67+
else:
68+
sub_message = f"The spell did not work!"
69+
70+
if hp[defender_name] <= 0:
71+
game_active = False
72+
message = f"{defender_name.upper()} fainted!"
73+
sub_message = "The duel is over."
74+
75+
# --- Turn Handlers ---
76+
77+
def voldemort_phase():
78+
"""Voldemort picks a random spell and casts it."""
79+
global message, sub_message
80+
if not game_active: return
81+
82+
options = get_options("Voldemort")
83+
spell_index = random.randint(1, len(options)) - 1
84+
execute_move("Voldemort", "Harry", options, spell_index)
85+
86+
# After Voldemort moves, wait 2 seconds then let Harry play
87+
if game_active:
88+
clock.schedule_unique(ready_harry, 2.0)
89+
90+
def ready_harry():
91+
"""Resets the UI so Harry can choose a spell."""
92+
global message, sub_message, waiting_for_input
93+
message = "What will HARRY do?"
94+
sub_message = "Select a spell..."
95+
waiting_for_input = True
96+
97+
def on_mouse_down(pos):
98+
global waiting_for_input
99+
100+
if game_active and waiting_for_input:
101+
options = get_options("Harry")[:4]
102+
for i in range(len(options)):
103+
x = 40 + (i % 2) * 380
104+
y = 440 + (i // 2) * 60
105+
if Rect((x, y), (350, 50)).collidepoint(pos):
106+
# Harry's action
107+
waiting_for_input = False
108+
execute_move("Harry", "Voldemort", options, i)
109+
110+
# If Voldemort is still alive, he takes his turn in 2 seconds
111+
if game_active:
112+
clock.schedule_unique(voldemort_phase, 2.0)
113+
114+
# --- Draw Functions ---
115+
116+
def draw():
117+
screen.clear()
118+
screen.draw.filled_rect(Rect((0, 0), (800, 400)), (200, 230, 255))
119+
screen.draw.filled_rect(Rect((0, 400), (800, 200)), (120, 180, 120))
120+
121+
voldy_sprite.draw()
122+
harry_sprite.draw()
123+
124+
draw_status_box("VOLDEMORT", display.Voldemort, 50, 50)
125+
draw_status_box("HARRY", display.Harry, 450, 250)
126+
127+
# Dialogue Box
128+
screen.draw.filled_rect(Rect((10, 410), (780, 180)), (50, 50, 60))
129+
screen.draw.rect(Rect((10, 410), (780, 180)), "white")
130+
131+
if waiting_for_input and game_active:
132+
draw_move_menu()
133+
else:
134+
screen.draw.text(message, (40, 450), fontsize=40, color="white")
135+
screen.draw.text(sub_message, (40, 510), fontsize=30, color="lightgray")
136+
137+
def draw_status_box(name, val, x, y):
138+
screen.draw.filled_rect(Rect((x, y), (300, 80)), "white")
139+
screen.draw.rect(Rect((x, y), (300, 80)), "black")
140+
screen.draw.text(name, (x+20, y+15), color="black", fontsize=30)
141+
screen.draw.rect(Rect((x+100, y+45), (160, 15)), "black")
142+
bw = (val / 100) * 158
143+
c = "green" if val > 50 else "orange" if val > 20 else "red"
144+
if bw > 0: screen.draw.filled_rect(Rect((x+101, y+46), (bw, 13)), c)
145+
146+
def draw_move_menu():
147+
opts = get_options("Harry")[:4]
148+
for i in range(len(opts)):
149+
x, y = 40 + (i%2)*380, 440 + (i//2)*60
150+
screen.draw.rect(Rect((x, y), (350, 50)), "white")
151+
screen.draw.text(f"> {opts[i, 'spell'].upper()}", (x+20, y+15), fontsize=30)
152+
153+
pgzrun.go()

game11/spells.csv

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
character,spell,damage,precision
2+
Harry,Expelliarmus,10,1
3+
Harry,Stupefy,15,1
4+
Harry,Expecto Patronum,20,1
5+
Harry, Epsikey, -25,1
6+
Voldemort,Crucio,15,0.7
7+
Voldemort,Imperio,20,0.6
8+
Voldemort,Avada Kedavra,40,0.3

0 commit comments

Comments
 (0)