Controlling NPC movement

NPCs can walk around the virtual world as the players. The movement is controlled in server-side extension.

Controlling NPC to walk in predefined path

Some NPCs' movement is fixed to a predefined path. For these NPCs, we can dispatch the path directly without path finding algorithm. In the following example, we will repeatedly control the NPC to walk between two points.

As we treat the NPC as a normal player in the logic, we will use the same walking mechanism from the player. The NPC will dispatch a public message with specific walking path to other players in the same room. Every client will then move the NPC according to the path. We have an npcLoop function in server-side extension. We will put the NPC movement logic there.

function npcLoop(){
if (theNpcUser != null) {
theNpcUser.updateMessageTime();
var rooms = theNpcUser.getRoomsConnected();
if (theNpcUser.getVariable("isoPosX").getValue() == 8){
_server.dispatchPublicMessage("|path|4,16;", _server. getCurrentZone().getRoom(rooms[0]), theNpcUser)
var uVars = {}
uVars.isoPosX = 4;
_server.setUserVariables(theNpcUser, uVars);
}else{
_server.dispatchPublicMessage("|path|8,16;", _server. getCurrentZone().getRoom(rooms[0]), theNpcUser)
var uVars = {}
uVars.isoPosX = 8;
_server.setUserVariables(theNpcUser, uVars);
}
}
}

Directing NPC to walk using path finding algorithm

Controlling the NPC to walk in predefined path sometimes looks too mechanical. We may want some NPC to walk randomly within the world, or even follow the players. We used A-star search algorithm in Chapter 6, Walking Around The World, for the movement of the player in client-side. We need the same algorithm in server-side now.

Path finding algorithm is relatively resource consuming. In order to gain performance on calculating the path, we will use Java implementation instead of the ActionScript. As the SmartFoxServer is running on Java environment, we can benefit from the performance of running native Java. We will apply the advanced extension techniques we just discussed to use the Java path finding class inside the ActionScript extension.

We can use an existing A-star Java class from Internet and integrate it with our map. We created a class called AStarSolution to load the map data on server-side and provide a getPath method to solve the path finding with a downloaded A-star class. The full code is in code example bundle and we will take a look at the getPath method.

The getPath method calls the A-star algorithm to calculate the path by providing the starting point and ending point. Later we put the path into the format that we used to send out the walking message.

public String getPath(int originX, int originY, int destX, int destY)
{
NodoAstar nodeInit = mapData[originY][originX];
NodoAstar nodeFinal = mapData[destY][destX];
Astar pathfinder = new Astar(mapData, nodeInit, nodeFinal, false);
ArrayList result = pathfinder.calcularCamino();
String path = "|path|";
if (result != null) {
for (int i = result.size()-1; i >= 0; i--) {
NodoAstar node = (NodoAstar) result.get(i);
path += node.getX()+","+node.getY()+";";
}
} else {
System.out.println("path not found");
}
return path;
}

We will control an enemy NPC to follow the first player in the virtual world to demonstrate the server-side path finding. We will use the current NPC position and the player's position to ask the Java A-star class to generate the path. Then we will dispatch the path to all players in the room.

function npcLoop() {
if (enemy != null) {
enemy.updateMessageTime();
// follow the 1st player.
var rooms = enemy.getRoomsConnected();
var currentRoom = _server.getCurrentZone().getRoom(rooms[0]);
var allUsers = currentRoom.getAllUsers();
if (allUsers[1] != undefined){
// get the position of the NPC and the 1st player.
var selfIsoX = Number(enemy.getVariable("isoPosX"). getValue());
var selfIsoY = Number(enemy.getVariable("isoPosY"). getValue());
var destX = Number(allUsers[1]. getVariable("isoPosX").getValue());
var destY = Number(allUsers[1]. getVariable("isoPosY").getValue());
// calculate the path to walk towards the 1st player
if (selfIsoX != destX || selfIsoY != destY) {
var uVars = {}
uVars.isoPosX = Number(destX);
uVars.isoPosY = Number(destY);
_server.setUserVariables(enemy, uVars);
var enemy_astar = new Packages. AStarSolution('island1'),
var path = enemy_astar .getPath(selfIsoX,selfIsoY,destX,destY);
_server.dispatchPublicMessage(path, _server. getCurrentZone().getRoom(rooms[0]), enemy)
}
}
}
}

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.119.28.94