記得8月份寫過俄羅斯方塊,那會全是用坐標表示的。包括所有方塊的變換,甚至方塊的表示。導致程序內部許多的case語句,甚為麻煩。代碼量也有近1800行左右。而且寫完后bug很多,修正也修正不完,異常頭痛便放棄了。

現在看看《編程之美》的俄羅斯方塊的思路,又想起vczh用腳本的寫的俄羅斯方塊,就又起了興趣。便重新設計完成了,這次基本沒什么bug了。只不過操作習慣上和QQ的俄羅斯方塊還有些不同。

1.       在底部的時候,如果按住旋轉不放,則會停留原地旋轉。原因是為了檢測接觸底部時旋轉不插入墻壁,就同接觸左右墻壁一樣,做了調整方塊坐標處理。處理方法是根據旋轉后方塊的坐標加上(減去)最大列(最小列)在減去(左)右邊界得到。底部也是這樣計算的。當然有了這樣的檢測便出現了這樣的小小的bug,不過我相信沒人會在底部按住不放的。

2.       這次方塊全部存儲在一個一維數組中,通過指針的變換來改變方塊種類與旋轉狀態,但是為了方便操作,就拷貝到了一個二維數組中。起初設計是一個四維數組,這樣就方便多了,但是VS2008的編譯器卻不能編譯通過,int[4][4]int **p的轉換不成功,朋友說是編譯器問題。后來經Lend3d說,很多項目都是不用大于二維的數組的,于是干脆就用了一維數組,本來要聽從他意見用結構表示一個低二位的數組元素,但是初始化和使用都不是很方便。

3.       另外關于GDI緩沖,試用了一下,但是作用貌似不大,不知道原因。關于這方面的知識援助還是要感謝HAM2008的幫助。



貼個頭文件出來就可以知道大致做法了。
#ifndef TETRIS_H
#define TETRIS_H

#pragma once

extern int Container[18][10];//容納方塊的空間
extern int current_block[4][4];

/****************************
* 方塊的主要行為
****************************
*/

class Tetris
{
public:
    Tetris();
    
~Tetris();
    
void GenerateBlock();
    
void StepLeft();
    
void StepRight();
    
void StepDown();
    
void Rotate();
    
void CaculateScore();
    
void IsOver();
public:
    
bool lost;
    
int score;//得分
    int GetX();
    
int GetY();
private:
    inline 
int CaculateMinCol();
    inline 
int CaculateMinRow();
    inline 
int CaculateMaxCol();
    inline 
int CaculateMaxRow();

    
void CaculateBlockBoundary();
    
bool DetectCollision();
    
void CopyToContainer();
    
void CopyToBlock();

    
int *block;
    
int total_rotate;
    
int kind;

    
int offset_x;
    
int offset_y;

    
int min_col,max_col;
    
int min_row,max_row;
}
;

#endif //TETRIS_H

可能自己設計上的能力還是不足吧,有些函數是不得以寫的,比如四個inline函數,因為計算的時候用的是四個循環,計算完就要跳出兩層循環。
難道用goto,如果直接return則后面的代碼執行不到了,不得以做了四個輔助函數。

源代碼下載:TetrisV1.0
可執行文件下載:TetrisV1.0.exe 如果不能運行可到微軟下載VS2008的 redist_x86