學習編程的過程中,C++似乎是一個難以跨過的坎,好不容易能寫點基礎算法,遇到數據結構又是無從下手,筆者作爲一個業餘選手,由於工作需要順便寫點代碼的人,站在另一個視角給初學者還不能獨立擼代碼的人提供一個案例,從實戰中跨過這道障礙。
學習編程前期所有語言都是想通的,只是語法規則不同,循序結構、循環結構、選擇結構,之後C++又多了指針,函數,面向對象,因此,在理解和初步掌握基礎語法規則的基礎之上,獨立完成一個貪吃蛇小遊戲確實讓人有一種酣暢淋漓之感,麻雀雖小,五臟俱全,就從最開始做出貪吃蛇的外部圍牆,再考慮設計隨機出現的實物,再考慮蛇如何吃食物可以加長,不要參考別人的代碼,不懂的語法就去翻書,比如隨機數那塊我就是百度的,然後嵌入到自己的代碼中,完全憑藉自己的邏輯和不斷地調試去指導我們的編程。相信我,完成這個小任務之後立馬可以提高你的功力,徹底將編程作爲你的工具,之後要做的就是如何利用好這個工具。
Snake.h
#pragma once
#include <iostream>
#include <Windows.h>
#include <time.h>
#include <list>
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <stack>
using namespace std;
class Snake_Position
{
public:
int x_snake;
int y_snake;
};
//系統函數
void setColor(int color);
void GOTO(int x, int y);
void HiddenCursor();
//自定義函數
void Init_Map();
void Show_Snake();
void Init();
void isDead();
void Show_Score();
Snake.cpp
#include "Snake.h"
using namespace std;
void GOTO(int x, int y)
{
COORD wall{ 2 * x, y };
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), wall);
}
void setColor(int color)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color);
}
void HiddenCursor()
{
CONSOLE_CURSOR_INFO info;
info.dwSize = 1;
info.bVisible = FALSE;
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &info);
}
Main.cpp
#include "Snake.h"
int iScore = 0;
int iGrade = 1;
//蛇頭蛇尾初始位置
int x_head = 1, y_head = 3;
int x_tail = 1, y_tail = 1;
//地圖座標
int i_Map = 1, j_Map = 1;
//第二節初始位置
int x_second = 1, y_second = 2;
//初始化移動方向
int towards1 = 2; //原來方向
int towards2; //按鍵按下後的方向
const int SIDE = 20;
int Snake_Map[SIDE][SIDE] = { 0 };
int Speed = 300;
list<Snake_Position> LIST;
Snake_Position snake;
int main()
{
Init();
srand((unsigned)time(NULL));
char getKeyboard = 'd'; //從鍵盤讀取的鍵值
char getKeyboard_Vice = 'd'; //副本: 如果讀取其他值,則保持原來鍵值
while (1)
{
int isSendFood = 1; //1--不發送食物 0--發送食物
int iFood;
int x = rand() % 18 + 1;
int y = rand() % 18 + 1;
setColor(6);
HiddenCursor();
GOTO(y, x);
cout << "★";
if (Snake_Map[x][y] != 2)
Snake_Map[x][y] = 3;
else
continue;
while (isSendFood)
{
if (_kbhit())
getKeyboard = _getch();
if (getKeyboard != 's' && getKeyboard != 'S' && getKeyboard != 'a' && getKeyboard != 'A' && getKeyboard != 'w' && getKeyboard != 'W' && getKeyboard != 'd' && getKeyboard != 'D')
getKeyboard = getKeyboard_Vice;
switch (getKeyboard)
{
case 'W':
case 'w':
towards2 = 4;
if ((towards1 + towards2) == 5)
{
getKeyboard = getKeyboard_Vice;
break;
}
towards1 = towards2; //如果現在方向合理,則保存方向到towards1
x_head -= 1;
isDead();
if (Snake_Map[x_head][y_head] == 3) //吃到食物
{
isSendFood = 0;
iScore += 1;
snake.x_snake = x_head;
snake.y_snake = y_head;
LIST.push_front(snake);
Snake_Map[x_head][y_head] = 2;
setColor(7);
HiddenCursor();
GOTO(y_head, x_head);
cout << "○";
}
else
{
snake.x_snake = x_head;
snake.y_snake = y_head;
LIST.push_front(snake);
Snake_Map[LIST.back().x_snake][LIST.back().y_snake] = 0;
setColor(7);
HiddenCursor();
GOTO(y_head, x_head);
cout << "○";
setColor(7);
HiddenCursor();
GOTO(LIST.back().y_snake, LIST.back().x_snake);
cout << " ";
LIST.pop_back();
}
Snake_Map[x_head][y_head] = 2;
Show_Score();
Sleep(Speed);
//Show_Snake();
getKeyboard_Vice = 'w';
break;
case 'S':
case 's':
towards2 = 1;
if ((towards1 + towards2) == 5)
{
getKeyboard = getKeyboard_Vice;
break;
}
towards1 = towards2;
x_head += 1;
isDead();
if (Snake_Map[x_head][y_head] == 3) //吃到食物
{
isSendFood = 0;
iScore += 1;
snake.x_snake = x_head;
snake.y_snake = y_head;
LIST.push_front(snake);
Snake_Map[x_head][y_head] = 2;
setColor(7);
HiddenCursor();
GOTO(y_head, x_head);
cout << "○";
}
else
{
snake.x_snake = x_head;
snake.y_snake = y_head;
LIST.push_front(snake);
Snake_Map[LIST.back().x_snake][LIST.back().y_snake] = 0;
setColor(7);
HiddenCursor();
GOTO(y_head, x_head);
cout << "○";
setColor(7);
HiddenCursor();
GOTO(LIST.back().y_snake, LIST.back().x_snake);
cout << " ";
LIST.pop_back();
}
Snake_Map[x_head][y_head] = 2;
Show_Score();
Sleep(Speed);
//Show_Snake();
getKeyboard_Vice = 's';
break;
case 'A':
case 'a':
towards2 = 3;
if ((towards1 + towards2) == 5)
{
getKeyboard = getKeyboard_Vice;
break;
}
towards1 = towards2;
y_head -= 1;
isDead();
if (Snake_Map[x_head][y_head] == 3) //吃到食物
{
isSendFood = 0;
iScore += 1;
snake.x_snake = x_head;
snake.y_snake = y_head;
LIST.push_front(snake);
Snake_Map[x_head][y_head] = 2;
setColor(7);
HiddenCursor();
GOTO(y_head, x_head);
cout << "○";
}
else
{
snake.x_snake = x_head;
snake.y_snake = y_head;
LIST.push_front(snake);
Snake_Map[LIST.back().x_snake][LIST.back().y_snake] = 0;
setColor(7);
HiddenCursor();
GOTO(y_head, x_head);
cout << "○";
setColor(7);
HiddenCursor();
GOTO(LIST.back().y_snake, LIST.back().x_snake);
cout << " ";
LIST.pop_back();
}
Snake_Map[x_head][y_head] = 2;
Show_Score();
Sleep(Speed);
//Show_Snake();
getKeyboard_Vice = 'a';
break;
case 'D':
case 'd':
towards2 = 2;
if ((towards1 + towards2) == 5)
{
getKeyboard = getKeyboard_Vice;
break;
}
towards1 = towards2;
y_head += 1;
isDead();
if (Snake_Map[x_head][y_head] == 3) //吃到食物
{
isSendFood = 0;
iScore += 1;
snake.x_snake = x_head;
snake.y_snake = y_head;
LIST.push_front(snake);
Snake_Map[x_head][y_head] = 2;
setColor(7);
HiddenCursor();
GOTO(y_head, x_head);
cout << "○";
}
else
{
snake.x_snake = x_head;
snake.y_snake = y_head;
LIST.push_front(snake);
Snake_Map[LIST.back().x_snake][LIST.back().y_snake] = 0;
setColor(7);
HiddenCursor();
GOTO(y_head, x_head);
cout << "○";
setColor(7);
HiddenCursor();
GOTO(LIST.back().y_snake, LIST.back().x_snake);
cout << " ";
LIST.pop_back();
}
Snake_Map[x_head][y_head] = 2;
Show_Score();
Sleep(Speed);
//Show_Snake();
getKeyboard_Vice = 'd';
break;
default:
break;
}
}
}
system("pause");
return 0;
}
void Init_Map()
{
for (int i = 0; i < SIDE; i++)
{
for (int j = 0; j < SIDE; j++)
{
if (i == 0 || i == SIDE - 1 || j == 0 || j == SIDE - 1)
{
GOTO(i, j);
cout << "■";
}
}
}
}
void Show_Snake()
{
for (int i = 1; i < SIDE - 1; i++)
{
for (int j = 1; j < SIDE - 1; j++)
{
if (Snake_Map[i][j] == 3)
{
GOTO(j, i);
cout << "★";
}
if (Snake_Map[i][j] == 2)
{
GOTO(j, i);
cout << "○";
}
if (Snake_Map[i][j] == 0)
{
GOTO(j, i);
cout << " ";
}
}
}
}
void Init()
{
Init_Map(); //初始化顯示地圖
for (int i = 0; i < SIDE; i++)
{
for (int j = 0; j < SIDE; j++)
{
if (i == 0 || i == SIDE - 1 || j == 0 || j == SIDE - 1)
Snake_Map[i][j] = 9;
}
}
//將蛇的初始三節座標依次保存到LIST中
Snake_Map[1][1] = 2;
snake.x_snake = 1;
snake.y_snake = 1;
LIST.push_front(snake);
Snake_Map[1][2] = 2;
snake.x_snake = 1;
snake.y_snake = 2;
LIST.push_front(snake);
Snake_Map[1][3] = 2;
snake.x_snake = 1;
snake.y_snake = 3;
LIST.push_front(snake);
Show_Snake();
}
void isDead()
{
if (Snake_Map[x_head][y_head] == 9 || Snake_Map[x_head][y_head] == 2) //死亡條件
{
system("cls");
cout << "你已經掛了, 遊戲結束!" << endl;
Sleep(2000);
exit(-1);
}
}
void Show_Score()
{
if (iScore == 5)
{
iGrade = 2;
Speed = 250;
//Sleep(2000);
}
if (iScore == 10)
{
iGrade = 3;
Speed = 200;
//Sleep(2000);
}
if (iScore == 15)
{
setColor(4);
HiddenCursor();
GOTO(5, 5);
cout << "您已達到王者級別";
Sleep(5000);
exit(0);
}
setColor(4);
HiddenCursor();
GOTO(30, 8);
cout << "級別: " << iGrade;
GOTO(30, 12);
cout << "得分: " << iScore;
}