头文件及全局变量声明:
#include <iostream>
#include <Windows.h>
#include <ctime>
#include <conio.h>
#include <String>
using namespace std;
int death = 0;
int scores = 0;
首先枚举方向:(上下左右):
enum Direction {
Up,
Down,
Left,
Right
};
然后定义蛇身体(一个小方块)的结构体:
struct block {
int X;
int Y;
};
调用windows的API,实现控制台输出位置重定向:
void ToPosition(int x,int y){
COORD pos;
pos.X = x;
pos.Y = y;
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(hOut,pos);
}
调用windows的API,检测键盘输入:
void GetInput(int obj){ //等待键盘输入obj,否则一直等待
while(1) {
if(kbhit()) {
char ch = getch();
if(ch == obj)
return;
}
}
}
定义蛇类,构造函数中初始化位置并打印。数据成员包括蛇身(结构体数组),食物,当前方向,上次方向,刷新时间以及分数,方法包括刷新位置,打印蛇身,清空打印,食物初始化,刷新食物:
class snake {
public:
snake(){
score = 0;
length = 3;
s[0].X = 15;
s[0].Y = 10;
s[1].X = 14;
s[1].Y = 10;
s[2].X = 13;
s[2].Y = 10;
ToPosition(s[0].X,s[0].Y);
cout<<"@";
for(int i = 1; i < length; i++) {
ToPosition(s[i].X,s[i].Y);
cout<<"*";
}
lastDirection = Direction(3);
direction = Direction(3);
FoodInit();
}
void print(){
flash();
Clear();
Food();
ToPosition(food.X,food.Y);
cout<<"#";
for(int i = length - 1; i > 0; i--) {
s[i] = s[i-1];
}
if(direction == Up) {
s[0].X = s[0].X;
s[0].Y = s[0].Y - 1;
}
if(direction == Down) {
s[0].X = s[0].X;
s[0].Y = s[0].Y + 1;
}
if(direction == Left) {
s[0].X = s[0].X - 1;
s[0].Y = s[0].Y;
}
if(direction == Right) {
s[0].X = s[0].X + 1;
s[0].Y = s[0].Y;
}
ToPosition(s[0].X,s[0].Y);
cout<<"@";
for(int i = 1; i < length; i++) {
ToPosition(s[i].X,s[i].Y);
cout<<"*";
}
for(int i = 1; i < length; i++) {
if(s[0].X == s[i].X && s[0].Y == s[i].Y)
death=1;
}
if(s[0].X == 0 || s[0].X == 30 || s[0].Y == 1 || s[0].Y == 20)
death =1;
ToPosition(34,2);
cout<<"Score: "<<score;
}
void flash(){
char input = ' ';
int start = clock();
while(clock() - start < 200) {
if(kbhit()) {
input = getch();
}
}
switch(input) {
case 'a': if(direction!= Right) direction = Left; break;
case 'w': if(direction!= Down) direction = Up; break;
case 'd': if(direction!= Left) direction = Right; break;
case 's': if(direction!= Up) direction = Down; break;
case ' ': direction = lastDirection; break;
}
lastDirection = direction;
}
void Clear(){
for(int i = 1; i < 30; i++)
for(int j = 2; j < 20; j++) {
ToPosition(i,j);
cout<<" ";
}
}
void FoodInit(){
srand((unsigned)time(NULL));
food.X = rand()%28 + 2;
food.Y = rand()%18 + 2;
}
void Food(){
if(s[0].X == food.X && s[0].Y == food.Y) {
int flag = 1;
while(flag) {
srand((unsigned)time(NULL));
food.X = rand()%29 + 1;
food.Y = rand()%18 + 2;
for(int i = 0; i < length; i++) {
if(food.X == s[i].X && food.Y == s[i].Y) {
srand((unsigned)time(NULL));
food.X = rand()%29 + 1;
food.Y = rand()%18 + 2;
break;
}else{
flag = 0;
}
}
score++;
scores++;
s[length] = s[length-1];
length++;
}
}
}
private:
int length;
Direction direction;
Direction lastDirection;
int flashtime;
block s[100];
block food;
int score;
};
定义游戏类,构造函数中打印游戏界面,开始游戏。方法包括:开始游戏,运行游戏(死亡检测),结束游戏,打印游戏界面:
class Game {
public:
Game(){
for(int i = 0; i < 25; i++) {
ToPosition(0,i);
cout<<" ";
}
death = 0;
scores = 0;
PrintFrame();
GameStart();
}
void GameStart(){
GetInput(32);
ToPosition(34,12);
cout<<" ";
GameRun();
}
void GameRun(){
ToPosition(34,2);
snake sk;
while(!death) {
sk.print();
}
GameOver();
}
void GameOver(){
for(int i = 0; i < 25; i++) {
ToPosition(0,i);
cout<<" ";
}
ToPosition(0,0);
cout<<"GAME OVER!"<<endl;
cout<<"Score: "<<scores<<endl;
}
~Game(){
}
void PrintFrame(){
int Line = 30;
int Long = 20;
ToPosition(Long/2+3,0);
cout<<"SNAKE";
for(int i = 0; i < Line; i++) {
ToPosition(i,1);
cout<<"*";
ToPosition(i,Long);
cout<<"*";
}
for(int i = 1; i < Long + 1; i++) {
ToPosition(0,i);
cout<<"$";
ToPosition(Line,i);
cout<<"$";
}
ToPosition(34,7);
cout<<"Up: "<<"w";
ToPosition(34,8);
cout<<"Left: "<<"a";
ToPosition(34,9);
cout<<"Down: "<<"s";
ToPosition(34,10);
cout<<"Right: "<<"d";
ToPosition(34,12);
cout<<"Please press the space key to start the game.";
}
private:
};
主函数完成游戏启停逻辑:
int main(){
while(1) {
Game game;
cout<<"Please press the Y key to reload the game."<<endl;
GetInput(121);
}
return 0;
}
完整版代码附后,转载请注明出处。