4 Commits

Author SHA1 Message Date
Johannes Schmelz
159927e52c now able to add all nessecary models 2024-12-08 02:16:40 +01:00
Johannes Schmelz
8614faf940 show popups 2024-12-07 22:11:31 +01:00
Johannes Schmelz
4ba43602fa player now moves without animation 2024-12-07 21:58:26 +01:00
Johannes Schmelz
b4e2beca3a frist working version, TODO: trigger the render events 2024-12-07 01:13:17 +01:00
116 changed files with 2065 additions and 3056 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 518 KiB

View File

@@ -1,152 +0,0 @@
# Blender 4.2.2 LTS MTL File: 'Hotel.V.1.2.blend'
# www.blender.org
newmtl Material
Ns 250.000000
Ka 1.000000 1.000000 1.000000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.500000
d 1.000000
illum 2
map_Kd -o 0 0.6 0 -s 3.8 4 0 Hotel_texture2.png
newmtl Material.002
Ns 250.000000
Ka 1.000000 1.000000 1.000000
Kd 0.799099 0.004025 0.021219
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.500000
d 1.000000
illum 2
newmtl Material.008
Ns 250.000000
Ka 1.000000 1.000000 1.000000
Kd 0.215859 0.215861 0.215861
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.500000
d 1.000000
illum 2
newmtl Material.010
Ns 250.000000
Ka 1.000000 1.000000 1.000000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.500000
d 1.000000
illum 2
map_Kd -o 0 0 -15 -s 4.28 4 0 Hotel_texture3.jpeg
newmtl Material.011
Ns 250.000000
Ka 1.000000 1.000000 1.000000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.500000
d 1.000000
illum 2
map_Kd -o 0 0.6 0 -s 3.8 4 0 Hotel_texture2.png
newmtl Material.012
Ns 250.000000
Ka 1.000000 1.000000 1.000000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.500000
d 1.000000
illum 2
map_Kd -o 0 0 -15 -s 4.28 4 0 Hotel_texture3.jpeg
newmtl Material.013
Ns 250.000000
Ka 1.000000 1.000000 1.000000
Kd 0.799099 0.004025 0.021219
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.500000
d 1.000000
illum 2
newmtl Material.014
Ns 250.000000
Ka 1.000000 1.000000 1.000000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.500000
d 1.000000
illum 2
map_Kd -o 0 0.6 0 -s 3.8 4 0 Hotel_texture2.png
newmtl Material.015
Ns 250.000000
Ka 1.000000 1.000000 1.000000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.500000
d 1.000000
illum 2
map_Kd -o 0 0 -15 -s 4.28 4 0 Hotel_texture3.jpeg
newmtl Material.016
Ns 250.000000
Ka 1.000000 1.000000 1.000000
Kd 0.799099 0.004025 0.021219
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.500000
d 1.000000
illum 2
newmtl Material.019
Ns 250.000000
Ka 1.000000 1.000000 1.000000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.500000
d 1.000000
illum 2
map_Kd -o 0 0.6 0 -s 4.15 3.9 0 Hotel_texture1.jpeg
newmtl Material.022
Ns 250.000000
Ka 1.000000 1.000000 1.000000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.500000
d 1.000000
illum 2
map_Kd -o 0 0.6 0 -s 4.15 3.8 0 Hotel_texture1.jpeg
newmtl Material.023
Ns 250.000000
Ka 1.000000 1.000000 1.000000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.500000
d 1.000000
illum 2
map_Kd -o 0 0.6 0 -s 4.15 3.8 0 Hotel_texture1.jpeg
newmtl Material.024
Ns 250.000000
Ka 1.000000 1.000000 1.000000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.500000
d 1.000000
illum 2
map_Kd -o 0 0.6 0 -s 4.15 3.9 0 Hotel_texture1.jpeg
newmtl Material.025
Ns 250.000000
Ka 1.000000 1.000000 1.000000
Kd 0.215859 0.215861 0.215861
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.500000
d 1.000000
illum 2

View File

@@ -1,558 +0,0 @@
# Blender 4.2.2 LTS
# www.blender.org
mtllib Hotel.V.1.2.mtl
o Korridor
v 1.832325 0.743096 0.449194
v 1.832325 0.295686 0.449194
v 0.271347 0.743096 0.429009
v 0.271347 0.295686 0.429009
v 1.837850 0.743096 0.022004
v 1.837850 0.295686 0.022004
v 0.276871 0.743096 0.001818
v 0.276871 0.295686 0.001818
vn -0.0129 -0.0000 0.9999
vn -0.9999 -0.0000 -0.0129
vn 0.0129 -0.0000 -0.9999
vn 0.9999 -0.0000 0.0129
vn -0.0000 1.0000 -0.0000
vn -0.0000 -1.0000 -0.0000
vt 0.375000 0.000000
vt 0.625000 0.000000
vt 0.625000 0.250000
vt 0.375000 0.250000
vt 0.625000 0.500000
vt 0.375000 0.500000
vt 0.625000 0.750000
vt 0.375000 0.750000
vt 0.625000 1.000000
vt 0.375000 1.000000
vt 0.125000 0.500000
vt 0.125000 0.750000
vt 0.875000 0.500000
vt 0.875000 0.750000
s 0
usemtl Material.008
f 1/1/1 3/4/1 4/3/1 2/2/1
f 3/4/2 7/6/2 8/5/2 4/3/2
f 7/6/3 5/8/3 6/7/3 8/5/3
f 5/8/4 1/10/4 2/9/4 6/7/4
f 3/11/5 1/12/5 5/8/5 7/6/5
f 8/5/6 6/7/6 2/14/6 4/13/6
o Dach300.002
v 2.503119 1.817345 1.102498
v 2.142795 1.919807 1.102498
v 2.503119 1.817345 -0.809905
v 2.142795 1.919807 -0.809905
v 1.831221 1.817345 1.102498
v 2.138520 1.919807 1.102498
v 1.831221 1.817345 -0.809905
v 2.138520 1.919807 -0.809905
vn 0.2735 0.9619 -0.0000
vn -0.0000 -0.0000 -1.0000
vn -0.3163 0.9487 -0.0000
vn -0.0000 -0.0000 1.0000
vn -0.0000 -1.0000 -0.0000
vn -0.0000 1.0000 -0.0000
vt 0.375000 0.000000
vt 0.625000 0.000000
vt 0.625000 0.250000
vt 0.375000 0.250000
vt 0.625000 0.500000
vt 0.375000 0.500000
vt 0.625000 0.750000
vt 0.375000 0.750000
vt 0.625000 1.000000
vt 0.375000 1.000000
vt 0.125000 0.500000
vt 0.125000 0.750000
vt 0.875000 0.500000
vt 0.875000 0.750000
s 0
usemtl Material.002
f 9/15/7 11/18/7 12/17/7 10/16/7
f 11/18/8 15/20/8 16/19/8 12/17/8
f 15/20/9 13/22/9 14/21/9 16/19/9
f 13/22/10 9/24/10 10/23/10 14/21/10
f 11/25/11 9/26/11 13/22/11 15/20/11
f 16/19/12 14/21/12 10/28/12 12/27/12
o neu1
v 1.833977 0.294749 1.094962
v 1.833977 1.817107 1.094962
v 1.833977 0.294749 -0.825603
v 1.833977 1.817107 -0.825603
v 2.517500 0.294749 1.094962
v 2.517500 1.817107 1.094962
v 2.517500 0.294749 -0.825603
v 2.517500 1.817107 -0.825603
vn -1.0000 -0.0000 -0.0000
vn -0.0000 -0.0000 -1.0000
vn 1.0000 -0.0000 -0.0000
vn -0.0000 -0.0000 1.0000
vn -0.0000 -1.0000 -0.0000
vn -0.0000 1.0000 -0.0000
vt 0.375000 0.000000
vt 0.625000 0.000000
vt 0.625000 0.250000
vt 0.375000 0.250000
vt 0.625000 0.500000
vt 0.375000 0.500000
vt 0.625000 0.750000
vt 0.375000 0.750000
vt 0.625000 1.000000
vt 0.375000 1.000000
vt 0.125000 0.500000
vt 0.125000 0.750000
vt 0.875000 0.500000
vt 0.875000 0.750000
s 0
usemtl Material
f 17/29/13 18/30/13 20/31/13 19/32/13
f 19/32/14 20/31/14 24/33/14 23/34/14
f 23/34/15 24/33/15 22/35/15 21/36/15
f 21/36/16 22/35/16 18/37/16 17/38/16
f 19/39/17 23/34/17 21/36/17 17/40/17
f 24/33/18 20/41/18 18/42/18 22/35/18
o Frontfassade
v 1.837487 0.305766 1.101834
v 1.837487 1.807752 1.101834
v 1.837487 0.305766 1.092930
v 1.837487 1.807752 1.092930
v 2.509542 0.305766 1.101834
v 2.509542 1.807752 1.101834
v 2.509542 0.305766 1.092930
v 2.509542 1.807752 1.092930
vn -1.0000 -0.0000 -0.0000
vn -0.0000 -0.0000 -1.0000
vn 1.0000 -0.0000 -0.0000
vn -0.0000 -0.0000 1.0000
vn -0.0000 -1.0000 -0.0000
vn -0.0000 1.0000 -0.0000
vt 0.375000 0.000000
vt 0.625000 0.000000
vt 0.625000 0.250000
vt 0.375000 0.250000
vt 0.625000 0.500000
vt 0.375000 0.500000
vt 0.625000 0.750000
vt 0.375000 0.750000
vt 0.625000 1.000000
vt 0.375000 1.000000
vt 0.125000 0.500000
vt 0.125000 0.750000
vt 0.875000 0.500000
vt 0.875000 0.750000
s 0
usemtl Material.010
f 25/43/19 26/44/19 28/45/19 27/46/19
f 27/46/20 28/45/20 32/47/20 31/48/20
f 31/48/21 32/47/21 30/49/21 29/50/21
f 29/50/22 30/49/22 26/51/22 25/52/22
f 27/53/23 31/48/23 29/50/23 25/54/23
f 32/47/24 28/55/24 26/56/24 30/49/24
o neu1.001
v -2.645782 0.310702 1.102233
v -2.645782 1.833060 1.102233
v -2.645782 0.310702 -0.818333
v -2.645782 1.833060 -0.818333
v -1.962258 0.310702 1.102233
v -1.962258 1.833060 1.102233
v -1.962258 0.310702 -0.818333
v -1.962258 1.833060 -0.818333
vn -1.0000 -0.0000 -0.0000
vn -0.0000 -0.0000 -1.0000
vn 1.0000 -0.0000 -0.0000
vn -0.0000 -0.0000 1.0000
vn -0.0000 -1.0000 -0.0000
vn -0.0000 1.0000 -0.0000
vt 0.375000 0.000000
vt 0.625000 0.000000
vt 0.625000 0.250000
vt 0.375000 0.250000
vt 0.625000 0.500000
vt 0.375000 0.500000
vt 0.625000 0.750000
vt 0.375000 0.750000
vt 0.625000 1.000000
vt 0.375000 1.000000
vt 0.125000 0.500000
vt 0.125000 0.750000
vt 0.875000 0.500000
vt 0.875000 0.750000
s 0
usemtl Material.011
f 33/57/25 34/58/25 36/59/25 35/60/25
f 35/60/26 36/59/26 40/61/26 39/62/26
f 39/62/27 40/61/27 38/63/27 37/64/27
f 37/64/28 38/63/28 34/65/28 33/66/28
f 35/67/29 39/62/29 37/64/29 33/68/29
f 40/61/30 36/69/30 34/70/30 38/63/30
o Frontfassade.001
v -2.642272 0.321718 1.109104
v -2.642272 1.823704 1.109104
v -2.642272 0.321718 1.100200
v -2.642272 1.823704 1.100200
v -1.970217 0.321718 1.109104
v -1.970217 1.823704 1.109104
v -1.970217 0.321718 1.100200
v -1.970217 1.823704 1.100200
vn -1.0000 -0.0000 -0.0000
vn -0.0000 -0.0000 -1.0000
vn 1.0000 -0.0000 -0.0000
vn -0.0000 -0.0000 1.0000
vn -0.0000 -1.0000 -0.0000
vn -0.0000 1.0000 -0.0000
vt 0.375000 0.000000
vt 0.625000 0.000000
vt 0.625000 0.250000
vt 0.375000 0.250000
vt 0.625000 0.500000
vt 0.375000 0.500000
vt 0.625000 0.750000
vt 0.375000 0.750000
vt 0.625000 1.000000
vt 0.375000 1.000000
vt 0.125000 0.500000
vt 0.125000 0.750000
vt 0.875000 0.500000
vt 0.875000 0.750000
s 0
usemtl Material.012
f 41/71/31 42/72/31 44/73/31 43/74/31
f 43/74/32 44/73/32 48/75/32 47/76/32
f 47/76/33 48/75/33 46/77/33 45/78/33
f 45/78/34 46/77/34 42/79/34 41/80/34
f 43/81/35 47/76/35 45/78/35 41/82/35
f 48/75/36 44/83/36 42/84/36 46/77/36
o Dach300.001
v -1.976640 1.833298 1.092314
v -2.336963 1.935760 1.092314
v -1.976640 1.833298 -0.785180
v -2.336963 1.935760 -0.785180
v -2.648537 1.833298 1.092314
v -2.341239 1.935760 1.092314
v -2.648537 1.833298 -0.785180
v -2.341239 1.935760 -0.785180
vn 0.2735 0.9619 -0.0000
vn -0.0000 -0.0000 -1.0000
vn -0.3163 0.9487 -0.0000
vn -0.0000 -0.0000 1.0000
vn -0.0000 -1.0000 -0.0000
vn -0.0000 1.0000 -0.0000
vt 0.375000 0.000000
vt 0.625000 0.000000
vt 0.625000 0.250000
vt 0.375000 0.250000
vt 0.625000 0.500000
vt 0.375000 0.500000
vt 0.625000 0.750000
vt 0.375000 0.750000
vt 0.625000 1.000000
vt 0.375000 1.000000
vt 0.125000 0.500000
vt 0.125000 0.750000
vt 0.875000 0.500000
vt 0.875000 0.750000
s 0
usemtl Material.013
f 49/85/37 51/88/37 52/87/37 50/86/37
f 51/88/38 55/90/38 56/89/38 52/87/38
f 55/90/39 53/92/39 54/91/39 56/89/39
f 53/92/40 49/94/40 50/93/40 54/91/40
f 51/95/41 49/96/41 53/92/41 55/90/41
f 56/89/42 54/91/42 50/98/42 52/97/42
o neu1.002
v -0.141720 0.277559 1.245076
v -0.141720 1.799917 1.245076
v -0.526580 0.277559 -0.636534
v -0.526580 1.799917 -0.636534
v 0.527939 0.277559 1.108105
v 0.527939 1.799917 1.108105
v 0.143079 0.277559 -0.773505
v 0.143079 1.799917 -0.773505
vn -0.9797 -0.0000 0.2004
vn -0.2004 -0.0000 -0.9797
vn 0.9797 -0.0000 -0.2004
vn 0.2004 -0.0000 0.9797
vn -0.0000 -1.0000 -0.0000
vn -0.0000 1.0000 -0.0000
vt 0.375000 0.000000
vt 0.625000 0.000000
vt 0.625000 0.250000
vt 0.375000 0.250000
vt 0.625000 0.500000
vt 0.375000 0.500000
vt 0.625000 0.750000
vt 0.375000 0.750000
vt 0.625000 1.000000
vt 0.375000 1.000000
vt 0.125000 0.500000
vt 0.125000 0.750000
vt 0.875000 0.500000
vt 0.875000 0.750000
s 0
usemtl Material.014
f 57/99/43 58/100/43 60/101/43 59/102/43
f 59/102/44 60/101/44 64/103/44 63/104/44
f 63/104/45 64/103/45 62/105/45 61/106/45
f 61/106/46 62/105/46 58/107/46 57/108/46
f 59/109/47 63/104/47 61/106/47 57/110/47
f 64/103/48 60/111/48 58/112/48 62/105/48
o Frontfassade.002
v -0.136904 0.288576 1.251104
v -0.136904 1.790561 1.251104
v -0.138688 0.288576 1.242381
v -0.138688 1.790561 1.242381
v 0.521519 0.288576 1.116432
v 0.521519 1.790561 1.116432
v 0.519735 0.288576 1.107709
v 0.519735 1.790561 1.107709
vn -0.9797 -0.0000 0.2004
vn -0.2004 -0.0000 -0.9797
vn 0.9797 -0.0000 -0.2004
vn 0.2004 -0.0000 0.9797
vn -0.0000 -1.0000 -0.0000
vn -0.0000 1.0000 -0.0000
vt 0.375000 0.000000
vt 0.625000 0.000000
vt 0.625000 0.250000
vt 0.375000 0.250000
vt 0.625000 0.500000
vt 0.375000 0.500000
vt 0.625000 0.750000
vt 0.375000 0.750000
vt 0.625000 1.000000
vt 0.375000 1.000000
vt 0.125000 0.500000
vt 0.125000 0.750000
vt 0.875000 0.500000
vt 0.875000 0.750000
s 0
usemtl Material.015
f 65/113/49 66/114/49 68/115/49 67/116/49
f 67/116/50 68/115/50 72/117/50 71/118/50
f 71/118/51 72/117/51 70/119/51 69/120/51
f 69/120/52 70/119/52 66/121/52 65/122/52
f 67/123/53 71/118/53 69/120/53 65/124/53
f 72/117/54 68/125/54 66/126/54 70/119/54
o Dach300.003
v 0.511862 1.800155 1.101269
v 0.158847 1.902617 1.173474
v 0.135633 1.800155 -0.738143
v -0.217382 1.902617 -0.665938
v -0.146407 1.800155 1.235910
v 0.154658 1.902617 1.174331
v -0.522636 1.800155 -0.603502
v -0.221571 1.902617 -0.665081
vn 0.2680 0.9619 -0.0548
vn -0.2004 -0.0000 -0.9797
vn -0.3099 0.9487 0.0634
vn 0.2004 -0.0000 0.9797
vn -0.0000 -1.0000 -0.0000
vn -0.0000 1.0000 -0.0000
vt 0.375000 0.000000
vt 0.625000 0.000000
vt 0.625000 0.250000
vt 0.375000 0.250000
vt 0.625000 0.500000
vt 0.375000 0.500000
vt 0.625000 0.750000
vt 0.375000 0.750000
vt 0.625000 1.000000
vt 0.375000 1.000000
vt 0.125000 0.500000
vt 0.125000 0.750000
vt 0.875000 0.500000
vt 0.875000 0.750000
s 0
usemtl Material.016
f 73/127/55 75/130/55 76/129/55 74/128/55
f 75/130/56 79/132/56 80/131/56 76/129/56
f 79/132/57 77/134/57 78/133/57 80/131/57
f 77/134/58 73/136/58 74/135/58 78/133/58
f 75/137/59 73/138/59 77/134/59 79/132/59
f 80/131/60 78/133/60 74/140/60 76/139/60
o Korridor.002
v 0.294809 0.748953 0.441551
v 0.294809 0.301543 0.441551
v 1.816918 0.748953 0.453486
v 1.816918 0.301543 0.453486
v 0.294640 0.748953 0.463026
v 0.294640 0.301543 0.463026
v 1.816749 0.748953 0.474962
v 1.816749 0.301543 0.474962
vn 0.0078 -0.0000 -1.0000
vn 1.0000 -0.0000 0.0078
vn -0.0078 -0.0000 1.0000
vn -1.0000 -0.0000 -0.0078
vn -0.0000 1.0000 -0.0000
vn -0.0000 -1.0000 -0.0000
vt 0.375000 0.000000
vt 0.625000 0.000000
vt 0.625000 0.250000
vt 0.375000 0.250000
vt 0.625000 0.500000
vt 0.375000 0.500000
vt 0.625000 0.750000
vt 0.375000 0.750000
vt 0.625000 1.000000
vt 0.375000 1.000000
vt 0.125000 0.500000
vt 0.125000 0.750000
vt 0.875000 0.500000
vt 0.875000 0.750000
s 0
usemtl Material.019
f 81/141/61 83/144/61 84/143/61 82/142/61
f 83/144/62 87/146/62 88/145/62 84/143/62
f 87/146/63 85/148/63 86/147/63 88/145/63
f 85/148/64 81/150/64 82/149/64 86/147/64
f 83/151/65 81/152/65 85/148/65 87/146/65
f 88/145/66 86/147/66 82/154/66 84/153/66
o Korridor.003
v 0.295923 0.753172 -0.007372
v 0.295923 0.305763 -0.007372
v 1.818032 0.753172 0.004563
v 1.818032 0.305763 0.004563
v 0.295755 0.753172 0.014104
v 0.295755 0.305763 0.014104
v 1.817863 0.753172 0.026039
v 1.817863 0.305763 0.026039
vn 0.0078 -0.0000 -1.0000
vn 1.0000 -0.0000 0.0078
vn -0.0078 -0.0000 1.0000
vn -1.0000 -0.0000 -0.0078
vn -0.0000 1.0000 -0.0000
vn -0.0000 -1.0000 -0.0000
vt 0.375000 0.000000
vt 0.625000 0.000000
vt 0.625000 0.250000
vt 0.375000 0.250000
vt 0.625000 0.500000
vt 0.375000 0.500000
vt 0.625000 0.750000
vt 0.375000 0.750000
vt 0.625000 1.000000
vt 0.375000 1.000000
vt 0.125000 0.500000
vt 0.125000 0.750000
vt 0.875000 0.500000
vt 0.875000 0.750000
s 0
usemtl Material.022
f 89/155/67 91/158/67 92/157/67 90/156/67
f 91/158/68 95/160/68 96/159/68 92/157/68
f 95/160/69 93/162/69 94/161/69 96/159/69
f 93/162/70 89/164/70 90/163/70 94/161/70
f 91/165/71 89/166/71 93/162/71 95/160/71
f 96/159/72 94/161/72 90/168/72 92/167/72
o Korridor.004
v -2.035452 0.753172 0.001578
v -2.035452 0.305763 0.001578
v -0.305429 0.753172 0.015144
v -0.305429 0.305763 0.015144
v -2.035621 0.753172 0.023054
v -2.035621 0.305763 0.023054
v -0.305598 0.753172 0.036620
v -0.305598 0.305763 0.036620
vn 0.0078 -0.0000 -1.0000
vn 1.0000 -0.0000 0.0078
vn -0.0078 -0.0000 1.0000
vn -1.0000 -0.0000 -0.0078
vn -0.0000 1.0000 -0.0000
vn -0.0000 -1.0000 -0.0000
vt 0.375000 0.000000
vt 0.625000 0.000000
vt 0.625000 0.250000
vt 0.375000 0.250000
vt 0.625000 0.500000
vt 0.375000 0.500000
vt 0.625000 0.750000
vt 0.375000 0.750000
vt 0.625000 1.000000
vt 0.375000 1.000000
vt 0.125000 0.500000
vt 0.125000 0.750000
vt 0.875000 0.500000
vt 0.875000 0.750000
s 0
usemtl Material.023
f 97/169/73 99/172/73 100/171/73 98/170/73
f 99/172/74 103/174/74 104/173/74 100/171/74
f 103/174/75 101/176/75 102/175/75 104/173/75
f 101/176/76 97/178/76 98/177/76 102/175/76
f 99/179/77 97/180/77 101/176/77 103/174/77
f 104/173/78 102/175/78 98/182/78 100/181/78
o Korridor.005
v -2.036718 0.748953 0.450501
v -2.036718 0.301543 0.450501
v -0.306695 0.748953 0.464067
v -0.306695 0.301543 0.464067
v -2.036887 0.748953 0.471977
v -2.036887 0.301543 0.471977
v -0.306864 0.748953 0.485542
v -0.306864 0.301543 0.485542
vn 0.0078 -0.0000 -1.0000
vn 1.0000 -0.0000 0.0078
vn -0.0078 -0.0000 1.0000
vn -1.0000 -0.0000 -0.0078
vn -0.0000 1.0000 -0.0000
vn -0.0000 -1.0000 -0.0000
vt 0.375000 0.000000
vt 0.625000 0.000000
vt 0.625000 0.250000
vt 0.375000 0.250000
vt 0.625000 0.500000
vt 0.375000 0.500000
vt 0.625000 0.750000
vt 0.375000 0.750000
vt 0.625000 1.000000
vt 0.375000 1.000000
vt 0.125000 0.500000
vt 0.125000 0.750000
vt 0.875000 0.500000
vt 0.875000 0.750000
s 0
usemtl Material.024
f 105/183/79 107/186/79 108/185/79 106/184/79
f 107/186/80 111/188/80 112/187/80 108/185/80
f 111/188/81 109/190/81 110/189/81 112/187/81
f 109/190/82 105/192/82 106/191/82 110/189/82
f 107/193/83 105/194/83 109/190/83 111/188/83
f 112/187/84 110/189/84 106/196/84 108/195/84
o Korridor.006
v -0.288805 0.743096 0.460344
v -0.288805 0.295686 0.460344
v -2.062986 0.743096 0.437401
v -2.062986 0.295686 0.437401
v -0.283281 0.743096 0.033143
v -0.283281 0.295686 0.033143
v -2.057462 0.743096 0.010200
v -2.057462 0.295686 0.010200
vn -0.0129 -0.0000 0.9999
vn -0.9999 -0.0000 -0.0129
vn 0.0129 -0.0000 -0.9999
vn 0.9999 -0.0000 0.0129
vn -0.0000 1.0000 -0.0000
vn -0.0000 -1.0000 -0.0000
vt 0.375000 0.000000
vt 0.625000 0.000000
vt 0.625000 0.250000
vt 0.375000 0.250000
vt 0.625000 0.500000
vt 0.375000 0.500000
vt 0.625000 0.750000
vt 0.375000 0.750000
vt 0.625000 1.000000
vt 0.375000 1.000000
vt 0.125000 0.500000
vt 0.125000 0.750000
vt 0.875000 0.500000
vt 0.875000 0.750000
s 0
usemtl Material.025
f 113/197/85 115/200/85 116/199/85 114/198/85
f 115/200/86 119/202/86 120/201/86 116/199/86
f 119/202/87 117/204/87 118/203/87 120/201/87
f 117/204/88 113/206/88 114/205/88 118/203/88
f 115/207/89 113/208/89 117/204/89 119/202/89
f 120/201/90 118/203/90 114/210/90 116/209/90

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 552 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 KiB

View File

