# 小恐龍專題
## 修改部分
### 遊戲介面及規則
* 增加遊戲封面以及遊戲結束的畫面,按下空白鍵開始遊戲或重玩。
* 增加顏色顯示
* 另外分數的部分要跳過障礙物或是破壞障礙物才能得分
* 分數每多200分,地圖會加速一點點。
### 功能部分
* 增加了**無敵星星道具**,地圖上隨機增加 * 符號,當角色碰到時會變成 O) ,並獲得30秒無敵效果。
* 增加了**迴力鏢道具**,當使用者按下B按鍵時,丟出迴力鏢,沿途壞障礙物並進入道具**冷卻時間(50秒)**,p.s **(要謹慎使用,因為迴力鏢也會把無敵星星破壞掉)**,另外之所以叫做迴力鏢是因為它會飛回來,而這時也要**躲避**飛回來的迴力鏢,否則就死掉了。
* 增加了**旋風砲**道具,當使用者按下C按鍵時,發射旋風砲彈,破壞**全地圖所有障礙物(包含無敵星星以及飛回來的迴力鏢)** 並進入道具**冷卻時間(120秒)**
---
## 遊戲介面及規則
### 遊戲封面以及結束畫面
```c++=
void display_start(void)
{
system("cls");
printf("\t __\n");
printf("\t / _) __\033[33mHello!!!\033[0m\n");
printf("\t _.----._/ / \n");
printf("\t / / \n");
printf("\t __/ ( | ( |\n");
printf("\t/__.-'|_|--|_|\n");
printf("\n\n\t");
printf("\033[36mWelcome to the Dino Game!\n\n\n\033[0m");
printf("\tPress Space to start the game!\n");
return;
}
void display_gameover(Dino* MyDino)
{
system("cls");
printf("\n\n\t");
printf("\033[31mGame Over!\033[0m\n\n\n");
printf("\tYour final score is: \033[33m%d\033[0m\n\n", MyDino->score);
printf("\tPress Space to play again.\n");
// 加入等待按下空白鍵的功能
while (!_kbhit() || _getch() != 32)
{
Sleep(100);
}
return;
}
```
### 遊戲封面

### 結束畫面

### 顏色顯示範例
```c++=
printf("\033[36mWelcome to the Dino Game!\n\n\n\033[0m");
```
### 跳過障礙物或是破壞障礙物才可以得分
```C++=
//跳過了障礙物才能加分 (10分)
if (MyDino->jump_time_left != 0 && MyDino->road[DINO_PLACE] == 'X')
{
MyDino->score += 10;
}
//破壞障礙物加分 (20分)
if (MyDino->jump_time_left == 0 && MyDino->road[DINO_PLACE] == '.')
{
MyDino->score += 20;
}
```
### 地圖加速
```C++=
void move(Dino* MyDino)
{
for (int i = 0; i < ROAD_LENGTH - 1; i++)
{
MyDino->road[i] = MyDino->road[i + 1];
}
// 加入根據分數增加小恐龍速度的功能
if (MyDino->score > 0 && MyDino->score % 200 == 0)
{
MyDino->wait_time -= 10;
}
MyDino->road[ROAD_LENGTH - 1] = '_';
}
```
---
## 功能部分
## 無敵星星功能
### 碰到無敵星星時,障礙物會變成 . 角色可直接穿過(表示破壞障礙物)
```C++=
//當碰到無敵星星時,障礙物會變成 '.' 且角色可直接穿過(加20分)
if (MyDino->star_time > 0)
{
MyDino->star_time -= 1;
for (int i = 0; i < ROAD_LENGTH; i++)
{
if (MyDino->road[i] == 'X')
{
MyDino->road[i] = '.';
}
}
}
```
### 碰到無敵星星時,改變角色型態
```C++=
if (MyDino->star_time != 0)
{
printf("\033[33mO)\033[0m");
}
else
{
printf("O");
}
```
### * 產生
```C++=
bool spawn_star(Dino* MyDino)
{
int random_number = rand() % 100;
if (random_number < MyDino->star_chance)
return true;
return false;
}
```
### 判斷是否有吃到無敵星星
```C++=
bool star_bumped(Dino* MyDino)
{
return MyDino->jump_time_left == 0 && MyDino->road[DINO_PLACE] == '*';
}
```
### 出現無敵星星
```C++=
if (spawn_star(MyDino))
{
MyDino->road[ROAD_LENGTH - 1] = '*';
}
```
### 判斷是否為無敵時間
```C++=
if (is_bumped(MyDino))
{
if (MyDino->star_time != 0)
{
display(MyDino);
}
else
{
display_gameover(MyDino); // 遊戲結束,顯示遊戲結束畫面
break;
}
}
```
### 無敵星星展示畫面

