• 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,试试另一个玩玩,大家加油吧

  • 相关阅读:
    ora29861:域索引标记为loading/failed/unusable(转载)
    总遇到些莫名奇妙的问题,很不爽!
    dul 10恢复oracle lob数据方法(转载)
    C#用GDAL/OGR库创建与写Shape文件(转载)
    缺陷跟踪系统Mantis之安装篇(转载)
    Oracle10g闪回恢复区详细解析(转载)
    五大最受欢迎的BUG管理系统(转载)
    使用dul恢复数据(转载)
    DUL使用(转载)
    gdul 1.0.2 使用
  • 原文地址:https://www.cnblogs.com/2017SSY/p/13782688.html
Copyright © 2020-2023  润新知