c++寫俄羅斯方塊小遊戲
阿新 • • 發佈:2018-11-08
第二篇部落格
把我之前用c++寫的一個俄羅斯方塊也傳上來算了,這個程式是我學完c++後寫的,雖然有點長,看起來比較嚇人,但是程式碼絕對是你能夠找到的理解起來最簡單的俄羅斯方塊的程式碼,對於一些基礎不好的同學還是非常友好的。(歡迎批評指正)
#include<iostream>
#include<windows.h>
#include <conio.h>
#include<time.h>
using namespace std;
//地圖初始化
int map[20][18] =
{
1, 1, 1, 1, 1, 1, 1, 1 , 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0 , 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
};
char ch = '0';
//畫出地圖
void drawMap()
{
for (int i = 0; i < 20; i++)
{
for (int j = 0; j < 18; j++)
switch (map[i][j])
{
case 0:
cout << " ";
break;
case 1:
cout << "□";
break;
case 2:
cout << "■";
break;
}
cout << endl;
}
}
//形狀類
class Shape
{
public:
int a0, a1, a2, a3, b0, b1, b2, b3;
//初始化
virtual void init()
{
map[a0][b0] = 2; map[a1][b1] = 2; map[a2][b2] = 2; map[a3][b3] = 2;
}
//清除形狀
virtual void clean()
{
map[a0][b0] = 0; map[a1][b1] = 0; map[a2][b2] = 0; map[a3][b3] = 0;
}
//點選
virtual void click(char ch){};
//下落
virtual void fall(){};
//判斷形狀是否到底
virtual bool shape_is_botton_adjacent(){ return true; };
//判斷形狀是否可向下移動
bool fall_moveable();
//判斷形狀是否可向左移動
bool laft_moveable();
//判斷形狀是否可向右移動
bool right_moveable();
//判斷方塊是否著陸
bool is_block_adjacent(int a, int b)
{
if (map[a][b] != 0)
return true;
else return false;
}
};
//“田”形狀類
class Tian :public Shape
{
public:
Tian(int a_0 = 1, int a_1 = 1, int a_2 = 2, int a_3 = 2, int b_0 = 8, int b_1 = 9, int b_2 = 8, int b_3 = 9)
{
a0 = a_0, a1 = a_1, a2 = a_2, a3 = a_3, b0 = b_0, b1 = b_1, b2 = b_2, b3 = b_3;
}
void fall()
{
if (fall_moveable() == true)
{
clean();
a0++; a1++; a2++; a3++;
}
}
void click(char ch)
{
switch (ch)
{
case'a':
{
if (laft_moveable() == true)
{
clean();
b0--; b1--; b2--; b3--;
}
break;
}
case'd':
{
if (right_moveable() == true)
{
clean();
b0++; b1++; b2++; b3++;
}
break;
}
case's':
{
if (fall_moveable() == true)
{
clean();
a0++; a1++; a2++; a3++;
}
break;
}
}
}
bool fall_moveable()
{
if (map[a2 + 1][b2] == 0 && map[a3 + 1][b3] == 0)
return true;
else return false;
}
bool laft_moveable()
{
if (map[a0][b0 - 1] == 0 && map[a2][b2 - 1] == 0)
return true;
else return false;
}
bool right_moveable()
{
if (map[a1][b1 + 1] == 0 && map[a3][b3 + 1] == 0)
return true;
else return false;
}
bool shape_is_botton_adjacent()
{
if (is_block_adjacent(a2, b2) || is_block_adjacent(a3, b3))
return true;
else return false;
}
};
//“|”形狀類
class Shu :public Shape
{
public:
Shu(int a_0 = 1, int a_1 = 2, int a_2 = 3, int a_3 = 4, int b_0 = 9, int b_1 = 9, int b_2 = 9, int b_3 = 9)
{
a0 = a_0, a1 = a_1, a2 = a_2, a3 = a_3, b0 = b_0, b1 = b_1, b2 = b_2, b3 = b_3;
}
void click(char ch)
{
switch (ch)
{
case'a':
{
if (laft_moveable() == true)
{
clean();
b0--; b1--; b2--; b3--;
}
break;
}
case'd':
{
if (right_moveable() == true)
{
clean();
b0++; b1++; b2++; b3++;
}
break;
}
case's':
{
if (fall_moveable() == true)
{
clean();
a0++; a1++; a2++; a3++;
}
break;
}
}
}
void fall()
{
if (fall_moveable() == true)
{
clean();
a0++; a1++; a2++; a3++;
}
}
bool fall_moveable()
{
if (map[a3 + 1][b3] == 0)
return true;
else return false;
}
bool laft_moveable()
{
if (map[a0][b0 - 1] == 0 && map[a2][b2 - 1] == 0 && map[a1][b1 - 1] == 0 && map[a3][b3 - 1] == 0)
return true;
else return false;
}
bool right_moveable()
{
if (map[a1][b1 + 1] == 0 && map[a3][b3 + 1] == 0 && map[a0][b0 + 1] == 0 && map[a2][b2 + 1] == 0)
return true;
else return false;
}
bool shape_is_botton_adjacent()
{
if (is_block_adjacent(a3, b3))
return true;
else return false;
}
};
//“——”形狀類
class Heng :public Shape
{
public:
Heng(int a_0 = 1, int a_1 = 1, int a_2 = 1, int a_3 = 1, int b_0 = 7, int b_1 = 8, int b_2 = 9, int b_3 = 10)
{
a0 = a_0, a1 = a_1, a2 = a_2, a3 = a_3, b0 = b_0, b1 = b_1, b2 = b_2, b3 = b_3;
}
void click(char ch)
{
switch (ch)
{
case'a':
{
if (laft_moveable() == true)
{
clean();
b0--; b1--; b2--; b3--;
}
break;
}
case'd':
{
if (right_moveable() == true)
{
clean();
b0++; b1++; b2++; b3++;
}
break;
}
case's':
{
if (fall_moveable() == true)
{
clean();
a0++; a1++; a2++; a3++;
}
break;
}
}
}
void fall()
{
if (fall_moveable() == true)
{
clean();
a0++; a1++; a2++; a3++;
}
}
bool fall_moveable()
{
if (map[a0 + 1][b0] == 0 && map[a2 + 1][b2] == 0 && map[a1 + 1][b1] == 0 && map[a3 + 1][b3] == 0)
return true;
else return false;
}
bool laft_moveable()
{
if (map[a0][b0 - 1] == 0)
return true;
else return false;
}
bool right_moveable()
{
if (map[a3][b3 + 1] == 0)
return true;
else return false;
}
bool shape_is_botton_adjacent()//判斷形狀是否可以移動
{
if (is_block_adjacent(a0, b0) || is_block_adjacent(a1, b1) || is_block_adjacent(a2, b2) || is_block_adjacent(a3, b3))
return true;
else return false;
}
};
//遊戲類
class Game
{
public:
void start()
{
lable:
srand((unsigned)time(NULL));
int random = rand() % 3;
Shape *pt;
Tian tian;
Shu shu;
Heng heng;
switch (random)
{
case 0:pt = &tian; break;
case 1:pt = &shu; break;
case 2:pt = &heng; break;
}
while (1)
{
pt->init();
drawMap();
if (kbhit())
ch = getche();
if (ch == 'w')
{
pt->clean();
switch (random)
{
case 0:break;
case 1:
if (heng_shu_rotateable(pt->a1, pt->b1))
{
Heng heng2(pt->a1, pt->a1, pt->a1 , pt->a1, pt->b1-1, pt->b1, pt->b1+1, pt->b1+2);
pt = &heng2;
pt->init();
random = 2;
}
break;
case 2:
if (heng_shu_rotateable(pt->a1, pt->b1))
{
Shu shu2(pt->a1-1, pt->a1, pt->a1+1, pt->a1+2, pt->b1, pt->b1, pt->b1, pt->b1);
pt = &shu2;
pt->init();
random = 1;
}
break;
}
}
else
pt->click(ch);
pt->fall();
Sleep(400);
system("cls");
ch = '0';
if (pt->shape_is_botton_adjacent())
{
for (int a = 0; a < 20; a++)
{
if (is_full(a))
movedown(a);
}
goto lable;
}
system("cls");
ch = '0';
}
}
//判斷是否為滿行
bool is_full(int a)
{
int j = 0;
for (int i = 1; i < 17; i++)
{
if (map[a][i] == 2)j++;
}
if (j == 16)return true;
else return false;
}
//下移
void movedown(int a)
{
for (int i = a; i>1; i--)
for (int j = 1; j < 17; j++)
map[i][j] = map[i - 1][j];
for (int i2 = 1; i2<17; i2++)
map[1][i2] = 0;
}
//判斷橫豎是否可以旋轉
bool heng_shu_rotateable(int a, int b)
{
int x = 0;
for (int i = a - 1; i <= a + 2; i++)
{
for (int j = b - 1; j <= b + 2; j++)
{
if (map[i][j] != 0)x++;
}
}
if (x == 0)return true;
else return false;
}
};
void main()
{
Game game;
game.start();
}
可能你會發現複製貼上過去後發現,這個遊戲只能往下掉兩種形狀。
不要驚訝,這是我故意弄的。
如果你願意去看我的程式碼,那剩下的形狀你絕對能夠自己寫出來;
如果你不願意看,那就花積分去下載吧,我上傳的是完整版的。
萬一有要轉載的朋友後面加上出處哦