Merge remote-tracking branch 'origin/gui'

This commit is contained in:
Johannes Schmelz 2024-12-09 14:13:44 +01:00
commit 249110f83c
77 changed files with 1760 additions and 1142 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 518 KiB

View File

@ -0,0 +1,152 @@
# 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

@ -0,0 +1,558 @@
# 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.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 552 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

View File

@ -3,6 +3,7 @@
// 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
@ -12,6 +13,8 @@ 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)
@ -47,6 +50,23 @@ 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")
}
@ -69,7 +89,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 = 30
fontSize = 25
color = new ColorRGBA(ColorRGBA.White)
textHAlignment = HAlignment.Center
textVAlignment = VAlignment.Center
@ -81,6 +101,13 @@ 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
@ -198,7 +225,6 @@ 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") {
@ -325,22 +351,23 @@ 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 orangeBackground = new QuadBackgroundComponent(color(1, 0.5, 0, 1)); // Orange background
source.setBackground(orangeBackground);
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); // Gray background
source.setColor(ColorRGBA.White);
def grayBackground = new QuadBackgroundComponent(ColorRGBA.Gray); // Use gray when disabled
source.setBackground(grayBackground);
}
}
}
@ -366,3 +393,15 @@ 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
}

View File

@ -9,7 +9,6 @@ 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;
@ -22,11 +21,11 @@ import com.jme3.shadow.EdgeFilteringMode;
import com.jme3.texture.Texture;
import com.jme3.util.SkyFactory;
import com.jme3.util.TangentBinormalGenerator;
import pp.monopoly.model.Board;
import pp.monopoly.client.gui.BobTheBuilder;
import pp.monopoly.client.gui.Toolbar;
import static pp.util.FloatMath.PI;
import pp.monopoly.model.Board;
import pp.monopoly.client.gui.FigureControl;
import static pp.util.FloatMath.TWO_PI;
import static pp.util.FloatMath.cos;
import static pp.util.FloatMath.sin;
@ -68,6 +67,8 @@ public class BoardAppState extends MonopolyAppState {
*/
private PopUpManager popUpManager;;
private Vector3f currentTarget = new Vector3f(0f,0,0f);
/**
* 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.
@ -97,8 +98,7 @@ public class BoardAppState extends MonopolyAppState {
sceneNode.detachAllChildren();
setupScene();
if (bobTheBuilder == null) {
bobTheBuilder = new BobTheBuilder(getApp(), getApp().getRootNode());
System.out.println("LISTENER IS REGISTEDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD");
bobTheBuilder = new BobTheBuilder(getApp(), sceneNode);
getGameLogic().addListener(bobTheBuilder);
}
getApp().getRootNode().attachChild(viewNode);
@ -122,12 +122,14 @@ public class BoardAppState extends MonopolyAppState {
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),
camera.setLocation(new Vector3f(30,20,0));
camera.lookAt(new Vector3f(getCurrentTarget()),
Vector3f.UNIT_Y);
camera.update();
}
/**
* Disables the sea and sky state, removing visual elements from the scene and unregistering listeners.
* This method is called when the state is set to inactive.
@ -181,12 +183,12 @@ public class BoardAppState extends MonopolyAppState {
*/
private void setupSky() {
final AssetManager assetManager = getApp().getAssetManager();
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 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 up = assetManager.loadTexture("Pictures/Backdrop/sued.jpg"); //NON-NLS
final Texture down = assetManager.loadTexture("Pictures/Backdrop/sued.jpg"); //NON-NLS
final Spatial sky = SkyFactory.createSky(assetManager, west, east, north, south, up, down);
// sky.rotate(0, PI, 0);
viewNode.attachChild(sky);
@ -212,6 +214,28 @@ public class BoardAppState extends MonopolyAppState {
seaGeo.setMaterial(seaMat);
seaGeo.setShadowMode(ShadowMode.CastAndReceive);
TangentBinormalGenerator.generate(seaGeo);
sceneNode.attachChild(createCardDeck());
sceneNode.attachChild(seaGeo);
}
private Node createCardDeck() {
Node cardDeck = new Node("cardDeck");
Spatial card = getApp().getAssetManager().loadModel("models/Kartendecks/Ereigniskarten_Deck.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_Deck.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;
}
}

View File

@ -1,99 +0,0 @@
////////////////////////////////////////
// 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,14 +13,13 @@ 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(GameMusic.class.getName());
private static final Preferences PREFERENCES = getPreferences(GameMusic.class);
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 String ENABLED_PREF = "enabled"; // NON-NLS
private static final String VOLUME_PREF = "volume"; // NON-NLS
@ -68,8 +67,9 @@ public class GameMusic extends AbstractAppState {
/**
* Plays the main music.
*/
private void playMainMusic() {
public void playMainMusic() {
if (!isEnabled()) {
return; // Sound is disabled
}
@ -92,11 +92,10 @@ 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
*/
private void playSecondaryMusic() {
public void playSecondaryMusic() {
if (!isEnabled()) {
stopAllMusic();
return;
}
if (isSecondaryMusicPlaying) {
@ -115,7 +114,7 @@ public class GameMusic extends AbstractAppState {
/**
* Stops the secondary music.
*/
private void stopSecondaryMusic() {
public void stopSecondaryMusic() {
if (secondaryMusic != null && isSecondaryMusicPlaying) {
secondaryMusic.stop();
isSecondaryMusicPlaying = false;
@ -127,17 +126,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();
return;
}
if (isSecondaryMusicPlaying) {
stopSecondaryMusic();
playMainMusic();
} else {
stopMainMusic();
playSecondaryMusic();
}
}
@ -153,6 +152,14 @@ 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.
@ -161,13 +168,14 @@ public class GameMusic extends AbstractAppState {
*/
@Override
public void setEnabled(boolean enabled) {
if (isEnabled() == enabled) return;
if (isEnabled() == enabled) return; // Avoid redundant operations
PREFERENCES.putBoolean(ENABLED_PREF, enabled);
if (enabled) {
playMainMusic();
} else {
stopMainMusic();
stopSecondaryMusic();
stopAllMusic();
}
super.setEnabled(enabled);

View File

@ -120,6 +120,7 @@ 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,6 +15,9 @@ 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;
@ -169,6 +172,12 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga
private AppSettings makeSettings() {
final AppSettings settings = new AppSettings(true);
settings.setTitle(lookup("monopoly.name"));
try {
settings.setIcons(new Image[]{ImageIO.read(new File("src/main/resources/icons/Uniman.png"))});
}
catch (IOException e) {
LOGGER.log(Level.ERROR, e.getMessage());
}
settings.setResolution(config.getResolutionWidth(), config.getResolutionHeight());
settings.setFullscreen(config.fullScreen());
settings.setUseRetinaFrameBuffer(config.useRetinaFrameBuffer());

View File

@ -1,9 +1,5 @@
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;
@ -14,7 +10,6 @@ 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;
@ -41,14 +36,15 @@ public class BobTheBuilder extends GameBoardSynchronizer {
@Override
public Spatial visit(Figure figure) {
final Node node = new Node(FIGURE);
node.attachChild(createFigure(figure));
Spatial spatial = createFigure(figure);
node.attachChild(spatial);
// Setze die Position basierend auf der Feld-ID
node.setLocalTranslation(figure.getPos());
// Setze die Rotation basierend auf der Feld-ID
node.setLocalRotation(figure.getRot().toQuaternion());
// node.addControl(new FigureControl(figure));
node.addControl(new FigureControl(node, figure, app));
return node;
}
@ -143,17 +139,4 @@ 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

@ -0,0 +1,145 @@
package pp.monopoly.client.gui;
import com.jme3.math.FastMath;
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
LOGGER.log(Level.DEBUG, "Delay completed. Starting animation...");
}
if (currentTarget == null && !path.isEmpty()) {
// Hole das nächste Ziel aus dem Pfad
currentTarget = path.poll();
animationTime = 0f;
LOGGER.log(Level.DEBUG, "Next target: {0}", currentTarget);
}
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 + 1);
spatial.setLocalTranslation(interpolatedPosition);
// Ziel erreicht
if (animationTime >= durationPerField) {
spatial.setLocalTranslation(currentTarget);
figure.moveTo(currentTarget); // Synchronisiere die interne Position
currentTarget = null; // Setze Ziel zurück
LOGGER.log(Level.DEBUG, "Target reached. Remaining path: {0}", path.size());
}
}
}
// Beispiel: Berechnung des nächsten Feldes
private int nextField() {
int currentField = figure.getCurrentFieldID();
return (currentField + 1) % 40; // Weiter zum nächsten Feld
}
@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,38 +2,92 @@ 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 String file;
private static MonopolyApp app;
private final MonopolyApp app;
private final String functionality;
private final PlayerColor playerColor;
public ImageButton( String s, String file, MonopolyApp app ) {
this(s, true, new ElementId(ELEMENT_ID), null, file, app);
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();
}
public ImageButton( String s, String style, String file, MonopolyApp app ) {
this(s, true, new ElementId(ELEMENT_ID), style, file, app);
/**
* Updates the button's appearance based on its state.
*
* @param state the current button state
*/
private void updateButtonAppearance(ButtonState state) {
setBackgroundTexture(state.name().toLowerCase());
}
public ImageButton( String s, ElementId elementId, String file, MonopolyApp app ) {
this(s, true, elementId, null, file, app);
/**
* 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);
}
});
}
public ImageButton( String s, ElementId elementId, String style, String file, MonopolyApp app ) {
this(s, true, elementId, style, file, app);
/**
* 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));
}
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));
/**
* 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,8 +79,9 @@ public class LobbyMenu extends Dialog {
this.app = app;
GameMusic music = app.getStateManager().getState(GameMusic.class);
music.toggleMusic();
if (music != null && music.isEnabled()) {
music.playSecondaryMusic();
}
playerInputField = new TextField("Spieler "+(app.getId()+1));
// Hintergrundbild laden und hinzufügen
addBackgroundImage();
@ -276,6 +277,12 @@ 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()) {
@ -283,10 +290,27 @@ 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 selected the selected figure
* @param selector the selected figure
*/
private void onDropdownSelectionChanged(Selector<String> selector) {
app.getGameLogic().playSound(Sound.BUTTON);

View File

@ -51,7 +51,17 @@ public class SettingsMenu extends Dialog {
private final SoundSlider soundSlider;
/**
* Constructs the Menu dialog for the Battleship application.
* 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.
*
* @param app the MonopolyApp instance
*/
@ -65,10 +75,14 @@ public class SettingsMenu extends Dialog {
addChild(soundSlider);
addChild(new Checkbox("Soundeffekte an / aus", new StateCheckboxModel(app, GameSound.class)));
soundCheckbox = new Checkbox("Soundeffekte an / aus", new StateCheckboxModel(app, GameSound.class));
addChild(soundCheckbox);
addChild(new Label("Hintergrund Musik", new ElementId("label"))); //NON-NLS
addChild(new Checkbox("Musik an / aus", new StateCheckboxModel(app, GameMusic.class)));
musicCheckbox = new Checkbox("Musik an / aus", new StateCheckboxModel(app, GameMusic.class));
musicCheckbox.addClickCommands(s -> toggleMusicPreference());
addChild(musicCheckbox);
addChild(musicSlider);
@ -84,16 +98,42 @@ public class SettingsMenu extends Dialog {
}
/**
* Updates the state of the load and save buttons based on the game logic.
* 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.
*/
@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

@ -1,565 +0,0 @@
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,8 +1,11 @@
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;
@ -13,8 +16,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.MonopolyApp;
import pp.monopoly.client.gui.popups.Bankrupt;
@ -30,88 +34,41 @@ import pp.monopoly.notification.UpdatePlayerView;
/**
* Represents the toolbar interface in the Monopoly application.
* <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>
* Provides game controls, player information, and event handling.
*/
public class Toolbar extends Dialog implements GameEventListener {
/**
* Reference to the Monopoly application instance.
*/
/** The Monopoly application instance*/
private final MonopolyApp app;
/**
* The main container for the toolbar interface.
*/
/** The container representing the toolbar interface */
private final Container toolbarContainer;
/**
* Container for displaying an overview of other players.
*/
/** The container representing the player overview information */
private Container overviewContainer;
/**
* Container for displaying account-related information.
*/
/** The container representing the player account information */
private Container accountContainer;
/**
* Handles player-related data and actions.
*/
/** The player handler instance */
private PlayerHandler playerHandler;
/**
* Label for the first dice display.
*/
/** The label representing the left dice */
private Label imageLabel;
/**
* Label for the second dice display.
*/
/** The label representing the right dice */
private Label imageLabel2;
/**
* Button for rolling the dice.
*/
private Button diceButton;
/**
* Button for initiating trades.
*/
/** The flag to check if the dice can be rolled */
private boolean canRollDice = false;
/** The trade button */
private Button tradeButton;
/**
* Button for accessing the property menu.
*/
/** The property menu button */
private Button propertyMenuButton;
/**
* Button for ending the player's turn.
*/
/** The end turn button */
private Button endTurnButton;
/**
* Stores the most recent dice roll event.
*/
/** The latest incoming Dice Roll Event */
private DiceRollEvent latestDiceRollEvent = null;
/**Indicates if the bankrupt PopUp has already been shown */
/** The flag to check if the bankrupt pop up is already shown */
private boolean bankruptPopUp = false;
/**
* 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>
* Constructs a new {@code Toolbar} for the given {@code MonopolyApp}.
*
* @param app the Monopoly application instance
* @param app The {@code MonopolyApp} instance to create the toolbar for.
*/
public Toolbar(MonopolyApp app) {
super(app.getDialogManager());
@ -120,111 +77,187 @@ public class Toolbar extends Dialog implements GameEventListener {
app.getGameLogic().addListener(this);
this.playerHandler = app.getGameLogic().getPlayerHandler();
toolbarContainer = createToolbarContainer();
toolbarContainer = setupToolbar();
app.getGuiNode().attachChild(toolbarContainer);
endTurnButton.setEnabled(false);
}
private Container createToolbarContainer() {
/**
* Sets up the toolbar interface with the game controls, player information, and event handling.
*
* @return The container representing the toolbar interface.
*/
private Container setupToolbar() {
Container container = new Container(new SpringGridLayout(Axis.X, Axis.Y), "toolbar");
container.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();
setupBorders(container);
setupPlayerInfoSection(container);
setupDiceSection(container);
setupActionMenu(container);
// Oberer Balken
Container playerColorBar = new Container();
playerColorBar.setPreferredSize(new Vector3f(app.getCamera().getWidth(), 15, 0)); // Höhe des oberen Balkens
playerColorBar.setBackground(new QuadBackgroundComponent(playerColor));
playerColorBar.setLocalTranslation(0, 210, 3); // Position über der Toolbar
app.getGuiNode().attachChild(playerColorBar);
return 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);
/**
* 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);
}
// 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);
/**
* 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
// 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);
Texture backgroundTexture = app.getAssetManager().loadTexture("Pictures/"+ Player.getColor(app.getId()).getColorName()+ "Background.png");
QuadBackgroundComponent background = new QuadBackgroundComponent(backgroundTexture);
playerInfoSection.setBackground(background);
// Übersicht und Konto
accountContainer = container.addChild(new Container());
overviewContainer = container.addChild(new Container());
receivedEvent(new UpdatePlayerView()); // Initiale Aktualisierung
accountContainer = playerInfoSection.addChild(new Container());
accountContainer.setPreferredSize(new Vector3f(300, 300, 0));
accountContainer.setBackground(null);
// Würfel-Bereich
container.addChild(createDiceSection());
overviewContainer = playerInfoSection.addChild(new Container());
overviewContainer.setPreferredSize(new Vector3f(300, 300, 0));
overviewContainer.setBackground(null);
// Aktionsmenü
refreshPlayerView();
}
/**
* Sets up the dice section of the toolbar interface.
*
* @param container The container representing the toolbar interface.
*/
private void setupDiceSection(Container container) {
Container diceContainer = container.addChild(new Container(new SpringGridLayout(Axis.X, Axis.Y)));
diceContainer.addChild(createDiceDisplay());
diceContainer.setBackground(null);
}
/**
* Sets up the action menu of the toolbar interface.
*
* @param container The container representing the toolbar interface.
*/
private void setupActionMenu(Container container) {
Container menuContainer = container.addChild(new Container());
menuContainer.addChild(createTradeButton());
menuContainer.addChild(createPropertyMenuButton());
menuContainer.addChild(createEndTurnButton());
menuContainer.setBackground(null);
return container;
}
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;
/**
* 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();
}
/**
* 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(100, 100));
icon.setIconSize(new Vector2f(80, 80));
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);
@ -233,63 +266,100 @@ public class Toolbar extends Dialog implements GameEventListener {
return container;
}
private Button createTradeButton() {
/**
* 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);
});
}
tradeButton = new Button("", new ElementId("button-toolbar"));
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.setPreferredSize(new Vector3f(150, 50, 0));
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));
IconComponent icon = new IconComponent(iconPath);
icon.setHAlignment(HAlignment.Center);
icon.setVAlignment(VAlignment.Center);
icon.setIconSize(new Vector2f(75 , 75));
tradeButton.setIcon(icon);
tradeButton.setIcon(iconTrade);
tradeButton.setFontSize(40);
// Add click behavior
tradeButton.addClickCommands(source -> ifTopDialog(() -> {
app.getGameLogic().playSound(Sound.BUTTON);
tradeButton.addClickCommands(s -> ifTopDialog(() -> {
new ChoosePartner(app).open();
}));
return tradeButton;
}
private Button createPropertyMenuButton() {
propertyMenuButton = new Button("", new ElementId("button-toolbar"));
String iconPath = "icons/icon-gebaude.png";
propertyMenuButton = new ImageButton("generic", app);
propertyMenuButton.setPreferredSize(new Vector3f(150, 50, 0));
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));
IconComponent icon = new IconComponent(iconPath);
icon.setHAlignment(HAlignment.Center);
icon.setVAlignment(VAlignment.Center);
icon.setIconSize(new Vector2f(50 , 50));
propertyMenuButton.setIcon(icon);
propertyMenuButton.setIcon(iconBuilding);
propertyMenuButton.setFontSize(30);
propertyMenuButton.addClickCommands(s -> ifTopDialog(() -> {
app.getGameLogic().playSound(Sound.BUTTON);
new BuildingAdminMenu(app).open();
}));
return propertyMenuButton;
}
private Button createEndTurnButton() {
endTurnButton = new Button("", new ElementId("button-toolbar"));
endTurnButton.setFontSize(28);
// return createActionButton(playerColor, "icons/icon-zugbeenden.png", 75, () -> handleEndTurn());
String iconPath = "icons/icon-zugbeenden.png";
endTurnButton = new ImageButton("generic", app);
endTurnButton.setPreferredSize(new Vector3f(150, 50, 0));
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));
IconComponent icon = new IconComponent(iconPath);
icon.setHAlignment(HAlignment.Center);
icon.setVAlignment(VAlignment.Center);
icon.setIconSize(new Vector2f(50 , 50));
endTurnButton.setIcon(icon);
endTurnButton.setIcon(iconEndTurn);
endTurnButton.addClickCommands(s -> ifTopDialog(() -> {
app.getGameLogic().playSound(Sound.BUTTON);
if (app.getGameLogic().getPlayerHandler().getPlayerById(app.getId()).getAccountBalance() < 0 && !bankruptPopUp) {
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 {
@ -297,13 +367,13 @@ public class Toolbar extends Dialog implements GameEventListener {
app.getGameLogic().send(new EndTurn());
receivedEvent(new ButtonStatusEvent(false));
}
}));
return endTurnButton;
}
/**
* Starts the dice animation.
*/
private void startDiceAnimation() {
long startTime = System.currentTimeMillis();
new Thread(() -> {
try {
animateDice(startTime);
@ -311,35 +381,42 @@ public class Toolbar extends Dialog implements GameEventListener {
showFinalDiceResult(latestDiceRollEvent);
}
} catch (InterruptedException e) {
System.err.println("Dice animation interrupted: " + e.getMessage());
e.printStackTrace();
}
}).start();
}
/**
* Animates the dice roll by cycling through dice images.
* Animates the dice roll.
*
* @param startTime The start time of the animation.
* @throws InterruptedException If the animation is interrupted.
*/
private void animateDice(long startTime) throws InterruptedException {
int[] currentFace = {1};
while (System.currentTimeMillis() - startTime < 2000) { // Animation duration
while (System.currentTimeMillis() - startTime < 2000) {
currentFace[0] = (currentFace[0] % 6) + 1;
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
updateDiceIcons(currentFace[0]);
Thread.sleep(100);
}
}
/**
* Displays the final dice result after animation.
* Updates the dice icons with the specified face.
*
* @param event the dice roll event containing the result
* @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.
*/
private void showFinalDiceResult(DiceRollEvent event) {
app.enqueue(() -> {
@ -348,27 +425,38 @@ public class Toolbar extends Dialog implements GameEventListener {
});
}
/**
* Sets the dice icon with the specified image path.
*
* @param label The label representing the dice.
* @param imagePath The path to the icon image.
*/
private void setDiceIcon(Label label, String imagePath) {
IconComponent icon = new IconComponent(imagePath);
icon.setIconSize(new Vector2f(80, 80)); // Set consistent dice size
icon.setIconSize(new Vector2f(80, 80));
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) {
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);
}
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";
}
/**
* Handles dice roll events by updating the dice display.
* Handles dice roll events and updates the dice display.
*
* @param event the dice roll event containing dice values
*/
@ -378,67 +466,76 @@ public class Toolbar extends Dialog implements GameEventListener {
}
/**
* Updates the player view with the latest account and overview data.
* Updates the player view by refreshing the player information displayed on the toolbar.
*
* @param event the update event for the player view
* @param event the update player view event
*/
@Override
public void receivedEvent(UpdatePlayerView event) {
playerHandler = app.getGameLogic().getPlayerHandler();
System.out.println("Update Player View");
refreshPlayerView();
}
/**
* Refreshes the player view.
*/
private void refreshPlayerView() {
accountContainer.clearChildren();
overviewContainer.clearChildren();
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")
));
addAccountDetails();
addOverviewDetails();
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);
}
/**
* Updates the enabled status of toolbar buttons based on the event.
* 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.
*
* @param event the button status event
* @param event the button status event indicating whether the buttons should be enabled
*/
@Override
public void receivedEvent(ButtonStatusEvent event) {
boolean enabled = event.buttonsEnabled();
diceButton.setEnabled(enabled);
canRollDice = enabled;
tradeButton.setEnabled(enabled);
propertyMenuButton.setEnabled(enabled);
endTurnButton.setEnabled(false);
}
/**
* Closes the toolbar and detaches it from the GUI.
* Closes the toolbar, detaching it from the GUI.
*/
@Override
public void close() {
@ -459,7 +556,7 @@ public class Toolbar extends Dialog implements GameEventListener {
*/
@Override
public void update() {
receivedEvent(new UpdatePlayerView());
refreshPlayerView();
super.update();
}
}

View File

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

View File

@ -66,7 +66,8 @@ public class Bankrupt extends Dialog {
// 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.addChild(new Label("Du hast noch einen negativen Kontostand. Wenn du jetzt deinen Zug beendest, gehst du Bankrott und verlierst das Spiel!\n"+
"Dieses PopUp wird nicht erneut angezeigt!", 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

View File

@ -78,7 +78,6 @@ public class BuildingPropertyCard extends Dialog {
Button quitButton = buildingPropertyContainer.addChild(new Button("Beenden", new ElementId("button")));
quitButton.setFontSize(32);
quitButton.addClickCommands(s -> ifTopDialog( () -> {
System.err.println("Button does something?");
app.getGameLogic().playSound(Sound.BUTTON);
close();
}));
@ -95,14 +94,14 @@ public class BuildingPropertyCard extends Dialog {
buildingPropertyContainer.setLocalTranslation(
(app.getCamera().getWidth() - buildingPropertyContainer.getPreferredSize().x) / 2,
(app.getCamera().getHeight() + buildingPropertyContainer.getPreferredSize().y) / 2,
8
10
);
// Zentriere das Popup
backgroundContainer.setLocalTranslation(
(app.getCamera().getWidth() - buildingPropertyContainer.getPreferredSize().x - padding) / 2,
(app.getCamera().getHeight() + buildingPropertyContainer.getPreferredSize().y+ padding) / 2,
7
9
);
app.getGuiNode().attachChild(buildingPropertyContainer);

View File

@ -40,8 +40,8 @@ public class BuyHouse extends Dialog {
/** Background container providing a border for the popup. */
private final Container backgroundContainer;
/** TextField to display selected properties. */
private TextField selectionDisplay;
/** Label to display selected properties. */
private Label selectionDisplay;
/** Reference for tracking dropdown selection changes. */
private VersionedReference<Set<Integer>> selectionRef;
@ -77,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("warning-Bold")));
Label title = buyHouseContainer.addChild(new Label("Gebäude Kaufen", new ElementId("label-Bold")));
title.setFontSize(48);
title.setColor(ColorRGBA.Black);
@ -145,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(ColorRGBA.Orange));
dropdownContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.0f, 0.0f, 0.0f, 1.0f)));
VersionedList<String> propertyOptions = new VersionedList<>();
List<BuildingProperty> playerProperties = getPlayerProperties();
@ -162,8 +162,9 @@ public class BuyHouse extends Dialog {
selectionRef = propertySelector.getSelectionModel().createReference();
// Initialize the selection display here
selectionDisplay = new TextField(""); // Create TextField for displaying selections
selectionDisplay = new Label("");
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

@ -69,7 +69,7 @@ public class EventCardPopup extends Dialog {
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));
propertyValuesContainer.setPreferredSize(new Vector3f(300,200,0));
// Beenden-Button
Button quitButton = eventCardContainer.addChild(new Button("Jawohl", new ElementId("button")));

View File

@ -45,8 +45,8 @@ public class RepayMortage extends Dialog {
/** Background container providing a border for the popup. */
private final Container backgroundContainer;
/** Text field to display selected properties. */
private TextField selectionDisplay;
/** Label to display selected properties. */
private Label selectionDisplay;
/** Reference to track property selections in the dropdown menu. */
private VersionedReference<Set<Integer>> selectionRef;
@ -82,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("warining-Bold")));
Label title = repayMortageContainer.addChild(new Label( "Hypothek Abbezahlen", new ElementId("label-Bold")));
title.setFontSize(48);
title.setColor(ColorRGBA.Black);
@ -97,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(ColorRGBA.Orange));
middleContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.0f, 0.0f, 0.0f, 1.0f)));
middleContainer.addChild(createPropertyDropdown());
@ -149,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(ColorRGBA.Orange));
dropdownContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.0f, 0.0f, 0.0f, 1.0f)));
VersionedList<String> propertyOptions = new VersionedList<>();
List<PropertyField> playerProperties = getPlayerProperties();
@ -166,8 +166,9 @@ public class RepayMortage extends Dialog {
selectionRef = propertySelector.getSelectionModel().createReference();
// Initialize the selection display here
selectionDisplay = new TextField(""); // Create TextField for displaying selections
selectionDisplay = new Label(""); // 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

@ -45,8 +45,8 @@ public class SellHouse extends Dialog {
/** Background container providing a styled border around the main dialog. */
private final Container backgroundContainer;
/** Text field to display selected properties. */
private TextField selectionDisplay;
/** Label to display selected properties. */
private Label selectionDisplay;
/** Reference to track selection changes in the property selector. */
private VersionedReference<Set<Integer>> selectionRef;
@ -82,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("warining-Bold")));
Label title = sellhouseContainer.addChild(new Label( "Gebäude Abreißen", new ElementId("label-Bold")));
title.setFontSize(48);
title.setColor(ColorRGBA.Black);
//Unterteilund des sellHouseContainer in drei "Untercontainer"
//Unterteilung des sellHouseContainer in drei "Untercontainer"
Container upContainer = sellhouseContainer.addChild(new Container());
Container middleContainer = sellhouseContainer.addChild(new Container());
Container downContainer = sellhouseContainer.addChild(new Container());
@ -119,13 +119,7 @@ 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();
}));
@ -155,7 +149,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(ColorRGBA.Orange));
dropdownContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.0f, 0.0f, 0.0f, 1.0f)));
VersionedList<String> propertyOptions = new VersionedList<>();
List<BuildingProperty> playerProperties = getPlayerProperties();
@ -172,8 +166,9 @@ public class SellHouse extends Dialog {
selectionRef = propertySelector.getSelectionModel().createReference();
// Initialize the selection display here
selectionDisplay = new TextField(""); // Create TextField for displaying selections
selectionDisplay = new Label("");
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

@ -46,8 +46,8 @@ public class TakeMortage extends Dialog {
/** Background container providing a styled border around the main dialog. */
private final Container backgroundContainer;
/** Text field to display selected properties. */
private TextField selectionDisplay;
/** Label to display selected properties. */
private Label selectionDisplay;
/** Reference to track selection changes in the property selector. */
private VersionedReference<Set<Integer>> selectionRef;
@ -83,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("warining-Bold")));
Label title = takeMortageContainer.addChild(new Label( "Hypothek aufnehmen", new ElementId("label-Bold")));
title.setFontSize(48);
title.setColor(ColorRGBA.Black);
@ -150,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(ColorRGBA.Orange));
dropdownContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.0f, 0.0f, 0.0f, 1.0f)));
VersionedList<String> propertyOptions = new VersionedList<>();
List<PropertyField> playerProperties = getPlayerProperties();
@ -172,8 +172,9 @@ public class TakeMortage extends Dialog {
selectionRef = propertySelector.getSelectionModel().createReference();
// Initialize the selection display here
selectionDisplay = new TextField(""); // Create TextField for displaying selections
selectionDisplay = new Label(""); // 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.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 195 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 205 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 193 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 195 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 364 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 518 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 552 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

View File

@ -1,9 +1,4 @@
package pp.monopoly.game.client;
import pp.monopoly.game.server.Player;
import pp.monopoly.message.server.NextPlayerTurn;
import pp.monopoly.message.server.ViewAssetsResponse;
/**
* Represents the active client state in the Monopoly game.
* Extends {@link ClientState}.
@ -24,17 +19,4 @@ public class ActiveState extends ClientState {
boolean isTurn() {
return true;
}
@Override
void recivedNextPlayerTurn(NextPlayerTurn msg) {
logic.getBoard().clear();
for (Player player : logic.getPlayerHandler().getPlayers()) {
logic.getBoard().add(player.getFigure());
}
}
@Override
void recivedViewAssetsResponse(ViewAssetsResponse msg) {
}
}

View File

@ -4,6 +4,9 @@ import java.lang.System.Logger;
import java.lang.System.Logger.Level;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import com.jme3.math.Vector3f;
import pp.monopoly.game.server.Player;
import pp.monopoly.game.server.PlayerHandler;
@ -24,8 +27,10 @@ import pp.monopoly.message.server.TradeReply;
import pp.monopoly.message.server.TradeRequest;
import pp.monopoly.message.server.ViewAssetsResponse;
import pp.monopoly.model.Board;
import pp.monopoly.model.Figure;
import pp.monopoly.model.Hotel;
import pp.monopoly.model.House;
import pp.monopoly.model.Rotation;
import pp.monopoly.model.TradeHandler;
import pp.monopoly.model.fields.BoardManager;
import pp.monopoly.model.fields.BuildingProperty;
@ -231,7 +236,7 @@ public class ClientGameLogic implements ServerInterpreter, GameEventBroker {
playerHandler = msg.getPlayerHandler();
setState(new WaitForTurnState(this));
for (Player player : playerHandler.getPlayers()) {
board.add(player.getFigure());
board.add(new Figure(Vector3f.ZERO, Rotation.NORTH, player.getFigure(), player.getId()));
}
notifyListeners(new ButtonStatusEvent(false));
notifyListeners(new UpdatePlayerView());
@ -248,7 +253,7 @@ public class ClientGameLogic implements ServerInterpreter, GameEventBroker {
@Override
public void received(PlayerStatusUpdate msg) {
playerHandler = msg.getPlayerHandler();
System.out.println("Update Player");
LOGGER.log(Level.TRACE, "Update Player View triggerd with message: {0}", msg);
notifyListeners(new UpdatePlayerView());
}
@ -305,19 +310,31 @@ public class ClientGameLogic implements ServerInterpreter, GameEventBroker {
} else if(msg.getKeyWord().equals("ReceivedRent")) {
playSound(Sound.MONEY_COLLECTED);
notifyListeners(new PopUpEvent("ReceivedRent", msg));
} else if (msg.getKeyWord().equals("aussetzen")) {
notifyListeners(new ButtonStatusEvent(false));
}
}
@Override
public void received(BuildInfo msg) {
System.out.println("TRIGGER BUILD INFO");
if (msg.isAdded()) {
BuildingProperty property = ((BuildingProperty)boardManager.getFieldAtIndex(msg.getId()));
if (property.getHotel() == 1 ) {
for(int i = 0; i < 4; i++) {
board.remove(board.getHouse(msg.getId(), i+1));
}
board.add(new Hotel(property.getId()));
} else {
board.add(new House( property.getHouses(), property.getId()));
}
} else {
if( ((BuildingProperty)boardManager.getFieldAtIndex(msg.getId())).getHouses() == 4 ) {
board.remove(board.getHotel(msg.getId()));
} else {
board.remove(board.getHouse(msg.getId(), ((BuildingProperty)boardManager.getFieldAtIndex(msg.getId())).getHouses()+1));
}
}
}

View File

@ -23,7 +23,6 @@ import pp.monopoly.message.server.NextPlayerTurn;
import pp.monopoly.message.server.NotificationMessage;
import pp.monopoly.message.server.PlayerStatusUpdate;
import pp.monopoly.model.FieldVisitor;
import pp.monopoly.model.Figure;
import pp.monopoly.model.card.Card;
import pp.monopoly.model.fields.BuildingProperty;
import pp.monopoly.model.fields.EventField;
@ -44,7 +43,7 @@ public class Player implements FieldVisitor<Void>{
private final int id;
private String name;
private int accountBalance = 15000;
private Figure figure;
private String figure;
private Set<Integer> properties = new HashSet<>();
private int getOutOfJailCard;
private int fieldID;
@ -82,11 +81,19 @@ public class Player implements FieldVisitor<Void>{
this.handler = handler;
}
public void setFigure(Figure figure) {
/**
* Set the figure of the player
* @param figure the figure to be set
*/
public void setFigure(String figure) {
this.figure = figure;
}
public Figure getFigure(){
/**
* Returns the figure of the player
* @return the figure of the player
*/
public String getFigure() {
return figure;
}
@ -180,7 +187,6 @@ public class Player implements FieldVisitor<Void>{
earnMoney(2000); // Passing GO gives money
}
fieldID = (fieldID + steps) % 40;
figure.moveTo(fieldID);
handler.getLogic().send(this, new PlayerStatusUpdate(handler));
handler.getLogic().getBoardManager().getFieldAtIndex(fieldID).accept(this);
return fieldID;
@ -194,7 +200,6 @@ public class Player implements FieldVisitor<Void>{
public int setPosition(int position){
if(position < 40 && position >= 0) {
fieldID = position;
figure.moveTo(fieldID);
handler.getLogic().send(this, new PlayerStatusUpdate(handler));
handler.getLogic().getBoardManager().getFieldAtIndex(fieldID).accept(this);
}
@ -212,7 +217,6 @@ public class Player implements FieldVisitor<Void>{
earnMoney(2000);
}
fieldID = position;
figure.moveTo(fieldID);
handler.getLogic().send(this, new PlayerStatusUpdate(handler));
handler.getLogic().getBoardManager().getFieldAtIndex(fieldID).accept(this);
}

View File

@ -6,12 +6,14 @@ import com.jme3.math.ColorRGBA;
* Enum representing six distinct colors for players in the game.
*/
public enum PlayerColor {
CYAN(new ColorRGBA(1 / 255f, 190 / 255f, 254 / 255f, 1), "Cyan"),
YELLOW(new ColorRGBA(255 / 255f, 255 / 255f, 0 / 255f, 1), "Gelb"),
RED(new ColorRGBA(255 / 255f, 0 / 255f, 0 / 255f, 1), "Rot"),
PINK(new ColorRGBA(255 / 255f, 77 / 255f, 166 / 255f, 1), "Pink"),
GREEN(new ColorRGBA(0 / 255f, 204 / 255f, 0 / 255f, 1), "Grün"),
PURPLE(new ColorRGBA(143 / 255f, 0 / 255f, 255 / 255f, 1), "Lila");
CYAN(new ColorRGBA(69 / 255f, 205 / 255f, 205 / 255f, 1), "Cyan"),
YELLOW(new ColorRGBA(225 / 255f, 201 / 255f, 44 / 255f, 1), "Yellow"),
RED(new ColorRGBA(255 / 255f, 33 / 255f, 33 / 255f, 1), "Red"),
PINK(new ColorRGBA(196 / 255f, 73 / 255f, 240 / 255f, 1), "Pink"),
GREEN(new ColorRGBA(61 / 255f, 227 / 255f, 58 / 255f, 1), "Green"),
PURPLE(new ColorRGBA(60 / 255f, 74 / 255f, 223 / 255f, 1), "Purple");
private final ColorRGBA color;
private final String colorName;

View File

@ -3,11 +3,9 @@ package pp.monopoly.game.server;
import java.lang.System.Logger;
import java.lang.System.Logger.Level;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import com.jme3.math.Vector3f;
import pp.monopoly.MonopolyConfig;
import pp.monopoly.message.client.AlterProperty;
@ -29,8 +27,6 @@ import pp.monopoly.message.server.ServerMessage;
import pp.monopoly.message.server.TradeReply;
import pp.monopoly.message.server.TradeRequest;
import pp.monopoly.message.server.ViewAssetsResponse;
import pp.monopoly.model.Figure;
import pp.monopoly.model.Rotation;
import pp.monopoly.model.TradeHandler;
import pp.monopoly.model.card.DeckHelper;
import pp.monopoly.model.fields.BoardManager;
@ -89,7 +85,7 @@ public class ServerGameLogic implements ClientInterpreter {
* @param player the Player to whom the message is sent
* @param msg the ServerMessage to send
*/
void send(Player player, ServerMessage msg) {
public void send(Player player, ServerMessage msg) {
if (player != null && msg != null) {
serverSender.send(player.getId(), msg);
LOGGER.log(Level.DEBUG, "Message sent to player {0}: {1}", player.getName(), msg.getClass().getSimpleName());
@ -172,7 +168,6 @@ public class ServerGameLogic implements ClientInterpreter {
PropertyField property = (PropertyField) boardManager.getFieldAtIndex(player.getFieldID()); // Assuming player position for property
player.buyProperty(property);
System.out.println("Properties:" +player.getProperties().toString());
LOGGER.log(Level.INFO, "Player {0} bought property {1}", player.getName(), property.getName());
}
updateAllPlayers();
@ -223,8 +218,7 @@ public class ServerGameLogic implements ClientInterpreter {
String name = msg.getName();
String truc = name.length() > 10 ? name.substring(0, 15) : name;
player.setName(truc);
Figure figure = new Figure(new Vector3f(0, 1, 0), Rotation.NORTH, msg.getFigure());
player.setFigure(figure);
player.setFigure(msg.getFigure());
// board.addFigure(figure);
playerHandler.setPlayerReady(player, true);
LOGGER.log(Level.DEBUG, "Player {0} is ready", player.getName());
@ -327,25 +321,29 @@ public class ServerGameLogic implements ClientInterpreter {
}
/**
* Executes the trade by transferring requested properties from the receiver
* to the sender and offered properties from the sender to the receiver.
* Executes a trade between two players, transferring properties and money as specified.
*
* @param sender the player initiating the trade
* @param receiver the player receiving the trade offer
* @param requestedProperties the properties requested by the receiver
* @param offeredProperties the properties offered by the sender
*/
public void executeTrade(Player sender, Player receiver, Set<PropertyField> requestedProperties, Set<PropertyField> offeredProperties) {
private void executeTrade(Player sender, Player receiver, Set<PropertyField> requestedProperties, Set<PropertyField> offeredProperties) {
// Transfer requested properties from receiver to sender
for (PropertyField field : requestedProperties) {
for (PropertyField field : offeredProperties) {
receiver.removeProperty(field.getId());
sender.addProperty(field.getId());
field.setOwner(sender); // Update ownership
System.out.printf("Property %s transferred from %s to %s.\n",
LOGGER.log(Level.DEBUG, "Property %s transferred from %s to %s.\n",
field.getName(), receiver.getName(), sender.getName());
}
// Transfer offered properties from sender to receiver
for (PropertyField field : offeredProperties) {
for (PropertyField field : requestedProperties) {
sender.removeProperty(field.getId());
receiver.addProperty(field.getId());
field.setOwner(receiver); // Update ownership
System.out.printf("Property %s transferred from %s to %s.\n",
LOGGER.log(Level.DEBUG, "Property %s transferred from %s to %s.\n",
field.getName(), sender.getName(), receiver.getName());
}
}
@ -448,16 +446,95 @@ public class ServerGameLogic implements ClientInterpreter {
} else if (msg.getKeyword().equals("PayJail")) {
playerHandler.getPlayerById(from).payBail();
} else if(msg.getKeyword().equals("hack")) {
// for (BuildingProperty bp : boardManager.getPropertyFields( List.of(1,3)).stream().filter(p -> p instanceof BuildingProperty).map(p -> (BuildingProperty) p).collect(Collectors.toList())) {
// bp.build();
// }
for(PropertyField field : boardManager.getBoard().stream().filter(p -> p instanceof PropertyField).map(p -> (PropertyField) p).collect(Collectors.toList())) {
field.setOwner(playerHandler.getPlayerById(0));
playerHandler.getPlayerById(0).addProperty(field.getId());
}
playerHandler.getPlayerById(0).earnMoney(20000);
generatePredefinedGameState();
}
updateAllPlayers();
}
private void generatePredefinedGameState() {
if(playerHandler.getPlayerCount() < 2) {
return;
}
Player p1 = playerHandler.getPlayerById(0);
Player p2 = playerHandler.getPlayerById(1);
// Reset properties and balances for a clean state
p1.getProperties().clear();
p2.getProperties().clear();
boardManager.getBoard().forEach(field -> {
if (field instanceof PropertyField) {
((PropertyField) field).setOwner(null);
}
});
// Define properties to assign
Set<Integer> p1Properties = Set.of(1, 3, 6, 8); // Gym, Sportplatz, Studium+, PhysikHörsaal
Set<Integer> p2Properties = Set.of(21, 23, 24, 9); // Red set + Audimax
// Assign properties via AlterProperty
assignProperties(p1, p1Properties);
assignProperties(p2, p2Properties);
// Player 1 builds houses on Gym and Sportplatz
// buildHouses(p1, Set.of(1, 3));
// Player 2 builds houses on the Red set
// buildHouses(p2, Set.of(21, 23, 24));
// Set player balances
p1.setAccountBalance(12325);
p2.setAccountBalance(26750);
// Add Get Out of Jail cards
p1.addJailCard();
// Set player positions
p1.setPosition(6); // Near Studium+
p2.setPosition(25); // Near Nordtor
LOGGER.log(Level.INFO, "Predefined game state generated.");
updateAllPlayers();
}
/**
* Assigns properties to a player using AlterProperty messages.
*
* @param player the player to assign properties to
* @param properties the set of property IDs to assign
*/
private void assignProperties(Player player, Set<Integer> properties) {
AlterProperty alterProperty = new AlterProperty("AssignProperties");
alterProperty.setProperties(properties);
for (Integer propertyId : properties) {
PropertyField field = (PropertyField) boardManager.getFieldAtIndex(propertyId);
field.setOwner(player);
player.addProperty(propertyId);
}
LOGGER.log(Level.DEBUG, "Properties assigned to player {0}: {1}", player.getName(), properties);
}
/**
* Builds houses for a player on specific properties using AlterProperty messages.
*
* @param player the player building houses
* @param properties the set of property IDs to build houses on
*/
private void buildHouses(Player player, Set<Integer> properties) {
AlterProperty alterProperty = new AlterProperty("BuyHouse");
alterProperty.setProperties(properties);
for (Integer propertyId : properties) {
BuildingProperty field = (BuildingProperty) boardManager.getFieldAtIndex(propertyId);
if (boardManager.canBuild(field) && player.getAccountBalance() >= field.getHousePrice()) {
field.build();
player.pay(field.getHousePrice());
LOGGER.log(Level.DEBUG, "House built on property {0} for player {1}.", field.getName(), player.getName());
}
}
}
}

View File

@ -28,7 +28,18 @@ public class TradeResponse extends ClientMessage{
this.tradeHandler = tradeHandler;
}
/**
* Returns whether the trade was accepted.
*
* @return {@code true} if the trade was accepted, {@code false} otherwise
*/
public boolean isAccepted() { return status; }
/**
* Returns the TradeHandler corresponding to the Trade.
*
* @return the TradeHandler corresponding to the Trade
*/
public TradeHandler getTradeHandler() {
return tradeHandler;
}

View File

@ -139,6 +139,14 @@ public class Board {
return getItems(House.class);
}
public House getHouse(int fieldId, int stage) {
return getHouses().filter(house -> house.getFieldID() == fieldId && house.getStage() == stage).findFirst().orElse(null);
}
public Hotel getHotel(int fieldId) {
return getHotels().filter(hotel -> hotel.getFieldID() == fieldId).findFirst().orElse(null);
}
/**
* Returns a stream of all hotels currently on the map.
*

View File

@ -7,6 +7,8 @@ import com.jme3.network.serializing.Serializable;
@Serializable
public class Figure implements Item{
private final int id;
private final String type;
private Vector3f position;
private Rotation rot; // The rotation of the Figure
@ -16,7 +18,7 @@ public class Figure implements Item{
* at position (0, 0), with a default rotation of NORTH.
*/
private Figure() {
this(null, Rotation.NORTH, "");
this(null, Rotation.NORTH, "", 0);
}
/**
@ -27,10 +29,19 @@ public class Figure implements Item{
* @param z the z-coordinate of the Figure's initial position
* @param rot the rotation of the Figure
*/
public Figure(Vector3f position, Rotation rot, String type) {
public Figure(Vector3f position, Rotation rot, String type, int id) {
this.position = calculateFieldPosition(0);
this.rot = rot;
this.type = type;
this.id = id;
}
/**
* Return the id corresponding to the players id
* @return the id of the figure
*/
public int getId() {
return id;
}
/**
@ -87,7 +98,7 @@ public class Figure implements Item{
moveTo(calculateFieldPosition(fieldId));
}
private Vector3f calculateFieldPosition(int fieldID) {
public Vector3f calculateFieldPosition(int fieldID) {
float baseX = 0.0f;
float baseZ = 0.0f;
@ -139,7 +150,18 @@ public class Figure implements Item{
float zOffset = new Random().nextFloat();
//TODO adjust y pos
return new Vector3f(baseX + xOffset, 1, baseZ + zOffset);
return new Vector3f(baseX , 0, baseZ );
}
public int getCurrentFieldID() {
Vector3f pos = getPos();
for (int fieldID = 0; fieldID < 40; fieldID++) {
Vector3f fieldPosition = calculateFieldPosition(fieldID);
if (pos.distance(fieldPosition) < 0.1f) { // Toleranz für Positionsvergleich
return fieldID;
}
}
throw new IllegalStateException("Current field ID could not be determined from position: " + pos);
}
/**

View File

@ -96,4 +96,13 @@ public class Hotel implements Item{
// TODO
return Rotation.NORTH;
}
/**
* Returns the ID of the field the hotel is on.
*
* @return the ID of the field the hotel is on
*/
public int getFieldID() {
return fieldID;
}
}

View File

@ -24,6 +24,15 @@ public class House implements Item{
this.fieldID = 0;
}
/**
* Returns the field ID of the house.
*
* @return the field ID of the house
*/
public int getFieldID() {
return fieldID;
}
/**
* Creates a new house with the given stage.
*

View File

@ -8,6 +8,7 @@ import java.util.Queue;
import pp.monopoly.game.server.Player;
import pp.monopoly.message.client.EndTurn;
import pp.monopoly.message.server.NotificationMessage;
public class DeckHelper{
@ -258,6 +259,7 @@ public class DeckHelper{
private void rueckstuferantrag(Player player) {
player.getHandler().getLogic().received(new EndTurn(), player.getId());
player.getHandler().getLogic().send(player, new NotificationMessage("aussetzen"));
}
private void hausfeierSturz(Player player) {
@ -272,6 +274,7 @@ public class DeckHelper{
private void dienstreiseLourd(Player player) {
player.pay(1000);
player.getHandler().getLogic().received(new EndTurn(), player.getId());
player.getHandler().getLogic().send(player, new NotificationMessage("aussetzen"));
}
private void blutspendenSonderurlaub(Player player) {
@ -296,6 +299,7 @@ public class DeckHelper{
private void partyEskaliert(Player player) {
player.getHandler().getLogic().received(new EndTurn(), player.getId());
player.getHandler().getLogic().send(player, new NotificationMessage("aussetzen"));
}
private void vpEinstandsparty(Player player) {
@ -308,6 +312,7 @@ public class DeckHelper{
private void bergmarsch(Player player) {
player.getHandler().getLogic().received(new EndTurn(), player.getId());
player.getHandler().getLogic().send(player, new NotificationMessage("aussetzen"));
}
private void jodelEispenis(Player player) {

View File

@ -146,9 +146,10 @@ public class BoardManager {
}
/**
* Checks if a House can be sold on the given Property
* Checks if a House or Hotel can be sold on the given Property.
*
* @param field the Property to check
* @return true if a house can be sold on the property, false otherwise
* @return true if a house or hotel can be sold on the property, false otherwise
*/
public boolean canSell(BuildingProperty field) {
if (field == null) {
@ -174,7 +175,7 @@ public class BoardManager {
int currentHouses = field.getHouses();
int currentHotel = field.getHotel();
// If there is a hotel, selling is allowed only if all other properties have max houses
// If there is a hotel, ensure all other properties have max houses (4) before selling it
if (currentHotel > 0) {
return groupProperties.stream()
.allMatch(bp -> bp.getHouses() == 4 || bp.equals(field));
@ -185,6 +186,7 @@ public class BoardManager {
.allMatch(bp -> bp.getHouses() <= currentHouses);
}
/**
* Gibt eine Liste von BuildingProperty-Feldern zurück, auf denen Häuser oder Hotels stehen.
* @return Liste von BuildingProperty-Feldern mit Gebäuden
@ -198,3 +200,10 @@ public class BoardManager {
}
}
/* TODO:
- Häuser beim bau eines Hotels entfernen
- Alle texturen schwarz
*
*/

View File

@ -90,7 +90,7 @@ public class ServerGameLogicTest {
// Arrange: Spieler initialisieren und Position setzen
Player player = new Player(1, "Testspieler", mock(PlayerHandler.class)); // Spieler-Objekt erstellen
Figure figure = mock(Figure.class); // Mock für die Spielfigur
player.setFigure(figure); // Mock-Figur dem Spieler zuweisen
int initialFieldID = player.getFieldID(); // Startfeld
DiceResult diceResult = new DiceResult(3, 4); // Würfel: 3 und 4
@ -106,7 +106,7 @@ public class ServerGameLogicTest {
// Assert: Position überprüfen und sicherstellen, dass `figure.moveTo` aufgerufen wurde
assertEquals(expectedFieldID, player.getFieldID()); // Überprüfen, ob der Spieler auf dem erwarteten Feld ist
verify(figure).moveTo(expectedFieldID); // Sicherstellen, dass die Figur bewegt wurde
}
/**
@ -748,7 +748,6 @@ public class ServerGameLogicTest {
// Create a player with mocked handler
Player player = new Player(1, "Spieler 1", handler);
player.setFigure(figure); // Set the mocked figure
// player.setPosition(5); // Set the initial position
// Stub handler.getLogic() to return mocked ServerGameLogic
@ -802,8 +801,6 @@ public class ServerGameLogicTest {
player.buyProperty(property);
System.out.println("Player Balance: " + player.getAccountBalance());
System.out.println("Player Properties: " + player.getProperties());
assertEquals(14000, player.getAccountBalance());
assertTrue(player.getProperties().contains(property.getId()));
}
@ -1028,7 +1025,11 @@ public class ServerGameLogicTest {
player.jail();
try {
player.payBail();
} catch (Exception e) {
e.printStackTrace();
}
// Assert: Spieler ist nicht mehr im Gulag und Geld wurde abgezogen
assertTrue(player.canFinishTurn()); // Spieler kann den Zug beenden
@ -1231,10 +1232,6 @@ public class ServerGameLogicTest {
handler.addPlayer(player2);
handler.addPlayer(player3);
player1.setFigure(figure); // Zuweisung einer Spielfigur
player2.setFigure(figure);
player3.setFigure(figure);
DeckHelper deckHelper = new DeckHelper();
Card card = null;
@ -1263,7 +1260,7 @@ public class ServerGameLogicTest {
// Arrange
PlayerHandler handler = new PlayerHandler(null);
Player player = new Player(1, handler);
player.setFigure(figure);
DeckHelper deckHelper = new DeckHelper();
Card card = null;
@ -1290,7 +1287,7 @@ public class ServerGameLogicTest {
// Arrange
PlayerHandler handler = new PlayerHandler(null);
Player player = new Player(1, handler);
player.setFigure(figure); // Zuweisung einer Spielfigur
DeckHelper deckHelper = new DeckHelper();
Card card = null;
@ -1316,7 +1313,7 @@ public class ServerGameLogicTest {
// Arrange
PlayerHandler handler = new PlayerHandler(null);
Player player = new Player(1, handler);
player.setFigure(figure); // Zuweisung einer Spielfigur
DeckHelper deckHelper = new DeckHelper();
Card card = null;
@ -1346,7 +1343,7 @@ public class ServerGameLogicTest {
ServerGameLogic logic = mock(ServerGameLogic.class); // Mock ServerGameLogic
PlayerHandler handler = new PlayerHandler(logic); // Übergebe den Mock
Player player = new Player(1, handler);
player.setFigure(figure); // Zuweisung einer Spielfigur
DeckHelper deckHelper = new DeckHelper();
Card card = null;
@ -1370,7 +1367,7 @@ public class ServerGameLogicTest {
ServerGameLogic logic = mock(ServerGameLogic.class); // Mock ServerGameLogic
PlayerHandler handler = new PlayerHandler(logic); // Übergebe den Mock
Player player = new Player(1, handler);
player.setFigure(figure); // Zuweisung einer Spielfigur
handler.addPlayer(player); // Spieler zur Liste hinzufügen
DeckHelper deckHelper = new DeckHelper();
@ -1395,7 +1392,7 @@ public class ServerGameLogicTest {
ServerGameLogic logic = mock(ServerGameLogic.class); // Mock ServerGameLogic
PlayerHandler handler = new PlayerHandler(logic); // Übergebe den Mock
Player player = new Player(1, handler);
player.setFigure(figure); // Zuweisung einer Spielfigur
handler.addPlayer(player); // Spieler zur Liste hinzufügen
DeckHelper deckHelper = new DeckHelper();
@ -1422,7 +1419,7 @@ public class ServerGameLogicTest {
ServerGameLogic logic = mock(ServerGameLogic.class); // Mock ServerGameLogic
PlayerHandler handler = new PlayerHandler(logic); // Übergebe den Mock
Player player = new Player(1, handler);
player.setFigure(figure); // Zuweisung einer Spielfigur
handler.addPlayer(player); // Spieler zur Liste hinzufügen
DeckHelper deckHelper = new DeckHelper();
@ -1449,7 +1446,7 @@ public class ServerGameLogicTest {
ServerGameLogic logic = mock(ServerGameLogic.class); // Mock ServerGameLogic
PlayerHandler handler = new PlayerHandler(logic); // Übergebe den Mock
Player player = new Player(1, handler);
player.setFigure(figure); // Zuweisung einer Spielfigur
handler.addPlayer(player); // Spieler zur Liste hinzufügen
DeckHelper deckHelper = new DeckHelper();
@ -1484,7 +1481,7 @@ public class ServerGameLogicTest {
ServerGameLogic logic = mock(ServerGameLogic.class); // Mock ServerGameLogic
PlayerHandler handler = new PlayerHandler(logic); // Übergebe den Mock
Player player = new Player(1, handler);
player.setFigure(figure); // Zuweisung einer Spielfigur
player.setAccountBalance(1500); // Startguthaben
handler.addPlayer(player); // Spieler zur Liste hinzufügen
DeckHelper deckHelper = new DeckHelper();
@ -1511,7 +1508,7 @@ public class ServerGameLogicTest {
ServerGameLogic logic = mock(ServerGameLogic.class); // Mock ServerGameLogic
PlayerHandler handler = new PlayerHandler(logic); // Übergebe den Mock
Player player = new Player(1, handler);
player.setFigure(figure); // Zuweisung einer Spielfigur
handler.addPlayer(player); // Spieler zur Liste hinzufügen
DeckHelper deckHelper = new DeckHelper();
@ -1542,7 +1539,7 @@ public class ServerGameLogicTest {
ServerGameLogic logic = mock(ServerGameLogic.class); // Mock ServerGameLogic
PlayerHandler handler = new PlayerHandler(logic); // Übergebe den Mock
Player player = new Player(1, handler);
player.setFigure(figure); // Zuweisung einer Spielfigur
handler.addPlayer(player); // Spieler zur Liste hinzufügen
DeckHelper deckHelper = new DeckHelper();
@ -1565,7 +1562,7 @@ public class ServerGameLogicTest {
ServerGameLogic logic = mock(ServerGameLogic.class); // Mock ServerGameLogic
PlayerHandler handler = new PlayerHandler(logic); // Übergebe den Mock
Player player = new Player(1, handler);
player.setFigure(figure); // Zuweisung einer Spielfigur
try {
player.setPosition(10); // Starte auf Position 10
} catch (Exception e) {
@ -1594,7 +1591,7 @@ public class ServerGameLogicTest {
ServerGameLogic logic = mock(ServerGameLogic.class); // Mock ServerGameLogic
PlayerHandler handler = new PlayerHandler(logic); // Übergebe den Mock
Player player = new Player(1, handler);
player.setFigure(figure); // Zuweisung einer Spielfigur
handler.addPlayer(player); // Spieler zur Liste hinzufügen
DeckHelper deckHelper = new DeckHelper();
@ -1619,7 +1616,7 @@ public class ServerGameLogicTest {
ServerGameLogic logic = mock(ServerGameLogic.class); // Mock der ServerGameLogic
PlayerHandler handler = new PlayerHandler(logic); // Mock-Logik übergeben
Player player = new Player(1, handler);
player.setFigure(figure); // Spielfigur setzen
handler.addPlayer(player); // Spieler hinzufügen
DeckHelper deckHelper = new DeckHelper();
@ -1644,7 +1641,7 @@ public class ServerGameLogicTest {
ServerGameLogic logic = mock(ServerGameLogic.class); // Mock der ServerGameLogic
PlayerHandler handler = new PlayerHandler(logic); // Mock-Logik übergeben
Player player = new Player(1, handler);
player.setFigure(figure); // Spielfigur setzen
handler.addPlayer(player); // Spieler hinzufügen
DeckHelper deckHelper = new DeckHelper();
@ -1673,7 +1670,7 @@ public class ServerGameLogicTest {
PlayerHandler handler = new PlayerHandler(logic); // Mock-Logik übergeben
Player player = new Player(1, handler);
player.setFigure(figure); // Spielfigur setzen
handler.addPlayer(player); // Spieler 1 hinzufügen
@ -1698,7 +1695,7 @@ public class ServerGameLogicTest {
ServerGameLogic logic = mock(ServerGameLogic.class); // Mock der ServerGameLogic
PlayerHandler handler = new PlayerHandler(logic); // Mock-Logik übergeben
Player player = new Player(1, handler);
player.setFigure(figure); // Spielfigur setzen
player.setAccountBalance(1500); // Startsaldo setzen
handler.addPlayer(player); // Spieler hinzufügen
DeckHelper deckHelper = new DeckHelper();
@ -1725,7 +1722,7 @@ public class ServerGameLogicTest {
ServerGameLogic logic = mock(ServerGameLogic.class); // Mock der ServerGameLogic
PlayerHandler handler = new PlayerHandler(logic); // Mock-Logik übergeben
Player player = new Player(1, handler);
player.setFigure(figure); // Spielfigur setzen
player.setAccountBalance(1500); // Startsaldo setzen
handler.addPlayer(player); // Spieler hinzufügen
DeckHelper deckHelper = new DeckHelper();
@ -1753,7 +1750,7 @@ public class ServerGameLogicTest {
ServerGameLogic logic = mock(ServerGameLogic.class); // Mock der ServerGameLogic
PlayerHandler handler = new PlayerHandler(logic); // Mock-Logik übergeben
Player player = new Player(1, handler);
player.setFigure(figure); // Spielfigur setzen
handler.addPlayer(player); // Spieler hinzufügen
DeckHelper deckHelper = new DeckHelper();
@ -1780,7 +1777,7 @@ public class ServerGameLogicTest {
ServerGameLogic logic = mock(ServerGameLogic.class); // Mock der ServerGameLogic
PlayerHandler handler = new PlayerHandler(logic); // Mock-Logik übergeben
Player player = new Player(1, handler);
player.setFigure(figure); // Spielfigur setzen
handler.addPlayer(player); // Spieler hinzufügen
player.setAccountBalance(15000); // Anfangsstand des Kontos
DeckHelper deckHelper = new DeckHelper();
@ -1806,7 +1803,7 @@ public class ServerGameLogicTest {
ServerGameLogic logic = mock(ServerGameLogic.class); // Mock der ServerGameLogic
PlayerHandler handler = new PlayerHandler(logic); // Mock-Logik übergeben
Player player = new Player(1, handler);
player.setFigure(figure); // Spielfigur setzen
handler.addPlayer(player); // Spieler hinzufügen
player.setAccountBalance(15000); // Anfangsstand des Kontos
DeckHelper deckHelper = new DeckHelper();
@ -1833,7 +1830,7 @@ public class ServerGameLogicTest {
ServerGameLogic logic = mock(ServerGameLogic.class); // Mock der ServerGameLogic
PlayerHandler handler = new PlayerHandler(logic); // Mock-Logik übergeben
Player player = new Player(1, handler);
player.setFigure(figure); // Spielfigur setzen
handler.addPlayer(player); // Spieler hinzufügen
player.setAccountBalance(15000); // Anfangsstand des Kontos
DeckHelper deckHelper = new DeckHelper();
@ -1860,7 +1857,7 @@ public class ServerGameLogicTest {
ServerGameLogic logic = mock(ServerGameLogic.class); // Mock der ServerGameLogic
PlayerHandler handler = new PlayerHandler(logic); // Mock-Logik übergeben
Player player = new Player(1, handler);
player.setFigure(figure); // Spielfigur setzen
handler.addPlayer(player); // Spieler hinzufügen
player.setAccountBalance(15000); // Startguthaben des Spielers
DeckHelper deckHelper = new DeckHelper();