@@ -19,8 +19,6 @@ import java.util.Deque;
import static java.lang.Math.max; import static java.lang.Math.max;
import java.lang.System.Logger;
/** /**
* Manages dialog boxes within the application, handling their display, positioning, and focus. * Manages dialog boxes within the application, handling their display, positioning, and focus.
*/ */
@@ -30,15 +28,11 @@ public class DialogManager {
*/ */
private final SimpleApplication app; private final SimpleApplication app;
private final static Logger LOGGER = System.getLogger(DialogManager.class.getName());
/** /**
* A stack to keep track of the dialogs. * A stack to keep track of the dialogs.
*/ */
private final Deque<Dialog> dialogStack = new ArrayDeque<>(); private final Deque<Dialog> dialogStack = new ArrayDeque<>();
private final Deque<PopupDialog> popUpStack = new ArrayDeque<>();
/** /**
* Constructs a DialogManager for the specified application. * Constructs a DialogManager for the specified application.
* *
@@ -118,45 +112,11 @@ public class DialogManager {
* @param dialog the dialog to open * @param dialog the dialog to open
*/ */
public void open(Dialog dialog) { public void open(Dialog dialog) {
if(dialog instanceof PopupDialog) {
popUpStack.push((PopupDialog) dialog);
processPopUps();
} else {
showDialog(dialog);
}
}
private void showDialog(Dialog dialog) {
dialogStack.push(dialog); dialogStack.push(dialog);
if(dialog instanceof PopupDialog) {
((PopupDialog)dialog).show();
}
dialog.update(); dialog.update();
app.getGuiNode().attachChild(dialog); app.getGuiNode().attachChild(dialog);
} }
private void processPopUps() {
if (popUpStack.isEmpty()) {
return; // Nothing to process
}
// Check if a popup dialog is already on top
if (dialogStack.peek() instanceof PopupDialog) {
LOGGER.log(Logger.Level.DEBUG, "Popup dialog already on top");
return; // Already a popup dialog on top
} else {
// Pop the next popup from the stack and validate before showing
PopupDialog popUp = popUpStack.pop();
showDialog( (Dialog) popUp);
}
}
/** /**
* Checks if the specified dialog is the topmost dialog in the dialog stack. * Checks if the specified dialog is the topmost dialog in the dialog stack.
* *
@@ -180,8 +140,6 @@ public class DialogManager {
if (!dialogStack.isEmpty()) if (!dialogStack.isEmpty())
dialogStack.peek().update(); dialogStack.peek().update();
app.getGuiNode().detachChild(dialog); app.getGuiNode().detachChild(dialog);
processPopUps();
} }
/** /**

View File

@@ -1,5 +0,0 @@
package pp.dialog;
public interface PopupDialog {
void show();
}

View File

@@ -3,7 +3,6 @@
// https://github.com/jMonkeyEngine-Contributions/Lemur/wiki/Styling // https://github.com/jMonkeyEngine-Contributions/Lemur/wiki/Styling
import com.jme3.math.ColorRGBA import com.jme3.math.ColorRGBA
import com.jme3.texture.Texture
import com.simsilica.lemur.* import com.simsilica.lemur.*
import com.simsilica.lemur.component.QuadBackgroundComponent import com.simsilica.lemur.component.QuadBackgroundComponent
import com.simsilica.lemur.Button import com.simsilica.lemur.Button
@@ -13,8 +12,6 @@ import com.simsilica.lemur.HAlignment
import com.simsilica.lemur.Insets3f import com.simsilica.lemur.Insets3f
import com.simsilica.lemur.component.QuadBackgroundComponent import com.simsilica.lemur.component.QuadBackgroundComponent
import com.simsilica.lemur.component.TbtQuadBackgroundComponent import com.simsilica.lemur.component.TbtQuadBackgroundComponent
import pp.monopoly.client.MonopolyApp
import pp.monopoly.game.server.Player
def bgColor = color(1, 1, 1, 1) def bgColor = color(1, 1, 1, 1)
def buttonEnabledColor = color(0, 0, 0, 1) def buttonEnabledColor = color(0, 0, 0, 1)
@@ -50,23 +47,6 @@ def orangeBorder = TbtQuadBackgroundComponent.create(
1f, false) 1f, false)
orangeBorder.color = color(1, 0.5, 0, 1) // Orange color orangeBorder.color = color(1, 0.5, 0, 1) // Orange color
def createCustomBackground(app) {
// Load the texture from the assets
Texture texture = app.getAssetManager().loadTexture("Pictures/kontobg.png")
// Create the TbtQuadBackgroundComponent
def backgroundCustom = TbtQuadBackgroundComponent.create(
texture, // The texture to use
1, 1, 1, // Insets for the 9-patch behavior
126, 126, // The size of the texture
1f, // The scale factor
false // No tiling
)
return backgroundCustom
}
selector("pp") { selector("pp") {
font = font("Interface/Fonts/Metropolis/Metropolis-Regular-32.fnt") font = font("Interface/Fonts/Metropolis/Metropolis-Regular-32.fnt")
} }
@@ -89,7 +69,7 @@ selector("label-Bold", "pp") {
selector("label-toolbar", "pp") { selector("label-toolbar", "pp") {
insets = new Insets3f(2, 2, 2, 2) insets = new Insets3f(2, 2, 2, 2)
font = font("Interface/Fonts/Metropolis/Metropolis-Bold-32.fnt") font = font("Interface/Fonts/Metropolis/Metropolis-Bold-32.fnt")
fontSize = 25 fontSize = 30
color = new ColorRGBA(ColorRGBA.White) color = new ColorRGBA(ColorRGBA.White)
textHAlignment = HAlignment.Center textHAlignment = HAlignment.Center
textVAlignment = VAlignment.Center textVAlignment = VAlignment.Center
@@ -101,13 +81,6 @@ selector("label-Text", "pp") {
color = buttonEnabledColor color = buttonEnabledColor
} }
selector("label-player", "pp") {
insets = new Insets3f(2, 2, 2, 2)
font = font("Interface/Fonts/Metropolis/Metropolis-Bold-32.fnt")
fontSize = 20
color = buttonEnabledColor
}
selector("label-account", "pp") { selector("label-account", "pp") {
insets = new Insets3f(2, 2, 2, 2) insets = new Insets3f(2, 2, 2, 2)
fontSize = 25 fontSize = 25
@@ -225,6 +198,7 @@ selector("button", "pp") {
insets = new Insets3f(3, 3, 3, 3) // Adjust the border thickness insets = new Insets3f(3, 3, 3, 3) // Adjust the border thickness
textHAlignment = HAlignment.Center textHAlignment = HAlignment.Center
textVAlignment = VAlignment.Center textVAlignment = VAlignment.Center
buttonCommands = stdButtonCommands
} }
selector("slider", "pp") { selector("slider", "pp") {
@@ -351,23 +325,22 @@ selector("selector.item.label", "hover") {
background = new QuadBackgroundComponent(new ColorRGBA(0.2f, 0.6f, 1.0f, 0.9f)) // Highlighted background background = new QuadBackgroundComponent(new ColorRGBA(0.2f, 0.6f, 1.0f, 0.9f)) // Highlighted background
} }
def enabledCommandToolbar = new Command<Button>() { def enabledCommandToolbar = new Command<Button>() {
MonopolyApp app // Pass the app instance to access player details
void execute(Button source) { void execute(Button source) {
// Get the current player's color if (source.isEnabled()){
Player currentPlayer = app.getGameLogic().getPlayerHandler().getPlayerById(app.getId()); source.setColor(ColorRGBA.White)
ColorRGBA playerColor = Player.getColor(currentPlayer.getId()).getColor(); def orangeBackground = new QuadBackgroundComponent(color(1, 0.5, 0, 1)); // Orange background
source.setBackground(orangeBackground);
if (source.isEnabled()) { } else{
source.setColor(ColorRGBA.White); source.setColor(ColorRGBA.White)
def playerBackground = new QuadBackgroundComponent(playerColor); // Use player's color def grayBackground = new QuadBackgroundComponent(ColorRGBA.Gray); // Gray background
source.setBackground(playerBackground);
} else {
source.setColor(ColorRGBA.White);
def grayBackground = new QuadBackgroundComponent(ColorRGBA.Gray); // Use gray when disabled
source.setBackground(grayBackground); source.setBackground(grayBackground);
} }
} }
} }
@@ -393,56 +366,3 @@ selector("button-toolbar", "pp") {
} }
selector("button-clear", "pp") { playerColor ->
def validColor = playerColor ?: new ColorRGBA(0, 0, 0, 0) // Vollständig transparent
def playerGradientBackground = new QuadBackgroundComponent(validColor)
// Kein Hintergrundbild, komplett transparent
playerGradientBackground.setColor(new ColorRGBA(0, 0, 0, 0)) // RGBA (Rot, Grün, Blau, Alpha)
background = playerGradientBackground.clone() // Setze den Hintergrund
insets = new Insets3f(-3, -3, -3, -3) // Optional: Ränder
textHAlignment = HAlignment.Center // Text-Zentrierung
textVAlignment = VAlignment.Center // Text-Zentrierung
}
def enabledCommandToolbar2= new Command<Button>() {
void execute(Button source) {
if (source.isEnabled()){
source.setColor(ColorRGBA.White)
def orangeBackground = new QuadBackgroundComponent(color(1, 0.5, 0, 1)); // Orange background
source.setBackground(orangeBackground);
} else{
source.setColor(ColorRGBA.White)
def grayBackground = new QuadBackgroundComponent(ColorRGBA.Gray); // Gray background
source.setBackground(grayBackground);
}
}
}
def stdButtonCommandsToolbar2 =[
(ButtonAction.Down) : [pressedCommand],
(ButtonAction.Up) : [pressedCommand],
(ButtonAction.Enabled) : [enabledCommandToolbar2],
(ButtonAction.Disabled): [enabledCommandToolbar2]
]
selector("button-toolbar2", "pp") {
def outerBackground = new QuadBackgroundComponent(color(1, 0.5, 0, 1)) // Orange border
def innerBackground = new QuadBackgroundComponent(buttonBgColor) // Inner button background
// Apply the outer border as the main background
background = outerBackground
// Use insets to create a margin/padding effect for the inner background
insets = new Insets3f(3, 3, 3, 3) // Adjust the border thickness
textHAlignment = HAlignment.Center
textVAlignment = VAlignment.Center
buttonCommands = stdButtonCommandsToolbar2
}

View File

@@ -3,16 +3,13 @@ package pp.monopoly.client;
import com.jme3.app.Application; import com.jme3.app.Application;
import com.jme3.app.state.AppStateManager; import com.jme3.app.state.AppStateManager;
import com.jme3.asset.AssetManager; import com.jme3.asset.AssetManager;
import com.jme3.effect.ParticleEmitter;
import com.jme3.effect.ParticleMesh;
import com.jme3.effect.shapes.EmitterSphereShape;
import com.jme3.light.AmbientLight; import com.jme3.light.AmbientLight;
import com.jme3.light.DirectionalLight; import com.jme3.light.DirectionalLight;
import com.jme3.light.PointLight;
import com.jme3.material.Material; import com.jme3.material.Material;
import com.jme3.math.ColorRGBA; import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath; import com.jme3.math.FastMath;
import com.jme3.math.Quaternion; import com.jme3.math.Quaternion;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f; import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera; import com.jme3.renderer.Camera;
import com.jme3.renderer.queue.RenderQueue.ShadowMode; import com.jme3.renderer.queue.RenderQueue.ShadowMode;
@@ -20,22 +17,16 @@ import com.jme3.scene.Geometry;
import com.jme3.scene.Node; import com.jme3.scene.Node;
import com.jme3.scene.Spatial; import com.jme3.scene.Spatial;
import com.jme3.scene.shape.Box; import com.jme3.scene.shape.Box;
import com.jme3.scene.shape.Cylinder;
import com.jme3.scene.shape.Sphere;
import com.jme3.shadow.DirectionalLightShadowRenderer; import com.jme3.shadow.DirectionalLightShadowRenderer;
import com.jme3.shadow.EdgeFilteringMode; import com.jme3.shadow.EdgeFilteringMode;
import com.jme3.texture.Texture; import com.jme3.texture.Texture;
import com.jme3.util.SkyFactory; import com.jme3.util.SkyFactory;
import com.jme3.util.TangentBinormalGenerator; import com.jme3.util.TangentBinormalGenerator;
import pp.monopoly.client.gui.BobTheBuilder;
import pp.monopoly.client.gui.CameraController;
import pp.monopoly.client.gui.CameraInputHandler;
import pp.monopoly.client.gui.Toolbar;
import pp.monopoly.model.Board; import pp.monopoly.model.Board;
import pp.monopoly.client.gui.FigureControl; import pp.monopoly.client.gui.BobTheBuilder;
import pp.monopoly.client.gui.Toolbar;
import static java.lang.Math.divideExact; import static pp.util.FloatMath.PI;
import static pp.util.FloatMath.TWO_PI; import static pp.util.FloatMath.TWO_PI;
import static pp.util.FloatMath.cos; import static pp.util.FloatMath.cos;
import static pp.util.FloatMath.sin; import static pp.util.FloatMath.sin;
@@ -77,17 +68,6 @@ public class BoardAppState extends MonopolyAppState {
*/ */
private PopUpManager popUpManager;; private PopUpManager popUpManager;;
private Vector3f currentTarget = new Vector3f(-10f,0,-10f);
private float modelHeight = -5f;
private final float targetHeight = 0f;
private final float animationSpeed = 0.01389f;
private Node modelNode;
private boolean startAnimation = false;
private CameraController cameraController;
private CameraInputHandler cameraInputHandler;
/** /**
* Initializes the state by setting up the sky, lights, and other visual components. * Initializes the state by setting up the sky, lights, and other visual components.
* This method is called when the state is first attached to the state manager. * This method is called when the state is first attached to the state manager.
@@ -98,16 +78,8 @@ public class BoardAppState extends MonopolyAppState {
@Override @Override
public void initialize(AppStateManager stateManager, Application application) { public void initialize(AppStateManager stateManager, Application application) {
super.initialize(stateManager, application); super.initialize(stateManager, application);
// Initialisiere den CameraController zuerst
cameraController = new CameraController(getApp().getCamera(), 25, 40);
// Danach den CameraInputHandler mit dem initialisierten CameraController
cameraInputHandler = new CameraInputHandler(cameraController, getApp().getInputManager());
popUpManager = new PopUpManager(getApp()); popUpManager = new PopUpManager(getApp());
viewNode.attachChild(sceneNode); viewNode.attachChild(sceneNode);
setupLights(); setupLights();
setupSky(); setupSky();
} }
@@ -121,19 +93,40 @@ public class BoardAppState extends MonopolyAppState {
getApp().getRootNode().detachAllChildren(); getApp().getRootNode().detachAllChildren();
getApp().getGuiNode().detachAllChildren(); getApp().getGuiNode().detachAllChildren();
getApp().getDialogManager().close(getApp().getDialogManager().getDialogStack().peek());
new Toolbar(getApp()).open(); new Toolbar(getApp()).open();
sceneNode.detachAllChildren(); sceneNode.detachAllChildren();
setupScene(); setupScene();
if (bobTheBuilder == null) { if (bobTheBuilder == null) {
bobTheBuilder = new BobTheBuilder(getApp(), sceneNode); bobTheBuilder = new BobTheBuilder(getApp(), getApp().getRootNode());
System.out.println("LISTENER IS REGISTEDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD");
getGameLogic().addListener(bobTheBuilder); getGameLogic().addListener(bobTheBuilder);
} }
getApp().getRootNode().attachChild(viewNode); getApp().getRootNode().attachChild(viewNode);
} }
//TODO remove this only for camera testing
private static final float ABOVE_SEA_LEVEL = 10f;
private static final float INCLINATION = 2.5f;
private float cameraAngle;
/**
* Adjusts the camera position and orientation to create a circular motion around
* the center of the map. This provides a dynamic view of the sea and surrounding environment.
*/
private void adjustCamera() {
final Board board = getGameLogic().getBoard();
final float mx = 0.5f * board.getWidth();
final float my = 0.5f * board.getHeight();
final float radius = 2f * sqrt(mx * mx + my + my);
final float cos = radius * cos(cameraAngle);
final float sin = radius * sin(cameraAngle);
final float x = mx - cos;
final float y = my - sin;
final Camera camera = getApp().getCamera();
camera.setLocation(new Vector3f(x, ABOVE_SEA_LEVEL, y));
camera.lookAt(new Vector3f(0,0, 0),
Vector3f.UNIT_Y);
camera.update();
}
/** /**
* Disables the sea and sky state, removing visual elements from the scene and unregistering listeners. * Disables the sea and sky state, removing visual elements from the scene and unregistering listeners.
@@ -148,7 +141,18 @@ public class BoardAppState extends MonopolyAppState {
} }
} }
/**
* Updates the state each frame, moving the camera to simulate it circling around the map.
*
* @param tpf the time per frame (seconds)
*/
@Override
public void update(float tpf) {
super.update(tpf);
//TODO remove this only for camera testing
cameraAngle += TWO_PI * 0.05f * tpf;
adjustCamera();
}
/** /**
* Sets up the lighting for the scene, including directional and ambient lights. * Sets up the lighting for the scene, including directional and ambient lights.
@@ -177,10 +181,10 @@ public class BoardAppState extends MonopolyAppState {
*/ */
private void setupSky() { private void setupSky() {
final AssetManager assetManager = getApp().getAssetManager(); final AssetManager assetManager = getApp().getAssetManager();
final Texture west = assetManager.loadTexture("Pictures/Backdrop/west.jpg"); //NON-NLS final Texture west = assetManager.loadTexture("Pictures/Backdrop/left.jpg"); //NON-NLS
final Texture east = assetManager.loadTexture("Pictures/Backdrop/ost.jpg"); //NON-NLS final Texture east = assetManager.loadTexture("Pictures/Backdrop/right.jpg"); //NON-NLS
final Texture north = assetManager.loadTexture("Pictures/Backdrop/nord.jpg"); //NON-NLS final Texture north = assetManager.loadTexture("Pictures/Backdrop/front.jpg"); //NON-NLS
final Texture south = assetManager.loadTexture("Pictures/Backdrop/sued.jpg"); //NON-NLS final Texture south = assetManager.loadTexture("Pictures/Backdrop/back.jpg"); //NON-NLS
final Texture up = assetManager.loadTexture("Pictures/Backdrop/up.jpg"); //NON-NLS final Texture up = assetManager.loadTexture("Pictures/Backdrop/up.jpg"); //NON-NLS
final Texture down = assetManager.loadTexture("Pictures/Backdrop/down.jpg"); //NON-NLS final Texture down = assetManager.loadTexture("Pictures/Backdrop/down.jpg"); //NON-NLS
final Spatial sky = SkyFactory.createSky(assetManager, west, east, north, south, up, down); final Spatial sky = SkyFactory.createSky(assetManager, west, east, north, south, up, down);
@@ -197,10 +201,10 @@ public class BoardAppState extends MonopolyAppState {
final float x = board.getWidth(); final float x = board.getWidth();
final float y = board.getHeight(); final float y = board.getHeight();
final Box seaMesh = new Box(y, 0.1f, x); final Box seaMesh = new Box(y, 0.1f, x);
final Geometry seaGeo = new Geometry("sea", seaMesh); //NON-NLS final Geometry seaGeo = new Geometry("sea", seaMesh); //NONs-NLS
seaGeo.setLocalTranslation(new Vector3f(0, -0.1f, 0)); seaGeo.setLocalTranslation(new Vector3f(0, -0.1f, 0));
Quaternion rotation = new Quaternion(); Quaternion rotation = new com.jme3.math.Quaternion();
rotation.fromAngleAxis(FastMath.HALF_PI, Vector3f.UNIT_Y); rotation.fromAngleAxis(FastMath.HALF_PI, com.jme3.math.Vector3f.UNIT_Y);
seaGeo.setLocalRotation(rotation); seaGeo.setLocalRotation(rotation);
final Material seaMat = new Material(getApp().getAssetManager(), "Common/MatDefs/Light/Lighting.j3md"); final Material seaMat = new Material(getApp().getAssetManager(), "Common/MatDefs/Light/Lighting.j3md");
Texture texture = getApp().getAssetManager().loadTexture("Pictures/board2.png"); Texture texture = getApp().getAssetManager().loadTexture("Pictures/board2.png");
@@ -208,146 +212,6 @@ public class BoardAppState extends MonopolyAppState {
seaGeo.setMaterial(seaMat); seaGeo.setMaterial(seaMat);
seaGeo.setShadowMode(ShadowMode.CastAndReceive); seaGeo.setShadowMode(ShadowMode.CastAndReceive);
TangentBinormalGenerator.generate(seaGeo); TangentBinormalGenerator.generate(seaGeo);
sceneNode.attachChild(createCardDeck());
sceneNode.attachChild(seaGeo); sceneNode.attachChild(seaGeo);
addModelToCenter(sceneNode);
// Schneefall hinzufügen
addSnowEffect(sceneNode);
} }
private Node createCardDeck() {
Node cardDeck = new Node("cardDeck");
Spatial card = getApp().getAssetManager().loadModel("models/Kartendecks/Ereigniskarten.j3o");
card.setLocalTranslation(5.5f, 0, 2.7f);
card.setLocalScale(4.1f);
card.setLocalRotation(new Quaternion().fromAngleAxis(FastMath.QUARTER_PI, Vector3f.UNIT_Y));
Spatial card2 = getApp().getAssetManager().loadModel("models/Kartendecks/Gemeinschaftskarten.j3o");
card2.setLocalTranslation(-1.4f, 0, -3.8f);
card2.setLocalScale(4.1f);
card2.setLocalRotation(new Quaternion().fromAngleAxis(FastMath.QUARTER_PI , Vector3f.UNIT_Y));
cardDeck.attachChild(card);
cardDeck.attachChild(card2);
return cardDeck;
}
public Vector3f getCurrentTarget(){
return currentTarget;
}
private void addSnowEffect(Node parentNode) {
// ParticleEmitter für Schnee
ParticleEmitter snowEmitter = new ParticleEmitter("Snow", ParticleMesh.Type.Triangle, 5000);
Material snowMat = new Material(getApp().getAssetManager(), "Common/MatDefs/Misc/Particle.j3md");
snowMat.setTexture("Texture", getApp().getAssetManager().loadTexture("Textures/snowflake.png")); // Schneeflocken-Textur
snowEmitter.setMaterial(snowMat);
// Eigenschaften für Schneepartikel
snowEmitter.setImagesX(1);
snowEmitter.setImagesY(1);
snowEmitter.setEndColor(new ColorRGBA(1f, 1f, 1f, 0.5f)); // Weiß, halbtransparent
snowEmitter.setStartColor(new ColorRGBA(1f, 1f, 1f, 1f)); // Vollweiß
snowEmitter.setStartSize(0.1f);
snowEmitter.setEndSize(0.2f);
snowEmitter.setGravity(0, 0.5f, 0); // Langsames Fallen
snowEmitter.setLowLife(3f);
snowEmitter.setHighLife(15f);
snowEmitter.getParticleInfluencer().setInitialVelocity(new Vector3f(0, -1, 0));
snowEmitter.getParticleInfluencer().setVelocityVariation(0.3f);
// Spawn-Bereich für Schneeflocken definieren
snowEmitter.setParticlesPerSec(200);
snowEmitter.setLocalTranslation(0, 10, 0);
snowEmitter.setShape(new EmitterSphereShape(new Vector3f(0, 0, 0), 15)); // Bereich von -15 bis 15
// Emitter zur Szene hinzufügen
parentNode.attachChild(snowEmitter);
}
private void addModelToCenter(Node parentNode) {
AssetManager assetManager = getApp().getAssetManager();
Material material = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");
material.setColor("Diffuse", ColorRGBA.White);
material.setBoolean("UseMaterialColors", true);
Sphere lowerSphereLeft = new Sphere(32, 32, 0.5f);
Geometry lowerSphereLeftGeom = new Geometry("LowerSphereLeft", lowerSphereLeft);
lowerSphereLeftGeom.setMaterial(material);
lowerSphereLeftGeom.setLocalTranslation(-0.6f - 4f, 0.5f, 0.3f - 5f);
Sphere lowerSphereRight = new Sphere(32, 32, 0.5f);
Geometry lowerSphereRightGeom = new Geometry("LowerSphereRight", lowerSphereRight);
lowerSphereRightGeom.setMaterial(material);
lowerSphereRightGeom.setLocalTranslation(0.6f - 4f, 0.5f, 0.3f - 5f);
Cylinder cylinder = new Cylinder(16, 16, 0.4f, 2f, true);
Geometry cylinderGeom = new Geometry("Cylinder", cylinder);
cylinderGeom.setMaterial(material);
cylinderGeom.setLocalTranslation(0f - 4f, 1.5f, 0f - 5f);
cylinderGeom.rotate(FastMath.HALF_PI, 0, 0);
Sphere upperSphere = new Sphere(32, 32, 0.4f);
Geometry upperSphereGeom = new Geometry("UpperSphere", upperSphere);
upperSphereGeom.setMaterial(material);
upperSphereGeom.setLocalTranslation(0f - 4f, 2.5f, 0f - 5f);
this.modelNode = new Node("3DModel");
this.modelNode.attachChild(lowerSphereLeftGeom);
this.modelNode.attachChild(lowerSphereRightGeom);
this.modelNode.attachChild(cylinderGeom);
this.modelNode.attachChild(upperSphereGeom);
this.modelNode.setLocalTranslation(0, modelHeight, 0);
parentNode.attachChild(this.modelNode);
PointLight lightLeft = new PointLight();
lightLeft.setColor(ColorRGBA.Blue);
lightLeft.setPosition(new Vector3f(-0.6f - 4f, 0f, 0.3f - 5f));
lightLeft.setRadius(2f);
parentNode.addLight(lightLeft);
PointLight lightRight = new PointLight();
lightRight.setColor(ColorRGBA.Blue);
lightRight.setPosition(new Vector3f(0.6f - 4f, 0f, 0.3f - 5f));
lightRight.setRadius(2f);
parentNode.addLight(lightRight);
}
@Override
public void update(float tpf) {
super.update(tpf);
if (startAnimation && modelHeight < targetHeight) {
modelHeight += animationSpeed * tpf; // Geschwindigkeit basierend auf Zeit pro Frame
if (modelHeight > targetHeight) {
modelHeight = targetHeight; // Zielhöhe nicht überschreiten
startAnimation = false; // Animation beenden
}
updateModelHeight(); // Aktualisiere die Position des Modells
}
}
private void updateModelHeight() {
if (modelNode == null) {
modelNode = (Node) sceneNode.getChild("3DModel");
}
if (modelNode != null) {
modelNode.setLocalTranslation(0, modelHeight, 0); // Aktualisiere die Y-Position
}
}
public void onRollDicePressed() {
System.out.println("onRollDicePressed called");
if (!startAnimation) {
startAnimation = true;
modelHeight = -5f; // Reset der Höhe
updateModelHeight(); // Stelle sicher, dass das Modell an der Startposition ist
System.out.println("Animation started, startAnimation set to: " + startAnimation);
}
}
} }

View File

@@ -0,0 +1,99 @@
////////////////////////////////////////
// Programming project code
// UniBw M, 2022, 2023, 2024
// www.unibw.de/inf2
// (c) Mark Minas (mark.minas@unibw.de)
////////////////////////////////////////
package pp.monopoly.client;
import java.lang.System.Logger;
import java.lang.System.Logger.Level;
import com.jme3.input.controls.ActionListener;
import com.jme3.scene.Node;
import pp.monopoly.client.gui.TestWorld;
/**
* Represents the state responsible for managing the battle interface within the Battleship game.
* This state handles the display and interaction of the battle map, including the opponent's map.
* It manages GUI components, input events, and the layout of the interface when this state is enabled.
*/
public class GameAppState extends MonopolyAppState {
private static final Logger LOGGER = System.getLogger(MonopolyAppState.class.getName());
/**
* A listener for handling click events in the battle interface.
* When a click is detected, it triggers the corresponding actions on the opponent's map.
*/
private final ActionListener clickListener = (name, isPressed, tpf) -> click(isPressed);
/**
* The root node for all GUI components in the battle state.
*/
private final Node battleNode = new Node("Game"); //NON-NLS
/**
* A view representing the opponent's map in the GUI.
*/
private TestWorld testWorld;
/**
* Enables the battle state by initializing, laying out, and adding GUI components.
* Attaches the components to the GUI node and registers input listeners.
*/
@Override
protected void enableState() {
LOGGER.log(Level.DEBUG, "Enabling game state");
battleNode.detachAllChildren();
initializeGuiComponents();
addGuiComponents();
getApp().getGuiNode().attachChild(battleNode);
}
/**
* Disables the battle state by removing GUI components and unregistering input listeners.
* Also handles cleanup of resources, such as the opponent's map view.
*/
@Override
protected void disableState() {
getApp().getGuiNode().detachChild(battleNode);
getApp().getInputManager().removeListener(clickListener);
}
/**
* Initializes the GUI components used in the battle state.
* Creates the opponent's map view and adds a grid overlay to it.
*/
private void initializeGuiComponents() {
// Initialisiere TestWorld mit Spielern
testWorld = new TestWorld(getApp());
testWorld.initializeScene();
}
/**
* Adds the initialized GUI components to the battle node.
* Currently, it attaches the opponent's map view to the node.
*/
private void addGuiComponents() {
}
/**
* Handles click events in the battle interface. If the event indicates a click (not a release),
* it translates the cursor position to the model's coordinate system and triggers the game logic
* for interacting with the opponent's map.
*
* @param isPressed whether the mouse button is currently pressed (true) or released (false)
*/
private void click(boolean isPressed) {
}
@Override
public void update(float tpf) {
super.update(tpf);
}
}

View File

@@ -13,13 +13,14 @@ import com.jme3.asset.AssetLoadException;
import com.jme3.asset.AssetNotFoundException; import com.jme3.asset.AssetNotFoundException;
import com.jme3.audio.AudioData; import com.jme3.audio.AudioData;
import com.jme3.audio.AudioNode; import com.jme3.audio.AudioNode;
/** /**
* Handles the background and secondary music in the game. * Handles the background and secondary music in the game.
* Allows playing, stopping, and toggling between background music and a secondary track. * Allows playing, stopping, and toggling between background music and a secondary track.
*/ */
public class GameMusic extends AbstractAppState { public class GameMusic extends AbstractAppState {
private static final Logger LOGGER = System.getLogger(pp.monopoly.client.GameMusic.class.getName()); private static final Logger LOGGER = System.getLogger(GameMusic.class.getName());
private static final Preferences PREFERENCES = getPreferences(pp.monopoly.client.GameMusic.class); private static final Preferences PREFERENCES = getPreferences(GameMusic.class);
private static final String ENABLED_PREF = "enabled"; // NON-NLS private static final String ENABLED_PREF = "enabled"; // NON-NLS
private static final String VOLUME_PREF = "volume"; // NON-NLS private static final String VOLUME_PREF = "volume"; // NON-NLS
@@ -67,9 +68,8 @@ public class GameMusic extends AbstractAppState {
/** /**
* Plays the main music. * Plays the main music.
*/ */
public void playMainMusic() { private void playMainMusic() {
if (!isEnabled()) { if (!isEnabled()) {
return; // Sound is disabled return; // Sound is disabled
} }
@@ -92,10 +92,11 @@ public class GameMusic extends AbstractAppState {
/** /**
* Plays the secondary music and stops the main music. * Plays the secondary music and stops the main music.
* *
* @param app The application instance
* @param secondaryMusicFile The file path of the secondary audio file
*/ */
public void playSecondaryMusic() { private void playSecondaryMusic() {
if (!isEnabled()) { if(!isEnabled()) {
stopAllMusic();
return; return;
} }
if (isSecondaryMusicPlaying) { if (isSecondaryMusicPlaying) {
@@ -114,7 +115,7 @@ public class GameMusic extends AbstractAppState {
/** /**
* Stops the secondary music. * Stops the secondary music.
*/ */
public void stopSecondaryMusic() { private void stopSecondaryMusic() {
if (secondaryMusic != null && isSecondaryMusicPlaying) { if (secondaryMusic != null && isSecondaryMusicPlaying) {
secondaryMusic.stop(); secondaryMusic.stop();
isSecondaryMusicPlaying = false; isSecondaryMusicPlaying = false;
@@ -126,17 +127,17 @@ public class GameMusic extends AbstractAppState {
* If the secondary track is playing, it stops and resumes the background music. * If the secondary track is playing, it stops and resumes the background music.
* If the background music is playing, it pauses and plays the secondary track. * If the background music is playing, it pauses and plays the secondary track.
* *
* @param app The application instance
* @param secondaryMusicFile The file path of the secondary audio file
*/ */
public void toggleMusic() { public void toggleMusic() {
if (!isEnabled()) { if(!isEnabled()) {
stopAllMusic();
return; return;
} }
if (isSecondaryMusicPlaying) { if (isSecondaryMusicPlaying) {
stopSecondaryMusic(); stopSecondaryMusic();
playMainMusic(); playMainMusic();
} else { } else {
stopMainMusic();
playSecondaryMusic(); playSecondaryMusic();
} }
} }
@@ -152,14 +153,6 @@ public class GameMusic extends AbstractAppState {
PREFERENCES.putFloat(VOLUME_PREF, vol); PREFERENCES.putFloat(VOLUME_PREF, vol);
} }
/**
* Stops all music (both main and secondary).
*/
public void stopAllMusic() {
stopMainMusic();
stopSecondaryMusic();
}
/** /**
* Enables or disables the sound system. * Enables or disables the sound system.
* When disabled, all music stops. * When disabled, all music stops.
@@ -168,14 +161,13 @@ public class GameMusic extends AbstractAppState {
*/ */
@Override @Override
public void setEnabled(boolean enabled) { public void setEnabled(boolean enabled) {
if (isEnabled() == enabled) return; // Avoid redundant operations if (isEnabled() == enabled) return;
PREFERENCES.putBoolean(ENABLED_PREF, enabled);
if (enabled) { if (enabled) {
playMainMusic(); playMainMusic();
} else { } else {
stopAllMusic(); stopMainMusic();
stopSecondaryMusic();
} }
super.setEnabled(enabled); super.setEnabled(enabled);

View File

@@ -120,7 +120,6 @@ public class GameSound extends AbstractAppState implements GameEventListener {
winnerSound = loadSound(app, "Sound/Effects/winner.ogg"); winnerSound = loadSound(app, "Sound/Effects/winner.ogg");
looserSound = loadSound(app, "Sound/Effects/loser.ogg"); looserSound = loadSound(app, "Sound/Effects/loser.ogg");
buttonSound = loadSound(app, "Sound/Effects/button.ogg"); buttonSound = loadSound(app, "Sound/Effects/button.ogg");
setVolume(volumeInPreferences());
} }
/** /**

View File

@@ -15,9 +15,6 @@ import java.lang.System.Logger.Level;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.logging.LogManager; import java.util.logging.LogManager;
import java.awt.Image;
import javax.imageio.ImageIO;
import com.jme3.app.DebugKeysAppState; import com.jme3.app.DebugKeysAppState;
import com.jme3.app.SimpleApplication; import com.jme3.app.SimpleApplication;
@@ -172,16 +169,6 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga
private AppSettings makeSettings() { private AppSettings makeSettings() {
final AppSettings settings = new AppSettings(true); final AppSettings settings = new AppSettings(true);
settings.setTitle(lookup("monopoly.name")); settings.setTitle(lookup("monopoly.name"));
try {
// Prüfen, ob das Betriebssystem ein Mac-System ist
if (!System.getProperty("os.name").toLowerCase().contains("mac")) {
settings.setIcons(new Image[]{ImageIO.read(new File("src/main/resources/icons/Uniman.png"))});
} else {
LOGGER.log(Level.INFO, "Icon setting skipped on macOS due to system restrictions.");
}
} catch (IOException e) {
LOGGER.log(Level.ERROR, e.getMessage());
}
settings.setResolution(config.getResolutionWidth(), config.getResolutionHeight()); settings.setResolution(config.getResolutionWidth(), config.getResolutionHeight());
settings.setFullscreen(config.fullScreen()); settings.setFullscreen(config.fullScreen());
settings.setUseRetinaFrameBuffer(config.useRetinaFrameBuffer()); settings.setUseRetinaFrameBuffer(config.useRetinaFrameBuffer());
@@ -292,7 +279,7 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga
final StatsAppState stats = new StatsAppState(guiNode, normalFont); final StatsAppState stats = new StatsAppState(guiNode, normalFont);
stateManager.attach(stats); stateManager.attach(stats);
} }
flyCam.setEnabled(true); flyCam.setEnabled(false);
stateManager.detach(stateManager.getState(StatsAppState.class)); stateManager.detach(stateManager.getState(StatsAppState.class));
stateManager.detach(stateManager.getState(DebugKeysAppState.class)); stateManager.detach(stateManager.getState(DebugKeysAppState.class));

View File

@@ -106,26 +106,6 @@ public class MonopolyAppConfig extends MonopolyClientConfig {
@Property("overlay.top.color") //NON-NLS @Property("overlay.top.color") //NON-NLS
private ColorRGBA topColor = ColorRGBA.White; private ColorRGBA topColor = ColorRGBA.White;
private ColorRGBA applyGammaCorrection(ColorRGBA color) {
return new ColorRGBA(
correctGamma(color.r),
correctGamma(color.g),
correctGamma(color.b),
color.a // Alpha bleibt unverändert
);
}
private float correctGamma(float channel) {
// Formel: ((RGB / 255)^2.2) * 255
float normalized = channel / 255.0f; // RGB normalisieren (0-1)
float gammaCorrected = (float) Math.pow(normalized, 2.2); // ^2.2
return gammaCorrected * 255.0f; // Zurückskalieren auf 0-255
}
private float correctGamma(float channel, float gamma) {
return (float) Math.pow(channel, gamma);
}
/** /**
* Creates a default {@code MonopolyAppConfig} with predefined values. * Creates a default {@code MonopolyAppConfig} with predefined values.
*/ */

View File

@@ -56,7 +56,7 @@ public class PopUpManager implements GameEventListener {
} }
}); });
} }
}, 6000); }, 2500);
} else if (event.msg().equals("Winner")) { } else if (event.msg().equals("Winner")) {
new WinnerPopUp(app).open(); new WinnerPopUp(app).open();
} else if (event.msg().equals("Looser")) { } else if (event.msg().equals("Looser")) {

View File

@@ -1,11 +1,12 @@
package pp.monopoly.client.gui; package pp.monopoly.client.gui;
import static com.jme3.material.Materials.LIGHTING;
import java.util.stream.Collectors;
import com.jme3.material.Material; import com.jme3.material.Material;
import com.jme3.material.RenderState.BlendMode; import com.jme3.material.RenderState.BlendMode;
import com.jme3.math.ColorRGBA; import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import com.jme3.renderer.queue.RenderQueue.ShadowMode; import com.jme3.renderer.queue.RenderQueue.ShadowMode;
import com.jme3.scene.Geometry; import com.jme3.scene.Geometry;
import com.jme3.scene.Node; import com.jme3.scene.Node;
@@ -13,6 +14,7 @@ import com.jme3.scene.Spatial;
import com.jme3.scene.shape.Box; import com.jme3.scene.shape.Box;
import pp.monopoly.client.MonopolyApp; import pp.monopoly.client.MonopolyApp;
import pp.monopoly.game.server.Player;
import pp.monopoly.model.Figure; import pp.monopoly.model.Figure;
import pp.monopoly.model.Hotel; import pp.monopoly.model.Hotel;
import pp.monopoly.model.House; import pp.monopoly.model.House;
@@ -39,17 +41,14 @@ public class BobTheBuilder extends GameBoardSynchronizer {
@Override @Override
public Spatial visit(Figure figure) { public Spatial visit(Figure figure) {
final Node node = new Node(FIGURE); final Node node = new Node(FIGURE);
Spatial spatial = createFigure(figure); node.attachChild(createFigure(figure));
node.attachChild(spatial);
// Setze die Position basierend auf der Feld-ID // Setze die Position basierend auf der Feld-ID
node.setLocalTranslation(figure.getPos()); node.setLocalTranslation(figure.getPos());
// Setze die Anfangsrotation auf 90 Grad nach links // Setze die Rotation basierend auf der Feld-ID
Quaternion initialRotation = new Quaternion().fromAngleAxis(FastMath.HALF_PI, Vector3f.UNIT_Y); node.setLocalRotation(figure.getRot().toQuaternion());
node.setLocalRotation(initialRotation); // node.addControl(new FigureControl(figure));
node.addControl(new FigureControl(node, figure, app));
return node; return node;
} }
@@ -144,4 +143,17 @@ public class BobTheBuilder extends GameBoardSynchronizer {
material.setColor(COLOR, color); material.setColor(COLOR, color);
return material; return material;
} }
@Override
public void receivedEvent(UpdatePlayerView event) {
board.removePlayers();
//TODO transition animation
for (Player player : app.getGameLogic().getPlayerHandler().getPlayers()) {
board.add(player.getFigure());
}
for (Item item : board.getItems().stream().filter(p -> p instanceof Figure).collect(Collectors.toList())) {
add(item);
}
}
} }

View File

@@ -3,57 +3,64 @@ package pp.monopoly.client.gui;
import com.jme3.math.Vector3f; import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera; import com.jme3.renderer.Camera;
/**
* Controls the movement of the camera within the scene.
*/
public class CameraController { public class CameraController {
public enum CameraMode {
FOCUS_CURRENT_PLAYER,
FOCUS_SELF,
FREECAM
}
private final Camera camera; private final Camera camera;
private CameraMode currentMode = CameraMode.FOCUS_CURRENT_PLAYER; private final float height = 25; // Height of the camera above the game board
private final float height; // Höhe der Kamera /**
private final float offset; // Versatz zur Spielfeldseite * Constructor for the CameraController.
*
public CameraController(Camera camera, float height, float offset) { * @param camera The camera to be controlled
*/
public CameraController(Camera camera) {
this.camera = camera; this.camera = camera;
this.height = height; setPosition(0);
this.offset = offset; camera.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y);
setMode(currentMode);
}
public void setMode(CameraMode mode) {
this.currentMode = mode;
updatePosition(0); // Standardmäßig das Startfeld fokussieren
} }
/**
* Updates the camera's position and orientation.
*
* @param tpf Time per frame
*/
public void update(float tpf) { public void update(float tpf) {
if (currentMode != CameraMode.FREECAM) { camera.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y);
camera.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y);
}
} }
public void updatePosition(int fieldID) { /**
Vector3f newPosition = fieldIdToVector(fieldID); * Sets the camera's position based on the field ID.
camera.setLocation(newPosition); *
if (currentMode != CameraMode.FREECAM) { * @param fieldID The ID of the field to which the camera should move
camera.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y); */
} public void setPosition(int fieldID) {
camera.setLocation(fieldIdToVector(fieldID));
} }
/**
* Sets the camera's position using specific coordinates.
*
* @param x The X-coordinate of the new camera position
* @param y The Y-coordinate of the new camera position
*/
public void setPosition(float x, float y) {
camera.setLocation(new Vector3f(x, height, y));
}
/**
* Maps a field ID to its corresponding position in the game world.
*
* @param fieldID The ID of the field
* @return The position of the field as a {@link Vector3f}
* @throws IllegalArgumentException If the field ID is invalid
*/
private Vector3f fieldIdToVector(int fieldID) { private Vector3f fieldIdToVector(int fieldID) {
switch (currentMode) { if (fieldID <= 10) return new Vector3f(30, height, 0);
case FOCUS_CURRENT_PLAYER: if (fieldID <= 20) return new Vector3f(0, height, 30);
if (fieldID <= 10) return new Vector3f(offset, height, 0); if (fieldID <= 30) return new Vector3f(-30, height, 0);
if (fieldID <= 20) return new Vector3f(0, height, offset); if (fieldID <= 40) return new Vector3f(0, height, -30);
if (fieldID <= 30) return new Vector3f(-offset, height, 0); else throw new IllegalArgumentException();
return new Vector3f(0, height, -offset);
case FOCUS_SELF:
return new Vector3f(0, height, fieldID <= 20 ? offset : -offset);
case FREECAM:
default:
return new Vector3f(0, height, 0);
}
} }
} }

