① 怎樣用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語言編一個俄羅斯方塊
游戲界面預覽:
菜單預覽:
自定義每個小方塊顏色功能界面:
游戲主要有四部分組成: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語言實現俄羅斯方塊小游戲,高手在民間!
我這次給大家帶來的是,俄羅斯方塊的小 游戲 ,在這個程序中,我們幾乎用到了之前所有的知識點,還用到了一些ege庫里邊的函數和功能,比如:按鍵處理,文字輸出、圖形繪制,還有圖片的顯示等。
主要為大家詳細介紹了Linux下C語言實現俄羅斯方塊小 游戲 ,具有一定的參考價值,感興趣的小夥伴們可以參考一下
下面是我整理的C++資料,私信我「01」就可以獲取了
游戲 歡迎界面
游戲 主界面:
游戲 結束界面:
我們看到的 游戲 池中所有的方塊(包括正在下落的模塊),都是根據上述的結構體pool中的數據在屏幕中列印出來的結果。也就是我們通過不斷更改pool結構體中的數據,然後再將pool中的數據不停的顯示到屏幕,就變成了我們看到的模塊的移動、翻轉、消行等效果。
C語言實現俄羅斯方塊小 游戲 的製作代碼,具體內容如下
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持我下次的作品。
④ 求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語言中俄羅斯方塊怎麼做
當時做得時候工具用turboC
2.0開發的,課程設計.
具體的代碼網上可以搜到很多,我就不細說了.
當時編碼的時候,通常把俄羅斯方塊的編碼工作分成幾個小塊完成,我描述一下:
1.
當前下落塊的控制邏輯.
2.
用戶輸入的控制邏輯,這個是用中斷控制,比如bioskey()函數去獲取當前的輸入值,具體的我記不清了.
3.
判斷一行是否能夠消去邏輯(公共環境是用20*12的數組來存放.)
4.
難度以及其他配置模塊管理,模塊劃分清楚之後,編碼較為容易.
希望可以有幫助:
)
⑥ 俄羅斯方塊 c語言編程思想 怎麼實現的一個思路
1.定義各基本的圖形單元,並把它們實現。
2.定義顯示區域中行、列數,實現可以按1中定義的單元進行填充(顯示)
3.定義數據結構,進行各行填充滿時的判斷,此時可以進行消除。並把上面各行依次下移。
(注意:1中定義的圖元,在下落到最底行時,就不必要保持圖元的信息,而是把相對應的2中
定義的行列區域進行填充,這實際上就是3中定義的數據結構的操作,圖形只是按照數據結構
中對應的定義顯示出來而已,實際上,你先把3定義好之後,再做1,2更合適)
4.加上對圖元的控制(加快速度,左右翻轉,左右移動)
5.增加積分設計,增加分值對速度的影響等。
6.增加其它好玩的設計,如:爆炸效果、消除時的特效等等。
7.有耐心的話,增加其它元素,如:連網對戰,雙人對戰,歷史積分記錄等等功能。
8.圖形美化,等等其它細節。
⑦ 怎樣用C語言寫俄羅斯方塊,求指教,謝謝!
首先你要下載vc++,初學者可以用vs98安裝好後在項目中可以添加如下代碼
#include"graphics.h"
#include<conio.h>
#include<stdlib.h>
intgcW=20,gcColor[]={DARKGRAY,LIGHTBLUE,LIGHTGREEN,LIGHTCYAN,
LIGHTRED,LIGHTMAGENTA,MAGENTA,YELLOW};
structtetris{
int_pool[16][32],(*pool)[32],tmap[8][4][16];
intx,y,s,st,t;
}gt;
voidtrsInit(){
intsp[8][4]={{15,4369},{23,785,116,547},{71,275,113,802},
{39,305,114,562},{54,561},{99,306},{51,51},{-1}};
int*p,i,j,b;
for(p=sp[0];*p>=0;++p)if(*p==0)*p=p[-2];
gt.pool=>._pool[4];
for(j=0;j<7;++j)
for(i=0;i<4;++i)
for(b=0;b<16;++b)
gt.tmap[j+1][i][b]=(sp[j][i]&1)*(j+1),
sp[j][i]>>=1;
memset(gt._pool,-1,sizeof(gt._pool));
for(i=0;i<10;++i)
memset(>.pool[i],0,sizeof(int[21]));
return;
}
inttrsCopy(intsp[],intx,inty,intc){
intm[]={0,32,64,96,1,33,65,97,2,34,66,98,3,35,67,99},i,cx,cy;
for(i=0;i<16;++i)if(sp[i]){
cx=x+(m[i]>>5),cy=y+(m[i]&31);
if(gt.pool[cx][cy])if(c==2)gt.pool[cx][cy]=0;elsereturn0;
if(c==1)gt.pool[cx][cy]=sp[i];
}
return1;
}
inttrsScene(){
intx,y=0;
gt.s=random(7)+1,gt.st=gt.t=0;
gt.x=4,gt.y=0;
for(--gt.t;;delay(10),--gt.t){
intk=0;
while(kbhit()){
k=getch();
if(k==27)return0;
if(k=='A'||k=='a'){
if(trsCopy(gt.tmap[gt.s][gt.st],gt.x-1,gt.y,0))--gt.x;
}elseif(k=='D'||k=='d'){
if(trsCopy(gt.tmap[gt.s][gt.st],gt.x+1,gt.y,0))++gt.x;
}elseif(k=='W'||k=='w'){
if(trsCopy(gt.tmap[gt.s][(gt.st+1)%4],gt.x,gt.y,0))
gt.st=(gt.st+1)%4;
}
}
if(k=='S'||k=='s'||gt.t<0){
if(trsCopy(gt.tmap[gt.s][gt.st],gt.x,gt.y+1,0))++gt.y,gt.t=50;
else{
trsCopy(gt.tmap[gt.s][gt.st],gt.x,gt.y,1);
for(--y;y>0;--y){
for(x=0;gt.pool[x][y]>0;++x);
if(gt.pool[x][y]<0)
for(k=y++;k>0;--k)
for(x=0;gt.pool[x][0]>=0;++x)
gt.pool[x][k]=gt.pool[x][k-1];
}
return1;
}
}
trsCopy(gt.tmap[gt.s][gt.st],gt.x,gt.y,1);
for(x=0;gt.pool[x][0]>=0;++x){
for(y=1;gt.pool[x][y]>=0;++y){
setfillstyle(1,gcColor[gt.pool[x][y]]);
bar(201+x*gcW,1+y*gcW,200+gcW+x*gcW,gcW+y*gcW);
}
}
trsCopy(gt.tmap[gt.s][gt.st],gt.x,gt.y,2);
}
}
intmain(){
intg=DETECT,m=0;
initgraph(&g,&m,"");
randomize();
trsInit();
while(trsScene());
return0;
}
⑧ 一個簡單的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語言編寫的俄羅斯方塊代碼
你好。試試這個#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();
}