⑴ 怎樣用C語言編寫俄羅斯方塊
我的空間有個源程序,你可以去看看。
http://hi..com/lkjhggv/blog/item/d331cfa10cc1e58146106468.html
⑵ 如何用C語言編一個俄羅斯方塊
游戲界面預覽:
菜單預覽:
自定義每個小方塊顏色功能界面:
游戲主要有四部分組成:Square類,Block類,gameField類,游戲引擎
Square類:
這個類描述的對象是組成大方塊中的每個小正方形實體。
類設計:
class Square
{
public Point location; //小方塊的坐標
public Size size; //小方塊大小
public Color foreColor; //小方塊前景色
public Color backColor; //小方塊背景色
public Square(Size initSize,Color initForeColor,Color initBackColor) //構造函數
{ ……}
public void Draw(System.IntPtr winHandle) //在指定設備上畫方塊
{ …… }
public void Erase(System.IntPtr winHandle)//擦除方塊
{ …… }
}
Block類:
這個類描述的對象是某一個大方塊的實體。每個大方塊由四個小正方形組成,一共有7種組合方式。這個類需要實現一個大方塊實體所有的屬性和動作。包括:方塊的形狀,位置,方塊左移,右移,下移,旋轉等。
類設計:
class Block
{
public Square square1; //組成block的四個小方塊
public Square square2;
public Square square3;
public Square square4; private const int squareSize = GameField.SquareSize; //小方塊的邊長
public enum BlockTypes
{
undefined = 0,
square = 1,
line = 2,
J = 3,
L = 4,
T = 5,
Z = 6,
S = 7
};//一共有7種形狀
public BlockTypes blockType; //方塊的形狀
//七個小方塊的顏色數組
private Color foreColor;
private Color backColor;
//方塊的方向
public enum RotateDirections
{
North = 1,
East = 2,
South = 3,
West = 4
};
public RotateDirections myRotation = RotateDirections.North;
public Block(Point thisLocation,BlockTypes bType)
{ ……}
//含有自定義顏色的重載
public Block(Point thisLocation, BlockTypes bType,Color fc,Color bc)
{ ……} /*畫方塊*/
public void Draw(System.IntPtr winHandle)
{…… }
/*擦方塊*/
public void Erase(System.IntPtr winHandle)
{…… } /*移動*/
public bool down()
{……}
public bool left()
{……}
public bool right()
{……}
/*旋轉block*/
public void Rotate()
{……}
/*檢測是否到頂*/
public int Top()
{……}
}
GameField類:
這個類描述的對象是游戲場景實體,包括場景的背景色,大小,方塊是否還可以移動,以及場景中填滿一行的檢測等。
類設計:
class GameField
{
public const int width = 20; //場景的寬,以方塊個數為單位
public const int height = 30;
public const int SquareSize = 15; //每個四分之一小方塊的邊長
public static Color BackColor; //場景的背景色
public static System.IntPtr winHandle; //場景的handle
public static Color[] BlockForeColor ={ Color.Blue, Color.Beige, Color.DarkKhaki, Color.DarkMagenta, Color.DarkOliveGreen, Color.DarkOrange, Color.DarkRed };
public static Color[] BlockBackColor ={ Color.LightCyan, Color.DarkSeaGreen, Color.Beige, Color.Beige, Color.Beige, Color.Beige, Color.Beige };
public static bool isChanged=false; //設置是否被更改的標志位
public static SoundPlayer sound = new SoundPlayer(); //播放聲音 public static Square[,] arriveBlock = new Square[width, height]; //保存已經不能再下落了的方塊
public static int[] arrBitBlock=new int[height]; //位數組:當某個位置有方塊時,該行的該位為1
private const int bitEmpty = 0x0; //0000 0000 0000 0000 0000
private const int bitFull = 0xFFFFF; //1111 1111 1111 1111 1111 /*檢測某個位置是否為空*/
public static bool isEmpty(int x, int y)
{……}
/*將方塊停住*/
public static void stopSquare(Square sq, int x, int y)
{……}
/*檢測行是否滿
* 返回:成功消除的行數和 (方便統計分數)
*/
public static int CheckLines()
{ ……}
/*播放聲音*/
public static void PlaySound(string soundstr)
{……}
/*重畫*/
public static void Redraw()
{ …… }
//結束
}
游戲引擎:
游戲引擎正如其名,就像一個發動機一樣讓游戲不間斷運行。本游戲中就是讓方塊以一定的速度下落。並響應鍵盤事件,實行左右移動,和向下加速功能。(代碼見源碼)
聲音播放:
音效是游戲不可缺少的一部分。在.Net2.0中已經提供了一個類來播放聲音。在using System.Media;命名空間。
本游戲中播放聲音的代碼如下:(在 GameField類中)
using System.Media;
public static SoundPlayer sound = new SoundPlayer();
/*播放聲音*/
public static void PlaySound(string soundstr)
{
switch (soundstr)
{
case "FinishOneLine": //消除一行的聲音
if (!File.Exists("FinishOneLine.wav")) return;
sound.SoundLocation = "FinishOneLine.wav";
break;
case "CanNotDo": //當無法操作時
if (!File.Exists("CanNotDo.wav")) return;
sound.SoundLocation = "CanNotDo.wav";
break;
}
sound.Play();
}
要播放的時候調用PlaySound()方法即可。
其實步驟很簡單,先引用System.Media空間,然後創建一個SoundPlayer 對象,用SoundLocation 屬性設置聲音文件的地址,然後調用Play()方法即可播放。不過注意,這個類可以播放的聲音格式只有Wav文件。
保存游戲設置:
在游戲中經常要保存用戶自定義的設置。本游戲通過寫進ini文件來保存。
主要代碼如:
/*載入窗體時從配置文件Setting.ini中讀取游戲設置*/
private void getSettings()
{
if (!File.Exists("Setting.ini"))
return;
FileStream fs = new FileStream("Setting.ini", FileMode.OpenOrCreate, FileAccess.ReadWrite);
StreamReader sr = new StreamReader(fs);
string line1=sr.ReadLine();
string line2=sr.ReadLine();
string line3=sr.ReadLine();
if (line1 != null && line1.Split('=').Length > 1)
{
GameField.BackColor = Color.FromArgb(int.Parse(line1.Split('=')[1]));
picBackGround.BackColor = GameField.BackColor;
}
if (line2 != null && line2.Split('=').Length > 1)
GameField.BlockForeColor = strToColor(line2.Split('=')[1]);
if (line3 != null && line3.Split('=').Length > 1)
GameField.BlockBackColor = strToColor(line3.Split('=')[1]);
sr.Close();
fs.Close();
}
/*如果游戲設置被更改,將新的設置保存到Setting.ini*/
private void saveSettings()
{
FileStream fs = new FileStream("Setting.ini", FileMode.Create, FileAccess.ReadWrite);
StreamWriter sw = new StreamWriter(fs);
sw.WriteLine("GameFieldColor="+GameField.BackColor.ToArgb());
sw.WriteLine("BlockFroeColor=" + colorToStr(GameField.BlockForeColor));
sw.WriteLine("BlockBackColor=" + colorToStr(GameField.BlockBackColor));
sw.Flush();
sw.Close();
fs.Close();
}
要源碼+QQ348199903
⑶ 用C語言編寫的俄羅斯方塊代碼
你好。試試這個#include
#include
#include
#include
#include
#include
#include
#define ESC 0x011b
#define UP 0x4800
#define DOWN 0x5000
#define LEFT 0x4b00
#define RIGHT 0x4d00
#define SPACE 0x3920
#define Y 0x1579
#define N 0x316e
#define clearkbd(); while(bioskey(1)) bioskey(0); /*清空鍵盤緩沖隊列*/
void update();
void messagebox();
void process();
void initremove();
void initinfo();
void initbox();
void initposition();
void next_shape();
typedef struct shape /*形狀單一狀態的記錄*/
{ int attr;
int co[8];
}shape;
typedef struct RE_AB /*相對,絕對坐標記錄*/
{ int Rx,Ry;
int x1,x2,y1,y2;
}RE_AB;
RE_AB RA;
shape p[19]={ { RED,0,1,1,0,1,1,2,1 }, /*數組中保證y最大的在最後,以便initposition使用*/
{ RED,0,1,1,0,1,1,1,2 },
{ RED,0,0,1,0,2,0,1,1 },
{ RED,0,0,0,1,1,1,0,2 },
{ GREEN,0,0,1,0,2,0,3,0 },
{ GREEN,0,0,0,1,0,2,0,3 },
{ CYAN,0,0,0,1,1,0,1,1 },
{ BROWN,0,0,1,0,1,1,2,1 },
{ BROWN,1,0,0,1,1,1,0,2 },
{ BLUE,1,0,2,0,1,1,0,1 },
{ BLUE,0,0,0,1,1,1,1,2 },
{ MAGENTA,0,0,0,1,0,2,1,2 },
{ MAGENTA,2,0,0,1,1,1,2,1},
{ MAGENTA,0,0,1,0,1,1,1,2 },
{ MAGENTA,0,0,0,1,1,0,2,0 },
{ YELLOW,0,2,1,0,1,1,1,2 },
{ YELLOW,0,0,1,0,2,0,2,1 },
{ YELLOW,1,0,0,0,0,1,0,2},
{ YELLOW,0,0,0,1,1,1,2,1 },
};
int nback,nleft,nright,r_f[12][22],rs1,rs2,xcors,xcorb,ycors,ycorb;
/*檢查方快有沒有左,右,下接觸,游戲區內所有格子有無顏色記錄數組,rs1形狀記錄,rs2為提示框用,記錄小格子在游戲區中的位置,按鍵存儲*/
void interrupt (*oldint)(); /*系統定時中斷*/
int count_down=0,count_other=0; /*中斷記時*/
void interrupt newint() /*設置新的中斷程序*/
{ count_down++;
count_other++;
oldint();
}
void intenable() /*設置中斷向量表,啟動新的中斷程序*/
{ oldint=getvect(0x1c);
disable();
setvect(0x1c,newint);
enable();
}
void intrestore() /*恢復中斷向量*/
{ disable();
setvect(0x1c,oldint);
enable();
}
void HZ12(int x0,int y0,int w,int color,char *s) /*根據字模,在dos下顯示漢字*/
/*橫坐標,縱坐標,字間隔,漢字顏色,漢字字元串*/
{ FILE *fp;
register char buffer[24];
register char str[2];
unsigned long fpos;/*fpos為最終偏移動量*/
register int i,j,k;
fp=fopen(hzk12,r);/*打開12*12漢字苦*/
while(*s)/*一直到字元串結束為止*/
{
if(*s<0)/*漢字輸出*/
{ str[0]=(*s)-0xa0;
str[1]=*(s+1)-0xa0;
fpos=((str[0]-1)*94+(str[1]-1))*24L;/*計算漢字在hzk12的偏移量*/
fseek(fp,fpos,SEEK_SET);/*指針移動到當前位置*/
fread(buffer,24,1,fp);/*讀取一個漢字到數組中*/
for(i=0;i<12;i++)/*12行*/
for(j=0;j<2;j++)/*兩個位元組*/
for(k=0;k<8;k++)/*8位*/
if (((buffer[i*2+j]>>(7-k))&0x1)!=NULL)/*是一就畫點*/
putpixel(x0+8*j+k,y0+i,color);
s+=2;/*一個漢字占兩個位元組,現在將指針移動兩個位元組*/
x0+=w;/*顯示坐標也按照間隔移動*/
}
else/*顯示非漢字字元*/
{ settextstyle(0,0,1);
setcolor(color);
str[0]=*s;str[1]=0;
outtextxy(x0,y0+3,str);/*顯示單個字元*/
x0+=w-7;/*顯示單個字元後的x坐標變化*/
s++;/*指針移動到下一個位元組*/
}
}
fclose(fp);
}
void translation() /*把相對坐標解釋為絕對坐標*/
{ if(RA.Rx==1)
{ RA.x1=1; RA.x2=16; }
else
{ RA.x1=16*(RA.Rx-1); RA.x2=16*RA.Rx; }
if(RA.Ry==1)
{ RA.y1=1; RA.y2=16; }
else
{ RA.y1=16*(RA.Ry-1); RA.y2=16*RA.Ry; }
}
int check_b() /*檢查是否到達低部*/
{ int x,y,i,zf=0; /*zf為是否有顏色填充記錄*/
for(i=0;i<7;i++,i++)
{ x=RA.Rx+p[rs1].co[i];
y=RA.Ry+p[rs1].co[i+1];
if(y>=6)
zf+=r_f[x-15][y-6+1];
}
if(zf==0)
return 1;
else
return 0;
}
int finish()
{ int tfull=0,i; /*判斷頂層空間是否有填充*/
for(i=1;i<11;i++)
tfull+=r_f[i][1];
if(tfull!=0)
return 1; /*告訴judge()可以結束了*/
}
int check_l() /*檢查形狀是否與左接觸*/
{ int x,y,i,zf=0;
for(i=0;i<7;i++,i++)
{ x=RA.Rx+p[rs1].co[i];
y=RA.Ry+p[rs1].co[i+1];
if(y>6)
zf+=r_f[x-15-1][y-6];
if(y<=6&&x==16)
zf+=1;
}
if(zf==0)
return 1;
else
return 0;
}
int check_r() /*檢查形狀是否與右接觸*/
{ /*zf為是否有顏色填充記錄*/
int x,y,i,zf=0; /*zf為是否有顏色填充記錄*/
for(i=0;i<7;i++,i++)
{
x=RA.Rx+p[rs1].co[i];
y=RA.Ry+p[rs1].co[i+1];
if(y>6)
zf+=r_f[x-15+1][y-6];
if(y<=6&&x==25)
zf+=1;
}
if(zf==0)
return 1;
else
return 0;
}
void check_touch()
{ nback=check_b();
nleft=check_l();
nright=check_r();
}
void draw(int cb) /*畫形狀,cb=1以填充色畫形狀,cb=2以背景色畫形狀,cb=3以白色畫形狀*/
{ int i,recordx=RA.Rx,recordy=RA.Ry;
for(i=0;i<7;i++,i++)
{ RA.Rx+=p[rs1].co[i];
RA.Ry+=p[rs1].co[i+1];
if(RA.Ry<=6)
{ RA.Rx=recordx;
RA.Ry=recordy;
continue;
}
translation();
if(cb==1)
setfillstyle(1,p[rs1].attr);
else
if(cb==2)
setfillstyle(1,BLACK);
else
if(cb==3)
{ setfillstyle(1,WHITE);
r_f[RA.Rx-15][RA.Ry-6]=1; /*置對應數組標記元素*/
}
bar(RA.x1+1,RA.y1+1,RA.x2-1,RA.y2-1);
RA.Rx=recordx;
RA.Ry=recordy;
}
}
void mov(int key) /*向下,左,右移動方塊*/
{ draw(2);
if(key==LEFT&&nleft)
RA.Rx--;
else
if(key==RIGHT&&nright)
RA.Rx++;
else
RA.Ry++;
nback=check_b();
if(nback) /*判斷形狀有沒有到達底部,有就將其顏色變為白色*/
draw(1);
else
draw(3);
}
void change() /*變換形狀*/
{ int status=rs1,buffer,i,x,y,zf=0;
if(p[rs1].attr==p[rs1+1].attr)
rs1++;
else
while(p[rs1].attr==p[rs1-1].attr)
rs1--;
for(i=0;i<7;i++,i++) /*檢查變化形狀後是否與已存形狀發生沖突*/
{ x=RA.Rx+p[rs1].co[i];
y=RA.Ry+p[rs1].co[i+1];
if(y>6)
zf+=r_f[x-15][y-6];
}
if(zf!=0)
rs1=status;
buffer=rs1;
rs1=status;
status=buffer;
draw(2);
buffer=rs1;
rs1=status;
status=buffer;
nback=check_b(); /*判斷變化後的形狀是不是到達了低部,這個檢查是十分必要的*/
if(nback)
draw(1);
else
draw(3);
}
void accelerate()
{ if(count_down>=1)
{ check_touch(); /*消除上一步動作對方塊狀態的影響*/
count_down=0;
if(nback) /*0表示到達底部,1表示沒有到達*/
mov(DOWN);
}
}
void drawbox() /*畫方塊所在方框*/
{ int xcor,ycor;
for(xcor=xcors;xcor<=xcorb;xcor++)
for(ycor=ycors;ycor<=ycorb;ycor++)
{ if(xcor==xcors||xcor==xcorb||ycor==ycors||ycor==ycorb)
{ RA.Rx=xcor;
RA.Ry=ycor;
translation();
setfillstyle(1,DARKGRAY);
bar(RA.x1+1,RA.y1+1,RA.x2-1,RA.y2-1);
}
}
}
void erasure(int k)
{ int i,j,recordx=RA.Rx,recordy=RA.Ry;
{ j=k-1;
for(;j>0;j--)
{ for(i=1;i<11;i++)
{ r_f[i][j+1]=r_f[i][j];
RA.Rx=i+15;
RA.Ry=j+1+6;
translation();
if(r_f[i][j+1]==1)
setfillstyle(1,WHITE);
else
setfillstyle(1,BLACK);
bar(RA.x1+1,RA.y1+1,RA.x2-1,RA.y2-1);
RA.Rx=recordx;
RA.Ry=recordy;
}
}
}
}
void pause()
{ HZ12(450,400,15,BLACK,正常);
HZ12(450,400,15,GREEN,暫停);
for(;;)
if(bioskey(1)&&bioskey(0)==SPACE)
{ clearkbd();
HZ12(450,400,15,BLACK,暫停);
HZ12(450,400,15,RED,正常);
return;
}
}
void judge()
{ int i,j,full=0; /*full等於10說明某一行滿,該消除了*/
if(finish()) /*判斷游戲是否該結束了*/
messagebox(); /*win編程里有這個函數*/
for(j=1;j<21;j++) /*判斷某一行是否滿了*/
{ for(i=1;i<11;i++)
full+=r_f[i][j];
if(full==10)
erasure(j); /*消除這行*/
full=0;
}
}
void update() /*使程序可以重新運行*/
{ cleardevice();
setbkcolor(BLACK);
initinfo(); /*提示信息初始化*/
initbox(); /*游戲框架初始化*/
srand((unsigned)time(NULL)); /*隨機器函數的初始化*/
rs1=random(19);
rs2=random(19);
next_shape();
initposition(); /*方塊最開始的出現位置*/
initremove(); /*記錄每個方格有無顏色填充數組初始化*/
HZ12(450,400,15,RED,正常);
process();
}
void EXIT()
{ closegraph();
intrestore(); /*恢復中斷向量*/
exit(0);
}
void initremove()
{ int i,j;
for(i=0;i<12;i++)
for(j=0;j<22;j++)
if(i==0||i==11||j==0||j==21)
r_f[i][j]=1;
else
r_f[i][j]=0;
}
void initinfo()
{ char aStr[2];
setcolor(RED);
outtextxy(450,100,This game's writer is:);
HZ12(450,140,15,RED,該程序作者:NULL);
outtextxy(525,110,NULL);
outtextxy(450,180,FUNCTION FOR KEYS:);
outtextxy(450,200,UP:change the shape);
outtextxy(450,210,DOWN:accelerate);
outtextxy(450,220,LEFT:move left);
outtextxy(450,230,RIGHT:move right);
outtextxy(450,240,ESC:exit this game);
outtextxy(450,250,SPACE:pause);
HZ12(450,260,20,RED,上:);
HZ12(450,280,20,RED,下:);
HZ12(450,300,20,RED,左:);
HZ12(450,320,20,RED,右:);
HZ12(450,340,20,RED,ESC:退出);
HZ12(450,360,15,RED,空格: 暫停/開始);
HZ12(450,380,15,RED,目前狀態:);
HZ12(20,200,15,RED,下一個形狀);
aStr[0]=24;
aStr[1]=0;
aStr[6]=0;
HZ12(480,260,12,GREEN,aStr);
HZ12(500,260,12,GREEN,( 變形 ));
aStr[0]=25;
aStr[1]=0;
HZ12(480,280,12,GREEN,aStr);
HZ12(500,280,12,GREEN,( 加速 ));
aStr[0]=27;
aStr[1]=0;
HZ12(480,300,12,GREEN,aStr);
HZ12(500,300,12,GREEN,向左);
aStr[0]=26;
aStr[1]=0;
HZ12(480,320,12,GREEN,aStr);
HZ12(500,320,12,GREEN,向右);
}
void messagebox()
{ int key;
setcolor(GREEN);
setfillstyle(1,DARKGRAY);
rectangle(220,200,420,300);
bar(221,201,419,299);
HZ12(280,210,15,GREEN,GAME OVER);
HZ12(275,230,15,GREEN,重新游戲: Y);
HZ12(275,270,15,GREEN,退出遊戲: N);
HZ12(450,400,15,BLACK,正常);
HZ12(450,400,15,GREEN,GAME OVER);
for(;;)
if(bioskey(1))
{ key=bioskey(0);
if(key==Y)
{ clearkbd();
update();
}
else
if(key==N)
{ clearkbd();
EXIT();
}
else
clearkbd();
}
}
void initbox()
{ xcors=15; /*畫游戲框*/
xcorb=26;
ycors=6;
ycorb=27;
drawbox();
xcors=2; /*畫提示框*/
xcorb=7;
ycors=6;
ycorb=11;
drawbox();
}
void initposition()
{ RA.Rx=18;
RA.Ry=6-p[rs1].co[7];;
RA.x1=0;
RA.x2=0;
RA.y1=0;
RA.y2=0;
}
void next_shape() /*畫下一形狀提示框*/
{ int recordx=RA.Rx,recordy=RA.Ry,buffer;
RA.Rx=3;
RA.Ry=7;
draw(2);
buffer=rs1;
rs1=rs2;
rs2=buffer;
draw(1);
RA.Rx=recordx;
RA.Ry=recordy;
buffer=rs1;
rs1=rs2;
rs2=buffer;
}
void process() /*游戲過程*/
{ for(;;)
{ check_touch();
if(!nback)
{ rs1=rs2;
rs2=random(19); /*產生另一種方塊的碼數*/
initposition();
judge(); /*判斷某一行是否滿了和這個游戲是否可以結束了*/
draw(1);
next_shape();
}
if(count_other>=1)
{ count_other=0;
if(bioskey(1)) /*對按鍵的處理*/
{ int key=bioskey(0);
clearkbd(); /*清除鍵盤緩沖隊列*/
if(key==ESC)
EXIT();
if(key==LEFT&&nleft&&nback)
mov(LEFT);
if(key==RIGHT&&nright&&nback)
mov(RIGHT);
if(key==UP&&nback)
change();
if(key==SPACE)
pause();
if(key==DOWN)
accelerate();
}
}
if(count_down>=4)
{ check_touch(); /*消除上一步動作對方塊狀態的影響*/
count_down=0;
if(nback) /*0表示到達底部,1表示沒有到達*/
mov(DOWN);
}
}/*for*/
}
main()
{ int gdriver=DETECT,gmode=0;
initgraph(&gdriver,&gmode,d:turboc); /*啟動圖形與中斷部分*/
intenable();
update();
}
⑷ 請教如何用C語言寫個俄羅斯方塊
游戲界面預覽: 菜單預覽: 自定義每個小方塊顏色功能界面: 游戲主要有四部分組成:Square類,Block類,gameField類,游戲引擎 Square類: 這個類描述的對象是組成大方塊中的每個小正方形實體。
⑸ 怎樣用c語言編寫俄羅斯方塊程序
俄羅斯方塊C源代碼
#include<stdio.h>
#include<windows.h>
#include<conio.h>
#include<time.h>
#defineZL4 //坐標增量,不使游戲窗口靠邊
#defineWID36 //游戲窗口的寬度
#defineHEI20 //游戲窗口的高度
inti,j,Ta,Tb,Tc; //Ta,Tb,Tc用於記住和轉換方塊變數的值
inta[60][60]={0}; //標記游戲屏幕各坐標點:0,1,2分別為空、方塊、邊框
intb[4]; //標記4個"口"方塊:1有,0無,類似開關
intx,y,level,score,speed; //方塊中心位置的x,y坐標,游戲等級、得分和游戲速度
intflag,next; //當前要操作的方塊類型序號,下一個方塊類型序號
voidgtxy(intm,intn); //以下聲明要用到的自編函數
voidgflag(); //獲得下一方塊序號
voidcsh(); //初始化界面
voidstart(); //開始部分
voidprfk(); //列印方塊
voidclfk(); //清除方塊
voidmkfk(); //製作方塊
voidkeyD(); //按鍵操作
intifmov(); //判斷方塊能否移動或變體
void clHA(); //清除滿行的方塊
voidclNEXT(); //清除邊框外的NEXT方塊
intmain()
{csh();
while(1)
{start();//開始部分
while(1)
{prfk();
Sleep(speed); //延時
clfk();
Tb=x;Tc=flag;//臨存當前x坐標和序號,以備撤銷操作
keyD();
y++;//方塊向下移動
if(ifmov()==0){y--;prfk();dlHA();break;}//不可動放下,刪行,跨出循環
}
for(i=y-2;i<y+2;i++){if(i==ZL){j=0;}} //方塊觸到框頂
if(j==0){system("cls");gtxy(10,10);printf("游戲結束!");getch();break;}
clNEXT(); //清除框外的NEXT方塊
}
return0;
}
voidgtxy(intm,intn)//控制游標移動
{COORDpos;//定義變數
pos.X=m;//橫坐標
pos.Y=n;//縱坐標
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);
}
voidcsh()//初始化界面
{gtxy(ZL+WID/2-5,ZL-2);printf("俄羅斯方塊");//列印游戲名稱
gtxy(ZL+WID+3,ZL+7);printf("*******NEXT:");//列印菜單信息
gtxy(ZL+WID+3,ZL+13);printf("**********");
gtxy(ZL+WID+3,ZL+15);printf("Esc:退出遊戲");
gtxy(ZL+WID+3,ZL+17);printf("↑鍵:變體");
gtxy(ZL+WID+3,ZL+19);printf("空格:暫停游戲");
gtxy(ZL,ZL);printf("╔");gtxy(ZL+WID-2,ZL);printf("╗");//列印框角
gtxy(ZL,ZL+HEI);printf("╚");gtxy(ZL+WID-2,ZL+HEI);printf("╝");
a[ZL][ZL+HEI]=2;a[ZL+WID-2][ZL+HEI]=2;//記住有圖案
for(i=2;i<WID-2;i+=2){gtxy(ZL+i,ZL);printf("═");}//列印上橫框
for(i=2;i<WID-2;i+=2){gtxy(ZL+i,ZL+HEI);printf("═");a[ZL+i][ZL+HEI]=2;}//下框
for(i=1;i<HEI;i++){gtxy(ZL,ZL+i);printf("║");a[ZL][ZL+i]=2;}//左豎框記住有圖案
for(i=1;i<HEI;i++){gtxy(ZL+WID-2,ZL+i);printf("║");a[ZL+WID-2][ZL+i]=2;}//右框
CONSOLE_CURSOR_INFOcursor_info={1,0};//以下是隱藏游標的設置
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cursor_info);
level=1;score=0;speed=400;
gflag();flag=next;//獲得一個當前方塊序號
}
voidgflag() //獲得下一個方塊的序號
{srand((unsigned)time(NULL));next=rand()%19+1; }
voidstart()//開始部分
{gflag();Ta=flag;flag=next;//保存當前方塊序號,將下一方塊序號臨時操作
x=ZL+WID+6;y=ZL+10;prfk();//給x,y賦值,在框外列印出下一方塊
flag=Ta;x=ZL+WID/2;y=ZL-1;//取回當前方塊序號,並給x,y賦值
}
voidprfk()//列印俄羅斯方塊
{for(i=0;i<4;i++){b[i]=1;}//數組b[4]每個元素的值都為1
mkfk();//製作俄羅斯方塊
for(i=x-2;i<=x+4;i+=2)//列印方塊
{for(j=y-2;j<=y+1;j++){if(a[i][j]==1&&j>ZL){gtxy(i,j);printf("□");}}}
gtxy(ZL+WID+3,ZL+1); printf("level:%d",level); //以下列印菜單信息
gtxy(ZL+WID+3,ZL+3); printf("score:%d",score);
gtxy(ZL+WID+3,ZL+5); printf("speed:%d",speed);
}
voidclfk()//清除俄羅斯方塊
{for(i=0;i<4;i++){b[i]=0;}//數組b[4]每個元素的值都為0
mkfk();//製作俄羅斯方塊
for(i=x-2;i<=x+4;i+=2)//清除方塊
{for(j=y-2;j<=y+1;j++){if(a[i][j]==0&&j>ZL){gtxy(i,j);printf("");}}}
}
voidmkfk()//製作俄羅斯方塊
{a[x][y]=b[0];//方塊中心位置狀態:1-有,0-無
switch(flag)//共6大類,19種小類型
{case1:{a[x][y-1]=b[1];a[x+2][y-1]=b[2];a[x+2][y]=b[3];break;}//田字方塊
case2:{a[x-2][y]=b[1];a[x+2][y]=b[2];a[x+4][y]=b[3];break;}//直線方塊:----
case3:{a[x][y-1]=b[1];a[x][y-2]=b[2];a[x][y+1]=b[3];break;}//直線方塊:|
case4:{a[x-2][y]=b[1];a[x+2][y]=b[2];a[x][y+1]=b[3];break;}//T字方塊
case5:{a[x][y-1]=b[1];a[x][y+1]=b[2];a[x-2][y]=b[3];break;}//T字順時針轉90度
case6:{a[x][y-1]=b[1];a[x-2][y]=b[2];a[x+2][y]=b[3];break;}//T字順轉180度
case7:{a[x][y-1]=b[1];a[x][y+1]=b[2];a[x+2][y]=b[3];break;}//T字順轉270度
case8:{a[x][y+1]=b[1];a[x-2][y]=b[2];a[x+2][y+1]=b[3];break;}//Z字方塊
case9:{a[x][y-1]=b[1];a[x-2][y]=b[2];a[x-2][y+1]=b[3];break;}//Z字順轉90度
case10:{a[x][y-1]=b[1];a[x-2][y-1]=b[2];a[x+2][y]=b[3];break;}//Z字順轉180度
case11:{a[x][y+1]=b[1];a[x+2][y-1]=b[2];a[x+2][y]=b[3];break;}//Z字順轉270度
case12:{a[x][y-1]=b[1];a[x][y+1]=b[2];a[x-2][y-1]=b[3];break;}//7字方塊
case13:{a[x-2][y]=b[1];a[x+2][y-1]=b[2];a[x+2][y]=b[3];break;}//7字順轉90度
case14:{a[x][y-1]=b[1];a[x][y+1]=b[2];a[x+2][y+1]=b[3];break;}//7字順轉180度
case15:{a[x-2][y]=b[1];a[x-2][y+1]=b[2];a[x+2][y]=b[3];break;}//7字順轉270度
case16:{a[x][y+1]=b[1];a[x][y-1]=b[2];a[x+2][y-1]=b[3];break;}//倒7字方塊
case17:{a[x-2][y]=b[1];a[x+2][y+1]=b[2];a[x+2][y]=b[3];break;}//倒7字順轉90度
case18:{a[x][y-1]=b[1];a[x][y+1]=b[2];a[x-2][y+1]=b[3];break;}//倒7字順轉180度
case19:{a[x-2][y]=b[1];a[x-2][y-1]=b[2];a[x+2][y]=b[3];break;}//倒7字順轉270度
}
}
voidkeyD()//按鍵操作
{if(kbhit())
{intkey;
key=getch();
if(key==224)
{key=getch();
if(key==75){x-=2;}//按下左方向鍵,中心橫坐標減2
if(key==77){x+=2;}//按下右方向鍵,中心橫坐標加2
if(key==72)//按下向上方向鍵,方塊變體
{if(flag>=2&&flag<=3){flag++;flag%=2;flag+=2;}
if(flag>=4&&flag<=7){flag++;flag%=4;flag+=4;}
if(flag>=8&&flag<=11){flag++;flag%=4;flag+=8;}
if(flag>=12&&flag<=15){flag++;flag%=4;flag+=12;}
if(flag>=16&&flag<=19){flag++;flag%=4;flag+=16;}}
}
if(key==32)//按空格鍵,暫停
{prfk();while(1){if(getch()==32){clfk();break;}}} //再按空格鍵,繼續游戲
if(ifmov()==0){x=Tb;flag=Tc;} //如果不可動,撤銷上面操作
else{prfk();Sleep(speed);clfk();Tb=x;Tc=flag;} //如果可動,執行操作
}
}
intifmov()//判斷能否移動
{if(a[x][y]!=0){return0;}//方塊中心處有圖案返回0,不可移動
else{if((flag==1&&(a[x][y-1]==0&&a[x+2][y-1]==0&&a[x+2][y]==0))||
(flag==2&&(a[x-2][y]==0&&a[x+2][y]==0&&a[x+4][y]==0))||
(flag==3&&(a[x][y-1]==0&&a[x][y-2]==0&&a[x][y+1]==0))||
(flag==4&&(a[x-2][y]==0&&a[x+2][y]==0&&a[x][y+1]==0))||
(flag==5&&(a[x][y-1]==0&&a[x][y+1]==0&&a[x-2][y]==0))||
(flag==6&&(a[x][y-1]==0&&a[x-2][y]==0&&a[x+2][y]==0))||
(flag==7&&(a[x][y-1]==0&&a[x][y+1]==0&&a[x+2][y]==0))||
(flag==8&&(a[x][y+1]==0&&a[x-2][y]==0&&a[x+2][y+1]==0))||
(flag==9&&(a[x][y-1]==0&&a[x-2][y]==0&&a[x-2][y+1]==0))||
(flag==10&&(a[x][y-1]==0&&a[x-2][y-1]==0&&a[x+2][y]==0))||
(flag==11&&(a[x][y+1]==0&&a[x+2][y-1]==0&&a[x+2][y]==0))||
(flag==12&&(a[x][y-1]==0&&a[x][y+1]==0&&a[x-2][y-1]==0))||
( flag==13 && ( a[x-2][y]==0 && a[x+2][y-1]==0 && a[x+2][y]==0 ) ) ||
( flag==14 && ( a[x][y-1]==0 && a[x][y+1]==0 && a[x+2][y+1]==0 ) ) ||
(flag==15 && ( a[x-2][y]==0 && a[x-2][y+1]==0 && a[x+2][y]==0 ) ) ||
(flag==16 && ( a[x][y+1]==0 && a[x][y-1]==0 && a[x+2][y-1]==0 ) ) ||
( flag==17 && ( a[x-2][y]==0 && a[x+2][y+1]==0 && a[x+2][y]==0 ) ) ||
(flag==18 && ( a[x][y-1]==0 &&a[x][y+1]==0 && a[x-2][y+1]==0 ) ) ||
(flag==19 && ( a[x-2][y]==0 && a[x-2][y-1]==0
&&a[x+2][y]==0))){return1;}
}
return0; //其它情況返回0
}
voidclNEXT() //清除框外的NEXT方塊
{flag=next;x=ZL+WID+6;y=ZL+10;clfk();}
void clHA() //清除滿行的方塊
{intk,Hang=0; //k是某行方塊個數,Hang是刪除的方塊行數
for(j=ZL+HEI-1;j>=ZL+1;j--)//當某行有WID/2-2個方塊時,則為滿行
{k=0;for(i=ZL+2;i<ZL+WID-2;i+=2)
{if(a[i][j]==1)//豎坐標從下往上,橫坐標由左至右依次判斷是否滿行
{k++; //下面將操作刪除行
if(k==WID/2-2) { for(k=ZL+2;k<ZL+WID-2;k+=2)
{a[k][j]=0;gtxy(k,j);printf("");Sleep(1);}
for(k=j-1;k>ZL;k--)
{for(i=ZL+2;i<ZL+WID-2;i+=2)//已刪行數上面有方塊,先清除再全部下移一行
{if(a[i][k]==1){a[i][k]=0;gtxy(i,k);printf("");a[i][k+1]=1;
gtxy(i,k+1);printf("□");}}
}
j++;//方塊下移後,重新判斷刪除行是否滿行
Hang++;//記錄刪除方塊的行數
}
}
}
}
score+=100*Hang; //每刪除一行,得100分
if(Hang>0&&(score%500==0||score/500>level-1)) //得分滿500速度加快升一級
{speed-=20;level++;if(speed<200)speed+=20; }
}
⑹ 一個簡單的c語言寫的俄羅斯方塊程序
1、考慮怎麼存儲俄羅斯方塊
俄羅斯方塊的形狀一共有19種類型,如果拿數組來表示的話,可能會比較會浪費空間(網上有很多實現代碼)
考慮到每種方塊形狀的范圍是4 *4的小方塊,用 字模點陣的方式來存儲,即設置一個4行4列的數組,元素置1即代表這個位置有小
方塊,元素置0即代表這個位置無小方塊,這個整個的4*4的數組組成俄羅斯方塊的形狀。
1000
1000
1100
0000
上述4*4來表示L形狀的方塊。
4*4 =16 bit 正好為short類型,所以每一個方塊可以用一個short類型的數據來表示。
我們把俄羅斯方塊點陣的數位存在rockArray中,我們可以事先把這19種方塊的字模點陣自己轉化成十六進制,然後在rockArray數組的初始化時賦值進去。
但是這種方式擴展性不好,每當有一種新方塊時需要改動,
所以可以寫一個配置文件來表示19種方塊。(RockShape.ini)
@###@###@@######1234
從配置文件中讀取方塊的類型的代碼在(Init.h的ReadRock函數中)在下面3中解釋下代碼如何實現
2如何畫出方塊
可以使用EasyX庫來畫出簡單的圖形,
EasyX庫是在VC下實現TC的簡單繪圖功能的一個庫,這個庫很容易學會(直接 網路EasyX庫,裡面有詳細的教程)
那麼如何畫出方塊,方塊已經存儲到一個short類型中了
從short中讀取出,可以用一個掩碼mask = 1來與short的每個bit位相與,結果為1,則畫出一個小方塊;
函數聲明:
void DisplayRock(int rockIdx, RockLocation_t* LocatePtr, bool displayed)1
參數1:表示在數組中的下標,取出short類型的方塊表示數據
參數2:表示當前坐標,即畫出方塊的左上角的坐標x,y
參數3:true表示畫出該方塊,false 表示擦除該方塊。
//方塊在圖形窗口中的位置(即定位4*4大塊的左上角坐標) typedef struct LOCATE
{ int left; int top;
} RockLocation_t;123456
3如何實現同一種類型方塊的翻轉,
在按『↑』時應該翻轉同一種類型的方塊,
比如下面的橫桿和豎桿
@###@###@###@###@@@@############****1234567891011
可以假想成靜態循環鏈表來實現這種方式
使同一種類型的方塊循環起來,
用一個struct結構來表示一種方塊
typedef struct ROCK
{ //用來表示方塊的形狀(每一個位元組是8位,用每4位表示方塊中的一行)
unsigned short rockShapeBits; int nextRockIndex; //下一個方塊,在數組中的下標 } RockType;123456
定義一個RockType類型的數組來存儲19種方塊
RockType RockArray[19] = { (0, 0) };
當我們按「↑」時,把傳入畫方塊函數DrawRock中的rockIndex變為當前方塊結構體中的nextRockIndex即可。
簡單解釋下ReadRock函數的實現:當讀取到空行的時候表示 一種方塊已經讀取完畢,當讀取到****行時 表示同一種類型的方塊讀取完畢,具體看代碼實現,代碼中具體的注釋
4、主要游戲實現的邏輯
貼一個預覽圖吧
註:上述預覽圖的游戲控制區和游戲顯示區在Draw.h的DrawGameWindow()函數實現的
(1)在初始位置畫出方塊,在預覽區畫出下一次的方塊
(2)方塊有兩種行為:響應鍵盤命令UserHitKeyBoard(),自由下落
如果敲擊鍵盤了(w ,a ,s ,d, )空格表示暫停,如果在規定時間內沒有敲擊鍵盤的話,方塊自由下落一個單位
if (kbhit()) //如果敲擊鍵盤了 就處理按鍵
{
userHit = getch();
UserHitKeyBoard(userHit, &curRockIndex, &curRockLocation);
} //沒有 就自動下移一個單位 :不能用else,因為可能按鍵不是上下左右
DWORD newtime = GetTickCount(); if (newtime - oldtime >= (unsigned int)(300) && moveAbled == TRUE)
{
oldtime = newtime;
DisplayRock(curRockIndex, &curRockLocation, false);
curRockLocation.top += ROCK_SQUARE_WIDTH; //下落一格
}1234567891011121314
(3)當方塊落地(即不能下移了)時,判斷是否滿行,如果滿行則消除,然後再判斷游戲是否結束,游戲結束的話,直接退出遊戲
判斷滿行:FullLine()函數,從最底下的一行開始判斷,直到遇到一行空行,
while (count != xROCK_SQUARE_NUM ) //遇到空行 14
{
linefull = true; count = 0; for (int i = 1; i <= xROCK_SQUARE_NUM; ++i)
{ if (game_board[idx][i] == 0)
{
linefull = false; count++;
}
} if (linefull) //滿行,消除當前行,更新分數
{
DelCurLine(idx);//消除滿行
game_socres += 3;
UpdateSocres(game_socres);
idx++;//因為下面要減1
}
idx--;
}
(4)消除滿行
將要刪除的滿行擦除:即將方塊化成與背景色相同的,該代碼為黑色
然後將上面的一行向下移,移一行刪除一行,直到遇到空行
具體看代碼的具體實現 game.h
void DelCurLine(int rowIdx)
(4)判斷方塊是否能移動
在game.h中實現
bool MoveAble(int rockIndex, RockLocation_t* currentLocatePtr, int f_direction)1
**比較當前位置的坐標(左上角)開始,能否放下rockIndex的方塊。
註:f_direction為」↑」的話,則傳入的rockIndex為下一個方塊**
如果不能移動的話,給游戲game_board設置標記表示該位置被佔有
//全局變數-游戲板的狀態描述(即表示當前界面哪些位置有方塊) //0表示沒有,1表示有(多加了兩行和兩列,形成一個圍牆,便於判斷方塊是否能夠移動) int game_board[yROCK_SQUARE_NUM + 2][xROCK_SQUARE_NUM + 2] = { 0 };123
實現過程遇到的一些問題
(1)在快速下落的時候,可能方塊會掉出圍牆的范圍內,
快速下落是使方塊每次下落2個單位距離。
在判斷不能下落時,使當前坐標的top即y減去一個單位的距離
(2)遇到多行滿行時消除不了,
在判斷滿行時,循環找出滿行,找出一個滿行,就消除一行,然後繼續判斷是否滿行,直到遇到空行
⑺ 用c語言編寫俄羅斯方塊的程序
這里把游戲的關鍵設計放在三個盒子和一個坐標上:
大盒子:一個兩維數組,記錄著方塊點陣的開與關(把游戲的舞台想像
成一個點陣),在下面也把這個東西稱為地圖
兩個5*5小盒子:兩維數組,一個盛放著正在下落的方塊,一個盛放在
下一個下落的方塊(即next),當然這兩個也必須想像成一個點陣:如長條
的點陣為:
00000
00100
00100
00100
00100
現在你只要有這么一個概念:一個不斷定時下落的小盒子從大盒子頂
部下降到底部,之後再將next盒子放在下落盒子,再進行下一輪的下落...
中間的控制等尚不要太著急.
現在面臨著一個問題:
下落的盒子和地圖之間要怎麼聯系起來?
一個好的方法是再定義一個坐標:x,y,保存著小盒子左上角在地圖上對應
的下標(位置),即當x
=
0,
y
=
0時,小盒子處於地圖的左上部.如此,當
小盒子需要移動時,即只須要改變x,y的值.
現在說說旋轉.
小盒子保存著當前下落形狀的點陣,那麼旋轉就只須要將這個點陣旋
轉90度:例如:
00000
00000
00100
00000
00100
->
01111
00100
00000
00100
00000
這一點實現起來還是不太難的.
判斷碰撞
通常這種情況只須要在有移動小盒或旋轉盒子時發生:也即點陣非空
是互斥的,當小盒要向下移(x++)時,如果小盒裡的點陣與地圖上的點陣(非
空的地方)重疊,則不能下移,(卡住了),旋轉則轉換後的形狀與地圖有沖
突則要放棄旋轉.
到了這里,你應該有一個大概的了解了,至於怎樣在屏幕上畫出來,這
個是比較簡單的,下面的代碼會慢慢與你解釋.
*/
/*接下一貼*/
⑻ 求一個簡單的c語言寫的俄羅斯方塊程序
剛學c的時候編的,所以程序規范性以及代碼的執行效率都不高,而且程序超長。但應該沒有太難的語句。
#include<stdio.h>
#include<string.h>
#include<bios.h>
#include<stdlib.h>
#include<time.h>
#include<dos.h>
int dx[4],dy[4]; /*定義全局變數*/
int zt1,zt2,str[15][19];
/*str[15][19]是把整個屏幕分為15*19個方格,每一個方格用一個數組單元表示,
如果=15,則這個方格已被佔用,=0,則還是空的*/
int cx[8][5][4],cy[8][5][4]; /*該變數表示每種狀態下,旋轉時坐標的改變*/
int x,y,j,ji,c;
int maxzt[8]=; /*各個種類的方塊分別有幾種狀態*/
cir() /*旋轉的處理函數*/
{ dx[0]=dx[0]+cx[zt1][zt2][0];dy[0]=dy[0]+cy[zt1][zt2][0];
dx[2]=dx[2]+cx[zt1][zt2][2];dy[2]=dy[2]+cy[zt1][zt2][2];
dx[3]=dx[3]+cx[zt1][zt2][3];dy[3]=dy[3]+cy[zt1][zt2][3];
}
jiance() /*檢測旋轉或移動能否進行的函數,能則j=1,不能j=0*/
{ j=1;
for(ji=0;ji<4;ji++)
{ x=dx[ji];y=dy[ji];
if(str[x][y]!=' ') j=0;
}
c=bioskey(1);
if(c!=0) c=bioskey(0);
}
main()
{ int dotx[4],doty[4],score; /*dotx[]doty[]表示一個方塊個點的坐標*/
int ddx,ddy;
int rzt1,rzt2,i,u,t=1;
int a[5],b[11],o,p,an,bn;
int rotx[4],roty[4],spd=0;
begin: system("cls"); /*游戲初始化階段*/
printf("londing...");
for(i=0;i<12;i++) /*變數初始階段*/
{ for(u=0;u<19;u++)
str[i][u]=' ';
}
for(i=0;i<12;i++)
for(u=0;u<19;u++)
cx[1][1][0]=1;cx[1][1][2]=-1;cx[1][1][3]=-2; /*對旋轉變數進行賦值*/
cy[1][1][0]=1;cy[1][1][2]=-1;cy[1][1][3]=-2;
cx[1][2][0]=-1;cx[1][2][2]=1;cx[1][2][3]=2;
cy[1][2][0]=-1;cy[1][2][2]=1;cy[1][2][3]=2;
cx[2][1][0]=0;cx[2][1][2]=0;cx[2][1][3]=0;
cy[2][1][0]=0;cy[2][1][2]=0;cy[2][1][3]=0;
cx[3][1][0]=1;cx[3][1][2]=-1;cx[3][1][3]=1;
cy[3][1][0]=-1;cy[3][1][2]=1;cy[3][1][3]=1;
cx[3][2][0]=1;cx[3][2][2]=-1;cx[3][2][3]=-1;
cy[3][2][0]=1;cy[3][2][2]=-1;cy[3][2][3]=1;
cx[3][3][0]=-1;cx[3][3][2]=1;cx[3][3][3]=-1;
cy[3][3][0]=1;cy[3][3][2]=-1;cy[3][3][3]=-1;
cx[3][4][0]=-1;cx[3][4][2]=1;cx[3][4][3]=1;
cy[3][4][0]=-1;cy[3][4][2]=1;cy[3][4][3]=-1;
cx[4][1][0]=-1;cx[4][1][2]=1;cx[4][1][3]=2;
cy[4][1][0]=1;cy[4][1][2]=1;cy[4][1][3]=0;
cx[4][2][0]=1;cx[4][2][2]=-1;cx[4][2][3]=-2;
cy[4][2][0]=-1;cy[4][2][2]=-1;cy[4][2][3]=0;
cx[5][1][0]=1;cx[5][1][2]=1;cx[5][1][3]=0;
cy[5][1][0]=-1;cy[5][1][2]=1;cy[5][1][3]=2;
cx[5][2][0]=-1;cx[5][2][2]=-1;cx[5][2][3]=0;
cy[5][2][0]=1;cy[5][2][2]=-1;cy[5][2][3]=-2;
cx[6][1][0]=1;cx[6][1][2]=-1;cx[6][1][3]=0;
cy[6][1][0]=-1;cy[6][1][2]=1;cy[6][1][3]=2;
cx[6][2][0]=1;cx[6][2][2]=-1;cx[6][2][3]=-2;
cy[6][2][0]=1;cy[6][2][2]=-1;cy[6][2][3]=0;
cx[6][3][0]=-1;cx[6][3][2]=1;cx[6][3][3]=0;
cy[6][3][0]=1;cy[6][3][2]=-1;cy[6][3][3]=-2;
cx[6][4][0]=-1;cx[6][4][2]=1;cx[6][4][3]=2;
cy[6][4][0]=-1;cy[6][4][2]=1;cy[6][4][3]=0;
cx[7][1][0]=-1;cx[7][1][2]=1;cx[7][1][3]=2;
cy[7][1][0]=1;cy[7][1][2]=-1;cy[7][1][3]=0;
cx[7][2][0]=-1;cx[7][2][2]=1;cx[7][2][3]=0;
cy[7][2][0]=-1;cy[7][2][2]=1;cy[7][2][3]=2;
cx[7][3][0]=1;cx[7][3][2]=-1;cx[7][3][3]=-2;
cy[7][3][0]=-1;cy[7][3][2]=1;cy[7][3][3]=0;
cx[7][4][0]=1;cx[7][4][2]=-1;cx[7][4][3]=0;
cy[7][4][0]=1;cy[7][4][2]=-1;cy[7][4][3]=-2;
srand(time(0)); /*對隨機數函數rand()進行初始化*/
zt1=rand()%7+1; /*生成第一、二個方塊*/
if(zt1==2) zt2=1;
if(zt1==1||zt1==4||zt1==5) zt2=rand()%2+1;
if(zt1==3||zt1==6||zt1==7) zt2=rand()%4+1;
rzt1=rand()%7+1;
if(rzt1==2) rzt2=1;
if(rzt1==1||rzt1==4||rzt1==5) rzt2=rand()%2+1;
if(rzt1==3||rzt1==6||rzt1==7) rzt2=rand()%4+1;
score=0;
for(o=1;o<11;o++) b[o]=0;
switch(zt1*10+zt2)
/*zt1和zt2分別代表方塊的種類和狀態,這步是根據這兩個變數確定方塊的四個點的坐標*/
{ case 11: dotx[0]=4;dotx[1]=5;dotx[2]=6;dotx[3]=7;
doty[0]=2;doty[1]=2;doty[2]=2;doty[3]=2;
break;
case 12: dotx[0]=5;dotx[1]=5;dotx[2]=5;dotx[3]=5;
doty[0]=4;doty[1]=3;doty[2]=2;doty[3]=1;
break;
case 21: dotx[0]=5;dotx[1]=6;dotx[2]=5;dotx[3]=6;
doty[0]=1;doty[1]=1;doty[2]=2;doty[3]=2;
break;
case 31: dotx[0]=4;dotx[1]=5;dotx[2]=6;dotx[3]=5;
doty[0]=2;doty[1]=2;doty[2]=2;doty[3]=1;
break;
case 32: dotx[0]=5;dotx[1]=5;dotx[2]=5;dotx[3]=6;
doty[0]=1;doty[1]=2;doty[2]=3;doty[3]=2;
break;
case 33: dotx[0]=6;dotx[1]=5;dotx[2]=4;dotx[3]=5;
doty[0]=1;doty[1]=1;doty[2]=1;doty[3]=2;
break;
case 34: dotx[0]=6;dotx[1]=6;dotx[2]=6;dotx[3]=5;
doty[0]=3;doty[1]=2;doty[2]=1;doty[3]=2;
break;
case 41: dotx[0]=6;dotx[1]=5;dotx[2]=5;dotx[3]=4;
doty[0]=2;doty[1]=2;doty[2]=1;doty[3]=1;
break;
case 42: dotx[0]=5;dotx[1]=5;dotx[2]=6;dotx[3]=6;
doty[0]=3;doty[1]=2;doty[2]=2;doty[3]=1;
break;
case 51: dotx[0]=4;dotx[1]=5;dotx[2]=5;dotx[3]=6;
doty[0]=2;doty[1]=2;doty[2]=1;doty[3]=1;
break;
case 52: dotx[0]=5;dotx[1]=5;dotx[2]=6;dotx[3]=6;
doty[0]=1;doty[1]=2;doty[2]=2;doty[3]=3;
break;
case 61: dotx[0]=4;dotx[1]=5;dotx[2]=6;dotx[3]=6;
doty[0]=2;doty[1]=2;doty[2]=2;doty[3]=1;
break;
case 62: dotx[0]=5;dotx[1]=5;dotx[2]=5;dotx[3]=6;
doty[0]=1;doty[1]=2;doty[2]=3;doty[3]=3;
break;
case 63: dotx[0]=6;dotx[1]=5;dotx[2]=4;dotx[3]=4;
doty[0]=1;doty[1]=1;doty[2]=1;doty[3]=2;
break;
case 64: dotx[0]=6;dotx[1]=6;dotx[2]=6;dotx[3]=5;
doty[0]=3;doty[1]=2;doty[2]=1;doty[3]=1;
break;
case 71: dotx[0]=6;dotx[1]=5;dotx[2]=4;dotx[3]=4;
doty[0]=2;doty[1]=2;doty[2]=2;doty[3]=1;
break;
case 72: dotx[0]=5;dotx[1]=5;dotx[2]=5;dotx[3]=6;
doty[0]=3;doty[1]=2;doty[2]=1;doty[3]=1;
break;
case 73: dotx[0]=4;dotx[1]=5;dotx[2]=6;dotx[3]=6;
doty[0]=1;doty[1]=1;doty[2]=1;doty[3]=2;
break;
case 74: dotx[0]=6;dotx[1]=6;dotx[2]=6;dotx[3]=5;
doty[0]=1;doty[1]=2;doty[2]=3;doty[3]=3;
break;
}
switch(rzt1*10+rzt2) /*確定第二個方塊各個點的坐標*/
{ case 11: rotx[0]=4;rotx[1]=5;rotx[2]=6;rotx[3]=7;
roty[0]=2;roty[1]=2;roty[2]=2;roty[3]=2;
break;
case 12: rotx[0]=5;rotx[1]=5;rotx[2]=5;rotx[3]=5;
roty[0]=4;roty[1]=3;roty[2]=2;roty[3]=1;
break;
case 21: rotx[0]=5;rotx[1]=6;rotx[2]=5;rotx[3]=6;
roty[0]=1;roty[1]=1;roty[2]=2;roty[3]=2;
break;
case 31: rotx[0]=4;rotx[1]=5;rotx[2]=6;rotx[3]=5;
roty[0]=2;roty[1]=2;roty[2]=2;roty[3]=1;
break;
case 32: rotx[0]=5;rotx[1]=5;rotx[2]=5;rotx[3]=6;
roty[0]=1;roty[1]=2;roty[2]=3;roty[3]=2;
break;
case 33: rotx[0]=6;rotx[1]=5;rotx[2]=4;rotx[3]=5;
roty[0]=1;roty[1]=1;roty[2]=1;roty[3]=2;
break;
case 34: rotx[0]=6;rotx[1]=6;rotx[2]=6;rotx[3]=5;
roty[0]=3;roty[1]=2;roty[2]=1;roty[3]=2;
break;
case 41: rotx[0]=6;rotx[1]=5;rotx[2]=5;rotx[3]=4;
roty[0]=2;roty[1]=2;roty[2]=1;roty[3]=1;
break;
case 42: rotx[0]=5;rotx[1]=5;rotx[2]=6;rotx[3]=6;
roty[0]=3;roty[1]=2;roty[2]=2;roty[3]=1;
break;
case 51: rotx[0]=4;rotx[1]=5;rotx[2]=5;rotx[3]=6;
roty[0]=2;roty[1]=2;roty[2]=1;roty[3]=1;
break;
case 52: rotx[0]=5;rotx[1]=5;rotx[2]=6;rotx[3]=6;
roty[0]=1;roty[1]=2;roty[2]=2;roty[3]=3;
break;
case 61: rotx[0]=4;rotx[1]=5;rotx[2]=6;rotx[3]=6;
roty[0]=2;roty[1]=2;roty[2]=2;roty[3]=1;
break;
case 62: rotx[0]=5;rotx[1]=5;rotx[2]=5;rotx[3]=6;
roty[0]=1;roty[1]=2;roty[2]=3;roty[3]=3;
break;
case 63: rotx[0]=6;rotx[1]=5;rotx[2]=4;rotx[3]=4;
roty[0]=1;roty[1]=1;roty[2]=1;roty[3]=2;
break;
case 64: rotx[0]=6;rotx[1]=6;rotx[2]=6;rotx[3]=5;
roty[0]=3;roty[1]=2;roty[2]=1;roty[3]=1;
break;
case 71: rotx[0]=6;rotx[1]=5;rotx[2]=4;rotx[3]=4;
roty[0]=2;roty[1]=2;roty[2]=2;roty[3]=1;
break;
case 72: rotx[0]=5;rotx[1]=5;rotx[2]=5;rotx[3]=6;
roty[0]=3;roty[1]=2;roty[2]=1;roty[3]=1;
break;
case 73: rotx[0]=4;rotx[1]=5;rotx[2]=6;rotx[3]=6;
roty[0]=1;roty[1]=1;roty[2]=1;roty[3]=2;
break;
case 74: rotx[0]=6;rotx[1]=6;rotx[2]=6;rotx[3]=5;
roty[0]=1;roty[1]=2;roty[2]=3;roty[3]=3;
break;
}
system("cls"); /*顯示初始階段*/
printf("\n\n\n"); /*游戲區域下移3*/
for(u=0;u<19;u++)
{ for(i=0;i<12;i++)
printf("%c",str[i][u]);
printf("\n");
}
gotoxy(16,5);printf("--------");
gotoxy(16,12);printf("--------");
for(i=6;i<12;i++)
for(i=6;i<12;i++)
for(i=0;i<4;i++)
{ gotoxy(rotx[i]+14,roty[i]+6);printf("%c",15);
}
begin2: delay(26000); /*游戲開始,延遲1*/
speed: delay(10000); /*加速,延遲2*/
gotoxy(16,14);printf("Score:%d",score);
for(i=0;i<4;i++)
{ gotoxy(dotx[i]+1,doty[i]+4);printf(" ");
ddx=dotx[i];ddy=doty[i];
str[ddx][ddy]=' ';
}
an=an-0.4; /*表示按鍵是否一直按著,用於方塊落地後的移動*/
c=bioskey(1); /*按鍵處理部分*/
/*bioskey(1)是用來檢測是否按下案件的函數*/
if(c!=0)
{ c=bioskey(0);
if(c==8292||c==19712)
{ for(i=0;i<4;i++)
jiance();
for(i=0;i<4;i++)
dotx[i]=(j)? dx[i] : dotx[i];
an=(j||bn);
}
if(c==7777||c==19200)
{ for(i=0;i<4;i++)
jiance();
for(i=0;i<4;i++)
dotx[i]=(j)? dx[i] : dotx[i];
an=(j||bn);
}
if(c==6512) /*暫停的處理*/
{ while(1)
{ c=bioskey(0);
if(c==6512) break;
}
goto begin3;
}
if(c==8051||c==20480) spd=1; /*加速(spd==1表示加速狀態)*/
if(c==4471||c==18432) /*旋轉的處理*/
{ for(i=0;i<4;i++)
/*dx[]與dy[]是臨時變數,這樣一旦判斷為不能旋轉,就可方便的回復旋轉前的坐標*/
cir(); /*旋轉*/
jiance(); /*判斷旋轉是否能進行*/
for(i=0;i<4;i++)
/*根據jiance()得到的j值,判斷是對dotx[]與doty[]賦旋轉後的還是旋轉前的值*/
if(j==1) /*如果旋轉可已經行,就對原方塊的狀態進行改變*/
{ an=(j||bn);zt2=zt2+1;
if(zt2>maxzt[zt1]) zt2=1;
goto overif; /*結束旋轉的處理*/
}
for(i=0;i<4;i++)
/*如果不能旋轉,再判斷坐標右移一個後能否旋轉*/
cir();
jiance();
for(i=0;i<4;i++)
if(j==1)
{ an=(j||bn);zt2=zt2+1;
if(zt2>maxzt[zt1]) zt2=1;
goto overif;
}
if(dotx[2]==1) goto overif;
for(i=0;i<4;i++)
/*判斷坐標左移一個後能否旋轉*/
cir();
jiance();
for(i=0;i<4;i++)
if(j==1)
{ an=(j||bn);zt2=zt2+1;
if(zt2>maxzt[zt1]) zt2=1;
goto overif;
}
overif: ;
}
}
begin3: for(i=0;i<4;i++) /*方塊下移的處理*/
jiance();
bn=j;
for(i=0;i<4;i++)
doty[i]=(j)? dy[i] : doty[i];
for(i=0;i<4;i++)
{ gotoxy(dotx[i]+1,doty[i]+4);printf("%c",15);
ddx=dotx[i];ddy=doty[i];
str[ddx][ddy]=15;
}
if(j==1&&spd==1)
if(j==1||an>0) goto begin2;
for(u=17;u>0;u--) /*方塊停止下移(方塊移動到底了)的處理*/
{ for(i=1;i<11;i++) /*判斷每一行是否排滿*/
if(str[i][u]==15) b[i]=1;
if (b[1]+b[2]+b[3]+b[4]+b[5]+b[6]+b[7]+b[8]+b[9]+b[10]<10)
{ for(o=1;o<11;o++) b[o]=0;
continue;
}
for(o=1;o<11;o++) b[o]=0;
a[t]=u;t++;
}
score+=(t)*(t-1)/2;
for(i=1;i<11;i++)
if(str[i][1]==15) b[i]=1;
if (b[1]+b[2]+b[3]+b[4]+b[5]+b[6]+b[7]+b[8]+b[9]+b[10]>0 &&t==1) goto over;
for(o=1;o<11;o++) b[o]=0;
if(t==1) goto ran;
switch(t) /*消除方塊的處理,t=要消除的函數+1*/
/*將要消除的行中,最上面一行,上面的方格整體下移,下面的case 4,3,2類似*/
case 4: for(u=a[3];u>1;u--)
case 3: for(u=a[2];u>1;u--)
case 2: for(u=a[1];u>1;u--)
}
t=1;
for(u=1;u<18;u++)
{ for(i=1;i<11;i++)
{ gotoxy(i+1,u+4);
printf("%c",str[i][u]);
}
}
ran: zt1=rzt1;zt2=rzt2;rzt1=rand()%7+1; /*生成下兩個方塊*/
if(rzt1==2) rzt2=1;
if(rzt1==1||rzt1==4||rzt1==5) rzt2=rand()%2+1;
if(rzt1==3||rzt1==6||rzt1==7) rzt2=rand()%4+1;
for(i=0;i<4;i++)
{ dotx[i]=rotx[i];doty[i]=roty[i];
gotoxy(dotx[i]+1,doty[i]+4);printf("%c",15);
}
switch(rzt1*10+rzt2)
{ case 11: rotx[0]=4;rotx[1]=5;rotx[2]=6;rotx[3]=7;
roty[0]=2;roty[1]=2;roty[2]=2;roty[3]=2;
break;
case 12: rotx[0]=5;rotx[1]=5;rotx[2]=5;rotx[3]=5;
roty[0]=4;roty[1]=3;roty[2]=2;roty[3]=1;
break;
case 21: rotx[0]=5;rotx[1]=6;rotx[2]=5;rotx[3]=6;
roty[0]=1;roty[1]=1;roty[2]=2;roty[3]=2;
break;
case 31: rotx[0]=4;rotx[1]=5;rotx[2]=6;rotx[3]=5;
roty[0]=2;roty[1]=2;roty[2]=2;roty[3]=1;
break;
case 32: rotx[0]=5;rotx[1]=5;rotx[2]=5;rotx[3]=6;
roty[0]=1;roty[1]=2;roty[2]=3;roty[3]=2;
break;
case 33: rotx[0]=6;rotx[1]=5;rotx[2]=4;rotx[3]=5;
roty[0]=1;roty[1]=1;roty[2]=1;roty[3]=2;
break;
case 34: rotx[0]=6;rotx[1]=6;rotx[2]=6;rotx[3]=5;
roty[0]=3;roty[1]=2;roty[2]=1;roty[3]=2;
break;
case 41: rotx[0]=6;rotx[1]=5;rotx[2]=5;rotx[3]=4;
roty[0]=2;roty[1]=2;roty[2]=1;roty[3]=1;
break;
case 42: rotx[0]=5;rotx[1]=5;rotx[2]=6;rotx[3]=6;
roty[0]=3;roty[1]=2;roty[2]=2;roty[3]=1;
break;
case 51: rotx[0]=4;rotx[1]=5;rotx[2]=5;rotx[3]=6;
roty[0]=2;roty[1]=2;roty[2]=1;roty[3]=1;
break;
case 52: rotx[0]=5;rotx[1]=5;rotx[2]=6;rotx[3]=6;
roty[0]=1;roty[1]=2;roty[2]=2;roty[3]=3;
break;
case 61: rotx[0]=4;rotx[1]=5;rotx[2]=6;rotx[3]=6;
roty[0]=2;roty[1]=2;roty[2]=2;roty[3]=1;
break;
case 62: rotx[0]=5;rotx[1]=5;rotx[2]=5;rotx[3]=6;
roty[0]=1;roty[1]=2;roty[2]=3;roty[3]=3;
break;
case 63: rotx[0]=6;rotx[1]=5;rotx[2]=4;rotx[3]=4;
roty[0]=1;roty[1]=1;roty[2]=1;roty[3]=2;
break;
case 64: rotx[0]=6;rotx[1]=6;rotx[2]=6;rotx[3]=5;
roty[0]=3;roty[1]=2;roty[2]=1;roty[3]=1;
break;
case 71: rotx[0]=6;rotx[1]=5;rotx[2]=4;rotx[3]=4;
roty[0]=2;roty[1]=2;roty[2]=2;roty[3]=1;
break;
case 72: rotx[0]=5;rotx[1]=5;rotx[2]=5;rotx[3]=6;
roty[0]=3;roty[1]=2;roty[2]=1;roty[3]=1;
break;
case 73: rotx[0]=4;rotx[1]=5;rotx[2]=6;rotx[3]=6;
roty[0]=1;roty[1]=1;roty[2]=1;roty[3]=2;
break;
case 74: rotx[0]=6;rotx[1]=6;rotx[2]=6;rotx[3]=5;
roty[0]=1;roty[1]=2;roty[2]=3;roty[3]=3;
break;
}
for(i=6;i<12;i++) /*刷新一下用來顯示下一個方塊的那個區域*/
for(i=6;i<12;i++)
for(u=17;u<23;u++)
for(i=0;i<4;i++)
c=bioskey(1);an=0;
if(c!=0) c=bioskey(0);
if(spd==1)
goto begin2;
over: system("cls");
gotoxy(36,11);printf("GAME OVER");
bioskey(0);
system("cls");
printf("Your score is %d\n\n",score);
printf("Press 'Q' to exit\nIf you want to play again,please press other keys.");
score=0;
c=bioskey(0);
if(c!=4209) goto begin;
}
另外,團IDC網上有許多產品團購,便宜有口碑
⑼ 求一份用C語言編寫的俄羅斯方塊的源代碼!
俄羅斯方塊C源代碼
#include<stdio.h>
#include<windows.h>
#include<conio.h>
#include<time.h>
#defineZL4 //坐標增量,不使游戲窗口靠邊
#defineWID36 //游戲窗口的寬度
#defineHEI20 //游戲窗口的高度
inti,j,Ta,Tb,Tc; //Ta,Tb,Tc用於記住和轉換方塊變數的值
inta[60][60]={0}; //標記游戲屏幕各坐標點:0,1,2分別為空、方塊、邊框
intb[4]; //標記4個"口"方塊:1有,0無,類似開關
intx,y,level,score,speed; //方塊中心位置的x,y坐標,游戲等級、得分和游戲速度
intflag,next; //當前要操作的方塊類型序號,下一個方塊類型序號
voidgtxy(intm,intn); //以下聲明要用到的自編函數
voidgflag(); //獲得下一方塊序號
voidcsh(); //初始化界面
voidstart(); //開始部分
voidprfk(); //列印方塊
voidclfk(); //清除方塊
voidmkfk(); //製作方塊
voidkeyD(); //按鍵操作
intifmov(); //判斷方塊能否移動或變體
void clHA(); //清除滿行的方塊
voidclNEXT(); //清除邊框外的NEXT方塊
intmain()
{csh();
while(1)
{start();//開始部分
while(1)
{prfk();
Sleep(speed); //延時
clfk();
Tb=x;Tc=flag;//臨存當前x坐標和序號,以備撤銷操作
keyD();
y++;//方塊向下移動
if(ifmov()==0){y--;prfk();dlHA();break;}//不可動放下,刪行,跨出循環
}
for(i=y-2;i<y+2;i++){if(i==ZL){j=0;}} //方塊觸到框頂
if(j==0){system("cls");gtxy(10,10);printf("游戲結束!");getch();break;}
clNEXT(); //清除框外的NEXT方塊
}
return0;
}
voidgtxy(intm,intn)//控制游標移動
{COORDpos;//定義變數
pos.X=m;//橫坐標
pos.Y=n;//縱坐標
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);
}
voidcsh()//初始化界面
{gtxy(ZL+WID/2-5,ZL-2);printf("俄羅斯方塊");//列印游戲名稱
gtxy(ZL+WID+3,ZL+7);printf("*******NEXT:");//列印菜單信息
gtxy(ZL+WID+3,ZL+13);printf("**********");
gtxy(ZL+WID+3,ZL+15);printf("Esc:退出遊戲");
gtxy(ZL+WID+3,ZL+17);printf("↑鍵:變體");
gtxy(ZL+WID+3,ZL+19);printf("空格:暫停游戲");
gtxy(ZL,ZL);printf("╔");gtxy(ZL+WID-2,ZL);printf("╗");//列印框角
gtxy(ZL,ZL+HEI);printf("╚");gtxy(ZL+WID-2,ZL+HEI);printf("╝");
a[ZL][ZL+HEI]=2;a[ZL+WID-2][ZL+HEI]=2;//記住有圖案
for(i=2;i<WID-2;i+=2){gtxy(ZL+i,ZL);printf("═");}//列印上橫框
for(i=2;i<WID-2;i+=2){gtxy(ZL+i,ZL+HEI);printf("═");a[ZL+i][ZL+HEI]=2;}//下框
for(i=1;i<HEI;i++){gtxy(ZL,ZL+i);printf("║");a[ZL][ZL+i]=2;}//左豎框記住有圖案
for(i=1;i<HEI;i++){gtxy(ZL+WID-2,ZL+i);printf("║");a[ZL+WID-2][ZL+i]=2;}//右框
CONSOLE_CURSOR_INFOcursor_info={1,0};//以下是隱藏游標的設置
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cursor_info);
level=1;score=0;speed=400;
gflag();flag=next;//獲得一個當前方塊序號
}
voidgflag() //獲得下一個方塊的序號
{srand((unsigned)time(NULL));next=rand()%19+1; }
voidstart()//開始部分
{gflag();Ta=flag;flag=next;//保存當前方塊序號,將下一方塊序號臨時操作
x=ZL+WID+6;y=ZL+10;prfk();//給x,y賦值,在框外列印出下一方塊
flag=Ta;x=ZL+WID/2;y=ZL-1;//取回當前方塊序號,並給x,y賦值
}
voidprfk()//列印俄羅斯方塊
{for(i=0;i<4;i++){b[i]=1;}//數組b[4]每個元素的值都為1
mkfk();//製作俄羅斯方塊
for(i=x-2;i<=x+4;i+=2)//列印方塊
{for(j=y-2;j<=y+1;j++){if(a[i][j]==1&&j>ZL){gtxy(i,j);printf("□");}}}
gtxy(ZL+WID+3,ZL+1); printf("level:%d",level); //以下列印菜單信息
gtxy(ZL+WID+3,ZL+3); printf("score:%d",score);
gtxy(ZL+WID+3,ZL+5); printf("speed:%d",speed);
}
voidclfk()//清除俄羅斯方塊
{for(i=0;i<4;i++){b[i]=0;}//數組b[4]每個元素的值都為0
mkfk();//製作俄羅斯方塊
for(i=x-2;i<=x+4;i+=2)//清除方塊
{for(j=y-2;j<=y+1;j++){if(a[i][j]==0&&j>ZL){gtxy(i,j);printf("");}}}
}
voidmkfk()//製作俄羅斯方塊
{a[x][y]=b[0];//方塊中心位置狀態:1-有,0-無
switch(flag)//共6大類,19種小類型
{case1:{a[x][y-1]=b[1];a[x+2][y-1]=b[2];a[x+2][y]=b[3];break;}//田字方塊
case2:{a[x-2][y]=b[1];a[x+2][y]=b[2];a[x+4][y]=b[3];break;}//直線方塊:----
case3:{a[x][y-1]=b[1];a[x][y-2]=b[2];a[x][y+1]=b[3];break;}//直線方塊:|
case4:{a[x-2][y]=b[1];a[x+2][y]=b[2];a[x][y+1]=b[3];break;}//T字方塊
case5:{a[x][y-1]=b[1];a[x][y+1]=b[2];a[x-2][y]=b[3];break;}//T字順時針轉90度
case6:{a[x][y-1]=b[1];a[x-2][y]=b[2];a[x+2][y]=b[3];break;}//T字順轉180度
case7:{a[x][y-1]=b[1];a[x][y+1]=b[2];a[x+2][y]=b[3];break;}//T字順轉270度
case8:{a[x][y+1]=b[1];a[x-2][y]=b[2];a[x+2][y+1]=b[3];break;}//Z字方塊
case9:{a[x][y-1]=b[1];a[x-2][y]=b[2];a[x-2][y+1]=b[3];break;}//Z字順轉90度
case10:{a[x][y-1]=b[1];a[x-2][y-1]=b[2];a[x+2][y]=b[3];break;}//Z字順轉180度
case11:{a[x][y+1]=b[1];a[x+2][y-1]=b[2];a[x+2][y]=b[3];break;}//Z字順轉270度
case12:{a[x][y-1]=b[1];a[x][y+1]=b[2];a[x-2][y-1]=b[3];break;}//7字方塊
case13:{a[x-2][y]=b[1];a[x+2][y-1]=b[2];a[x+2][y]=b[3];break;}//7字順轉90度
case14:{a[x][y-1]=b[1];a[x][y+1]=b[2];a[x+2][y+1]=b[3];break;}//7字順轉180度
case15:{a[x-2][y]=b[1];a[x-2][y+1]=b[2];a[x+2][y]=b[3];break;}//7字順轉270度
case16:{a[x][y+1]=b[1];a[x][y-1]=b[2];a[x+2][y-1]=b[3];break;}//倒7字方塊
case17:{a[x-2][y]=b[1];a[x+2][y+1]=b[2];a[x+2][y]=b[3];break;}//倒7字順轉90度
case18:{a[x][y-1]=b[1];a[x][y+1]=b[2];a[x-2][y+1]=b[3];break;}//倒7字順轉180度
case19:{a[x-2][y]=b[1];a[x-2][y-1]=b[2];a[x+2][y]=b[3];break;}//倒7字順轉270度
}
}
voidkeyD()//按鍵操作
{if(kbhit())
{intkey;
key=getch();
if(key==224)
{key=getch();
if(key==75){x-=2;}//按下左方向鍵,中心橫坐標減2
if(key==77){x+=2;}//按下右方向鍵,中心橫坐標加2
if(key==72)//按下向上方向鍵,方塊變體
{if(flag>=2&&flag<=3){flag++;flag%=2;flag+=2;}
if(flag>=4&&flag<=7){flag++;flag%=4;flag+=4;}
if(flag>=8&&flag<=11){flag++;flag%=4;flag+=8;}
if(flag>=12&&flag<=15){flag++;flag%=4;flag+=12;}
if(flag>=16&&flag<=19){flag++;flag%=4;flag+=16;}}
}
if(key==32)//按空格鍵,暫停
{prfk();while(1){if(getch()==32){clfk();break;}}} //再按空格鍵,繼續游戲
if(ifmov()==0){x=Tb;flag=Tc;} //如果不可動,撤銷上面操作
else{prfk();Sleep(speed);clfk();Tb=x;Tc=flag;} //如果可動,執行操作
}
}
intifmov()//判斷能否移動
{if(a[x][y]!=0){return0;}//方塊中心處有圖案返回0,不可移動
else{if((flag==1&&(a[x][y-1]==0&&a[x+2][y-1]==0&&a[x+2][y]==0))||
(flag==2&&(a[x-2][y]==0&&a[x+2][y]==0&&a[x+4][y]==0))||
(flag==3&&(a[x][y-1]==0&&a[x][y-2]==0&&a[x][y+1]==0))||
(flag==4&&(a[x-2][y]==0&&a[x+2][y]==0&&a[x][y+1]==0))||
(flag==5&&(a[x][y-1]==0&&a[x][y+1]==0&&a[x-2][y]==0))||
(flag==6&&(a[x][y-1]==0&&a[x-2][y]==0&&a[x+2][y]==0))||
(flag==7&&(a[x][y-1]==0&&a[x][y+1]==0&&a[x+2][y]==0))||
(flag==8&&(a[x][y+1]==0&&a[x-2][y]==0&&a[x+2][y+1]==0))||
(flag==9&&(a[x][y-1]==0&&a[x-2][y]==0&&a[x-2][y+1]==0))||
(flag==10&&(a[x][y-1]==0&&a[x-2][y-1]==0&&a[x+2][y]==0))||
(flag==11&&(a[x][y+1]==0&&a[x+2][y-1]==0&&a[x+2][y]==0))||
(flag==12&&(a[x][y-1]==0&&a[x][y+1]==0&&a[x-2][y-1]==0))||
( flag==13 && ( a[x-2][y]==0 && a[x+2][y-1]==0 && a[x+2][y]==0 ) ) ||
( flag==14 && ( a[x][y-1]==0 && a[x][y+1]==0 && a[x+2][y+1]==0 ) ) ||
(flag==15 && ( a[x-2][y]==0 && a[x-2][y+1]==0 && a[x+2][y]==0 ) ) ||
(flag==16 && ( a[x][y+1]==0 && a[x][y-1]==0 && a[x+2][y-1]==0 ) ) ||
( flag==17 && ( a[x-2][y]==0 && a[x+2][y+1]==0 && a[x+2][y]==0 ) ) ||
(flag==18 && ( a[x][y-1]==0 &&a[x][y+1]==0 && a[x-2][y+1]==0 ) ) ||
(flag==19 && ( a[x-2][y]==0 && a[x-2][y-1]==0
&&a[x+2][y]==0))){return1;}
}
return0; //其它情況返回0
}
voidclNEXT() //清除框外的NEXT方塊
{flag=next;x=ZL+WID+6;y=ZL+10;clfk();}
void clHA() //清除滿行的方塊
{intk,Hang=0; //k是某行方塊個數,Hang是刪除的方塊行數
for(j=ZL+HEI-1;j>=ZL+1;j--)//當某行有WID/2-2個方塊時,則為滿行
{k=0;for(i=ZL+2;i<ZL+WID-2;i+=2)
{if(a[i][j]==1)//豎坐標從下往上,橫坐標由左至右依次判斷是否滿行
{k++; //下面將操作刪除行
if(k==WID/2-2) { for(k=ZL+2;k<ZL+WID-2;k+=2)
{a[k][j]=0;gtxy(k,j);printf("");Sleep(1);}
for(k=j-1;k>ZL;k--)
{for(i=ZL+2;i<ZL+WID-2;i+=2)//已刪行數上面有方塊,先清除再全部下移一行
{if(a[i][k]==1){a[i][k]=0;gtxy(i,k);printf("");a[i][k+1]=1;
gtxy(i,k+1);printf("□");}}
}
j++;//方塊下移後,重新判斷刪除行是否滿行
Hang++;//記錄刪除方塊的行數
}
}
}
}
score+=100*Hang; //每刪除一行,得100分
if(Hang>0&&(score%500==0||score/500>level-1)) //得分滿500速度加快升一級
{speed-=20;level++;if(speed<200)speed+=20; }
}