View File

@@ -1,31 +1,60 @@
package pp.monopoly.client.gui; //package pp.monopoly.client.gui;
//
import com.jme3.input.InputManager; //import com.jme3.input.InputManager;
import com.jme3.input.KeyInput; //import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener; //import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger; //import com.jme3.input.controls.KeyTrigger;
//
public class CameraInputHandler { ///**
private CameraController cameraController; // * Handhabt die Eingaben für die Kamera.
// */
public CameraInputHandler(CameraController cameraController, InputManager inputManager) { //public class CameraInputHandler {
this.cameraController = cameraController; //
// private CameraController cameraController; // Kamera-Controller
// Tasten für die verschiedenen Kameramodi registrieren //
inputManager.addMapping("FocusCurrentPlayer", new KeyTrigger(KeyInput.KEY_1)); // /**
inputManager.addMapping("FocusSelf", new KeyTrigger(KeyInput.KEY_2)); // * Konstruktor für den CameraInputHandler.
inputManager.addMapping("FreeCam", new KeyTrigger(KeyInput.KEY_3)); // *
// * @param cameraController Der Kamera-Controller, der gesteuert werden soll.
inputManager.addListener(actionListener, "FocusCurrentPlayer", "FocusSelf", "FreeCam"); // * @param inputManager Der InputManager, um Eingaben zu registrieren.
} // */
// public CameraInputHandler(CameraController cameraController, InputManager inputManager) {
private final ActionListener actionListener = (name, isPressed, tpf) -> { // if (cameraController == null || inputManager == null) {
if (!isPressed) return; // throw new IllegalArgumentException("CameraController und InputManager dürfen nicht null sein");
// }
switch (name) { // this.cameraController = cameraController;
case "FocusCurrentPlayer" -> cameraController.setMode(CameraController.CameraMode.FOCUS_CURRENT_PLAYER); //
case "FocusSelf" -> cameraController.setMode(CameraController.CameraMode.FOCUS_SELF); // // Mappings für Kamerasteuerung
case "FreeCam" -> cameraController.setMode(CameraController.CameraMode.FREECAM); // inputManager.addMapping("FocusCurrentPlayer", new KeyTrigger(KeyInput.KEY_1)); // Modus 1
} // inputManager.addMapping("FocusSelf", new KeyTrigger(KeyInput.KEY_2)); // Modus 2
}; // inputManager.addMapping("FreeCam", new KeyTrigger(KeyInput.KEY_3)); // Modus 3
} //
// // Listener für die Kameramodi
// inputManager.addListener(actionListener, "FocusCurrentPlayer", "FocusSelf", "FreeCam");
// }
//
// /**
// * ActionListener für die Kamerasteuerung.
// */
// private final ActionListener actionListener = (name, isPressed, tpf) -> {
// if (!isPressed) return;
//
// // Umschalten der Kamera-Modi basierend auf der Eingabe
// switch (name) {
// case "FocusCurrentPlayer" -> {
// cameraController.setMode(CameraController.CameraMode.FOCUS_CURRENT_PLAYER);
// System.out.println("Kameramodus: Fokus auf aktuellen Spieler");
// }
// case "FocusSelf" -> {
// cameraController.setMode(CameraController.CameraMode.FOCUS_SELF);
// System.out.println("Kameramodus: Fokus auf eigene Figur");
// }
// case "FreeCam" -> {
// cameraController.setMode(CameraController.CameraMode.FREECAM);
// System.out.println("Kameramodus: Freie Kamera");
// }
// default -> System.err.println("Unbekannter Kameramodus: " + name);
// }
// };
//}
//

View File

@@ -1,158 +0,0 @@
package pp.monopoly.client.gui;
import com.jme3.math.FastMath;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Node;
import com.jme3.scene.control.AbstractControl;
import pp.monopoly.client.MonopolyApp;
import pp.monopoly.game.client.ClientGameLogic;
import pp.monopoly.model.Figure;
import pp.monopoly.notification.GameEventListener;
import pp.monopoly.notification.UpdatePlayerView;
// import java.lang.System.Logger;
// import java.lang.System.Logger.Level;
import java.util.LinkedList;
import java.util.Queue;
public class FigureControl extends AbstractControl implements GameEventListener {
// // // private static final Logger LOGGER = System.getLogger(FigureControl.class.getName());
private final Figure figure;
private final Node spatial;
private final MonopolyApp app;
private Queue<Vector3f> path; // Path to follow
private Vector3f currentTarget;
private float animationTime = 0f; // Time elapsed for the current movement
private final float durationPerField = 0.5f; // Time to move between fields
private float delayTime = 3f; // Verzögerung in Sekunden
private float delayElapsed = 0f; // Zeit, die seit dem Start der Verzögerung vergangen ist
public FigureControl(Node spatial, Figure figure, MonopolyApp app) {
super();
this.figure = figure;
this.spatial = spatial;
this.app = app;
this.path = new LinkedList<>();
app.getGameLogic().addListener(this);
}
@Override
protected void controlUpdate(float tpf) {
if (delayTime > 0) {
delayElapsed += tpf;
if (delayElapsed < delayTime) {
return; // Warte, bis die Verzögerung abgeschlossen ist
}
delayTime = 0; // Verzögerung abgeschlossen
}
if (currentTarget == null && !path.isEmpty()) {
// Hole das nächste Ziel aus dem Pfad
currentTarget = path.poll();
animationTime = 0f;
// Prüfe, ob eine Drehung erforderlich ist (Felder 0, 10, 20, 30)
int currentField = figure.getCurrentFieldID();
int nextField = nextField(currentField);
if ((nextField(currentField) == 10) ||
(nextField(currentField) == 20) ||
(nextField(currentField) == 30) ||
(nextField(currentField) == 0)) {
Quaternion rotation = spatial.getLocalRotation();
Quaternion turnRight = new Quaternion().fromAngleAxis(-FastMath.HALF_PI, Vector3f.UNIT_Y);
spatial.setLocalRotation(rotation.mult(turnRight));
}
}
if (currentTarget != null) {
animationTime += tpf;
Vector3f startPosition = spatial.getLocalTranslation();
Vector3f interpolatedPosition = startPosition.interpolateLocal(
currentTarget,
animationTime / durationPerField
);
// Hüpfeffekt hinzufügen
float hopHeight = 0.5f * FastMath.sin(FastMath.PI * (animationTime / durationPerField));
interpolatedPosition.setY(hopHeight );
spatial.setLocalTranslation(interpolatedPosition);
// Ziel erreicht
if (animationTime >= durationPerField) {
spatial.setLocalTranslation(currentTarget);
figure.moveTo(currentTarget); // Synchronisiere die interne Position
currentTarget = null; // Setze Ziel zurück
}
}
}
private int nextField(int currentField) {
return (currentField + 1) % 40;
}
@Override
protected void controlRender(RenderManager rm, ViewPort vp) {
// No rendering logic required
}
public void setPath(int startField, int endField) {
// LOGGER.log(Level.TRACE, "setPath called with startField: {0} to endField {1}", startField, endField);
path.clear();
for (int fieldId = startField; fieldId != endField; fieldId = (fieldId + 1) % 40) {
Vector3f position = figure.calculateFieldPosition(fieldId);
// LOGGER.log(Level.DEBUG, "Adding postition to path: {0}", position);
path.add(position);
}
Vector3f finalPosition = figure.calculateFieldPosition(endField);
path.add(finalPosition);
// LOGGER.log(Level.DEBUG, "Final position added to path: {0}", finalPosition);
// LOGGER.log(Level.TRACE, "Path size: {0}", path.size());
}
@Override
public void receivedEvent(UpdatePlayerView event) {
// LOGGER.log(Level.TRACE, "receivedEvent called with event: {0}", event);
int newPos = app.getGameLogic().getPlayerHandler().getPlayerById(figure.getId()).getFieldID();
int currentField = figure.getCurrentFieldID();
if (currentField == newPos) {
// LOGGER.log(Level.DEBUG, "No movement required. Current field: {0}, New field: {1}", currentField, newPos);
return;
}
// LOGGER.log(Level.DEBUG, "Movement required. Current field: {0}, New field: {1}", currentField, newPos);
setPath(currentField, newPos);
delayTime = 3f; // Verzögerung zurücksetzen
delayElapsed = 0f; // Timer zurücksetzen
}
}

View File

@@ -2,92 +2,38 @@ package pp.monopoly.client.gui;
import com.jme3.texture.Texture; import com.jme3.texture.Texture;
import com.simsilica.lemur.Button; import com.simsilica.lemur.Button;
import com.simsilica.lemur.Command;
import com.simsilica.lemur.component.QuadBackgroundComponent; import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.style.ElementId;
import pp.monopoly.client.MonopolyApp; import pp.monopoly.client.MonopolyApp;
import pp.monopoly.game.server.Player;
import pp.monopoly.game.server.PlayerColor;
import pp.monopoly.notification.Sound;
public class ImageButton extends Button { public class ImageButton extends Button {
private final MonopolyApp app; private final String file;
private final String functionality; private static MonopolyApp app;
private final PlayerColor playerColor;
public ImageButton(String functionality, MonopolyApp app) { public ImageButton( String s, String file, MonopolyApp app ) {
super("", "button-clear"); this(s, true, new ElementId(ELEMENT_ID), null, file, app);
this.app = app;
this.functionality = functionality;
this.playerColor = Player.getColor(app.getId());
updateButtonAppearance(ButtonState.ENABLED);
addButtonCommands();
} }
/** public ImageButton( String s, String style, String file, MonopolyApp app ) {
* Updates the button's appearance based on its state. this(s, true, new ElementId(ELEMENT_ID), style, file, app);
*
* @param state the current button state
*/
private void updateButtonAppearance(ButtonState state) {
setBackgroundTexture(state.name().toLowerCase());
} }
/** public ImageButton( String s, ElementId elementId, String file, MonopolyApp app ) {
* Adds button commands for state-specific actions like hover, press, enable, and disable. this(s, true, elementId, null, file, app);
*/
private void addButtonCommands() {
addCommands(ButtonAction.Enabled, source -> updateButtonAppearance(ButtonState.ENABLED));
addCommands(ButtonAction.Disabled, source -> updateButtonAppearance(ButtonState.DISABLED));
addCommands(ButtonAction.Hover, source -> {
if (isEnabled()) {
updateButtonAppearance(ButtonState.HOVER);
}
});
addCommands(ButtonAction.HighlightOff, source -> updateButtonAppearance(isEnabled() ? ButtonState.ENABLED : ButtonState.DISABLED));
addCommands(ButtonAction.Up, source -> updateButtonAppearance(isEnabled() ? ButtonState.ENABLED : ButtonState.DISABLED));
addCommands(ButtonAction.Down, source -> {
if (isEnabled()) {
app.getGameLogic().playSound(Sound.BUTTON);
}
});
} }
/** public ImageButton( String s, ElementId elementId, String style, String file, MonopolyApp app ) {
* Sets the background texture for the button based on the given state. this(s, true, elementId, style, file, app);
*
* @param state the button state (e.g., "enabled", "disabled", "hover")
*/
private void setBackgroundTexture(String state) {
String texturePath = buildTexturePath(state);
Texture texture = app.getAssetManager().loadTexture(texturePath);
setBackground(new QuadBackgroundComponent(texture));
} }
/** protected ImageButton( String s, boolean applyStyles, ElementId elementId, String style, String file, MonopolyApp app ) {
* Builds the file path for the button texture. super(s, false, elementId, style);
* this.file = file;
* @param state the button state (e.g., "enabled", "disabled", "hover") ImageButton.app = app;
* @return the full file path to the texture Texture backgroundImage = app.getAssetManager().loadTexture("Pictures/Buttons/"+file+".png");
*/ setBackground(new QuadBackgroundComponent(backgroundImage));
private String buildTexturePath(String state) {
return String.format("Pictures/Buttons/Button_%s_%s_%s.png", functionality, playerColor.getColorName(), state);
} }
/**
* Button states for handling appearance transitions.
*/
private enum ButtonState {
ENABLED, DISABLED, HOVER
}
public void addClickCommands( Command<? super Button> command ) {
super.addCommands(ButtonAction.Down, command);
}
@SuppressWarnings("unchecked") // because Java doesn't like var-arg generics
public void addClickCommands( Command<? super Button>... commands ) {
super.addCommands(ButtonAction.Down, commands);
}
} }

View File

@@ -79,9 +79,8 @@ public class LobbyMenu extends Dialog {
this.app = app; this.app = app;
GameMusic music = app.getStateManager().getState(GameMusic.class); GameMusic music = app.getStateManager().getState(GameMusic.class);
if (music != null && music.isEnabled()) { music.toggleMusic();
music.playSecondaryMusic();
}
playerInputField = new TextField("Spieler "+(app.getId()+1)); playerInputField = new TextField("Spieler "+(app.getId()+1));
// Hintergrundbild laden und hinzufügen // Hintergrundbild laden und hinzufügen
addBackgroundImage(); addBackgroundImage();
@@ -154,7 +153,6 @@ public class LobbyMenu extends Dialog {
figures.add("Katze"); figures.add("Katze");
figures.add("OOP"); figures.add("OOP");
figures.add("Handyholster"); figures.add("Handyholster");
figures.add("Panzer");
figureDropdown = new Selector<>(figures, "glass"); figureDropdown = new Selector<>(figures, "glass");
@@ -278,12 +276,6 @@ public class LobbyMenu extends Dialog {
new SettingsMenu(app).open(); new SettingsMenu(app).open();
} }
/**
* Updates the menu at regular intervals.
* Checks if the dropdown selection has been updated and invokes the selection change handler.
*
* @param tpf Time per frame, in seconds, since the last update.
*/
@Override @Override
public void update(float tpf) { public void update(float tpf) {
if (selectionRef.update()) { if (selectionRef.update()) {
@@ -291,27 +283,10 @@ public class LobbyMenu extends Dialog {
} }
} }
/**
* Closes the current menu and transitions music playback.
* Stops the secondary music (if playing) and resumes the main background music
* if music is enabled in the preferences. Ensures smooth transitions in audio.
*/
@Override
public void close() {
GameMusic music = app.getStateManager().getState(GameMusic.class);
if (music != null) {
music.stopSecondaryMusic();
if (music.isEnabled()) {
music.playMainMusic();
}
}
super.close();
}
/** /**
* Updates the selected figure based on the dropdown menu selection. * Updates the selected figure based on the dropdown menu selection.
* *
* @param selector the selected figure * @param selected the selected figure
*/ */
private void onDropdownSelectionChanged(Selector<String> selector) { private void onDropdownSelectionChanged(Selector<String> selector) {
app.getGameLogic().playSound(Sound.BUTTON); app.getGameLogic().playSound(Sound.BUTTON);
@@ -326,6 +301,7 @@ public class LobbyMenu extends Dialog {
figure = selector.getSelectedItem(); figure = selector.getSelectedItem();
break; break;
} }
System.out.println("FIGUR:::::"+figure);
} }
/** /**

View File

@@ -51,17 +51,7 @@ public class SettingsMenu extends Dialog {
private final SoundSlider soundSlider; private final SoundSlider soundSlider;
/** /**
* Checkbox for toggling sound effects. * Constructs the Menu dialog for the Battleship application.
*/
private final Checkbox soundCheckbox;
/**
* Checkbox for toggling background music.
*/
private final Checkbox musicCheckbox;
/**
* Constructs the Menu dialog for the Monopoly application.
* *
* @param app the MonopolyApp instance * @param app the MonopolyApp instance
*/ */
@@ -75,14 +65,10 @@ public class SettingsMenu extends Dialog {
addChild(soundSlider); addChild(soundSlider);
soundCheckbox = new Checkbox("Soundeffekte an / aus", new StateCheckboxModel(app, GameSound.class)); addChild(new Checkbox("Soundeffekte an / aus", new StateCheckboxModel(app, GameSound.class)));
addChild(soundCheckbox);
addChild(new Label("Hintergrund Musik", new ElementId("label"))); //NON-NLS addChild(new Label("Hintergrund Musik", new ElementId("label"))); //NON-NLS
addChild(new Checkbox("Musik an / aus", new StateCheckboxModel(app, GameMusic.class)));
musicCheckbox = new Checkbox("Musik an / aus", new StateCheckboxModel(app, GameMusic.class));
musicCheckbox.addClickCommands(s -> toggleMusicPreference());
addChild(musicCheckbox);
addChild(musicSlider); addChild(musicSlider);
@@ -98,42 +84,16 @@ public class SettingsMenu extends Dialog {
} }
/** /**
* Toggles the music preference based on the state of the musicCheckbox. * Updates the state of the load and save buttons based on the game logic.
* Enables or disables background music and starts playback if enabled.
*/
private void toggleMusicPreference() {
boolean enabled = musicCheckbox.isChecked();
GameMusic gameMusic = app.getStateManager().getState(GameMusic.class);
if (gameMusic != null) {
gameMusic.setEnabled(enabled);
if (enabled) {
gameMusic.playMainMusic();
}
}
}
/**
* Updates the state of the music checkbox to match the current preferences.
* This ensures the checkbox reflects the actual enabled/disabled state of the music.
*/ */
@Override @Override
public void update() { public void update() {
GameMusic gameMusic = app.getStateManager().getState(GameMusic.class);
if (gameMusic != null) {
musicCheckbox.setChecked(gameMusic.isEnabled());
}
} }
/**
* Updates UI elements such as sliders and synchronizes the state of the settings menu.
*
* @param delta the time in seconds since the last update
*/
@Override @Override
public void update(float delta) { public void update(float delta) {
musicSlider.update(); musicSlider.update();
soundSlider.update(); soundSlider.update();
update();
} }
/** /**

View File

@@ -65,7 +65,7 @@ public class StartMenu extends Dialog {
app.getGuiNode().attachChild(centerMenu); app.getGuiNode().attachChild(centerMenu);
// Load the Monopoly logo as a texture // Load the Monopoly logo as a texture
Texture logoTexture = app.getAssetManager().loadTexture("Pictures/logo-monopolyw.png"); Texture logoTexture = app.getAssetManager().loadTexture("Pictures/logo-monopoly.png");
// Create a container for the logo // Create a container for the logo
Container logoContainer = new Container(); Container logoContainer = new Container();
@@ -91,8 +91,8 @@ public class StartMenu extends Dialog {
QuadBackgroundComponent unibwBackground = new QuadBackgroundComponent(unibwTexture); QuadBackgroundComponent unibwBackground = new QuadBackgroundComponent(unibwTexture);
unibwContainer.setBackground(unibwBackground); unibwContainer.setBackground(unibwBackground);
float unibwWidth = 662; float unibwWidth = 512;
float unibwHeight = 180; float unibwHeight = 128;
unibwContainer.setPreferredSize(new Vector3f(unibwWidth, unibwHeight, 0)); unibwContainer.setPreferredSize(new Vector3f(unibwWidth, unibwHeight, 0));
unibwContainer.setLocalTranslation(new Vector3f( unibwContainer.setLocalTranslation(new Vector3f(

View File

@@ -0,0 +1,565 @@
package pp.monopoly.client.gui;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import com.jme3.light.AmbientLight;
import com.jme3.light.DirectionalLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.control.AbstractControl;
import com.jme3.texture.Texture;
import pp.monopoly.client.MonopolyApp;
import pp.monopoly.client.gui.popups.AcceptTrade;
import pp.monopoly.client.gui.popups.BuildingPropertyCard;
import pp.monopoly.client.gui.popups.ConfirmTrade;
import pp.monopoly.client.gui.popups.EventCardPopup;
import pp.monopoly.client.gui.popups.FoodFieldCard;
import pp.monopoly.client.gui.popups.GateFieldCard;
import pp.monopoly.client.gui.popups.Gulag;
import pp.monopoly.client.gui.popups.GulagInfo;
import pp.monopoly.client.gui.popups.LooserPopUp;
import pp.monopoly.client.gui.popups.NoMoneyWarning;
import pp.monopoly.client.gui.popups.ReceivedRent;
import pp.monopoly.client.gui.popups.RejectTrade;
import pp.monopoly.client.gui.popups.Rent;
import pp.monopoly.client.gui.popups.TimeOut;
import pp.monopoly.client.gui.popups.WinnerPopUp;
import pp.monopoly.game.server.Player;
import pp.monopoly.game.server.PlayerHandler;
import pp.monopoly.message.server.NotificationMessage;
import pp.monopoly.message.server.TradeReply;
import pp.monopoly.model.fields.BuildingProperty;
import pp.monopoly.model.fields.FoodField;
import pp.monopoly.model.fields.GateField;
import pp.monopoly.notification.EventCardEvent;
import pp.monopoly.notification.GameEventListener;
import pp.monopoly.notification.PopUpEvent;
import pp.monopoly.notification.UpdatePlayerView;
/**
* TestWorld zeigt eine einfache Szene mit Spielfeld und Spielfiguren.
*/
public class TestWorld implements GameEventListener {
private final MonopolyApp app;
private PlayerHandler playerHandler;
private CameraController cameraController;
private Toolbar toolbar;
private List<String> existingHouses = new ArrayList<>();
/**
* Konstruktor für die TestWorld.
*
* @param app Die Hauptanwendung
*/
public TestWorld(MonopolyApp app) {
this.app = app;
this.playerHandler = app.getGameLogic().getPlayerHandler();
app.getGameLogic().addListener(this);
cameraController = new CameraController(app.getCamera());
}
/**
* Initialisiert die Szene mit Spielfeld und Figuren.
*/
public void initializeScene() {
// Entferne bestehende Inhalte
app.getGuiNode().detachAllChildren();
app.getRootNode().detachAllChildren();
System.out.println("Szene initialisiert.");
//Füge Inhalte ein
setSkyColor();
createBoard();
addLighting();
createPlayerFigures();
toolbar = new Toolbar(app);
toolbar.open();
}
/**
* Setzt die Hintergrundfarbe der Szene auf hellblau.
*/
private void setSkyColor() {
app.getViewPort().setBackgroundColor(new com.jme3.math.ColorRGBA(0.5f, 0.7f, 1.0f, 1.0f));
}
/**
* Erstellt das Spielfeld und fügt es zur Szene hinzu.
*/
private void createBoard() {
try {
com.jme3.scene.shape.Box box = new com.jme3.scene.shape.Box(10, 0.1f, 10);
com.jme3.scene.Geometry geom = new com.jme3.scene.Geometry("Board", box);
Material mat = new Material(app.getAssetManager(), "Common/MatDefs/Light/Lighting.j3md");
Texture texture = app.getAssetManager().loadTexture("Pictures/board2.png");
mat.setTexture("DiffuseMap", texture);
geom.setMaterial(mat);
geom.setLocalTranslation(0, -0.1f, 0);
com.jme3.math.Quaternion rotation = new com.jme3.math.Quaternion();
rotation.fromAngleAxis(FastMath.HALF_PI, com.jme3.math.Vector3f.UNIT_Y);
geom.setLocalRotation(rotation);
app.getRootNode().attachChild(geom);
} catch (Exception e) {
System.err.println("Fehler beim Erstellen des Spielfelds: " + e.getMessage());
}
}
private void addLighting() {
// Direktionales Licht
DirectionalLight sun = new DirectionalLight();
sun.setColor(ColorRGBA.White);
sun.setDirection(new Vector3f(-0.5f, -0.7f, -1.0f).normalizeLocal());
app.getRootNode().addLight(sun);
// Umgebungslicht
AmbientLight ambient = new AmbientLight();
ambient.setColor(new ColorRGBA(0.6f, 0.6f, 0.6f, 1.0f));
app.getRootNode().addLight(ambient);
}
private com.jme3.math.Quaternion calculateRotationForField(int fieldID) {
com.jme3.math.Quaternion rotation = new com.jme3.math.Quaternion();
// Berechne die Rotation basierend auf der Feld-ID
if (fieldID >= 0 && fieldID <= 9) {
// Untere Seite (0-9)
rotation.fromAngleAxis(0, Vector3f.UNIT_Y); // Richtung: nach oben
} else if (fieldID >= 10 && fieldID <= 19) {
// Rechte Seite (10-19)
rotation.fromAngleAxis(FastMath.HALF_PI, Vector3f.UNIT_Y); // Richtung: nach links
} else if (fieldID >= 20 && fieldID <= 29) {
// Obere Seite (20-29)
rotation.fromAngleAxis(FastMath.PI, Vector3f.UNIT_Y); // Richtung: nach unten
} else if (fieldID >= 30 && fieldID <= 39) {
// Linke Seite (30-39)
rotation.fromAngleAxis(3 * FastMath.HALF_PI, Vector3f.UNIT_Y); // Richtung: nach rechts
}
// Korrigiere die Richtung für die Quadranten 1019 und 3039 (gegenüberliegende Richtung)
if ((fieldID >= 10 && fieldID <= 19) || (fieldID >= 30 && fieldID <= 39)) {
com.jme3.math.Quaternion oppositeDirection = new com.jme3.math.Quaternion();
oppositeDirection.fromAngleAxis(FastMath.PI, Vector3f.UNIT_Y); // 180° drehen
rotation = rotation.multLocal(oppositeDirection);
}
// Füge zusätzliche 90° nach links hinzu
com.jme3.math.Quaternion leftTurn = new com.jme3.math.Quaternion();
leftTurn.fromAngleAxis(FastMath.HALF_PI, Vector3f.UNIT_Y); // 90° nach links
rotation = rotation.multLocal(leftTurn);
return rotation;
}
/**
* Erstellt die Spielfiguren basierend auf der bereits bekannten Spielerliste.
*/
private void createPlayerFigures() {
for (Player player : playerHandler.getPlayers()) {
try {
// Lade das Modell
com.jme3.scene.Spatial model = app.getAssetManager().loadModel(
"models/" + "Spielfiguren/" + player.getFigure().getType() + "/" + player.getFigure().getType() + ".j3o");
// Skaliere und positioniere das Modell
model.setLocalScale(0.5f);
Vector3f startPosition = calculateFieldPosition(player.getFieldID(), player.getId());
model.setLocalTranslation(startPosition);
// Setze die Rotation basierend auf der Feld-ID
model.setLocalRotation(calculateRotationForField(player.getFieldID()));
model.setName("PlayerFigure_" + player.getId());
// Füge das Modell zur Szene hinzu
app.getRootNode().attachChild(model);
} catch (Exception e) {
System.err.println("Fehler beim Laden des Modells für Spieler " + player.getId() + ": " + e.getMessage());
}
}
}
private Vector3f calculateFieldPosition(int fieldID, int playerIndex) {
float offset = 0.1f;
float baseX = 0.0f;
float baseZ = 0.0f;
switch (fieldID) {
case 0: baseX = -9.1f; baseZ = -9.1f; break;
case 1: baseX = -6.5f; baseZ = -9.1f; break;
case 2: baseX = -4.9f; baseZ = -9.1f; break;
case 3: baseX = -3.3f; baseZ = -9.1f; break;
case 4: baseX = -1.6f; baseZ = -9.1f; break;
case 5: baseX = 0.0f; baseZ = -9.1f; break;
case 6: baseX = 1.6f; baseZ = -9.1f; break;
case 7: baseX = 3.3f; baseZ = -9.1f; break;
case 8: baseX = 4.9f; baseZ = -9.1f; break;
case 9: baseX = 6.5f; baseZ = -9.1f; break;
case 10: baseX = 9.1f; baseZ = -9.1f; break;
case 11: baseX = 9.1f; baseZ = -6.5f; break;
case 12: baseX = 9.1f; baseZ = -4.9f; break;
case 13: baseX = 9.1f; baseZ = -3.3f; break;
case 14: baseX = 9.1f; baseZ = -1.6f; break;
case 15: baseX = 9.1f; baseZ = 0.0f; break;
case 16: baseX = 9.1f; baseZ = 1.6f; break;
case 17: baseX = 9.1f; baseZ = 3.3f; break;
case 18: baseX = 9.1f; baseZ = 4.9f; break;
case 19: baseX = 9.1f; baseZ = 6.5f; break;
case 20: baseX = 9.1f; baseZ = 9.1f; break;
case 21: baseX = 6.5f; baseZ = 9.1f; break;
case 22: baseX = 4.9f; baseZ = 9.1f; break;
case 23: baseX = 3.3f; baseZ = 9.1f; break;
case 24: baseX = 1.6f; baseZ = 9.1f; break;
case 25: baseX = 0.0f; baseZ = 9.1f; break;
case 26: baseX = -1.6f; baseZ = 9.1f; break;
case 27: baseX = -3.3f; baseZ = 9.1f; break;
case 28: baseX = -4.9f; baseZ = 9.1f; break;
case 29: baseX = -6.5f; baseZ = 9.1f; break;
case 30: baseX = -9.1f; baseZ = 9.1f; break;
case 31: baseX = -9.1f; baseZ = 6.5f; break;
case 32: baseX = -9.1f; baseZ = 4.9f; break;
case 33: baseX = -9.1f; baseZ = 3.3f; break;
case 34: baseX = -9.1f; baseZ = 1.6f; break;
case 35: baseX = -9.1f; baseZ = 0.0f; break;
case 36: baseX = -9.1f; baseZ = -1.6f; break;
case 37: baseX = -9.1f; baseZ = -3.3f; break;
case 38: baseX = -9.1f; baseZ = -4.9f; break;
case 39: baseX = -9.1f; baseZ = -6.5f; break;
default: throw new IllegalArgumentException("Ungültige Feld-ID: " + fieldID);
}
float xOffset = (playerIndex % 2) * offset;
float zOffset = (playerIndex / 2) * offset;
return new Vector3f(baseX + xOffset, 0, baseZ + zOffset);
}
private void movePlayerFigure(Player player) {
int playerIndexOnField = calculatePlayerIndexOnField(player.getFieldID(), player.getId());
String figureName = "PlayerFigure_" + player.getId();
com.jme3.scene.Spatial figure = app.getRootNode().getChild(figureName);
if (figure != null) {
// Füge einen Delay hinzu (z.B. 3 Sekunden)
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
app.enqueue(() -> {
// Setze die Position
Vector3f targetPosition = calculateFieldPosition(player.getFieldID(), player.getId());
figure.setLocalTranslation(targetPosition);
// Aktualisiere die Rotation basierend auf der Feld-ID
figure.setLocalRotation(calculateRotationForField(player.getFieldID()));
});
}
}, 3000); // 3000 Millisekunden Delay
} else {
System.err.println("Figur für Spieler " + player.getId() + " nicht gefunden.");
}
}
private int getFieldIDFromPosition(Vector3f position) {
for (int fieldID = 0; fieldID < 40; fieldID++) {
Vector3f fieldPosition = calculateFieldPosition(fieldID, 0);
if (fieldPosition.distance(position) < 0.5f) { // Toleranz für Positionserkennung
return fieldID;
}
}
throw new IllegalArgumentException("Position entspricht keinem gültigen Feld: " + position);
}
/**
* Berechnet den Eckpunkt basierend auf Start- und Zielposition.
*
* @param startPosition Die Startposition der Figur.
* @param targetPosition Die Zielposition der Figur.
* @return Die Position der Ecke, die passiert werden muss.
*/
private Vector3f calculateCornerPosition(Vector3f startPosition, Vector3f targetPosition) {
// Ziel: Immer entlang der Spielfeldkante navigieren
float deltaX = targetPosition.x - startPosition.x;
float deltaZ = targetPosition.z - startPosition.z;
// Überprüfen, ob Bewegung entlang X oder Z-Koordinate zuerst erfolgen soll
if (deltaX != 0 && deltaZ != 0) {
if (Math.abs(deltaX) > Math.abs(deltaZ)) {
// Bewegung entlang X zuerst
return new Vector3f(targetPosition.x, 0, startPosition.z);
} else {
// Bewegung entlang Z zuerst
return new Vector3f(startPosition.x, 0, targetPosition.z);
}
} else {
// Bewegung ist bereits entlang einer Achse (keine Ecke erforderlich)
return targetPosition;
}
}
private List<Vector3f> calculatePath(int startFieldID, int targetFieldID, int playerIndex) {
List<Vector3f> pathPoints = new ArrayList<>();
// Bewegung im Uhrzeigersinn
if (startFieldID < targetFieldID) {
for (int i = startFieldID; i <= targetFieldID; i++) {
// Füge Ecken hinzu, falls sie überschritten werden
if (i == 10 || i == 20 || i == 30 || i == 0) {
pathPoints.add(calculateFieldPosition(i, playerIndex));
}
}
} else {
// Bewegung über das Ende des Spielfelds hinaus (z.B. von 39 zu 5)
for (int i = startFieldID; i < 40; i++) {
if (i == 10 || i == 20 || i == 30 || i == 0) {
pathPoints.add(calculateFieldPosition(i, playerIndex));
}
}
for (int i = 0; i <= targetFieldID; i++) {
if (i == 10 || i == 20 || i == 30 || i == 0) {
pathPoints.add(calculateFieldPosition(i, playerIndex));
}
}
}
// Füge das Ziel hinzu
pathPoints.add(calculateFieldPosition(targetFieldID, playerIndex));
return pathPoints;
}
private int calculatePlayerIndexOnField(int fieldID, int playerID) {
List<Player> playersOnField = playerHandler.getPlayers().stream()
.filter(p -> p.getFieldID() == fieldID)
.toList();
for (int i = 0; i < playersOnField.size(); i++) {
if (playersOnField.get(i).getId() == playerID) {
return i;
}
}
return 0;
}
private void animateMovementAlongPath(com.jme3.scene.Spatial figure, List<Vector3f> pathPoints) {
float animationDurationPerSegment = 2.5f; // Langsamere Animation (2.5 Sekunden pro Segment)
int[] currentSegment = {0};
app.enqueue(() -> {
figure.addControl(new AbstractControl() {
private float elapsedTime = 0.0f;
@Override
protected void controlUpdate(float tpf) {
if (currentSegment[0] >= pathPoints.size() - 1) {
this.setEnabled(false); // Animation abgeschlossen
return;
}
elapsedTime += tpf;
float progress = Math.min(elapsedTime / animationDurationPerSegment, 1.0f);
Vector3f start = pathPoints.get(currentSegment[0]);
Vector3f end = pathPoints.get(currentSegment[0] + 1);
Vector3f interpolatedPosition = start.interpolateLocal(end, progress);
figure.setLocalTranslation(interpolatedPosition);
if (progress >= 1.0f) {
elapsedTime = 0.0f;
currentSegment[0]++;
}
}
@Override
protected void controlRender(RenderManager rm, ViewPort vp) {
// Nicht benötigt
}
});
});
}
@Override
public void receivedEvent(PopUpEvent event) {
if (event.msg().equals("Buy")) {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
app.enqueue(() -> {
int field = app.getGameLogic().getPlayerHandler().getPlayerById(app.getId()).getFieldID();
Object fieldObject = app.getGameLogic().getBoardManager().getFieldAtIndex(field);
if (fieldObject instanceof BuildingProperty) {
new BuildingPropertyCard(app).open();
} else if (fieldObject instanceof GateField) {
new GateFieldCard(app).open();
} else if (fieldObject instanceof FoodField) {
new FoodFieldCard(app).open();
}
});
}
}, 2500);
} else if (event.msg().equals("Winner")) {
new WinnerPopUp(app).open();
} else if (event.msg().equals("Looser")) {
new LooserPopUp(app).open();
} else if (event.msg().equals("timeout")) {
new TimeOut(app).open();
} else if (event.msg().equals("tradeRequest")) {
new ConfirmTrade(app).open();
} else if (event.msg().equals("goingToJail")) {
new Gulag(app).open();
} else if (event.msg().equals("NoMoneyWarning")) {
new NoMoneyWarning(app).open();
} else if(event.msg().equals("rent")) {
new Rent(app, ( (NotificationMessage) event.message()).getRentOwner(), ( (NotificationMessage) event.message()).getRentAmount() ).open();
} else if (event.msg().equals("jailtryagain")) {
new GulagInfo(app, 1).open();
} else if (event.msg().equals("jailpay")) {
new GulagInfo(app, 3).open();
} else if (event.msg().equals("tradepos")) {
new AcceptTrade(app, (TradeReply) event.message()).open();
} else if (event.msg().equals("tradeneg")) {
new RejectTrade(app, (TradeReply) event.message()).open();
} else if (event.msg().equals("ReceivedRent")) {
new ReceivedRent(app, ( (NotificationMessage) event.message()).getRentOwner(), ( (NotificationMessage) event.message()).getRentAmount() ).open();
}
}
private Vector3f calculateBuildingPosition(int fieldID) {
float baseX = 0.0f;
float baseZ = 0.0f;
switch (fieldID) {
case 0: baseX = -8.4f; baseZ = -7.7f; break;
case 1: baseX = -6.3f; baseZ = -7.7f; break;
case 2: baseX = -4.7f; baseZ = -7.7f; break;
case 3: baseX = -3.1f; baseZ = -7.7f; break;
case 4: baseX = -1.4f; baseZ = -7.7f; break;
case 5: baseX = 0.2f; baseZ = -7.7f; break;
case 6: baseX = 1.8f; baseZ = -7.7f; break;
case 7: baseX = 3.5f; baseZ = -7.7f; break;
case 8: baseX = 5.1f; baseZ = -7.7f; break;
case 9: baseX = 6.7f; baseZ = -7.7f; break;
case 10: baseX = 8.2f; baseZ = -7.7f; break;
case 11: baseX = 8.2f; baseZ = -6.5f; break; //passt
case 12: baseX = 8.2f; baseZ = -4.9f; break; //passt
case 13: baseX = 8.2f; baseZ = -3.3f; break; //passt
case 14: baseX = 8.2f; baseZ = -1.6f; break; //passt
case 15: baseX = 8.2f; baseZ = 0.0f; break; //passt
case 16: baseX = 8.2f; baseZ = 1.6f; break; //passt
case 17: baseX = 8.2f; baseZ = 3.3f; break; //passt
case 18: baseX = 8.2f; baseZ = 4.9f; break; //passt
case 19: baseX = 8.2f; baseZ = 6.5f; break; //passt
case 20: baseX = 8.2f; baseZ = 7.7f; break;
case 21: baseX = 6.5f; baseZ = 7.7f; break;
case 22: baseX = 4.9f; baseZ = 7.7f; break;
case 23: baseX = 3.3f; baseZ = 7.7f; break;
case 24: baseX = 1.6f; baseZ = 7.7f; break;
case 25: baseX = 0.0f; baseZ = 7.7f; break;
case 26: baseX = -1.6f; baseZ = 7.7f; break;
case 27: baseX = -3.3f; baseZ = 7.7f; break;
case 28: baseX = -4.9f; baseZ = 7.7f; break;
case 29: baseX = -6.5f; baseZ = 7.7f; break;
case 30: baseX = -7.2f; baseZ = 7.7f; break;
case 31: baseX = -7.2f; baseZ = 6.5f; break;
case 32: baseX = -7.2f; baseZ = 4.9f; break;
case 33: baseX = -7.2f; baseZ = 3.3f; break;
case 34: baseX = -7.2f; baseZ = 1.6f; break;
case 35: baseX = -7.2f; baseZ = 0.0f; break;
case 36: baseX = -7.2f; baseZ = -1.6f; break;
case 37: baseX = -7.2f; baseZ = -3.3f; break;
case 38: baseX = -7.2f; baseZ = -4.9f; break;
case 39: baseX = -7.2f; baseZ = -6.5f; break;
default: throw new IllegalArgumentException("Ungültige Feld-ID: " + fieldID);
}
return new Vector3f(baseX, 0, baseZ);
}
private void updateHousesOnBoard() {
app.enqueue(() -> {
List<BuildingProperty> propertiesWithBuildings = app.getGameLogic().getBoardManager().getPropertiesWithBuildings();
for (BuildingProperty property : propertiesWithBuildings) {
int houseCount = property.getHouses();
int hotelCount = property.getHotel();
String uniqueIdentifier = "Building_" + property.getId() + "_" + (hotelCount > 0 ? "Hotel" : houseCount);
if (existingHouses.contains(uniqueIdentifier)) continue;
try {
String modelPath = hotelCount > 0
? "models/Hotel/Hotel.j3o"
: "models/Haus/" + houseCount + "Haus.j3o";
com.jme3.scene.Spatial buildingModel = app.getAssetManager().loadModel(modelPath);
Material mat = new Material(app.getAssetManager(), "Common/MatDefs/Light/Lighting.j3md");
buildingModel.setMaterial(mat);
buildingModel.setLocalScale(0.5f);
Vector3f position = calculateBuildingPosition(property.getId()).add(0, 0.5f, 0);
buildingModel.setLocalTranslation(position);
com.jme3.math.Quaternion rotation = new com.jme3.math.Quaternion();
if (property.getId() >= 1 && property.getId() <= 10) {
rotation.fromAngleAxis(FastMath.HALF_PI, Vector3f.UNIT_Y);
} else if (property.getId() >= 21 && property.getId() <= 30) {
rotation.fromAngleAxis(3 * FastMath.HALF_PI, Vector3f.UNIT_Y);
} else if (property.getId() >= 31 && property.getId() <= 39) {
rotation.fromAngleAxis(FastMath.PI, Vector3f.UNIT_Y);
}
buildingModel.setLocalRotation(rotation);
buildingModel.setName(uniqueIdentifier);
app.getRootNode().attachChild(buildingModel);
existingHouses.add(uniqueIdentifier);
} catch (Exception e) {
System.err.println("Fehler beim Hinzufügen eines Gebäudes: " + e.getMessage());
}
}
});
}
@Override
public void receivedEvent(EventCardEvent event) {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
app.enqueue(() -> new EventCardPopup(app, event.description()).open());
}
}, 2500);
}
@Override
public void receivedEvent(UpdatePlayerView event) {
this.playerHandler = app.getGameLogic().getPlayerHandler();
for (Player player : playerHandler.getPlayers()) {
movePlayerFigure(player);
}
updateHousesOnBoard();
}
}

