void渲染(void);/*獨特的繪圖功能*/
/*註意,這個函數重畫整個地圖,根據地圖中的格子和小方框在地圖中的中間坐標,在適當的位置畫出小方框*/
/*當然/*DOS的圖形很低,但是這裏全屏畫圖還是可以的。我用雙緩沖區來交換圖紙,這讓我感覺更好*/
void init map(void);/*初始化地圖(大框)*/
/*之前提到過這個二維數組裏有壹個1的圓防止小盒子出界,而這個就是生成這個圓的函數*/
void new game();/*創建新遊戲*/
/*此函數初始化壹個或多個時鐘,並構建第壹個下降框。當然,施工結束後,進行預覽*/
void rotateBox(int box 1[5][5],int box 2[5][5]);
/*核心函數成員,逆時針旋轉box1 90度,保存在box2 */
void rebidnext();
/*核心函數成員,生成下壹個框*/
int drop();
/*核心函數的成員,向下移動下墜框(實際上是增加下墜框的Y值)。當然需要判斷是否與地圖格子和地圖重疊,不能完成下落操作,返回0*/
void putBox();
/*在此之上,落盒和地圖是兩個獨立的維度。*/*當下落失敗時,小盒子將返回頂部再次進行下落。當這種情況發生時,原來的盒子內容當然會變成地圖上的內容。putBox就是根據XY */在地圖上寫下墜框的內容
void clear();
/*此功能在掉落失敗和putBox後執行,掃描整幅地圖*//*並去除點陣的整行。具體細節在函數*/中描述
int move(int dir);
/*左右移動下拉框,dir表示向左或向右,與drop相同*/
int test(int mx,int my,int box[5][5]);
/*這是判斷方框在MX和我的坐標中是否與地圖上的非空格子重疊的關鍵點。這是壹個非常常見的函數*/
int rotate();
/*旋轉下降盒。當然,如果旋轉後和地圖沖突,會取消旋轉,返回0,但是返回值好像沒用~ */
int new fall();
/*創建下降元素,將“下壹個”預覽的內容復制到下降框*/*並將下降框移動到地圖的頂部。當然,在這個過程中,如果頂部有沖突,它會返回0,這意味著它已滿...gameOver*/
int main();
/*最後到達主功能,在這裏可以看到整個遊戲架子*/
/*結構,包括遊戲主循環,鍵盤處理等...*/
/******************************************************\
*可變面積*
\******************************************************/
/*在上面的解釋中,可能有些忽略,因為妳可能不知道實際使用的變量*/
int map[MAX _ Y+4][MAX _ X+4];/*地圖\大框...MAX_X,Y是可視面積*/
/*我說過我們需要在外面安排兩個“警衛*/
int curbox[5][5];/*當前下落的盒子*/
int curx,cury/*保存當前活動框在地圖上的位置*/
int next box[5][5];/*容納下壹個形狀的盒子*/
/*這只是幾個方框和坐標*/
/*這裏有七個標準的俄羅斯方塊圖形格子,會復制到相應的方框*/*...:) */
Int box[MAX_C][5][5] = {/*MAX_C(7)預定義框*/
{
{0,0,0,0,0},
{0,0,0,0,0},
{1,1,1,1,0},
{0,0,0,0,0},
{0,0,0,0,0}
},
{
{0,0,0,0,0},
{0,0,1,0,0},
{0,1,1,1,0},
{0,0,0,0,0},
{0,0,0,0,0}
},
{
{0,0,0,0,0},
{0,1,1,0,0},
{0,0,1,1,0},
{0,0,0,0,0},
{0,0,0,0,0}
},
{
{0,0,0,0,0},
{0,0,1,1,0},
{0,1,1,0,0},
{0,0,0,0,0},
{0,0,0,0,0}
},
{
{0,0,0,0,0},
{0,1,1,0,0},
{0,0,1,0,0},
{0,0,1,0,0},
{0,0,0,0,0}
},
{
{0,0,0,0,0},
{0,0,1,1,0},
{0,0,1,0,0},
{0,0,1,0,0},
{0,0,0,0,0}
},
{
{0,0,0,0,0},
{0,0,1,1,0},
{0,0,1,1,0},
{0,0,0,0,0},
{0,0,0,0,0}
}
};
/******************************************************\
*時鐘*
\******************************************************/
/*時鐘部分也很好理解,壹個用來設置時鐘,壹個用來測試時鐘激活狀態*/
定時器tDown/*正常的下降定時時鐘間隔將會更大*/
定時器tFast/*按下KEY_DOWN時使用快速下降*/
int speed = 13;/*控制下降時間間隔*/
#定義快速_INTV 1 /*快速時鐘的間隔*/
Int GetTickCount() {/*讀取BIOS時鐘*/
int ret
ret = peek(0x0,0x46e);/*實際在0:046e讀取內存內容*/
ret & lt& lt= 8;/*這個地方是$ % # $ $ % &;^*/
ret += peek(0x0,0x 46c);/*新東西那麽多,找幾本書看看*/
返回(ret);
}
int setTimer(Timer *t,unsigned int intv,BOOL en) {
t->;enabled = en/*設置時鐘*/
t->;intervel = intv
t->;last time = GetTickCount();/*lasttime記錄最後的*/
/* What /*tickcount返回*/
/*因此,當再次測試時間時,新tickcount會生成它。減去最後壹次tickcount得到壹個時間間隔,可以與intervel進行比較,以確定它是否被激活*/
返回0;
}
Boolstesttimer (timer * t) {/*以上六行解釋:)*/
無符號int tmp,dt;
如果(!(t->;enabled))返回FALSE
tmp = GetTickCount();
dt = tmp-(t-& gt;last time);
if(dt & gt;= t->;intervel) {
t->;lasttime = tmp
返回TRUE
}
返回FALSE
}
void渲染(void) {
int x,y;
靜態int c page = 0;/*當前頁面,使用*/
#define STARTX 50 /*定義幾個常量*/
#定義STARTY 0
#定義鏡頭18
setactivepage(cPage=(cPage == 0?1:0));/*選擇頁面*/
clear device();/*清空屏幕*/
set color(15);
矩形(STARTX + LEN * 2 - 2,
STARTY + LEN * 3 - 2
STARTX + LEN * (MAX_X - 2) + 2,
STARTY+LEN *(MAX _ Y-2)+2);
/*用白色畫出輪廓*/
setfillstyle(SOLID_FILL,5);
for(y = 3;y & ltMAX _ Y-2;Y++) {/*畫地圖*/
for(x = 2;x & ltMAX _ X-2;x++) {
if(map[y][x]) {
矩形(x * LEN + STARTX,
y * LEN + STARTY,
x * LEN + STARTX + LEN,
y * LEN+STARTY+LEN);
bar( x * LEN + STARTX + 1,
y * LEN + STARTY + 1,
x * LEN + STARTX + LEN - 2,
y * LEN+STARTY+LEN-2);
}
}
}
/*不要把畫圖操作介紹的太復雜,只是為了寫作*/
/*在上面的段落中,根據局部地圖上的點陣將地圖反映到屏幕上*/
for(y = 0;y & lt5;Y++) {/*畫落體*/
for(x = 0;x & lt5;x++) {
if(curbox[y][x]) {
if(y+cury & gt;2) {
矩形((x + curx) * LEN + STARTX,
(y + cury) * LEN + STARTY,
(x + curx) * LEN + STARTX + LEN,
(y+cury)* LEN+STARTY+LEN);
bar((x+curx)* LEN+STARTX+1,
(y + cury) * LEN + STARTY + 1,
(x + curx) * LEN + STARTX + LEN - 2,
(y+cury)* LEN+STARTY+LEN-2);
}
}
}
}
/*根據下落框在地圖上的坐標,將下落框繪制到相應的區域*/
for(y = 0;y & lt5;Y++) {/*畫下壹個*/
for(x = 0;x & lt5;x++) {
if(nextbox[y][x]) {
矩形(x * LEN + 320,
y * LEN + 10,
x * LEN + 338,
y * LEN+28);
bar( x * LEN + 321,
y * LEN + 11,
x * LEN + 336,
y * LEN+26);
}
}
}
/*這將繪制下壹個框的預覽*/
setvisual page(c page);/*確保在頁面中繪制*/
/*展示它*/
}
/******************************************************\
*初始化部分*
\******************************************************/
/*提供newGame()來初始化新遊戲*/
Void initMap(void) {/*初始化映射*/
int x,y;/*我們需要壹圈警衛...*/
for(y = 0;y & ltMAX _ Y;y++) {
for(x = 0;x & ltMAX _ X;x++) {
if(x & lt;2 | | x & gtMAX _ X-3 | | y & gt;MAX_Y - 3)
map[y][x]= 1;
else map[y][x]= 0;
}
}/*此形狀在此處初始化*/
}/*當然沒有封面...*/
Void newGame() {/*創建新遊戲*/
int x,y;
init map();/*初始化映射*/
srand(GetTickCount());/*初始化隨機生成器*/
rebidnext();/*創建下壹個*/
setTimer(& amp;tDown,速度,1);/*開始時鐘(快速和慢速)*/
setTimer(& amp;tFast,FAST_INTV,1);
new fall();/*操作跌落箱*/
/*所以第壹個下落的方塊在地圖的頂部準備好了*/
}
/******************************************************\
*核心功能*
\******************************************************/
void rotate box(int box 1[5][5],int box2[5][5]) {
/*旋轉box1並輸出到box2*/
int x,y;
for(x = 0;x & lt5;X++) /*這個函數可能需要實際的*/
for(y = 4;y & gt= 0;Y-)/*寫出來打動*/
box 2[y][x]= box 1[x][4-y];
}
Void rebuidNext() {/* *創建下壹個形狀並將其放入nextbox */
int i,x,y;
I = random(MAX _ C);/*選擇幾個方塊中的壹個*/
for(y = 0;y & lt5;Y++) /*並復制它*/
for(x = 0;x & lt5;x++)
next box[y][x]= box[I][y][x];/*復制*/
}
Int drop() {/*行蹤,返回成功或失敗*/
int newy/*盒子將放置的新位置*/
newy = cury+1;/*是當前的Y位置+1*/
if(test(curx,newy,curbox)) {
cury = newy/*測試箱在這個位置*/
返回1;/*有沖突嗎?如果沒有,*/
}/*直接設置cury */*/
返回0;
}
Void putBox() {/*在地圖上填充邊界框*/
int x,y;
for(y = 0;y & lt5;Y++) /*這個也簡單,主要是對root */
for(x = 0;x & lt5;X++) /*根據curx,cury表示位置*/
if(curbox[y][x])
map[y+cury][x+curx]= curbox[y][x];
}
Void clear() {/*清除整行*/
/*這個函數其實效率很低,簡單來說。
從頭到尾都經過測試*/
/*具體算法是:從第0行到最後壹行,測試地圖格子是否滿,如果滿,從當前行開始,上面的地圖下降壹行*/
int x,y;
int dx,dy;
int完整標誌;
for(y = 0;y & ltMAX _ Y-2;Y++) {/*最後兩行是保留的*/
完整標誌= 1;/*假設已滿*/
for(x = 2;x & ltMAX _ X-2;X++) {/*保留列~ */
如果(!map[y][x]) {
完整標誌= 0;
打破;
}
}
If(fullflag) {/*下移壹行*/
for(dy = y;dy & gt0;dy -)
for(dx = 2;dx & ltMAX _ X-2;dx++)
map[dy][dx]= map[dy-1][dx];
for(dx = 2;dx & ltMAX _ X-2;dx++)
map[0][dx]= 0;
/*並清除第壹行*/
}
}
}
Int move(int dir) {/*返回成功或失敗*/
int newx
if(dir)newx = curx+1;
/*像drop壹樣,準備好移動的坐標*/
else newx = curx-1;
If(test(newx,cury,curbox)) {/*測試是否有沖突*/
curx = newx/*開關curx*/
返回1;
}
返回0;
}
int test(int mx,int my,int box[5][5]) {
/*測試盒子是否能降落在mx,我在地圖中的位置*/*這是最關鍵的函數,判斷是否有非空沖突*/*但是算法還是很簡單的*/
int x,y;
for(y = 0;y & lt5;y++)
for(x = 0;x & lt5;x++)
if(map[y+my][x+MX]& amp;& amp方框[y][x])
返回0;
返回1;
}
int rotate() {
int x,y;
int newbox[5][5];/*我們必須將當前框旋轉到新框*/
/*再次測試這個新盒子的沖突*/
rotateBox(curbox,new box);/*轉到新框*/
if(test(curx,cury,newbox)) {
/*並且新框可以放在地圖上不沖突*/
for(y = 0;y & lt5;y++)
for(x = 0;x & lt5;x++)
curbox[y][x]= new box[y][x];/*復制到*/
返回1;
}
否則返回0;
}
Int newfall() {/*無法創建下降元素。返回0*/
int x,y;
curx = MAX _ X/2-2;/*重新分配小方框的位置*/
cury = 0;
for(y = 0;y & lt5;y++)
for(x = 0;x & lt5;x++)
curbox[y][x]= next box[y][x];/*復制下壹個框*/
rebidnext();/*重建nextBox*/
返回測試(curx、cury、curbox);
}
/************************************************************\
*主要功能-整個遊戲架構*
\************************************************************/
int main() {
char鍵;/*記錄當前按鍵*/
int I;
int gd = VGA,gm = VGAMED/*初始化圖形模式*/
Timer * ptDown/*時鐘下降(快或慢)*/
定時器趨勢器;/*以免渲染給程序造成太大負擔*/
/*用時鐘控制渲染速度*/*設置為interval = 1,*/*所以是18 FPS,當然達不到標準的60 FPS...畢竟是DOS...*/
setTimer(& amp;趨勢者,1,1);
init graph(& amp;gd,& ampgm,“”;/*初始化圖形*/
new game();/*新遊戲...*/
While(1) {/*主遊戲循環*/
If(kbhit()) {/*如果按下鍵盤*/
key = getch();/*將鍵值讀取到key*/
}
else key = 0;
開關(鍵){/*判斷讀取鍵*/
案例索引_UP:
rotate();/*,旋轉下拉框*/
打破;
案例關鍵點_向下:
ptDown = & amptFast/*使用tFast時鐘*/
打破;
案例關鍵字_左:
移動(0);/*向左移動*/
打破;
案例關鍵字_右:
移動(1);/*向右移動*/
打破;
案例鍵_ESC:
closegraph();/*結束遊戲*/
退出(0);
默認值:
ptDown = & amptDown/*使用原始速度*/
}
If(testTimer(ptDown)) {/*已經在上面設置了行蹤。
使用的時鐘在ptDown */中
如果(!Drop()) {/* falls,0*/
putBox();/*寫在地圖上*/
clear();/*清除整行*/
如果(!Newfall()) {/*創建新的掉落,如果失敗,遊戲結束*/
closegraph();
退出(0);
}
}
}
if(testTimer(& amp;Trender)) /*最後...提供;給予...*/
render();
}
}。
/*本節目結束*/
我用Turbo C運行,因為它總是說我語法錯誤。但我就是不知道怎麽了。請幫我運行壹下,幫我看看哪裏出了問題。我非常感激!!!!謝謝妳