---
## 迴力鏢功能
### 當B按鍵按下
```C++=
bool b_pressed(void)
{
return _kbhit() != 0 && _getch() == 66;
}
```
### 顯示迴力鏢
```C++=
// 顯示迴力鏢
else if (MyDino->boomerangright > 0 && i == MyDino->boomerangright)
{
printf("\033[36m>\033[0m");
}
```
### 迴力鏢破壞沿途障礙物(包含無敵星星)
```c++=
// 迴力鏢破壞沿途障礙物(包含 * 無敵星星)
if (MyDino->boomerangright > 0 && MyDino->boomerangright < ROAD_LENGTH)
{
MyDino->boomerangright++;
MyDino->boomerang_count--;
if (MyDino->road[MyDino->boomerangright] == 'X' || MyDino->road[MyDino->boomerangright] == '*')
{
MyDino->road[MyDino->boomerangright] = '.';
}
if (MyDino->road[MyDino->boomerangright - 1] == 'X' || MyDino->road[MyDino->boomerangright - 1] == '*')
{
MyDino->road[MyDino->boomerangright - 1] = '.';
}
}
// 迴力鏢到底時返回
else if (MyDino->boomerangright == ROAD_LENGTH)
{
MyDino->boomerangright = 0;
MyDino->boomerang_count = 0;
MyDino->road[ROAD_LENGTH - 1] = '<';
}
if (MyDino->key == 'B' && MyDino->boomerangright == 0)
{
// continue;
MyDino->boomerangright = DINO_PLACE;
MyDino->boomerang_count = 50;
}
```
### 顯示迴力鏢可用及冷卻
```c++=
// 迴力鏢可用及冷卻顯示
if (MyDino->boomerangright == 0)
{
printf("\033[42;37m\n\t\tBoomerang Available : Press \033[30mB\033[42;37m to use it\n\033[0m");
}
else if (MyDino->boomerangright != 0 && MyDino->key == 'B')
{
printf("\033[47;30m\n\t\tBoomerang Cooling : %d\n\033[0m", MyDino->boomerang_count);
}
else if (MyDino->boomerangright != 0)
{
printf("\033[41;37m\n\t\tWARRNING!!!\n\033[0m \t\t\033[41;37mWATCH OUT for your Boomerang WHEN IT FLIES BACK!!!\n\033[0m");
printf("\033[43;31m\n\t\tBoomerang Cooling : %d\n\033[0m", MyDino->boomerang_count);
}
```
### 迴力鏢展示畫面


