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; }