C++課題練習: 俄羅斯方塊 紀錄 - arthur850512的創作 - 巴哈姆特

創作內容

0 GP

C++課題練習: 俄羅斯方塊 紀錄

作者:艾倫D索妮雅│2020-05-04 16:57:27│巴幣:0│人氣:1232


概念紀錄:
>遊戲框架 => frame[Height][Width] ..... 0,1,2,3
>方塊種類 => Asset[7][4][4]
>當前方塊 => asset[4][4]
>方塊旋轉90度 : assetB[x][y] = assetA[3-y][x] B:旋轉後 A:旋轉前
>碰撞偵測
>鍵盤控制
>方塊落下、左右移動、旋轉控制

好久沒回來練C++了
拿之前一直想寫卻一直發懶沒寫的課題來練一下手感 ~w~
然後小屋圖片又掛了.....~.~ 之後有時間再回來重用

#include<iostream>
#include<windows.h>
#include<string>
#include<cstdlib>
#include<conio.h>
#include<ctime>
 
/* 俄羅斯方塊  Tetris */

using namespace std;

/* 工具箱  */
HANDLE hIn,hOut;
//取得後臺處理I/O控制權,hIn=>鍵盤控制  hOut=>螢幕輸出控制
void Control_HANDLE_Unit()
{
hIn=GetStdHandle(STD_INPUT_HANDLE);
hOut=GetStdHandle(STD_OUTPUT_HANDLE);
}
//座標給定函式
void position(int x,int y)
{
static COORD c;
c.X = x;
c.Y = y;
SetConsoleCursorPosition(hOut,c);
}

/*遊戲主體*/
/** 遊戲框架 **/
const int nWidth=15,nHeight=20;
char Unit[3]={'|','H','X'};//邊、底邊、方塊
int frame[nHeight][nWidth]={0};//後臺參數,框架中frame[y][x] x,y為x座標和y座標; 其值=>有0,1,2,3; 0空白,1為邊,2為底邊,3方塊
int Delay_time;
int score = 0;
//繪製函式
void draw(int x,int y,int uniframe,char *unit)
{
if(uniframe==1)
{
position(x,y);
cout<<unit[0];
}
else if(uniframe==2)
{
position(x,y);
cout<<unit[1];
}
else if(uniframe==3)
{
position(x,y);
cout<<unit[2];
}
else
{
position(x,y);
cout<<' ';
}
}
/**方塊架構 **/
int i=5,j=0; //方塊初始座標
//7種方塊
int Asset[7][4][4]={{{0,0,3,0},{0,0,3,0},{0,0,3,0},{0,0,3,0}},
  {{0,0,3,0},{0,3,3,0},{0,3,0,0},{0,0,0,0}},
  {{0,3,0,0},{0,3,3,0},{0,0,3,0},{0,0,0,0}},
  {{0,0,0,0},{0,0,3,0},{0,3,3,3},{0,0,0,0}},
  {{0,0,0,0},{0,3,3,0},{0,3,3,0},{0,0,0,0}},
  {{0,3,3,0},{0,0,3,0},{0,0,3,0},{0,0,0,0}},
{{0,3,3,0},{0,3,0,0},{0,3,0,0},{0,0,0,0}}};
//方塊落下 =>方塊放置位置(x,y)、清除方塊、方塊放置位置(x,y+1)
void AssetPos(int px,int py,int (&asset)[4][4])//px,py為起始位置
{
for(int y=py; y<(py+4); y++)
{
for(int x=px; x<(px+4); x++)
{
if(frame[y][x]==0 && asset[y-py][x-px]!=0)
{
frame[y][x]=asset[y-py][x-px];
draw(x,y,frame[y][x],Unit);
}
}
}
}
void cleanAsset(int px,int py,int (&asset)[4][4])
{
for(int y=py; y<(py+4); y++)
{
for(int x=px; x<(px+4); x++)
{
if(asset[y-py][x-px]==3)
{
frame[y][x]=0;
draw(x,y,frame[y][x],Unit);
}
}
}
}

//判斷方塊是否碰撞
bool collision(int px,int py,int (&asset)[4][4])
{
for(int y=py; y<(py+4); y++)
for(int x=px; x<(px+4); x++)
if(frame[y][x]!=0 && asset[y-py][x-px]!=0)return 1;
return 0;
}

//方塊旋轉
void Rotation(int px,int py,int (&asset)[4][4])
{
int temp[4][4]={0};
for(int x=0; x<4; x++)
for(int y=0; y<4; y++)
temp[x][y]=asset[3-y][x]; //轉90度
cleanAsset(px,py,asset);
if(!collision(px, py, temp))
{
for(int x=0; x<4; x++)
for(int y=0; y<4; y++)
asset[x][y]=temp[x][y];
}
AssetPos(px,py,asset);
}

