在学了一小段时间的UE4后,自己试着写了一个尽可能还原官方的俄罗斯方块
感觉还好吧,主要障碍都是游戏逻辑本身的,费了九牛二虎之力总算都克服了
这里分享下官方手册吧,能够解决很多游戏细节的问题(增加编程难度),感兴趣的小伙伴可以康康
在这里分享下核心代码吧,如果也有想写俄罗斯方块的小伙伴可以参考下
1 // Fill out your copyright notice in the Description page of Project Settings. 2 3 #pragma once 4 5 #include "CoreMinimal.h" 6 #include "GameFramework/Pawn.h" 7 #include <queue> 8 #include "Components/TextRenderComponent.h" 9 #include "SoundSoundWave.h" 10 #include "Table.generated.h" 11 12 UCLASS() 13 class TETRIS_API ATable : public APawn 14 { 15 GENERATED_BODY() 16 17 /** Dummy root component */ 18 UPROPERTY(Category = Block, VisibleDefaultsOnly, BlueprintReadOnly, meta = (AllowPrivateAccess = "true")) 19 class USceneComponent* DummyRoot; 20 21 public: 22 // Sets default values for this pawn's properties 23 ATable(); 24 25 protected: 26 // Called when the game starts or when spawned 27 virtual void BeginPlay() override; 28 29 public: 30 // Called every frame 31 virtual void Tick(float DeltaTime) override; 32 33 // Called to bind functionality to input 34 virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override; 35 36 class UMaterialInterface* Materials[10]; 37 38 bool bHaveTetrimino;//whether have one Tetrimino to controll? 39 int32 Blocks[12][42];//store the blocks on screen,x,y 40 int32 HoldBlocks[5][5];//store the blocks on Hold,x,y 41 int32 NextBlocks[5][13];//store the blocks on Next,x,y 42 int32 Next[4];//Blocks type on Next 43 int32 CurrentLevel; 44 int32 Bag[10],BagTop; 45 std::queue<int32>Queue; 46 float TimeBetweenFall;//time between each fall 47 float TimeBeforeLock;//time between land and lock 48 //time all in SECONDS!! 49 50 /* 51 reference as below: 52 0 empty 53 1 O 54 2 I 55 3 T 56 4 L 57 5 J 58 6 S 59 7 Z 60 */ 61 62 int32 PosX, PosY, face, type;//the position of the holding Tetrimino,and its face(0=North,1=East,2=South,3=West) 63 /* handle the blocks falling down,decide to keep falling or lock */ 64 void MoveDown(); 65 /* Lock them down! */ 66 void LockDown(); 67 void RLockDown(); 68 /* Draw Out everything! */ 69 void DrawOut(); 70 void AddOneInQueue(); 71 void DrawNext(); 72 void Ghost(); 73 int32 GX, GY, HoldingType, Lines, Score; 74 75 //7 types and 4 faces and 5 points and X or Y 76 /*ALL START WITH ZERO!*/ 77 int32 ClockRotation[7][4][5][2] = { 78 {//O 79 {//North 80 {//point 1 81 0,0 82 }, 83 {//point 2 84 0,0 85 }, 86 {//point 3 87 0,0 88 }, 89 {//point 4 90 0,0 91 }, 92 {//point 5 93 0,0 94 } 95 }, 96 {//East 97 {//point 1 98 0,0 99 }, 100 {//point 2 101 0,0 102 }, 103 {//point 3 104 0,0 105 }, 106 {//point 4 107 0,0 108 }, 109 {//point 5 110 0,0 111 } 112 }, 113 {//South 114 {//point 1 115 0,0 116 }, 117 {//point 2 118 0,0 119 }, 120 {//point 3 121 0,0 122 }, 123 {//point 4 124 0,0 125 }, 126 {//point 5 127 0,0 128 } 129 }, 130 {//Wast 131 {//point 1 132 0,0 133 }, 134 {//point 2 135 0,0 136 }, 137 {//point 3 138 0,0 139 }, 140 {//point 4 141 0,0 142 }, 143 {//point 5 144 0,0 145 } 146 } 147 }, 148 {//I 149 {//North 150 {//point 1 151 0,0 152 }, 153 {//point 2 154 -2,0 155 }, 156 {//point 3 157 +1,0 158 }, 159 {//point 4 160 -2,-1 161 }, 162 {//point 5 163 +1,+2 164 } 165 }, 166 {//East 167 {//point 1 168 0,0 169 }, 170 {//point 2 171 -1,0 172 }, 173 {//point 3 174 +2,0 175 }, 176 {//point 4 177 -1,+2 178 }, 179 {//point 5 180 +2,-1 181 } 182 }, 183 {//South 184 {//point 1 185 0,0 186 }, 187 {//point 2 188 +2,0 189 }, 190 {//point 3 191 -1,0 192 }, 193 {//point 4 194 +2,+1 195 }, 196 {//point 5 197 -1,-2 198 } 199 }, 200 {//Wast 201 {//point 1 202 0,0 203 }, 204 {//point 2 205 +1,0 206 }, 207 {//point 3 208 -2,0 209 }, 210 {//point 4 211 +2,-2 212 }, 213 {//point 5 214 -2,+1 215 } 216 } 217 }, 218 {//T 219 {//North 220 {//point 1 221 0,0 222 }, 223 {//point 2 224 -1,0 225 }, 226 {//point 3 227 -1,+1 228 }, 229 {//point 4 230 -1,-2 231 }, 232 {//point 5 233 -1,-2 234 } 235 }, 236 {//East 237 {//point 1 238 0,0 239 }, 240 {//point 2 241 +1,0 242 }, 243 {//point 3 244 +1,-1 245 }, 246 {//point 4 247 0,+2 248 }, 249 {//point 5 250 +1,+2 251 } 252 }, 253 {//South 254 {//point 1 255 0,0 256 }, 257 {//point 2 258 +1,0 259 }, 260 {//point 3 261 0,-2 262 }, 263 {//point 4 264 0,-2 265 }, 266 {//point 5 267 +1,-2 268 } 269 }, 270 {//Wast 271 {//point 1 272 0,0 273 }, 274 {//point 2 275 -1,0 276 }, 277 {//point 3 278 -1,-1 279 }, 280 {//point 4 281 0,+2 282 }, 283 {//point 5 284 -1,+2 285 } 286 } 287 }, 288 {//L 289 {//North 290 {//point 1 291 0,0 292 }, 293 {//point 2 294 -1,0 295 }, 296 {//point 3 297 -1,+1 298 }, 299 {//point 4 300 0,-2 301 }, 302 {//point 5 303 -1,-2 304 } 305 }, 306 {//East 307 {//point 1 308 0,0 309 }, 310 {//point 2 311 +1,0 312 }, 313 {//point 3 314 +1,-1 315 }, 316 {//point 4 317 0,+2 318 }, 319 {//point 5 320 +1,+2 321 } 322 }, 323 {//South 324 {//point 1 325 0,0 326 }, 327 {//point 2 328 +1,0 329 }, 330 {//point 3 331 +1,+1 332 }, 333 {//point 4 334 0,-2 335 }, 336 {//point 5 337 +1,-2 338 } 339 }, 340 {//Wast 341 {//point 1 342 0,0 343 }, 344 {//point 2 345 -1,0 346 }, 347 {//point 3 348 -1,-1 349 }, 350 {//point 4 351 0,+2 352 }, 353 {//point 5 354 -1,+2 355 } 356 } 357 }, 358 {//J 359 {//North 360 {//point 1 361 0,0 362 }, 363 {//point 2 364 -1,0 365 }, 366 {//point 3 367 -1,+1 368 }, 369 {//point 4 370 0,-2 371 }, 372 {//point 5 373 -1,-2 374 } 375 }, 376 {//East 377 {//point 1 378 0,0 379 }, 380 {//point 2 381 +1,0 382 }, 383 {//point 3 384 +1,-1 385 }, 386 {//point 4 387 0,+2 388 }, 389 {//point 5 390 +1,+2 391 } 392 }, 393 {//South 394 {//point 1 395 0,0 396 }, 397 {//point 2 398 +1,0 399 }, 400 {//point 3 401 +1,+1 402 }, 403 {//point 4 404 0,-2 405 }, 406 {//point 5 407 +1,-2 408 } 409 }, 410 {//Wast 411 {//point 1 412 0,0 413 }, 414 {//point 2 415 -1,0 416 }, 417 {//point 3 418 -1,-1 419 }, 420 {//point 4 421 0,+2 422 }, 423 {//point 5 424 -1,+2 425 } 426 } 427 }, 428 {//S 429 {//North 430 {//point 1 431 0,0 432 }, 433 {//point 2 434 -1,0 435 }, 436 {//point 3 437 -1,+1 438 }, 439 {//point 4 440 0,-2 441 }, 442 {//point 5 443 -1,-2 444 } 445 }, 446 {//East 447 {//point 1 448 0,0 449 }, 450 {//point 2 451 +1,0 452 }, 453 {//point 3 454 +1,-2 455 }, 456 {//point 4 457 0,+2 458 }, 459 {//point 5 460 +1,+2 461 } 462 }, 463 {//South 464 {//point 1 465 0,0 466 }, 467 {//point 2 468 +1,0 469 }, 470 {//point 3 471 +1,+1 472 }, 473 {//point 4 474 0,-2 475 }, 476 {//point 5 477 +1,-2 478 } 479 }, 480 {//Wast 481 {//point 1 482 0,0 483 }, 484 {//point 2 485 -1,0 486 }, 487 {//point 3 488 -1,-1 489 }, 490 {//point 4 491 0,+2 492 }, 493 {//point 5 494 -1,+2 495 } 496 } 497 }, 498 {//Z 499 {//North 500 {//point 1 501 0,0 502 }, 503 {//point 2 504 -1,0 505 }, 506 {//point 3 507 -1,+1 508 }, 509 {//point 4 510 0,-2 511 }, 512 {//point 5 513 -1,-2 514 } 515 }, 516 {//East 517 {//point 1 518 0,0 519 }, 520 {//point 2 521 +1,0 522 }, 523 {//point 3 524 +1,-1 525 }, 526 {//point 4 527 0,+2 528 }, 529 {//point 5 530 +1,+2 531 } 532 }, 533 {//South 534 {//point 1 535 0,0 536 }, 537 {//point 2 538 +1,0 539 }, 540 {//point 3 541 +1,+1 542 }, 543 {//point 4 544 0,-2 545 }, 546 {//point 5 547 +1,-2 548 } 549 }, 550 {//Wast 551 {//point 1 552 0,0 553 }, 554 {//point 2 555 -1,0 556 }, 557 {//point 3 558 -1,-1 559 }, 560 {//point 4 561 0,+2 562 }, 563 {//point 5 564 -1,+2 565 } 566 } 567 } 568 }; 569 int32 CounterClockRotation[7][4][5][2] = { 570 {//O 571 {//North 572 {//point 1 573 0,0 574 }, 575 {//point 2 576 0,0 577 }, 578 {//point 3 579 0,0 580 }, 581 {//point 4 582 0,0 583 }, 584 {//point 5 585 0,0 586 } 587 }, 588 {//East 589 {//point 1 590 0,0 591 }, 592 {//point 2 593 0,0 594 }, 595 {//point 3 596 0,0 597 }, 598 {//point 4 599 0,0 600 }, 601 {//point 5 602 0,0 603 } 604 }, 605 {//South 606 {//point 1 607 0,0 608 }, 609 {//point 2 610 0,0 611 }, 612 {//point 3 613 0,0 614 }, 615 {//point 4 616 0,0 617 }, 618 {//point 5 619 0,0 620 } 621 }, 622 {//Wast 623 {//point 1 624 0,0 625 }, 626 {//point 2 627 0,0 628 }, 629 {//point 3 630 0,0 631 }, 632 {//point 4 633 0,0 634 }, 635 {//point 5 636 0,0 637 } 638 } 639 }, 640 {//I 641 {//North 642 {//point 1 643 0,0 644 }, 645 {//point 2 646 -1,0 647 }, 648 {//point 3 649 +2,0 650 }, 651 {//point 4 652 -1,+2 653 }, 654 {//point 5 655 +2,-1 656 } 657 }, 658 {//East 659 {//point 1 660 0,0 661 }, 662 {//point 2 663 +2,0 664 }, 665 {//point 3 666 -1,0 667 }, 668 {//point 4 669 +2,+1 670 }, 671 {//point 5 672 -1,-2 673 } 674 }, 675 {//South 676 {//point 1 677 0,0 678 }, 679 {//point 2 680 +1,0 681 }, 682 {//point 3 683 -2,0 684 }, 685 {//point 4 686 +1,-2 687 }, 688 {//point 5 689 -2,+1 690 } 691 }, 692 {//Wast 693 {//point 1 694 0,0 695 }, 696 {//point 2 697 -2,0 698 }, 699 {//point 3 700 +1,0 701 }, 702 {//point 4 703 -2,-1 704 }, 705 {//point 5 706 +1,+2 707 } 708 } 709 }, 710 {//T 711 {//North 712 {//point 1 713 0,0 714 }, 715 {//point 2 716 +1,0 717 }, 718 {//point 3 719 +1,+1 720 }, 721 {//point 4 722 +1,-2 723 }, 724 {//point 5 725 +1,-2 726 } 727 }, 728 {//East 729 {//point 1 730 0,0 731 }, 732 {//point 2 733 +1,0 734 }, 735 {//point 3 736 +1,-1 737 }, 738 {//point 4 739 0,+2 740 }, 741 {//point 5 742 +1,+2 743 } 744 }, 745 {//South 746 {//point 1 747 0,0 748 }, 749 {//point 2 750 -1,0 751 }, 752 {//point 3 753 0,-2 754 }, 755 {//point 4 756 0,-2 757 }, 758 {//point 5 759 -1,-2 760 } 761 }, 762 {//Wast 763 {//point 1 764 0,0 765 }, 766 {//point 2 767 -1,0 768 }, 769 {//point 3 770 -1,-1 771 }, 772 {//point 4 773 0,+2 774 }, 775 {//point 5 776 -1,+2 777 } 778 } 779 }, 780 {//L 781 {//North 782 {//point 1 783 0,0 784 }, 785 {//point 2 786 +1,0 787 }, 788 {//point 3 789 +1,+1 790 }, 791 {//point 4 792 0,-2 793 }, 794 {//point 5 795 +1,-2 796 } 797 }, 798 {//East 799 {//point 1 800 0,0 801 }, 802 {//point 2 803 +1,0 804 }, 805 {//point 3 806 +1,-1 807 }, 808 {//point 4 809 0,+2 810 }, 811 {//point 5 812 +1,+2 813 } 814 }, 815 {//South 816 {//point 1 817 0,0 818 }, 819 {//point 2 820 -1,0 821 }, 822 {//point 3 823 -1,+1 824 }, 825 {//point 4 826 0,-2 827 }, 828 {//point 5 829 -1,-2 830 } 831 }, 832 {//Wast 833 {//point 1 834 0,0 835 }, 836 {//point 2 837 -1,0 838 }, 839 {//point 3 840 -1,-1 841 }, 842 {//point 4 843 0,+2 844 }, 845 {//point 5 846 -1,+2 847 } 848 } 849 }, 850 {//J 851 {//North 852 {//point 1 853 0,0 854 }, 855 {//point 2 856 +1,0 857 }, 858 {//point 3 859 +1,+1 860 }, 861 {//point 4 862 0,-2 863 }, 864 {//point 5 865 +1,-2 866 } 867 }, 868 {//East 869 {//point 1 870 0,0 871 }, 872 {//point 2 873 +1,0 874 }, 875 {//point 3 876 +1,-1 877 }, 878 {//point 4 879 0,+2 880 }, 881 {//point 5 882 +1,+2 883 } 884 }, 885 {//South 886 {//point 1 887 0,0 888 }, 889 {//point 2 890 -1,0 891 }, 892 {//point 3 893 -1,+1 894 }, 895 {//point 4 896 0,-2 897 }, 898 {//point 5 899 -1,-2 900 } 901 }, 902 {//Wast 903 {//point 1 904 0,0 905 }, 906 {//point 2 907 -1,0 908 }, 909 {//point 3 910 -1,-1 911 }, 912 {//point 4 913 0,+2 914 }, 915 {//point 5 916 -1,+2 917 } 918 } 919 }, 920 {//S 921 {//North 922 {//point 1 923 0,0 924 }, 925 {//point 2 926 +1,0 927 }, 928 {//point 3 929 +1,+1 930 }, 931 {//point 4 932 0,-2 933 }, 934 {//point 5 935 +1,-2 936 } 937 }, 938 {//East 939 {//point 1 940 0,0 941 }, 942 {//point 2 943 +1,0 944 }, 945 {//point 3 946 +1,-1 947 }, 948 {//point 4 949 0,+2 950 }, 951 {//point 5 952 +1,+2 953 } 954 }, 955 {//South 956 {//point 1 957 0,0 958 }, 959 {//point 2 960 -1,0 961 }, 962 {//point 3 963 -1,+1 964 }, 965 {//point 4 966 0,-2 967 }, 968 {//point 5 969 -1,-2 970 } 971 }, 972 {//Wast 973 {//point 1 974 0,0 975 }, 976 {//point 2 977 -1,0 978 }, 979 {//point 3 980 -1,-1 981 }, 982 {//point 4 983 0,+2 984 }, 985 {//point 5 986 -1,+2 987 } 988 } 989 }, 990 {//Z 991 {//North 992 {//point 1 993 0,0 994 }, 995 {//point 2 996 +1,0 997 }, 998 {//point 3 999 +1,+1 1000 }, 1001 {//point 4 1002 0,-2 1003 }, 1004 {//point 5 1005 +1,-2 1006 } 1007 }, 1008 {//East 1009 {//point 1 1010 0,0 1011 }, 1012 {//point 2 1013 +1,0 1014 }, 1015 {//point 3 1016 +1,-1 1017 }, 1018 {//point 4 1019 0,+2 1020 }, 1021 {//point 5 1022 +1,+2 1023 } 1024 }, 1025 {//South 1026 {//point 1 1027 0,0 1028 }, 1029 {//point 2 1030 -1,0 1031 }, 1032 {//point 3 1033 -1,+1 1034 }, 1035 {//point 4 1036 0,-2 1037 }, 1038 {//point 5 1039 -1,-2 1040 } 1041 }, 1042 {//Wast 1043 {//point 1 1044 0,0 1045 }, 1046 {//point 2 1047 -1,0 1048 }, 1049 {//point 3 1050 -1,-1 1051 }, 1052 {//point 4 1053 0,+2 1054 }, 1055 {//point 5 1056 -1,+2 1057 } 1058 } 1059 } 1060 }; 1061 1062 /*Pattern*/ 1063 bool IsLineDone(int32 Y); 1064 bool IsTSlot(int32 X, int32 Y); 1065 std::queue<int32>DoneQueue; 1066 void Animate(); 1067 void AnimateDone(); 1068 void AddScoreLines(int32 addScore, int32 addLines); 1069 1070 /*Phases!*/ 1071 void Generation(); 1072 1073 void GameOver(); 1074 1075 UStaticMeshComponent* BlockBody[12][42]; 1076 UStaticMeshComponent* HoldBlockBody[5][5]; 1077 UStaticMeshComponent* NextBlockBody[5][13]; 1078 1079 //UPROPERTY() 1080 class UTextRenderComponent* ScoreText; 1081 class UTextRenderComponent* HoldText; 1082 class UTextRenderComponent* NextText; 1083 class UTextRenderComponent* ScoreNum; 1084 class UTextRenderComponent* LevelText; 1085 class UTextRenderComponent* LevelNum; 1086 class UTextRenderComponent* LinesText; 1087 class UTextRenderComponent* LinesNum; 1088 class UTextRenderComponent* PauseText; 1089 1090 /* to check whether this place is empty, XY for position,fa for face, type for block type */ 1091 bool Check(int32 X, int32 Y, int32 fa, int32 ty); 1092 1093 void PutBlock(int32 X, int32 Y, int32 fa, int32 ty, int32 goal); 1094 void PutHoldBlock(int32 X, int32 Y, int32 fa, int32 ty, int32 goal); 1095 void PutNextBlock(int32 X, int32 Y, int32 fa, int32 ty, int32 goal); 1096 1097 UFUNCTION() 1098 void MoveRight(); 1099 UFUNCTION() 1100 void MoveRightReleased(); 1101 UFUNCTION() 1102 void MoveLeft(); 1103 UFUNCTION() 1104 void MoveLeftReleased(); 1105 UFUNCTION() 1106 void HardDrop(); 1107 UFUNCTION() 1108 void SoftDrop(); 1109 UFUNCTION() 1110 void SoftDropReleased(); 1111 UFUNCTION() 1112 void RotateClockwise(); 1113 UFUNCTION() 1114 void RotateCounterClockwise(); 1115 UFUNCTION() 1116 void Hold(); 1117 UFUNCTION() 1118 void Pause(); 1119 1120 bool Holding; 1121 1122 USoundWave* SoundWaveClear; 1123 USoundWave* SoundWaveDrop; 1124 USoundWave* SoundWaveGameOver; 1125 USoundWave* SoundWaveHold; 1126 USoundWave* SoundWaveLevel; 1127 USoundWave* SoundWaveLock; 1128 USoundWave* SoundWaveMove; 1129 USoundWave* SoundWaveMoveFail; 1130 USoundWave* SoundWaveTetris; 1131 USoundWave* SoundWaveBGM; 1132 1133 private: 1134 //TimerHandle for multiple function since only one type of counting will carry out 1135 FTimerHandle TimeTick; 1136 /* Timer for Auto-Repeat */ 1137 FTimerHandle AutoTick; 1138 /* Timer for Animate */ 1139 FTimerHandle AnimateTick; 1140 /* State for Auto-Repeat */ 1141 bool bIsAutoRepeating; 1142 bool bIsAutoDelay; 1143 bool bIsRightPressed; 1144 bool bIsLeftPressed; 1145 bool bIsSoftDrop; 1146 bool bGameOver; 1147 bool bPause; 1148 };
1 // Fill out your copyright notice in the Description page of Project Settings. 2 3 4 #include "Table.h" 5 #include "GenericPlatform/GenericPlatformMath.h" 6 #include "UObject/ConstructorHelpers.h" 7 #include "Engine/StaticMesh.h" 8 #include "Materials/MaterialInstance.h" 9 #include <algorithm> 10 #include "Kismet/GameplayStatics.h" 11 #include "Components/StaticMeshComponent.h" 12 13 #define LOCTEXT_NAMESPACE "TetrisTable" 14 15 // Sets default values 16 ATable::ATable() 17 { 18 // Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it. 19 PrimaryActorTick.bCanEverTick = false; 20 21 CurrentLevel = 1; 22 TimeBetweenFall = FGenericPlatformMath::Pow((0.8 - ((CurrentLevel - 1) * 0.007)), (CurrentLevel - 1)); 23 TimeBeforeLock = 0.5; 24 25 //UE_LOG(LogTemp, Warning, TEXT("HERE!!!!!: %f"), TimeBetweenFall); 26 static ConstructorHelpers::FObjectFinder<UMaterial>Mat1(TEXT("Material'/Game/Materials/M_1.M_1'")); 27 static ConstructorHelpers::FObjectFinder<UMaterial>Mat2(TEXT("Material'/Game/Materials/M_2.M_2'")); 28 static ConstructorHelpers::FObjectFinder<UMaterial>Mat3(TEXT("Material'/Game/Materials/M_3.M_3'")); 29 static ConstructorHelpers::FObjectFinder<UMaterial>Mat4(TEXT("Material'/Game/Materials/M_4.M_4'")); 30 static ConstructorHelpers::FObjectFinder<UMaterial>Mat5(TEXT("Material'/Game/Materials/M_5.M_5'")); 31 static ConstructorHelpers::FObjectFinder<UMaterial>Mat6(TEXT("Material'/Game/Materials/M_6.M_6'")); 32 static ConstructorHelpers::FObjectFinder<UMaterial>Mat7(TEXT("Material'/Game/Materials/M_7.M_7'")); 33 static ConstructorHelpers::FObjectFinder<UMaterial>Mat8(TEXT("Material'/Game/Materials/M_Glass.M_Glass'"));//Mat for Ghost 34 static ConstructorHelpers::FObjectFinder<UMaterial>Mat9(TEXT("Material'/Game/Materials/M_9.M_9'")); 35 36 37 Materials[1] = Cast<UMaterialInterface>(Mat1.Object); 38 Materials[2] = Cast<UMaterialInterface>(Mat2.Object); 39 Materials[3] = Cast<UMaterialInterface>(Mat3.Object); 40 Materials[4] = Cast<UMaterialInterface>(Mat4.Object); 41 Materials[5] = Cast<UMaterialInterface>(Mat5.Object); 42 Materials[6] = Cast<UMaterialInterface>(Mat6.Object); 43 Materials[7] = Cast<UMaterialInterface>(Mat7.Object); 44 Materials[8] = Cast<UMaterialInterface>(Mat8.Object);//GhostMaterial 45 Materials[9] = Cast<UMaterialInterface>(Mat9.Object); 46 47 // Create dummy root scene component 48 DummyRoot = CreateDefaultSubobject<USceneComponent>(TEXT("Dummy0")); 49 RootComponent = DummyRoot; 50 51 static ConstructorHelpers::FObjectFinder<UStaticMesh>CubeObj(TEXT("StaticMesh'/Engine/VREditor/BasicMeshes/SM_Cube_01.SM_Cube_01'")); 52 for (int32 i = 0; i <= 11; i++) 53 for (int32 j = 0; j <= 21; j++) { 54 FString BlockName; 55 BlockName = TEXT("block") + FString::FromInt(j + i * 22 + 1); 56 BlockBody[i][j] = CreateDefaultSubobject<UStaticMeshComponent>(FName(*BlockName)); 57 BlockBody[i][j]->SetStaticMesh(CubeObj.Object); 58 BlockBody[i][j]->SetupAttachment(DummyRoot); 59 BlockBody[i][j]->SetRelativeLocation(FVector(0, 50 * i, 50 * j)); 60 } 61 62 int32 blabla = 9999; 63 for (int32 i = 1; i <= 4; i++) 64 for (int32 j = 1; j <= 4; j++) { 65 FString BlockName; 66 BlockName = TEXT("block") + FString::FromInt(blabla++); 67 HoldBlockBody[i][j] = CreateDefaultSubobject<UStaticMeshComponent>(FName(*BlockName)); 68 HoldBlockBody[i][j]->SetStaticMesh(CubeObj.Object); 69 HoldBlockBody[i][j]->SetupAttachment(DummyRoot); 70 HoldBlockBody[i][j]->SetRelativeLocation(FVector(0, -300 + 50 * (i - 1), 700 + 50 * (j - 1))); 71 HoldBlockBody[i][j]->SetVisibility(false); 72 } 73 for (int32 i = 1; i <= 4; i++) 74 for (int32 j = 1; j <= 12; j++) { 75 FString BlockName; 76 BlockName = TEXT("block") + FString::FromInt(blabla++); 77 NextBlockBody[i][j] = CreateDefaultSubobject<UStaticMeshComponent>(FName(*BlockName)); 78 NextBlockBody[i][j]->SetStaticMesh(CubeObj.Object); 79 NextBlockBody[i][j]->SetupAttachment(DummyRoot); 80 NextBlockBody[i][j]->SetRelativeLocation(FVector(0, 700 + 50 * (i - 1), 350 + 50 * (j - 1))); 81 NextBlockBody[i][j]->SetVisibility(false); 82 } 83 84 // Create static mesh component 85 ScoreText = CreateDefaultSubobject<UTextRenderComponent>(TEXT("ScoreText0")); 86 ScoreText->SetRelativeLocation(FVector(0, -400, 520)); 87 ScoreText->SetRelativeRotation(FRotator(180, 0, 180)); 88 ScoreText->SetText(FText::Format(LOCTEXT("ScoreFmt", "SCORE"), FText::AsNumber(0))); 89 ScoreText->SetupAttachment(DummyRoot); 90 ScoreText->SetWorldSize(120); 91 ScoreNum = CreateDefaultSubobject<UTextRenderComponent>(TEXT("ScoreNum0")); 92 ScoreNum->SetRelativeLocation(FVector(0, -400, 420)); 93 ScoreNum->SetRelativeRotation(FRotator(180, 0, 180)); 94 ScoreNum->SetText(FText::Format(LOCTEXT("ScoreNumFmt", "{0}"), FText::AsNumber(Score))); 95 ScoreNum->SetupAttachment(DummyRoot); 96 ScoreNum->SetWorldSize(120); 97 HoldText = CreateDefaultSubobject<UTextRenderComponent>(TEXT("HoldText0")); 98 HoldText->SetRelativeLocation(FVector(0, -350, 870)); 99 HoldText->SetRelativeRotation(FRotator(180, 0, 180)); 100 HoldText->SetText(FText::Format(LOCTEXT("HoldFmt", "HOLD"), FText::AsNumber(0))); 101 HoldText->SetupAttachment(DummyRoot); 102 HoldText->SetWorldSize(120); 103 NextText = CreateDefaultSubobject<UTextRenderComponent>(TEXT("NextText0")); 104 NextText->SetRelativeLocation(FVector(0, 650, 920)); 105 NextText->SetRelativeRotation(FRotator(180, 0, 180)); 106 NextText->SetText(FText::Format(LOCTEXT("NextFmt", "NEXT"), FText::AsNumber(0))); 107 NextText->SetupAttachment(DummyRoot); 108 NextText->SetWorldSize(120); 109 LevelText = CreateDefaultSubobject<UTextRenderComponent>(TEXT("LevelText0")); 110 LevelText->SetRelativeLocation(FVector(0, -400, 320)); 111 LevelText->SetRelativeRotation(FRotator(180, 0, 180)); 112 LevelText->SetText(FText::Format(LOCTEXT("LevelFmt", "LEVEL"), FText::AsNumber(0))); 113 LevelText->SetupAttachment(DummyRoot); 114 LevelText->SetWorldSize(120); 115 LevelNum = CreateDefaultSubobject<UTextRenderComponent>(TEXT("LevelNum0")); 116 LevelNum->SetRelativeLocation(FVector(0, -400, 220)); 117 LevelNum->SetRelativeRotation(FRotator(180, 0, 180)); 118 LevelNum->SetText(FText::Format(LOCTEXT("LevelNumFmt", "{0}"), FText::AsNumber(CurrentLevel))); 119 LevelNum->SetupAttachment(DummyRoot); 120 LevelNum->SetWorldSize(120); 121 LinesText = CreateDefaultSubobject<UTextRenderComponent>(TEXT("LinesText0")); 122 LinesText->SetRelativeLocation(FVector(0, -400, 120)); 123 LinesText->SetRelativeRotation(FRotator(180, 0, 180)); 124 LinesText->SetText(FText::Format(LOCTEXT("LinesFmt", "LINES"), FText::AsNumber(0))); 125 LinesText->SetupAttachment(DummyRoot); 126 LinesText->SetWorldSize(120); 127 LinesNum = CreateDefaultSubobject<UTextRenderComponent>(TEXT("LinesNum0")); 128 LinesNum->SetRelativeLocation(FVector(0, -400, 20)); 129 LinesNum->SetRelativeRotation(FRotator(180, 0, 180)); 130 LinesNum->SetText(FText::Format(LOCTEXT("LinesNumFmt", "{0}"), FText::AsNumber(0))); 131 LinesNum->SetupAttachment(DummyRoot); 132 LinesNum->SetWorldSize(120); 133 PauseText = CreateDefaultSubobject<UTextRenderComponent>(TEXT("PauseText0")); 134 PauseText->SetRelativeLocation(FVector(-100, 125, 500)); 135 PauseText->SetRelativeRotation(FRotator(180, 0, 180)); 136 PauseText->SetText(FText::Format(LOCTEXT("PauseText", ""), FText::AsNumber(0))); 137 PauseText->SetupAttachment(DummyRoot); 138 PauseText->SetWorldSize(120); 139 140 static ConstructorHelpers::FObjectFinder<USoundWave> SW1(TEXT("SoundWave'/Game/Sounds/Clear.Clear'")); 141 SoundWaveClear = SW1.Object; 142 static ConstructorHelpers::FObjectFinder<USoundWave> SW2(TEXT("SoundWave'/Game/Sounds/Drop.Drop'")); 143 SoundWaveDrop = SW2.Object; 144 static ConstructorHelpers::FObjectFinder<USoundWave> SW3(TEXT("SoundWave'/Game/Sounds/GameOver.GameOver'")); 145 SoundWaveGameOver = SW3.Object; 146 static ConstructorHelpers::FObjectFinder<USoundWave> SW4(TEXT("SoundWave'/Game/Sounds/Hold.Hold'")); 147 SoundWaveHold = SW4.Object; 148 static ConstructorHelpers::FObjectFinder<USoundWave> SW5(TEXT("SoundWave'/Game/Sounds/Level.Level'")); 149 SoundWaveLevel = SW5.Object; 150 static ConstructorHelpers::FObjectFinder<USoundWave> SW6(TEXT("SoundWave'/Game/Sounds/Lock.Lock'")); 151 SoundWaveLock = SW6.Object; 152 static ConstructorHelpers::FObjectFinder<USoundWave> SW7(TEXT("SoundWave'/Game/Sounds/Move.Move'")); 153 SoundWaveMove = SW7.Object; 154 static ConstructorHelpers::FObjectFinder<USoundWave> SW8(TEXT("SoundWave'/Game/Sounds/MoveFail.MoveFail'")); 155 SoundWaveMoveFail = SW8.Object; 156 static ConstructorHelpers::FObjectFinder<USoundWave> SW9(TEXT("SoundWave'/Game/Sounds/Tetris.Tetris'")); 157 SoundWaveTetris = SW9.Object; 158 static ConstructorHelpers::FObjectFinder<USoundWave> SW10(TEXT("SoundWave'/Game/Sounds/BGM.BGM'")); 159 SoundWaveBGM = SW10.Object; 160 } 161 162 // Called when the game starts or when spawned 163 void ATable::BeginPlay() 164 { 165 Super::BeginPlay(); 166 SoundWaveBGM->bLooping = true; 167 UGameplayStatics::PlaySound2D(GetWorld(), SoundWaveBGM, 0.3f); 168 BagTop = 8; 169 DrawOut(); 170 Score = 0; 171 for (int i = 1; i <= 3; i++) AddOneInQueue(); 172 for (int i = 0; i <= 11; i++) Blocks[i][0] = 1; 173 for (int j = 0; j <= 21; j++) Blocks[0][j] = Blocks[11][j] = 1; 174 /* T3 test 175 for (int i = 1; i <= 10; i++) 176 for (int j = 1; j <= 5; j++) 177 Blocks[i][j] = 1; 178 for (int i = 5; i <= 10; i++) 179 for (int j = 4; j <= 5; j++)Blocks[i][j] = 0; 180 for (int j = 1; j <= 4; j++)Blocks[4][j] = 0; 181 Blocks[5][2] = 0; 182 */ 183 Generation(); 184 } 185 186 // Called every frame 187 void ATable::Tick(float DeltaTime) 188 { 189 Super::Tick(DeltaTime); 190 191 } 192 193 // Called to bind functionality to input 194 void ATable::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) 195 { 196 Super::SetupPlayerInputComponent(PlayerInputComponent); 197 198 // 设置"动作"绑定。 199 PlayerInputComponent->BindAction("Hold", IE_Pressed, this, &ATable::Hold); 200 PlayerInputComponent->BindAction("MoveRight", IE_Pressed, this, &ATable::MoveRight); 201 PlayerInputComponent->BindAction("MoveRight", IE_Released, this, &ATable::MoveRightReleased); 202 PlayerInputComponent->BindAction("MoveLeft", IE_Pressed, this, &ATable::MoveLeft); 203 PlayerInputComponent->BindAction("MoveLeft", IE_Released, this, &ATable::MoveLeftReleased); 204 PlayerInputComponent->BindAction("HardDrop", IE_Pressed, this, &ATable::HardDrop); 205 PlayerInputComponent->BindAction("SoftDrop", IE_Pressed, this, &ATable::SoftDrop); 206 PlayerInputComponent->BindAction("SoftDrop", IE_Released, this, &ATable::SoftDropReleased); 207 PlayerInputComponent->BindAction("RotateClockwise", IE_Pressed, this, &ATable::RotateClockwise); 208 PlayerInputComponent->BindAction("RotateCounterClockwise", IE_Pressed, this, &ATable::RotateCounterClockwise); 209 PlayerInputComponent->BindAction("Pause", IE_Pressed, this, &ATable::Pause); 210 } 211 212 void ATable::MoveDown() 213 { 214 //UE_LOG(LogTemp, Warning, TEXT("Move Down!!")); 215 if (Check(PosX, PosY - 1, face, type)) { 216 //UE_LOG(LogTemp, Warning, TEXT("Moving!!!")); 217 PosY--; 218 if (bIsSoftDrop) AddScoreLines(1, 0); 219 DrawOut(); 220 //move down complete 221 } 222 if (!Check(PosX, PosY - 1, face, type)) { 223 GetWorldTimerManager().SetTimer(TimeTick, this, &ATable::LockDown, TimeBeforeLock, false); 224 //UE_LOG(LogTemp, Warning, TEXT("Ready To Lock!")); 225 } 226 } 227 228 void ATable::LockDown() 229 { 230 if (Check(PosX, PosY - 1, face, type)) { 231 //back to falling 232 GetWorldTimerManager().SetTimer(TimeTick, this, &ATable::MoveDown, TimeBetweenFall, true); 233 //UE_LOG(LogTemp, Warning, TEXT("Back to fall!")); 234 return; 235 } 236 237 PutBlock(PosX, PosY, face, type, type); 238 UGameplayStatics::PlaySound2D(GetWorld(), SoundWaveLock, 0.3f); 239 PosX = PosY = face = type = -1; 240 /*check for lockout*/ 241 if (PosY >= 21) { 242 //UE_LOG(LogTemp, Warning, TEXT("LOCKOUT!!")); 243 GameOver(); 244 return; 245 } 246 /*check for lockout*/ 247 248 /*check pattern*/ 249 250 for (int i = 20; i >= 1; i--) 251 if (IsLineDone(i)) DoneQueue.push(i); 252 Animate(); 253 254 //set timer for generation 255 GetWorldTimerManager().SetTimer(TimeTick, this, &ATable::Generation, 0.1f, false); 256 } 257 258 void ATable::RLockDown() 259 { 260 //UE_LOG(LogTemp, Warning, TEXT("HEY!")); 261 262 if (Check(PosX, PosY - 1, face, type)) { 263 //back to falling 264 GetWorldTimerManager().SetTimer(TimeTick, this, &ATable::MoveDown, TimeBetweenFall, true); 265 //UE_LOG(LogTemp, Warning, TEXT("Back to fall!")); 266 return; 267 } 268 269 PutBlock(PosX, PosY, face, type, type); 270 UGameplayStatics::PlaySound2D(GetWorld(), SoundWaveLock, 0.3f); 271 /*check for lockout*/ 272 if (PosY >= 21) { 273 //UE_LOG(LogTemp, Warning, TEXT("LOCKOUT!!")); 274 GameOver(); 275 return; 276 } 277 /*check for lockout*/ 278 279 /*check pattern*/ 280 //UE_LOG(LogTemp, Warning, TEXT("%d!"), type); 281 //UE_LOG(LogTemp, Warning, TEXT("%d?!"), IsTSlot(PosX, PosY)); 282 for (int i = 20; i >= 1; i--) 283 if (IsLineDone(i)) DoneQueue.push(i); 284 if (type == 3 && IsTSlot(PosX, PosY)) { 285 UE_LOG(LogTemp, Warning, TEXT("HO!")); 286 int As = 0, Cs = 0; 287 switch (face) 288 { 289 case 0: 290 if (Blocks[PosX + 1][PosY + 1])As++; 291 if (Blocks[PosX - 1][PosY + 1])As++; 292 if (Blocks[PosX + 1][PosY - 1])Cs++; 293 if (Blocks[PosX - 1][PosY - 1])Cs++; 294 break; 295 case 1: 296 if (Blocks[PosX + 1][PosY + 1])As++; 297 if (Blocks[PosX + 1][PosY - 1])As++; 298 if (Blocks[PosX - 1][PosY + 1])Cs++; 299 if (Blocks[PosX - 1][PosY - 1])Cs++; 300 break; 301 case 2: 302 if (Blocks[PosX + 1][PosY - 1])As++; 303 if (Blocks[PosX - 1][PosY - 1])As++; 304 if (Blocks[PosX + 1][PosY + 1])Cs++; 305 if (Blocks[PosX - 1][PosY + 1])Cs++; 306 break; 307 case 3: 308 if (Blocks[PosX - 1][PosY + 1])As++; 309 if (Blocks[PosX - 1][PosY - 1])As++; 310 if (Blocks[PosX + 1][PosY + 1])Cs++; 311 if (Blocks[PosX + 1][PosY - 1])Cs++; 312 break; 313 default: 314 break; 315 } 316 if (As == 2 && Cs >= 1) { 317 //GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Yellow, FString::Printf(TEXT("T-Spin!"))); 318 if (DoneQueue.size() == 1) { 319 GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Purple, FString::Printf(TEXT("T-Spin Single!"))); 320 AddScoreLines(700 * CurrentLevel, 0); 321 } 322 else if(DoneQueue.size() == 2){ 323 GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Purple, FString::Printf(TEXT("T-Spin Double!!"))); 324 AddScoreLines(900 * CurrentLevel, 0); 325 } 326 else if(DoneQueue.size() == 3){ 327 GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Purple, FString::Printf(TEXT("T-Spin Triple!!!"))); 328 AddScoreLines(1100 * CurrentLevel, 0); 329 } 330 else { 331 GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Purple, FString::Printf(TEXT("T-Spin!"))); 332 AddScoreLines(400 * CurrentLevel, 0); 333 } 334 } 335 else if (As >= 1 && Cs == 2) { 336 if (DoneQueue.size() == 1) { 337 GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Purple, FString::Printf(TEXT("Mini T-Spin Single!"))); 338 AddScoreLines(100 * CurrentLevel, 0); 339 } 340 else { 341 GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Purple, FString::Printf(TEXT("Mini T-Spin!"))); 342 AddScoreLines(100 * CurrentLevel, 0); 343 } 344 } 345 } 346 PosX = PosY = face = type = -1; 347 Animate(); 348 349 //set timer for generation 350 GetWorldTimerManager().SetTimer(TimeTick, this, &ATable::Generation, 0.1f, false); 351 } 352 353 void ATable::DrawOut() 354 { 355 Ghost(); 356 PutBlock(GX, GY, face, type, 8); 357 PutBlock(PosX, PosY, face, type, type); 358 for (int32 i = 1; i <= 10; i++) 359 for (int32 j = 1; j <= 20; j++) { 360 if (Blocks[i][j] == 0)BlockBody[i][j]->SetVisibility(false); 361 else { 362 BlockBody[i][j]->SetMaterial(0, Materials[Blocks[i][j]]); 363 BlockBody[i][j]->SetVisibility(true); 364 } 365 } 366 PutBlock(PosX, PosY, face, type, 0); 367 PutBlock(GX, GY, face, type, 0); 368 } 369 370 void ATable::AddOneInQueue() 371 { 372 //UE_LOG(LogTemp, Warning, TEXT("Add ONe!!!")); 373 if (BagTop <= 7) { 374 Queue.push(Bag[BagTop++]); 375 return; 376 } 377 BagTop = 1; 378 for (int32 i = 1; i <= 7; i++)Bag[i] = i; 379 std::random_shuffle(Bag + 1, Bag + 8); 380 Queue.push(Bag[BagTop++]); 381 return; 382 } 383 384 void ATable::DrawNext() 385 { 386 for (int i = 1; i <= 3; i++) { 387 Next[i] = Queue.front(); 388 Queue.push(Next[i]); 389 Queue.pop(); 390 } 391 PutNextBlock(2, 11, 0, Next[1], Next[1]); 392 PutNextBlock(2, 7, 0, Next[2], Next[2]); 393 PutNextBlock(2, 3, 0, Next[3], Next[3]); 394 for (int32 i = 1; i <= 4; i++) 395 for (int32 j = 1; j <= 12; j++) { 396 if (NextBlocks[i][j] == 0)NextBlockBody[i][j]->SetVisibility(false); 397 else { 398 NextBlockBody[i][j]->SetMaterial(0, Materials[NextBlocks[i][j]]); 399 NextBlockBody[i][j]->SetVisibility(true); 400 } 401 } 402 PutNextBlock(2, 11, 0, Next[1], 0); 403 PutNextBlock(2, 7, 0, Next[2], 0); 404 PutNextBlock(2, 3, 0, Next[3], 0); 405 } 406 407 void ATable::Ghost() 408 { 409 GX = PosX, GY = PosY; 410 while (Check(GX, GY - 1, face, type)) GY--; 411 return; 412 } 413 414 bool ATable::IsLineDone(int32 Y) 415 { 416 for (int i = 1; i <= 10; i++) 417 if (!Blocks[i][Y])return false; 418 return true; 419 } 420 421 bool ATable::IsTSlot(int32 X, int32 Y) 422 { 423 int tmp = 0; 424 if (Blocks[X + 1][Y + 1])tmp++; 425 if (Blocks[X + 1][Y - 1])tmp++; 426 if (Blocks[X - 1][Y + 1])tmp++; 427 if (Blocks[X - 1][Y - 1])tmp++; 428 return tmp >= 3; 429 } 430 431 void ATable::Animate() 432 { 433 int tot = DoneQueue.size(); 434 //UE_LOG(LogTemp, Warning, TEXT("Donesize %d!!!"), tot); 435 for (int i = 1; i <= tot; i++) { 436 int tmp = DoneQueue.front(); 437 //UE_LOG(LogTemp, Warning, TEXT("Done %d!!!"), tmp); 438 DoneQueue.pop(); 439 DoneQueue.push(tmp); 440 for (int j = 1; j <= 10; j++) 441 Blocks[j][tmp] = 9; 442 } 443 DrawOut(); 444 GetWorldTimerManager().SetTimer(AnimateTick, this, &ATable::AnimateDone, 0.09f, false); 445 } 446 447 void ATable::AnimateDone() 448 { 449 int tot = DoneQueue.size(); 450 //UE_LOG(LogTemp, Warning, TEXT("Donesize %d!!!"), tot); 451 if (tot == 1) AddScoreLines(100 * CurrentLevel, tot), UGameplayStatics::PlaySound2D(GetWorld(), SoundWaveClear, 0.3f); 452 else if (tot == 2) AddScoreLines(300 * CurrentLevel, tot), UGameplayStatics::PlaySound2D(GetWorld(), SoundWaveClear, 0.3f); 453 else if (tot == 3) AddScoreLines(500 * CurrentLevel, tot), UGameplayStatics::PlaySound2D(GetWorld(), SoundWaveClear, 0.3f); 454 else if (tot == 4) { 455 AddScoreLines(800 * CurrentLevel, tot); 456 GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Yellow, FString::Printf(TEXT("TETRIS!"))); 457 UGameplayStatics::PlaySound2D(GetWorld(), SoundWaveTetris, 0.3f); 458 } 459 for (int t = 1; t <= tot; t++) { 460 int tmp = DoneQueue.front(); 461 DoneQueue.pop(); 462 //UE_LOG(LogTemp, Warning, TEXT("Remove %d!!!"), tmp); 463 for (int j = tmp; j <= 20; j++) 464 for (int i = 1; i <= 10; i++) 465 Blocks[i][j] = Blocks[i][j + 1]; 466 } 467 DrawOut(); 468 } 469 470 void ATable::AddScoreLines(int32 addScore, int32 addLines) 471 { 472 Score += addScore; 473 Lines += addLines; 474 ScoreNum->SetText(FText::Format(LOCTEXT("ScoreNumFmt", "{0}"), FText::AsNumber(Score))); 475 LinesNum->SetText(FText::Format(LOCTEXT("LinesNumFmt", "{0}"), FText::AsNumber(Lines))); 476 if (Lines >= CurrentLevel * 10) { 477 //Level up! 478 UGameplayStatics::PlaySound2D(GetWorld(), SoundWaveLevel, 0.3f); 479 CurrentLevel++; 480 LevelNum->SetText(FText::Format(LOCTEXT("LevelNumFmt", "{0}"), FText::AsNumber(CurrentLevel))); 481 TimeBetweenFall = FGenericPlatformMath::Pow((0.8 - ((CurrentLevel - 1) * 0.007)), (CurrentLevel - 1)); 482 } 483 } 484 485 void ATable::Generation() 486 { 487 //UE_LOG(LogTemp, Warning, TEXT("HERE!!!!!")); 488 PosX = 5, PosY = 21, face = 0; 489 type = Queue.front(); 490 Queue.pop(); 491 AddOneInQueue(); 492 //UE_LOG(LogTemp, Warning, TEXT("HERE TYPE!!!!!: %d"), type); 493 Holding = false; 494 DrawNext(); 495 if (!Check(PosX, PosY, face, type)) { 496 //UE_LOG(LogTemp, Warning, TEXT("BLOCKOUT!!")); 497 GameOver(); 498 return; 499 } 500 MoveDown(); 501 //Begin to fall 502 //UE_LOG(LogTemp, Warning, TEXT("Set TImer!!")); 503 GetWorldTimerManager().SetTimer(TimeTick, this, &ATable::MoveDown, TimeBetweenFall, true); 504 } 505 506 void ATable::GameOver() 507 { 508 //UE_LOG(LogTemp, Warning, TEXT("GAMEOVER!!")); 509 //UE_LOG(LogTemp, Warning, TEXT("GAMEOVER!!")); 510 //UE_LOG(LogTemp, Warning, TEXT("GAMEOVER!!")); 511 PauseText->SetRelativeLocation(FVector(-100, 10, 500)); 512 PauseText->SetText(FText::Format(LOCTEXT("PauseText", "GAMEOVER"), FText::AsNumber(0))); 513 GetWorldTimerManager().ClearTimer(TimeTick); 514 GetWorldTimerManager().ClearTimer(AutoTick); 515 GetWorldTimerManager().ClearTimer(AnimateTick); 516 bGameOver = true; 517 for (int i = 1; i <= 10; i++) 518 for (int j = 1; j <= 20; j++) { 519 if (Blocks[i][j] == 0) { 520 Blocks[i][j] = FMath::RandRange(1, 7); 521 BlockBody[i][j]->SetMaterial(0, Materials[Blocks[i][j]]); 522 BlockBody[i][j]->SetVisibility(true); 523 } 524 } 525 } 526 527 bool ATable::Check(int32 X, int32 Y, int32 fa, int32 ty) 528 { 529 //UE_LOG(LogTemp, Warning, TEXT("ty is%d!!!"),ty); 530 switch (ty) 531 { 532 case 1://O 533 if (Blocks[X][Y] || Blocks[X + 1][Y] || Blocks[X][Y + 1] || Blocks[X + 1][Y + 1]) 534 return false; 535 else return true; 536 break; 537 case 2://I 538 switch (fa) 539 { 540 case 0://North 541 if (Blocks[X - 1][Y] || Blocks[X][Y] || Blocks[X + 1][Y] || Blocks[X + 2][Y]) 542 return false; 543 else return true; 544 break; 545 case 1://East 546 if (Blocks[X + 1][Y + 1] || Blocks[X + 1][Y] || Blocks[X + 1][Y - 1] || Blocks[X + 1][Y - 2]) 547 return false; 548 else return true; 549 break; 550 case 2://South 551 if (Blocks[X - 1][Y - 1] || Blocks[X][Y - 1] || Blocks[X + 1][Y - 1] || Blocks[X + 2][Y - 1]) 552 return false; 553 else return true; 554 break; 555 case 3://West 556 if (Blocks[X][Y + 1] || Blocks[X][Y] || Blocks[X][Y - 1] || Blocks[X][Y - 2]) 557 return false; 558 else return true; 559 break; 560 default: 561 break; 562 } 563 break; 564 case 3://T 565 switch (fa) 566 { 567 case 0: 568 if (Blocks[X][Y] || Blocks[X][Y + 1] || Blocks[X - 1][Y] || Blocks[X + 1][Y]) 569 return false; 570 else return true; 571 break; 572 case 1: 573 if (Blocks[X][Y] || Blocks[X + 1][Y] || Blocks[X][Y + 1] || Blocks[X][Y - 1]) 574 return false; 575 else return true; 576 break; 577 case 2: 578 if (Blocks[X][Y] || Blocks[X][Y - 1] || Blocks[X + 1][Y] || Blocks[X - 1][Y]) 579 return false; 580 else return true; 581 break; 582 case 3: 583 if (Blocks[X][Y] || Blocks[X - 1][Y] || Blocks[X][Y + 1] || Blocks[X][Y - 1]) 584 return false; 585 else return true; 586 break; 587 default: 588 break; 589 } 590 break; 591 case 4://L 592 switch (fa) 593 { 594 case 0://North 595 if (Blocks[X][Y] || Blocks[X - 1][Y] || Blocks[X + 1][Y] || Blocks[X + 1][Y + 1]) 596 return false; 597 else return true; 598 break; 599 case 1: 600 if (Blocks[X][Y] || Blocks[X][Y + 1] || Blocks[X][Y - 1] || Blocks[X + 1][Y - 1]) 601 return false; 602 else return true; 603 break; 604 case 2: 605 if (Blocks[X][Y] || Blocks[X - 1][Y] || Blocks[X + 1][Y] || Blocks[X - 1][Y - 1]) 606 return false; 607 else return true; 608 break; 609 case 3: 610 if (Blocks[X][Y] || Blocks[X][Y + 1] || Blocks[X][Y - 1] || Blocks[X - 1][Y + 1]) 611 return false; 612 else return true; 613 break; 614 default: 615 break; 616 } 617 break; 618 case 5://J 619 switch (fa) 620 { 621 case 0: 622 if (Blocks[X][Y] || Blocks[X + 1][Y] || Blocks[X - 1][Y] || Blocks[X - 1][Y + 1]) 623 return false; 624 else return true; 625 break; 626 case 1: 627 if (Blocks[X][Y] || Blocks[X][Y + 1] || Blocks[X][Y - 1] || Blocks[X + 1][Y + 1]) 628 return false; 629 else return true; 630 break; 631 case 2: 632 if (Blocks[X + 1][Y] || Blocks[X][Y] || Blocks[X - 1][Y] || Blocks[X + 1][Y - 1]) 633 return false; 634 else return true; 635 break; 636 case 3: 637 if (Blocks[X][Y] || Blocks[X][Y + 1] || Blocks[X][Y - 1] || Blocks[X - 1][Y - 1]) 638 return false; 639 else return true; 640 break; 641 default: 642 break; 643 } 644 break; 645 case 6://S 646 switch (fa) 647 { 648 case 0: 649 if (Blocks[X][Y] || Blocks[X + 1][Y + 1] || Blocks[X][Y + 1] || Blocks[X - 1][Y]) 650 return false; 651 else return true; 652 break; 653 case 1: 654 if (Blocks[X][Y] || Blocks[X + 1][Y] || Blocks[X][Y + 1] || Blocks[X + 1][Y - 1]) 655 return false; 656 else return true; 657 break; 658 case 2: 659 if (Blocks[X][Y] || Blocks[X][Y - 1] || Blocks[X + 1][Y] || Blocks[X - 1][Y - 1]) 660 return false; 661 else return true; 662 break; 663 case 3: 664 if (Blocks[X][Y] || Blocks[X][Y - 1] || Blocks[X - 1][Y] || Blocks[X - 1][Y + 1]) 665 return false; 666 else return true; 667 break; 668 default: 669 break; 670 } 671 break; 672 case 7://Z 673 switch (fa) 674 { 675 case 0: 676 if (Blocks[X][Y] || Blocks[X][Y + 1] || Blocks[X + 1][Y] || Blocks[X - 1][Y + 1]) 677 return false; 678 else return true; 679 break; 680 case 1: 681 if (Blocks[X][Y] || Blocks[X][Y - 1] || Blocks[X + 1][Y] || Blocks[X + 1][Y + 1]) 682 return false; 683 else return true; 684 break; 685 case 2: 686 if (Blocks[X][Y] || Blocks[X][Y - 1] || Blocks[X - 1][Y] || Blocks[X + 1][Y - 1]) 687 return false; 688 else return true; 689 break; 690 case 3: 691 if (Blocks[X][Y] || Blocks[X][Y + 1] || Blocks[X - 1][Y] || Blocks[X - 1][Y - 1]) 692 return false; 693 else return true; 694 break; 695 default: 696 break; 697 } 698 break; 699 default: 700 break; 701 } 702 return false; 703 } 704 705 void ATable::PutBlock(int32 X, int32 Y, int32 fa, int32 ty,int32 goal) 706 { 707 switch (ty) 708 { 709 case 1://O 710 Blocks[X][Y] = Blocks[X + 1][Y] = Blocks[X][Y + 1] = Blocks[X + 1][Y + 1] = goal; 711 return; 712 break; 713 case 2://I 714 switch (fa) 715 { 716 case 0://North 717 Blocks[X - 1][Y] = Blocks[X][Y] = Blocks[X + 1][Y] = Blocks[X + 2][Y] = goal; 718 return; 719 break; 720 case 1://East 721 Blocks[X + 1][Y + 1] = Blocks[X + 1][Y] = Blocks[X + 1][Y - 1] = Blocks[X + 1][Y - 2] = goal; 722 return; 723 break; 724 case 2://South 725 Blocks[X - 1][Y - 1] = Blocks[X][Y - 1] = Blocks[X + 1][Y - 1] = Blocks[X + 2][Y - 1] = goal; 726 return; 727 break; 728 case 3://West 729 Blocks[X][Y + 1] = Blocks[X][Y] = Blocks[X][Y - 1] = Blocks[X][Y - 2] = goal; 730 return; 731 break; 732 default: 733 break; 734 } 735 break; 736 case 3://T 737 switch (fa) 738 { 739 case 0: 740 Blocks[X][Y] = Blocks[X][Y + 1] = Blocks[X - 1][Y] = Blocks[X + 1][Y] = goal; 741 return; 742 break; 743 case 1: 744 Blocks[X][Y] = Blocks[X + 1][Y] = Blocks[X][Y + 1] = Blocks[X][Y - 1] = goal; 745 return; 746 break; 747 case 2: 748 Blocks[X][Y] = Blocks[X][Y - 1] = Blocks[X + 1][Y] = Blocks[X - 1][Y] = goal; 749 return; 750 break; 751 case 3: 752 Blocks[X][Y] = Blocks[X - 1][Y] = Blocks[X][Y + 1] = Blocks[X][Y - 1] = goal; 753 return; 754 break; 755 default: 756 break; 757 } 758 break; 759 case 4://L 760 switch (fa) 761 { 762 case 0://North 763 Blocks[X][Y] = Blocks[X - 1][Y] = Blocks[X + 1][Y] = Blocks[X + 1][Y + 1] = goal; 764 return; 765 break; 766 case 1: 767 Blocks[X][Y] = Blocks[X][Y + 1] = Blocks[X][Y - 1] = Blocks[X + 1][Y - 1] = goal; 768 return; 769 break; 770 case 2: 771 Blocks[X][Y] = Blocks[X - 1][Y] = Blocks[X + 1][Y] = Blocks[X - 1][Y - 1] = goal; 772 return; 773 break; 774 case 3: 775 Blocks[X][Y] = Blocks[X][Y + 1] = Blocks[X][Y - 1] = Blocks[X - 1][Y + 1] = goal; 776 return; 777 break; 778 default: 779 break; 780 } 781 break; 782 case 5://J 783 switch (fa) 784 { 785 case 0: 786 Blocks[X][Y] = Blocks[X + 1][Y] = Blocks[X - 1][Y] = Blocks[X - 1][Y + 1] = goal; 787 return; 788 break; 789 case 1: 790 Blocks[X][Y] = Blocks[X][Y + 1] = Blocks[X][Y - 1] = Blocks[X + 1][Y + 1] = goal; 791 return; 792 break; 793 case 2: 794 Blocks[X + 1][Y] = Blocks[X][Y] = Blocks[X - 1][Y] = Blocks[X + 1][Y - 1] = goal; 795 return; 796 break; 797 case 3: 798 Blocks[X][Y] = Blocks[X][Y + 1] = Blocks[X][Y - 1] = Blocks[X - 1][Y - 1] = goal; 799 return; 800 break; 801 default: 802 break; 803 } 804 break; 805 case 6://S 806 switch (fa) 807 { 808 case 0: 809 Blocks[X][Y] = Blocks[X + 1][Y + 1] = Blocks[X][Y + 1] = Blocks[X - 1][Y] = goal; 810 return; 811 break; 812 case 1: 813 Blocks[X][Y] = Blocks[X + 1][Y] = Blocks[X][Y + 1] = Blocks[X + 1][Y - 1] = goal; 814 return; 815 break; 816 case 2: 817 Blocks[X][Y] = Blocks[X][Y - 1] = Blocks[X + 1][Y] = Blocks[X - 1][Y - 1] = goal; 818 return; 819 break; 820 case 3: 821 Blocks[X][Y] = Blocks[X][Y - 1] = Blocks[X - 1][Y] = Blocks[X - 1][Y + 1] = goal; 822 return; 823 break; 824 default: 825 break; 826 } 827 break; 828 case 7://Z 829 switch (fa) 830 { 831 case 0: 832 Blocks[X][Y] = Blocks[X][Y + 1] = Blocks[X + 1][Y] = Blocks[X - 1][Y + 1] = goal; 833 return; 834 break; 835 case 1: 836 Blocks[X][Y] = Blocks[X][Y - 1] = Blocks[X + 1][Y] = Blocks[X + 1][Y + 1] = goal; 837 return; 838 break; 839 case 2: 840 Blocks[X][Y] = Blocks[X][Y - 1] = Blocks[X - 1][Y] = Blocks[X + 1][Y - 1] = goal; 841 return; 842 break; 843 case 3: 844 Blocks[X][Y] = Blocks[X][Y + 1] = Blocks[X - 1][Y] = Blocks[X - 1][Y - 1] = goal; 845 return; 846 break; 847 default: 848 break; 849 } 850 break; 851 default: 852 break; 853 } 854 return; 855 } 856 857 void ATable::PutHoldBlock(int32 X, int32 Y, int32 fa, int32 ty, int32 goal) 858 { 859 switch (ty) 860 { 861 case 1://O 862 HoldBlocks[X][Y] = HoldBlocks[X + 1][Y] = HoldBlocks[X][Y + 1] = HoldBlocks[X + 1][Y + 1] = goal; 863 return; 864 break; 865 case 2://I 866 switch (fa) 867 { 868 case 0://North 869 HoldBlocks[X - 1][Y] = HoldBlocks[X][Y] = HoldBlocks[X + 1][Y] = HoldBlocks[X + 2][Y] = goal; 870 return; 871 break; 872 case 1://East 873 HoldBlocks[X + 1][Y + 1] = HoldBlocks[X + 1][Y] = HoldBlocks[X + 1][Y - 1] = HoldBlocks[X + 1][Y - 2] = goal; 874 return; 875 break; 876 case 2://South 877 HoldBlocks[X - 1][Y - 1] = HoldBlocks[X][Y - 1] = HoldBlocks[X + 1][Y - 1] = HoldBlocks[X + 2][Y - 1] = goal; 878 return; 879 break; 880 case 3://West 881 HoldBlocks[X][Y + 1] = HoldBlocks[X][Y] = HoldBlocks[X][Y - 1] = HoldBlocks[X][Y - 2] = goal; 882 return; 883 break; 884 default: 885 break; 886 } 887 break; 888 case 3://T 889 switch (fa) 890 { 891 case 0: 892 HoldBlocks[X][Y] = HoldBlocks[X][Y + 1] = HoldBlocks[X - 1][Y] = HoldBlocks[X + 1][Y] = goal; 893 return; 894 break; 895 case 1: 896 HoldBlocks[X][Y] = HoldBlocks[X + 1][Y] = HoldBlocks[X][Y + 1] = HoldBlocks[X][Y - 1] = goal; 897 return; 898 break; 899 case 2: 900 HoldBlocks[X][Y] = HoldBlocks[X][Y - 1] = HoldBlocks[X + 1][Y] = HoldBlocks[X - 1][Y] = goal; 901 return; 902 break; 903 case 3: 904 HoldBlocks[X][Y] = HoldBlocks[X - 1][Y] = HoldBlocks[X][Y + 1] = HoldBlocks[X][Y - 1] = goal; 905 return; 906 break; 907 default: 908 break; 909 } 910 break; 911 case 4://L 912 switch (fa) 913 { 914 case 0://North 915 HoldBlocks[X][Y] = HoldBlocks[X - 1][Y] = HoldBlocks[X + 1][Y] = HoldBlocks[X + 1][Y + 1] = goal; 916 return; 917 break; 918 case 1: 919 HoldBlocks[X][Y] = HoldBlocks[X][Y + 1] = HoldBlocks[X][Y - 1] = HoldBlocks[X + 1][Y - 1] = goal; 920 return; 921 break; 922 case 2: 923 HoldBlocks[X][Y] = HoldBlocks[X - 1][Y] = HoldBlocks[X + 1][Y] = HoldBlocks[X - 1][Y - 1] = goal; 924 return; 925 break; 926 case 3: 927 HoldBlocks[X][Y] = HoldBlocks[X][Y + 1] = HoldBlocks[X][Y - 1] = HoldBlocks[X - 1][Y + 1] = goal; 928 return; 929 break; 930 default: 931 break; 932 } 933 break; 934 case 5://J 935 switch (fa) 936 { 937 case 0: 938 HoldBlocks[X][Y] = HoldBlocks[X + 1][Y] = HoldBlocks[X - 1][Y] = HoldBlocks[X - 1][Y + 1] = goal; 939 return; 940 break; 941 case 1: 942 HoldBlocks[X][Y] = HoldBlocks[X][Y + 1] = HoldBlocks[X][Y - 1] = HoldBlocks[X + 1][Y + 1] = goal; 943 return; 944 break; 945 case 2: 946 HoldBlocks[X + 1][Y] = HoldBlocks[X][Y] = HoldBlocks[X - 1][Y] = HoldBlocks[X + 1][Y - 1] = goal; 947 return; 948 break; 949 case 3: 950 HoldBlocks[X][Y] = HoldBlocks[X][Y + 1] = HoldBlocks[X][Y - 1] = HoldBlocks[X - 1][Y - 1] = goal; 951 return; 952 break; 953 default: 954 break; 955 } 956 break; 957 case 6://S 958 switch (fa) 959 { 960 case 0: 961 HoldBlocks[X][Y] = HoldBlocks[X + 1][Y + 1] = HoldBlocks[X][Y + 1] = HoldBlocks[X - 1][Y] = goal; 962 return; 963 break; 964 case 1: 965 HoldBlocks[X][Y] = HoldBlocks[X + 1][Y] = HoldBlocks[X][Y + 1] = HoldBlocks[X + 1][Y - 1] = goal; 966 return; 967 break; 968 case 2: 969 HoldBlocks[X][Y] = HoldBlocks[X][Y - 1] = HoldBlocks[X + 1][Y] = HoldBlocks[X - 1][Y - 1] = goal; 970 return; 971 break; 972 case 3: 973 HoldBlocks[X][Y] = HoldBlocks[X][Y - 1] = HoldBlocks[X - 1][Y] = HoldBlocks[X - 1][Y + 1] = goal; 974 return; 975 break; 976 default: 977 break; 978 } 979 break; 980 case 7://Z 981 switch (fa) 982 { 983 case 0: 984 HoldBlocks[X][Y] = HoldBlocks[X][Y + 1] = HoldBlocks[X + 1][Y] = HoldBlocks[X - 1][Y + 1] = goal; 985 return; 986 break; 987 case 1: 988 HoldBlocks[X][Y] = HoldBlocks[X][Y - 1] = HoldBlocks[X + 1][Y] = HoldBlocks[X + 1][Y + 1] = goal; 989 return; 990 break; 991 case 2: 992 HoldBlocks[X][Y] = HoldBlocks[X][Y - 1] = HoldBlocks[X - 1][Y] = HoldBlocks[X + 1][Y - 1] = goal; 993 return; 994 break; 995 case 3: 996 HoldBlocks[X][Y] = HoldBlocks[X][Y + 1] = HoldBlocks[X - 1][Y] = HoldBlocks[X - 1][Y - 1] = goal; 997 return; 998 break; 999 default: 1000 break; 1001 } 1002 break; 1003 default: 1004 break; 1005 } 1006 return; 1007 } 1008 1009 void ATable::PutNextBlock(int32 X, int32 Y, int32 fa, int32 ty, int32 goal) 1010 { 1011 switch (ty) 1012 { 1013 case 1://O 1014 NextBlocks[X][Y] = NextBlocks[X + 1][Y] = NextBlocks[X][Y + 1] = NextBlocks[X + 1][Y + 1] = goal; 1015 return; 1016 break; 1017 case 2://I 1018 switch (fa) 1019 { 1020 case 0://North 1021 NextBlocks[X - 1][Y] = NextBlocks[X][Y] = NextBlocks[X + 1][Y] = NextBlocks[X + 2][Y] = goal; 1022 return; 1023 break; 1024 case 1://East 1025 NextBlocks[X + 1][Y + 1] = NextBlocks[X + 1][Y] = NextBlocks[X + 1][Y - 1] = NextBlocks[X + 1][Y - 2] = goal; 1026 return; 1027 break; 1028 case 2://South 1029 NextBlocks[X - 1][Y - 1] = NextBlocks[X][Y - 1] = NextBlocks[X + 1][Y - 1] = NextBlocks[X + 2][Y - 1] = goal; 1030 return; 1031 break; 1032 case 3://West 1033 NextBlocks[X][Y + 1] = NextBlocks[X][Y] = NextBlocks[X][Y - 1] = NextBlocks[X][Y - 2] = goal; 1034 return; 1035 break; 1036 default: 1037 break; 1038 } 1039 break; 1040 case 3://T 1041 switch (fa) 1042 { 1043 case 0: 1044 NextBlocks[X][Y] = NextBlocks[X][Y + 1] = NextBlocks[X - 1][Y] = NextBlocks[X + 1][Y] = goal; 1045 return; 1046 break; 1047 case 1: 1048 NextBlocks[X][Y] = NextBlocks[X + 1][Y] = NextBlocks[X][Y + 1] = NextBlocks[X][Y - 1] = goal; 1049 return; 1050 break; 1051 case 2: 1052 NextBlocks[X][Y] = NextBlocks[X][Y - 1] = NextBlocks[X + 1][Y] = NextBlocks[X - 1][Y] = goal; 1053 return; 1054 break; 1055 case 3: 1056 NextBlocks[X][Y] = NextBlocks[X - 1][Y] = NextBlocks[X][Y + 1] = NextBlocks[X][Y - 1] = goal; 1057 return; 1058 break; 1059 default: 1060 break; 1061 } 1062 break; 1063 case 4://L 1064 switch (fa) 1065 { 1066 case 0://North 1067 NextBlocks[X][Y] = NextBlocks[X - 1][Y] = NextBlocks[X + 1][Y] = NextBlocks[X + 1][Y + 1] = goal; 1068 return; 1069 break; 1070 case 1: 1071 NextBlocks[X][Y] = NextBlocks[X][Y + 1] = NextBlocks[X][Y - 1] = NextBlocks[X + 1][Y - 1] = goal; 1072 return; 1073 break; 1074 case 2: 1075 NextBlocks[X][Y] = NextBlocks[X - 1][Y] = NextBlocks[X + 1][Y] = NextBlocks[X - 1][Y - 1] = goal; 1076 return; 1077 break; 1078 case 3: 1079 NextBlocks[X][Y] = NextBlocks[X][Y + 1] = NextBlocks[X][Y - 1] = NextBlocks[X - 1][Y + 1] = goal; 1080 return; 1081 break; 1082 default: 1083 break; 1084 } 1085 break; 1086 case 5://J 1087 switch (fa) 1088 { 1089 case 0: 1090 NextBlocks[X][Y] = NextBlocks[X + 1][Y] = NextBlocks[X - 1][Y] = NextBlocks[X - 1][Y + 1] = goal; 1091 return; 1092 break; 1093 case 1: 1094 NextBlocks[X][Y] = NextBlocks[X][Y + 1] = NextBlocks[X][Y - 1] = NextBlocks[X + 1][Y + 1] = goal; 1095 return; 1096 break; 1097 case 2: 1098 NextBlocks[X + 1][Y] = NextBlocks[X][Y] = NextBlocks[X - 1][Y] = NextBlocks[X + 1][Y - 1] = goal; 1099 return; 1100 break; 1101 case 3: 1102 NextBlocks[X][Y] = NextBlocks[X][Y + 1] = NextBlocks[X][Y - 1] = NextBlocks[X - 1][Y - 1] = goal; 1103 return; 1104 break; 1105 default: 1106 break; 1107 } 1108 break; 1109 case 6://S 1110 switch (fa) 1111 { 1112 case 0: 1113 NextBlocks[X][Y] = NextBlocks[X + 1][Y + 1] = NextBlocks[X][Y + 1] = NextBlocks[X - 1][Y] = goal; 1114 return; 1115 break; 1116 case 1: 1117 NextBlocks[X][Y] = NextBlocks[X + 1][Y] = NextBlocks[X][Y + 1] = NextBlocks[X + 1][Y - 1] = goal; 1118 return; 1119 break; 1120 case 2: 1121 NextBlocks[X][Y] = NextBlocks[X][Y - 1] = NextBlocks[X + 1][Y] = NextBlocks[X - 1][Y - 1] = goal; 1122 return; 1123 break; 1124 case 3: 1125 NextBlocks[X][Y] = NextBlocks[X][Y - 1] = NextBlocks[X - 1][Y] = NextBlocks[X - 1][Y + 1] = goal; 1126 return; 1127 break; 1128 default: 1129 break; 1130 } 1131 break; 1132 case 7://Z 1133 switch (fa) 1134 { 1135 case 0: 1136 NextBlocks[X][Y] = NextBlocks[X][Y + 1] = NextBlocks[X + 1][Y] = NextBlocks[X - 1][Y + 1] = goal; 1137 return; 1138 break; 1139 case 1: 1140 NextBlocks[X][Y] = NextBlocks[X][Y - 1] = NextBlocks[X + 1][Y] = NextBlocks[X + 1][Y + 1] = goal; 1141 return; 1142 break; 1143 case 2: 1144 NextBlocks[X][Y] = NextBlocks[X][Y - 1] = NextBlocks[X - 1][Y] = NextBlocks[X + 1][Y - 1] = goal; 1145 return; 1146 break; 1147 case 3: 1148 NextBlocks[X][Y] = NextBlocks[X][Y + 1] = NextBlocks[X - 1][Y] = NextBlocks[X - 1][Y - 1] = goal; 1149 return; 1150 break; 1151 default: 1152 break; 1153 } 1154 break; 1155 default: 1156 break; 1157 } 1158 return; 1159 } 1160 1161 void ATable::MoveRight() 1162 { 1163 if (bGameOver || bPause)return; 1164 bool bMoved = false; 1165 if (Check(PosX + 1, PosY, face, type)) { 1166 PosX++; 1167 bMoved = true; 1168 UGameplayStatics::PlaySound2D(GetWorld(), SoundWaveMove, 0.3f); 1169 DrawOut(); 1170 if (!bIsRightPressed && bIsLeftPressed) { 1171 bIsRightPressed = true; 1172 GetWorldTimerManager().ClearTimer(AutoTick); 1173 bIsAutoRepeating = false; 1174 bIsAutoDelay = false; 1175 } 1176 else if (!bIsRightPressed)bIsRightPressed = true; 1177 if (!bIsAutoRepeating) { 1178 if (!bIsAutoDelay) { 1179 bIsAutoDelay = true; 1180 GetWorldTimerManager().SetTimer(AutoTick, this, &ATable::MoveRight, 0.2f, false); 1181 } 1182 else { 1183 GetWorldTimerManager().SetTimer(AutoTick, this, &ATable::MoveRight, 0.2f / 7.0f, true); 1184 bIsAutoRepeating = true; 1185 } 1186 } 1187 //move right complete 1188 } 1189 if (bMoved && !Check(PosX, PosY - 1, face, type)) { 1190 GetWorldTimerManager().SetTimer(TimeTick, this, &ATable::LockDown, TimeBeforeLock, false); 1191 //UE_LOG(LogTemp, Warning, TEXT("Ready To Lock!")); 1192 } 1193 //UE_LOG(LogTemp, Warning, TEXT("left:%d right%d"), bIsLeftPressed, bIsRightPressed); 1194 } 1195 1196 void ATable::MoveRightReleased() 1197 { 1198 if (bGameOver || bPause)return; 1199 GetWorldTimerManager().ClearTimer(AutoTick); 1200 bIsAutoRepeating = false; 1201 bIsAutoDelay = false; 1202 bIsRightPressed = false; 1203 if (bIsLeftPressed)MoveLeft(); 1204 } 1205 1206 void ATable::MoveLeft() 1207 { 1208 if (bGameOver || bPause)return; 1209 bool bMoved = false; 1210 if (Check(PosX - 1, PosY, face, type)) { 1211 PosX--; 1212 bMoved = true; 1213 UGameplayStatics::PlaySound2D(GetWorld(), SoundWaveMove, 0.3f); 1214 DrawOut(); 1215 if (!bIsLeftPressed && bIsRightPressed) { 1216 bIsLeftPressed = true; 1217 GetWorldTimerManager().ClearTimer(AutoTick); 1218 bIsAutoRepeating = false; 1219 bIsAutoDelay = false; 1220 } 1221 else if (!bIsLeftPressed)bIsLeftPressed = true; 1222 if (!bIsAutoRepeating) { 1223 if (!bIsAutoDelay) { 1224 bIsAutoDelay = true; 1225 GetWorldTimerManager().SetTimer(AutoTick, this, &ATable::MoveLeft, 0.2f, false); 1226 } 1227 else { 1228 GetWorldTimerManager().SetTimer(AutoTick, this, &ATable::MoveLeft, 0.2f / 7.0f, true); 1229 bIsAutoRepeating = true; 1230 } 1231 } 1232 //move Left complete 1233 } 1234 if (bMoved && !Check(PosX, PosY - 1, face, type)) { 1235 GetWorldTimerManager().SetTimer(TimeTick, this, &ATable::LockDown, TimeBeforeLock, false); 1236 //UE_LOG(LogTemp, Warning, TEXT("Ready To Lock!")); 1237 } 1238 //UE_LOG(LogTemp, Warning, TEXT("left:%d right%d"), bIsLeftPressed, bIsRightPressed); 1239 } 1240 1241 void ATable::MoveLeftReleased() 1242 { 1243 if (bGameOver || bPause)return; 1244 GetWorldTimerManager().ClearTimer(AutoTick); 1245 bIsAutoRepeating = false; 1246 bIsAutoDelay = false; 1247 bIsLeftPressed = false; 1248 if (bIsRightPressed)MoveRight(); 1249 } 1250 1251 void ATable::HardDrop() 1252 { 1253 if (bGameOver || bPause)return; 1254 while (Check(PosX, PosY - 1, face, type)) 1255 PosY--, AddScoreLines(2, 0); 1256 UGameplayStatics::PlaySound2D(GetWorld(), SoundWaveDrop, 0.3f); 1257 LockDown(); 1258 } 1259 1260 void ATable::SoftDrop() 1261 { 1262 if (bGameOver || bPause)return; 1263 bIsSoftDrop = true; 1264 TimeBetweenFall /= 20.0f; 1265 if (Check(PosX, PosY - 1, face, type)) 1266 GetWorldTimerManager().SetTimer(TimeTick, this, &ATable::MoveDown, TimeBetweenFall, true); 1267 } 1268 1269 void ATable::SoftDropReleased() 1270 { 1271 if (bGameOver || bPause)return; 1272 bIsSoftDrop = false; 1273 TimeBetweenFall = FGenericPlatformMath::Pow((0.8 - ((CurrentLevel - 1) * 0.007)), (CurrentLevel - 1)); 1274 if (Check(PosX, PosY - 1, face, type)) 1275 GetWorldTimerManager().SetTimer(TimeTick, this, &ATable::MoveDown, TimeBetweenFall, true); 1276 } 1277 1278 void ATable::RotateClockwise() 1279 { 1280 if (bGameOver || bPause)return; 1281 for (int i = 0; i < 5; i++) { 1282 if (Check(PosX + ClockRotation[type - 1][face][i][0], PosY + ClockRotation[type - 1][face][i][1], (face + 1) % 4, type)) { 1283 PosX += ClockRotation[type - 1][face][i][0]; 1284 PosY += ClockRotation[type - 1][face][i][1]; 1285 face = (face + 1) % 4; 1286 1287 if (!Check(PosX, PosY - 1, face, type)) { 1288 GetWorldTimerManager().SetTimer(TimeTick, this, &ATable::RLockDown, TimeBeforeLock, false); 1289 //UE_LOG(LogTemp, Warning, TEXT("Ready To Lock!")); 1290 } 1291 DrawOut(); 1292 UGameplayStatics::PlaySound2D(GetWorld(), SoundWaveMoveFail, 0.1f); 1293 UGameplayStatics::PlaySound2D(GetWorld(), SoundWaveMove, 0.3f); 1294 return; 1295 } 1296 } 1297 } 1298 1299 void ATable::RotateCounterClockwise() 1300 { 1301 if (bGameOver || bPause)return; 1302 for (int i = 0; i < 5; i++) { 1303 if (Check(PosX + CounterClockRotation[type - 1][face][i][0], PosY + CounterClockRotation[type - 1][face][i][1], (face + 3) % 4, type)) { 1304 PosX += CounterClockRotation[type - 1][face][i][0]; 1305 PosY += CounterClockRotation[type - 1][face][i][1]; 1306 face = (face + 3) % 4; 1307 1308 if (!Check(PosX, PosY - 1, face, type)) { 1309 GetWorldTimerManager().SetTimer(TimeTick, this, &ATable::RLockDown, TimeBeforeLock, false); 1310 //UE_LOG(LogTemp, Warning, TEXT("Ready To Lock!")); 1311 } 1312 DrawOut(); 1313 UGameplayStatics::PlaySound2D(GetWorld(), SoundWaveMoveFail, 0.1f); 1314 UGameplayStatics::PlaySound2D(GetWorld(), SoundWaveMove, 0.3f); 1315 return; 1316 } 1317 } 1318 } 1319 1320 void ATable::Hold() 1321 { 1322 if (bGameOver||bPause)return; 1323 if (Holding)return; 1324 Holding = true; 1325 UGameplayStatics::PlaySound2D(GetWorld(), SoundWaveHold, 0.3f); 1326 if (!HoldingType) { 1327 HoldingType = type; 1328 type = Queue.front(); 1329 Queue.pop(); 1330 AddOneInQueue(); 1331 DrawNext(); 1332 } 1333 else { 1334 HoldingType ^= type; 1335 type ^= HoldingType; 1336 HoldingType ^= type; 1337 } 1338 PutHoldBlock(2, 3, 0, HoldingType, HoldingType); 1339 for (int32 i = 1; i <= 4; i++) 1340 for (int32 j = 1; j <= 4; j++) { 1341 if (HoldBlocks[i][j] == 0)HoldBlockBody[i][j]->SetVisibility(false); 1342 else { 1343 HoldBlockBody[i][j]->SetMaterial(0, Materials[HoldBlocks[i][j]]); 1344 HoldBlockBody[i][j]->SetVisibility(true); 1345 } 1346 } 1347 PutHoldBlock(2, 3, 0, HoldingType, 0); 1348 PosX = 5, PosY = 21, face = 0; 1349 if (!Check(PosX, PosY, face, type)) { 1350 //UE_LOG(LogTemp, Warning, TEXT("BLOCKOUT!!")); 1351 GameOver(); 1352 return; 1353 } 1354 MoveDown(); 1355 //Begin to fall 1356 GetWorldTimerManager().SetTimer(TimeTick, this, &ATable::MoveDown, TimeBetweenFall, true); 1357 } 1358 1359 void ATable::Pause() 1360 { 1361 if (bGameOver) { 1362 GetWorld()->GetFirstPlayerController()->ConsoleCommand(TEXT("RestartLevel")); 1363 return; 1364 } 1365 if (!bPause) { 1366 PauseText->SetText(FText::Format(LOCTEXT("PauseText", "PAUSE"), FText::AsNumber(0))); 1367 bPause = true; 1368 GetWorldTimerManager().ClearTimer(TimeTick); 1369 GetWorldTimerManager().ClearTimer(AutoTick); 1370 GetWorldTimerManager().ClearTimer(AnimateTick); 1371 } 1372 else { 1373 PauseText->SetText(FText::Format(LOCTEXT("PauseText", ""), FText::AsNumber(0))); 1374 bPause = false; 1375 GetWorldTimerManager().SetTimer(TimeTick, this, &ATable::MoveDown, TimeBetweenFall, true); 1376 } 1377 } 1378 1379 #undef LOCTEXT_NAMESPACE
里面有许多不明所以的资源调用。。还是请主要看逻辑吧QAQ
现在想转去Unity,试试另一个玩玩,大家加油吧