In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
In this issue, the editor will bring you about how C++ uses Easyx graphics library to achieve aircraft war. The article is rich in content and analyzes and describes for you from a professional point of view. I hope you can get something after reading this article.
Common header file common.h
# pragma once#include # pragma comment (lib, "winmm.lib") using namespace std
Manage Resource res.h-Singleton Design pattern
# pragma once#include "common.h" class Res {private: Res (); / / Constructor privatized public: / / provide public interface static int WIDTH (string name); / / obtain the resource width static int HEIGHT (string name); static Res* GetInstance () through the key of the image / / get the object of the resource (class)-the unique object static void DrawIMG (int x, int y, string name); / / draw the location of the picture, use the key to find which picture to draw / / draw the character-location, find different types of roles by name, and use preIndex to identify static void DrawRole (int x, int y, string name, int preIndex) / / play music-windows multithreaded DWORD type, WINAPI decorated static DWORD WINAPI PlayMusic (LPVOID lparame); ~ Res (); public: static map img; / / picture resources-pictures are stored in map static map music; / / music resources}
Res.cpp
# include "res.h" map Res::img; / / static data members of picture resources are initialized outside the class, and the class name defines the map Res::music; / / music resource Res::Res () / / constructor to initialize the data members-handle {/ / background string background = ". / res/background.jpg" under the path. / / role-4-background image + mask map string roleImg [4] = {". / res/planeNormal_1.jpg", ". / res/planeNormal_2.jpg", ". / res/planeExplode_1.jpg", ". / res/planeExplode_2.jpg"}; / / bullet string ballImg [2] = {". / res/bullet1.jpg", ". / res/bullet2.jpg"} / / enemy string enemyImg [4] = {". / res/enemy_1.jpg", ". / res/enemy_2.jpg", ". / res/enemyPlane1.jpg", ". / res/enemyPlane2.jpg"}; / / string-- > IMAGE* is a pointer and does not need to take the address img ["background"] = new IMAGE; img ["role"] = new IMAGE [4]; img ["bullet"] = new IMAGE [2] Img ["enemy"] = new IMAGE [4]; loadimage (img ["background"], background.c_str ()); / / load image path project attribute multi-byte for (int I = 0; I
< 4; i++) {/*假设img["角色"]为p,则p=new IMAGE [4];则img["角色"]+i 等效: p+i*/ loadimage(img["角色"] + i, roleImg[i].data()); //用.data或.cst()转换为字符串 loadimage(img["敌机"] + i, enemyImg[i].data()); } for (int i = 0; i < 2; i++) { loadimage(img["子弹"] + i, ballImg[i].c_str()); } }//获取图片的宽度---碰撞的时候需要---返回对象指针,对象指针调用(img类型)数据成员,有一个成员函数int Res::WIDTH(string name){//获取对象,获取什么样的属性,(img类型)数据成员有一个getwidth()成员函数---是库中的成员函数 return GetInstance()->Img [name]-> getwidth ();} / get the height of the picture int Res::HEIGHT (string name) {return GetInstance ()-> IMG [name]-> getheight ();} Res* Res::GetInstance () {static Res* res = new Res; return res;} / / Map with only one picture: background map void Res::DrawIMG (int x, int y, string name) {putimage (x, y, GetInstance ()-> img [name]) / / Pictures} void Res::DrawRole (int x, int y, string name, int preIndex) {/ / multiple image maps-- transparent maps-- go to the background putimage (xpeny, GetInstance ()-> img [name] + preIndex, NOTSRCERASE); / / the number of frames putimage (xpeny, GetInstance ()-> img [name] + preIndex+1, SRCINVERT) } DWORD _ stdcall Res::PlayMusic (LPVOID lparame) {int key = (int) lparame; / / parameters of the threading function-strongly converted to int switch (key) / / different music types {case 1: mciSendString ("close. / res/f_gun.mp3", 0,0,0) / / close mciSendString ("open. / res/f_gun.mp3", 0,0,0) before playback; / / open it first, and then play mciSendString ("play. / res/f_gun.mp3", 0,0,0); break; case 2: mciSendString ("close. / res/5.mp3", 0,0,0) MciSendString ("open. / res/5.mp3", 0,0,0); mciSendString ("play. / res/5.mp3", 0,0,0); break; case 3: mciSendString ("close. / res/10.mp3", 0,0,0); mciSendString ("open. / res/10.mp3", 0,0,0); mciSendString ("play. / res/10.mp3", 0,0,0) Break;} return 0;} Res::~Res () {delete img ["background"]; delete [] img ["character"]; delete [] img ["enemy"]; delete [] img ["bullet"];}
Masturbation game. CPP main function part
# include "control.h" # include "graph.h" # include "role.h" # include "enemy.h" int main () {srand ((unsigned int) time (NULL)); / / Random function seed-different positions Graph* pMap = new Graph; Role* pRole = new Role; Enemy* pEnemy = new Enemy; Control* pControl = new Control (pMap, pRole, pEnemy); BeginBatchDraw () / / A pair of buffered drawings while (1) {cleardevice (); / / clear screen pControl- > DrawMap (); / / Map pControl- > DrawRole (); / / draw characters pControl- > DrawEnemy (); / / draw enemy planes before attacking enemy planes pControl- > PlayEemey () FlushBatchDraw (); / / displays the execution of unfinished drawing tasks} EndBatchDraw (); return 0;}
Whether the plane moves or the bullet moves, point.h is essentially the change of coordinates-the change of processing points.
# pragma once#include "common.h" class Point {public: enum Dir {left,right,down,up}; / / enumerates the direction in which the point moves. The change of different moving direction points is different Point (int x = 0, int y = 0); Point (const Point& point); / / copy construction-- assignment int& getX () between points / / external interface, get the coordinates of the point int& getY (); / / move the point void move (int speed, Dir dir); / / move the speed direction-determine how the coordinates change protected: int x; int y;} / * the enemy plane moves from top to bottom, the character can move up and down, left and right, s-shaped enemy plane can increase x direction increment, increase y direction increment * /
Point.cpp
# include "point.h" Point::Point (int x, int y): X (x), y (y) {} Point::Point (const Point& point) {this- > x = point.x; this- > y = point.y;} int& Point::getX () {/ / TODO: insert return statement return x here;} int& Point::getY () {/ / TODO: insert return statement return y here } void Point::move (int speed, Dir dir) / / move {switch (dir) {case Point::left: this- > x-= speed; break; case Point::right: this- > x + = speed; break; case Point::up: this- > y-= speed; break; case Point::down: this- > y + = speed; break according to the direction }}
Element.h enemy aircraft and aircraft have different directions, others are basically the same-abstract element class
# pragma once#include "common.h" # include "point.h" / / all enemy planes and characters are derived from this class class Element {public: virtual ~ Element (); / / subclass object initializes parent class pointer Element (); Element (int x, int y, string name, bool live, int hp = 0); int& GetX (); int& GetY (); bool& GetLive () Int& GetHp (); int GetWidth (); / / get width, height int GetHeight (); void DrawElement (int pre); / / drawing element-void MoveElement (int speed, Point::Dir dir); / / moving element protected: Point point; / / the position of the element on the window string name / / the name of the element bool live; / / the mark that exists-enemy planes / bullets will disappear int hp; / / Blood volume}
Element.cpp
# include "element.h" # include "res.h" int Element::GetWidth () {return Res::GetInstance ()-> WIDTH (name); / / return Res::GetInstance ()-> IMG [name]-> getwidth (); public attribute} int Element::GetHeight () {return Res::GetInstance ()-> HEIGHT (name) in class IMAGE } / / encapsulate the mobile process in the resource file, and call the function in the resource-draw the character void Element::DrawElement (int pre) {Res::GetInstance ()-> DrawRole (point.getX (), point.getY (), name, pre);} / / Mobile void Element::MoveElement (int speed, Point::Dir dir) {point.move (speed, dir) } Element::~Element () {} Element::Element () {} / / the combination of classes must take the initialization parameter list Element::Element (int x, int y, string name, bool live, int hp): point (xPowery), name (name) {this- > live = live; this- > hp = hp;} int& Element::GetX () {/ / TODO: insert the return statement return point.getX () here / / use point to store this point, and get this point should return the x coordinate} int& Element::GetY () {/ / TODO: insert the return statement return point.getY ();} bool& Element::GetLive () {/ / TODO: insert the return statement return live;} int& Element::GetHp () {/ / TODO: insert the return statement return hp;} here
Role.h-character moves, character fires bullets
# pragma once#include "common.h" class Element;class Role {public: Role (); ~ Role (); void DrawPlane (int preIndex); / / frame number of void MovePlane (int speed); / / Speed void DrawBullet (); / / drawing bullet void MoveBullet (int speed); / / moving bullet-moving speed Element*& GetPlane () / / external keystroke operation requires access to aircraft and bullet list& GetBullet (); protected: Element* plane; / / role-instantiate a role with elements-the role is also one of the elements list bullet; / / bullets-- an aircraft has multiple bullets (objects containing multiple elements) bullets are also elements}
Role.cpp
# include "role.h" # include "res.h" # include "element.h" # include "Timer.hpp" Role::Role () / / new an element class-place the plane in the middle of the window {plane = new Element (Res::GetInstance ()-> WIDTH (background) / 2-Res::GetInstance ()-> WIDTH (role) / 2 / / x Res::GetInstance ()-> HEIGHT ("background")-Res::GetInstance ()-> HEIGHT ("role"), / / y "role", / / name true, / / live / / hp} Role::~Role () {} void Role::DrawPlane (int preIndex) / / draw aircraft {plane- > DrawElement (preIndex) } void Role::MovePlane (int speed) / / Mobile aircraft-combined with keys to control the key operation of asynchronous processing {if (GetAsyncKeyState (VK_UP) & & plane- > GetY () > = 0) / / go up Y cannot exceed the upper boundary {plane- > MoveElement (speed, Point::up) / / change the point of the plane-moving element} / / go down GetY () HEIGHT ("background")-Res::GetInstance ()-> HEIGHT ("character") {plane- > MoveElement (speed, Point::down) } / / go right GetX () WIDTH ("background")-Res::GetInstance ()-> WIDTH ("character") {plane- > MoveElement (speed, Point::right) } / / go left X cannot be less than the left boundary if (GetAsyncKeyState (VK_LEFT) & & plane- > GetX () > = 0) {plane- > MoveElement (speed, Point::left) } / / bullet generation-firing bullets by space-controlling speed with a timer-generating a bullet in 100ms if (GetAsyncKeyState (VK_SPACE) & & MyTimer::Timer (100Pol 0)) {/ / add the creation thread function in the music call Windows-function pointer passes to the thread processing function-plays the first sound. Le HANDLE threadID = CreateThread (NULL 0, Res::PlayMusic, (int*) 1,0,0) Bullet.push_back (new Element (plane- > GetX () + 45, plane- > GetY ()-10, "bullet", 1)); / / tail insertion click on the space new the coordinates of a bullet are in the middle CloseHandle (threadID) directly above the coordinates of the aircraft; / / close the thread} MoveBullet (1) with a return value / / move bullet DrawBullet () / / draw bullet} void Role::DrawBullet () / / bullet is stored in the container, and each bullet should be drawn {for (auto v: bullet) / / iterator traverses {if (v-> GetLive ()) / / to determine whether the bullet can be drawn {v-> DrawElement (0). / / serial number 0, only 2 bullets} void Role::MoveBullet (int speed) / / each bullet has to move-from the bottom up {for (auto v: bullet) {v-> GetY ()-= speed }} Element*& Role::GetPlane () {/ / TODO: insert the return statement return plane;} list& Role::GetBullet () {/ / TODO: insert the return statement return bullet;} / / every time a bullet is generated, the music is played, and the return value is of type HANDLE
Control.h controls the operation of the whole game-medium drive.
# pragma onceclass Graph;class Role;class Enemy;class Control {public: Control (Graph* pMap = nullptr, Role* pRole = nullptr,Enemy* pEnemy=nullptr); ~ Control (); void DrawMap (); void DrawRole (); void DrawEnemy (); / / drawing enemy aircraft void PlayEemey (); / / enemy aircraft protected: / / all components Role* pRole / / role Graph* pMap; / / Map Enemy* pEnemy; / / enemy plane}
Control.cpp-encapsulates the implementation details-just call the control class object in the main function
# include "control.h" # include "role.h" # include "graph.h" / / Map # include "timer.hpp" # include "enemy.h" # include "element.h" # include "res.h" Control::Control (Graph* pMap, Role* pRole, Enemy* pEnemy) {this- > pMap = pMap; this- > pRole = pRole; this- > pEnemy = pEnemy;} Control::~Control () {} void Control::DrawMap () {pMap- > DrawMap () } void Control::DrawRole () {pRole- > DrawPlane (0); / / frame 0 pRole- > MovePlane (1) / / Speed} / / generate one enemy plane every second (not too often)-generate an enemy plane and put it in the container void Control::DrawEnemy () {if (MyTimer::Timer (1000, 1)) {pEnemy- > GetEnemy (). Push_back (pEnemy- > createEnemy ()) } if (MyTimer::Timer (10,2)) / / move an aircraft timer No. 2 {pEnemy- > MoveEnemy (1); / / Speed} pEnemy- > DrawEnemy (0); / / draw only one enemy plane} void Control::PlayEemey () / / judgment of rectangle and rectangle {/ / 1. Collision handling: when you encounter a bullet, set the live of the bullet to 0Murray-only process the mark for (auto bullet: pRole- > GetBullet ()) / / get the bullet information {if (bullet- > GetLive () = = 0) / / if the bullet tag = = 0, continue to look for continue; if (bullet- > GetY ()).
< 0) //如果超出窗口边界,把标记置为false bullet->GetLive () = false For (auto enemy: pEnemy- > GetEnemy ()) / / the major premise of collision handling with bullets-there is {if (enemy- > GetLive () & & bullet- > GetX () > enemy- > GetX () & & bullet- > GetX ()) GetX () + Res::WIDTH ("enemy") & & bullet- > GetY () > enemy- > GetY () & & bullet- > GetY ()
< enemy->GetY () + Res::HEIGHT ("enemy") {enemy- > GetHp () -; / / intersect, blood volume decreases if (enemy- > GetHp () GetLive () = false) / / set the enemy aircraft flag to false--- without vanishing} bullet- > GetLive () = false / / the bullet will disappear after touching the enemy plane} / / the enemy plane will disappear outside the window boundary if (enemy- > GetY () > = Res::HEIGHT ("background")) {enemy- > GetLive () = false } / / 2. Delete the corresponding data through the tag-> memory management traverses the enemy for (auto iterE = pEnemy- > GetEnemy (). Begin (); iterE! = pEnemy- > GetEnemy (). End () ) {if ((* iterE)-> GetLive () = = false) / / the current enemy is marked as false--- > delete the enemy {iterE = pEnemy- > GetEnemy (). Erase (iterE);} else {iterE++ / / + + Don't write in the for loop}} / / traversing bullets-bullets delete for (auto iterB = pRole- > GetBullet (). Begin (); iterB! = pRole- > GetBullet (). End () ) {if ((* iterB)-> GetLive () = = false) {iterB = pRole- > GetBullet () .erase (iterB);} else {iterB++;}}
Graph.h-Map (window class)
# pragma onceclass Graph {public: Graph (); ~ Graph (); void DrawMap ();}
Graph.cpp
# include "graph.h" # include "res.h" Graph::Graph () {initgraph (Res::GetInstance ()-> img ["background"]-> getwidth (), Res::GetInstance ()-> img ["background"]-> getheight ()); mciSendString ("open. / res/game_music.mp3", 0,0,0) / / add music mciSendString ("play. / res/game_music.mp3 repeat", 0,0,0) after the window is created; / / repeat playback} Graph::~Graph () {closegraph (); / / close the window} void Graph::DrawMap () {Res::DrawIMG (0,0, "background");}
Time.hpp-definition and implementation written together, ending with hpp to control the firing of bullets with time-timer
# pragma once#include "common.h" class MyTimer {public: static bool Timer (int duration, int id) / / interval id {static int startTime [10]; / / start time-the static variable is automatically initialized to 0 int endTime = clock () / / end time if (endTime-startTime [id] > = duration) / / end time-start time > = interval {startTime [id] = endTime; / / change the original end time to the new start time return true } return false;}}
Enemy.h enemy aircraft
# pragma once#include "common.h" class Element;class Enemy {public: Enemy (); ~ Enemy (); void DrawEnemy (int preIndex); / / draw several pictures of void MoveEnemy (int speed); Element* createEnemy (); / / create enemy list& GetEnemy (); / / access enemy plane-collision detection protected: list enemyPlane / / (Storage) multiple enemy planes}
Enemy.cpp
# include "enemy.h" # include "element.h" # include "res.h" Enemy::Enemy () {} Enemy::~Enemy () {} void Enemy::DrawEnemy (int preIndex) {for (auto v: enemyPlane) / / drawing element {if (v-> GetLive ()) / / determine whether the enemy plane exists {v-> DrawElement (preIndex) } void Enemy::MoveEnemy (int speed) {for (auto v: enemyPlane) {v-> MoveElement (speed, Point::down) / / Speed Direction}} Element* Enemy::createEnemy () / / get window width and height-Random XMagol y coordinates come out from the upper boundary of the window velocity blood volume {return new Element (rand ()% Res::GetInstance ()-> WIDTH ("background"),-1*Res::GetInstance ()-> HEIGHT ("enemy plane"), "enemy plane", 1,3) } list& Enemy::GetEnemy () {/ / TODO: insert the return statement return enemyPlane; / / return a container here} the above is how C++ realized the aircraft war using Easyx graphics library that the editor shared for you. If you happen to have similar doubts, please refer to the above analysis to understand. If you want to know more about it, you are welcome to follow the industry information channel.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.