//鍵盤控制 往左、往右、旋轉
static DWORD count;
static INPUT_RECORD ir;
void key_Control(int (&asset)[4][4])
{
ReadConsoleInput(hIn,&ir,1,&count);
switch(ir.Event.KeyEvent.wVirtualKeyCode)
{
case VK_LEFT://向左
cleanAsset(i,j,asset);
if(collision(i-1,j,asset))//判斷落到下一格是否發生碰撞
AssetPos(i,j,asset);
else
{
i--;
AssetPos(i,j,asset);
}
break;
  case VK_RIGHT://向右
cleanAsset(i,j,asset);
if(collision(i+1,j,asset))//判斷落到下一格是否發生碰撞
AssetPos(i,j,asset);
else
{
i++;
AssetPos(i,j,asset);
}
break;
case VK_UP://旋轉
Rotation(i,j,asset);
break;
case VK_DOWN: //快速落下
Delay_time=0;
break;
}
Sleep(30);
}
//遊戲判定
bool Eliminate_Row_Asset(int y)//當一排都為方塊時,消除該牌方塊
{
for(int x=1;x<nWidth-1;x++)
if(frame[y][x]!=3)return 0;
return 1;
}
void Score(int count)
{
score+=count;
position(nWidth+16,nHeight-1);
cout<<score;
}
bool GameOver()
{
for(int x=0; x<nWidth; x++)
{
if(frame[0][x]==3)
return 1;
}
return 0;
}
void SpeedMode()
{
if(score>5000)
Delay_time = 25;
else if(score>4000)
Delay_time = 50;
else if(score>2000)
Delay_time = 100;
else if (score>1000)
Delay_time = 150;
else
Delay_time = 200;
}

int main()
{
Control_HANDLE_Unit();
//遊戲背景
for(int x=0; x<nWidth; x++)//底邊框
frame[nHeight-1][x]=2;
for(int y=0; y<nHeight; y++)//邊框
{
frame[y][0]=1;
frame[y][nWidth-1]=1;
}
for(int y=0; y<nHeight; y++)
for(int x=0; x<nWidth; x++)
draw(x,y,frame[y][x],Unit);
for(int y=0; y<nHeight; y++)
{
position(nWidth+1,y);
cout<<'>'<<y;
}
//計分板
position(nWidth+10,nHeight-1);
cout<<"Score:";
Score(0);
//放入方塊
int asset[4][4]={0};//目前的方塊
while(1)
{
i=5,j=0;//起始座標i,j
SpeedMode();//速度模式
srand(time(NULL));
int random = rand()%7;
for(int i=0; i<4; i++)
{
for(int j=0; j<4; j++)
asset[i][j]=Asset[random][i][j];//選取隨機7種方塊之一
}
AssetPos(i,j,asset);
//方塊落下
while(1)
{
while(!kbhit())
{
Sleep(Delay_time);
cleanAsset(i,j,asset);
if(collision(i,j+1,asset))//有碰撞
{
AssetPos(i,j,asset);
break;
}
j++;
AssetPos(i,j,asset);
Sleep(Delay_time);
if(kbhit())
{
ReadConsoleInput(hIn,&ir,1,&count);
key_Control(asset);
}
}
if(kbhit())
{
ReadConsoleInput(hIn,&ir,1,&count);
key_Control(asset);
}
cleanAsset(i,j,asset);
if(collision(i,j+1,asset))
{
AssetPos(i,j,asset);
break;
}
AssetPos(i,j,asset);
}
for(int y=nHeight-2; y>0; y--)//削掉方塊並計分
{
if(Eliminate_Row_Asset(y))
{
for(int x=1; x<nWidth-1; x++)
{
frame[y][x]=0;
draw(x,y,frame[y][x],Unit);
}
Sleep(100);
Score(100);
for(int j=y; j>0; j--)//上面方塊掉下來
{
for(int x=1; x<nWidth-1; x++)
{
frame[j][x]=frame[j-1][x];
draw(x,j,frame[j][x],Unit);
}
}
y++;
}
}
if(GameOver())
{
position(nWidth+10,nHeight/2);
cout<<"GAMEOVER!!";
break;
}
}
system("PAUSE");
return 0;
}
引用網址:https://home.gamer.com.tw/TrackBack.php?sn=4771098
All rights reserved. 版權所有,保留一切權利

相關創作

留言共 1 篇留言


打這麼多誰看得完阿.jpg

05-04 17:58

艾倫D索妮雅
~w ~05-04 18:06
我要留言提醒:您尚未登入,請先登入再留言

喜歡★arthur850512 可決定是否刪除您的留言,請勿發表違反站規文字。

前一篇:2020 2/24 隨意... 後一篇:跟風...#sailor...

追蹤私訊切換新版閱覽

作品資料夾

airsky00大家
加油,努力創作~~看更多我要大聲說昨天01:03


face基於日前微軟官方表示 Internet Explorer 不再支援新的網路標準,可能無法使用新的應用程式來呈現網站內容,在瀏覽器支援度及網站安全性的雙重考量下,為了讓巴友們有更好的使用體驗,巴哈姆特即將於 2019年9月2日 停止支援 Internet Explorer 瀏覽器的頁面呈現和功能。
屆時建議您使用下述瀏覽器來瀏覽巴哈姆特:
。Google Chrome(推薦)
。Mozilla Firefox
。Microsoft Edge(Windows10以上的作業系統版本才可使用)

face我們了解您不想看到廣告的心情⋯ 若您願意支持巴哈姆特永續經營,請將 gamer.com.tw 加入廣告阻擋工具的白名單中,謝謝 !【教學】