C++练习实例———控制台实现坦克大战小游戏

    本篇文章总结一下我在网上看到的一个C++坦克大战小游戏,我在原有的基础上加入了技能功能,并对碰撞代码进行了改进,然后将代码进行了整理,感觉很有意思。游戏中用到了EasyX图形库,这个库非常小巧轻便,下载地址:https://www.easyx.cn/downloads/ 

    现在正文开始,首先,创建一个简单的坐标类

#ifndef POINT_H
#define POINT_H
//坐标类
class Point
{
public:
	Point(int x = 0, int y = 0) : m_x(x), m_y(y) {};
	~Point() {};
	Point& operator=(const Point &p)
	{
		m_x = p.m_x;
		m_y = p.m_y;
		return *this;
	}
	void Set(int x, int y){
		m_x = x;
		m_y = y;
	}
	void SetX(int x) { m_x = x; }
	void SetY(int y) { m_y = y; }
	int GetX() const{ return m_x; }
	int GetY()const {return m_y;}
private:
	int m_x;
	int m_y;
};


#endif

   然后为了便于画图,创建一个Rect类

#include "Point.h"
#ifndef RECT_H
#define RECT_H
//矩形类,便于画图
class Rect
{
public:
	Rect(int x1 = 0, int y1 = 0, int x2 = 0, int y2 = 0) :
		m_StartPoint(x1, y1), m_EndPoint(x2, y2)
	{}
	Rect(const Point p1, const Point p2) :
		m_StartPoint(p1), m_EndPoint(p2)
	{}
	Rect(const Rect& r1):
		m_StartPoint(r1.GetStartPoint()), m_EndPoint(r1.GetEndPoint())
	{}
	~Rect() {};
	void SetRect(const Point pStart, const Point pEnd);
	void SetRect(int x1, int y1, int x2, int y2);
	void SetStartPoint(const Point p){ m_StartPoint = p; }
	void SetEndPoint(const Point p){ m_EndPoint = p; }
	Point GetStartPoint() const{ return m_StartPoint; }
	Point GetEndPoint() const{ return m_EndPoint; }
	Point GetRightPoint() const; 
	Point GetLeftPoint() const; 
	Rect& operator=(const Rect &rect)
	{
		m_StartPoint = rect.GetStartPoint();
		m_EndPoint = rect.GetEndPoint();
		return *this;
	}
	int GetWidth();
	int GetHeight();

private:
	Point m_StartPoint;//矩形左上角的坐标点
	Point m_EndPoint;//矩形右下角的坐标点
};

#endif
#include "Rect.h"

void Rect::SetRect(Point pStart, Point pEnd)
{
	m_StartPoint = pStart;
	m_EndPoint = pEnd;
}

void Rect::SetRect(int x1, int y1, int x2, int y2)
{
	m_StartPoint.Set(x1, y1);
	m_EndPoint.Set(x2, y2);
}
Point Rect::GetRightPoint() const
{
	Point p = m_StartPoint;
	p.SetX(m_EndPoint.GetX());
	return p;
}

Point Rect::GetLeftPoint() const
{
	Point p = m_StartPoint;
	p.SetY(m_EndPoint.GetY());
	return p;
}

int Rect::GetWidth()
{
	return m_EndPoint.GetX() - m_StartPoint.GetX();
}

int Rect::GetHeight()
{
	return m_EndPoint.GetY() - m_StartPoint.GetY();
}

  游戏对象之间会发生碰撞,需要写一个用于碰撞检测的类Shape

#include "Rect.h"
#ifndef SHAPE_H
#define SHAPE_H
//该类用于碰撞检测
class Shape
{
public:
	static bool CheckPointInRect(Point& point, Rect& rect);//判断第一个参数点point是否在第二个参数代表的矩形内
	static bool CheckIntersect(Rect& rectA, Rect& rectB);//判断两个矩形是否碰撞
};

#endif

   

#include "Shape.h"

bool Shape::CheckPointInRect(Point& point, Rect& rect)
{
	if (point.GetX() < rect.GetStartPoint().GetX()-1 || point.GetX() >rect.GetEndPoint().GetX()+1 ||
		point.GetY() <rect.GetStartPoint().GetY()-1 || point.GetY() >rect.GetEndPoint().GetY()+1)
		return false;
	else return true;
}

bool Shape::CheckIntersect(Rect& rectA, Rect& rectB)
{
	if (CheckPointInRect(rectA.GetStartPoint(), rectB) ||
		CheckPointInRect(rectA.GetEndPoint(), rectB) ||
		CheckPointInRect(rectA.GetRightPoint(), rectB) ||
		CheckPointInRect(rectA.GetLeftPoint(), rectB))
		return true;
	
	else return false;

}

好的,现在需要一个对游戏数据进行统计处理的类,因为游戏中的数据是伴随整个游戏过程的,区别与游戏中具体的对象,所以把数据成员都设置为静态

#include <list>
#ifndef SETTING_H
#define SETTING_H
using namespace std;
//数值设定类,用于计算分数和关卡等
class Setting
{
public:
	static bool NewLev;

