Beauty of 2D horizontal confrontation shooting game

A small game has been made with the latest version of easyx. All class functions in the program are inline functions, about 300 lines. The development environment is Visual Studio 2015 Community. Whether other compilers can pass the compilation is uncertain.

The screenshot of the game is as follows:

Code Description:
For nonblocking delay,
First, we need ctime to create a clock_t variable a, which is initialized to clock(), which seems to be the number of milliseconds since 1970.
We will execute func() every 0.5 seconds.
Then create the main loop while(1)
Use clock() - a before calling;
If clock() - a > 500, perform func() and reassign a to clock().
If Sleep(500) is used, the loop can only perform func functions, and nothing can be done during this period.

The complete game source code is as follows:

#include <easyx.h>
#include <time.h>
#include <conio.h>

class Bullet;
class Tank;
class E_Bullet;
class Boss;
bool dead = false;
bool wined = false;
struct pos//Coordinate class
{
	int a;
	int b;
};
class E_Bullet//Bullets fired by the enemy
{
public:
	clock_t d;
	int x;
	int y;
	bool on = false;
	pos show()//Draw a new position
	{
		setfillcolor(RGB(255, 180, 20));
		fillrectangle(x - 5, y - 5, x + 5, y + 5);
		return pos{ x,y };
	}
	pos del()//Overwrite original location
	{
		setfillcolor(0);
		setlinecolor(0);
		fillrectangle(x - 5, y - 5, x + 5, y + 5);
		rectangle(x - 5, y - 5, x + 5, y + 5);
		return pos{ x,y };
	}
	pos move()//Left shift
	{
		x -= 3;
		return pos{ x,y };
	}
};
class Bullet//Same as for the bullets fired by players
{
public:
	clock_t d;
	int x;
	int y;
	bool on = false;
	pos show()
	{
		setfillcolor(RGB(150, 180, 210));
		fillrectangle(x - 5, y - 5, x + 5, y + 5);
		return pos{ x,y };
	}
	pos del()
	{
		setfillcolor(0);
		setlinecolor(0);
		fillrectangle(x - 5, y - 5, x + 5, y + 5);
		rectangle(x - 5, y - 5, x + 5, y + 5);
		return pos{ x,y };
	}
	pos move()//Right shift
	{
		x += 3;
		return pos{ x,y };
	}
};
class Boss//Enemy
{
public:
	bool hurting = false;
	clock_t d_hurt;
	COLORREF clr = RGB(0, 130, 125);
	int x;
	int y;
	int hp = 100;//life
	clock_t d;//The non blocking delay is not actually a delay, but a judgment of how long a function has been executed for the last time
	clock_t att_d;
	bool angle = false;//direction
	pos show()
	{
		setfillcolor(clr);
		fillrectangle(x - 20, y - 40, x + 20, y + 40);
		return pos{ x,y };
	}
	pos del()
	{
		setfillcolor(0);
		setlinecolor(0);
		rectangle(x - 20, y - 40, x + 20, y + 40);
		fillrectangle(x - 20, y - 40, x + 20, y + 40);
		return pos{ x,y };
	}
	void fire(E_Bullet& but)//attack
	{
		but.on = true;//Place a bullet
		but.x = x -20;
		but.y = y;
		but.d = clock();
	}
	void move()//Up and down movement
	{ 
		if (angle == true)
			y -= 5;
		if (angle == false)
			y += 5;
		if (y >= 440)
			angle = true;
		if (y <= 40)
			angle = false;
	}
	void hurt()//Injured
	{
		hp -= 4;
		d_hurt = clock();
		setfillcolor(0);
		setlinecolor(WHITE);
		fillrectangle(160, 485, 560, 510);//Update blood strips
		rectangle(160, 485, 160+hp*4, 510);
		setfillcolor(RGB(230, 0, 1));
		setlinecolor(RGB(255, 255, 255));
		fillrectangle(160, 485,160+hp*4, 510);
		rectangle(160, 485, 160 + hp * 4, 510);
		hurting = true;
		if (hp <= 0)//Hang up
		{
			wined = true;
		}
	}
};
class Tank//Players, same as above
{
public:
	bool hurting = false;
	int hp = 100;
	int x;
	COLORREF clr = RGB(150, 180, 210);
	int y;
	clock_t d_hurt;
	Tank(){}
	Tank(int _x, int _y) { x = _x; y = _y; }
	Tank operator=(pos p) { x = p.a; y = p.a; }
	pos show()
	{
		setfillcolor(clr);
		fillrectangle(x - 25, y - 25, x + 25, y + 25);
		setfillcolor(RGB(100, 200, 180));
		fillrectangle(x, y + 5, x + 40, y - 5);
		return pos{ x,y };
	}
	pos del()
	{
		setfillcolor(0);
		setlinecolor(0);
		fillrectangle(x - 25, y - 25, x + 25, y + 25);
		rectangle(x - 25, y - 25, x + 25, y + 25);
		fillrectangle(x, y + 5, x + 40, y - 5);
		rectangle(x, y + 5, x + 40, y - 5);
		return pos{ x,y };
	}
	void fire(Bullet& but)
	{
		but.on = true;
		but.x = x + 45;
		but.y = y;
		but.d = clock();
		but.show();
	}
	void hurt()
	{
		hp -= 2;
		d_hurt = clock();
		setfillcolor(0);
		setlinecolor(WHITE);
		fillrectangle(160, 515, 560, 540);
		rectangle(160, 515, 560, 540);
		rectangle(160, 515, 160 + hp * 4, 540);
		setfillcolor(RGB(0, 255, 1));
		setlinecolor(RGB(255, 255, 255));
		fillrectangle(160, 515, 160 + hp * 4, 540);
		rectangle(160, 515, 160 + hp * 4, 540);
		hurting = true;
		if (hp <= 0)
			dead = true;
	}
};
#define BT_MAX 8
int main()
{
	initgraph(640, 550, 4);//Initialization screen
	settextcolor(RGB(0, 254, 0));
	settextstyle(35, 0, "Blackbody");
	outtextxy(150, 200, "W,S move,K attack");
	Sleep(3000);
	setlinecolor(0);
	setfillcolor(0);
	rectangle(0, 0, 640, 550);
	fillrectangle(0, 0, 640, 550);
	setlinecolor(RGB(255, 255, 255));
	setfillcolor(RGB(255, 255, 255));
	clock_t delay = clock();//Player movement delay
	clock_t d_f = clock();//Delay of player's firing
	line(0, 481, 640, 481);//Split picture and blood bar
	Bullet bt[BT_MAX];//Player's bullets
	Tank tk(30, 30);//Game player
	Boss bo;//Enemy
	bo.x = 580;
	bo.y = 240;
	E_Bullet ebt[BT_MAX];//Enemy bullets
	bo.d = clock();//Initialization delay
	bo.att_d = clock();
	tk.show();
	settextstyle(20, 0, "Blackbody");
	outtextxy(10,485,"BOSS Life value:");
	setfillcolor(RGB(230, 0, 1));
	fillrectangle(160, 485, 560, 510);//Enemy blood bar
	outtextxy(10, 520, "Player's health:");
	setfillcolor(RGB(0, 255, 1));
	fillrectangle(160, 515, 560, 540);//Player blood bar
	while (1)//Main cycle
	{
		if (wined||dead)//Player dead or enemy dead
			break;
		if (GetAsyncKeyState('W') & 0x8000)//Player mobility
		{
			if (tk.y > 28 && (clock() - delay) >= 40)
			{
				tk.del(); tk.y -= 3; tk.show(); delay = clock();
			}
		}
		if (GetAsyncKeyState('w') & 0x8000)//Player mobility
		{
			if (tk.y > 28 && (clock() - delay) >= 40)
			{
				tk.del(); tk.y -= 3; tk.show(); delay = clock();
			}
		}
		if (GetAsyncKeyState('k') & 0x8000)//Players open fire
		{
			for (int i = 0; i < BT_MAX; i++)
			{
				if (bt[i].on == false && (clock() - d_f) > 800)
				{
					bt[i].on = true;
					tk.fire(bt[i]);
					d_f = clock();
					break;
				}
			}
		}
		if (GetAsyncKeyState('K') & 0x8000)//Players open fire
		{
			for (int i = 0; i < BT_MAX; i++)
			{
				if (bt[i].on == false && (clock() - d_f) > 800)
				{
					tk.fire(bt[i]);
					d_f = clock();
					break;
				}
			}
		}
		if (GetAsyncKeyState('S') & 0x8000)//Player mobility
		{
			if (tk.y < 452 && (clock() - delay) >= 40)
			{
				tk.del(); tk.y += 3; tk.show(); delay = clock();
			}
		}
		if (GetAsyncKeyState('s') & 0x8000)//Player mobility
			if (tk.y < 452 && (clock() - delay) >= 40)
			{
				tk.del(); tk.y += 3; tk.show(); delay = clock();
			}
		for (int i = 0; i < BT_MAX; i++)//Traverse bullets, refresh bullets
		{
			if (bt[i].on == true && (clock() - bt[i].d) > 20)
			{
				bt[i].del();
				bt[i].move();
				bt[i].show();
				bt[i].d = clock();
				if (bt[i].x >= 635)
					bt[i].on = false, bt[i].del();//At the far right of the screen
				if ((bt[i].x + 5 >= bo.x - 20 && bt[i].x - 5 <= bo.x + 20) && (bt[i].y - 5 < bo.y + 40 && bt[i].y + 5 > bo.y - 40))
					//Hit the enemy
					bt[i].on = false, bo.hurt(),bt[i].del();
			}
		}
		if (clock() - bo.att_d > 700)//Enemy automatic fire
		{
			for (int i = 0; i < BT_MAX; i++)
			{
				if (ebt[i].on == false)
				{
					bo.fire(ebt[i]); break;
				}
			}
			bo.att_d = clock();
		}
		for (int i = 0; i < BT_MAX; i++)//Enemy bullets, same as above
		{
			if (ebt[i].on == true && (clock() - ebt[i].d > 20))
			{
				ebt[i].del();
				ebt[i].move();
				ebt[i].show();
				ebt[i].d = clock();
				if (ebt[i].x < 5)
					ebt[i].del(),ebt[i].on = false;
				if (ebt[i].x - 5 < tk.x + 25 && ebt[i].x + 5 > tk.x - 25 && ebt[i].y - 5 < tk.y + 25 && ebt[i].y + 5 > tk.y - 25)
				{
					ebt[i].on = false, tk.hurt(), ebt[i].del();
				}
			}
		}
		if (tk.hurting == true)//Player injury blinks for 0.1 seconds
			if (clock() - tk.d_hurt > 100)
			{
				tk.clr = RGB(150, 180, 210), tk.show(), tk.hurting = false;
			}
			else
			tk.clr = RGB(255, 0, 0), tk.show();
		if (bo.hurting == true)//Enemy damage blinks for 0.1 seconds
			if (clock() - bo.d_hurt > 100)
			{
				bo.clr = RGB(0, 130, 125), bo.show(), bo.hurting = false;
			}
			else
				bo.clr = RGB(0, 255, 0), bo.show();
		if (clock() - bo.d > 50)//Enemy movement delay;
			bo.del(), bo.move(), bo.show(), bo.d = clock();
	}
	if (wined)//Victory and defeat have been divided.
	{
		settextcolor(RGB(0, 254, 0));
		settextstyle(35, 0, "Blackbody");
		outtextxy(150, 200, "You beat it. boss!You win!!");
	}
	else 
	{
		settextcolor(RGB(254, 0, 0));
		settextstyle(35, 0, "Blackbody");
		outtextxy(140, 200, "You are boss Defeated!");
	}
	Sleep(5000);
	closegraph();//Close the canvas
	return 0;
}

 

79 original articles published, praised 151, 10000 visitors+
Private letter follow

Posted by langemarkdesign on Mon, 10 Feb 2020 08:35:24 -0800