标签:
坦克大战最短路 算法:优先队列+广度优先搜索 用户自定义地图 1. 设置地图大小起点和终点 设置弹药 2. 设置铁墙、土墙、河水 3. 模式一:用户自己走 模式二:自动给出最短路 对比 坦克方法: 1. 调整方向 2. 开枪 事件: 判断是否达到 是否可以走 是否打到墙(子弹能可以穿过河) 游戏是否结束 人性化: 背景音乐 子弹效果 保存地图 当前最短 爆炸效果
一、界面 1、地图 大小 12*12 每个方格 边长60个像素 左上角为原点(0,0) 2、对象 坦克(Tank) 砖块(Brick) 1次打破 钢墙(Steel) 2次打破 河水(River) 子弹可以穿过,坦克不可以 星星(Star) 子弹(Bullet) 3、菜单 添加对象 手动模式 自动模式 4、显示 当前消耗 帮助 二、类设计 1.游戏父类 GameObject 属性: x,y,width,height,image 方法: 构造函数(初始化) Draw(); GetRectangle(); 2.墙壁父类 WallFather:GameObject 属性: +life 方法: 构造函数(初始化) 重写Draw(); IsOver(); 3.River&Star父类 RSFather:GameObject 方法: 构造函数(初始化) 重写Draw(); 4.Bullet :GameObject 属性: +power 方法: 构造函数(初始化) 重写Draw(); 5.Tank:GameObject 属性: 方法: 重写Draw(g); Move(); Fire(); 6.SingleObject 方法: GetSingle(); Draw(); Check(); 三、事件响应
1.新建一个VC++ win32 DLL 2.添加头文件"" 在头文件中加入以下代码: #ifndef DLL_EXPORT #define DECLDIR __declspec(dllimport) #else #define DECLDIR __declspec(dllexport) #endif 3.添加源程序,添加以下代码: #define DLL_EXPORT //先定义宏 #include "Dll.h"//这个头文件必须在#define DLL_EXPORT后面 4.编写自己需要的函数: extern "C" { DECLDIR 返回值 函数名(参数...) { } } 5.添加必要的头文件,不需要main函数,编译即可 6.建立一个C#工程,将生成的Dll文件(在Debug目录下)扔到C#工程Bin 目录下。 7.在C#中添加如下代码: (1). 命名空间 using System.Runtime.InteropServices; (2).声明 [DllImport("CppDll.dll", SetLastError = true)] private static extern 返回值 函数名(参数...); 8.然后这个函数就可以直接在C#工程中使用了
C++ C# ===================================== WORD ushort DWORD uint UCHAR int/byte 大部分情况都可以使用int代替,而如果需要严格对齐的话则应该用bytebyte UCHAR* string/IntPtr unsigned char* [MarshalAs(UnmanagedType.LPArray)]byte[]/?(Intptr) char* string LPCTSTR string LPTSTR [MarshalAs(UnmanagedType.LPTStr)] string long int ulong uint Handle IntPtr HWND IntPtr void* IntPtr int int int* ref int *int IntPtr unsigned int uint COLORREF uint
#include<iostream> #include<algorithm> #include<string> #include<cstring> #include<queue> #define N 15 #define Max_Len 100 #define DLL_EXPORT //先定义宏 #include "Dll.h"//这个头文件必须在#define DLL_EXPORT后面 using namespace std; int n, m, sx, sy, ex, ey, visit[N][N]; int dir[][2] = { { 0, 1 }, { 0, -1 }, { 1, 0 }, { -1, 0 } }; char chess[N][N]; enum TankAcationType { //Move MoveStep, //Fire Move FireOneWall, //Fire Fire Move FireTwoWall, //Dir->Up Move ChangeTheDirToUp, //Dir->Up Fire ChangeToUpFireOne, //Dir->Up Fire Fire ChangeToUpFireTwo, //Dir->Down Fire ChangeToDownFireOne, //Dir->Down Move ChangeTheDirToDown, //Dir->Down Fire Fire ChangeToDownFireTwo, //Dir->Left Move ChangeTheDirToLeft, //Dir->Left Fire ChangeToLeftFireOne, //Dir->Left Fire Fire ChangeToLeftFireTwo, //Dir->Right Move ChangeTheDirToRight, //Dir->Right Fire ChangeToRightFireOne, //Dir->Right Fire Fire ChangeToRightFireTwo, None } TmpType; TankAcationType TmpPath[Max_Len]; struct Node{ int x, y, s,d; int step; TankAcationType Path[Max_Len]; friend bool operator <(Node a, Node b){ return a.s>b.s; } }; bool ok(int x, int y){ if (x >= 0 && x<m&&y >= 0 && y<n&&chess[x][y] != 'R'&&chess[x][y] != '#') return true; return false; } extern "C" { DECLDIR int bfs( char * Map,TankAcationType * ActionPath,int &Count){ m = 15; n = 15; for (int i = 0; i < 15; i++) for (int j = 0; j < 15; j++) chess[i][j] = '#'; for (int i = 0; i < 12;i++) for (int j = 0; j < 11; j++) chess[i][j] = '.'; for (int i = 0; i<n; i++) for (int j = 0; j < m; j++){ if (Map[i*m + j] == '#'&&chess[i][j] == '.')continue; chess[i][j] = Map[i*m + j]; } for (int i = 0; i<m; i++) for (int j = 0; j<n; j++){ if (chess[i][j] == 'T'){ sx = i; sy = j; chess[i][j] = 'R'; } else if (chess[i][j] == 'X'){ ex = i; ey = j; chess[i][j] = '.'; } } priority_queue<Node> q; memset(visit, -1, sizeof(visit)); visit[sx][sy] = 0; Node head = { sx, sy, 0 ,1,0}; head.d = 1; q.push(head); while (!q.empty()) { Node f = q.top(); q.pop(); if (f.x == ex&&f.y == ey){ for (int i = 0; i < f.step; i++) ActionPath[i] = f.Path[i]; Count = f.step; return f.s; } for (int i = 0; i<4; i++){ int dx = f.x + dir[i][0], dy = f.y + dir[i][1]; if (ok(dx, dy) && visit[dx][dy]){ visit[dx][dy] = 0; int temp = 0; if (chess[dx][dy] == 'S'){ temp = 3; if (f.d==i) TmpType = FireTwoWall; else { temp++; switch (i) { case 0: TmpType = ChangeToDownFireTwo; break; case 1: TmpType = ChangeToUpFireTwo; break; case 2: TmpType = ChangeToRightFireTwo; break; case 3: TmpType = ChangeToLeftFireTwo; break; } } } else if (chess[dx][dy] == 'B'){ temp = 2; if(f.d==i)TmpType = FireOneWall; else { temp++; switch (i) { case 0: TmpType = ChangeToDownFireOne; break; case 1: TmpType = ChangeToUpFireOne; break; case 2: TmpType = ChangeToRightFireOne; break; case 3: TmpType = ChangeToLeftFireOne; break; } } } else if (chess[dx][dy] == '.') { temp = 1; if(f.d==i)TmpType = MoveStep; else { temp++; switch (i) { case 0: TmpType = ChangeTheDirToDown; break; case 1: TmpType = ChangeTheDirToUp; break; case 2: TmpType = ChangeTheDirToRight; break; case 3: TmpType = ChangeTheDirToLeft; break; } } } for (int k = 0; k < f.step; k++) TmpPath[k] = f.Path[k]; TmpPath[f.step] = TmpType; Node tmp = { dx, dy, f.s + temp}; for (int k = 0; k <= f.step; k++) tmp.Path[k] = TmpPath[k]; tmp.step = f.step + 1; tmp.d = i; q.push(tmp); } } } return -1; } }
#region AutoRun 方法 public static void AutoRun() { for (int i = 0; i <TotalStep; i++) { switch (GameObject.AcationPath[i]) { case TankAcationType.ChangeTheDirToUp: MessageBox.Show("向上"); GameObject.Cost++; SingleObject.GetObject().T.Dir = Direction.Up; MessageBox.Show("向前"); SingleObject.GetObject().T.Move(); break; case TankAcationType.ChangeTheDirToDown: MessageBox.Show("向下"); GameObject.Cost++; SingleObject.GetObject().T.Dir = Direction.Down; MessageBox.Show("向前"); SingleObject.GetObject().T.Move(); break; case TankAcationType.ChangeTheDirToLeft: MessageBox.Show("向左"); GameObject.Cost++; SingleObject.GetObject().T.Dir = Direction.Left; MessageBox.Show("向前"); SingleObject.GetObject().T.Move(); break; case TankAcationType.ChangeTheDirToRight: MessageBox.Show("向右"); GameObject.Cost++; SingleObject.GetObject().T.Dir = Direction.Right; MessageBox.Show("向前"); SingleObject.GetObject().T.Move(); break; case TankAcationType.FireOneWall: MessageBox.Show("开火"); SingleObject.GetObject().T.Fire(); MessageBox.Show("向前"); SingleObject.GetObject().T.Move(); break; case TankAcationType.FireTwoWall: MessageBox.Show("开火"); SingleObject.GetObject().T.Fire(); MessageBox.Show("开火"); SingleObject.GetObject().T.Fire(); MessageBox.Show("向前"); SingleObject.GetObject().T.Move(); break; case TankAcationType.MoveStep: MessageBox.Show("向前"); SingleObject.GetObject().T.Move(); break; case TankAcationType.ChangeToDownFireOne: MessageBox.Show("向下"); GameObject.Cost++; SingleObject.GetObject().T.Dir = Direction.Down; MessageBox.Show("开火"); SingleObject.GetObject().T.Fire(); MessageBox.Show("向前"); SingleObject.GetObject().T.Move(); break; case TankAcationType.ChangeToDownFireTwo: MessageBox.Show("向下"); GameObject.Cost++; SingleObject.GetObject().T.Dir = Direction.Down; MessageBox.Show("开火"); SingleObject.GetObject().T.Fire(); MessageBox.Show("开火"); SingleObject.GetObject().T.Fire(); MessageBox.Show("向前"); SingleObject.GetObject().T.Move(); break; case TankAcationType.ChangeToLeftFireOne: MessageBox.Show("向左"); GameObject.Cost++; SingleObject.GetObject().T.Dir = Direction.Left; MessageBox.Show("开火"); SingleObject.GetObject().T.Fire(); MessageBox.Show("向前"); SingleObject.GetObject().T.Move(); break; case TankAcationType.ChangeToLeftFireTwo: MessageBox.Show("向左"); GameObject.Cost++; SingleObject.GetObject().T.Dir = Direction.Left; MessageBox.Show("开火"); SingleObject.GetObject().T.Fire(); MessageBox.Show("开火"); SingleObject.GetObject().T.Fire(); MessageBox.Show("向前"); SingleObject.GetObject().T.Move(); break; case TankAcationType.ChangeToRightFireOne: MessageBox.Show("向右"); GameObject.Cost++; SingleObject.GetObject().T.Dir = Direction.Right; MessageBox.Show("开火"); SingleObject.GetObject().T.Fire(); MessageBox.Show("向前"); SingleObject.GetObject().T.Move(); break; case TankAcationType.ChangeToRightFireTwo: MessageBox.Show("向右"); GameObject.Cost++; SingleObject.GetObject().T.Dir = Direction.Right; MessageBox.Show("开火"); SingleObject.GetObject().T.Fire(); MessageBox.Show("开火"); SingleObject.GetObject().T.Fire(); MessageBox.Show("向前"); SingleObject.GetObject().T.Move(); break; case TankAcationType.ChangeToUpFireOne: MessageBox.Show("向上"); GameObject.Cost++; SingleObject.GetObject().T.Dir = Direction.Up; MessageBox.Show("开火"); SingleObject.GetObject().T.Fire(); MessageBox.Show("向前"); SingleObject.GetObject().T.Move(); break; case TankAcationType.ChangeToUpFireTwo: MessageBox.Show("向上"); GameObject.Cost++; SingleObject.GetObject().T.Dir = Direction.Up; MessageBox.Show("开火"); SingleObject.GetObject().T.Fire(); MessageBox.Show("开火"); SingleObject.GetObject().T.Fire(); MessageBox.Show("向前"); SingleObject.GetObject().T.Move(); break; } } } #endregion
标签:
原文地址:http://blog.csdn.net/mummyding/article/details/43965923