View File

@@ -1,11 +1,8 @@
package pp.monopoly.client.gui; package pp.monopoly.client.gui;
import com.jme3.input.event.MouseButtonEvent;
import com.jme3.input.event.MouseMotionEvent;
import com.jme3.math.ColorRGBA; import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector2f; import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f; import com.jme3.math.Vector3f;
import com.jme3.scene.Spatial;
import com.jme3.texture.Texture; import com.jme3.texture.Texture;
import com.simsilica.lemur.Axis; import com.simsilica.lemur.Axis;
import com.simsilica.lemur.Button; import com.simsilica.lemur.Button;
@@ -16,11 +13,9 @@ import com.simsilica.lemur.VAlignment;
import com.simsilica.lemur.component.IconComponent; import com.simsilica.lemur.component.IconComponent;
import com.simsilica.lemur.component.QuadBackgroundComponent; import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.component.SpringGridLayout; import com.simsilica.lemur.component.SpringGridLayout;
import com.simsilica.lemur.event.MouseEventControl;
import com.simsilica.lemur.event.MouseListener;
import com.simsilica.lemur.style.ElementId; import com.simsilica.lemur.style.ElementId;
import pp.dialog.Dialog; import pp.dialog.Dialog;
import pp.monopoly.client.BoardAppState;
import pp.monopoly.client.MonopolyApp; import pp.monopoly.client.MonopolyApp;
import pp.monopoly.client.gui.popups.Bankrupt; import pp.monopoly.client.gui.popups.Bankrupt;
import pp.monopoly.game.server.Player; import pp.monopoly.game.server.Player;
@@ -35,41 +30,88 @@ import pp.monopoly.notification.UpdatePlayerView;
/** /**
* Represents the toolbar interface in the Monopoly application. * Represents the toolbar interface in the Monopoly application.
* Provides game controls, player information, and event handling. * <p>
* This class provides game controls, player information, and event handling
* for actions such as dice rolling, trading, and ending turns.
* Implements {@link GameEventListener} to respond to game events.
* </p>
*/ */
public class Toolbar extends Dialog implements GameEventListener { public class Toolbar extends Dialog implements GameEventListener {
/** The Monopoly application instance*/ /**
* Reference to the Monopoly application instance.
*/
private final MonopolyApp app; private final MonopolyApp app;
/** The container representing the toolbar interface */
/**
* The main container for the toolbar interface.
*/
private final Container toolbarContainer; private final Container toolbarContainer;
/** The container representing the player overview information */
/**
* Container for displaying an overview of other players.
*/
private Container overviewContainer; private Container overviewContainer;
/** The container representing the player account information */
/**
* Container for displaying account-related information.
*/
private Container accountContainer; private Container accountContainer;
/** The player handler instance */
/**
* Handles player-related data and actions.
*/
private PlayerHandler playerHandler; private PlayerHandler playerHandler;
/** The label representing the left dice */
/**
* Label for the first dice display.
*/
private Label imageLabel; private Label imageLabel;
/** The label representing the right dice */
/**
* Label for the second dice display.
*/
private Label imageLabel2; private Label imageLabel2;
/** The flag to check if the dice can be rolled */
private boolean canRollDice = false;
/** The trade button */ /**
* Button for rolling the dice.
*/
private Button diceButton;
/**
* Button for initiating trades.
*/
private Button tradeButton; private Button tradeButton;
/** The property menu button */
/**
* Button for accessing the property menu.
*/
private Button propertyMenuButton; private Button propertyMenuButton;
/** The end turn button */
/**
* Button for ending the player's turn.
*/
private Button endTurnButton; private Button endTurnButton;
/** The latest incoming Dice Roll Event */
/**
* Stores the most recent dice roll event.
*/
private DiceRollEvent latestDiceRollEvent = null; private DiceRollEvent latestDiceRollEvent = null;
/** The flag to check if the bankrupt pop up is already shown */
/**Indicates if the bankrupt PopUp has already been shown */
private boolean bankruptPopUp = false; private boolean bankruptPopUp = false;
/** /**
* Constructs a new {@code Toolbar} for the given {@code MonopolyApp}. * Constructs the toolbar for the Monopoly application.
* <p>
* Initializes the toolbar interface, adds event listeners, and sets up
* the GUI elements such as dice, buttons, and player information displays.
* </p>
* *
* @param app The {@code MonopolyApp} instance to create the toolbar for. * @param app the Monopoly application instance
*/ */
public Toolbar(MonopolyApp app) { public Toolbar(MonopolyApp app) {
super(app.getDialogManager()); super(app.getDialogManager());
@@ -78,200 +120,111 @@ public class Toolbar extends Dialog implements GameEventListener {
app.getGameLogic().addListener(this); app.getGameLogic().addListener(this);
this.playerHandler = app.getGameLogic().getPlayerHandler(); this.playerHandler = app.getGameLogic().getPlayerHandler();
toolbarContainer = setupToolbar(); toolbarContainer = createToolbarContainer();
app.getGuiNode().attachChild(toolbarContainer); app.getGuiNode().attachChild(toolbarContainer);
endTurnButton.setEnabled(false);
} }
/** private Container createToolbarContainer() {
* Sets up the toolbar interface with the game controls, player information, and event handling.
*
* @return The container representing the toolbar interface.
*/
private Container setupToolbar() {
Container container = new Container(new SpringGridLayout(Axis.X, Axis.Y), "toolbar"); Container container = new Container(new SpringGridLayout(Axis.X, Axis.Y), "toolbar");
container.setLocalTranslation(0, 200, 0); container.setLocalTranslation(0, 200, 0);
container.setPreferredSize(new Vector3f(app.getCamera().getWidth(), 200, 0)); container.setPreferredSize(new Vector3f(app.getCamera().getWidth(), 200, 0));
Texture backgroundToolbar = app.getAssetManager().loadTexture("Pictures/toolbarbg.png"); Texture backgroundToolbar = app.getAssetManager().loadTexture("Pictures/toolbarbg.png");
QuadBackgroundComponent background = new QuadBackgroundComponent(backgroundToolbar); QuadBackgroundComponent background = new QuadBackgroundComponent(backgroundToolbar);
background.setMargin(0, 0); // Removes any internal margin
container.setBackground(background); container.setBackground(background);
setupBorders(container); // Spielerfarbe abrufen
setupSpacer(container); Player currentPlayer = playerHandler.getPlayerById(app.getId());
setupPlayerInfoSection(container); ColorRGBA playerColor = Player.getColor(currentPlayer.getId()).getColor();
setupSpacer(container);
setupDiceSection(container);
setupActionMenu(container);
return container; // Oberer Balken
} Container playerColorBar = new Container();
playerColorBar.setPreferredSize(new Vector3f(app.getCamera().getWidth(), 15, 0)); // Höhe des oberen Balkens
playerColorBar.setBackground(new QuadBackgroundComponent(playerColor));
playerColorBar.setLocalTranslation(0, 210, 3); // Position über der Toolbar
app.getGuiNode().attachChild(playerColorBar);
/** // unterer Balken
* Sets up the borders for the toolbar interface. Container playerColorBarbot = new Container();
* playerColorBarbot.setPreferredSize(new Vector3f(app.getCamera().getWidth(), 10, 0)); // Höhe des oberen Balkens
* @param container The container representing the toolbar interface. playerColorBarbot.setBackground(new QuadBackgroundComponent(playerColor));
*/ playerColorBarbot.setLocalTranslation(0, 10, 3); // Position über der Toolbar
private void setupBorders(Container container) { app.getGuiNode().attachChild(playerColorBarbot);
addBorder(0, 205, app.getCamera().getWidth(), 5, ColorRGBA.DarkGray); // Top
addBorder(0, 5, app.getCamera().getWidth(), 10, ColorRGBA.DarkGray); // Bottom
addBorder(0, 200, 8, 210, ColorRGBA.DarkGray); // Left
addBorder(app.getCamera().getWidth() - 5, 200, 8, 210, ColorRGBA.DarkGray); // Right
}
/**
* Adds a border to the toolbar interface with the specified dimensions and color.
*
* @param x The x-coordinate of the border.
* @param y The y-coordinate of the border.
* @param width The width of the border.
* @param height The height of the border.
* @param color The color of the border.
*/
private void addBorder(float x, float y, float width, float height, ColorRGBA color) {
Container border = new Container();
border.setPreferredSize(new Vector3f(width, height, 0));
border.setBackground(new QuadBackgroundComponent(color));
border.setLocalTranslation(x, y, 3);
app.getGuiNode().attachChild(border);
}
/** // Linker Balken
* Adds a spacer to the specified container. Container leftBar = new Container();
* leftBar.setPreferredSize(new Vector3f(10, 210, 0)); // Breite 10, Höhe 210
* @param container the container to which the spacer is added leftBar.setBackground(new QuadBackgroundComponent(playerColor));
*/ leftBar.setLocalTranslation(0, 200, 3); // Position am linken Rand
private void setupSpacer(Container container) { app.getGuiNode().attachChild(leftBar);
Container spacer = container.addChild(new Container());
spacer.setPreferredSize(new Vector3f(20, 10, 0));
spacer.setBackground(null);
}
/** // Rechter Balken
* Sets up the player information section of the toolbar interface. Container rightBar = new Container();
* rightBar.setPreferredSize(new Vector3f(10, 210, 0)); // Breite 10, Höhe 210
* @param parentContainer The container representing the toolbar interface. rightBar.setBackground(new QuadBackgroundComponent(playerColor));
*/ rightBar.setLocalTranslation(app.getCamera().getWidth() - 10, 200, 2); // Position am rechten Rand
private void setupPlayerInfoSection(Container parentContainer) { app.getGuiNode().attachChild(rightBar);
Container playerInfoSection = parentContainer.addChild(new Container(new SpringGridLayout(Axis.X, Axis.Y)));
playerInfoSection.setPreferredSize(new Vector3f(600, 300, 0)); // Adjust size for both containers
Texture backgroundTexture = app.getAssetManager().loadTexture("Pictures/"+ Player.getColor(app.getId()).getColorName()+ "Background.png"); // Übersicht und Konto
QuadBackgroundComponent background = new QuadBackgroundComponent(backgroundTexture); accountContainer = container.addChild(new Container());
playerInfoSection.setBackground(background); overviewContainer = container.addChild(new Container());
receivedEvent(new UpdatePlayerView()); // Initiale Aktualisierung
accountContainer = playerInfoSection.addChild(new Container()); // Würfel-Bereich
accountContainer.setPreferredSize(new Vector3f(300, 300, 0)); container.addChild(createDiceSection());
accountContainer.setBackground(null);
overviewContainer = playerInfoSection.addChild(new Container()); // Aktionsmenü
overviewContainer.setPreferredSize(new Vector3f(300, 300, 0));
overviewContainer.setBackground(null);
refreshPlayerView();
}
/**
* Sets up the dice section of the toolbar interface.
*
* @param container The container representing the toolbar interface.
*/
private void setupDiceSection(Container container) {
Container diceContainer = container.addChild(new Container(new SpringGridLayout(Axis.X, Axis.Y)));
diceContainer.addChild(createDiceDisplay());
diceContainer.setBackground(null);
}
/**
* Sets up the action menu of the toolbar interface.
*
* @param container The container representing the toolbar interface.
*/
private void setupActionMenu(Container container) {
Container menuContainer = container.addChild(new Container()); Container menuContainer = container.addChild(new Container());
menuContainer.addChild(createTradeButton()); menuContainer.addChild(createTradeButton());
menuContainer.addChild(createPropertyMenuButton()); menuContainer.addChild(createPropertyMenuButton());
menuContainer.addChild(createEndTurnButton()); menuContainer.addChild(createEndTurnButton());
menuContainer.setBackground(null); menuContainer.setBackground(null);
return container;
} }
/**
* Returns the color of the current player. private Container createDiceSection() {
* Container diceContainer = new Container(new SpringGridLayout(Axis.X, Axis.Y));
* @return The color of the current player. diceContainer.addChild(createDiceDisplay());
*/ diceContainer.setBackground(null);
private ColorRGBA getCurrentPlayerColor() {
Player currentPlayer = playerHandler.getPlayerById(app.getId()); diceButton = new Button("Würfeln", new ElementId("button-toolbar"));
return Player.getColor(currentPlayer.getId()).getColor(); diceButton.setPreferredSize(new Vector3f(200, 50, 0));
diceButton.addClickCommands(s -> ifTopDialog(() -> {
diceButton.setEnabled(false);
endTurnButton.setEnabled(true);
startDiceAnimation();
app.getGameLogic().send(new RollDice());
app.getGameLogic().playSound(Sound.BUTTON);
}));
diceContainer.addChild(diceButton);
return diceContainer;
} }
/**
* Creates the dice display section of the toolbar interface.
*
* @return The container representing the dice display section.
*/
private Container createDiceDisplay() { private Container createDiceDisplay() {
Container horizontalContainer = new Container(new SpringGridLayout(Axis.X, Axis.Y)); Container horizontalContainer = new Container(new SpringGridLayout(Axis.X, Axis.Y));
horizontalContainer.setPreferredSize(new Vector3f(200, 150, 0)); horizontalContainer.setPreferredSize(new Vector3f(200, 150, 0));
horizontalContainer.setBackground(null);
imageLabel = createDiceLabel("Pictures/dice/one.png"); imageLabel = createDiceLabel("Pictures/dice/one.png");
imageLabel2 = createDiceLabel("Pictures/dice/two.png"); imageLabel2 = createDiceLabel("Pictures/dice/two.png");
horizontalContainer.setBackground(null);
horizontalContainer.addChild(createDiceContainer(imageLabel)); horizontalContainer.addChild(createDiceContainer(imageLabel));
horizontalContainer.addChild(createDiceContainer(imageLabel2)); horizontalContainer.addChild(createDiceContainer(imageLabel2));
// Add mouse event control for click handling
MouseEventControl.addListenersToSpatial(horizontalContainer, new MouseListener() {
@Override
public void mouseButtonEvent(MouseButtonEvent event, Spatial target, Spatial capture) {
if (event.isPressed()) {
handleDiceRoll();
}
}
@Override
public void mouseEntered(MouseMotionEvent event, Spatial target, Spatial capture) {
// Do nothing
}
@Override
public void mouseExited(MouseMotionEvent event, Spatial target, Spatial capture) {
// Do nothing
}
@Override
public void mouseMoved(MouseMotionEvent event, Spatial target, Spatial capture) {
// Do nothing
}
});
return horizontalContainer; return horizontalContainer;
} }
/**
* Creates a dice label with the specified icon path.
*
* @param iconPath The path to the icon image.
* @return The label representing the dice.
*/
private Label createDiceLabel(String iconPath) { private Label createDiceLabel(String iconPath) {
Label label = new Label(""); Label label = new Label("");
IconComponent icon = new IconComponent(iconPath); IconComponent icon = new IconComponent(iconPath);
icon.setIconSize(new Vector2f(80, 80)); icon.setIconSize(new Vector2f(100, 100));
label.setIcon(icon); label.setIcon(icon);
return label; return label;
} }
/**
* Creates a dice container with the specified label.
*
* @param label The label representing the dice.
* @return The container representing the dice.
*/
private Container createDiceContainer(Label label) { private Container createDiceContainer(Label label) {
Container container = new Container(); Container container = new Container();
container.setBackground(null); container.setBackground(null);
@@ -280,120 +233,77 @@ public class Toolbar extends Dialog implements GameEventListener {
return container; return container;
} }
/**
* Handles the dice roll event.
*/
private void handleDiceRoll() {
ifTopDialog(() -> {
if (!canRollDice) return;
canRollDice = false;
if (endTurnButton != null) endTurnButton.setEnabled(true);
startDiceAnimation();
app.getGameLogic().send(new RollDice());
app.getGameLogic().playSound(Sound.BUTTON);
// Animation in BoardAppState starten
BoardAppState boardAppState = app.getStateManager().getState(BoardAppState.class);
if (boardAppState != null) {
boardAppState.onRollDicePressed(); // Animation starten
}
});
}
private Button createTradeButton() { private Button createTradeButton() {
String iconPath = "icons/icon-handeln.png";
// createActionButton(playerColor, "icons/icon-handeln.png", 100, () -> new ChoosePartner(app).open()); tradeButton = new Button("", new ElementId("button-toolbar"));
tradeButton = new ImageButton("generic", app);
tradeButton.setPreferredSize(new Vector3f(150, 50, 0)); tradeButton.setPreferredSize(new Vector3f(150, 50, 0));
IconComponent icon = new IconComponent(iconPath); String iconTradePath = "icons/icon-handeln.png";
icon.setHAlignment(HAlignment.Center); IconComponent iconTrade = new IconComponent(iconTradePath);
icon.setVAlignment(VAlignment.Center); iconTrade.setHAlignment(HAlignment.Center);
icon.setIconSize(new Vector2f(75 , 75)); iconTrade.setVAlignment(VAlignment.Center);
tradeButton.setIcon(icon); iconTrade.setIconSize(new Vector2f(100, 100));
tradeButton.addClickCommands(s -> ifTopDialog(() -> { tradeButton.setIcon(iconTrade);
tradeButton.setFontSize(40);
// Add click behavior
tradeButton.addClickCommands(source -> ifTopDialog(() -> {
app.getGameLogic().playSound(Sound.BUTTON);
new ChoosePartner(app).open(); new ChoosePartner(app).open();
})); }));
return tradeButton; return tradeButton;
} }
private Button createPropertyMenuButton() { private Button createPropertyMenuButton() {
propertyMenuButton = new Button("", new ElementId("button-toolbar"));
String iconPath = "icons/icon-gebaude.png";
propertyMenuButton = new ImageButton("generic", app);
propertyMenuButton.setPreferredSize(new Vector3f(150, 50, 0)); propertyMenuButton.setPreferredSize(new Vector3f(150, 50, 0));
IconComponent icon = new IconComponent(iconPath); String iconBuildingPath = "icons/icon-gebaude.png";
icon.setHAlignment(HAlignment.Center); IconComponent iconBuilding = new IconComponent(iconBuildingPath);
icon.setVAlignment(VAlignment.Center); iconBuilding.setHAlignment(HAlignment.Center);
icon.setIconSize(new Vector2f(50 , 50)); iconBuilding.setVAlignment(VAlignment.Center);
propertyMenuButton.setIcon(icon); iconBuilding.setIconSize(new Vector2f(75, 75));
propertyMenuButton.setIcon(iconBuilding);
propertyMenuButton.setFontSize(30);
propertyMenuButton.addClickCommands(s -> ifTopDialog(() -> { propertyMenuButton.addClickCommands(s -> ifTopDialog(() -> {
app.getGameLogic().playSound(Sound.BUTTON);
new BuildingAdminMenu(app).open(); new BuildingAdminMenu(app).open();
})); }));
return propertyMenuButton; return propertyMenuButton;
} }
private Button createEndTurnButton() { private Button createEndTurnButton() {
// return createActionButton(playerColor, "icons/icon-zugbeenden.png", 75, () -> handleEndTurn()); endTurnButton = new Button("", new ElementId("button-toolbar"));
endTurnButton.setFontSize(28);
String iconPath = "icons/icon-zugbeenden.png";
endTurnButton = new ImageButton("generic", app);
endTurnButton.setPreferredSize(new Vector3f(150, 50, 0)); endTurnButton.setPreferredSize(new Vector3f(150, 50, 0));
IconComponent icon = new IconComponent(iconPath); String iconEndTurnPath = "icons/icon-zugbeenden.png";
icon.setHAlignment(HAlignment.Center); IconComponent iconEndTurn = new IconComponent(iconEndTurnPath);
icon.setVAlignment(VAlignment.Center); iconEndTurn.setHAlignment(HAlignment.Center);
icon.setIconSize(new Vector2f(50 , 50)); iconEndTurn.setVAlignment(VAlignment.Center);
endTurnButton.setIcon(icon); iconEndTurn.setIconSize(new Vector2f(75, 75));
endTurnButton.setIcon(iconEndTurn);
endTurnButton.addClickCommands(s -> ifTopDialog(() -> { endTurnButton.addClickCommands(s -> ifTopDialog(() -> {
handleEndTurn(); app.getGameLogic().playSound(Sound.BUTTON);
if (app.getGameLogic().getPlayerHandler().getPlayerById(app.getId()).getAccountBalance() < 0 && !bankruptPopUp) {
new Bankrupt(app).open();
bankruptPopUp = true;
} else {
bankruptPopUp = false;
app.getGameLogic().send(new EndTurn());
receivedEvent(new ButtonStatusEvent(false));
}
})); }));
return endTurnButton; return endTurnButton;
} }
/**
* Creates a background with the specified color.
*
* @param color The color of the background.
* @return The background component.
*/
private QuadBackgroundComponent createButtonBackground(ColorRGBA color) {
QuadBackgroundComponent background = new QuadBackgroundComponent(color);
Texture gradient = app.getAssetManager().loadTexture("Textures/gradient.png");
if (gradient != null) background.setTexture(gradient);
return background;
}
/**
* Handles the end turn event.
*/
private void handleEndTurn() {
Player currentPlayer = playerHandler.getPlayerById(app.getId());
if (currentPlayer.getAccountBalance() < 0 && !bankruptPopUp) {
new Bankrupt(app).open();
bankruptPopUp = true;
} else {
bankruptPopUp = false;
app.getGameLogic().send(new EndTurn());
receivedEvent(new ButtonStatusEvent(false));
}
}
/**
* Starts the dice animation.
*/
private void startDiceAnimation() { private void startDiceAnimation() {
long startTime = System.currentTimeMillis(); long startTime = System.currentTimeMillis();
new Thread(() -> { new Thread(() -> {
try { try {
animateDice(startTime); animateDice(startTime);
@@ -401,42 +311,35 @@ public class Toolbar extends Dialog implements GameEventListener {
showFinalDiceResult(latestDiceRollEvent); showFinalDiceResult(latestDiceRollEvent);
} }
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); System.err.println("Dice animation interrupted: " + e.getMessage());
} }
}).start(); }).start();
} }
/** /**
* Animates the dice roll. * Animates the dice roll by cycling through dice images.
*
* @param startTime The start time of the animation.
* @throws InterruptedException If the animation is interrupted.
*/ */
private void animateDice(long startTime) throws InterruptedException { private void animateDice(long startTime) throws InterruptedException {
int[] currentFace = {1}; int[] currentFace = {1};
while (System.currentTimeMillis() - startTime < 2000) { while (System.currentTimeMillis() - startTime < 2000) { // Animation duration
currentFace[0] = (currentFace[0] % 6) + 1; currentFace[0] = (currentFace[0] % 6) + 1;
updateDiceIcons(currentFace[0]);
Thread.sleep(100); String rotatingImage1 = diceToString(currentFace[0]);
String rotatingImage2 = diceToString((currentFace[0] % 6) + 1);
app.enqueue(() -> {
setDiceIcon(imageLabel, rotatingImage1);
setDiceIcon(imageLabel2, rotatingImage2);
});
Thread.sleep(100); // Time between frame updates
} }
} }
/** /**
* Updates the dice icons with the specified face. * Displays the final dice result after animation.
* *
* @param face The face of the dice. * @param event the dice roll event containing the result
*/
private void updateDiceIcons(int face) {
app.enqueue(() -> {
setDiceIcon(imageLabel, diceToString(face));
setDiceIcon(imageLabel2, diceToString((face % 6) + 1));
});
}
/**
* Shows the final dice result.
*
* @param event The dice roll event.
*/ */
private void showFinalDiceResult(DiceRollEvent event) { private void showFinalDiceResult(DiceRollEvent event) {
app.enqueue(() -> { app.enqueue(() -> {
@@ -445,38 +348,27 @@ public class Toolbar extends Dialog implements GameEventListener {
}); });
} }
/**
* Sets the dice icon with the specified image path.
*
* @param label The label representing the dice.
* @param imagePath The path to the icon image.
*/
private void setDiceIcon(Label label, String imagePath) { private void setDiceIcon(Label label, String imagePath) {
IconComponent icon = new IconComponent(imagePath); IconComponent icon = new IconComponent(imagePath);
icon.setIconSize(new Vector2f(80, 80)); icon.setIconSize(new Vector2f(80, 80)); // Set consistent dice size
label.setIcon(icon); label.setIcon(icon);
} }
/**
* Converts the dice number to a string representation.
*
* @param i The dice number.
* @return The string representation of the dice number.
*/
private String diceToString(int i) { private String diceToString(int i) {
return "Pictures/dice/" + switch (i) { switch (i) {
case 1 -> "one"; case 1: return "Pictures/dice/one.png";
case 2 -> "two"; case 2: return "Pictures/dice/two.png";
case 3 -> "three"; case 3: return "Pictures/dice/three.png";
case 4 -> "four"; case 4: return "Pictures/dice/four.png";
case 5 -> "five"; case 5: return "Pictures/dice/five.png";
case 6 -> "six"; case 6: return "Pictures/dice/six.png";
default -> throw new IllegalArgumentException("Invalid dice number: " + i); default: throw new IllegalArgumentException("Invalid dice number: " + i);
} + ".png"; }
} }
/** /**
* Handles dice roll events and updates the dice display. * Handles dice roll events by updating the dice display.
* *
* @param event the dice roll event containing dice values * @param event the dice roll event containing dice values
*/ */
@@ -486,76 +378,67 @@ public class Toolbar extends Dialog implements GameEventListener {
} }
/** /**
* Updates the player view by refreshing the player information displayed on the toolbar. * Updates the player view with the latest account and overview data.
* *
* @param event the update player view event * @param event the update event for the player view
*/ */
@Override @Override
public void receivedEvent(UpdatePlayerView event) { public void receivedEvent(UpdatePlayerView event) {
playerHandler = app.getGameLogic().getPlayerHandler(); playerHandler = app.getGameLogic().getPlayerHandler();
refreshPlayerView(); System.out.println("Update Player View");
}
/**
* Refreshes the player view.
*/
private void refreshPlayerView() {
accountContainer.clearChildren(); accountContainer.clearChildren();
overviewContainer.clearChildren(); overviewContainer.clearChildren();
addAccountDetails(); accountContainer.addChild(new Label("Kontostand", new ElementId("label-toolbar")));
addOverviewDetails(); accountContainer.addChild(new Label(
playerHandler.getPlayerById(app.getId()).getAccountBalance() + " EUR",
new ElementId("label-account")
));
accountContainer.addChild(new Label("Gulag Karten", new ElementId("label-toolbar")));
accountContainer.addChild(new Label(
playerHandler.getPlayerById(app.getId()).getNumJailCard() + "",
new ElementId("label-account")
));
accountContainer.setBackground(null); accountContainer.setBackground(null);
overviewContainer.addChild(new Label("Übersicht", new ElementId("label-toolbar")));
for (Player player : playerHandler.getPlayers()) {
if (player.getId() != app.getId()) {
// Spielerfarbe abrufen
ColorRGBA playerColor = (Player.getColor(player.getId()).getColor());
// Label für den Spieler erstellen
Label playerLabel = new Label(
player.getName() + ": " + player.getAccountBalance() + " EUR",
new ElementId("label-Text")
);
// Farbe setzen
playerLabel.setColor(playerColor);
// Label zum Container hinzufügen
overviewContainer.addChild(playerLabel);
}
}
overviewContainer.setBackground(null); overviewContainer.setBackground(null);
} }
/** /**
* Adds the account details to the player view. * Updates the enabled status of toolbar buttons based on the event.
*/
private void addAccountDetails() {
Player currentPlayer = playerHandler.getPlayerById(app.getId());
accountContainer.addChild(new Label("Kontostand", new ElementId("label-toolbar")));
accountContainer.addChild(new Label(currentPlayer.getAccountBalance() + " EUR", new ElementId("label-account")));
accountContainer.addChild(new Label("Gulag Karten", new ElementId("label-toolbar")));
accountContainer.addChild(new Label(String.valueOf(currentPlayer.getNumJailCard()), new ElementId("label-account")));
}
/**
* Adds the overview details to the player view.
*/
private void addOverviewDetails() {
overviewContainer.addChild(new Label("Übersicht", new ElementId("label-toolbar")));
for (Player player : playerHandler.getPlayers()) {
if (player.getId() != app.getId()) {
Label playerLabel = new Label(
player.getName() + ": " + player.getAccountBalance() + " EUR",
new ElementId("label-player")
);
playerLabel.setColor(Player.getColor(player.getId()).getColor());
overviewContainer.addChild(playerLabel);
}
}
}
/**
* Updates the status of toolbar buttons based on the provided button status event.
* Disables or enables buttons such as trade, property menu, and end turn based on the player's turn status.
* *
* @param event the button status event indicating whether the buttons should be enabled * @param event the button status event
*/ */
@Override @Override
public void receivedEvent(ButtonStatusEvent event) { public void receivedEvent(ButtonStatusEvent event) {
boolean enabled = event.buttonsEnabled(); boolean enabled = event.buttonsEnabled();
canRollDice = enabled; diceButton.setEnabled(enabled);
tradeButton.setEnabled(enabled); tradeButton.setEnabled(enabled);
propertyMenuButton.setEnabled(enabled); propertyMenuButton.setEnabled(enabled);
endTurnButton.setEnabled(false); endTurnButton.setEnabled(false);
} }
/** /**
* Closes the toolbar, detaching it from the GUI. * Closes the toolbar and detaches it from the GUI.
*/ */
@Override @Override
public void close() { public void close() {
@@ -576,7 +459,7 @@ public class Toolbar extends Dialog implements GameEventListener {
*/ */
@Override @Override
public void update() { public void update() {
refreshPlayerView(); receivedEvent(new UpdatePlayerView());
super.update(); super.update();
} }
} }

View File

@@ -910,6 +910,7 @@
} }
sliderhorsetup(); sliderhorsetup();
adjustothercolumnmodel(); adjustothercolumnmodel();
// System.out.println("Columns available: " +availableColumns);
} }
@StyleAttribute(value="visibleColumns") @StyleAttribute(value="visibleColumns")
@@ -922,6 +923,7 @@
sliderhorsetup(); sliderhorsetup();
grid.refreshGrid(); grid.refreshGrid();
refreshSelector(); refreshSelector();
// System.out.println("Columns visble: " +grid.getVisibleColumns());
} }
// Column Operations // Column Operations