---
## 旋風炮功能
### 當C按鍵按下
```C++=
// C鍵按下
bool c_pressed(void)
{
return _kbhit() != 0 && _getch() == 67;
}
```
### 顯示旋風砲
```C++=
// 顯示旋風砲
else if (MyDino->cannon_time == 119 && i > DINO_PLACE)
{
printf("\033[43;31m!\033[0m");
}
```
### 旋風炮函式
```C++=
// 旋風砲函式
void cannon(Dino* MyDino)
{
if (MyDino->key == 'C' && MyDino->cannon_time == 0)
{
for (int i = DINO_PLACE + 1; i < ROAD_LENGTH; i++)
{
if (MyDino->road[i] == 'X' || MyDino->road[i] == '*' || MyDino->road[i] == '<')
{
MyDino->road[i] = '.';
}
}
MyDino->cannon_time = 120; // 設定冷卻時間為120秒
}
if (MyDino->cannon_time > 0)
{
MyDino->cannon_time--; // 每次執行,冷卻時間減1
}
}
```
### 顯示旋風炮可用及冷卻
```C++=
// 旋風砲可用及冷卻顯示
if (MyDino->cannon_time == 0)
{
printf("\033[42;37m\n\t\tCannon Available : Press \033[30mC\033[42;37m to use it\n\033[0m");
}
else if (MyDino->cannon_time != 0 && MyDino->key == 'C')
{
printf("\033[47;30m\n\t\tCannon Cooling : %d\033[0m", MyDino->cannon_time);
}
else if (MyDino->cannon_time != 0)
{
printf("\033[43;31m\n\t\tCannon Cooling : %d\033[0m", MyDino->cannon_time);
}
```
### 旋風炮展示畫面

