C语言练手游戏-控制台输出一个会移动的坦克

把C语言的知识融合起来做一个练手的小游戏项目,将自己掌握到的数据结构、数组、函数、宏定义等知识综合利用,增加对语法的熟练程度。

操作系统: windows 10 x64
编译IDE : VS2015

  // 实现一个能在屏幕上自由移动的坦克.cpp : 定义控制台应用程序的入口点。


#include "stdafx.h"
#include <windows.h>
#include <conio.h>


//方向宏定义
#define  UP    0
#define  DOWN  1
#define  LEFT  2
#define  RIGHT 3



//全局数组,画地图用
int g_map[40][40] = { 0 };


//坦克数据结构
typedef struct _TANKINFO
{
	unsigned int nNosX;                   //坦克X坐标 
	unsigned int nNosY;					  //坦克Y坐标 
	unsigned int nLevel;				  //坦克等级
	unsigned int nMaxHP;				  //坦克最大血值
	unsigned int nCurlHP;				  //坦克当前血值
	unsigned int nOldSpeed;				  //坦克原始速度
	unsigned int nSpeed;				  //坦克当前速度
	unsigned int nDirection;			  //坦克方向
	unsigned int nGodirection;			  //坦克想要改变的方向
	unsigned int nKill;					  //坦克杀敌数
	unsigned int nDie;					  //坦克死亡数
	unsigned int wColor;				  //坦克颜色
	unsigned int nIndex;				  //坦克在数组中的数值
	unsigned int nBulletType;			  //初始坦克的子弹类型
	bool         bSubSpeed;				  //是否被减速
	char*        szForm;				  //坦克组成的样子
	char*        szBuff;				  //状态
}TANKINFO,*PTANKINFO;

TANKINFO tank;


//坦克样式结构,上下左右方向
int tankstyle[4][3][3] =
{
	//方向向上的坦克
	{
		{0,1,0},
		{1,1,1},
		{1,0,1}

	},

	//方向向下的坦克
	{
		{1,0,1},
		{1,1,1},
		{0,1,0}
	},

	//方向向左的坦克
	{
		{0,1,1},
		{1,1,0},
		{0,1,1}
	},

	//方向向右的坦克
	{
		{1,1,0},
		{0,1,1},
		{1,1,0}
	}
};

//血量绘画
char *m_blood[10] = {" ①","②","③","④","⑤","⑥","⑦","⑧","⑨","⑩" };


//按键接收
char KeyBoardMonitor() 
{
	char ch;
	if (_kbhit())
	{
		ch = _getch();
	}
	else
	{
		return 0;
	}
	return ch;
}

//画图函数
void writeChar(int High, int Wide, char * pszChar, WORD wArr)
{
	//设置光标属性
	CONSOLE_CURSOR_INFO cci;
	cci.dwSize = 1;        // 光标百分比厚度(1~100)
	cci.bVisible = FALSE; //是否显示光标
	SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cci);
	//设置坐标
	COORD loc;
	loc.X = Wide * 2; //X的值是Wide的2倍;
	loc.Y = High;
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), wArr);
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), loc);
	printf(pszChar);  //打印时需要注意有些特殊字符是占2个字节
}


//清除坦克
void clsTank() 
{
	for (unsigned int y = tank.nNosY - 1,i=0;  y <= tank.nNosY + 1;  y++,i++)
	{
		for (unsigned int x = tank.nNosX-1,j=0;x<= tank.nNosX+1;x++,j++)
		{
			//用坦克的方向对照坦克模型数组,把坦克在界面上画出来
			writeChar(y, x, "  ",FOREGROUND_GREEN);

		}
	}
}

//绘画坦克
void DrawTank()
{
	for (unsigned int y = tank.nNosY - 1, i = 0; y <= tank.nNosY + 1; y++, i++)
	{
		for (unsigned int x = tank.nNosX - 1, j = 0; x <= tank.nNosX + 1; x++, j++)
		{
			//用坦克的方向对照坦克模型数组,把坦克在界面上画出来
			writeChar(y, x, tankstyle[tank.nDirection][i][j] == 1 ? "█" : "  ", FOREGROUND_RED);

		}
	}
}


//坦克撞墙检测
bool allowMove() 
{
	if ((tank.nNosX <= 1)
		||
		(tank.nNosX >= 38)                                            //画图边界判断
		||
		(tank.nNosY <= 2)
		||
		(tank.nNosY >= 38)
		)
	{
		return false;
	}
	return true;
}

//移动坦克
void moveTank() 
{


	clsTank();

	//碰撞检查
	if (allowMove() == false)
	{
		MessageBoxA(0, "撞墙啦!", "扑街", 0);
		clsTank();
		DrawTank();
	}


		if (tank.nDirection != tank.nGodirection)
		{
			tank.nDirection = tank.nGodirection;                                //根据键盘获取到的键盘赋值到现有的方向
		}
		else
		{

			switch (tank.nGodirection)
			{
			case UP:
			{
				tank.nNosY--;
				break;
			}

			case DOWN:
			{
				tank.nNosY++;
				break;
			}

			case LEFT:
			{
				tank.nNosX--;
				break;
			}

			case RIGHT:
			{
				tank.nNosX++;
				break;
			}
			}
		}
	

	DrawTank();

}

//画出地图
void DrawMap() 
{
	//遇到四周,那么写入1
	for (int row = 0; row < 40; row++)
	{
		for (int col = 0; col < 40; col++)
		{
			if ((row == 0)
				||
				(row == 39)
				||
				(col == 0)
				||
				(col == 39)
				)
			{
				g_map[row][col] = 1;
			}
			else
			{
				g_map[row][col] = 0;

			}
		}
	}
	//输出所有的地图
	for (int row = 0; row < 40; row++)
	{
		for (int col = 0; col < 40; col++)
		{
			if (g_map[row][col] == 1)
			{
				printf("■");
			}
			else
			{
				printf("  ");
			}
		}
		printf("
");
	}

}


int main()
{
	//给坦克赋值
	tank.nNosX = 10;
	tank.nNosY = 10;
	
	//画出地图
	DrawMap();
	//画出坦克
	DrawTank();

	char ch;
	while(true)
	{
		ch = KeyBoardMonitor();
		if (ch == 0)
		{
			continue;
		}
		if (ch == VK_ESCAPE) 
		{
			break;
		}
		switch (ch)
		{
		case 'w':
		{
			tank.nGodirection = UP;
		}
		break;
		case 's':
		{
			tank.nGodirection = DOWN;
		}
		break;
		case 'a':
		{
			tank.nGodirection = LEFT;
		}
		break;
		case 'd':
		{
			tank.nGodirection = RIGHT;
		}
		break;
		}
		moveTank();
	}


    return 0;
}


运行效果

原文地址:https://www.cnblogs.com/17bdw/p/6048060.html