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 java.lang.System.Logger;
/**
* 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 static Logger LOGGER = System.getLogger(DialogManager.class.getName());
/**
* A stack to keep track of the dialogs.
*/
private final Deque<Dialog> dialogStack = new ArrayDeque<>();
private final Deque<PopupDialog> popUpStack = new ArrayDeque<>();
/**
* Constructs a DialogManager for the specified application.
*
@@ -118,45 +112,11 @@ public class DialogManager {
* @param dialog the dialog to open
*/
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);
if(dialog instanceof PopupDialog) {
((PopupDialog)dialog).show();
}
dialog.update();
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.
*
@@ -180,8 +140,6 @@ public class DialogManager {
if (!dialogStack.isEmpty())
dialogStack.peek().update();
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
import com.jme3.math.ColorRGBA
import com.jme3.texture.Texture
import com.simsilica.lemur.*
import com.simsilica.lemur.component.QuadBackgroundComponent
import com.simsilica.lemur.Button
@@ -13,8 +12,6 @@ import com.simsilica.lemur.HAlignment
import com.simsilica.lemur.Insets3f
import com.simsilica.lemur.component.QuadBackgroundComponent
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 buttonEnabledColor = color(0, 0, 0, 1)
@@ -50,23 +47,6 @@ def orangeBorder = TbtQuadBackgroundComponent.create(
1f, false)
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") {
font = font("Interface/Fonts/Metropolis/Metropolis-Regular-32.fnt")
}
@@ -89,7 +69,7 @@ selector("label-Bold", "pp") {
selector("label-toolbar", "pp") {
insets = new Insets3f(2, 2, 2, 2)
font = font("Interface/Fonts/Metropolis/Metropolis-Bold-32.fnt")
fontSize = 25
fontSize = 30
color = new ColorRGBA(ColorRGBA.White)
textHAlignment = HAlignment.Center
textVAlignment = VAlignment.Center
@@ -101,13 +81,6 @@ selector("label-Text", "pp") {
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") {
insets = new Insets3f(2, 2, 2, 2)
fontSize = 25
@@ -225,6 +198,7 @@ selector("button", "pp") {
insets = new Insets3f(3, 3, 3, 3) // Adjust the border thickness
textHAlignment = HAlignment.Center
textVAlignment = VAlignment.Center
buttonCommands = stdButtonCommands
}
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
}
def enabledCommandToolbar = new Command<Button>() {
MonopolyApp app // Pass the app instance to access player details
void execute(Button source) {
// Get the current player's color
Player currentPlayer = app.getGameLogic().getPlayerHandler().getPlayerById(app.getId());
ColorRGBA playerColor = Player.getColor(currentPlayer.getId()).getColor();
if (source.isEnabled()) {
source.setColor(ColorRGBA.White);
def playerBackground = new QuadBackgroundComponent(playerColor); // Use player's color
source.setBackground(playerBackground);
} else {
source.setColor(ColorRGBA.White);
def grayBackground = new QuadBackgroundComponent(ColorRGBA.Gray); // Use gray when disabled
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);
}
}
}
@@ -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.state.AppStateManager;
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.DirectionalLight;
import com.jme3.light.PointLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;
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.Spatial;
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.EdgeFilteringMode;
import com.jme3.texture.Texture;
import com.jme3.util.SkyFactory;
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.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.cos;
import static pp.util.FloatMath.sin;
@@ -77,17 +68,6 @@ public class BoardAppState extends MonopolyAppState {
*/
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.
* This method is called when the state is first attached to the state manager.
@@ -98,16 +78,8 @@ public class BoardAppState extends MonopolyAppState {
@Override
public void initialize(AppStateManager stateManager, Application 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());
viewNode.attachChild(sceneNode);
setupLights();
setupSky();
}
@@ -121,19 +93,40 @@ public class BoardAppState extends MonopolyAppState {
getApp().getRootNode().detachAllChildren();
getApp().getGuiNode().detachAllChildren();
getApp().getDialogManager().close(getApp().getDialogManager().getDialogStack().peek());
new Toolbar(getApp()).open();
sceneNode.detachAllChildren();
setupScene();
if (bobTheBuilder == null) {
bobTheBuilder = new BobTheBuilder(getApp(), sceneNode);
bobTheBuilder = new BobTheBuilder(getApp(), getApp().getRootNode());
System.out.println("LISTENER IS REGISTEDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD");
getGameLogic().addListener(bobTheBuilder);
}
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.
@@ -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.
@@ -177,10 +181,10 @@ public class BoardAppState extends MonopolyAppState {
*/
private void setupSky() {
final AssetManager assetManager = getApp().getAssetManager();
final Texture west = assetManager.loadTexture("Pictures/Backdrop/west.jpg"); //NON-NLS
final Texture east = assetManager.loadTexture("Pictures/Backdrop/ost.jpg"); //NON-NLS
final Texture north = assetManager.loadTexture("Pictures/Backdrop/nord.jpg"); //NON-NLS
final Texture south = assetManager.loadTexture("Pictures/Backdrop/sued.jpg"); //NON-NLS
final Texture west = assetManager.loadTexture("Pictures/Backdrop/left.jpg"); //NON-NLS
final Texture east = assetManager.loadTexture("Pictures/Backdrop/right.jpg"); //NON-NLS
final Texture north = assetManager.loadTexture("Pictures/Backdrop/front.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 down = assetManager.loadTexture("Pictures/Backdrop/down.jpg"); //NON-NLS
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 y = board.getHeight();
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));
Quaternion rotation = new Quaternion();
rotation.fromAngleAxis(FastMath.HALF_PI, Vector3f.UNIT_Y);
Quaternion rotation = new com.jme3.math.Quaternion();
rotation.fromAngleAxis(FastMath.HALF_PI, com.jme3.math.Vector3f.UNIT_Y);
seaGeo.setLocalRotation(rotation);
final Material seaMat = new Material(getApp().getAssetManager(), "Common/MatDefs/Light/Lighting.j3md");
Texture texture = getApp().getAssetManager().loadTexture("Pictures/board2.png");
@@ -208,146 +212,6 @@ public class BoardAppState extends MonopolyAppState {
seaGeo.setMaterial(seaMat);
seaGeo.setShadowMode(ShadowMode.CastAndReceive);
TangentBinormalGenerator.generate(seaGeo);
sceneNode.attachChild(createCardDeck());
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.audio.AudioData;
import com.jme3.audio.AudioNode;
/**
* Handles the background and secondary music in the game.
* Allows playing, stopping, and toggling between background music and a secondary track.
*/
public class GameMusic extends AbstractAppState {
private static final Logger LOGGER = System.getLogger(pp.monopoly.client.GameMusic.class.getName());
private static final Preferences PREFERENCES = getPreferences(pp.monopoly.client.GameMusic.class);
private static final Logger LOGGER = System.getLogger(GameMusic.class.getName());
private static final Preferences PREFERENCES = getPreferences(GameMusic.class);
private static final String ENABLED_PREF = "enabled"; // NON-NLS
private static final String VOLUME_PREF = "volume"; // NON-NLS
@@ -67,9 +68,8 @@ public class GameMusic extends AbstractAppState {
/**
* Plays the main music.
*/
public void playMainMusic() {
private void playMainMusic() {
if (!isEnabled()) {
return; // Sound is disabled
}
@@ -92,10 +92,11 @@ public class GameMusic extends AbstractAppState {
/**
* 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() {
if (!isEnabled()) {
stopAllMusic();
private void playSecondaryMusic() {
if(!isEnabled()) {
return;
}
if (isSecondaryMusicPlaying) {
@@ -114,7 +115,7 @@ public class GameMusic extends AbstractAppState {
/**
* Stops the secondary music.
*/
public void stopSecondaryMusic() {
private void stopSecondaryMusic() {
if (secondaryMusic != null && isSecondaryMusicPlaying) {
secondaryMusic.stop();
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 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() {
if (!isEnabled()) {
stopAllMusic();
if(!isEnabled()) {
return;
}
if (isSecondaryMusicPlaying) {
stopSecondaryMusic();
playMainMusic();
} else {
stopMainMusic();
playSecondaryMusic();
}
}
@@ -152,14 +153,6 @@ public class GameMusic extends AbstractAppState {
PREFERENCES.putFloat(VOLUME_PREF, vol);
}
/**
* Stops all music (both main and secondary).
*/
public void stopAllMusic() {
stopMainMusic();
stopSecondaryMusic();
}
/**
* Enables or disables the sound system.
* When disabled, all music stops.
@@ -168,14 +161,13 @@ public class GameMusic extends AbstractAppState {
*/
@Override
public void setEnabled(boolean enabled) {
if (isEnabled() == enabled) return; // Avoid redundant operations
PREFERENCES.putBoolean(ENABLED_PREF, enabled);
if (isEnabled() == enabled) return;
if (enabled) {
playMainMusic();
} else {
stopAllMusic();
stopMainMusic();
stopSecondaryMusic();
}
super.setEnabled(enabled);

View File

@@ -120,7 +120,6 @@ public class GameSound extends AbstractAppState implements GameEventListener {
winnerSound = loadSound(app, "Sound/Effects/winner.ogg");
looserSound = loadSound(app, "Sound/Effects/loser.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.Executors;
import java.util.logging.LogManager;
import java.awt.Image;
import javax.imageio.ImageIO;
import com.jme3.app.DebugKeysAppState;
import com.jme3.app.SimpleApplication;
@@ -172,16 +169,6 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga
private AppSettings makeSettings() {
final AppSettings settings = new AppSettings(true);
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.setFullscreen(config.fullScreen());
settings.setUseRetinaFrameBuffer(config.useRetinaFrameBuffer());
@@ -292,7 +279,7 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga
final StatsAppState stats = new StatsAppState(guiNode, normalFont);
stateManager.attach(stats);
}
flyCam.setEnabled(true);
flyCam.setEnabled(false);
stateManager.detach(stateManager.getState(StatsAppState.class));
stateManager.detach(stateManager.getState(DebugKeysAppState.class));

View File

@@ -106,26 +106,6 @@ public class MonopolyAppConfig extends MonopolyClientConfig {
@Property("overlay.top.color") //NON-NLS
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.
*/

View File

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

View File

@@ -1,11 +1,12 @@
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.RenderState.BlendMode;
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.scene.Geometry;
import com.jme3.scene.Node;
@@ -13,6 +14,7 @@ import com.jme3.scene.Spatial;
import com.jme3.scene.shape.Box;
import pp.monopoly.client.MonopolyApp;
import pp.monopoly.game.server.Player;
import pp.monopoly.model.Figure;
import pp.monopoly.model.Hotel;
import pp.monopoly.model.House;
@@ -39,17 +41,14 @@ public class BobTheBuilder extends GameBoardSynchronizer {
@Override
public Spatial visit(Figure figure) {
final Node node = new Node(FIGURE);
Spatial spatial = createFigure(figure);
node.attachChild(spatial);
node.attachChild(createFigure(figure));
// Setze die Position basierend auf der Feld-ID
node.setLocalTranslation(figure.getPos());
// Setze die Anfangsrotation auf 90 Grad nach links
Quaternion initialRotation = new Quaternion().fromAngleAxis(FastMath.HALF_PI, Vector3f.UNIT_Y);
node.setLocalRotation(initialRotation);
node.addControl(new FigureControl(node, figure, app));
// Setze die Rotation basierend auf der Feld-ID
node.setLocalRotation(figure.getRot().toQuaternion());
// node.addControl(new FigureControl(figure));
return node;
}
@@ -86,7 +85,7 @@ public class BobTheBuilder extends GameBoardSynchronizer {
private Spatial createFigure(Figure figure) {
// Lade das Modell
Spatial model = app.getAssetManager().loadModel("models/" + "Spielfiguren/" + figure.getType() + "/" + figure.getType() + ".j3o");
// Skaliere und positioniere das Modell
model.scale(0.5f);
@@ -144,4 +143,17 @@ public class BobTheBuilder extends GameBoardSynchronizer {
material.setColor(COLOR, color);
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.renderer.Camera;
/**
* Controls the movement of the camera within the scene.
*/
public class CameraController {
public enum CameraMode {
FOCUS_CURRENT_PLAYER,
FOCUS_SELF,
FREECAM
}
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
public CameraController(Camera camera, float height, float offset) {
/**
* Constructor for the CameraController.
*
* @param camera The camera to be controlled
*/
public CameraController(Camera camera) {
this.camera = camera;
this.height = height;
this.offset = offset;
setMode(currentMode);
}
public void setMode(CameraMode mode) {
this.currentMode = mode;
updatePosition(0); // Standardmäßig das Startfeld fokussieren
setPosition(0);
camera.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y);
}
/**
* Updates the camera's position and orientation.
*
* @param tpf Time per frame
*/
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);
camera.setLocation(newPosition);
if (currentMode != CameraMode.FREECAM) {
camera.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y);
}
/**
* Sets the camera's position based on the field ID.
*
* @param fieldID The ID of the field to which the camera should move
*/
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) {
switch (currentMode) {
case FOCUS_CURRENT_PLAYER:
if (fieldID <= 10) return new Vector3f(offset, height, 0);
if (fieldID <= 20) return new Vector3f(0, height, offset);
if (fieldID <= 30) return new Vector3f(-offset, height, 0);
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);
}
if (fieldID <= 10) return new Vector3f(30, height, 0);
if (fieldID <= 20) return new Vector3f(0, height, 30);
if (fieldID <= 30) return new Vector3f(-30, height, 0);
if (fieldID <= 40) return new Vector3f(0, height, -30);
else throw new IllegalArgumentException();
}
}
}

View File

@@ -1,31 +1,60 @@
package pp.monopoly.client.gui;
import com.jme3.input.InputManager;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
public class CameraInputHandler {
private CameraController cameraController;
public CameraInputHandler(CameraController cameraController, InputManager inputManager) {
this.cameraController = cameraController;
// Tasten für die verschiedenen Kameramodi registrieren
inputManager.addMapping("FocusCurrentPlayer", new KeyTrigger(KeyInput.KEY_1));
inputManager.addMapping("FocusSelf", new KeyTrigger(KeyInput.KEY_2));
inputManager.addMapping("FreeCam", new KeyTrigger(KeyInput.KEY_3));
inputManager.addListener(actionListener, "FocusCurrentPlayer", "FocusSelf", "FreeCam");
}
private final ActionListener actionListener = (name, isPressed, tpf) -> {
if (!isPressed) return;
switch (name) {
case "FocusCurrentPlayer" -> cameraController.setMode(CameraController.CameraMode.FOCUS_CURRENT_PLAYER);
case "FocusSelf" -> cameraController.setMode(CameraController.CameraMode.FOCUS_SELF);
case "FreeCam" -> cameraController.setMode(CameraController.CameraMode.FREECAM);
}
};
}
//package pp.monopoly.client.gui;
//
//import com.jme3.input.InputManager;
//import com.jme3.input.KeyInput;
//import com.jme3.input.controls.ActionListener;
//import com.jme3.input.controls.KeyTrigger;
//
///**
// * Handhabt die Eingaben für die Kamera.
// */
//public class CameraInputHandler {
//
// private CameraController cameraController; // Kamera-Controller
//
// /**
// * Konstruktor für den CameraInputHandler.
// *
// * @param cameraController Der Kamera-Controller, der gesteuert werden soll.
// * @param inputManager Der InputManager, um Eingaben zu registrieren.
// */
// public CameraInputHandler(CameraController cameraController, InputManager inputManager) {
// if (cameraController == null || inputManager == null) {
// throw new IllegalArgumentException("CameraController und InputManager dürfen nicht null sein");
// }
// this.cameraController = cameraController;
//
// // Mappings für Kamerasteuerung
// 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.simsilica.lemur.Button;
import com.simsilica.lemur.Command;
import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.style.ElementId;
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 {
private final MonopolyApp app;
private final String functionality;
private final PlayerColor playerColor;
public ImageButton(String functionality, MonopolyApp app) {
super("", "button-clear");
this.app = app;
this.functionality = functionality;
this.playerColor = Player.getColor(app.getId());
updateButtonAppearance(ButtonState.ENABLED);
addButtonCommands();
private final String file;
private static MonopolyApp app;
public ImageButton( String s, String file, MonopolyApp app ) {
this(s, true, new ElementId(ELEMENT_ID), null, file, app);
}
public ImageButton( String s, String style, String file, MonopolyApp app ) {
this(s, true, new ElementId(ELEMENT_ID), style, file, app);
}
public ImageButton( String s, ElementId elementId, String file, MonopolyApp app ) {
this(s, true, elementId, null, file, app);
}
public ImageButton( String s, ElementId elementId, String style, String file, MonopolyApp app ) {
this(s, true, elementId, style, file, app);
}
protected ImageButton( String s, boolean applyStyles, ElementId elementId, String style, String file, MonopolyApp app ) {
super(s, false, elementId, style);
this.file = file;
ImageButton.app = app;
Texture backgroundImage = app.getAssetManager().loadTexture("Pictures/Buttons/"+file+".png");
setBackground(new QuadBackgroundComponent(backgroundImage));
}
/**
* Updates the button's appearance based on its state.
*
* @param state the current button state
*/
private void updateButtonAppearance(ButtonState state) {
setBackgroundTexture(state.name().toLowerCase());
}
/**
* Adds button commands for state-specific actions like hover, press, enable, and disable.
*/
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);
}
});
}
/**
* Sets the background texture for the button based on the given state.
*
* @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));
}
/**
* Builds the file path for the button texture.
*
* @param state the button state (e.g., "enabled", "disabled", "hover")
* @return the full file path to the texture
*/
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;
GameMusic music = app.getStateManager().getState(GameMusic.class);
if (music != null && music.isEnabled()) {
music.playSecondaryMusic();
}
music.toggleMusic();
playerInputField = new TextField("Spieler "+(app.getId()+1));
// Hintergrundbild laden und hinzufügen
addBackgroundImage();
@@ -154,7 +153,6 @@ public class LobbyMenu extends Dialog {
figures.add("Katze");
figures.add("OOP");
figures.add("Handyholster");
figures.add("Panzer");
figureDropdown = new Selector<>(figures, "glass");
@@ -278,12 +276,6 @@ public class LobbyMenu extends Dialog {
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
public void update(float tpf) {
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.
*
* @param selector the selected figure
* @param selected the selected figure
*/
private void onDropdownSelectionChanged(Selector<String> selector) {
app.getGameLogic().playSound(Sound.BUTTON);
@@ -326,6 +301,7 @@ public class LobbyMenu extends Dialog {
figure = selector.getSelectedItem();
break;
}
System.out.println("FIGUR:::::"+figure);
}
/**

View File

@@ -51,17 +51,7 @@ public class SettingsMenu extends Dialog {
private final SoundSlider soundSlider;
/**
* Checkbox for toggling sound effects.
*/
private final Checkbox soundCheckbox;
/**
* Checkbox for toggling background music.
*/
private final Checkbox musicCheckbox;
/**
* Constructs the Menu dialog for the Monopoly application.
* Constructs the Menu dialog for the Battleship application.
*
* @param app the MonopolyApp instance
*/
@@ -75,15 +65,11 @@ public class SettingsMenu extends Dialog {
addChild(soundSlider);
soundCheckbox = new Checkbox("Soundeffekte an / aus", new StateCheckboxModel(app, GameSound.class));
addChild(soundCheckbox);
addChild(new Checkbox("Soundeffekte an / aus", new StateCheckboxModel(app, GameSound.class)));
addChild(new Label("Hintergrund Musik", new ElementId("label"))); //NON-NLS
musicCheckbox = new Checkbox("Musik an / aus", new StateCheckboxModel(app, GameMusic.class));
musicCheckbox.addClickCommands(s -> toggleMusicPreference());
addChild(musicCheckbox);
addChild(new Checkbox("Musik an / aus", new StateCheckboxModel(app, GameMusic.class)));
addChild(musicSlider);
addChild(new Button("Zurück zum Spiel", new ElementId("button"))).addClickCommands(s -> ifTopDialog(() -> {
@@ -98,42 +84,16 @@ public class SettingsMenu extends Dialog {
}
/**
* Toggles the music preference based on the state of the musicCheckbox.
* 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.
* Updates the state of the load and save buttons based on the game logic.
*/
@Override
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
public void update(float delta) {
musicSlider.update();
soundSlider.update();
update();
}
/**

View File

@@ -65,7 +65,7 @@ public class StartMenu extends Dialog {
app.getGuiNode().attachChild(centerMenu);
// 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
Container logoContainer = new Container();
@@ -91,8 +91,8 @@ public class StartMenu extends Dialog {
QuadBackgroundComponent unibwBackground = new QuadBackgroundComponent(unibwTexture);
unibwContainer.setBackground(unibwBackground);
float unibwWidth = 662;
float unibwHeight = 180;
float unibwWidth = 512;
float unibwHeight = 128;
unibwContainer.setPreferredSize(new Vector3f(unibwWidth, unibwHeight, 0));
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;
import com.jme3.input.event.MouseButtonEvent;
import com.jme3.input.event.MouseMotionEvent;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.scene.Spatial;
import com.jme3.texture.Texture;
import com.simsilica.lemur.Axis;
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.QuadBackgroundComponent;
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 pp.dialog.Dialog;
import pp.monopoly.client.BoardAppState;
import pp.monopoly.client.MonopolyApp;
import pp.monopoly.client.gui.popups.Bankrupt;
import pp.monopoly.game.server.Player;
@@ -35,41 +30,88 @@ import pp.monopoly.notification.UpdatePlayerView;
/**
* 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 {
/** The Monopoly application instance*/
/**
* Reference to the Monopoly application instance.
*/
private final MonopolyApp app;
/** The container representing the toolbar interface */
/**
* The main container for the toolbar interface.
*/
private final Container toolbarContainer;
/** The container representing the player overview information */
/**
* Container for displaying an overview of other players.
*/
private Container overviewContainer;
/** The container representing the player account information */
/**
* Container for displaying account-related information.
*/
private Container accountContainer;
/** The player handler instance */
/**
* Handles player-related data and actions.
*/
private PlayerHandler playerHandler;
/** The label representing the left dice */
/**
* Label for the first dice display.
*/
private Label imageLabel;
/** The label representing the right dice */
/**
* Label for the second dice display.
*/
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;
/** The property menu button */
/**
* Button for accessing the property menu.
*/
private Button propertyMenuButton;
/** The end turn button */
/**
* Button for ending the player's turn.
*/
private Button endTurnButton;
/** The latest incoming Dice Roll Event */
/**
* Stores the most recent dice roll event.
*/
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;
/**
* 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) {
super(app.getDialogManager());
@@ -78,200 +120,111 @@ public class Toolbar extends Dialog implements GameEventListener {
app.getGameLogic().addListener(this);
this.playerHandler = app.getGameLogic().getPlayerHandler();
toolbarContainer = setupToolbar();
toolbarContainer = createToolbarContainer();
app.getGuiNode().attachChild(toolbarContainer);
endTurnButton.setEnabled(false);
}
/**
* Sets up the toolbar interface with the game controls, player information, and event handling.
*
* @return The container representing the toolbar interface.
*/
private Container setupToolbar() {
private Container createToolbarContainer() {
Container container = new Container(new SpringGridLayout(Axis.X, Axis.Y), "toolbar");
container.setLocalTranslation(0, 200, 0);
container.setPreferredSize(new Vector3f(app.getCamera().getWidth(), 200, 0));
Texture backgroundToolbar = app.getAssetManager().loadTexture("Pictures/toolbarbg.png");
QuadBackgroundComponent background = new QuadBackgroundComponent(backgroundToolbar);
background.setMargin(0, 0); // Removes any internal margin
container.setBackground(background);
// Spielerfarbe abrufen
Player currentPlayer = playerHandler.getPlayerById(app.getId());
ColorRGBA playerColor = Player.getColor(currentPlayer.getId()).getColor();
// 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);
setupBorders(container);
setupSpacer(container);
setupPlayerInfoSection(container);
setupSpacer(container);
setupDiceSection(container);
setupActionMenu(container);
return container;
}
/**
* Sets up the borders for the toolbar interface.
*
* @param container The container representing the toolbar interface.
*/
private void setupBorders(Container container) {
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);
}
/**
* Adds a spacer to the specified container.
*
* @param container the container to which the spacer is added
*/
private void setupSpacer(Container container) {
Container spacer = container.addChild(new Container());
spacer.setPreferredSize(new Vector3f(20, 10, 0));
spacer.setBackground(null);
}
/**
* Sets up the player information section of the toolbar interface.
*
* @param parentContainer The container representing the toolbar interface.
*/
private void setupPlayerInfoSection(Container parentContainer) {
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");
QuadBackgroundComponent background = new QuadBackgroundComponent(backgroundTexture);
playerInfoSection.setBackground(background);
accountContainer = playerInfoSection.addChild(new Container());
accountContainer.setPreferredSize(new Vector3f(300, 300, 0));
accountContainer.setBackground(null);
overviewContainer = playerInfoSection.addChild(new Container());
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) {
// unterer Balken
Container playerColorBarbot = new Container();
playerColorBarbot.setPreferredSize(new Vector3f(app.getCamera().getWidth(), 10, 0)); // Höhe des oberen Balkens
playerColorBarbot.setBackground(new QuadBackgroundComponent(playerColor));
playerColorBarbot.setLocalTranslation(0, 10, 3); // Position über der Toolbar
app.getGuiNode().attachChild(playerColorBarbot);
// Linker Balken
Container leftBar = new Container();
leftBar.setPreferredSize(new Vector3f(10, 210, 0)); // Breite 10, Höhe 210
leftBar.setBackground(new QuadBackgroundComponent(playerColor));
leftBar.setLocalTranslation(0, 200, 3); // Position am linken Rand
app.getGuiNode().attachChild(leftBar);
// Rechter Balken
Container rightBar = new Container();
rightBar.setPreferredSize(new Vector3f(10, 210, 0)); // Breite 10, Höhe 210
rightBar.setBackground(new QuadBackgroundComponent(playerColor));
rightBar.setLocalTranslation(app.getCamera().getWidth() - 10, 200, 2); // Position am rechten Rand
app.getGuiNode().attachChild(rightBar);
// Übersicht und Konto
accountContainer = container.addChild(new Container());
overviewContainer = container.addChild(new Container());
receivedEvent(new UpdatePlayerView()); // Initiale Aktualisierung
// Würfel-Bereich
container.addChild(createDiceSection());
// Aktionsmenü
Container menuContainer = container.addChild(new Container());
menuContainer.addChild(createTradeButton());
menuContainer.addChild(createPropertyMenuButton());
menuContainer.addChild(createEndTurnButton());
menuContainer.setBackground(null);
return container;
}
/**
* Returns the color of the current player.
*
* @return The color of the current player.
*/
private ColorRGBA getCurrentPlayerColor() {
Player currentPlayer = playerHandler.getPlayerById(app.getId());
return Player.getColor(currentPlayer.getId()).getColor();
private Container createDiceSection() {
Container diceContainer = new Container(new SpringGridLayout(Axis.X, Axis.Y));
diceContainer.addChild(createDiceDisplay());
diceContainer.setBackground(null);
diceButton = new Button("Würfeln", new ElementId("button-toolbar"));
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() {
Container horizontalContainer = new Container(new SpringGridLayout(Axis.X, Axis.Y));
horizontalContainer.setPreferredSize(new Vector3f(200, 150, 0));
horizontalContainer.setBackground(null);
imageLabel = createDiceLabel("Pictures/dice/one.png");
imageLabel2 = createDiceLabel("Pictures/dice/two.png");
horizontalContainer.setBackground(null);
horizontalContainer.addChild(createDiceContainer(imageLabel));
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;
}
/**
* 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) {
Label label = new Label("");
IconComponent icon = new IconComponent(iconPath);
icon.setIconSize(new Vector2f(80, 80));
icon.setIconSize(new Vector2f(100, 100));
label.setIcon(icon);
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) {
Container container = new Container();
container.setBackground(null);
@@ -280,120 +233,77 @@ public class Toolbar extends Dialog implements GameEventListener {
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() {
String iconPath = "icons/icon-handeln.png";
// createActionButton(playerColor, "icons/icon-handeln.png", 100, () -> new ChoosePartner(app).open());
tradeButton = new ImageButton("generic", app);
tradeButton = new Button("", new ElementId("button-toolbar"));
tradeButton.setPreferredSize(new Vector3f(150, 50, 0));
IconComponent icon = new IconComponent(iconPath);
icon.setHAlignment(HAlignment.Center);
icon.setVAlignment(VAlignment.Center);
icon.setIconSize(new Vector2f(75 , 75));
tradeButton.setIcon(icon);
String iconTradePath = "icons/icon-handeln.png";
IconComponent iconTrade = new IconComponent(iconTradePath);
iconTrade.setHAlignment(HAlignment.Center);
iconTrade.setVAlignment(VAlignment.Center);
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();
}));
return tradeButton;
}
private Button createPropertyMenuButton() {
String iconPath = "icons/icon-gebaude.png";
propertyMenuButton = new ImageButton("generic", app);
propertyMenuButton = new Button("", new ElementId("button-toolbar"));
propertyMenuButton.setPreferredSize(new Vector3f(150, 50, 0));
IconComponent icon = new IconComponent(iconPath);
icon.setHAlignment(HAlignment.Center);
icon.setVAlignment(VAlignment.Center);
icon.setIconSize(new Vector2f(50 , 50));
propertyMenuButton.setIcon(icon);
String iconBuildingPath = "icons/icon-gebaude.png";
IconComponent iconBuilding = new IconComponent(iconBuildingPath);
iconBuilding.setHAlignment(HAlignment.Center);
iconBuilding.setVAlignment(VAlignment.Center);
iconBuilding.setIconSize(new Vector2f(75, 75));
propertyMenuButton.setIcon(iconBuilding);
propertyMenuButton.setFontSize(30);
propertyMenuButton.addClickCommands(s -> ifTopDialog(() -> {
app.getGameLogic().playSound(Sound.BUTTON);
new BuildingAdminMenu(app).open();
}));
return propertyMenuButton;
}
private Button createEndTurnButton() {
// return createActionButton(playerColor, "icons/icon-zugbeenden.png", 75, () -> handleEndTurn());
String iconPath = "icons/icon-zugbeenden.png";
endTurnButton = new ImageButton("generic", app);
endTurnButton = new Button("", new ElementId("button-toolbar"));
endTurnButton.setFontSize(28);
endTurnButton.setPreferredSize(new Vector3f(150, 50, 0));
IconComponent icon = new IconComponent(iconPath);
icon.setHAlignment(HAlignment.Center);
icon.setVAlignment(VAlignment.Center);
icon.setIconSize(new Vector2f(50 , 50));
endTurnButton.setIcon(icon);
String iconEndTurnPath = "icons/icon-zugbeenden.png";
IconComponent iconEndTurn = new IconComponent(iconEndTurnPath);
iconEndTurn.setHAlignment(HAlignment.Center);
iconEndTurn.setVAlignment(VAlignment.Center);
iconEndTurn.setIconSize(new Vector2f(75, 75));
endTurnButton.setIcon(iconEndTurn);
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;
}
/**
* 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() {
long startTime = System.currentTimeMillis();
new Thread(() -> {
try {
animateDice(startTime);
@@ -401,42 +311,35 @@ public class Toolbar extends Dialog implements GameEventListener {
showFinalDiceResult(latestDiceRollEvent);
}
} catch (InterruptedException e) {
e.printStackTrace();
System.err.println("Dice animation interrupted: " + e.getMessage());
}
}).start();
}
/**
* Animates the dice roll.
*
* @param startTime The start time of the animation.
* @throws InterruptedException If the animation is interrupted.
* Animates the dice roll by cycling through dice images.
*/
private void animateDice(long startTime) throws InterruptedException {
int[] currentFace = {1};
while (System.currentTimeMillis() - startTime < 2000) {
while (System.currentTimeMillis() - startTime < 2000) { // Animation duration
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.
*/
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.
* @param event the dice roll event containing the result
*/
private void showFinalDiceResult(DiceRollEvent event) {
app.enqueue(() -> {
@@ -444,39 +347,28 @@ public class Toolbar extends Dialog implements GameEventListener {
setDiceIcon(imageLabel2, diceToString(event.b()));
});
}
/**
* 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) {
IconComponent icon = new IconComponent(imagePath);
icon.setIconSize(new Vector2f(80, 80));
icon.setIconSize(new Vector2f(80, 80)); // Set consistent dice size
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) {
return "Pictures/dice/" + switch (i) {
case 1 -> "one";
case 2 -> "two";
case 3 -> "three";
case 4 -> "four";
case 5 -> "five";
case 6 -> "six";
default -> throw new IllegalArgumentException("Invalid dice number: " + i);
} + ".png";
switch (i) {
case 1: return "Pictures/dice/one.png";
case 2: return "Pictures/dice/two.png";
case 3: return "Pictures/dice/three.png";
case 4: return "Pictures/dice/four.png";
case 5: return "Pictures/dice/five.png";
case 6: return "Pictures/dice/six.png";
default: throw new IllegalArgumentException("Invalid dice number: " + i);
}
}
/**
* 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
*/
@@ -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
public void receivedEvent(UpdatePlayerView event) {
playerHandler = app.getGameLogic().getPlayerHandler();
refreshPlayerView();
}
/**
* Refreshes the player view.
*/
private void refreshPlayerView() {
System.out.println("Update Player View");
accountContainer.clearChildren();
overviewContainer.clearChildren();
addAccountDetails();
addOverviewDetails();
accountContainer.addChild(new Label("Kontostand", new ElementId("label-toolbar")));
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);
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);
}
/**
* Adds the account details to the player view.
*/
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.
* Updates the enabled status of toolbar buttons based on the event.
*
* @param event the button status event indicating whether the buttons should be enabled
* @param event the button status event
*/
@Override
public void receivedEvent(ButtonStatusEvent event) {
boolean enabled = event.buttonsEnabled();
canRollDice = enabled;
diceButton.setEnabled(enabled);
tradeButton.setEnabled(enabled);
propertyMenuButton.setEnabled(enabled);
endTurnButton.setEnabled(false);
}
/**
* Closes the toolbar, detaching it from the GUI.
* Closes the toolbar and detaches it from the GUI.
*/
@Override
public void close() {
@@ -576,7 +459,7 @@ public class Toolbar extends Dialog implements GameEventListener {
*/
@Override
public void update() {
refreshPlayerView();
receivedEvent(new UpdatePlayerView());
super.update();
}
}

View File

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

View File

@@ -12,31 +12,33 @@ import com.simsilica.lemur.Label;
import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.style.ElementId;
import pp.dialog.Dialog;
import pp.dialog.PopupDialog;
import pp.monopoly.client.MonopolyApp;
import pp.monopoly.client.gui.SettingsMenu;
import pp.monopoly.message.server.TradeReply;
import pp.monopoly.notification.Sound;
/**
* Represents a confirmation dialog that appears when a trade is accepted.
* Displays a message to the user informing them that the trade was accepted.
* Represents a confirmation dialog that appears when a trade is 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. */
private final MonopolyApp app;
/** Semi-transparent overlay background for the dialog. */
private Geometry overlayBackground;
private final Geometry overlayBackground;
/** Container for the warning message content. */
private Container noMoneyWarningContainer;
private final Container noMoneyWarningContainer;
/** 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 msg the trade reply message containing details about the trade
@@ -45,99 +47,80 @@ public class AcceptTrade extends Dialog implements PopupDialog {
super(app.getDialogManager());
this.app = app;
// Initialize GUI elements
createOverlayBackground();
createBackgroundContainer();
createWarningContainer(msg);
// 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 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.
*/
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) {
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;
backgroundContainer.setPreferredSize(noMoneyWarningContainer.getPreferredSize().addLocal(padding, padding, 0));
// Title
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();
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;
}
/**
@@ -145,9 +128,9 @@ public class AcceptTrade extends Dialog implements PopupDialog {
*/
@Override
public void close() {
app.getGuiNode().detachChild(overlayBackground);
app.getGuiNode().detachChild(backgroundContainer);
app.getGuiNode().detachChild(noMoneyWarningContainer);
app.getGuiNode().detachChild(noMoneyWarningContainer); // Entferne das Menü
app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
app.getGuiNode().detachChild(overlayBackground); // Entferne das Overlay
super.close();
}
@@ -156,6 +139,6 @@ public class AcceptTrade extends Dialog implements PopupDialog {
*/
@Override
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.style.ElementId;
import pp.dialog.Dialog;
import pp.dialog.PopupDialog;
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. */
private final MonopolyApp app;
/** Semi-transparent overlay background for the popup. */
private Geometry overlayBackground;
private final Geometry overlayBackground;
/** Main container for the bankruptcy warning content. */
private Container bankruptContainer;
private final Container bankruptContainer;
/** Background container providing a border for the popup. */
private Container backgroundContainer;
private final Container backgroundContainer;
/**
* Constructs the bankruptcy warning popup.
@@ -40,102 +40,85 @@ public class Bankrupt extends Dialog implements PopupDialog {
super(app.getDialogManager());
this.app = app;
// Initialize the components
createOverlayBackground();
createBackgroundContainer();
createBankruptContainer();
// 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
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.
*
* @return the geometry of the overlay
*/
private void createOverlayBackground() {
private Geometry createOverlayBackground() {
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.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);
overlayBackground.setMaterial(material);
overlayBackground.setLocalTranslation(0, 0, 0);
overlay.setMaterial(material);
overlay.setLocalTranslation(0, 0, 0);
return overlay;
}
/**
* Creates the background container for the popup.
*/
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.
* Closes the menu and removes the GUI elements.
*/
@Override
public void close() {
app.getGuiNode().detachChild(overlayBackground);
app.getGuiNode().detachChild(backgroundContainer);
app.getGuiNode().detachChild(bankruptContainer);
app.getGuiNode().detachChild(bankruptContainer); // Entferne das Menü
app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
app.getGuiNode().detachChild(overlayBackground); // Entferne das Overlay
super.close();
}
@@ -146,4 +129,4 @@ public class Bankrupt extends Dialog implements PopupDialog {
public void escape() {
close();
}
}
}

View File

@@ -1,7 +1,6 @@
package pp.monopoly.client.gui.popups;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.simsilica.lemur.Button;
import com.simsilica.lemur.Container;
import com.simsilica.lemur.Label;
@@ -9,7 +8,6 @@ import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.style.ElementId;
import pp.dialog.Dialog;
import pp.dialog.PopupDialog;
import pp.monopoly.client.MonopolyApp;
import pp.monopoly.client.gui.SettingsMenu;
import pp.monopoly.message.client.BuyPropertyResponse;
@@ -18,12 +16,16 @@ import pp.monopoly.model.fields.BuildingProperty;
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;
/** Main container for the building property information. */
private final Container buildingPropertyContainer;
/** Background container providing a border for the property card. */
private final Container backgroundContainer;
/**
@@ -35,120 +37,84 @@ public class BuildingPropertyCard extends Dialog implements PopupDialog {
super(app.getDialogManager());
this.app = app;
//Generate the corresponding field
int index = app.getGameLogic().getPlayerHandler().getPlayerById(app.getId()).getFieldID();
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
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
float padding = 10f;
// Hauptcontainer für die Gebäudekarte
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));
//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());
// Position the containers
centerContainers(padding);
}
/**
* Adds the property details and buttons to the container.
*
* @param container the main container for the property card
* @param field the building property to display
*/
private void addContentToContainer(Container container, BuildingProperty field) {
// Title
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")));
// Text, der auf der Karte steht
// Die Preise werden dynamisch dem BoardManager entnommen
Container propertyValuesContainer = buildingPropertyContainer.addChild(new Container());
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")));
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")));
propertyValuesContainer.addChild(new Label("„-mit 4 Häuser: " + 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("", new ElementId("label-Text")));// Leerzeile
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)));
// Add buttons
addButtons(container);
}
/**
* 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")));
// Beenden-Button
Button quitButton = buildingPropertyContainer.addChild(new Button("Beenden", new ElementId("button")));
quitButton.setFontSize(32);
quitButton.addClickCommands(s -> ifTopDialog(() -> {
quitButton.addClickCommands(s -> ifTopDialog( () -> {
System.err.println("Button does something?");
app.getGameLogic().playSound(Sound.BUTTON);
close();
}));
// Buy button
Button buyButton = container.addChild(new Button("Kaufen", new ElementId("button")));
// Kaufen-Button
Button buyButton = buildingPropertyContainer.addChild(new Button("Kaufen", new ElementId("button")));
buyButton.setFontSize(32);
buyButton.addClickCommands(s -> ifTopDialog(() -> {
buyButton.addClickCommands(s -> ifTopDialog( () -> {
app.getGameLogic().playSound(Sound.BUTTON);
close();
app.getGameLogic().send(new BuyPropertyResponse());
}));
}
/**
* Centers the containers on the screen.
*
* @param padding the padding size
*/
private void centerContainers(float padding) {
// Center main container
// Zentriere das Popup
buildingPropertyContainer.setLocalTranslation(
(app.getCamera().getWidth() - buildingPropertyContainer.getPreferredSize().x) / 2,
(app.getCamera().getHeight() + buildingPropertyContainer.getPreferredSize().y) / 2,
8
);
// Center background container with padding
// Zentriere das Popup
backgroundContainer.setLocalTranslation(
(app.getCamera().getWidth() - buildingPropertyContainer.getPreferredSize().x - padding) / 2,
(app.getCamera().getHeight() + buildingPropertyContainer.getPreferredSize().y + padding) / 2,
7
(app.getCamera().getWidth() - buildingPropertyContainer.getPreferredSize().x - padding) / 2,
(app.getCamera().getHeight() + buildingPropertyContainer.getPreferredSize().y+ padding) / 2,
7
);
}
/**
* Attaches the popup to the GUI through the DialogManager.
*/
@Override
public void show() {
app.getGuiNode().attachChild(backgroundContainer);
app.getGuiNode().attachChild(buildingPropertyContainer);
}
/**
* Closes the popup and removes associated GUI elements.
* Closes the popup and removes the associated GUI elements.
*/
@Override
public void close() {
app.getGuiNode().detachChild(buildingPropertyContainer);
app.getGuiNode().detachChild(backgroundContainer);
app.getGuiNode().detachChild(buildingPropertyContainer); // Entferne das Menü
app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
super.close();
}
@@ -159,4 +125,4 @@ public class BuildingPropertyCard extends Dialog implements PopupDialog {
public void escape() {
new SettingsMenu(app).open();
}
}
}

View File

@@ -7,6 +7,7 @@ import com.simsilica.lemur.Button;
import com.simsilica.lemur.Container;
import com.simsilica.lemur.Label;
import com.simsilica.lemur.Selector;
import com.simsilica.lemur.TextField;
import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.component.SpringGridLayout;
import com.simsilica.lemur.core.VersionedList;
@@ -39,8 +40,8 @@ public class BuyHouse extends Dialog {
/** Background container providing a border for the popup. */
private final Container backgroundContainer;
/** Label to display selected properties. */
private Label selectionDisplay;
/** TextField to display selected properties. */
private TextField selectionDisplay;
/** Reference for tracking dropdown selection changes. */
private VersionedReference<Set<Integer>> selectionRef;
@@ -76,7 +77,7 @@ public class BuyHouse extends Dialog {
backgroundContainer.setPreferredSize(buyHouseContainer.getPreferredSize().addLocal(padding, padding, 0));
// 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.setColor(ColorRGBA.Black);
@@ -144,7 +145,7 @@ public class BuyHouse extends Dialog {
private Container createPropertyDropdown() {
Container dropdownContainer = new Container(new SpringGridLayout(Axis.Y, Axis.X));
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<>();
List<BuildingProperty> playerProperties = getPlayerProperties();
@@ -161,9 +162,8 @@ public class BuyHouse extends Dialog {
selectionRef = propertySelector.getSelectionModel().createReference();
// Initialize the selection display here
selectionDisplay = new Label("");
selectionDisplay = new TextField(""); // Create TextField for displaying selections
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
// Set initial selection

View File

@@ -7,7 +7,6 @@ import com.simsilica.lemur.Label;
import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.style.ElementId;
import pp.dialog.Dialog;
import pp.dialog.PopupDialog;
import pp.monopoly.client.MonopolyApp;
import pp.monopoly.client.gui.SettingsMenu;
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.
*/
public class ConfirmTrade extends Dialog implements PopupDialog {
public class ConfirmTrade extends Dialog {
/** Reference to the Monopoly application instance. */
private final MonopolyApp app;
/** Main container for the "Confirm Trade" popup UI. */
private Container confirmTradeContainer;
private final Container confirmTradeContainer;
/** 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. */
private final TradeHandler tradeHandler;
private TradeHandler tradeHandler;
/**
* Constructs the "Confirm Trade" popup.
@@ -40,61 +39,53 @@ public class ConfirmTrade extends Dialog implements PopupDialog {
public ConfirmTrade(MonopolyApp app) {
super(app.getDialogManager());
this.app = app;
this.tradeHandler = app.getGameLogic().getTradeHandler();
tradeHandler = app.getGameLogic().getTradeHandler();
// Initialize components
createBackgroundContainer();
createConfirmTradeContainer();
}
/**
* Initializes the background container.
*/
private void createBackgroundContainer() {
// Create the background container
backgroundContainer = new Container();
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();
// Title
Label title = confirmTradeContainer.addChild(new Label("Handel", new ElementId("warning-title")));
float padding = 10;
backgroundContainer.setPreferredSize(confirmTradeContainer.getPreferredSize().addLocal(padding, padding, 0));
// Titel
Label title = confirmTradeContainer.addChild(new Label( "Handel", new ElementId("warning-title")));
title.setFontSize(48);
title.setColor(ColorRGBA.Black);
// Build trade information strings
StringBuilder offeredProperties = new StringBuilder();
for (PropertyField field : tradeHandler.getOfferedProperties()) {
offeredProperties.append(field.getName()).append(", ");
offeredProperties.append(field.getName());
offeredProperties.append(", ");
}
StringBuilder requestedProperties = new StringBuilder();
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());
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("„Spieler " + " " + tradeHandler.getSender().getName() + " " +" möchte:", 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("- " + tradeHandler.getOfferedAmount() + " EUR", 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("- " + tradeHandler.getOfferedJailCards() +" Sonderkarten", 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("", 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.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("- "+ requestedProperties, 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("", new ElementId("label-Text")));// Leerzeile
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)));
// Decline button
// Ablehnen-Button
Button declineButton = confirmTradeContainer.addChild(new Button("Ablehnen", new ElementId("button")));
declineButton.setFontSize(32);
declineButton.addClickCommands(s -> ifTopDialog(() -> {
@@ -102,50 +93,39 @@ public class ConfirmTrade extends Dialog implements PopupDialog {
app.getGameLogic().send(new TradeResponse(false, tradeHandler));
close();
}));
// Negotiate button
// Verhandeln-Button
Button negotiateButton = confirmTradeContainer.addChild(new Button("Verhandeln", new ElementId("button")));
negotiateButton.setFontSize(32);
negotiateButton.addClickCommands(s -> ifTopDialog(() -> {
negotiateButton.addClickCommands(s -> ifTopDialog( () -> {
app.getGameLogic().playSound(Sound.BUTTON);
close();
TradeHandler t = new TradeHandler(app.getGameLogic().getPlayerHandler().getPlayerById(tradeHandler.getSender().getId()));
t.setReceiver(app.getGameLogic().getPlayerHandler().getPlayerById(tradeHandler.getReceiver().getId()));
new TradeMenu(app, t).open();
}));
// Confirm button
// Confirm-Button
Button confirmButton = confirmTradeContainer.addChild(new Button("Bestätigen", new ElementId("button")));
confirmButton.setFontSize(32);
confirmButton.addClickCommands(s -> ifTopDialog(() -> {
confirmButton.addClickCommands(s -> ifTopDialog( () -> {
app.getGameLogic().playSound(Sound.BUTTON);
app.getGameLogic().send(new TradeResponse(true, tradeHandler));
close();
}));
}
/**
* 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));
// Zentriere das Menü
confirmTradeContainer.setLocalTranslation(
(app.getCamera().getWidth() - confirmTradeContainer.getPreferredSize().x) / 2,
(app.getCamera().getHeight() + confirmTradeContainer.getPreferredSize().y) / 2,
8
(app.getCamera().getWidth() - confirmTradeContainer.getPreferredSize().x) / 2,
(app.getCamera().getHeight() + confirmTradeContainer.getPreferredSize().y) / 2,
8
);
// Zentriere das Menü
backgroundContainer.setLocalTranslation(
(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
);
// Attach to GUI node
app.getGuiNode().attachChild(backgroundContainer);
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.style.ElementId;
import pp.dialog.Dialog;
import pp.dialog.PopupDialog;
import pp.monopoly.client.MonopolyApp;
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. */
private final MonopolyApp app;
/** Semi-transparent overlay background for the popup. */
private Geometry overlayBackground;
private final Geometry overlayBackground;
/** Main container for the event card information. */
private Container eventCardContainer;
private final Container eventCardContainer;
/** 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.
@@ -42,87 +42,74 @@ public class EventCardPopup extends Dialog implements PopupDialog {
super(app.getDialogManager());
this.app = app;
// Initialize the UI components
createOverlayBackground();
createBackgroundContainer();
createEventCardContainer(description);
}
// Halbtransparentes Overlay hinzufügen
overlayBackground = createOverlayBackground();
app.getGuiNode().attachChild(overlayBackground);
/**
* 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() {
// Create the background 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.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
Label title = eventCardContainer.addChild(new Label("Ereigniskarte", new ElementId("settings-title")));
title.setFontSize(48);
title.setColor(ColorRGBA.Black);
float padding = 10;
backgroundContainer.setPreferredSize(eventCardContainer.getPreferredSize().addLocal(padding, padding, 0));
// Event description
Container textContainer = eventCardContainer.addChild(new Container());
textContainer.addChild(new Label(description, new ElementId("label-Text")));
textContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
textContainer.setPreferredSize(new Vector3f(300, 200, 0));
// Titel
Label gateFieldTitle = eventCardContainer.addChild(new Label("Ereigniskarte", new ElementId("settings-title")));
gateFieldTitle.setFontSize(48);
gateFieldTitle.setColor(ColorRGBA.Black);
// Confirm button
Button confirmButton = eventCardContainer.addChild(new Button("Jawohl", new ElementId("button")));
confirmButton.setFontSize(32);
confirmButton.addClickCommands(source -> ifTopDialog(() -> {
// Text, der auf der Karte steht
// Die Erklärungsfelder werden automatisch den descriptions der Message entnommen
Container propertyValuesContainer = eventCardContainer.addChild(new Container());
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);
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
public void show() {
float padding = 10;
// Adjust sizes and center elements
backgroundContainer.setPreferredSize(eventCardContainer.getPreferredSize().addLocal(padding, padding, 0));
eventCardContainer.setLocalTranslation(
(app.getCamera().getWidth() - eventCardContainer.getPreferredSize().x) / 2,
(app.getCamera().getHeight() + eventCardContainer.getPreferredSize().y) / 2,
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);
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));
material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
overlay.setMaterial(material);
overlay.setLocalTranslation(0, 0, 0);
return overlay;
}
/**
@@ -130,9 +117,9 @@ public class EventCardPopup extends Dialog implements PopupDialog {
*/
@Override
public void close() {
app.getGuiNode().detachChild(overlayBackground);
app.getGuiNode().detachChild(eventCardContainer);
app.getGuiNode().detachChild(backgroundContainer);
app.getGuiNode().detachChild(overlayBackground);
super.close();
}
@@ -143,4 +130,4 @@ public class EventCardPopup extends Dialog implements PopupDialog {
public void escape() {
close();
}
}
}

View File

@@ -3,7 +3,6 @@ package pp.monopoly.client.gui.popups;
import com.jme3.material.Material;
import com.jme3.material.RenderState.BlendMode;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Quad;
import com.simsilica.lemur.Button;
@@ -13,27 +12,27 @@ import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.style.ElementId;
import pp.dialog.Dialog;
import pp.dialog.PopupDialog;
import pp.monopoly.client.MonopolyApp;
import pp.monopoly.client.gui.SettingsMenu;
import pp.monopoly.message.client.BuyPropertyResponse;
import pp.monopoly.model.fields.FoodField;
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. */
private final MonopolyApp app;
/** Semi-transparent overlay background for the popup. */
private Geometry overlayBackground;
private final Geometry overlayBackground;
/** Main container for the food field information. */
private Container foodFieldContainer;
private final Container foodFieldContainer;
/** 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.
@@ -44,123 +43,108 @@ public class FoodFieldCard extends Dialog implements PopupDialog {
super(app.getDialogManager());
this.app = app;
// Retrieve field information
int index = app.getGameLogic().getPlayerHandler().getPlayerById(app.getId()).getFieldID();
FoodField field = (FoodField) app.getGameLogic().getBoardManager().getFieldAtIndex(index);
// Create UI elements
createOverlayBackground();
createBackgroundContainer();
createFoodFieldContainer(field);
}
overlayBackground = createOverlayBackground();
app.getGuiNode().attachChild(overlayBackground);
/**
* 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.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.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.1f, 0.1f, 0.1f, 0.9f)));
foodFieldContainer.setPreferredSize(new Vector3f(360,420,1));
// Title
Label title = foodFieldContainer.addChild(new Label(field.getName(), new ElementId("label-Bold")));
title.setFontSize(48);
title.setColor(ColorRGBA.White);
float padding = 10;
backgroundContainer.setPreferredSize(foodFieldContainer.getPreferredSize().addLocal(padding, padding, 0));
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());
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("Miete: 40x Würfel-Augen, wenn Besitzer eines Restaurants.", 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("", new ElementId("label-Text"))); // Empty line
propertyValuesContainer.addChild(new Label("", new ElementId("label-Text"))); // Leerzeile
propertyValuesContainer.addChild(new Label("Wenn man Besitzer des", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label(field.getName()+" ist, so ist die", new ElementId("label-Text")));
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.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")));
quitButton.setFontSize(32);
quitButton.addClickCommands(s -> ifTopDialog(() -> {
quitButton.addClickCommands(s -> ifTopDialog( () -> {
app.getGameLogic().playSound(Sound.BUTTON);
close();
}));
// Buy button
// Kaufen-Button
Button buyButton = foodFieldContainer.addChild(new Button("Kaufen", new ElementId("button")));
buyButton.setFontSize(32);
buyButton.addClickCommands(s -> ifTopDialog(() -> {
buyButton.addClickCommands(s -> ifTopDialog( () -> {
app.getGameLogic().playSound(Sound.BUTTON);
app.getGameLogic().send(new BuyPropertyResponse());
close();
}));
}
/**
* 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));
// Zentriere das Popup
foodFieldContainer.setLocalTranslation(
(app.getCamera().getWidth() - foodFieldContainer.getPreferredSize().x) / 2,
(app.getCamera().getHeight() + foodFieldContainer.getPreferredSize().y) / 2,
8
(app.getCamera().getWidth() - foodFieldContainer.getPreferredSize().x) / 2,
(app.getCamera().getHeight() + foodFieldContainer.getPreferredSize().y) / 2,
8
);
// Zentriere das Popup
backgroundContainer.setLocalTranslation(
(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
);
// Attach components to the GUI
app.getGuiNode().attachChild(overlayBackground);
app.getGuiNode().attachChild(backgroundContainer);
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.
*/
@Override
public void close() {
app.getGuiNode().detachChild(overlayBackground);
app.getGuiNode().detachChild(foodFieldContainer);
app.getGuiNode().detachChild(backgroundContainer);
app.getGuiNode().detachChild(foodFieldContainer); // Entferne das Menü
app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
app.getGuiNode().detachChild(overlayBackground); // Entferne das Overlay
super.close();
}
/**
* Handles the escape key action by closing the popup.
* Opens the settings menu when the escape key is pressed.
*/
@Override
public void escape() {
close();
new SettingsMenu(app).open();
}
}

View File

@@ -1,15 +1,12 @@
package pp.monopoly.client.gui.popups;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.simsilica.lemur.Button;
import com.simsilica.lemur.Container;
import com.simsilica.lemur.Label;
import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.style.ElementId;
import pp.dialog.Dialog;
import pp.dialog.PopupDialog;
import pp.monopoly.client.MonopolyApp;
import pp.monopoly.client.gui.SettingsMenu;
import pp.monopoly.message.client.BuyPropertyResponse;
@@ -17,17 +14,17 @@ import pp.monopoly.model.fields.GateField;
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. */
private final MonopolyApp app;
/** Main container for the gate field information. */
private Container gateFieldContainer;
private final Container gateFieldContainer;
/** 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.
@@ -38,90 +35,73 @@ public class GateFieldCard extends Dialog implements PopupDialog {
super(app.getDialogManager());
this.app = app;
// Generate the corresponding field
//Generate the corresponfing field
int index = app.getGameLogic().getPlayerHandler().getPlayerById(app.getId()).getFieldID();
GateField field = (GateField) app.getGameLogic().getBoardManager().getFieldAtIndex(index);
// Initialize UI elements
createBackgroundContainer();
createGateFieldContainer(field);
}
/**
* Initializes the background container.
*/
private void createBackgroundContainer() {
// Create the background container
backgroundContainer = new Container();
backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Light gray background
gateFieldContainer.setPreferredSize(new Vector3f(360,420,1));
}
backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Darker background
attachChild(backgroundContainer);
/**
* Initializes the main gate field container and its UI components.
*
* @param field the gate field information to display
*/
private void createGateFieldContainer(GateField field) {
// Hauptcontainer für die Gebäudekarte
gateFieldContainer = new Container();
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")));
gateFieldTitle.setFontSize(48);
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());
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("Wenn man 2 Bahnhöfe besitzt: 500 EUR", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("Wenn man 3 Bahnhöfe besitzt: 1000 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("", new ElementId("label-Text"))); // Empty line
propertyValuesContainer.addChild(new Label("Wenn man", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("2 Bahnhof besitzt: 500 EUR", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("Wenn man", new ElementId("label-Text")));
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.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")));
quitButton.setFontSize(32);
quitButton.addClickCommands(s -> ifTopDialog(() -> {
quitButton.addClickCommands(s -> ifTopDialog( () -> {
app.getGameLogic().playSound(Sound.BUTTON);
close();
}));
// Buy button
// Kaufen-Button
Button buyButton = gateFieldContainer.addChild(new Button("Kaufen", new ElementId("button")));
buyButton.setFontSize(32);
buyButton.addClickCommands(s -> ifTopDialog(() -> {
buyButton.addClickCommands(s -> ifTopDialog( () -> {
app.getGameLogic().playSound(Sound.BUTTON);
app.getGameLogic().send(new BuyPropertyResponse());
close();
}));
}
/**
* 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));
// Zentriere das Popup
gateFieldContainer.setLocalTranslation(
(app.getCamera().getWidth() - gateFieldContainer.getPreferredSize().x) / 2,
(app.getCamera().getHeight() + gateFieldContainer.getPreferredSize().y) / 2,
8
);
// Zentriere das Popup
backgroundContainer.setLocalTranslation(
(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
);
// Attach components to the GUI
app.getGuiNode().attachChild(backgroundContainer);
app.getGuiNode().attachChild(gateFieldContainer);
}
@@ -130,8 +110,8 @@ public class GateFieldCard extends Dialog implements PopupDialog {
*/
@Override
public void close() {
app.getGuiNode().detachChild(gateFieldContainer); // Remove main container
app.getGuiNode().detachChild(backgroundContainer); // Remove background container
app.getGuiNode().detachChild(gateFieldContainer); // Entferne das Menü
app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
super.close();
}

View File

@@ -11,9 +11,7 @@ import com.simsilica.lemur.Container;
import com.simsilica.lemur.Label;
import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.style.ElementId;
import pp.dialog.Dialog;
import pp.dialog.PopupDialog;
import pp.monopoly.client.MonopolyApp;
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.
* </p>
*/
public class Gulag extends Dialog implements PopupDialog {
public class Gulag extends Dialog {
/** Reference to the Monopoly application instance. */
private final MonopolyApp app;
/** Semi-transparent overlay background for the popup. */
private Geometry overlayBackground;
private final Geometry overlayBackground;
/** Main container for the Gulag warning message. */
private Container gulagContainer;
private final Container gulagContainer;
/** 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
*/
@@ -45,97 +43,90 @@ public class Gulag extends Dialog implements PopupDialog {
super(app.getDialogManager());
this.app = app;
// Initialize UI elements
createOverlayBackground();
createBackgroundContainer();
createGulagContainer();
}
/**
* Creates the semi-transparent overlay background for the popup.
*/
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);
}
// Halbtransparentes Overlay hinzufügen
overlayBackground = createOverlayBackground();
app.getGuiNode().attachChild(overlayBackground);
/**
* Creates the background container providing a border for the popup.
*/
private void createBackgroundContainer() {
// Create the background 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.
*/
private void createGulagContainer() {
// Hauptcontainer für die Warnung
gulagContainer = new Container();
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
Label title = gulagContainer.addChild(new Label("Du kommst ins Gulag!", new ElementId("warning-title")));
title.setFontSize(48);
title.setColor(ColorRGBA.Black);
float padding = 10; // Passt den backgroundContainer an die Größe des bankruptContainers an
backgroundContainer.setPreferredSize(gulagContainer.getPreferredSize().addLocal(padding, padding, 0));
// Confirmation Button
Button confirmButton = gulagContainer.addChild(new Button("Jawohl Gulag", new ElementId("button")));
confirmButton.setFontSize(32);
confirmButton.addClickCommands(source -> ifTopDialog(() -> {
// Titel
Label gateFieldTitle = gulagContainer.addChild(new Label("Du kommst ins Gulag!", new ElementId("warning-title")));
gateFieldTitle.setFontSize(48);
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);
close();
}));
}
/**
* Displays the popup by attaching its elements to the GUI.
*/
@Override
public void show() {
float padding = 10;
// Adjust and position the containers
backgroundContainer.setPreferredSize(gulagContainer.getPreferredSize().addLocal(padding, padding, 0));
// Zentriere das Popup
gulagContainer.setLocalTranslation(
(app.getCamera().getWidth() - gulagContainer.getPreferredSize().x) / 2,
(app.getCamera().getHeight() + gulagContainer.getPreferredSize().y) / 2,
8
);
// Zentriere das Popup
backgroundContainer.setLocalTranslation(
(app.getCamera().getWidth() - gulagContainer.getPreferredSize().x - padding) / 2,
(app.getCamera().getHeight() + gulagContainer.getPreferredSize().y + padding) / 2,
7
(app.getCamera().getWidth() - gulagContainer.getPreferredSize().x - padding) / 2,
(app.getCamera().getHeight() + gulagContainer.getPreferredSize().y+ padding) / 2,
7
);
// Attach components to the GUI
app.getGuiNode().attachChild(overlayBackground);
app.getGuiNode().attachChild(backgroundContainer);
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.
*/
@Override
public void close() {
app.getGuiNode().detachChild(overlayBackground);
app.getGuiNode().detachChild(gulagContainer);
app.getGuiNode().detachChild(backgroundContainer);
app.getGuiNode().detachChild(gulagContainer); // Entferne das Menü
app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
app.getGuiNode().detachChild(overlayBackground); // Entferne das Overlay
super.close();
}
/**
* Handles the escape action by closing the popup.
* Handles the escape action to close the popup.
*/
@Override
public void escape() {
close();
}
}

View File

@@ -7,138 +7,112 @@ import com.simsilica.lemur.Label;
import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.style.ElementId;
import pp.dialog.Dialog;
import pp.dialog.PopupDialog;
import pp.monopoly.client.MonopolyApp;
import pp.monopoly.client.gui.SettingsMenu;
import pp.monopoly.message.client.NotificationAnswer;
import pp.monopoly.notification.Sound;
/**
* 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.
* </p>
*/
public class GulagInfo extends Dialog implements PopupDialog {
public class GulagInfo extends Dialog {
/** Reference to the Monopoly application instance. */
private final MonopolyApp app;
/** Main container for the Gulag information dialog. */
private Container gulagInfoContainer;
private final Container gulagInfoContainer;
/** 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.
*
* @param app the Monopoly application instance
* @param app the Monopoly application instance
* @param trys the number of failed attempts to roll doubles for release
*/
public GulagInfo(MonopolyApp app, int trys) {
super(app.getDialogManager());
this.app = app;
// Initialize UI components
createBackgroundContainer();
createGulagInfoContainer(trys);
}
/**
* Creates the background container providing a border for the dialog.
*/
private void createBackgroundContainer() {
// Create the background 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);
/**
* 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) {
// Hauptcontainer für das Bestätigungspopup
gulagInfoContainer = new Container();
gulagInfoContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f)));
// Title
Label title = gulagInfoContainer.addChild(new Label("Gulag", new ElementId("warning-title")));
float padding = 10; // Passt den backgroundContainer an die Größe des confirmTradeContainer an
backgroundContainer.setPreferredSize(gulagInfoContainer.getPreferredSize().addLocal(padding, padding, 0));
// Titel
Label title = gulagInfoContainer.addChild(new Label( "Gulag", new ElementId("warning-title")));
title.setFontSize(48);
title.setColor(ColorRGBA.Black);
// Text Description
Container textContainer = gulagInfoContainer.addChild(new Container());
textContainer.addChild(new Label("„Du sitzt im Gefängnis und kommst nicht raus ...", new ElementId("label-Text")));
textContainer.addChild(new Label("Es sei denn, du ...", new ElementId("label-Text")));
textContainer.addChild(new Label("- bestichst die Wache mit 500 EUR", new ElementId("label-Text")));
textContainer.addChild(new Label("- löst eine Gulag-Frei-Karte ein", new ElementId("label-Text")));
textContainer.addChild(new Label("- wartest 3 Runden und bezahlst dann", new ElementId("label-Text")));
textContainer.addChild(new Label("- oder du würfelst einen Pasch", new ElementId("label-Text")));
textContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
// Text, der auf der Karte steht
// Die Werte werden dem Handel entnommen (Iwas auch immer da dann ist)
Container propertyValuesContainer = gulagInfoContainer.addChild(new Container());
propertyValuesContainer.addChild(new Label("„Du sitzt im Gefänginis und kommst nicht raus ...", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("Es sei denn, du ...", new ElementId("label-Text")));// Leerzeile
propertyValuesContainer.addChild(new Label("", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("- bestichst die Wache mit 500 EUR", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("- löst eine Gulag-Frei-Karte ein", new ElementId("label-Text")));
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);
}
/**
* 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
// Bezahlen-Button
Button payButton = gulagInfoContainer.addChild(new Button("Bestechungsgeld bezahlen", new ElementId("button")));
payButton.setFontSize(32);
payButton.addClickCommands(s -> ifTopDialog(() -> {
payButton.addClickCommands(s -> ifTopDialog( () -> {
app.getGameLogic().playSound(Sound.BUTTON);
app.getGameLogic().send(new NotificationAnswer("PayJail"));
close();
}));
// Use Jail-Free Card Button
Button eventCardButton = gulagInfoContainer.addChild(new Button("Ereigniskarte nutzen", new ElementId("button-toolbar2")));
// Ereigniskarte-Button
Button eventCardButton = gulagInfoContainer.addChild(new Button("Ereigniskarte nutzen", new ElementId("button")));
eventCardButton.setFontSize(32);
eventCardButton.addClickCommands(s -> ifTopDialog(() -> {
eventCardButton.addClickCommands(s -> ifTopDialog( () -> {
app.getGameLogic().playSound(Sound.BUTTON);
app.getGameLogic().send(new NotificationAnswer("UseJailCard"));
close();
}));
// Close Button
// Schließen-Button
Button closeButton = gulagInfoContainer.addChild(new Button("Schließen", new ElementId("button")));
closeButton.setFontSize(32);
closeButton.addClickCommands(s -> ifTopDialog(this::close));
closeButton.addClickCommands(s -> ifTopDialog(() -> {
app.getGameLogic().playSound(Sound.BUTTON);
close();
}));
// Disable options based on conditions
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
// Zentriere das Menü
gulagInfoContainer.setLocalTranslation(
(app.getCamera().getWidth() - gulagInfoContainer.getPreferredSize().x) / 2,
(app.getCamera().getHeight() + gulagInfoContainer.getPreferredSize().y) / 2,
8
);
// Zentriere das Menü
backgroundContainer.setLocalTranslation(
(app.getCamera().getWidth() - gulagInfoContainer.getPreferredSize().x - padding) / 2,
(app.getCamera().getHeight() + gulagInfoContainer.getPreferredSize().y + padding) / 2,
7
(app.getCamera().getWidth() - gulagInfoContainer.getPreferredSize().x - padding) / 2,
(app.getCamera().getHeight() + gulagInfoContainer.getPreferredSize().y+ padding) / 2,
7
);
// Attach containers to the GUI
app.getGuiNode().attachChild(backgroundContainer);
if(app.getGameLogic().getPlayerHandler().getPlayerById(app.getId()).getNumJailCard() == 0) {
eventCardButton.setEnabled(false);
}
if(trys == 3) {
closeButton.setEnabled(false);
}
app.getGuiNode().attachChild(gulagInfoContainer);
}
@@ -147,8 +121,16 @@ public class GulagInfo extends Dialog implements PopupDialog {
*/
@Override
public void close() {
app.getGuiNode().detachChild(gulagInfoContainer); // Remove dialog
app.getGuiNode().detachChild(backgroundContainer); // Remove background
app.getGuiNode().detachChild(gulagInfoContainer); // Entferne das Menü
app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
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.style.ElementId;
import pp.dialog.Dialog;
import pp.dialog.PopupDialog;
import pp.monopoly.client.MonopolyApp;
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. */
private final MonopolyApp app;
@@ -41,15 +46,66 @@ public class NoMoneyWarning extends Dialog implements PopupDialog {
super(app.getDialogManager());
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.
*/
@@ -57,7 +113,7 @@ public class NoMoneyWarning extends Dialog implements PopupDialog {
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)); // Semi-transparent black
material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); // Halbtransparent
material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
overlay.setMaterial(material);
overlay.setLocalTranslation(0, 0, 0);
@@ -65,86 +121,13 @@ public class NoMoneyWarning extends Dialog implements PopupDialog {
}
/**
* 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
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.
* Closes the menu and removes the GUI elements.
*/
@Override
public void close() {
app.getGuiNode().detachChild(overlayBackground);
app.getGuiNode().detachChild(backgroundContainer);
app.getGuiNode().detachChild(noMoneyWarningContainer);
app.getGuiNode().detachChild(noMoneyWarningContainer); // Entferne das Menü
app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
app.getGuiNode().detachChild(overlayBackground); // Entferne das Overlay
super.close();
}
@@ -155,4 +138,4 @@ public class NoMoneyWarning extends Dialog implements PopupDialog {
public void escape() {
close();
}
}
}

View File

@@ -12,95 +12,115 @@ import com.simsilica.lemur.Label;
import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.style.ElementId;
import pp.dialog.Dialog;
import pp.dialog.PopupDialog;
import pp.monopoly.client.MonopolyApp;
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. */
private final MonopolyApp app;
/** Semi-transparent overlay background for the popup. */
private Geometry overlayBackground;
private final Geometry overlayBackground;
/** Main container for the rent information and action. */
private Container rentContainer;
private final Container rentContainer;
/** 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 playerName the name of the player who paid the rent
* @param amount the amount of rent received
* @param playerName the name of the player to whom the rent is owed
* @param amount the amount of rent to be paid
*/
public ReceivedRent(MonopolyApp app, String playerName, int amount) {
super(app.getDialogManager());
this.app = app;
// Initialize GUI elements
createOverlayBackground();
createBackgroundContainer();
createRentContainer(playerName, amount);
// Create the overlay
overlayBackground = createOverlayBackground();
app.getGuiNode().attachChild(overlayBackground);
// 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.
*
* @return the overlay geometry
*/
private void createOverlayBackground() {
private Geometry createOverlayBackground() {
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.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);
overlay.setMaterial(material);
overlay.setLocalTranslation(0, 0, 0);
return overlay;
}
/**
* Creates the background container with styling.
*
* @return the styled background container
*/
private void createBackgroundContainer() {
backgroundContainer = new Container();
backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Light gray 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 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
* @return the rent container
*/
private void createRentContainer(String playerName, int amount) {
rentContainer = new Container();
rentContainer.setBackground(new QuadBackgroundComponent(ColorRGBA.Gray));
rentContainer.setPreferredSize(new Vector3f(550, 250, 10));
private Container createRentContainer(String playerName, int amount) {
Container container = new Container();
container.setBackground(new QuadBackgroundComponent(ColorRGBA.Gray));
container.setPreferredSize(new Vector3f(550, 250, 10));
// 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.setColor(ColorRGBA.Black);
// Rent message
Container textContainer = rentContainer.addChild(new Container());
textContainer.addChild(new Label(playerName + " zahlt dir " + amount + " EUR Miete",
Container textContainer = container.addChild(new Container());
textContainer.addChild(new Label(playerName+ " zahlt dir " + amount + " EUR Miete",
new ElementId("label-Text")));
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
Button confirmButton = rentContainer.addChild(new Button("Bestätigen", new ElementId("button")));
confirmButton.setFontSize(32);
confirmButton.addClickCommands(s -> ifTopDialog(() -> {
app.getGameLogic().playSound(Sound.BUTTON);
close();
// Payment button
Button payButton = container.addChild(new Button("Bestätigen", new ElementId("button")));
payButton.setFontSize(32);
payButton.addClickCommands(s -> ifTopDialog( () -> {
app.getGameLogic().playSound(Sound.BUTTON);
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.
*/
@Override
public void close() {
app.getGuiNode().detachChild(overlayBackground);
app.getGuiNode().detachChild(backgroundContainer);
app.getGuiNode().detachChild(rentContainer);
app.getGuiNode().detachChild(backgroundContainer);
app.getGuiNode().detachChild(overlayBackground);
super.close();
}

View File

@@ -12,16 +12,19 @@ import com.simsilica.lemur.Label;
import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.style.ElementId;
import pp.dialog.Dialog;
import pp.dialog.PopupDialog;
import pp.monopoly.client.MonopolyApp;
import pp.monopoly.message.server.TradeReply;
import pp.monopoly.notification.Sound;
/**
* 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.
* RejectTrade is a popup that appears when a trade proposal is rejected by another player
* 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. */
private final MonopolyApp app;
@@ -29,11 +32,12 @@ public class RejectTrade extends Dialog implements PopupDialog {
private final Geometry overlayBackground;
/** Main container for the rejection message content. */
private final Container rejectTradeContainer;
private final Container noMoneyWarningContainer;
/** Background container providing a border for the popup. */
private final Container backgroundContainer;
/**
* 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());
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
*/
@@ -60,98 +117,21 @@ public class RejectTrade extends Dialog implements PopupDialog {
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)); // Semi-transparent black
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;
}
/**
* 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.
*/
@Override
public void close() {
app.getGuiNode().detachChild(overlayBackground);
app.getGuiNode().detachChild(backgroundContainer);
app.getGuiNode().detachChild(rejectTradeContainer);
app.getGuiNode().detachChild(noMoneyWarningContainer); // Entferne das Menü
app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
app.getGuiNode().detachChild(overlayBackground); // Entferne das Overlay
super.close();
}
@@ -162,4 +142,4 @@ public class RejectTrade extends Dialog implements PopupDialog {
public void escape() {
close();
}
}
}

View File

@@ -12,7 +12,6 @@ import com.simsilica.lemur.Label;
import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.style.ElementId;
import pp.dialog.Dialog;
import pp.dialog.PopupDialog;
import pp.monopoly.client.MonopolyApp;
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.
* </p>
*/
public class Rent extends Dialog implements PopupDialog {
public class Rent extends Dialog {
/** Reference to the Monopoly application instance. */
private final MonopolyApp app;
/** Semi-transparent overlay background for the popup. */
private final Geometry overlayBackground;
/** Main container for the rent information and action. */
private final Container rentContainer;
/** Background container providing a border for the rent popup. */
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) {
super(app.getDialogManager());
this.app = app;
// Create the overlay and containers
// Create the overlay
overlayBackground = createOverlayBackground();
backgroundContainer = createBackgroundContainer();
rentContainer = createRentContainer(playerName, amount);
app.getGuiNode().attachChild(overlayBackground);
// 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();
}
/**
* Creates a semi-transparent overlay background.
*
* @return the overlay geometry
*/
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));
material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); // Semi-transparent black
material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
overlay.setMaterial(material);
overlay.setLocalTranslation(0, 0, 0);
return overlay;
}
/**
* Creates the background container with styling.
*
* @return the styled background container
*/
private Container createBackgroundContainer() {
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;
}
/**
* 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) {
Container container = new Container();
container.setBackground(new QuadBackgroundComponent(ColorRGBA.Gray));
container.setPreferredSize(new Vector3f(550, 250, 10));
// Title
Label title = container.addChild(new Label("Miete!", new ElementId("warning-title")));
title.setFontSize(48);
title.setColor(ColorRGBA.Black);
// Rent message
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")));
textContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
textContainer.setPreferredSize(container.getPreferredSize().addLocal(-250, -200, 0));
// Payment button
Button payButton = container.addChild(new Button("Überweisen", new ElementId("button")));
payButton.setFontSize(32);
payButton.addClickCommands(s -> ifTopDialog(() -> {
app.getGameLogic().playSound(Sound.BUTTON);
close();
payButton.addClickCommands(s -> ifTopDialog( () -> {
app.getGameLogic().playSound(Sound.BUTTON);
close();
}));
return container;
}
/**
* Centers the rent and background containers on the screen.
*/
private void centerContainers() {
float padding = 10;
// Center rent container
rentContainer.setLocalTranslation(
(app.getCamera().getWidth() - rentContainer.getPreferredSize().x) / 2,
(app.getCamera().getHeight() + rentContainer.getPreferredSize().y) / 2,
8
);
// Center background container with padding
backgroundContainer.setPreferredSize(rentContainer.getPreferredSize().addLocal(padding, padding, 0));
backgroundContainer.setLocalTranslation(
(app.getCamera().getWidth() - backgroundContainer.getPreferredSize().x) / 2,
@@ -102,25 +146,22 @@ public class Rent extends Dialog implements PopupDialog {
);
}
@Override
public void show() {
// Attach components to GUI only when the dialog is displayed via DialogManager
app.getGuiNode().attachChild(overlayBackground);
app.getGuiNode().attachChild(backgroundContainer);
app.getGuiNode().attachChild(rentContainer);
}
/**
* Closes the popup and removes GUI elements.
*/
@Override
public void close() {
app.getGuiNode().detachChild(overlayBackground);
app.getGuiNode().detachChild(backgroundContainer);
app.getGuiNode().detachChild(rentContainer);
app.getGuiNode().detachChild(backgroundContainer);
app.getGuiNode().detachChild(overlayBackground);
super.close();
}
/**
* Handles the escape action to close the dialog.
*/
@Override
public void escape() {
close();
}
}

View File

@@ -7,6 +7,7 @@ import com.simsilica.lemur.Button;
import com.simsilica.lemur.Container;
import com.simsilica.lemur.Label;
import com.simsilica.lemur.Selector;
import com.simsilica.lemur.TextField;
import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.component.SpringGridLayout;
import com.simsilica.lemur.core.VersionedList;
@@ -44,8 +45,8 @@ public class RepayMortage extends Dialog {
/** Background container providing a border for the popup. */
private final Container backgroundContainer;
/** Label to display selected properties. */
private Label selectionDisplay;
/** Text field to display selected properties. */
private TextField selectionDisplay;
/** Reference to track property selections in the dropdown menu. */
private VersionedReference<Set<Integer>> selectionRef;
@@ -81,7 +82,7 @@ public class RepayMortage extends Dialog {
backgroundContainer.setPreferredSize(repayMortageContainer.getPreferredSize().addLocal(padding, padding, 0));
// 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.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)));
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());
@@ -148,7 +149,7 @@ public class RepayMortage extends Dialog {
private Container createPropertyDropdown() {
Container dropdownContainer = new Container(new SpringGridLayout(Axis.Y, Axis.X));
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<>();
List<PropertyField> playerProperties = getPlayerProperties();
@@ -165,9 +166,8 @@ public class RepayMortage extends Dialog {
selectionRef = propertySelector.getSelectionModel().createReference();
// 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.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
dropdownContainer.addChild(selectionDisplay); // Add it to the dropdown container
// Set initial selection

View File

@@ -7,6 +7,7 @@ import com.simsilica.lemur.Button;
import com.simsilica.lemur.Container;
import com.simsilica.lemur.Label;
import com.simsilica.lemur.Selector;
import com.simsilica.lemur.TextField;
import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.component.SpringGridLayout;
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. */
private final Container backgroundContainer;
/** Label to display selected properties. */
private Label selectionDisplay;
/** Text field to display selected properties. */
private TextField selectionDisplay;
/** Reference to track selection changes in the property selector. */
private VersionedReference<Set<Integer>> selectionRef;
@@ -81,11 +82,11 @@ public class SellHouse extends Dialog {
backgroundContainer.setPreferredSize(sellhouseContainer.getPreferredSize().addLocal(padding, padding, 0));
// 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.setColor(ColorRGBA.Black);
//Unterteilung des sellHouseContainer in drei "Untercontainer"
//Unterteilund des sellHouseContainer in drei "Untercontainer"
Container upContainer = sellhouseContainer.addChild(new Container());
Container middleContainer = sellhouseContainer.addChild(new Container());
Container downContainer = sellhouseContainer.addChild(new Container());
@@ -118,7 +119,13 @@ public class SellHouse extends Dialog {
confirmButton.addClickCommands(s -> ifTopDialog( () -> {
app.getGameLogic().playSound(Sound.BUTTON);
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()));
for (Integer integer : msg.getProperties()) {
System.out.println("ID des verkaufs: "+integer);
}
app.getGameLogic().send(msg);
close();
}));
@@ -148,7 +155,7 @@ public class SellHouse extends Dialog {
private Container createPropertyDropdown() {
Container dropdownContainer = new Container(new SpringGridLayout(Axis.Y, Axis.X));
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<>();
List<BuildingProperty> playerProperties = getPlayerProperties();
@@ -165,9 +172,8 @@ public class SellHouse extends Dialog {
selectionRef = propertySelector.getSelectionModel().createReference();
// Initialize the selection display here
selectionDisplay = new Label("");
selectionDisplay = new TextField(""); // Create TextField for displaying selections
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
// Set initial selection

View File

@@ -7,6 +7,7 @@ import com.simsilica.lemur.Button;
import com.simsilica.lemur.Container;
import com.simsilica.lemur.Label;
import com.simsilica.lemur.Selector;
import com.simsilica.lemur.TextField;
import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.component.SpringGridLayout;
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. */
private final Container backgroundContainer;
/** Label to display selected properties. */
private Label selectionDisplay;
/** Text field to display selected properties. */
private TextField selectionDisplay;
/** Reference to track selection changes in the property selector. */
private VersionedReference<Set<Integer>> selectionRef;
@@ -82,7 +83,7 @@ public class TakeMortage extends Dialog {
backgroundContainer.setPreferredSize(takeMortageContainer.getPreferredSize().addLocal(padding, padding, 0));
// 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.setColor(ColorRGBA.Black);
@@ -149,7 +150,7 @@ public class TakeMortage extends Dialog {
private Container createPropertyDropdown() {
Container dropdownContainer = new Container(new SpringGridLayout(Axis.Y, Axis.X));
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<>();
List<PropertyField> playerProperties = getPlayerProperties();
@@ -171,9 +172,8 @@ public class TakeMortage extends Dialog {
selectionRef = propertySelector.getSelectionModel().createReference();
// 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.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
dropdownContainer.addChild(selectionDisplay); // Add it to the dropdown container
// 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