NPC简单AI处理
2009-02-16 19:11
288 查看
以前曾做过一个ARPG游戏,相应用到了NPC寻路与攻击多种状态等。
一般的NPC移动时就是通过不停检测与英雄是否产生了碰撞,否则就获得英雄的坐标,再进行分X或Y的方向行走。当然这只是用于地图没有任何障碍物上。
public boolean isRamWithHero() {// 碰撞检测
if ((x + imWidth > hero.x + 10) & (y + (imHeight >> 1) > hero.y)
& (hero.x + hero.imWidth > x + 10)
& (hero.y + (hero.imHeight >> 1) > y)) {
return true;
}
return false;
}
public boolean isMoveX() {
if (x - hero.x >= steplength) {// left
direction = MS_LEFT;
return true;
} else if (hero.x - x >= steplength) {// right
direction = MS_RIGHT;
return true;
}
return false;
}
public boolean isMoveY() {
if (hero.y - y >= steplength) {// left
direction = MS_DOWN;
return true;
} else if (y - hero.y >= steplength) {// right
direction = MS_UP;
return true;
}
return false;
}
public void seekWalk() {// 寻路行走
if (isRamWithHero()) {
if (hero.RoleState == RS_ATTACK || hero.RoleState == RS_SKILL) {// 检测主角是否攻击状态
RoleState = RS_BEATING;
} else {
RoleState = RS_ATTACK;
}
} else {// 处理寻路行走
if (isMoveY) {
if (!isMoveY()) {
isMoveX();
}
} else {
if (!isMoveX()) {
isMoveY();
}
}
}
}
当一个NPC有了寻找英雄的功能后,就要有攻击英雄的技能,但是考虑一个问题的是,只按X或Y这两个方向做移动的话,那当NPC有一定数量后,就会产生重叠的现象,而为了做得太真实一点,所以就在NPC攻击英雄时产生一个机率,让NPC由英雄的正方向走到其左边或者右边,进行围攻。
public void dealAttack() {// 处理攻击走位
counter = (byte) MainCanvas.getRandom(0, 2);// 各有一半的机会走不同方向
switch (direction) {
case MS_UP:
case MS_DOWN:
if (counter == 0) {
MoveDirection = MS_LEFT;
} else if (counter == 1) {
MoveDirection = MS_RIGHT;
}
RoleState = RS_DEALMOVE;
break;
case MS_LEFT:
case MS_RIGHT:
if (counter == 0) {
MoveDirection = MS_UP;
} else if (counter == 1) {
MoveDirection = MS_DOWN;
}
RoleState = RS_DEALMOVE;
break;
}
counter = 0;
dealMove();
}
public void dealMove() {// 处理位置移动
if (isRamWithHero()
& (hero.RoleState == RS_ATTACK || hero.RoleState == RS_SKILL)) {
setBeatingFormat();
RoleState = RS_BEATING;
} else {
switch (MoveDirection) {
case MS_UP:
dealMoveUp();
break;
case MS_DOWN:
dealMoveDown();
break;
case MS_LEFT:
dealMoveLeft();
break;
case MS_RIGHT:
dealMoveRight();
break;
}
}
}
public void dealMoveUp() {// 走到上面
if (y + imHeight > hero.y & y > 35 && MapY <= 30) {
direction = MS_UP;
} else if (counter < 16) {
counter++;
if (x - hero.x >= steplength) {
direction = MS_LEFT;
} else if (hero.x - x >= steplength) {
direction = MS_RIGHT;
} else {
setMoveFormat();
RoleState = RS_WALK;
}
} else {
setMoveFormat();
RoleState = RS_WALK;
}
}
public void dealMoveDown() {// 走到下面
if (y < hero.y + hero.imHeight) {
direction = MS_DOWN;
} else if (counter < 16) {
counter++;
if (x - hero.x >= steplength) {
direction = MS_LEFT;
} else if (hero.x - x >= steplength) {
direction = MS_RIGHT;
} else {
setMoveFormat();
RoleState = RS_WALK;
}
} else {
setMoveFormat();
RoleState = RS_WALK;
}
}
public void dealMoveLeft() {// 走到左边
if (x + imWidth > hero.x) {
direction = MS_LEFT;
} else if (counter < 16) {
counter++;
if (y - hero.y >= steplength & y > 30 && MapY <= 30) {
direction = MS_UP;
} else if (hero.y - y >= steplength) {
direction = MS_DOWN;
} else {
setMoveFormat();
RoleState = RS_WALK;
}
} else {
setMoveFormat();
RoleState = RS_WALK;
}
}
public void dealMoveRight() {// 走到右边
if (x < hero.x + hero.imWidth) {
direction = MS_RIGHT;
} else if (counter < 16) {
counter++;
if (y - hero.y >= steplength & y > 30 && MapY <= 30) {
direction = MS_UP;
} else if (hero.y - y >= steplength) {
direction = MS_DOWN;
} else {
setMoveFormat();
RoleState = RS_WALK;
}
} else {
setMoveFormat();
RoleState = RS_WALK;
}
}
这是我整理出来的部分代码,当中为了清晰还做了裁剪,但是已能表达原意,其体思路还是清晰的。
本人一直致力于AI与图形优化,即时等研究与开发。常常对于自己说的AIAI悲哀悲哀,做研究这一路很是郁闷与痛苦的,但是其结果却是那样的振备人心,当到屏幕上那个图片按着你的意思你的规矩进行相应的动作,会有无限的欢喜,因为会感觉,他们的生命是我的给予。呵呵,AI一路,可说是一门技术,愿与志同道合者一起研究学习。
[转自 j2megame的hubluesky会员]
一般的NPC移动时就是通过不停检测与英雄是否产生了碰撞,否则就获得英雄的坐标,再进行分X或Y的方向行走。当然这只是用于地图没有任何障碍物上。
public boolean isRamWithHero() {// 碰撞检测
if ((x + imWidth > hero.x + 10) & (y + (imHeight >> 1) > hero.y)
& (hero.x + hero.imWidth > x + 10)
& (hero.y + (hero.imHeight >> 1) > y)) {
return true;
}
return false;
}
public boolean isMoveX() {
if (x - hero.x >= steplength) {// left
direction = MS_LEFT;
return true;
} else if (hero.x - x >= steplength) {// right
direction = MS_RIGHT;
return true;
}
return false;
}
public boolean isMoveY() {
if (hero.y - y >= steplength) {// left
direction = MS_DOWN;
return true;
} else if (y - hero.y >= steplength) {// right
direction = MS_UP;
return true;
}
return false;
}
public void seekWalk() {// 寻路行走
if (isRamWithHero()) {
if (hero.RoleState == RS_ATTACK || hero.RoleState == RS_SKILL) {// 检测主角是否攻击状态
RoleState = RS_BEATING;
} else {
RoleState = RS_ATTACK;
}
} else {// 处理寻路行走
if (isMoveY) {
if (!isMoveY()) {
isMoveX();
}
} else {
if (!isMoveX()) {
isMoveY();
}
}
}
}
当一个NPC有了寻找英雄的功能后,就要有攻击英雄的技能,但是考虑一个问题的是,只按X或Y这两个方向做移动的话,那当NPC有一定数量后,就会产生重叠的现象,而为了做得太真实一点,所以就在NPC攻击英雄时产生一个机率,让NPC由英雄的正方向走到其左边或者右边,进行围攻。
public void dealAttack() {// 处理攻击走位
counter = (byte) MainCanvas.getRandom(0, 2);// 各有一半的机会走不同方向
switch (direction) {
case MS_UP:
case MS_DOWN:
if (counter == 0) {
MoveDirection = MS_LEFT;
} else if (counter == 1) {
MoveDirection = MS_RIGHT;
}
RoleState = RS_DEALMOVE;
break;
case MS_LEFT:
case MS_RIGHT:
if (counter == 0) {
MoveDirection = MS_UP;
} else if (counter == 1) {
MoveDirection = MS_DOWN;
}
RoleState = RS_DEALMOVE;
break;
}
counter = 0;
dealMove();
}
public void dealMove() {// 处理位置移动
if (isRamWithHero()
& (hero.RoleState == RS_ATTACK || hero.RoleState == RS_SKILL)) {
setBeatingFormat();
RoleState = RS_BEATING;
} else {
switch (MoveDirection) {
case MS_UP:
dealMoveUp();
break;
case MS_DOWN:
dealMoveDown();
break;
case MS_LEFT:
dealMoveLeft();
break;
case MS_RIGHT:
dealMoveRight();
break;
}
}
}
public void dealMoveUp() {// 走到上面
if (y + imHeight > hero.y & y > 35 && MapY <= 30) {
direction = MS_UP;
} else if (counter < 16) {
counter++;
if (x - hero.x >= steplength) {
direction = MS_LEFT;
} else if (hero.x - x >= steplength) {
direction = MS_RIGHT;
} else {
setMoveFormat();
RoleState = RS_WALK;
}
} else {
setMoveFormat();
RoleState = RS_WALK;
}
}
public void dealMoveDown() {// 走到下面
if (y < hero.y + hero.imHeight) {
direction = MS_DOWN;
} else if (counter < 16) {
counter++;
if (x - hero.x >= steplength) {
direction = MS_LEFT;
} else if (hero.x - x >= steplength) {
direction = MS_RIGHT;
} else {
setMoveFormat();
RoleState = RS_WALK;
}
} else {
setMoveFormat();
RoleState = RS_WALK;
}
}
public void dealMoveLeft() {// 走到左边
if (x + imWidth > hero.x) {
direction = MS_LEFT;
} else if (counter < 16) {
counter++;
if (y - hero.y >= steplength & y > 30 && MapY <= 30) {
direction = MS_UP;
} else if (hero.y - y >= steplength) {
direction = MS_DOWN;
} else {
setMoveFormat();
RoleState = RS_WALK;
}
} else {
setMoveFormat();
RoleState = RS_WALK;
}
}
public void dealMoveRight() {// 走到右边
if (x < hero.x + hero.imWidth) {
direction = MS_RIGHT;
} else if (counter < 16) {
counter++;
if (y - hero.y >= steplength & y > 30 && MapY <= 30) {
direction = MS_UP;
} else if (hero.y - y >= steplength) {
direction = MS_DOWN;
} else {
setMoveFormat();
RoleState = RS_WALK;
}
} else {
setMoveFormat();
RoleState = RS_WALK;
}
}
这是我整理出来的部分代码,当中为了清晰还做了裁剪,但是已能表达原意,其体思路还是清晰的。
本人一直致力于AI与图形优化,即时等研究与开发。常常对于自己说的AIAI悲哀悲哀,做研究这一路很是郁闷与痛苦的,但是其结果却是那样的振备人心,当到屏幕上那个图片按着你的意思你的规矩进行相应的动作,会有无限的欢喜,因为会感觉,他们的生命是我的给予。呵呵,AI一路,可说是一门技术,愿与志同道合者一起研究学习。
[转自 j2megame的hubluesky会员]
相关文章推荐
- NPC简单AI处理
- Java版战棋(SLG)游戏AI及寻径处理入门
- linux下 c中怎么让才能安全关闭线程 和 linux线程退出时执行的程序(线程清理处理程序)简单例子
- WP7开发系列——Windows Phone 7平台简单图像处理
- (4)事件处理——(7)简单事件(Simple events)
- iOS开发 - 代码耦合性简单处理
- [转载]简单方法处理usp10.dll (原文地址:http://bbs.kafan.cn/viewthread.php?tid=421630)
- Java大数类处理的简单程序
- 处理PHP字符串的10个简单方法
- PHP 简单处理--文件下载--文件上传
- 一个简单的能处理MIP-MAP的类
- SQL 处理简单的 Xml
- PostgreSQL服务过程中的那些事二:Pg服务进程处理简单查询一:开启事务
- webdriver结合tesseract-ocr处理简单验证码
- 最简单的处理MVC中默认的Json方法返回时间的问题
- 简单运算处理类
- Android 6.0 运行时权限简单处理
- 小小的总结一下java异常处理和List、ArrayList、Vector、Set、HashSet、TreeSet集合的简单应用
- 【转帖】C++中对日期和时间的处理的函数简单介绍
- Linux TCP server系列(1)-简单TCP服务器+多进程处理客户请求