	static int GetGameLevel() { return m_GameLevel; }
	static int GetTankNum() { return m_TankNum; }
	static int GetHp(){return m_Hp;}
	static void SetHp(int hp) { m_Hp = hp; }
	static int GetSumScore(){ return m_SumScore; }
	static int GetKillNum() { return m_KillNum; }
	static void NewGameLevel();
	static void Damaged();
	static int GetGameSpeed() { return m_GameSpeed; }

private:
	static int m_GameSpeed;     //游戏速度
	static int m_Hp;            // 生命值
	static int m_GameLevel;	    // 关卡等级
	static int m_TankNum;		// 当前坦克数
	static int m_SumScore;		// 总分
	static int m_KillScore;	    // 击毁坦克得分
	static int m_KillNum;		// 共击毁坦克数
};

#endif
#include "Setting.h"
int Setting::m_GameSpeed = 60;
bool Setting::NewLev = true;
int Setting::m_Hp = 20;
int Setting::m_GameLevel = 0;
int Setting::m_TankNum = 5;
int Setting::m_SumScore = 0;
int Setting::m_KillScore = 5;
int Setting::m_KillNum = 0;

void Setting::NewGameLevel()
{
	m_GameLevel++;
	m_TankNum = 10 + 5 * (m_GameLevel - 1);
	m_KillScore += 5;
}

void Setting::Damaged()
{
	m_TankNum--;
	m_SumScore += m_KillScore;
	m_KillNum++;
	if (m_TankNum == 0)	NewLev = true;
}

 有了以上的基础后,还需要创建一个画图类,进行游戏基础界面的展示,注意这个类需要包含graphics.h,用到了一些画图接     口,需要查文档

#include <graphics.h>
#include "Rect.h"
#ifndef GRAPHIC_H
#define GRAPHIC_H

enum 
{
	SCREEN_WIDTH = 1024,
	SCREEN_HEIGHT = 568
};
enum 
 {
	 BATTLE_GROUND_X1 = 5,
	 BATTLE_GROUND_Y1 = 5,
	 BATTLE_GROUND_X2 = 800, 
	 BATTLE_GROUND_Y2 = (SCREEN_HEIGHT - BATTLE_GROUND_Y1)
 };
class Graphic
{
public:
	static void DrawBattleGround();
	static void Create();
	static void Destroy();
	static void ShowScore();
	static int GetScreenWidth(){ return SCREEN_WIDTH; }
	static int GetScreenHeight(){ return SCREEN_HEIGHT; }
	static Rect GetBattleGround(){ return m_RectBattleGround; }

private:
	static Rect m_RectBattleGround;
	static Rect m_RectScreen;
	static char m_pArray[100];
};

#endif
#include "Graphic.h"
#include "Setting.h"

enum { SCORE_LEFT = 810, SCORE_TOP = 5 };
Rect Graphic::m_RectScreen;
Rect Graphic::m_RectBattleGround;
char Graphic::m_pArray[100];

void Graphic::ShowScore()
{
	COLORREF fill_color_save = getfillcolor();
	COLORREF color_save = getcolor();

	rectangle(SCORE_LEFT, SCORE_TOP, SCORE_LEFT + 200, SCORE_TOP + 40);
	RECT r = { SCORE_LEFT, SCORE_TOP, SCORE_LEFT + 200, SCORE_TOP + 40 };

	wsprintf((LPSTR)m_pArray, _T("第 %d 关"), Setting::GetGameLevel());
	drawtext((LPSTR)m_pAr
  • 7
    点赞
  • 55
    收藏
    觉得还不错? 一键收藏
  • 16
    评论
游戏分里外两个部分组成,里部分(用户不可见) 通过里部分执行判断,地图数组更改,和各种值的改变。更改完里部分再根据相应变化更改表部分。(用户可视部分)表部分的打印通过gotoxy去到相应坐标再printf打印出字符,通过文本函数改变文字字体颜色与文字背景颜色与字符组合实现图形界面。 程序通过 计数器+循环判断 的思想,类似单核cpu的多线程实现(单线程在不同程序/函数间来回执行)省去了多线程。(具体过程在功能设计与描述有详细描述) 另AI实现与加强依赖于rand随机函数的运用,进一步强化AI,增加游戏乐趣 功能方面,游戏参考于80年代任天堂红白机(FC/FamilyComputer)上的游戏坦克大战(Battle City),包括地图,游戏模式等等(当时的游戏直接烧在电路板上)。所以游戏平衡方面已经有了很好的参考,无需再花大量时间测试平衡性。 但诸如地图中的树林元素,随机道具等没有实现。但较之原版,该游戏由C/C++编写PC运行,由字符界面实现游戏画面。原版一辆坦克的子弹未消失之前不能发射第二颗。导致子弹打击远处CD长,近处CD短。该游戏每个子弹都有相同CD,子弹未消失只要CD达到即可发射第二颗,第三颗…增加了真实性,相较于原版是个改进。且考虑到PC性能不一内置了游戏速度调整。玩家可根据PC性能调整至合适的速度。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值