View File

@@ -12,31 +12,33 @@ import com.simsilica.lemur.Label;
import com.simsilica.lemur.component.QuadBackgroundComponent; import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.style.ElementId; import com.simsilica.lemur.style.ElementId;
import pp.dialog.Dialog; import pp.dialog.Dialog;
import pp.dialog.PopupDialog;
import pp.monopoly.client.MonopolyApp; import pp.monopoly.client.MonopolyApp;
import pp.monopoly.client.gui.SettingsMenu;
import pp.monopoly.message.server.TradeReply; import pp.monopoly.message.server.TradeReply;
import pp.monopoly.notification.Sound; import pp.monopoly.notification.Sound;
/** /**
* Represents a confirmation dialog that appears when a trade is accepted. * Represents a confirmation dialog that appears when a trade is accepted .
* Displays a message to the user informing them that the trade was accepted. * <p>
* Displays a message to the user informing them that the trade they proposed has been accepted,
* along with a confirmation button to close the dialog.
* </p>
*/ */
public class AcceptTrade extends Dialog implements PopupDialog { public class AcceptTrade extends Dialog {
/** Reference to the Monopoly application instance. */ /** Reference to the Monopoly application instance. */
private final MonopolyApp app; private final MonopolyApp app;
/** Semi-transparent overlay background for the dialog. */ /** Semi-transparent overlay background for the dialog. */
private Geometry overlayBackground; private final Geometry overlayBackground;
/** Container for the warning message content. */ /** Container for the warning message content. */
private Container noMoneyWarningContainer; private final Container noMoneyWarningContainer;
/** Background container providing a border for the dialog. */ /** Background container providing a border for the dialog. */
private Container backgroundContainer; private final Container backgroundContainer;
/** /**
* Constructs the AcceptTrade dialog. * Constructs the accept trade dialog.
* *
* @param app the Monopoly application instance * @param app the Monopoly application instance
* @param msg the trade reply message containing details about the trade * @param msg the trade reply message containing details about the trade
@@ -45,99 +47,80 @@ public class AcceptTrade extends Dialog implements PopupDialog {
super(app.getDialogManager()); super(app.getDialogManager());
this.app = app; this.app = app;
// Initialize GUI elements
createOverlayBackground(); // Halbtransparentes Overlay hinzufügen
createBackgroundContainer(); overlayBackground = createOverlayBackground();
createWarningContainer(msg); app.getGuiNode().attachChild(overlayBackground);
// Create the background container
backgroundContainer = new Container();
backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Darker background
app.getGuiNode().attachChild(backgroundContainer);
// Hauptcontainer für die Warnung
noMoneyWarningContainer = new Container();
noMoneyWarningContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f)));
noMoneyWarningContainer.setPreferredSize(new Vector3f(550,250,10));
float padding = 10; // Passt den backgroundContainer an die Größe des bankruptContainers an
backgroundContainer.setPreferredSize(noMoneyWarningContainer.getPreferredSize().addLocal(padding, padding, 0));
// Titel
Label gateFieldTitle = noMoneyWarningContainer.addChild(new Label("Handel angenommen!", new ElementId("warning-title")));
gateFieldTitle.setFontSize(48);
gateFieldTitle.setColor(ColorRGBA.Black);
// Text, der im Popup steht
Container textContainer = noMoneyWarningContainer.addChild(new Container());
textContainer.addChild(new Label("Du hast Spieler"+ " " + msg.getTradeHandler().getReceiver().getName() + " " + "einen Handel vorgeschlagen", new ElementId("label-Text")));
textContainer.addChild(new Label("", new ElementId("label-Text")));
textContainer.addChild(new Label("Der Handel wurde angenommen", new ElementId("label-Text")));
textContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
// Passt den textContainer an die Größe des bankruptContainers an
textContainer.setPreferredSize(noMoneyWarningContainer.getPreferredSize().addLocal(-250,-200,0));
// Beenden-Button
Button quitButton = noMoneyWarningContainer.addChild(new Button("Bestätigen", new ElementId("button")));
quitButton.setFontSize(32);
quitButton.addClickCommands(source -> ifTopDialog(() -> {
app.getGameLogic().playSound(Sound.BUTTON);
close();
}));
// Zentriere das Popup
noMoneyWarningContainer.setLocalTranslation(
(app.getCamera().getWidth() - noMoneyWarningContainer.getPreferredSize().x) / 2,
(app.getCamera().getHeight() + noMoneyWarningContainer.getPreferredSize().y) / 2,
8
);
// Zentriere das Popup
backgroundContainer.setLocalTranslation(
(app.getCamera().getWidth() - noMoneyWarningContainer.getPreferredSize().x - padding) / 2,
(app.getCamera().getHeight() + noMoneyWarningContainer.getPreferredSize().y+ padding) / 2,
7
);
app.getGuiNode().attachChild(noMoneyWarningContainer);
} }
/** /**
* Creates a semi-transparent background overlay for the dialog. * Creates a semi-transparent background overlay for the dialog.
*/
private void createOverlayBackground() {
Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight());
overlayBackground = new Geometry("Overlay", quad);
Material material = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); // Semi-transparent
material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
overlayBackground.setMaterial(material);
overlayBackground.setLocalTranslation(0, 0, 0);
}
/**
* Creates the background container for the dialog.
*/
private void createBackgroundContainer() {
backgroundContainer = new Container();
backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Light gray background
}
/**
* Creates the main warning container for the dialog.
* *
* @param msg the trade reply message * @return the geometry of the overlay
*/ */
private void createWarningContainer(TradeReply msg) { private Geometry createOverlayBackground() {
noMoneyWarningContainer = new Container(); Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight());
noMoneyWarningContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); Geometry overlay = new Geometry("Overlay", quad);
noMoneyWarningContainer.setPreferredSize(new Vector3f(550, 250, 10)); Material material = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); // Halbtransparent
float padding = 10; material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
backgroundContainer.setPreferredSize(noMoneyWarningContainer.getPreferredSize().addLocal(padding, padding, 0)); overlay.setMaterial(material);
overlay.setLocalTranslation(0, 0, 0);
// Title return overlay;
Label title = noMoneyWarningContainer.addChild(new Label("Handel angenommen!", new ElementId("warning-title")));
title.setFontSize(48);
title.setColor(ColorRGBA.Black);
// Message
Container textContainer = noMoneyWarningContainer.addChild(new Container());
textContainer.addChild(new Label("Du hast Spieler " + msg.getTradeHandler().getReceiver().getName() + " einen Handel vorgeschlagen.", new ElementId("label-Text")));
textContainer.addChild(new Label("", new ElementId("label-Text")));
textContainer.addChild(new Label("Der Handel wurde angenommen.", new ElementId("label-Text")));
textContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
textContainer.setPreferredSize(noMoneyWarningContainer.getPreferredSize().addLocal(-250, -200, 0));
// Confirmation button
Button confirmButton = noMoneyWarningContainer.addChild(new Button("Bestätigen", new ElementId("button")));
confirmButton.setFontSize(32);
confirmButton.addClickCommands(source -> ifTopDialog(() -> {
app.getGameLogic().playSound(Sound.BUTTON);
close();
}));
}
/**
* Centers the warning and background containers on the screen.
*/
private void centerContainers() {
float padding = 10;
// Center main container
noMoneyWarningContainer.setLocalTranslation(
(app.getCamera().getWidth() - noMoneyWarningContainer.getPreferredSize().x) / 2,
(app.getCamera().getHeight() + noMoneyWarningContainer.getPreferredSize().y) / 2,
8
);
// Center background container with padding
backgroundContainer.setPreferredSize(noMoneyWarningContainer.getPreferredSize().addLocal(padding, padding, 0));
backgroundContainer.setLocalTranslation(
(app.getCamera().getWidth() - backgroundContainer.getPreferredSize().x) / 2,
(app.getCamera().getHeight() + backgroundContainer.getPreferredSize().y) / 2,
7
);
}
/**
* Displays the dialog by attaching it to the GUI through the DialogManager.
*/
@Override
public void show() {
app.getGuiNode().attachChild(overlayBackground);
app.getGuiNode().attachChild(backgroundContainer);
app.getGuiNode().attachChild(noMoneyWarningContainer);
centerContainers();
} }
/** /**
@@ -145,9 +128,9 @@ public class AcceptTrade extends Dialog implements PopupDialog {
*/ */
@Override @Override
public void close() { public void close() {
app.getGuiNode().detachChild(overlayBackground); app.getGuiNode().detachChild(noMoneyWarningContainer); // Entferne das Menü
app.getGuiNode().detachChild(backgroundContainer); app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
app.getGuiNode().detachChild(noMoneyWarningContainer); app.getGuiNode().detachChild(overlayBackground); // Entferne das Overlay
super.close(); super.close();
} }
@@ -156,6 +139,6 @@ public class AcceptTrade extends Dialog implements PopupDialog {
*/ */
@Override @Override
public void escape() { public void escape() {
new SettingsMenu(app).open(); close();
} }
} }

View File

@@ -12,24 +12,24 @@ import com.simsilica.lemur.Label;
import com.simsilica.lemur.component.QuadBackgroundComponent; import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.style.ElementId; import com.simsilica.lemur.style.ElementId;
import pp.dialog.Dialog; import pp.dialog.Dialog;
import pp.dialog.PopupDialog;
import pp.monopoly.client.MonopolyApp; import pp.monopoly.client.MonopolyApp;
/** /**
* Bankrupt is a Warning-Popup which appears when the balance is negative at the end of a player´s turn. * Bankrupt is a Warning-Popup which appears when the balance is negative at the end of a player´s turn
*/ */
public class Bankrupt extends Dialog implements PopupDialog { public class Bankrupt extends Dialog {
/** Reference to the Monopoly application instance. */ /** Reference to the Monopoly application instance. */
private final MonopolyApp app; private final MonopolyApp app;
/** Semi-transparent overlay background for the popup. */ /** Semi-transparent overlay background for the popup. */
private Geometry overlayBackground; private final Geometry overlayBackground;
/** Main container for the bankruptcy warning content. */ /** Main container for the bankruptcy warning content. */
private Container bankruptContainer; private final Container bankruptContainer;
/** Background container providing a border for the popup. */ /** Background container providing a border for the popup. */
private Container backgroundContainer; private final Container backgroundContainer;
/** /**
* Constructs the bankruptcy warning popup. * Constructs the bankruptcy warning popup.
@@ -40,102 +40,85 @@ public class Bankrupt extends Dialog implements PopupDialog {
super(app.getDialogManager()); super(app.getDialogManager());
this.app = app; this.app = app;
// Initialize the components
createOverlayBackground(); // Halbtransparentes Overlay hinzufügen
createBackgroundContainer(); overlayBackground = createOverlayBackground();
createBankruptContainer(); app.getGuiNode().attachChild(overlayBackground);
// Create the background container
backgroundContainer = new Container();
backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Darker background
app.getGuiNode().attachChild(backgroundContainer);
// Hauptcontainer für die Warnung
bankruptContainer = new Container();
bankruptContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f)));
bankruptContainer.setPreferredSize(new Vector3f(550,250,10));
float padding = 10; // Passt den backgroundContainer an die Größe des bankruptContainers an
backgroundContainer.setPreferredSize(bankruptContainer.getPreferredSize().addLocal(padding, padding, 0));
// Titel
Label gateFieldTitle = bankruptContainer.addChild(new Label("Vorsicht !", new ElementId("warning-title")));
gateFieldTitle.setFontSize(48);
gateFieldTitle.setColor(ColorRGBA.Black);
// Text, der im Popup steht
Container textContainer = bankruptContainer.addChild(new Container());
textContainer.addChild(new Label("Du hast noch einen negativen Kontostand. Wenn du jetzt deinen Zug beendest, gehst du Bankrott und verlierst das Spiel!", new ElementId("label-Text")));
textContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
// Passt den textContainer an die Größe des bankruptContainers an
textContainer.setPreferredSize(bankruptContainer.getPreferredSize().addLocal(-250,-200,0));
// Beenden-Button
Button quitButton = bankruptContainer.addChild(new Button("Bestätigen", new ElementId("button")));
quitButton.setFontSize(32);
quitButton.addClickCommands(source -> ifTopDialog(this::close));
// Zentriere das Popup
bankruptContainer.setLocalTranslation(
(app.getCamera().getWidth() - bankruptContainer.getPreferredSize().x) / 2,
(app.getCamera().getHeight() + bankruptContainer.getPreferredSize().y) / 2,
8
);
// Zentriere das Popup
backgroundContainer.setLocalTranslation(
(app.getCamera().getWidth() - bankruptContainer.getPreferredSize().x - padding) / 2,
(app.getCamera().getHeight() + bankruptContainer.getPreferredSize().y+ padding) / 2,
7
);
app.getGuiNode().attachChild(bankruptContainer);
} }
/** /**
* Creates a semi-transparent background overlay for the popup. * Creates a semi-transparent background overlay for the popup.
*
* @return the geometry of the overlay
*/ */
private void createOverlayBackground() { private Geometry createOverlayBackground() {
Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight()); Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight());
overlayBackground = new Geometry("Overlay", quad); Geometry overlay = new Geometry("Overlay", quad);
Material material = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); Material material = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); // Semi-transparent material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); // Halbtransparent
material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha); material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
overlayBackground.setMaterial(material); overlay.setMaterial(material);
overlayBackground.setLocalTranslation(0, 0, 0); overlay.setLocalTranslation(0, 0, 0);
return overlay;
} }
/** /**
* Creates the background container for the popup. * Closes the menu and removes the GUI elements.
*/
private void createBackgroundContainer() {
backgroundContainer = new Container();
backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Light gray background
}
/**
* Creates the main container for the bankruptcy warning content.
*/
private void createBankruptContainer() {
bankruptContainer = new Container();
bankruptContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f)));
bankruptContainer.setPreferredSize(new Vector3f(550, 350, 10));
// Title
Label title = bankruptContainer.addChild(new Label("Vorsicht!", new ElementId("warning-title")));
title.setFontSize(48);
title.setColor(ColorRGBA.Black);
// Text content
Container textContainer = bankruptContainer.addChild(new Container());
textContainer.addChild(new Label(
"Du hast einen negativen Kontostand. Wenn du jetzt deinen Zug beendest, gehst du bankrott und verlierst das Spiel!\n"
+ "Dieses Pop-Up wird nicht erneut angezeigt!",
new ElementId("label-Text")));
textContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
textContainer.setPreferredSize(bankruptContainer.getPreferredSize().addLocal(-250, -200, 0));
// Confirmation button
Button confirmButton = bankruptContainer.addChild(new Button("Bestätigen", new ElementId("button")));
confirmButton.setFontSize(32);
confirmButton.addClickCommands(source -> ifTopDialog(this::close));
}
/**
* Centers the popup containers on the screen.
*/
private void centerContainers() {
float padding = 10;
// Center bankrupt container
bankruptContainer.setLocalTranslation(
(app.getCamera().getWidth() - bankruptContainer.getPreferredSize().x) / 2,
(app.getCamera().getHeight() + bankruptContainer.getPreferredSize().y) / 2,
8
);
// Center background container with padding
backgroundContainer.setPreferredSize(bankruptContainer.getPreferredSize().addLocal(padding, padding, 0));
backgroundContainer.setLocalTranslation(
(app.getCamera().getWidth() - backgroundContainer.getPreferredSize().x) / 2,
(app.getCamera().getHeight() + backgroundContainer.getPreferredSize().y) / 2,
7
);
}
/**
* Displays the popup by attaching it to the GUI.
*/
@Override
public void show() {
app.getGuiNode().attachChild(overlayBackground);
app.getGuiNode().attachChild(backgroundContainer);
app.getGuiNode().attachChild(bankruptContainer);
centerContainers();
}
/**
* Closes the popup and removes the associated GUI elements.
*/ */
@Override @Override
public void close() { public void close() {
app.getGuiNode().detachChild(overlayBackground); app.getGuiNode().detachChild(bankruptContainer); // Entferne das Menü
app.getGuiNode().detachChild(backgroundContainer); app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
app.getGuiNode().detachChild(bankruptContainer); app.getGuiNode().detachChild(overlayBackground); // Entferne das Overlay
super.close(); super.close();
} }

View File

