标签:
坦克大战最短路 算法:优先队列+广度优先搜索 用户自定义地图 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