UE4 暂别 俄罗斯方块

在学了一小段时间的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 };
Table.h
   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
Table.cpp

里面有许多不明所以的资源调用。。还是请主要看逻辑吧QAQ

现在想转去Unity,试试另一个玩玩,大家加油吧

原文地址:https://www.cnblogs.com/2017SSY/p/13782688.html