@@ -1,7 +1,6 @@
package pp.monopoly.client.gui.popups; package pp.monopoly.client.gui.popups;
import com.jme3.math.ColorRGBA; import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.simsilica.lemur.Button; import com.simsilica.lemur.Button;
import com.simsilica.lemur.Container; import com.simsilica.lemur.Container;
import com.simsilica.lemur.Label; import com.simsilica.lemur.Label;
@@ -9,7 +8,6 @@ import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.style.ElementId; import com.simsilica.lemur.style.ElementId;
import pp.dialog.Dialog; import pp.dialog.Dialog;
import pp.dialog.PopupDialog;
import pp.monopoly.client.MonopolyApp; import pp.monopoly.client.MonopolyApp;
import pp.monopoly.client.gui.SettingsMenu; import pp.monopoly.client.gui.SettingsMenu;
import pp.monopoly.message.client.BuyPropertyResponse; import pp.monopoly.message.client.BuyPropertyResponse;
@@ -18,12 +16,16 @@ import pp.monopoly.model.fields.BuildingProperty;
import pp.monopoly.notification.Sound; import pp.monopoly.notification.Sound;
/** /**
* BuildingPropertyCard creates a popup for displaying field information. * BuildingPropertyCard creates the popup for field information
*/ */
public class BuildingPropertyCard extends Dialog implements PopupDialog { public class BuildingPropertyCard extends Dialog {
/** Reference to the Monopoly application instance. */
private final MonopolyApp app; private final MonopolyApp app;
/** Main container for the building property information. */
private final Container buildingPropertyContainer; private final Container buildingPropertyContainer;
/** Background container providing a border for the property card. */
private final Container backgroundContainer; private final Container backgroundContainer;
/** /**
@@ -35,120 +37,84 @@ public class BuildingPropertyCard extends Dialog implements PopupDialog {
super(app.getDialogManager()); super(app.getDialogManager());
this.app = app; this.app = app;
//Generate the corresponding field
int index = app.getGameLogic().getPlayerHandler().getPlayerById(app.getId()).getFieldID(); int index = app.getGameLogic().getPlayerHandler().getPlayerById(app.getId()).getFieldID();
BuildingProperty field = (BuildingProperty) new BoardManager().getFieldAtIndex(index); BuildingProperty field = (BuildingProperty) new BoardManager().getFieldAtIndex(index);
// Create the main container for the popup
buildingPropertyContainer = new Container();
buildingPropertyContainer.setBackground(new QuadBackgroundComponent(field.getColor().getColor()));
addContentToContainer(buildingPropertyContainer, field);
buildingPropertyContainer.setPreferredSize(new Vector3f(360,420,1));
// Create the background container // Create the background container
backgroundContainer = new Container(); backgroundContainer = new Container();
backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Light gray backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Darker background
attachChild(backgroundContainer);
// Add padding to the background // Hauptcontainer für die Gebäudekarte
float padding = 10f; buildingPropertyContainer = new Container();
buildingPropertyContainer.setBackground(new QuadBackgroundComponent(field.getColor().getColor()));
float padding = 10; // Passt den backgroundContainer an die Größe des buildingPropertyContainer an
backgroundContainer.setPreferredSize(buildingPropertyContainer.getPreferredSize().addLocal(padding, padding, 0)); backgroundContainer.setPreferredSize(buildingPropertyContainer.getPreferredSize().addLocal(padding, padding, 0));
//Titel
Label settingsTitle = buildingPropertyContainer.addChild(new Label( field.getName(), new ElementId("label-Bold")));
settingsTitle.setBackground(new QuadBackgroundComponent(field.getColor().getColor()));
settingsTitle.setFontSize(48);
System.out.println(backgroundContainer.getPreferredSize()); // Text, der auf der Karte steht
// Die Preise werden dynamisch dem BoardManager entnommen
// Position the containers Container propertyValuesContainer = buildingPropertyContainer.addChild(new Container());
centerContainers(padding); propertyValuesContainer.addChild(new Label("„Grundstückswert: " + field.getPrice() + " EUR", new ElementId("label-Text")));
} propertyValuesContainer.addChild(new Label("", new ElementId("label-Text")));// Leerzeile
propertyValuesContainer.addChild(new Label("„Miete allein: " + field.getAllRent().get(0)+ " EUR", new ElementId("label-Text")));
/** propertyValuesContainer.addChild(new Label("„-mit 1 Haus: " + field.getAllRent().get(1) + " EUR", new ElementId("label-Text")));
* Adds the property details and buttons to the container. propertyValuesContainer.addChild(new Label("„-mit 2 Häuser: " + field.getAllRent().get(2) + " EUR", new ElementId("label-Text")));
* propertyValuesContainer.addChild(new Label("„-mit 3 Häuser: " + field.getAllRent().get(3) + " EUR", new ElementId("label-Text")));
* @param container the main container for the property card propertyValuesContainer.addChild(new Label("„-mit 4 Häuser: " + field.getAllRent().get(4) + " EUR", new ElementId("label-Text")));
* @param field the building property to display propertyValuesContainer.addChild(new Label("„-mit 1 Hotel: " + field.getAllRent().get(5) + " EUR", new ElementId("label-Text")));
*/ propertyValuesContainer.addChild(new Label("„-1 Haus kostet: " + field.getHousePrice()+ " EUR", new ElementId("label-Text")));
private void addContentToContainer(Container container, BuildingProperty field) { propertyValuesContainer.addChild(new Label("", new ElementId("label-Text")));// Leerzeile
// Title propertyValuesContainer.addChild(new Label("„Hypothek: " + field.getHypo() + " EUR", new ElementId("label-Text")));
Label title = container.addChild(new Label(field.getName(), new ElementId("label-Bold")));
title.setBackground(new QuadBackgroundComponent(field.getColor().getColor()));
title.setFontSize(38);
// Property details
Container propertyValuesContainer = container.addChild(new Container());
propertyValuesContainer.addChild(new Label("Grundstückswert: " + field.getPrice() + " EUR", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("Miete allein: " + field.getAllRent().get(0) + " EUR", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("- mit 1 Haus: " + field.getAllRent().get(1) + " EUR", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("- mit 2 Häusern: " + field.getAllRent().get(2) + " EUR", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("- mit 3 Häusern: " + field.getAllRent().get(3) + " EUR", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("- mit 4 Häusern: " + field.getAllRent().get(4) + " EUR", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("- mit 1 Hotel: " + field.getAllRent().get(5) + " EUR", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("1 Haus kostet: " + field.getHousePrice() + " EUR", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("Hypothek: " + field.getHypo() + " EUR", new ElementId("label-Text")));
propertyValuesContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f))); propertyValuesContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
// Add buttons // Beenden-Button
addButtons(container); Button quitButton = buildingPropertyContainer.addChild(new Button("Beenden", new ElementId("button")));
}
/**
* Adds the buttons for closing or buying the property.
*
* @param container the main container
*/
private void addButtons(Container container) {
// Quit button
Button quitButton = container.addChild(new Button("Beenden", new ElementId("button")));
quitButton.setFontSize(32); quitButton.setFontSize(32);
quitButton.addClickCommands(s -> ifTopDialog(() -> { quitButton.addClickCommands(s -> ifTopDialog( () -> {
System.err.println("Button does something?");
app.getGameLogic().playSound(Sound.BUTTON); app.getGameLogic().playSound(Sound.BUTTON);
close(); close();
})); }));
// Kaufen-Button
// Buy button Button buyButton = buildingPropertyContainer.addChild(new Button("Kaufen", new ElementId("button")));
Button buyButton = container.addChild(new Button("Kaufen", new ElementId("button")));
buyButton.setFontSize(32); buyButton.setFontSize(32);
buyButton.addClickCommands(s -> ifTopDialog(() -> { buyButton.addClickCommands(s -> ifTopDialog( () -> {
app.getGameLogic().playSound(Sound.BUTTON); app.getGameLogic().playSound(Sound.BUTTON);
close(); close();
app.getGameLogic().send(new BuyPropertyResponse()); app.getGameLogic().send(new BuyPropertyResponse());
})); }));
}
/** // Zentriere das Popup
* Centers the containers on the screen.
*
* @param padding the padding size
*/
private void centerContainers(float padding) {
// Center main container
buildingPropertyContainer.setLocalTranslation( buildingPropertyContainer.setLocalTranslation(
(app.getCamera().getWidth() - buildingPropertyContainer.getPreferredSize().x) / 2, (app.getCamera().getWidth() - buildingPropertyContainer.getPreferredSize().x) / 2,
(app.getCamera().getHeight() + buildingPropertyContainer.getPreferredSize().y) / 2, (app.getCamera().getHeight() + buildingPropertyContainer.getPreferredSize().y) / 2,
8 8
); );
// Center background container with padding // Zentriere das Popup
backgroundContainer.setLocalTranslation( backgroundContainer.setLocalTranslation(
(app.getCamera().getWidth() - buildingPropertyContainer.getPreferredSize().x - padding) / 2, (app.getCamera().getWidth() - buildingPropertyContainer.getPreferredSize().x - padding) / 2,
(app.getCamera().getHeight() + buildingPropertyContainer.getPreferredSize().y + padding) / 2, (app.getCamera().getHeight() + buildingPropertyContainer.getPreferredSize().y+ padding) / 2,
7 7
); );
}
/**
* Attaches the popup to the GUI through the DialogManager.
*/
@Override
public void show() {
app.getGuiNode().attachChild(backgroundContainer);
app.getGuiNode().attachChild(buildingPropertyContainer); app.getGuiNode().attachChild(buildingPropertyContainer);
} }
/** /**
* Closes the popup and removes associated GUI elements. * Closes the popup and removes the associated GUI elements.
*/ */
@Override @Override
public void close() { public void close() {
app.getGuiNode().detachChild(buildingPropertyContainer); app.getGuiNode().detachChild(buildingPropertyContainer); // Entferne das Menü
app.getGuiNode().detachChild(backgroundContainer); app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
super.close(); super.close();
} }

View File

@@ -7,6 +7,7 @@ import com.simsilica.lemur.Button;
import com.simsilica.lemur.Container; import com.simsilica.lemur.Container;
import com.simsilica.lemur.Label; import com.simsilica.lemur.Label;
import com.simsilica.lemur.Selector; import com.simsilica.lemur.Selector;
import com.simsilica.lemur.TextField;
import com.simsilica.lemur.component.QuadBackgroundComponent; import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.component.SpringGridLayout; import com.simsilica.lemur.component.SpringGridLayout;
import com.simsilica.lemur.core.VersionedList; import com.simsilica.lemur.core.VersionedList;
@@ -39,8 +40,8 @@ public class BuyHouse extends Dialog {
/** Background container providing a border for the popup. */ /** Background container providing a border for the popup. */
private final Container backgroundContainer; private final Container backgroundContainer;
/** Label to display selected properties. */ /** TextField to display selected properties. */
private Label selectionDisplay; private TextField selectionDisplay;
/** Reference for tracking dropdown selection changes. */ /** Reference for tracking dropdown selection changes. */
private VersionedReference<Set<Integer>> selectionRef; private VersionedReference<Set<Integer>> selectionRef;
@@ -76,7 +77,7 @@ public class BuyHouse extends Dialog {
backgroundContainer.setPreferredSize(buyHouseContainer.getPreferredSize().addLocal(padding, padding, 0)); backgroundContainer.setPreferredSize(buyHouseContainer.getPreferredSize().addLocal(padding, padding, 0));
// Title // Title
Label title = buyHouseContainer.addChild(new Label("Gebäude Kaufen", new ElementId("label-Bold"))); Label title = buyHouseContainer.addChild(new Label("Gebäude Kaufen", new ElementId("warning-Bold")));
title.setFontSize(48); title.setFontSize(48);
title.setColor(ColorRGBA.Black); title.setColor(ColorRGBA.Black);
@@ -144,7 +145,7 @@ public class BuyHouse extends Dialog {
private Container createPropertyDropdown() { private Container createPropertyDropdown() {
Container dropdownContainer = new Container(new SpringGridLayout(Axis.Y, Axis.X)); Container dropdownContainer = new Container(new SpringGridLayout(Axis.Y, Axis.X));
dropdownContainer.setPreferredSize(new Vector3f(300, 200, 0)); dropdownContainer.setPreferredSize(new Vector3f(300, 200, 0));
dropdownContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.0f, 0.0f, 0.0f, 1.0f))); dropdownContainer.setBackground(new QuadBackgroundComponent(ColorRGBA.Orange));
VersionedList<String> propertyOptions = new VersionedList<>(); VersionedList<String> propertyOptions = new VersionedList<>();
List<BuildingProperty> playerProperties = getPlayerProperties(); List<BuildingProperty> playerProperties = getPlayerProperties();
@@ -161,9 +162,8 @@ public class BuyHouse extends Dialog {
selectionRef = propertySelector.getSelectionModel().createReference(); selectionRef = propertySelector.getSelectionModel().createReference();
// Initialize the selection display here // Initialize the selection display here
selectionDisplay = new Label(""); selectionDisplay = new TextField(""); // Create TextField for displaying selections
selectionDisplay.setPreferredSize(new Vector3f(300, 30, 0)); selectionDisplay.setPreferredSize(new Vector3f(300, 30, 0));
selectionDisplay.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
dropdownContainer.addChild(selectionDisplay); // Add it to the dropdown container dropdownContainer.addChild(selectionDisplay); // Add it to the dropdown container
// Set initial selection // Set initial selection

View File

@@ -7,7 +7,6 @@ import com.simsilica.lemur.Label;
import com.simsilica.lemur.component.QuadBackgroundComponent; import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.style.ElementId; import com.simsilica.lemur.style.ElementId;
import pp.dialog.Dialog; import pp.dialog.Dialog;
import pp.dialog.PopupDialog;
import pp.monopoly.client.MonopolyApp; import pp.monopoly.client.MonopolyApp;
import pp.monopoly.client.gui.SettingsMenu; import pp.monopoly.client.gui.SettingsMenu;
import pp.monopoly.client.gui.TradeMenu; import pp.monopoly.client.gui.TradeMenu;
@@ -19,18 +18,18 @@ import pp.monopoly.notification.Sound;
/** /**
* ConfirmTrade is a popup which appears when a trade is proposed to this certain player. * ConfirmTrade is a popup which appears when a trade is proposed to this certain player.
*/ */
public class ConfirmTrade extends Dialog implements PopupDialog { public class ConfirmTrade extends Dialog {
/** Reference to the Monopoly application instance. */ /** Reference to the Monopoly application instance. */
private final MonopolyApp app; private final MonopolyApp app;
/** Main container for the "Confirm Trade" popup UI. */ /** Main container for the "Confirm Trade" popup UI. */
private Container confirmTradeContainer; private final Container confirmTradeContainer;
/** Background container providing a border for the popup. */ /** Background container providing a border for the popup. */
private Container backgroundContainer; private final Container backgroundContainer;
/** The trade handler managing the details of the trade proposal. */ /** The trade handler managing the details of the trade proposal. */
private final TradeHandler tradeHandler; private TradeHandler tradeHandler;
/** /**
* Constructs the "Confirm Trade" popup. * Constructs the "Confirm Trade" popup.
@@ -40,61 +39,53 @@ public class ConfirmTrade extends Dialog implements PopupDialog {
public ConfirmTrade(MonopolyApp app) { public ConfirmTrade(MonopolyApp app) {
super(app.getDialogManager()); super(app.getDialogManager());
this.app = app; this.app = app;
this.tradeHandler = app.getGameLogic().getTradeHandler(); tradeHandler = app.getGameLogic().getTradeHandler();
// Initialize components // Create the background container
createBackgroundContainer();
createConfirmTradeContainer();
}
/**
* Initializes the background container.
*/
private void createBackgroundContainer() {
backgroundContainer = new Container(); backgroundContainer = new Container();
backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f)));
} attachChild(backgroundContainer);
/**
* Initializes the main confirm trade container and its UI components.
*/
private void createConfirmTradeContainer() {
confirmTradeContainer = new Container(); confirmTradeContainer = new Container();
// Title float padding = 10;
Label title = confirmTradeContainer.addChild(new Label("Handel", new ElementId("warning-title"))); backgroundContainer.setPreferredSize(confirmTradeContainer.getPreferredSize().addLocal(padding, padding, 0));
// Titel
Label title = confirmTradeContainer.addChild(new Label( "Handel", new ElementId("warning-title")));
title.setFontSize(48); title.setFontSize(48);
title.setColor(ColorRGBA.Black); title.setColor(ColorRGBA.Black);
// Build trade information strings
StringBuilder offeredProperties = new StringBuilder(); StringBuilder offeredProperties = new StringBuilder();
for (PropertyField field : tradeHandler.getOfferedProperties()) { for (PropertyField field : tradeHandler.getOfferedProperties()) {
offeredProperties.append(field.getName()).append(", "); offeredProperties.append(field.getName());
offeredProperties.append(", ");
} }
StringBuilder requestedProperties = new StringBuilder(); StringBuilder requestedProperties = new StringBuilder();
for (PropertyField field : tradeHandler.getRequestedProperties()) { for (PropertyField field : tradeHandler.getRequestedProperties()) {
requestedProperties.append(field.getName()).append(", "); requestedProperties.append(field.getName());
requestedProperties.append(", ");
} }
// Trade details // Text, der auf der Karte steht
Container propertyValuesContainer = confirmTradeContainer.addChild(new Container()); Container propertyValuesContainer = confirmTradeContainer.addChild(new Container());
propertyValuesContainer.addChild(new Label("„Spieler " + tradeHandler.getSender().getName() + " möchte:", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("„Spieler " + " " + tradeHandler.getSender().getName() + " " +" möchte:", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("", new ElementId("label-Text")));// Leerzeile
propertyValuesContainer.addChild(new Label("- " + offeredProperties, new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("- " + offeredProperties, new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("- " + tradeHandler.getOfferedAmount() + " EUR", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("- " + tradeHandler.getOfferedAmount() + " EUR", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("- " + tradeHandler.getOfferedJailCards() + " Sonderkarten", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("- " + tradeHandler.getOfferedJailCards() +" Sonderkarten", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("", new ElementId("label-Text")));// Leerzeile
propertyValuesContainer.addChild(new Label("gegen:", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("gegen:", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("", new ElementId("label-Text")));// Leerzeile
propertyValuesContainer.addChild(new Label("- " + requestedProperties, new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("- "+ requestedProperties, new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("- " + tradeHandler.getRequestedAmount() + " EUR", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("- "+ tradeHandler.getRequestedAmount() +" EUR", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("- " + tradeHandler.getRequestedJailCards() + " Sonderkarten", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("- "+ tradeHandler.getRequestedJailCards() +" Sonderkarten", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("", new ElementId("label-Text")));// Leerzeile
propertyValuesContainer.addChild(new Label("tauschen, willst du das Angebot annehmen?", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("tauschen, willst du das Angebot annehmen?", new ElementId("label-Text")));
propertyValuesContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f))); propertyValuesContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
// Decline button // Ablehnen-Button
Button declineButton = confirmTradeContainer.addChild(new Button("Ablehnen", new ElementId("button"))); Button declineButton = confirmTradeContainer.addChild(new Button("Ablehnen", new ElementId("button")));
declineButton.setFontSize(32); declineButton.setFontSize(32);
declineButton.addClickCommands(s -> ifTopDialog(() -> { declineButton.addClickCommands(s -> ifTopDialog(() -> {
@@ -102,50 +93,39 @@ public class ConfirmTrade extends Dialog implements PopupDialog {
app.getGameLogic().send(new TradeResponse(false, tradeHandler)); app.getGameLogic().send(new TradeResponse(false, tradeHandler));
close(); close();
})); }));
// Verhandeln-Button
// Negotiate button
Button negotiateButton = confirmTradeContainer.addChild(new Button("Verhandeln", new ElementId("button"))); Button negotiateButton = confirmTradeContainer.addChild(new Button("Verhandeln", new ElementId("button")));
negotiateButton.setFontSize(32); negotiateButton.setFontSize(32);
negotiateButton.addClickCommands(s -> ifTopDialog(() -> { negotiateButton.addClickCommands(s -> ifTopDialog( () -> {
app.getGameLogic().playSound(Sound.BUTTON); app.getGameLogic().playSound(Sound.BUTTON);
close(); close();
TradeHandler t = new TradeHandler(app.getGameLogic().getPlayerHandler().getPlayerById(tradeHandler.getSender().getId())); TradeHandler t = new TradeHandler(app.getGameLogic().getPlayerHandler().getPlayerById(tradeHandler.getSender().getId()));
t.setReceiver(app.getGameLogic().getPlayerHandler().getPlayerById(tradeHandler.getReceiver().getId())); t.setReceiver(app.getGameLogic().getPlayerHandler().getPlayerById(tradeHandler.getReceiver().getId()));
new TradeMenu(app, t).open(); new TradeMenu(app, t).open();
})); }));
// Confirm-Button
// Confirm button
Button confirmButton = confirmTradeContainer.addChild(new Button("Bestätigen", new ElementId("button"))); Button confirmButton = confirmTradeContainer.addChild(new Button("Bestätigen", new ElementId("button")));
confirmButton.setFontSize(32); confirmButton.setFontSize(32);
confirmButton.addClickCommands(s -> ifTopDialog(() -> { confirmButton.addClickCommands(s -> ifTopDialog( () -> {
app.getGameLogic().playSound(Sound.BUTTON); app.getGameLogic().playSound(Sound.BUTTON);
app.getGameLogic().send(new TradeResponse(true, tradeHandler)); app.getGameLogic().send(new TradeResponse(true, tradeHandler));
close(); close();
})); }));
}
/** // Zentriere das Menü
* Displays the popup by attaching it to the GUI.
*/
@Override
public void show() {
float padding = 10;
// Center and adjust sizes
backgroundContainer.setPreferredSize(confirmTradeContainer.getPreferredSize().addLocal(padding, padding, 0));
confirmTradeContainer.setLocalTranslation( confirmTradeContainer.setLocalTranslation(
(app.getCamera().getWidth() - confirmTradeContainer.getPreferredSize().x) / 2, (app.getCamera().getWidth() - confirmTradeContainer.getPreferredSize().x) / 2,
(app.getCamera().getHeight() + confirmTradeContainer.getPreferredSize().y) / 2, (app.getCamera().getHeight() + confirmTradeContainer.getPreferredSize().y) / 2,
8 8
); );
// Zentriere das Menü
backgroundContainer.setLocalTranslation( backgroundContainer.setLocalTranslation(
(app.getCamera().getWidth() - confirmTradeContainer.getPreferredSize().x - padding) / 2, (app.getCamera().getWidth() - confirmTradeContainer.getPreferredSize().x - padding) / 2,
(app.getCamera().getHeight() + confirmTradeContainer.getPreferredSize().y + padding) / 2, (app.getCamera().getHeight() + confirmTradeContainer.getPreferredSize().y+ padding) / 2,
7 7
); );
// Attach to GUI node
app.getGuiNode().attachChild(backgroundContainer);
app.getGuiNode().attachChild(confirmTradeContainer); app.getGuiNode().attachChild(confirmTradeContainer);
} }

View File

@@ -12,25 +12,25 @@ import com.simsilica.lemur.Label;
import com.simsilica.lemur.component.QuadBackgroundComponent; import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.style.ElementId; import com.simsilica.lemur.style.ElementId;
import pp.dialog.Dialog; import pp.dialog.Dialog;
import pp.dialog.PopupDialog;
import pp.monopoly.client.MonopolyApp; import pp.monopoly.client.MonopolyApp;
import pp.monopoly.notification.Sound; import pp.monopoly.notification.Sound;
/** /**
* EventCardPopup is a popup which appears when a certain EventCard is triggered by entering an EventCardField. * EventCardPopup is a popup which appears when a certain EventCard is triggered by entering a EventCardField
*/ */
public class EventCardPopup extends Dialog implements PopupDialog { public class EventCardPopup extends Dialog {
/** Reference to the Monopoly application instance. */ /** Reference to the Monopoly application instance. */
private final MonopolyApp app; private final MonopolyApp app;
/** Semi-transparent overlay background for the popup. */ /** Semi-transparent overlay background for the popup. */
private Geometry overlayBackground; private final Geometry overlayBackground;
/** Main container for the event card information. */ /** Main container for the event card information. */
private Container eventCardContainer; private final Container eventCardContainer;
/** Background container providing a border for the popup. */ /** Background container providing a border for the popup. */
private Container backgroundContainer; private final Container backgroundContainer;
/** /**
* Constructs the EventCardPopup to display the details of a triggered event card. * Constructs the EventCardPopup to display the details of a triggered event card.
@@ -42,87 +42,74 @@ public class EventCardPopup extends Dialog implements PopupDialog {
super(app.getDialogManager()); super(app.getDialogManager());
this.app = app; this.app = app;
// Initialize the UI components // Halbtransparentes Overlay hinzufügen
createOverlayBackground(); overlayBackground = createOverlayBackground();
createBackgroundContainer(); app.getGuiNode().attachChild(overlayBackground);
createEventCardContainer(description);
}
/** // Create the background container
* Initializes the semi-transparent background overlay.
*/
private void createOverlayBackground() {
Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight());
overlayBackground = new Geometry("Overlay", quad);
Material material = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); // Semi-transparent black
material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
overlayBackground.setMaterial(material);
overlayBackground.setLocalTranslation(0, 0, 0);
}
/**
* Initializes the background container.
*/
private void createBackgroundContainer() {
backgroundContainer = new Container(); backgroundContainer = new Container();
backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Light gray background backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Darker background
} app.getGuiNode().attachChild(backgroundContainer);
/**
* Initializes the main event card container and its UI components.
*
* @param description the description of the triggered event card
*/
private void createEventCardContainer(String description) {
eventCardContainer = new Container(); eventCardContainer = new Container();
eventCardContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); eventCardContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f)));
eventCardContainer.setPreferredSize(new Vector3f(550, 400, 10)); eventCardContainer.setPreferredSize(new Vector3f(550,400,10));
// Title float padding = 10;
Label title = eventCardContainer.addChild(new Label("Ereigniskarte", new ElementId("settings-title"))); backgroundContainer.setPreferredSize(eventCardContainer.getPreferredSize().addLocal(padding, padding, 0));
title.setFontSize(48);
title.setColor(ColorRGBA.Black);
// Event description // Titel
Container textContainer = eventCardContainer.addChild(new Container()); Label gateFieldTitle = eventCardContainer.addChild(new Label("Ereigniskarte", new ElementId("settings-title")));
textContainer.addChild(new Label(description, new ElementId("label-Text"))); gateFieldTitle.setFontSize(48);
textContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f))); gateFieldTitle.setColor(ColorRGBA.Black);
textContainer.setPreferredSize(new Vector3f(300, 200, 0));
// Confirm button // Text, der auf der Karte steht
Button confirmButton = eventCardContainer.addChild(new Button("Jawohl", new ElementId("button"))); // Die Erklärungsfelder werden automatisch den descriptions der Message entnommen
confirmButton.setFontSize(32); Container propertyValuesContainer = eventCardContainer.addChild(new Container());
confirmButton.addClickCommands(source -> ifTopDialog(() -> { propertyValuesContainer.addChild(new Label(description, new ElementId("label-Text")));
propertyValuesContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
propertyValuesContainer.setPreferredSize(new Vector3f(300,200,10));
// Beenden-Button
Button quitButton = eventCardContainer.addChild(new Button("Jawohl", new ElementId("button")));
quitButton.setFontSize(32);
quitButton.addClickCommands(source -> ifTopDialog( () -> {
app.getGameLogic().playSound(Sound.BUTTON); app.getGameLogic().playSound(Sound.BUTTON);
close(); close();
})); }));
// Zentriere das Popup
eventCardContainer.setLocalTranslation(
(app.getCamera().getWidth() - eventCardContainer.getPreferredSize().x) / 2,
(app.getCamera().getHeight() + eventCardContainer.getPreferredSize().y) / 2,
10
);
// Zentriere das Popup
backgroundContainer.setLocalTranslation(
(app.getCamera().getWidth() - eventCardContainer.getPreferredSize().x - padding) / 2,
(app.getCamera().getHeight() + eventCardContainer.getPreferredSize().y+ padding) / 2,
9
);
app.getGuiNode().attachChild(eventCardContainer);
} }
/** /**
* Displays the popup by attaching it to the GUI. * Creates a semi-transparent background overlay for the popup.
*
* @return the geometry of the overlay
*/ */
@Override private Geometry createOverlayBackground() {
public void show() { Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight());
float padding = 10; Geometry overlay = new Geometry("Overlay", quad);
Material material = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
// Adjust sizes and center elements material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f));
backgroundContainer.setPreferredSize(eventCardContainer.getPreferredSize().addLocal(padding, padding, 0)); material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
eventCardContainer.setLocalTranslation( overlay.setMaterial(material);
(app.getCamera().getWidth() - eventCardContainer.getPreferredSize().x) / 2, overlay.setLocalTranslation(0, 0, 0);
(app.getCamera().getHeight() + eventCardContainer.getPreferredSize().y) / 2, return overlay;
8
);
backgroundContainer.setLocalTranslation(
(app.getCamera().getWidth() - eventCardContainer.getPreferredSize().x - padding) / 2,
(app.getCamera().getHeight() + eventCardContainer.getPreferredSize().y + padding) / 2,
7
);
// Attach components to the GUI
app.getGuiNode().attachChild(overlayBackground);
app.getGuiNode().attachChild(backgroundContainer);
app.getGuiNode().attachChild(eventCardContainer);
} }
/** /**
@@ -130,9 +117,9 @@ public class EventCardPopup extends Dialog implements PopupDialog {
*/ */
@Override @Override
public void close() { public void close() {
app.getGuiNode().detachChild(overlayBackground);
app.getGuiNode().detachChild(eventCardContainer); app.getGuiNode().detachChild(eventCardContainer);
app.getGuiNode().detachChild(backgroundContainer); app.getGuiNode().detachChild(backgroundContainer);
app.getGuiNode().detachChild(overlayBackground);
super.close(); super.close();
} }

View File

@@ -3,7 +3,6 @@ package pp.monopoly.client.gui.popups;
import com.jme3.material.Material; import com.jme3.material.Material;
import com.jme3.material.RenderState.BlendMode; import com.jme3.material.RenderState.BlendMode;
import com.jme3.math.ColorRGBA; import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry; import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Quad; import com.jme3.scene.shape.Quad;
import com.simsilica.lemur.Button; import com.simsilica.lemur.Button;
@@ -13,27 +12,27 @@ import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.style.ElementId; import com.simsilica.lemur.style.ElementId;
import pp.dialog.Dialog; import pp.dialog.Dialog;
import pp.dialog.PopupDialog;
import pp.monopoly.client.MonopolyApp; import pp.monopoly.client.MonopolyApp;
import pp.monopoly.client.gui.SettingsMenu;
import pp.monopoly.message.client.BuyPropertyResponse; import pp.monopoly.message.client.BuyPropertyResponse;
import pp.monopoly.model.fields.FoodField; import pp.monopoly.model.fields.FoodField;
import pp.monopoly.notification.Sound; import pp.monopoly.notification.Sound;
/** /**
* FoodFieldCard creates the popup for field information. * FoodFieldCard creates the popup for field information
*/ */
public class FoodFieldCard extends Dialog implements PopupDialog { public class FoodFieldCard extends Dialog {
/** Reference to the Monopoly application instance. */ /** Reference to the Monopoly application instance. */
private final MonopolyApp app; private final MonopolyApp app;
/** Semi-transparent overlay background for the popup. */ /** Semi-transparent overlay background for the popup. */
private Geometry overlayBackground; private final Geometry overlayBackground;
/** Main container for the food field information. */ /** Main container for the food field information. */
private Container foodFieldContainer; private final Container foodFieldContainer;
/** Background container providing a border for the popup. */ /** Background container providing a border for the popup. */
private Container backgroundContainer; private final Container backgroundContainer;
/** /**
* Constructs a FoodFieldCard popup displaying details about a food field. * Constructs a FoodFieldCard popup displaying details about a food field.
@@ -44,123 +43,108 @@ public class FoodFieldCard extends Dialog implements PopupDialog {
super(app.getDialogManager()); super(app.getDialogManager());
this.app = app; this.app = app;
// Retrieve field information
int index = app.getGameLogic().getPlayerHandler().getPlayerById(app.getId()).getFieldID(); int index = app.getGameLogic().getPlayerHandler().getPlayerById(app.getId()).getFieldID();
FoodField field = (FoodField) app.getGameLogic().getBoardManager().getFieldAtIndex(index); FoodField field = (FoodField) app.getGameLogic().getBoardManager().getFieldAtIndex(index);
// Create UI elements overlayBackground = createOverlayBackground();
createOverlayBackground(); app.getGuiNode().attachChild(overlayBackground);
createBackgroundContainer();
createFoodFieldContainer(field);
}
/**
* Initializes the semi-transparent background overlay.
*/
private void createOverlayBackground() {
Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight());
overlayBackground = new Geometry("Overlay", quad);
Material material = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); // Semi-transparent
material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
overlayBackground.setMaterial(material);
overlayBackground.setLocalTranslation(0, 0, 0);
}
/**
* Initializes the background container.
*/
private void createBackgroundContainer() {
backgroundContainer = new Container(); backgroundContainer = new Container();
backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Light gray background backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Darker background
attachChild(backgroundContainer);
}
/**
* Initializes the main food field container and its UI components.
*
* @param field the food field information to display
*/
private void createFoodFieldContainer(FoodField field) {
foodFieldContainer = new Container(); foodFieldContainer = new Container();
foodFieldContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.1f, 0.1f, 0.1f, 0.9f))); foodFieldContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.1f, 0.1f, 0.1f, 0.9f)));
foodFieldContainer.setPreferredSize(new Vector3f(360,420,1));
// Title float padding = 10;
Label title = foodFieldContainer.addChild(new Label(field.getName(), new ElementId("label-Bold"))); backgroundContainer.setPreferredSize(foodFieldContainer.getPreferredSize().addLocal(padding, padding, 0));
title.setFontSize(48);
title.setColor(ColorRGBA.White); Label settingsTitle = foodFieldContainer.addChild(new Label(field.getName(), new ElementId("label-Bold")));
settingsTitle.setFontSize(48);
settingsTitle.setColor(ColorRGBA.White);
// Field details
Container propertyValuesContainer = foodFieldContainer.addChild(new Container()); Container propertyValuesContainer = foodFieldContainer.addChild(new Container());
propertyValuesContainer.addChild(new Label("„Preis: " + field.getPrice() + " EUR", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("„Preis: " + field.getPrice() + " EUR", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("", new ElementId("label-Text"))); // Empty line propertyValuesContainer.addChild(new Label("", new ElementId("label-Text"))); // Leerzeile
propertyValuesContainer.addChild(new Label("Miete: 40x Würfel-Augen, wenn Besitzer eines Restaurants.", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("Wenn man Besitzer des", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("„Miete: 100x Würfel-Augen, wenn Besitzer beider Restaurants.", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label(field.getName()+" ist, so ist die", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("", new ElementId("label-Text"))); // Empty line propertyValuesContainer.addChild(new Label("Miete 40-mal so hoch, wie", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("Augen auf den zwei Würfeln sind.", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("", new ElementId("label-Text"))); // Leerzeile
propertyValuesContainer.addChild(new Label("„Wenn man Besitzer beider", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("Restaurants ist, so ist die", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("Miete 100-mal so hoch, wie", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("Augen auf den zwei Würfeln sind.", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("", new ElementId("label-Text"))); // Leerzeile
propertyValuesContainer.addChild(new Label("„Hypothek: " + field.getHypo() + " EUR", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("„Hypothek: " + field.getHypo() + " EUR", new ElementId("label-Text")));
propertyValuesContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f))); propertyValuesContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
// Quit button // Beenden-Button
Button quitButton = foodFieldContainer.addChild(new Button("Beenden", new ElementId("button"))); Button quitButton = foodFieldContainer.addChild(new Button("Beenden", new ElementId("button")));
quitButton.setFontSize(32); quitButton.setFontSize(32);
quitButton.addClickCommands(s -> ifTopDialog(() -> { quitButton.addClickCommands(s -> ifTopDialog( () -> {
app.getGameLogic().playSound(Sound.BUTTON); app.getGameLogic().playSound(Sound.BUTTON);
close(); close();
})); }));
// Kaufen-Button
// Buy button
Button buyButton = foodFieldContainer.addChild(new Button("Kaufen", new ElementId("button"))); Button buyButton = foodFieldContainer.addChild(new Button("Kaufen", new ElementId("button")));
buyButton.setFontSize(32); buyButton.setFontSize(32);
buyButton.addClickCommands(s -> ifTopDialog(() -> { buyButton.addClickCommands(s -> ifTopDialog( () -> {
app.getGameLogic().playSound(Sound.BUTTON); app.getGameLogic().playSound(Sound.BUTTON);
app.getGameLogic().send(new BuyPropertyResponse()); app.getGameLogic().send(new BuyPropertyResponse());
close(); close();
})); }));
}
/** // Zentriere das Popup
* Displays the popup by attaching its elements to the GUI.
*/
@Override
public void show() {
float padding = 10;
// Adjust sizes and center elements
backgroundContainer.setPreferredSize(foodFieldContainer.getPreferredSize().addLocal(padding, padding, 0));
foodFieldContainer.setLocalTranslation( foodFieldContainer.setLocalTranslation(
(app.getCamera().getWidth() - foodFieldContainer.getPreferredSize().x) / 2, (app.getCamera().getWidth() - foodFieldContainer.getPreferredSize().x) / 2,
(app.getCamera().getHeight() + foodFieldContainer.getPreferredSize().y) / 2, (app.getCamera().getHeight() + foodFieldContainer.getPreferredSize().y) / 2,
8 8
); );
// Zentriere das Popup
backgroundContainer.setLocalTranslation( backgroundContainer.setLocalTranslation(
(app.getCamera().getWidth() - foodFieldContainer.getPreferredSize().x - padding) / 2, (app.getCamera().getWidth() - foodFieldContainer.getPreferredSize().x - padding) / 2,
(app.getCamera().getHeight() + foodFieldContainer.getPreferredSize().y + padding) / 2, (app.getCamera().getHeight() + foodFieldContainer.getPreferredSize().y+ padding) / 2,
7 7
); );
// Attach components to the GUI
app.getGuiNode().attachChild(overlayBackground);
app.getGuiNode().attachChild(backgroundContainer);
app.getGuiNode().attachChild(foodFieldContainer); app.getGuiNode().attachChild(foodFieldContainer);
} }
/**
* Creates a semi-transparent background overlay for the popup.
*
* @return the geometry of the overlay
*/
private Geometry createOverlayBackground() {
Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight());
Geometry overlay = new Geometry("Overlay", quad);
Material material = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); // Halbtransparent
material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
overlay.setMaterial(material);
overlay.setLocalTranslation(0, 0, 0);
return overlay;
}
/** /**
* Closes the popup and removes its associated GUI elements. * Closes the popup and removes its associated GUI elements.
*/ */
@Override @Override
public void close() { public void close() {
app.getGuiNode().detachChild(overlayBackground); app.getGuiNode().detachChild(foodFieldContainer); // Entferne das Menü
app.getGuiNode().detachChild(foodFieldContainer); app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
app.getGuiNode().detachChild(backgroundContainer); app.getGuiNode().detachChild(overlayBackground); // Entferne das Overlay
super.close(); super.close();
} }
/** /**
* Handles the escape key action by closing the popup. * Opens the settings menu when the escape key is pressed.
*/ */
@Override @Override
public void escape() { public void escape() {
close(); new SettingsMenu(app).open();
} }
} }

View File

@@ -1,15 +1,12 @@
package pp.monopoly.client.gui.popups; package pp.monopoly.client.gui.popups;
import com.jme3.math.ColorRGBA; import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.simsilica.lemur.Button; import com.simsilica.lemur.Button;
import com.simsilica.lemur.Container; import com.simsilica.lemur.Container;
import com.simsilica.lemur.Label; import com.simsilica.lemur.Label;
import com.simsilica.lemur.component.QuadBackgroundComponent; import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.style.ElementId; import com.simsilica.lemur.style.ElementId;
import pp.dialog.Dialog; import pp.dialog.Dialog;
import pp.dialog.PopupDialog;
import pp.monopoly.client.MonopolyApp; import pp.monopoly.client.MonopolyApp;
import pp.monopoly.client.gui.SettingsMenu; import pp.monopoly.client.gui.SettingsMenu;
import pp.monopoly.message.client.BuyPropertyResponse; import pp.monopoly.message.client.BuyPropertyResponse;
@@ -17,17 +14,17 @@ import pp.monopoly.model.fields.GateField;
import pp.monopoly.notification.Sound; import pp.monopoly.notification.Sound;
/** /**
* GateFieldCard creates the popup for field information. * GateFieldCard creates the popup for field information
*/ */
public class GateFieldCard extends Dialog implements PopupDialog { public class GateFieldCard extends Dialog {
/** Reference to the Monopoly application instance. */ /** Reference to the Monopoly application instance. */
private final MonopolyApp app; private final MonopolyApp app;
/** Main container for the gate field information. */ /** Main container for the gate field information. */
private Container gateFieldContainer; private final Container gateFieldContainer;
/** Background container providing a border for the popup. */ /** Background container providing a border for the popup. */
private Container backgroundContainer; private final Container backgroundContainer;
/** /**
* Constructs a GateFieldCard popup displaying details about a gate field. * Constructs a GateFieldCard popup displaying details about a gate field.
@@ -38,90 +35,73 @@ public class GateFieldCard extends Dialog implements PopupDialog {
super(app.getDialogManager()); super(app.getDialogManager());
this.app = app; this.app = app;
// Generate the corresponding field //Generate the corresponfing field
int index = app.getGameLogic().getPlayerHandler().getPlayerById(app.getId()).getFieldID(); int index = app.getGameLogic().getPlayerHandler().getPlayerById(app.getId()).getFieldID();
GateField field = (GateField) app.getGameLogic().getBoardManager().getFieldAtIndex(index); GateField field = (GateField) app.getGameLogic().getBoardManager().getFieldAtIndex(index);
// Initialize UI elements // Create the background container
createBackgroundContainer();
createGateFieldContainer(field);
}
/**
* Initializes the background container.
*/
private void createBackgroundContainer() {
backgroundContainer = new Container(); backgroundContainer = new Container();
backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Light gray background backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Darker background
gateFieldContainer.setPreferredSize(new Vector3f(360,420,1)); attachChild(backgroundContainer);
}
/** // Hauptcontainer für die Gebäudekarte
* Initializes the main gate field container and its UI components.
*
* @param field the gate field information to display
*/
private void createGateFieldContainer(GateField field) {
gateFieldContainer = new Container(); gateFieldContainer = new Container();
gateFieldContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); gateFieldContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f)));
// Title float padding = 10; // Passt den backgroundContainer an die Größe des gateFieldContainers an
backgroundContainer.setPreferredSize(gateFieldContainer.getPreferredSize().addLocal(padding, padding, 0));
// Titel, bestehend aus dynamischen Namen anhand der ID und der Schriftfarbe/größe
Label gateFieldTitle = gateFieldContainer.addChild(new Label(field.getName(), new ElementId("label-Bold"))); Label gateFieldTitle = gateFieldContainer.addChild(new Label(field.getName(), new ElementId("label-Bold")));
gateFieldTitle.setFontSize(48); gateFieldTitle.setFontSize(48);
gateFieldTitle.setColor(ColorRGBA.Black); gateFieldTitle.setColor(ColorRGBA.Black);
// Field details // Text, der auf der Karte steht
// Die Preise werden dynamisch dem BoardManager entnommen
Container propertyValuesContainer = gateFieldContainer.addChild(new Container()); Container propertyValuesContainer = gateFieldContainer.addChild(new Container());
propertyValuesContainer.addChild(new Label("„Preis: " + field.getPrice() + " EUR", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("„Preis: " + field.getPrice() + " EUR", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("", new ElementId("label-Text"))); // Empty line propertyValuesContainer.addChild(new Label("", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("Miete: 250 EUR", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("Miete: 250 EUR", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("Wenn man 2 Bahnhöfe besitzt: 500 EUR", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("Wenn man", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("Wenn man 3 Bahnhöfe besitzt: 1000 EUR", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("2 Bahnhof besitzt: 500 EUR", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("Wenn man 4 Bahnhöfe besitzt: 2000 EUR", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("Wenn man", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("", new ElementId("label-Text"))); // Empty line propertyValuesContainer.addChild(new Label("3 Bahnhof besitzt: 1000 EUR", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("Wenn man", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("4 Bahnhof besitzt: 2000 EUR", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("„Hypothek: " + field.getHypo() + " EUR", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("„Hypothek: " + field.getHypo() + " EUR", new ElementId("label-Text")));
propertyValuesContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f))); propertyValuesContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
// Quit button // Beenden-Button
Button quitButton = gateFieldContainer.addChild(new Button("Beenden", new ElementId("button"))); Button quitButton = gateFieldContainer.addChild(new Button("Beenden", new ElementId("button")));
quitButton.setFontSize(32); quitButton.setFontSize(32);
quitButton.addClickCommands(s -> ifTopDialog(() -> { quitButton.addClickCommands(s -> ifTopDialog( () -> {
app.getGameLogic().playSound(Sound.BUTTON); app.getGameLogic().playSound(Sound.BUTTON);
close(); close();
})); }));
// Kaufen-Button
// Buy button
Button buyButton = gateFieldContainer.addChild(new Button("Kaufen", new ElementId("button"))); Button buyButton = gateFieldContainer.addChild(new Button("Kaufen", new ElementId("button")));
buyButton.setFontSize(32); buyButton.setFontSize(32);
buyButton.addClickCommands(s -> ifTopDialog(() -> { buyButton.addClickCommands(s -> ifTopDialog( () -> {
app.getGameLogic().playSound(Sound.BUTTON); app.getGameLogic().playSound(Sound.BUTTON);
app.getGameLogic().send(new BuyPropertyResponse()); app.getGameLogic().send(new BuyPropertyResponse());
close(); close();
})); }));
}
/** // Zentriere das Popup
* Displays the popup by attaching its elements to the GUI.
*/
@Override
public void show() {
float padding = 10;
// Adjust sizes and center elements
backgroundContainer.setPreferredSize(gateFieldContainer.getPreferredSize().addLocal(padding, padding, 0));
gateFieldContainer.setLocalTranslation( gateFieldContainer.setLocalTranslation(
(app.getCamera().getWidth() - gateFieldContainer.getPreferredSize().x) / 2, (app.getCamera().getWidth() - gateFieldContainer.getPreferredSize().x) / 2,
(app.getCamera().getHeight() + gateFieldContainer.getPreferredSize().y) / 2, (app.getCamera().getHeight() + gateFieldContainer.getPreferredSize().y) / 2,
8 8
); );
// Zentriere das Popup
backgroundContainer.setLocalTranslation( backgroundContainer.setLocalTranslation(
(app.getCamera().getWidth() - gateFieldContainer.getPreferredSize().x - padding) / 2, (app.getCamera().getWidth() - gateFieldContainer.getPreferredSize().x - padding) / 2,
(app.getCamera().getHeight() + gateFieldContainer.getPreferredSize().y + padding) / 2, (app.getCamera().getHeight() + gateFieldContainer.getPreferredSize().y+ padding) / 2,
7 7
); );
// Attach components to the GUI
app.getGuiNode().attachChild(backgroundContainer);
app.getGuiNode().attachChild(gateFieldContainer); app.getGuiNode().attachChild(gateFieldContainer);
} }
@@ -130,8 +110,8 @@ public class GateFieldCard extends Dialog implements PopupDialog {
*/ */
@Override @Override
public void close() { public void close() {
app.getGuiNode().detachChild(gateFieldContainer); // Remove main container app.getGuiNode().detachChild(gateFieldContainer); // Entferne das Menü
app.getGuiNode().detachChild(backgroundContainer); // Remove background container app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
super.close(); super.close();
} }

View File

@@ -11,9 +11,7 @@ import com.simsilica.lemur.Container;
import com.simsilica.lemur.Label; import com.simsilica.lemur.Label;
import com.simsilica.lemur.component.QuadBackgroundComponent; import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.style.ElementId; import com.simsilica.lemur.style.ElementId;
import pp.dialog.Dialog; import pp.dialog.Dialog;
import pp.dialog.PopupDialog;
import pp.monopoly.client.MonopolyApp; import pp.monopoly.client.MonopolyApp;
import pp.monopoly.notification.Sound; import pp.monopoly.notification.Sound;
@@ -23,21 +21,21 @@ import pp.monopoly.notification.Sound;
* This popup informs the player that they are being sent to the Gulag and includes a confirmation button. * This popup informs the player that they are being sent to the Gulag and includes a confirmation button.
* </p> * </p>
*/ */
public class Gulag extends Dialog implements PopupDialog { public class Gulag extends Dialog {
/** Reference to the Monopoly application instance. */ /** Reference to the Monopoly application instance. */
private final MonopolyApp app; private final MonopolyApp app;
/** Semi-transparent overlay background for the popup. */ /** Semi-transparent overlay background for the popup. */
private Geometry overlayBackground; private final Geometry overlayBackground;
/** Main container for the Gulag warning message. */ /** Main container for the Gulag warning message. */
private Container gulagContainer; private final Container gulagContainer;
/** Background container providing a border for the popup. */ /** Background container providing a border for the popup. */
private Container backgroundContainer; private final Container backgroundContainer;
/** /**
* Constructs the Gulag popup. * Constructs the Gulag popup, displaying a warning when a player lands on the "Wache" field.
* *
* @param app the Monopoly application instance * @param app the Monopoly application instance
*/ */
@@ -45,97 +43,90 @@ public class Gulag extends Dialog implements PopupDialog {
super(app.getDialogManager()); super(app.getDialogManager());
this.app = app; this.app = app;
// Initialize UI elements
createOverlayBackground();
createBackgroundContainer();
createGulagContainer();
}
/** // Halbtransparentes Overlay hinzufügen
* Creates the semi-transparent overlay background for the popup. overlayBackground = createOverlayBackground();
*/ app.getGuiNode().attachChild(overlayBackground);
private void createOverlayBackground() {
Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight());
overlayBackground = new Geometry("Overlay", quad);
Material material = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); // Semi-transparent black
material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
overlayBackground.setMaterial(material);
overlayBackground.setLocalTranslation(0, 0, 0);
}
/** // Create the background container
* Creates the background container providing a border for the popup.
*/
private void createBackgroundContainer() {
backgroundContainer = new Container(); backgroundContainer = new Container();
backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Light gray background backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Darker background
} app.getGuiNode().attachChild(backgroundContainer);
/**
* Creates the main container for the Gulag warning message.
*/ // Hauptcontainer für die Warnung
private void createGulagContainer() {
gulagContainer = new Container(); gulagContainer = new Container();
gulagContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); gulagContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f)));
gulagContainer.setPreferredSize(new Vector3f(550, 250, 10)); gulagContainer.setPreferredSize(new Vector3f(550,250,10));
// Title float padding = 10; // Passt den backgroundContainer an die Größe des bankruptContainers an
Label title = gulagContainer.addChild(new Label("Du kommst ins Gulag!", new ElementId("warning-title"))); backgroundContainer.setPreferredSize(gulagContainer.getPreferredSize().addLocal(padding, padding, 0));
title.setFontSize(48);
title.setColor(ColorRGBA.Black);
// Confirmation Button // Titel
Button confirmButton = gulagContainer.addChild(new Button("Jawohl Gulag", new ElementId("button"))); Label gateFieldTitle = gulagContainer.addChild(new Label("Du kommst ins Gulag!", new ElementId("warning-title")));
confirmButton.setFontSize(32); gateFieldTitle.setFontSize(48);
confirmButton.addClickCommands(source -> ifTopDialog(() -> { gateFieldTitle.setColor(ColorRGBA.Black);
// Beenden-Button
Button quitButton = gulagContainer.addChild(new Button("Jawohl Gulag", new ElementId("button")));
quitButton.setFontSize(32);
quitButton.addClickCommands(source -> ifTopDialog(() -> {
app.getGameLogic().playSound(Sound.BUTTON); app.getGameLogic().playSound(Sound.BUTTON);
close(); close();
})); }));
}
/**
* Displays the popup by attaching its elements to the GUI.
*/
@Override
public void show() {
float padding = 10;
// Adjust and position the containers // Zentriere das Popup
backgroundContainer.setPreferredSize(gulagContainer.getPreferredSize().addLocal(padding, padding, 0));
gulagContainer.setLocalTranslation( gulagContainer.setLocalTranslation(
(app.getCamera().getWidth() - gulagContainer.getPreferredSize().x) / 2, (app.getCamera().getWidth() - gulagContainer.getPreferredSize().x) / 2,
(app.getCamera().getHeight() + gulagContainer.getPreferredSize().y) / 2, (app.getCamera().getHeight() + gulagContainer.getPreferredSize().y) / 2,
8 8
); );
// Zentriere das Popup
backgroundContainer.setLocalTranslation( backgroundContainer.setLocalTranslation(
(app.getCamera().getWidth() - gulagContainer.getPreferredSize().x - padding) / 2, (app.getCamera().getWidth() - gulagContainer.getPreferredSize().x - padding) / 2,
(app.getCamera().getHeight() + gulagContainer.getPreferredSize().y + padding) / 2, (app.getCamera().getHeight() + gulagContainer.getPreferredSize().y+ padding) / 2,
7 7
); );
// Attach components to the GUI
app.getGuiNode().attachChild(overlayBackground);
app.getGuiNode().attachChild(backgroundContainer);
app.getGuiNode().attachChild(gulagContainer); app.getGuiNode().attachChild(gulagContainer);
} }
/**
* Creates a semi-transparent overlay background for the popup.
*
* @return the geometry of the overlay
*/
private Geometry createOverlayBackground() {
Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight());
Geometry overlay = new Geometry("Overlay", quad);
Material material = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); // Halbtransparent
material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
overlay.setMaterial(material);
overlay.setLocalTranslation(0, 0, 0);
return overlay;
}
/** /**
* Closes the popup and removes its associated GUI elements. * Closes the popup and removes its associated GUI elements.
*/ */
@Override @Override
public void close() { public void close() {
app.getGuiNode().detachChild(overlayBackground); app.getGuiNode().detachChild(gulagContainer); // Entferne das Menü
app.getGuiNode().detachChild(gulagContainer); app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
app.getGuiNode().detachChild(backgroundContainer); app.getGuiNode().detachChild(overlayBackground); // Entferne das Overlay
super.close(); super.close();
} }
/** /**
* Handles the escape action by closing the popup. * Handles the escape action to close the popup.
*/ */
@Override @Override
public void escape() { public void escape() {
close(); close();
} }
} }