---
## 完整程式碼
```C++
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <windows.h>
#include <time.h>
#define ROAD_LENGTH 50 // 路面長度
#define DINO_PLACE 6 // 小恐龍在路面上的第幾格
struct dino
{
char road[ROAD_LENGTH + 1]; // 字串結尾需要'\0'
int jump_time_left; // 還剩多久掉回地面
int score; // 分數
int wait_time; // 每次迴圈之間等待的時間
int barrier_chance; // 放置障礙物的機率
int star_chance; // 無敵星星的機率
int star_time; // 無敵倒數
int boomerangright; // 迴力鏢位置
int boomerang_count; // 迴力鏢冷卻
int cannon_time; // 旋風砲冷卻
int key; // 按鍵
};
typedef struct dino Dino;
bool space_pressed(void)
{
return _kbhit() != 0 && _getch() == 32;
}
int keyboard()
{
if (_kbhit())
{
return _getch();
}
else
{
return -1;
}
}
// B鍵按下
bool b_pressed(void)
{
return _kbhit() != 0 && _getch() == 66;
}
// C鍵按下
bool c_pressed(void)
{
return _kbhit() != 0 && _getch() == 67;
}
void move(Dino* MyDino)
{
for (int i = 0; i < ROAD_LENGTH - 1; i++)
{
MyDino->road[i] = MyDino->road[i + 1];
}
// 加入根據分數增加小恐龍速度的功能
if (MyDino->score > 0 && MyDino->score % 200 == 0)
{
MyDino->wait_time -= 10;
}
MyDino->road[ROAD_LENGTH - 1] = '_';
}
Dino* init(void)
{
Dino* MyDino = (Dino*)malloc(sizeof(Dino));
if (MyDino != NULL)
{
MyDino->score = 0;
MyDino->jump_time_left = 0;
MyDino->wait_time = 150;
MyDino->barrier_chance = 10;
MyDino->star_chance = 1;
MyDino->star_time = 0;
MyDino->boomerangright = 0;
MyDino->boomerang_count = 50;
MyDino->cannon_time = 0;
for (int i = 0; i < ROAD_LENGTH; i++)
{
MyDino->road[i] = '_';
}
MyDino->road[ROAD_LENGTH] = '\0';
}
return MyDino;
}
void display_start(void)
{
system("cls");
printf("\t __\n");
printf("\t / _) __\033[33mHello!!!\033[0m\n");
printf("\t _.----._/ / \n");
printf("\t / / \n");
printf("\t __/ ( | ( |\n");
printf("\t/__.-'|_|--|_|\n");
printf("\n\n\t");
printf("\033[36mWelcome to the Dino Game!\n\n\n\033[0m");
printf("\tPress Space to start the game!\n");
return;
}
void display_gameover(Dino* MyDino)
{
system("cls");
printf("\n\n\t");
printf("\033[31mGame Over!\033[0m\n\n\n");
printf("\tYour final score is: \033[33m%d\033[0m\n\n", MyDino->score);
printf("\tPress Space to play again.\n");
// 加入等待按下空白鍵的功能
while (!_kbhit() || _getch() != 32)
{
Sleep(100);
}
return;
}
void display(Dino* MyDino)
{
system("cls");
printf("\n\n\t");
for (int i = 0; i < ROAD_LENGTH; i++)
{
if (i == DINO_PLACE && MyDino->jump_time_left > 0)
{
if (MyDino->star_time != 0)
{
printf("\033[33mO)\033[0m");
}
else
{
printf("O");
}
}
else
{
printf(" ");
}
}
printf("\n\t");
for (int i = 0; i < ROAD_LENGTH; i++)
{
if (i == DINO_PLACE && MyDino->jump_time_left == 0)
{
if (MyDino->star_time != 0)
{
printf("\033[33mO)\033[0m");
}
else
{
printf("O");
}
}
// 顯示迴力鏢
else if (MyDino->boomerangright > 0 && i == MyDino->boomerangright)
{
printf("\033[36m>\033[0m");
}
// 顯示旋風砲
else if (MyDino->cannon_time == 119 && i > DINO_PLACE)
{
printf("\033[43;31m!\033[0m");
}
else
{
printf("%c", MyDino->road[i]);
}
}
printf("\n\n\n\t");
printf("\t\tCurrent Score : %d\n", MyDino->score);
if (MyDino->star_time != 0)
{
printf("\033[47;30m\n\t\t\tInvincibility Countdown : %d\n\033[0m", MyDino->star_time);
}
// 迴力鏢可用及冷卻顯示
if (MyDino->boomerangright == 0)
{
printf("\033[42;37m\n\t\tBoomerang Available : Press \033[30mB\033[42;37m to use it\n\033[0m");
}
else if (MyDino->boomerangright != 0 && MyDino->key == 'B')
{
printf("\033[47;30m\n\t\tBoomerang Cooling : %d\n\033[0m", MyDino->boomerang_count);
}
else if (MyDino->boomerangright != 0)
{
printf("\033[41;37m\n\t\tWARRNING!!!\n\033[0m \t\t\033[41;37mWATCH OUT for your Boomerang WHEN IT FLIES BACK!!!\n\033[0m");
printf("\033[43;31m\n\t\tBoomerang Cooling : %d\n\033[0m", MyDino->boomerang_count);
}
// 旋風砲可用及冷卻顯示
if (MyDino->cannon_time == 0)
{
printf("\033[42;37m\n\t\tCannon Available : Press \033[30mC\033[42;37m to use it\n\033[0m");
}
else if (MyDino->cannon_time != 0 && MyDino->key == 'C')
{
printf("\033[47;30m\n\t\tCannon Cooling : %d\033[0m", MyDino->cannon_time);
}
else if (MyDino->cannon_time != 0)
{
printf("\033[43;31m\n\t\tCannon Cooling : %d\033[0m", MyDino->cannon_time);
}
return;
}
bool is_bumped(Dino* MyDino)
{
if (MyDino->star_time != 0)
{
return MyDino->jump_time_left == 0 && MyDino->road[DINO_PLACE] == '.';
}
else
{
return MyDino->jump_time_left == 0 && (MyDino->road[DINO_PLACE] == 'X' || MyDino->road[DINO_PLACE] == '<');
}
}
bool spawn_barrier(Dino* MyDino)
{
int random_number = rand() % 100;
if (random_number < MyDino->barrier_chance)
return true;
return false;
}
bool star_bumped(Dino* MyDino)
{
return MyDino->jump_time_left == 0 && MyDino->road[DINO_PLACE] == '*';
}
bool spawn_star(Dino* MyDino)
{
int random_number = rand() % 100;
if (random_number < MyDino->star_chance)
return true;
return false;
}
// 旋風砲函式
void cannon(Dino* MyDino)
{
if (MyDino->key == 'C' && MyDino->cannon_time == 0)
{
for (int i = DINO_PLACE + 1; i < ROAD_LENGTH; i++)
{
if (MyDino->road[i] == 'X' || MyDino->road[i] == '*' || MyDino->road[i] == '<')
{
MyDino->road[i] = '.';
}
}
MyDino->cannon_time = 120; // 設定冷卻時間為120秒
}
if (MyDino->cannon_time > 0)
{
MyDino->cannon_time--; // 每次執行,冷卻時間減1
}
}
int main()
{
/* 初始化 */
srand(time(NULL));
Dino* MyDino = init();
display_start(); // 新增遊戲開始畫面
/* 遊戲本體 */
while (true)
{
/* 開始遊戲 */
if (space_pressed())
{
display(MyDino);
/* 遊戲循環 */
while (true)
{
/* 遊戲邏輯 */
MyDino->key = keyboard();
if (MyDino->key == 32 && MyDino->jump_time_left == 0)
{
MyDino->jump_time_left = 3;
}
move(MyDino);
cannon(MyDino);
if (spawn_barrier(MyDino))
{
if (MyDino->star_time != 0)
{
MyDino->road[ROAD_LENGTH - 1] = '.';
}
else
{
MyDino->road[ROAD_LENGTH - 1] = 'X';
}
}
if (MyDino->jump_time_left > 0)
MyDino->jump_time_left -= 1;
if (is_bumped(MyDino))
{
if (MyDino->star_time != 0)
{
display(MyDino);
}
else
{
display_gameover(MyDino); // 遊戲結束,顯示遊戲結束畫面
break;
}
}
// 迴力鏢破壞沿途障礙物(包含 * 無敵星星)
if (MyDino->boomerangright > 0 && MyDino->boomerangright < ROAD_LENGTH)
{
MyDino->boomerangright++;
MyDino->boomerang_count--;
if (MyDino->road[MyDino->boomerangright] == 'X' || MyDino->road[MyDino->boomerangright] == '*')
{
MyDino->road[MyDino->boomerangright] = '.';
}
if (MyDino->road[MyDino->boomerangright - 1] == 'X' || MyDino->road[MyDino->boomerangright - 1] == '*')
{
MyDino->road[MyDino->boomerangright - 1] = '.';
}
}
// 迴力鏢到底時返回
else if (MyDino->boomerangright == ROAD_LENGTH)
{
MyDino->boomerangright = 0;
MyDino->boomerang_count = 0;
MyDino->road[ROAD_LENGTH - 1] = '<';
}
if (MyDino->key == 'B' && MyDino->boomerangright == 0)
{
// continue;
MyDino->boomerangright = DINO_PLACE;
MyDino->boomerang_count = 50;
}
// 跳過了障礙物才能加分 (10分)
if (MyDino->jump_time_left != 0 && MyDino->road[DINO_PLACE] == 'X')
{
MyDino->score += 10;
}
if (spawn_star(MyDino))
{
MyDino->road[ROAD_LENGTH - 1] = '*';
}
// 當碰到無敵星星時,障礙物會變成 '.' 且角色可直接穿過(加20分)
if (MyDino->star_time > 0)
{
MyDino->star_time -= 1;
for (int i = 0; i < ROAD_LENGTH; i++)
{
if (MyDino->road[i] == 'X')
{
MyDino->road[i] = '.';
}
}
}
if (star_bumped(MyDino))
{
MyDino->star_time = 30;
}
// 破壞障礙物加分 (20分)
if (MyDino->jump_time_left == 0 && MyDino->road[DINO_PLACE] == '.')
{
MyDino->score += 20;
}
/* 渲染呈現 */
display(MyDino);
Sleep(MyDino->wait_time);
}
/* 重新初始化遊戲 */
free(MyDino);
MyDino = init();
display_start();
}
}
return 0;
}
```
## 示範影片
[連結](https://youtu.be/RQCLYNoIAlM)