C++编写简易的飞机大战

时间:2022-11-11 09:29:23

初学C/C++的小伙伴可以用做这个小游戏来熟悉一下编程的乐趣。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
#include<windows.h>
#include"resource.h"
#include<stdlib.h>
#include<time.h>
#include<stdio.h>
 
#define TIMER_DIREN 101      //定义定时器
#define TIMER_DIRENMOVE 102
#define TIMER_ZIDAN 103
#define TIMER_DIRENRELEASE 104
 
typedef struct Node    //敌人,自己,子弹结构体
{
  int x;
  int y;
  struct Node *pnext;
}DiRen,FeiJi,ZiDan;
void ZaoDiRen();                //造敌人
void ShowDiRen(DiRen *pHead,HWND hWnd);     //显示敌人
void ZaoZiDan();                //造子弹
void ShowZiDan(ZiDan *pHead,HWND hWnd);     //显示子弹
void DiRenMove(DiRen *pHead);          //敌人移动
void ZiDanMove(DiRen *pHead);          //子弹移动
void shoot(HWND hWnd,FeiJi *ziji,DiRen **diren,ZiDan **zidan);//判断是否射中  
void ReleaseDiren(DiRen **pHead);        //释放出去的敌人
void ReleaseZidan(ZiDan **pHead);        //释放出去的子弹
void ZaoZiJi(HWND hWnd);            //造自己
LRESULT CALLBACK pp(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam);//回调函数
int __stdcall WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
  WNDCLASSEX wc;
  HWND hWnd;
  MSG msg;
  wc.hInstance=hInstance;
  wc.cbClsExtra=0;
  wc.cbSize=sizeof(WNDCLASSEX);
  wc.cbWndExtra=0;
  wc.hIcon=NULL ;
  wc.hCursor=NULL ;
  wc.hIconSm=NULL;
  wc.lpfnWndProc=pp;
  wc.lpszClassName="hello";
  wc.lpszMenuName=NULL;
  wc.style=CS_HREDRAW|CS_VREDRAW | CS_OWNDC ;
  wc.hbrBackground=(HBRUSH)5;
  RegisterClassEx(&wc);
  hWnd=CreateWindow("hello","world", WS_OVERLAPPEDWINDOW,100,100,600,600,NULL,NULL,hInstance,NULL);
  ShowWindow(hWnd,nCmdShow);
  while(GetMessage(&msg,NULL,0,0))
  {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }
  return 0;
}
DiRen *pDiRen=NULL;  //敌人
ZiDan *pZiDan=NULL;  //子弹
FeiJi *pZiJi=NULL;   //自己
static int score=0;   //分数
static char sco[20];  //装分数的字符窜
LRESULT CALLBACK pp(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
  int i=1,  //位
    jscore;
  HDC hdc;
  HDC memdc;
  HBITMAP hbm;
  BITMAP bminfo;
  switch(msg)
  {
  case WM_TIMER:   //定时器
    hdc=GetDC(hWnd); //得到设备句柄
    hbm=LoadBitmap(GetModuleHandle(NULL),MAKEINTRESOURCE(IDB_BITMAP4));//载入背景位图
    GetObject(hbm, sizeof(bminfo), &bminfo);
    memdc=CreateCompatibleDC(hdc);
    SelectObject(memdc,hbm);
    BitBlt(hdc,0,0,600,600,memdc,0,0,SRCCOPY);
    /*itoa(score,sco,10);*/
    sprintf(sco,"%d",score);  //将分数装入字符窜
    jscore=score;
    while((jscore=jscore/10)>0) //判断分数有几位
      i++;
    TextOut(hdc,0,0,"分数",4);
    TextOut(hdc,30,0,sco,i); //显示分数
    DeleteDC(memdc);
    ReleaseDC(hWnd,hdc);  //释放句柄
    DeleteObject(hbm);
    ZaoZiJi(hWnd);     //造自己
    if(TIMER_ZIDAN==wParam)  //定时器101
    {
      ZiDanMove(pZiDan);   //子弹移动
      ReleaseZidan(&pZiDan); //释放出屏幕的子弹
    }
    else if( TIMER_DIREN==wParam) //定时器102
    {
      ZaoDiRen();       //造敌人   
    }
    else if(TIMER_DIRENRELEASE==wParam)  //定时器103
    {
      ReleaseDiren(&pDiRen);  //释放出屏幕的敌人
    }
    ShowDiRen(pDiRen,hWnd);       //显示敌人
    DiRenMove(pDiRen);       //敌人移动
    ShowZiDan(pZiDan,hWnd);     //显示子弹
    shoot(hWnd,pZiJi,&pDiRen,&pZiDan);   //是否射中
    break;
  case WM_CLOSE:    //关闭
    PostQuitMessage(0);
    break;
  case WM_KEYDOWN:    //判断按键
    switch(wParam)  
    {
    case VK_LEFT:   //左移
      if(pZiJi->x>0)
        pZiJi->x-=20;
      break;
    case VK_RIGHT:  //右移
      if(pZiJi->x<530)
      pZiJi->x+=20;
      break;
    case VK_UP:   //上移
      if(pZiJi->y>0)
      pZiJi->y-=20;
      break;
    case VK_DOWN:  //下移
      if(pZiJi->y<520)
      pZiJi->y+=20;
      break;
    case VK_SPACE:  //空格发射子弹
      ZaoZiDan();
      break;
    }
    break;
  case WM_CREATE:   //创建
    srand(time(NULL)); 
    pZiJi=(struct Node*)malloc(sizeof(struct Node));
    pZiJi->x=200;     //自己的x
    pZiJi->y=500;     //自己的y
    SetTimer(hWnd,TIMER_DIREN,1000,NULL);  //设置定时器
    SetTimer(hWnd,TIMER_DIRENMOVE,200,NULL);
    SetTimer(hWnd,TIMER_ZIDAN,100,NULL);
    SetTimer(hWnd,TIMER_DIRENRELEASE,300,NULL);
    break;
  }
  return DefWindowProc(hWnd,msg,wParam,lParam);
}
 
 
void ZaoDiRen()  //造子弹
{
  DiRen *u;
  u=(struct Node*)malloc(sizeof(struct Node));
  u->x=rand()%550;   //子弹的x随机出现
  u->y=-10;      //出现的纵坐标固定
  u->pnext=NULL;
  if(NULL==pDiRen) 
  {
    pDiRen=u;
  }
  else
  {
    u->pnext=pDiRen;   //将新产生的链表放在头
    pDiRen=u;
 
  }
}
void ShowDiRen(struct Node *pHead,HWND hWnd)  //显示敌人
{
  HDC hdc;
  HDC memdc;
  HBITMAP hbm;
  BITMAP bminfo;
  hdc=GetDC(hWnd);
  hbm=LoadBitmap(GetModuleHandle(NULL),MAKEINTRESOURCE(IDB_BITMAP1));//载入敌人位图
  GetObject(hbm, sizeof(bminfo), &bminfo);
  memdc=CreateCompatibleDC(hdc);
  SelectObject(memdc,hbm);
  while(pHead!=NULL) //敌人链表不为空,显示敌机
  {
    BitBlt(hdc,pHead->x,pHead->y,40,40,memdc,0,0,SRCCOPY);
    pHead=pHead->pnext;
  }
  DeleteDC(memdc);
  ReleaseDC(hWnd,hdc);
  DeleteObject(hbm);
}
void ZaoZiJi(HWND hWnd)
{
  HDC hdc;
  HDC memdc;
  HBITMAP hbm;
  BITMAP bminfo;
  hdc=GetDC(hWnd);
  hbm=LoadBitmap(GetModuleHandle(NULL),MAKEINTRESOURCE(IDB_BITMAP3));//载入自己的位图
  GetObject(hbm, sizeof(bminfo), &bminfo);
  memdc=CreateCompatibleDC(hdc);
  SelectObject(memdc,hbm);
  BitBlt(hdc,pZiJi->x,pZiJi->y,40,40,memdc,0,0,SRCCOPY); //显示自己
  DeleteDC(memdc);
  ReleaseDC(hWnd,hdc);
  DeleteObject(hbm);
}
void ZaoZiDan()   //造子弹
{
  ZiDan *u;
  u=(ZiDan*)malloc(sizeof(ZiDan));
  u->x=pZiJi->x+15;
  u->y=pZiJi->y+10;
  u->pnext=NULL;
  if(pZiDan==NULL)
  {
    pZiDan=u;
  
  else
  {
    u->pnext=pZiDan;  //将子弹放在链表头
    pZiDan=u;
  }
}
void ShowZiDan(ZiDan *pHead,HWND hWnd) //显示子弹
{
  HDC hdc;
  HDC memdc;
  HBITMAP hbm;
  BITMAP bminfo;
  hdc=GetDC(hWnd);
  hbm=LoadBitmap(GetModuleHandle(NULL),MAKEINTRESOURCE(IDB_BITMAP2)); //插入子弹位图
  GetObject(hbm, sizeof(bminfo), &bminfo);
  memdc=CreateCompatibleDC(hdc);
  SelectObject(memdc,hbm);
  while(pHead!=NULL)  //子弹链表不为空,显示子弹
  {
    /*Ellipse(hdc,pHead->x,pHead->y,pHead->x+5,pHead->y+5);*/
    BitBlt(hdc,pHead->x,pHead->y,10,10,memdc,0,0,SRCCOPY);
    pHead=pHead->pnext;
  
  DeleteDC(memdc);
  ReleaseDC(hWnd,hdc);
  DeleteObject(hbm);
}
 
void DiRenMove(DiRen *pHead)  //敌人移动
{
  while(pHead!=NULL)  //链表不为空,敌人移动
  
    if(score<500)
    {
      pHead->y+=10;
      pHead=pHead->pnext;
    }
    else
    {
      pHead->y+=20;
      pHead=pHead->pnext;
    }
  }
}
void ZiDanMove(DiRen *pHead)  //子弹移动
{
  while(pHead!=NULL)  //链表不为空子弹移动
  {
    pHead->y-=20;
    pHead=pHead->pnext;
  }
}
 
void shoot(HWND hWnd,FeiJi *ziji,DiRen **diren,ZiDan **zidan) //判断是否中
{
  DiRen *js1=*diren;
  ZiDan *js2=*zidan;
  int n = 1;
  while(js1!=NULL) //判断自己是否撞机
  {
    //撞击释放定时器游戏结束
    if((ziji->x-js1->x<30&&ziji->x-js1->x>-38)&&(ziji->y-js1->y<25&&ziji->y-js1->y>-38))
    {
      KillTimer(hWnd,TIMER_DIREN);
      KillTimer(hWnd,TIMER_ZIDAN);
      KillTimer(hWnd,TIMER_DIRENMOVE);
      KillTimer(hWnd,TIMER_DIRENRELEASE);
      MessageBox(hWnd,"You Lose","窗口",MB_OK);
      PostQuitMessage(0);
      break;
    }
    else
      js1=js1->pnext;  //没有判断下一个敌机
  }
  js1=*diren;  //敌机回到头
  while((js1=*diren)!=NULL)  //判断敌人是否为空
  {
    zidan = &pZiDan; 
    n = 0;
    while((js2=*zidan)!=NULL) //判断子弹是否为空
    {   
      //敌机中弹
      if((js2->x - js1->x <= 40&&js2->x - js1->x>=-5)&&(js2->y - js1->y <= 40&&js2->y - js1->y>=-8))
      {
        score+=100;
        n = 1;
        *zidan = js2->pnext;
        if(js1->pnext!=NULL) //链表下节不为空,指向下一个释放中弹的飞机子弹
        {
          *diren = js1->pnext;
          diren = &pDiRen;
          free(js1);
          free(js2);
        }
        else
          *diren = NULL; 
        break;
      }
      else
      {
        zidan = &js2->pnext;  //没中看下一个
      }
    }
    if(n != 1)  //判断是否是中弹出来的
    {
      diren = &js1->pnext;
    }
  }
}
void ReleaseDiren(DiRen **pHead) //释放飞出屏幕的敌人
{
  DiRen *js=*pHead;
  while((js=*pHead)!=NULL)
  {
    if(js->y>600)    //飞出屏幕释放
    {
      *pHead=js->pnext;
      free(js);
    }
    else
    {
      pHead = &js->pnext;  //看下一个
    }
  }
}
void ReleaseZidan(ZiDan **pHead)  //释放子弹
{
  ZiDan *js=*pHead;
  while((js=*pHead)!=NULL)
  {
    if(js->y<0)    //飞出的子弹释放
    {
      *pHead=js->pnext; 
      free(js);
    }
    else
      pHead=&js->pnext;  //没飞出看下一个
  }
}

同时分享一个网友的方法

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
//mytestView.cpp:Cmytest;
//;
#include"stdafx.h;
#include"mytest.h;
#include"mytestDoc;
#include"mytestView;
#ifdef_DEBUG;
#definenewDEBUG_NEW;
#endif;//CmytestVie
// mytestView.cpp : CmytestView 类的实现
//
#include "stdafx.h"
#include "mytest.h"
#include "mytestDoc.h"
#include "mytestView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CmytestView
IMPLEMENT_DYNCREATE(CmytestView, CView)
BEGIN_MESSAGE_MAP(CmytestView, CView)
ON_WM_CREATE()
ON_WM_TIMER()
ON_WM_KEYDOWN()
END_MESSAGE_MAP()
// CmytestView 构造/析构
CmytestView::CmytestView()
{
// TODO: 在此处添加构造代码
m_x_me=0;
m_x_enemy=0;
m_y_enemyone=0;
m_y_enemytwo=0;
m_y_bomb=0;
m_x_bomb=0;
m_x_ball=0;
m_y_ball=0;
m_x_explsion=0;
}
CmytestView::~CmytestView()
{
}
BOOL CmytestView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: 在此处通过修改
// CREATESTRUCT cs 来修改窗口类或样式
return CView::PreCreateWindow(cs);
}
// CmytestView 绘制
void CmytestView::OnDraw(CDC* pDC)
{
CmytestDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
// TODO: 在此处为本机数据添加绘制代码
/*CBitmap bitmap;
bitmap.LoadBitmapW(IDB_ME);
*/
//画图
/*pDC->BitBlt(100,50,50,60,&MemDC,0,0,SRCCOPY);*/
/*POINT pt;
pt.x=200;
pt.y=200;
CImageList imageList;
imageList.Create(50,60,ILC_COLOR24|ILC_MASK,1,0);
imageList.Add(&bitmap,RGB(0,0,0));
imageList.Draw(pDC,0,pt,ILD_TRANSPARENT);
CDC MemDC;
MemDC.CreateCompatibleDC(NULL);
MemDC.SelectObject(&bitmap);*/
//RECT rc;
//GetClientRect(&rc);
//CBrush brush;
//brush.CreateSolidBrush(RGB(3,108,254));
//pDC->SelectObject(&brush);
//CBrush *oldbrush=pDC->SelectObject(&brush);
//pDC->Rectangle(&rc);
//pDC->SelectObject(oldbrush);
//CBitmap bitmap;
//bitmap.LoadBitmapW(IDB_ME);
//POINT pt;
//pt.x=200;
//pt.y=200;
//CImageList imageList;
//imageList.Create(60,50,ILC_COLOR24|ILC_MASK,1,0);
//imageList.Add(&bitmap,RGB(0,0,0));
//imageList.Draw(pDC,0,pt,ILD_TRANSPARENT);
// CDC MemDC;
//MemDC.CreateCompatibleDC(NULL);
//MemDC.SelectObject(&bitmap);
//刷新
RECT rc;
GetClientRect(&rc);
CBrush brush;
brush.CreateSolidBrush(RGB(3,108,254));
pDC->SelectObject(&brush);
CBrush *oldbrush=pDC->SelectObject(&brush);
pDC->Rectangle(&rc);
pDC->SelectObject(oldbrush);
//敌机
CBitmap bitmap1;
bitmap1.LoadBitmapW(IDB_enemy);
POINT pt1;
pt1.x=200;
pt1.y=m_y_enemyone;
POINT pt1_2;
pt1_2.x=300;
pt1_2.y=m_y_enemytwo;
CImageList imageList1;
imageList1.Create(35,35,ILC_COLOR24|ILC_MASK,1,0);
imageList1.Add(&bitmap1,RGB(0,0,0));
imageList1.Draw(pDC,0,pt1,ILD_TRANSPARENT);
imageList1.Draw(pDC,1,pt1_2,ILD_TRANSPARENT);
//战机
CBitmap bitmap2;
bitmap2.LoadBitmapW(IDB_ME);
POINT pt2;
pt2.x=m_x_me;
pt2.y=100;
CImageList imageList2;
imageList2.Create(50,60,ILC_COLOR24|ILC_MASK,1,0);
imageList2.Add(&bitmap2,RGB(0,0,0));
imageList2.Draw(pDC,0,pt2,ILD_TRANSPARENT);
//子弹
CBitmap bitmap3;
bitmap3.LoadBitmapW(IDB_ball);
POINT pt3;
pt3.x=150;
pt3.y=m_y_ball;
CImageList imageList3;
imageList3.Create(8,8,ILC_COLOR24|ILC_MASK,1,0);
imageList3.Add(&bitmap3,RGB(0,0,0));
imageList3.Draw(pDC,0,pt3,ILD_TRANSPARENT);
//炸弹
CBitmap bitmap4;
bitmap4.LoadBitmapW(IDB_bomb);
POINT pt4;
pt4.x=m_x_bomb;
pt4.y=250;
CImageList imageList4;
imageList4.Create(10,20,ILC_COLOR24|ILC_MASK,1,0);
imageList4.Add(&bitmap4,RGB(0,0,0));
imageList4.Draw(pDC,0,pt4,ILD_TRANSPARENT);
//爆炸
CBitmap bitmap5;
bitmap5.LoadBitmapW(IDB_explsion);
POINT pt5_1;
pt5_1.x=310;
pt5_1.y=310;
POINT pt5_2;
pt5_2.x=330;
pt5_2.y=330;
POINT pt5_3;
pt5_3.x=350;
pt5_3.y=450;
POINT pt5_4;
pt5_4.x=470;
pt5_4.y=470;
POINT pt5_5;
pt5_5.x=510;
pt5_5.y=510;
POINT pt5_6;
pt5_6.x=530;
pt5_6.y=530;
POINT pt5_7;
pt5_7.x=540;
pt5_7.y=540;
POINT pt5_8;
pt5_8.x=450;
pt5_8.y=250;
CImageList imageList5;
imageList5.Create(66,66,ILC_COLOR24|ILC_MASK,1,0);
imageList5.Add(&bitmap5,RGB(0,0,0));
imageList5.Draw(pDC,0,pt5_1,ILD_TRANSPARENT);
imageList5.Draw(pDC,1,pt5_2,ILD_TRANSPARENT);
imageList5.Draw(pDC,2,pt5_3,ILD_TRANSPARENT);
imageList5.Draw(pDC,3,pt5_4,ILD_TRANSPARENT);
imageList5.Draw(pDC,4,pt5_5,ILD_TRANSPARENT);
imageList5.Draw(pDC,5,pt5_6,ILD_TRANSPARENT);
imageList5.Draw(pDC,6,pt5_7,ILD_TRANSPARENT);
imageList5.Draw(pDC,7,pt5_8,ILD_TRANSPARENT);
/*CDC MemDC;
MemDC.CreateCompatibleDC(NULL);
MemDC.SelectObject(&bitmap2);*/
}
// CmytestView 诊断
#ifdef _DEBUG
void CmytestView::AssertValid() const
{
CView::AssertValid();
}
void CmytestView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CmytestDoc* CmytestView::GetDocument() const // 非调试版本是内联的 {
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CmytestDoc))); return (CmytestDoc*)m_pDocument;
}
#endif //_DEBUG
// CmytestView 消息处理程序
int CmytestView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: 在此添加您专用的创建代码
SetTimer(1,30,NULL);
return 0;
}
void CmytestView::OnTimer(UINT_PTR nIDEvent)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
CView::OnTimer(nIDEvent);
CDC *pDC=GetDC();
//刷新背景
RECT rc;
GetClientRect(&rc);
CBrush brush;
brush.CreateSolidBrush(RGB(3,108,254));
pDC->SelectObject(&brush);
CBrush *oldbrush=pDC->SelectObject(&brush);
pDC->Rectangle(&rc);
pDC->SelectObject(oldbrush);
//战机
CBitmap bitmap2;
bitmap2.LoadBitmapW(IDB_ME);
POINT pt2;
pt2.x=m_x_me;
pt2.y=100;
CImageList imageList2;
imageList2.Create(50,60,ILC_COLOR24|ILC_MASK,1,0);
imageList2.Add(&bitmap2,RGB(0,0,0));
imageList2.Draw(pDC,0,pt2,ILD_TRANSPARENT);
//子弹

欢迎试玩一下游戏 方向键:w,a,s,d  控制键:J,K