View File

@@ -7,138 +7,112 @@ import com.simsilica.lemur.Label;
import com.simsilica.lemur.component.QuadBackgroundComponent; import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.style.ElementId; import com.simsilica.lemur.style.ElementId;
import pp.dialog.Dialog; import pp.dialog.Dialog;
import pp.dialog.PopupDialog;
import pp.monopoly.client.MonopolyApp; import pp.monopoly.client.MonopolyApp;
import pp.monopoly.client.gui.SettingsMenu;
import pp.monopoly.message.client.NotificationAnswer; import pp.monopoly.message.client.NotificationAnswer;
import pp.monopoly.notification.Sound; import pp.monopoly.notification.Sound;
/** /**
* GulagInfo is a popup that provides options for a player who is stuck in the "Gulag" (jail) field. * GulagInfo is a popup that provides options for a player who is stuck in the "Gulag" (jail) field.
* <p>
* This dialog offers multiple actions, including paying a bribe, using a "Get Out of Jail" card, or waiting. * This dialog offers multiple actions, including paying a bribe, using a "Get Out of Jail" card, or waiting.
* </p>
*/ */
public class GulagInfo extends Dialog implements PopupDialog { public class GulagInfo extends Dialog {
/** Reference to the Monopoly application instance. */ /** Reference to the Monopoly application instance. */
private final MonopolyApp app; private final MonopolyApp app;
/** Main container for the Gulag information dialog. */ /** Main container for the Gulag information dialog. */
private Container gulagInfoContainer; private final Container gulagInfoContainer;
/** Background container providing a styled border around the dialog. */ /** Background container providing a styled border around the dialog. */
private Container backgroundContainer; private final Container backgroundContainer;
/** /**
* Constructs a GulagInfo popup that provides the player with options for getting out of the "Gulag" field. * Constructs a GulagInfo popup that provides the player with options for getting out of the "Gulag" field.
* *
* @param app the Monopoly application instance * @param app the Monopoly application instance
* @param trys the number of failed attempts to roll doubles for release * @param trys the number of failed attempts to roll doubles for release
*/ */
public GulagInfo(MonopolyApp app, int trys) { public GulagInfo(MonopolyApp app, int trys) {
super(app.getDialogManager()); super(app.getDialogManager());
this.app = app; this.app = app;
// Initialize UI components // Create the background container
createBackgroundContainer();
createGulagInfoContainer(trys);
}
/**
* Creates the background container providing a border for the dialog.
*/
private void createBackgroundContainer() {
backgroundContainer = new Container(); backgroundContainer = new Container();
backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Light gray background backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Darker background
} attachChild(backgroundContainer);
/** // Hauptcontainer für das Bestätigungspopup
* Creates the main container for the Gulag information dialog.
*
* @param trys the number of failed attempts to roll doubles for release
*/
private void createGulagInfoContainer(int trys) {
gulagInfoContainer = new Container(); gulagInfoContainer = new Container();
gulagInfoContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f)));
// Title float padding = 10; // Passt den backgroundContainer an die Größe des confirmTradeContainer an
Label title = gulagInfoContainer.addChild(new Label("Gulag", new ElementId("warning-title"))); backgroundContainer.setPreferredSize(gulagInfoContainer.getPreferredSize().addLocal(padding, padding, 0));
// Titel
Label title = gulagInfoContainer.addChild(new Label( "Gulag", new ElementId("warning-title")));
title.setFontSize(48); title.setFontSize(48);
title.setColor(ColorRGBA.Black); title.setColor(ColorRGBA.Black);
// Text Description // Text, der auf der Karte steht
Container textContainer = gulagInfoContainer.addChild(new Container()); // Die Werte werden dem Handel entnommen (Iwas auch immer da dann ist)
textContainer.addChild(new Label("„Du sitzt im Gefängnis und kommst nicht raus ...", new ElementId("label-Text"))); Container propertyValuesContainer = gulagInfoContainer.addChild(new Container());
textContainer.addChild(new Label("Es sei denn, du ...", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("„Du sitzt im Gefänginis und kommst nicht raus ...", new ElementId("label-Text")));
textContainer.addChild(new Label("- bestichst die Wache mit 500 EUR", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("Es sei denn, du ...", new ElementId("label-Text")));// Leerzeile
textContainer.addChild(new Label("- löst eine Gulag-Frei-Karte ein", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("", new ElementId("label-Text")));
textContainer.addChild(new Label("- wartest 3 Runden und bezahlst dann", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("- bestichst die Wache mit 500 EUR", new ElementId("label-Text")));
textContainer.addChild(new Label("- oder du würfelst einen Pasch", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("- löst eine Gulag-Frei-Karte ein", new ElementId("label-Text")));
textContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f))); propertyValuesContainer.addChild(new Label("- wartest 3 Runden und bezahlst dann", new ElementId("label-Text")));// Leerzeile
propertyValuesContainer.addChild(new Label("- oder du würfelst einen Pasch", new ElementId("label-Text")));
propertyValuesContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
// Action Buttons
addActionButtons(trys);
}
/** // Bezahlen-Button
* Adds action buttons to the dialog.
*
* @param trys the number of failed attempts to roll doubles for release
*/
private void addActionButtons(int trys) {
// Bribe Button
Button payButton = gulagInfoContainer.addChild(new Button("Bestechungsgeld bezahlen", new ElementId("button"))); Button payButton = gulagInfoContainer.addChild(new Button("Bestechungsgeld bezahlen", new ElementId("button")));
payButton.setFontSize(32); payButton.setFontSize(32);
payButton.addClickCommands(s -> ifTopDialog(() -> { payButton.addClickCommands(s -> ifTopDialog( () -> {
app.getGameLogic().playSound(Sound.BUTTON); app.getGameLogic().playSound(Sound.BUTTON);
app.getGameLogic().send(new NotificationAnswer("PayJail")); app.getGameLogic().send(new NotificationAnswer("PayJail"));
close(); close();
})); }));
// Ereigniskarte-Button
// Use Jail-Free Card Button Button eventCardButton = gulagInfoContainer.addChild(new Button("Ereigniskarte nutzen", new ElementId("button")));
Button eventCardButton = gulagInfoContainer.addChild(new Button("Ereigniskarte nutzen", new ElementId("button-toolbar2")));
eventCardButton.setFontSize(32); eventCardButton.setFontSize(32);
eventCardButton.addClickCommands(s -> ifTopDialog(() -> { eventCardButton.addClickCommands(s -> ifTopDialog( () -> {
app.getGameLogic().playSound(Sound.BUTTON); app.getGameLogic().playSound(Sound.BUTTON);
app.getGameLogic().send(new NotificationAnswer("UseJailCard")); app.getGameLogic().send(new NotificationAnswer("UseJailCard"));
close(); close();
})); }));
// Schließen-Button
// Close Button
Button closeButton = gulagInfoContainer.addChild(new Button("Schließen", new ElementId("button"))); Button closeButton = gulagInfoContainer.addChild(new Button("Schließen", new ElementId("button")));
closeButton.setFontSize(32); closeButton.setFontSize(32);
closeButton.addClickCommands(s -> ifTopDialog(this::close)); closeButton.addClickCommands(s -> ifTopDialog(() -> {
app.getGameLogic().playSound(Sound.BUTTON);
close();
}));
// Disable options based on conditions // Zentriere das Menü
if (app.getGameLogic().getPlayerHandler().getPlayerById(app.getId()).getNumJailCard() == 0) {
eventCardButton.setEnabled(false);
}
if (trys == 3) {
closeButton.setEnabled(false);
}
}
/**
* Displays the popup by attaching its elements to the GUI.
*/
@Override
public void show() {
float padding = 10;
// Adjust the background size
backgroundContainer.setPreferredSize(gulagInfoContainer.getPreferredSize().addLocal(padding, padding, 0));
// Center the dialog and background
gulagInfoContainer.setLocalTranslation( gulagInfoContainer.setLocalTranslation(
(app.getCamera().getWidth() - gulagInfoContainer.getPreferredSize().x) / 2, (app.getCamera().getWidth() - gulagInfoContainer.getPreferredSize().x) / 2,
(app.getCamera().getHeight() + gulagInfoContainer.getPreferredSize().y) / 2, (app.getCamera().getHeight() + gulagInfoContainer.getPreferredSize().y) / 2,
8 8
); );
// Zentriere das Menü
backgroundContainer.setLocalTranslation( backgroundContainer.setLocalTranslation(
(app.getCamera().getWidth() - gulagInfoContainer.getPreferredSize().x - padding) / 2, (app.getCamera().getWidth() - gulagInfoContainer.getPreferredSize().x - padding) / 2,
(app.getCamera().getHeight() + gulagInfoContainer.getPreferredSize().y + padding) / 2, (app.getCamera().getHeight() + gulagInfoContainer.getPreferredSize().y+ padding) / 2,
7 7
); );
// Attach containers to the GUI if(app.getGameLogic().getPlayerHandler().getPlayerById(app.getId()).getNumJailCard() == 0) {
app.getGuiNode().attachChild(backgroundContainer); eventCardButton.setEnabled(false);
}
if(trys == 3) {
closeButton.setEnabled(false);
}
app.getGuiNode().attachChild(gulagInfoContainer); app.getGuiNode().attachChild(gulagInfoContainer);
} }
@@ -147,8 +121,16 @@ public class GulagInfo extends Dialog implements PopupDialog {
*/ */
@Override @Override
public void close() { public void close() {
app.getGuiNode().detachChild(gulagInfoContainer); // Remove dialog app.getGuiNode().detachChild(gulagInfoContainer); // Entferne das Menü
app.getGuiNode().detachChild(backgroundContainer); // Remove background app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
super.close(); super.close();
} }
/**
* Handles the escape action to close the GulagInfo dialog.
*/
@Override
public void escape() {
new SettingsMenu(app).open();
}
} }

View File

@@ -12,14 +12,19 @@ import com.simsilica.lemur.Label;
import com.simsilica.lemur.component.QuadBackgroundComponent; import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.style.ElementId; import com.simsilica.lemur.style.ElementId;
import pp.dialog.Dialog; import pp.dialog.Dialog;
import pp.dialog.PopupDialog;
import pp.monopoly.client.MonopolyApp; import pp.monopoly.client.MonopolyApp;
import pp.monopoly.notification.Sound; import pp.monopoly.notification.Sound;
/** /**
* NoMoneyWarning is a warning popup that informs the player they lack sufficient funds to proceed with an action. * NoMoneyWarning is a warning popup that appears when a player tries to perform
* an action they cannot afford due to insufficient funds, such as attempting
* to purchase a property or building.
* <p>
* This dialog notifies the player of their lack of funds and provides a single
* confirmation button to close the dialog.
* </p>
*/ */
public class NoMoneyWarning extends Dialog implements PopupDialog { public class NoMoneyWarning extends Dialog {
/** Reference to the Monopoly application instance. */ /** Reference to the Monopoly application instance. */
private final MonopolyApp app; private final MonopolyApp app;
@@ -41,15 +46,66 @@ public class NoMoneyWarning extends Dialog implements PopupDialog {
super(app.getDialogManager()); super(app.getDialogManager());
this.app = app; this.app = app;
overlayBackground = createOverlayBackground();
backgroundContainer = createBackgroundContainer();
noMoneyWarningContainer = createNoMoneyWarningContainer();
adjustPaddingAndCenter(); // Halbtransparentes Overlay hinzufügen
overlayBackground = createOverlayBackground();
app.getGuiNode().attachChild(overlayBackground);
// Create the background container
backgroundContainer = new Container();
backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Darker background
app.getGuiNode().attachChild(backgroundContainer);
// Hauptcontainer für die Warnung
noMoneyWarningContainer = new Container();
noMoneyWarningContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f)));
noMoneyWarningContainer.setPreferredSize(new Vector3f(550,250,10));
float padding = 10; // Passt den backgroundContainer an die Größe des bankruptContainers an
backgroundContainer.setPreferredSize(noMoneyWarningContainer.getPreferredSize().addLocal(padding, padding, 0));
// Titel
Label gateFieldTitle = noMoneyWarningContainer.addChild(new Label("Na, schon wieder Pleite?", new ElementId("warning-title")));
gateFieldTitle.setFontSize(38);
gateFieldTitle.setColor(ColorRGBA.Black);
// Text, der im Popup steht
Container textContainer = noMoneyWarningContainer.addChild(new Container());
textContainer.addChild(new Label("Du hast nicht genug Geld, um dieses Gebäude zu kaufen", new ElementId("label-Text")));
textContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
// Passt den textContainer an die Größe des bankruptContainers an
textContainer.setPreferredSize(noMoneyWarningContainer.getPreferredSize().addLocal(-250,-200,0));
// Bestätigen-Button
Button quitButton = noMoneyWarningContainer.addChild(new Button("Bestätigen", new ElementId("button")));
quitButton.setFontSize(32);
quitButton.addClickCommands(source -> ifTopDialog(() -> {
app.getGameLogic().playSound(Sound.BUTTON);
close();
}));
// Zentriere das Popup
noMoneyWarningContainer.setLocalTranslation(
(app.getCamera().getWidth() - noMoneyWarningContainer.getPreferredSize().x) / 2,
(app.getCamera().getHeight() + noMoneyWarningContainer.getPreferredSize().y) / 2,
8
);
// Zentriere das Popup
backgroundContainer.setLocalTranslation(
(app.getCamera().getWidth() - noMoneyWarningContainer.getPreferredSize().x - padding) / 2,
(app.getCamera().getHeight() + noMoneyWarningContainer.getPreferredSize().y+ padding) / 2,
7
);
app.getGuiNode().attachChild(noMoneyWarningContainer);
} }
/** /**
* Creates the semi-transparent overlay background. * Creates a semi-transparent overlay background for the dialog.
* *
* @return The geometry representing the overlay background. * @return The geometry representing the overlay background.
*/ */
@@ -57,7 +113,7 @@ public class NoMoneyWarning extends Dialog implements PopupDialog {
Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight()); Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight());
Geometry overlay = new Geometry("Overlay", quad); Geometry overlay = new Geometry("Overlay", quad);
Material material = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); Material material = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); // Semi-transparent black material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); // Halbtransparent
material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha); material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
overlay.setMaterial(material); overlay.setMaterial(material);
overlay.setLocalTranslation(0, 0, 0); overlay.setLocalTranslation(0, 0, 0);
@@ -65,86 +121,13 @@ public class NoMoneyWarning extends Dialog implements PopupDialog {
} }
/** /**
* Creates the background container for the dialog. * Closes the menu and removes the GUI elements.
*
* @return A styled container for the dialog background.
*/
private Container createBackgroundContainer() {
Container container = new Container();
container.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Light gray
return container;
}
/**
* Creates the main container for the NoMoneyWarning dialog UI.
*
* @return The container for the dialog content.
*/
private Container createNoMoneyWarningContainer() {
Container container = new Container();
container.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f)));
container.setPreferredSize(new Vector3f(550, 250, 10));
// Title
Label title = container.addChild(new Label("Na, schon wieder Pleite?", new ElementId("warning-title")));
title.setFontSize(38);
title.setColor(ColorRGBA.Black);
// Warning message
Container textContainer = container.addChild(new Container());
textContainer.addChild(new Label("Du hast nicht genug Geld, um dieses Gebäude zu kaufen", new ElementId("label-Text")));
textContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
textContainer.setPreferredSize(container.getPreferredSize().addLocal(-250, -200, 0));
// Confirmation button
Button confirmButton = container.addChild(new Button("Bestätigen", new ElementId("button")));
confirmButton.setFontSize(32);
confirmButton.addClickCommands(source -> ifTopDialog(() -> {
app.getGameLogic().playSound(Sound.BUTTON);
close();
}));
return container;
}
/**
* Adjusts the padding and centers the dialog on the screen.
*/
private void adjustPaddingAndCenter() {
float padding = 10;
backgroundContainer.setPreferredSize(noMoneyWarningContainer.getPreferredSize().addLocal(padding, padding, 0));
noMoneyWarningContainer.setLocalTranslation(
(app.getCamera().getWidth() - noMoneyWarningContainer.getPreferredSize().x) / 2,
(app.getCamera().getHeight() + noMoneyWarningContainer.getPreferredSize().y) / 2,
8
);
backgroundContainer.setLocalTranslation(
(app.getCamera().getWidth() - backgroundContainer.getPreferredSize().x) / 2,
(app.getCamera().getHeight() + backgroundContainer.getPreferredSize().y) / 2,
7
);
}
/**
* Displays the dialog by attaching its components to the GUI node.
*/
@Override
public void show() {
app.getGuiNode().attachChild(overlayBackground);
app.getGuiNode().attachChild(backgroundContainer);
app.getGuiNode().attachChild(noMoneyWarningContainer);
}
/**
* Closes the dialog and removes its components from the GUI node.
*/ */
@Override @Override
public void close() { public void close() {
app.getGuiNode().detachChild(overlayBackground); app.getGuiNode().detachChild(noMoneyWarningContainer); // Entferne das Menü
app.getGuiNode().detachChild(backgroundContainer); app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
app.getGuiNode().detachChild(noMoneyWarningContainer); app.getGuiNode().detachChild(overlayBackground); // Entferne das Overlay
super.close(); super.close();
} }

View File

@@ -12,95 +12,115 @@ import com.simsilica.lemur.Label;
import com.simsilica.lemur.component.QuadBackgroundComponent; import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.style.ElementId; import com.simsilica.lemur.style.ElementId;
import pp.dialog.Dialog; import pp.dialog.Dialog;
import pp.dialog.PopupDialog;
import pp.monopoly.client.MonopolyApp; import pp.monopoly.client.MonopolyApp;
import pp.monopoly.notification.Sound; import pp.monopoly.notification.Sound;
/** /**
* ReceivedRent is a popup that informs a player about rent they have received. * Rent is a popup that is triggered when a player lands on a property owned by another player
* and needs to pay rent in the Monopoly application.
* <p>
* Displays the rent amount and the recipient player's name, with an option to confirm the payment.
* </p>
*/ */
public class ReceivedRent extends Dialog implements PopupDialog { public class ReceivedRent extends Dialog {
/** Reference to the Monopoly application instance. */ /** Reference to the Monopoly application instance. */
private final MonopolyApp app; private final MonopolyApp app;
/** Semi-transparent overlay background for the popup. */ /** Semi-transparent overlay background for the popup. */
private Geometry overlayBackground; private final Geometry overlayBackground;
/** Main container for the rent information and action. */ /** Main container for the rent information and action. */
private Container rentContainer; private final Container rentContainer;
/** Background container providing a border for the rent popup. */ /** Background container providing a border for the rent popup. */
private Container backgroundContainer; private final Container backgroundContainer;
/** /**
* Constructs the ReceivedRent popup displaying the rent amount and payer. * Constructs the Rent popup displaying the rent amount and recipient player.
* *
* @param app the Monopoly application instance * @param app the Monopoly application instance
* @param playerName the name of the player who paid the rent * @param playerName the name of the player to whom the rent is owed
* @param amount the amount of rent received * @param amount the amount of rent to be paid
*/ */
public ReceivedRent(MonopolyApp app, String playerName, int amount) { public ReceivedRent(MonopolyApp app, String playerName, int amount) {
super(app.getDialogManager()); super(app.getDialogManager());
this.app = app; this.app = app;
// Initialize GUI elements // Create the overlay
createOverlayBackground(); overlayBackground = createOverlayBackground();
createBackgroundContainer(); app.getGuiNode().attachChild(overlayBackground);
createRentContainer(playerName, amount);
// Create and position the background container
backgroundContainer = createBackgroundContainer();
app.getGuiNode().attachChild(backgroundContainer);
// Create and position the rent container
rentContainer = createRentContainer(playerName, amount);
app.getGuiNode().attachChild(rentContainer);
centerContainers();
} }
/** /**
* Creates a semi-transparent overlay background. * Creates a semi-transparent overlay background.
*
* @return the overlay geometry
*/ */
private void createOverlayBackground() { private Geometry createOverlayBackground() {
Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight()); Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight());
overlayBackground = new Geometry("Overlay", quad); Geometry overlay = new Geometry("Overlay", quad);
Material material = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); Material material = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); // Semi-transparent black material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); // Semi-transparent black
material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha); material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
overlayBackground.setMaterial(material); overlay.setMaterial(material);
overlayBackground.setLocalTranslation(0, 0, 0); overlay.setLocalTranslation(0, 0, 0);
return overlay;
} }
/** /**
* Creates the background container with styling. * Creates the background container with styling.
*
* @return the styled background container
*/ */
private void createBackgroundContainer() { private Container createBackgroundContainer() {
backgroundContainer = new Container(); Container container = new Container();
backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Light gray background container.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Light gray background
return container;
} }
/** /**
* Creates the main rent container with title, text, and button. * Creates the main rent container with title, text, and button.
* *
* @param playerName the name of the player who paid the rent * @param playerName the name of the player to whom the rent is owed
* @param amount the rent amount * @param amount the rent amount
* @return the rent container
*/ */
private void createRentContainer(String playerName, int amount) { private Container createRentContainer(String playerName, int amount) {
rentContainer = new Container(); Container container = new Container();
rentContainer.setBackground(new QuadBackgroundComponent(ColorRGBA.Gray)); container.setBackground(new QuadBackgroundComponent(ColorRGBA.Gray));
rentContainer.setPreferredSize(new Vector3f(550, 250, 10)); container.setPreferredSize(new Vector3f(550, 250, 10));
// Title // Title
Label title = rentContainer.addChild(new Label("Miete!", new ElementId("warning-title"))); Label title = container.addChild(new Label("Miete!", new ElementId("warning-title")));
title.setFontSize(48); title.setFontSize(48);
title.setColor(ColorRGBA.Black); title.setColor(ColorRGBA.Black);
// Rent message // Rent message
Container textContainer = rentContainer.addChild(new Container()); Container textContainer = container.addChild(new Container());
textContainer.addChild(new Label(playerName + " zahlt dir " + amount + " EUR Miete", textContainer.addChild(new Label(playerName+ " zahlt dir " + amount + " EUR Miete",
new ElementId("label-Text"))); new ElementId("label-Text")));
textContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f))); textContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
textContainer.setPreferredSize(rentContainer.getPreferredSize().addLocal(-250, -200, 0)); textContainer.setPreferredSize(container.getPreferredSize().addLocal(-250, -200, 0));
// Confirmation button // Payment button
Button confirmButton = rentContainer.addChild(new Button("Bestätigen", new ElementId("button"))); Button payButton = container.addChild(new Button("Bestätigen", new ElementId("button")));
confirmButton.setFontSize(32); payButton.setFontSize(32);
confirmButton.addClickCommands(s -> ifTopDialog(() -> { payButton.addClickCommands(s -> ifTopDialog( () -> {
app.getGameLogic().playSound(Sound.BUTTON); app.getGameLogic().playSound(Sound.BUTTON);
close(); close();
})); }));
return container;
} }
/** /**
@@ -125,25 +145,14 @@ public class ReceivedRent extends Dialog implements PopupDialog {
); );
} }
/**
* Displays the popup by attaching it to the GUI through the DialogManager.
*/
@Override
public void show() {
app.getGuiNode().attachChild(overlayBackground);
app.getGuiNode().attachChild(backgroundContainer);
app.getGuiNode().attachChild(rentContainer);
centerContainers();
}
/** /**
* Closes the popup and removes GUI elements. * Closes the popup and removes GUI elements.
*/ */
@Override @Override
public void close() { public void close() {
app.getGuiNode().detachChild(overlayBackground);
app.getGuiNode().detachChild(backgroundContainer);
app.getGuiNode().detachChild(rentContainer); app.getGuiNode().detachChild(rentContainer);
app.getGuiNode().detachChild(backgroundContainer);
app.getGuiNode().detachChild(overlayBackground);
super.close(); super.close();
} }

View File

@@ -12,16 +12,19 @@ import com.simsilica.lemur.Label;
import com.simsilica.lemur.component.QuadBackgroundComponent; import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.style.ElementId; import com.simsilica.lemur.style.ElementId;
import pp.dialog.Dialog; import pp.dialog.Dialog;
import pp.dialog.PopupDialog;
import pp.monopoly.client.MonopolyApp; import pp.monopoly.client.MonopolyApp;
import pp.monopoly.message.server.TradeReply; import pp.monopoly.message.server.TradeReply;
import pp.monopoly.notification.Sound; import pp.monopoly.notification.Sound;
/** /**
* RejectTrade is a popup that appears when a trade proposal is rejected by another player. * RejectTrade is a popup that appears when a trade proposal is rejected by another player
* Displays a message indicating the rejection and provides an option to close the popup. * in the Monopoly application.
* <p>
* Displays a message indicating that the proposed trade has been declined, along with
* details of the involved players and provides an option to close the popup.
* </p>
*/ */
public class RejectTrade extends Dialog implements PopupDialog { public class RejectTrade extends Dialog {
/** Reference to the Monopoly application instance. */ /** Reference to the Monopoly application instance. */
private final MonopolyApp app; private final MonopolyApp app;
@@ -29,11 +32,12 @@ public class RejectTrade extends Dialog implements PopupDialog {
private final Geometry overlayBackground; private final Geometry overlayBackground;
/** Main container for the rejection message content. */ /** Main container for the rejection message content. */
private final Container rejectTradeContainer; private final Container noMoneyWarningContainer;
/** Background container providing a border for the popup. */ /** Background container providing a border for the popup. */
private final Container backgroundContainer; private final Container backgroundContainer;
/** /**
* Constructs the RejectTrade popup displaying the rejection of a trade proposal. * Constructs the RejectTrade popup displaying the rejection of a trade proposal.
* *
@@ -44,15 +48,68 @@ public class RejectTrade extends Dialog implements PopupDialog {
super(app.getDialogManager()); super(app.getDialogManager());
this.app = app; this.app = app;
overlayBackground = createOverlayBackground();
backgroundContainer = createBackgroundContainer();
rejectTradeContainer = createRejectTradeContainer(msg);
adjustPaddingAndCenter(); // Halbtransparentes Overlay hinzufügen
overlayBackground = createOverlayBackground();
app.getGuiNode().attachChild(overlayBackground);
// Create the background container
backgroundContainer = new Container();
backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Darker background
app.getGuiNode().attachChild(backgroundContainer);
// Hauptcontainer für die Warnung
noMoneyWarningContainer = new Container();
noMoneyWarningContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f)));
noMoneyWarningContainer.setPreferredSize(new Vector3f(550,250,10));
float padding = 10; // Passt den backgroundContainer an die Größe des bankruptContainers an
backgroundContainer.setPreferredSize(noMoneyWarningContainer.getPreferredSize().addLocal(padding, padding, 0));
// Titel
Label gateFieldTitle = noMoneyWarningContainer.addChild(new Label("Handel abgelehnt!", new ElementId("warning-title")));
gateFieldTitle.setFontSize(48);
gateFieldTitle.setColor(ColorRGBA.Black);
// Text, der im Popup steht
Container textContainer = noMoneyWarningContainer.addChild(new Container());
textContainer.addChild(new Label("Du hast Spieler"+ " " + msg.getTradeHandler().getReceiver().getName() + " " + "einen Handel vorgeschlagen", new ElementId("label-Text")));
textContainer.addChild(new Label("", new ElementId("label-Text")));
textContainer.addChild(new Label("Der Handel wurde abgelehnt", new ElementId("label-Text")));
textContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
// Passt den textContainer an die Größe des bankruptContainers an
textContainer.setPreferredSize(noMoneyWarningContainer.getPreferredSize().addLocal(-250,-200,0));
// Beenden-Button
Button quitButton = noMoneyWarningContainer.addChild(new Button("Bestätigen", new ElementId("button")));
quitButton.setFontSize(32);
quitButton.addClickCommands(source -> ifTopDialog(() -> {
app.getGameLogic().playSound(Sound.BUTTON);
close();
}));
// Zentriere das Popup
noMoneyWarningContainer.setLocalTranslation(
(app.getCamera().getWidth() - noMoneyWarningContainer.getPreferredSize().x) / 2,
(app.getCamera().getHeight() + noMoneyWarningContainer.getPreferredSize().y) / 2,
8
);
// Zentriere das Popup
backgroundContainer.setLocalTranslation(
(app.getCamera().getWidth() - noMoneyWarningContainer.getPreferredSize().x - padding) / 2,
(app.getCamera().getHeight() + noMoneyWarningContainer.getPreferredSize().y+ padding) / 2,
7
);
app.getGuiNode().attachChild(noMoneyWarningContainer);
} }
/** /**
* Creates the semi-transparent background overlay for the popup. * Creates a semi-transparent background overlay for the popup.
* *
* @return the geometry of the overlay * @return the geometry of the overlay
*/ */
@@ -60,98 +117,21 @@ public class RejectTrade extends Dialog implements PopupDialog {
Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight()); Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight());
Geometry overlay = new Geometry("Overlay", quad); Geometry overlay = new Geometry("Overlay", quad);
Material material = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); Material material = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); // Semi-transparent black material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); // Halbtransparent
material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha); material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
overlay.setMaterial(material); overlay.setMaterial(material);
overlay.setLocalTranslation(0, 0, 0); overlay.setLocalTranslation(0, 0, 0);
return overlay; return overlay;
} }
/**
* Creates the background container for the dialog.
*
* @return A styled container for the dialog background.
*/
private Container createBackgroundContainer() {
Container container = new Container();
container.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Light gray background
return container;
}
/**
* Creates the main container for the RejectTrade dialog UI.
*
* @param msg the trade reply message containing details about the rejected trade
* @return The container for the rejection message and action button
*/
private Container createRejectTradeContainer(TradeReply msg) {
Container container = new Container();
container.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f)));
container.setPreferredSize(new Vector3f(550, 250, 10));
// Title
Label title = container.addChild(new Label("Handel abgelehnt!", new ElementId("warning-title")));
title.setFontSize(48);
title.setColor(ColorRGBA.Black);
// Rejection message
Container textContainer = container.addChild(new Container());
textContainer.addChild(new Label("Du hast Spieler " + msg.getTradeHandler().getReceiver().getName()
+ " einen Handel vorgeschlagen.", new ElementId("label-Text")));
textContainer.addChild(new Label("", new ElementId("label-Text")));
textContainer.addChild(new Label("Der Handel wurde abgelehnt.", new ElementId("label-Text")));
textContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
textContainer.setPreferredSize(container.getPreferredSize().addLocal(-250, -200, 0));
// Confirmation button
Button confirmButton = container.addChild(new Button("Bestätigen", new ElementId("button")));
confirmButton.setFontSize(32);
confirmButton.addClickCommands(source -> ifTopDialog(() -> {
app.getGameLogic().playSound(Sound.BUTTON);
close();
}));
return container;
}
/**
* Adjusts the padding and centers the dialog on the screen.
*/
private void adjustPaddingAndCenter() {
float padding = 10;
backgroundContainer.setPreferredSize(rejectTradeContainer.getPreferredSize().addLocal(padding, padding, 0));
rejectTradeContainer.setLocalTranslation(
(app.getCamera().getWidth() - rejectTradeContainer.getPreferredSize().x) / 2,
(app.getCamera().getHeight() + rejectTradeContainer.getPreferredSize().y) / 2,
8
);
backgroundContainer.setLocalTranslation(
(app.getCamera().getWidth() - backgroundContainer.getPreferredSize().x) / 2,
(app.getCamera().getHeight() + backgroundContainer.getPreferredSize().y) / 2,
7
);
}
/**
* Displays the popup by attaching its elements to the GUI node.
*/
@Override
public void show() {
app.getGuiNode().attachChild(overlayBackground);
app.getGuiNode().attachChild(backgroundContainer);
app.getGuiNode().attachChild(rejectTradeContainer);
}
/** /**
* Closes the menu and removes the GUI elements. * Closes the menu and removes the GUI elements.
*/ */
@Override @Override
public void close() { public void close() {
app.getGuiNode().detachChild(overlayBackground); app.getGuiNode().detachChild(noMoneyWarningContainer); // Entferne das Menü
app.getGuiNode().detachChild(backgroundContainer); app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
app.getGuiNode().detachChild(rejectTradeContainer); app.getGuiNode().detachChild(overlayBackground); // Entferne das Overlay
super.close(); super.close();
} }

View File

@@ -12,7 +12,6 @@ import com.simsilica.lemur.Label;
import com.simsilica.lemur.component.QuadBackgroundComponent; import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.style.ElementId; import com.simsilica.lemur.style.ElementId;
import pp.dialog.Dialog; import pp.dialog.Dialog;
import pp.dialog.PopupDialog;
import pp.monopoly.client.MonopolyApp; import pp.monopoly.client.MonopolyApp;
import pp.monopoly.notification.Sound; import pp.monopoly.notification.Sound;
@@ -23,77 +22,122 @@ import pp.monopoly.notification.Sound;
* Displays the rent amount and the recipient player's name, with an option to confirm the payment. * Displays the rent amount and the recipient player's name, with an option to confirm the payment.
* </p> * </p>
*/ */
public class Rent extends Dialog implements PopupDialog { public class Rent extends Dialog {
/** Reference to the Monopoly application instance. */
private final MonopolyApp app; private final MonopolyApp app;
/** Semi-transparent overlay background for the popup. */
private final Geometry overlayBackground; private final Geometry overlayBackground;
/** Main container for the rent information and action. */
private final Container rentContainer; private final Container rentContainer;
/** Background container providing a border for the rent popup. */
private final Container backgroundContainer; private final Container backgroundContainer;
/**
* Constructs the Rent popup displaying the rent amount and recipient player.
*
* @param app the Monopoly application instance
* @param playerName the name of the player to whom the rent is owed
* @param amount the amount of rent to be paid
*/
public Rent(MonopolyApp app, String playerName, int amount) { public Rent(MonopolyApp app, String playerName, int amount) {
super(app.getDialogManager()); super(app.getDialogManager());
this.app = app; this.app = app;
// Create the overlay and containers // Create the overlay
overlayBackground = createOverlayBackground(); overlayBackground = createOverlayBackground();
backgroundContainer = createBackgroundContainer(); app.getGuiNode().attachChild(overlayBackground);
rentContainer = createRentContainer(playerName, amount);
// Create and position the background container
backgroundContainer = createBackgroundContainer();
app.getGuiNode().attachChild(backgroundContainer);
// Create and position the rent container
rentContainer = createRentContainer(playerName, amount);
app.getGuiNode().attachChild(rentContainer);
// Center containers (positioning logic only, no GUI attachment)
centerContainers(); centerContainers();
} }
/**
* Creates a semi-transparent overlay background.
*
* @return the overlay geometry
*/
private Geometry createOverlayBackground() { private Geometry createOverlayBackground() {
Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight()); Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight());
Geometry overlay = new Geometry("Overlay", quad); Geometry overlay = new Geometry("Overlay", quad);
Material material = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); Material material = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); // Semi-transparent black
material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha); material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
overlay.setMaterial(material); overlay.setMaterial(material);
overlay.setLocalTranslation(0, 0, 0); overlay.setLocalTranslation(0, 0, 0);
return overlay; return overlay;
} }
/**
* Creates the background container with styling.
*
* @return the styled background container
*/
private Container createBackgroundContainer() { private Container createBackgroundContainer() {
Container container = new Container(); Container container = new Container();
container.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); container.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Light gray background
return container; return container;
} }
/**
* Creates the main rent container with title, text, and button.
*
* @param playerName the name of the player to whom the rent is owed
* @param amount the rent amount
* @return the rent container
*/
private Container createRentContainer(String playerName, int amount) { private Container createRentContainer(String playerName, int amount) {
Container container = new Container(); Container container = new Container();
container.setBackground(new QuadBackgroundComponent(ColorRGBA.Gray)); container.setBackground(new QuadBackgroundComponent(ColorRGBA.Gray));
container.setPreferredSize(new Vector3f(550, 250, 10)); container.setPreferredSize(new Vector3f(550, 250, 10));
// Title
Label title = container.addChild(new Label("Miete!", new ElementId("warning-title"))); Label title = container.addChild(new Label("Miete!", new ElementId("warning-title")));
title.setFontSize(48); title.setFontSize(48);
title.setColor(ColorRGBA.Black); title.setColor(ColorRGBA.Black);
// Rent message
Container textContainer = container.addChild(new Container()); Container textContainer = container.addChild(new Container());
textContainer.addChild(new Label("Du musst " + amount + " EUR Miete an " + playerName + " zahlen", textContainer.addChild(new Label("Du musst " + amount + " EUR Miete an " + playerName + " zahlen",
new ElementId("label-Text"))); new ElementId("label-Text")));
textContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f))); textContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
textContainer.setPreferredSize(container.getPreferredSize().addLocal(-250, -200, 0)); textContainer.setPreferredSize(container.getPreferredSize().addLocal(-250, -200, 0));
// Payment button
Button payButton = container.addChild(new Button("Überweisen", new ElementId("button"))); Button payButton = container.addChild(new Button("Überweisen", new ElementId("button")));
payButton.setFontSize(32); payButton.setFontSize(32);
payButton.addClickCommands(s -> ifTopDialog(() -> { payButton.addClickCommands(s -> ifTopDialog( () -> {
app.getGameLogic().playSound(Sound.BUTTON); app.getGameLogic().playSound(Sound.BUTTON);
close(); close();
})); }));
return container; return container;
} }
/**
* Centers the rent and background containers on the screen.
*/
private void centerContainers() { private void centerContainers() {
float padding = 10; float padding = 10;
// Center rent container
rentContainer.setLocalTranslation( rentContainer.setLocalTranslation(
(app.getCamera().getWidth() - rentContainer.getPreferredSize().x) / 2, (app.getCamera().getWidth() - rentContainer.getPreferredSize().x) / 2,
(app.getCamera().getHeight() + rentContainer.getPreferredSize().y) / 2, (app.getCamera().getHeight() + rentContainer.getPreferredSize().y) / 2,
8 8
); );
// Center background container with padding
backgroundContainer.setPreferredSize(rentContainer.getPreferredSize().addLocal(padding, padding, 0)); backgroundContainer.setPreferredSize(rentContainer.getPreferredSize().addLocal(padding, padding, 0));
backgroundContainer.setLocalTranslation( backgroundContainer.setLocalTranslation(
(app.getCamera().getWidth() - backgroundContainer.getPreferredSize().x) / 2, (app.getCamera().getWidth() - backgroundContainer.getPreferredSize().x) / 2,
@@ -102,25 +146,22 @@ public class Rent extends Dialog implements PopupDialog {
); );
} }
@Override /**
public void show() { * Closes the popup and removes GUI elements.
// Attach components to GUI only when the dialog is displayed via DialogManager */
app.getGuiNode().attachChild(overlayBackground);
app.getGuiNode().attachChild(backgroundContainer);
app.getGuiNode().attachChild(rentContainer);
}
@Override @Override
public void close() { public void close() {
app.getGuiNode().detachChild(overlayBackground);
app.getGuiNode().detachChild(backgroundContainer);
app.getGuiNode().detachChild(rentContainer); app.getGuiNode().detachChild(rentContainer);
app.getGuiNode().detachChild(backgroundContainer);
app.getGuiNode().detachChild(overlayBackground);
super.close(); super.close();
} }
/**
* Handles the escape action to close the dialog.
*/
@Override @Override
public void escape() { public void escape() {
close(); close();
} }
} }

View File

@@ -7,6 +7,7 @@ import com.simsilica.lemur.Button;
import com.simsilica.lemur.Container; import com.simsilica.lemur.Container;
import com.simsilica.lemur.Label; import com.simsilica.lemur.Label;
import com.simsilica.lemur.Selector; import com.simsilica.lemur.Selector;
import com.simsilica.lemur.TextField;
import com.simsilica.lemur.component.QuadBackgroundComponent; import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.component.SpringGridLayout; import com.simsilica.lemur.component.SpringGridLayout;
import com.simsilica.lemur.core.VersionedList; import com.simsilica.lemur.core.VersionedList;
@@ -44,8 +45,8 @@ public class RepayMortage extends Dialog {
/** Background container providing a border for the popup. */ /** Background container providing a border for the popup. */
private final Container backgroundContainer; private final Container backgroundContainer;
/** Label to display selected properties. */ /** Text field to display selected properties. */
private Label selectionDisplay; private TextField selectionDisplay;
/** Reference to track property selections in the dropdown menu. */ /** Reference to track property selections in the dropdown menu. */
private VersionedReference<Set<Integer>> selectionRef; private VersionedReference<Set<Integer>> selectionRef;
@@ -81,7 +82,7 @@ public class RepayMortage extends Dialog {
backgroundContainer.setPreferredSize(repayMortageContainer.getPreferredSize().addLocal(padding, padding, 0)); backgroundContainer.setPreferredSize(repayMortageContainer.getPreferredSize().addLocal(padding, padding, 0));
// Titel // Titel
Label title = repayMortageContainer.addChild(new Label( "Hypothek Abbezahlen", new ElementId("label-Bold"))); Label title = repayMortageContainer.addChild(new Label( "Hypothek Abbezahlen", new ElementId("warining-Bold")));
title.setFontSize(48); title.setFontSize(48);
title.setColor(ColorRGBA.Black); title.setColor(ColorRGBA.Black);
@@ -96,7 +97,7 @@ public class RepayMortage extends Dialog {
upContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f))); upContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
middleContainer.setPreferredSize(new Vector3f(100, 150, 0)); middleContainer.setPreferredSize(new Vector3f(100, 150, 0));
middleContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.0f, 0.0f, 0.0f, 1.0f))); middleContainer.setBackground(new QuadBackgroundComponent(ColorRGBA.Orange));
middleContainer.addChild(createPropertyDropdown()); middleContainer.addChild(createPropertyDropdown());
@@ -148,7 +149,7 @@ public class RepayMortage extends Dialog {
private Container createPropertyDropdown() { private Container createPropertyDropdown() {
Container dropdownContainer = new Container(new SpringGridLayout(Axis.Y, Axis.X)); Container dropdownContainer = new Container(new SpringGridLayout(Axis.Y, Axis.X));
dropdownContainer.setPreferredSize(new Vector3f(300, 200, 0)); dropdownContainer.setPreferredSize(new Vector3f(300, 200, 0));
dropdownContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.0f, 0.0f, 0.0f, 1.0f))); dropdownContainer.setBackground(new QuadBackgroundComponent(ColorRGBA.Orange));
VersionedList<String> propertyOptions = new VersionedList<>(); VersionedList<String> propertyOptions = new VersionedList<>();
List<PropertyField> playerProperties = getPlayerProperties(); List<PropertyField> playerProperties = getPlayerProperties();
@@ -165,9 +166,8 @@ public class RepayMortage extends Dialog {
selectionRef = propertySelector.getSelectionModel().createReference(); selectionRef = propertySelector.getSelectionModel().createReference();
// Initialize the selection display here // Initialize the selection display here
selectionDisplay = new Label(""); // Create TextField for displaying selections selectionDisplay = new TextField(""); // Create TextField for displaying selections
selectionDisplay.setPreferredSize(new Vector3f(300, 30, 0)); selectionDisplay.setPreferredSize(new Vector3f(300, 30, 0));
selectionDisplay.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
dropdownContainer.addChild(selectionDisplay); // Add it to the dropdown container dropdownContainer.addChild(selectionDisplay); // Add it to the dropdown container
// Set initial selection // Set initial selection

View File

@@ -7,6 +7,7 @@ import com.simsilica.lemur.Button;
import com.simsilica.lemur.Container; import com.simsilica.lemur.Container;
import com.simsilica.lemur.Label; import com.simsilica.lemur.Label;
import com.simsilica.lemur.Selector; import com.simsilica.lemur.Selector;
import com.simsilica.lemur.TextField;
import com.simsilica.lemur.component.QuadBackgroundComponent; import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.component.SpringGridLayout; import com.simsilica.lemur.component.SpringGridLayout;
import com.simsilica.lemur.core.VersionedList; import com.simsilica.lemur.core.VersionedList;
@@ -44,8 +45,8 @@ public class SellHouse extends Dialog {
/** Background container providing a styled border around the main dialog. */ /** Background container providing a styled border around the main dialog. */
private final Container backgroundContainer; private final Container backgroundContainer;
/** Label to display selected properties. */ /** Text field to display selected properties. */
private Label selectionDisplay; private TextField selectionDisplay;
/** Reference to track selection changes in the property selector. */ /** Reference to track selection changes in the property selector. */
private VersionedReference<Set<Integer>> selectionRef; private VersionedReference<Set<Integer>> selectionRef;
@@ -81,11 +82,11 @@ public class SellHouse extends Dialog {
backgroundContainer.setPreferredSize(sellhouseContainer.getPreferredSize().addLocal(padding, padding, 0)); backgroundContainer.setPreferredSize(sellhouseContainer.getPreferredSize().addLocal(padding, padding, 0));
// Titel // Titel
Label title = sellhouseContainer.addChild(new Label( "Gebäude Abreißen", new ElementId("label-Bold"))); Label title = sellhouseContainer.addChild(new Label( "Gebäude Abreißen", new ElementId("warining-Bold")));
title.setFontSize(48); title.setFontSize(48);
title.setColor(ColorRGBA.Black); title.setColor(ColorRGBA.Black);
//Unterteilung des sellHouseContainer in drei "Untercontainer" //Unterteilund des sellHouseContainer in drei "Untercontainer"
Container upContainer = sellhouseContainer.addChild(new Container()); Container upContainer = sellhouseContainer.addChild(new Container());
Container middleContainer = sellhouseContainer.addChild(new Container()); Container middleContainer = sellhouseContainer.addChild(new Container());
Container downContainer = sellhouseContainer.addChild(new Container()); Container downContainer = sellhouseContainer.addChild(new Container());
@@ -118,7 +119,13 @@ public class SellHouse extends Dialog {
confirmButton.addClickCommands(s -> ifTopDialog( () -> { confirmButton.addClickCommands(s -> ifTopDialog( () -> {
app.getGameLogic().playSound(Sound.BUTTON); app.getGameLogic().playSound(Sound.BUTTON);
AlterProperty msg = new AlterProperty("SellHouse"); AlterProperty msg = new AlterProperty("SellHouse");
for (String string : selectedProperties) {
System.out.println(string);
}
msg.setProperties(selectedProperties.stream().map(p -> app.getGameLogic().getBoardManager().getFieldByName(p).getId()).map(p -> (Integer) p).collect(Collectors.toSet())); msg.setProperties(selectedProperties.stream().map(p -> app.getGameLogic().getBoardManager().getFieldByName(p).getId()).map(p -> (Integer) p).collect(Collectors.toSet()));
for (Integer integer : msg.getProperties()) {
System.out.println("ID des verkaufs: "+integer);
}
app.getGameLogic().send(msg); app.getGameLogic().send(msg);
close(); close();
})); }));
@@ -148,7 +155,7 @@ public class SellHouse extends Dialog {
private Container createPropertyDropdown() { private Container createPropertyDropdown() {
Container dropdownContainer = new Container(new SpringGridLayout(Axis.Y, Axis.X)); Container dropdownContainer = new Container(new SpringGridLayout(Axis.Y, Axis.X));
dropdownContainer.setPreferredSize(new Vector3f(300, 200, 0)); dropdownContainer.setPreferredSize(new Vector3f(300, 200, 0));
dropdownContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.0f, 0.0f, 0.0f, 1.0f))); dropdownContainer.setBackground(new QuadBackgroundComponent(ColorRGBA.Orange));
VersionedList<String> propertyOptions = new VersionedList<>(); VersionedList<String> propertyOptions = new VersionedList<>();
List<BuildingProperty> playerProperties = getPlayerProperties(); List<BuildingProperty> playerProperties = getPlayerProperties();
@@ -165,9 +172,8 @@ public class SellHouse extends Dialog {
selectionRef = propertySelector.getSelectionModel().createReference(); selectionRef = propertySelector.getSelectionModel().createReference();
// Initialize the selection display here // Initialize the selection display here
selectionDisplay = new Label(""); selectionDisplay = new TextField(""); // Create TextField for displaying selections
selectionDisplay.setPreferredSize(new Vector3f(300, 30, 0)); selectionDisplay.setPreferredSize(new Vector3f(300, 30, 0));
selectionDisplay.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
dropdownContainer.addChild(selectionDisplay); // Add it to the dropdown container dropdownContainer.addChild(selectionDisplay); // Add it to the dropdown container
// Set initial selection // Set initial selection

View File

@@ -7,6 +7,7 @@ import com.simsilica.lemur.Button;
import com.simsilica.lemur.Container; import com.simsilica.lemur.Container;
import com.simsilica.lemur.Label; import com.simsilica.lemur.Label;
import com.simsilica.lemur.Selector; import com.simsilica.lemur.Selector;
import com.simsilica.lemur.TextField;
import com.simsilica.lemur.component.QuadBackgroundComponent; import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.component.SpringGridLayout; import com.simsilica.lemur.component.SpringGridLayout;
import com.simsilica.lemur.core.VersionedList; import com.simsilica.lemur.core.VersionedList;
@@ -45,8 +46,8 @@ public class TakeMortage extends Dialog {
/** Background container providing a styled border around the main dialog. */ /** Background container providing a styled border around the main dialog. */
private final Container backgroundContainer; private final Container backgroundContainer;
/** Label to display selected properties. */ /** Text field to display selected properties. */
private Label selectionDisplay; private TextField selectionDisplay;
/** Reference to track selection changes in the property selector. */ /** Reference to track selection changes in the property selector. */
private VersionedReference<Set<Integer>> selectionRef; private VersionedReference<Set<Integer>> selectionRef;
@@ -82,7 +83,7 @@ public class TakeMortage extends Dialog {
backgroundContainer.setPreferredSize(takeMortageContainer.getPreferredSize().addLocal(padding, padding, 0)); backgroundContainer.setPreferredSize(takeMortageContainer.getPreferredSize().addLocal(padding, padding, 0));
// Titel // Titel
Label title = takeMortageContainer.addChild(new Label( "Hypothek aufnehmen", new ElementId("label-Bold"))); Label title = takeMortageContainer.addChild(new Label( "Hypothek aufnehmen", new ElementId("warining-Bold")));
title.setFontSize(48); title.setFontSize(48);
title.setColor(ColorRGBA.Black); title.setColor(ColorRGBA.Black);
@@ -149,7 +150,7 @@ public class TakeMortage extends Dialog {
private Container createPropertyDropdown() { private Container createPropertyDropdown() {
Container dropdownContainer = new Container(new SpringGridLayout(Axis.Y, Axis.X)); Container dropdownContainer = new Container(new SpringGridLayout(Axis.Y, Axis.X));
dropdownContainer.setPreferredSize(new Vector3f(300, 200, 0)); dropdownContainer.setPreferredSize(new Vector3f(300, 200, 0));
dropdownContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.0f, 0.0f, 0.0f, 1.0f))); dropdownContainer.setBackground(new QuadBackgroundComponent(ColorRGBA.Orange));
VersionedList<String> propertyOptions = new VersionedList<>(); VersionedList<String> propertyOptions = new VersionedList<>();
List<PropertyField> playerProperties = getPlayerProperties(); List<PropertyField> playerProperties = getPlayerProperties();
@@ -171,9 +172,8 @@ public class TakeMortage extends Dialog {
selectionRef = propertySelector.getSelectionModel().createReference(); selectionRef = propertySelector.getSelectionModel().createReference();
// Initialize the selection display here // Initialize the selection display here
selectionDisplay = new Label(""); // Create TextField for displaying selections selectionDisplay = new TextField(""); // Create TextField for displaying selections
selectionDisplay.setPreferredSize(new Vector3f(300, 30, 0)); selectionDisplay.setPreferredSize(new Vector3f(300, 30, 0));
selectionDisplay.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
dropdownContainer.addChild(selectionDisplay); // Add it to the dropdown container dropdownContainer.addChild(selectionDisplay); // Add it to the dropdown container
// Set initial selection // Set initial selection

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 304 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 195 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 205 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 170 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 193 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 198 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 201 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 MiB

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 132 KiB

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 195 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 588 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 190 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 364 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 MiB

Some files were not shown because too many files have changed in this diff Show More