xml| background before the time with a flash to do a game of the demo, communication with the socket. Have promised to write a tutorial, now free to write it.
First from the Flash talk. I want to achieve the effect is to click on the ground, the character will go to click the location. Train of thought: A mouse listener listens to the mouse click event, the x coordinates and the y coordinates are uploaded to the role as the destination of the role. Each frame of the character moves a little bit to this destination.
ROLE_MC is a movieclip in the scene
role_mc.x = role_mc._x;
Role_mc.y = role_mc._y;
var mouselistener:object = new Object ();
Mouselistener.onmousedown = function () {
Moverole (ROLE_MC, _xmouse, _ymouse);
};
Mouse.addlistener (MouseListener);
function Moverole (Role:movieclip, X:number, Y:number) {
role.x = x;
Role.y = y;
Role.onenterframe = function () {
if (this.x!= this._x) {
This._x + = this.x-this._x>0? 1:-1;
}
if (this.y!= this._y) {
This._y + = this.y-this._y>0? 1:-1;
}
if (this.x = = this._x && This.y = = this._y) {
Delete This.onenterframe;
}
};
Try the effect and find that the character will move at a 45-degree angle to the vertical or horizontal level after the destination. This is the algorithm in the move function that is not written well. Now let's think about what I want to do with the movement. [1.gif]
As the figure, the character at point A, to move to point B, the direction is AB. The C-point is the point where the next character will appear, and the vector AC corresponds to the speed of the character. The vector ac is decomposed into two axes to get the vector ae in the x direction and the vector ad in the y direction, which is the XY value that the character needs to move in this frame. The speed of a character is known, and to get two decomposed vectors, you just have to know the angle. Angles can also be obtained from point A and point B. I set the character to the right for 0 degrees, then 90 degrees up, 90 degrees down, and 180 degrees to the left. The reason for this is to calculate conveniently. such as Math.atan2 (Role_mc.y-role_mc._y, role_mc.x-role_mc._x) can be directly to the direction of the role oriented (note that math.atan2 get the number in radians, not the angle). So rewrite as: role_mc.x = role_mc._x;
Role_mc.y = role_mc._y;
Role_mc.speed = 5;
Role_mc.angle = 0;
var mouselistener:object = new Object ();
Mouselistener.onmousedown = function () {
Moverole (ROLE_MC, _xmouse, _ymouse);
};
Mouse.addlistener (MouseListener);
function Moverole (Role:movieclip, X:number, Y:number) {
role.x = x;
Role.y = y;
Role.angle = Math.atan2 (role.y-role._y, role.x-role._x);
Role.onenterframe = function () {
if (this.x!= this._x) {
This._x + = Math.Abs (this.x-this._x) >math.abs (This.speed*math.cos (this.angle))? This.speed*math.cos (This.angle): this.x-this._x; When the role and destination distance is less than the speed of the role, can not be calculated by the speed of the displacement, and directly moved to the destination, y direction of the same
}
if (this.y!= this._y) {
This._y + = Math.Abs (this.y-this._y) >math.abs (This.speed*math.sin (this.angle))? This.speed*math.sin (This.angle): this.y-this._y;
}
if (this.x = = this._x && This.y = = this._y) {
Delete This.onenterframe;
}
};
The move seems to be no big deal. Now to be a character. I have two pictures of myself drawn from the RO, or the characters from the game to get the figure out.
[Role.png]
[Head.png]:
Import two pictures into the role_mc of Flash. Because I make a picture of the body and the head in all directions, I use a mask to show only the one I need. The first frame is made to stand in the first direction, give frame name stand_1, add As:stop (), after several frames to make walking animation, give frame name run_1, plus As:play (), after walking animation, add a blank key frame, plus as:gotoandplay ("Run _1 "). This completes One Direction. Add a few other directions behind this paragraph. All I do is direction 1 for down, 2 for left, 3 for left, 4 for left, 5 for top. The other three directions can be followed by a horizontal flip in the 234 direction. Perhaps I said not very clear, look at this document (TEACH1.FLA) I know. After doing this step, you can add something to the Moverole function and let the character make the appropriate action. Let's take a look at the angle value of the character to represent which direction the role is oriented. See figure below
[2.gif]:
The red line in the diagram is the divider of each direction, the angle is also listed, in radians for the convenience of the calculation. The as also modified to achieve the effect of walking.
role_mc.x = role_mc._x;
Role_mc.y = role_mc._y;
Role_mc.speed = 5;
Role_mc.angle = 0;
var mouselistener:object = new Object ();
Mouselistener.onmousedown = function () {
Moverole (ROLE_MC, _xmouse, _ymouse);
};
Mouse.addlistener (MouseListener);
function Moverole (Role:movieclip, X:number, Y:number) {
role.x = x;
Role.y = y;
Role.angle = Math.atan2 (role.y-role._y, role.x-role._x);
Role.dire = 1+math.round ((role.angle+math.pi)/(MATH.PI/4)); The value of the angle of the character orientation from-math.pi to Math.PI to the natural number 1 to 8, respectively, eight directions
Role.dire = role.dire>6? Role.dire-6: role.dire+2; Handle the eight directions in accordance with the direction of the representative on the diagram.
if (role.dire>5) {
If the direction is one of 789, flip the MC horizontally
Role.dire = Role.dire = = 6? 4:role.dire = 7? 3:2; Direction 6 corresponds direction 4,7 corresponds 3,8 corresponds to 2
Role._xscale =-100;
} else {
Role._xscale = 100;
}
Role.gotoandplay ("Run_" +role.dire);
Role.onenterframe = function () {
if (this.x!= this._x) {
This._x + = Math.Abs (this.x-this._x) >math.abs (This.speed*math.cos (this.angle))? This.speed*math.cos (This.angle): this.x-this._x;
}
if (this.y!= this._y) {
This._y + = Math.Abs (this.y-this._y) >math.abs (This.speed*math.sin (this.angle))? This.speed*math.sin (This.angle): this.y-this._y;
}
if (this.x = = this._x && This.y = = this._y) {
Delete This.onenterframe;
This.gotoandstop ("Stand_" +this.dire);
}
};
The general appearance has already come out. Now let's think about what the other players are going to do? Flash wants to add a new character to the screen when the server has a new player landing here. We can do a function of creating roles, and when a newcomer logs in, one is added. You can also use this function to create yourself when you log in. Other players to move, but also from the server received is who to move to where the information, flash just call the Moverole function can be. Now let's do a function that creates a role. ROLE_MC do not need to put in the scene, in the library to give him a link name role, you can easily invoke the Attachmovie command.
Creating a mouse listener
var mouselistener:object = new Object ();
Mouselistener.onmousedown = function () {
for (var i = 0; i<allroles.length; i++) {
if (Allroles[i].ctrl) {
Moverole (Allroles[i], _xmouse, _ymouse);
Break
}
}
};
Mouse.addlistener (MouseListener);
Creating roles
var allroles:array = new Array ();
Allroles[allroles.length] = Createrole (Math.random (), True, 5, STAGE.WIDTH/2, STAGE.HEIGHT/2);
function Createrole () {
var roleobj:movieclip = This.attachmovie ("Role", "ROLE_MC", this.getnexthighestdepth ());
Roleobj.id = Arguments[0]; Distinguishing the IDs of each role, you can get a value from the database. In this tutorial, we'll just use a random number instead.
Roleobj.ctrl = arguments[1]; Identifies whether the role is a player-controlled role
Roleobj.speed = arguments[2];
roleobj._x = arguments[3];
roleobj._y = arguments[4];
roleobj.x = roleobj._x;
ROLEOBJ.Y = roleobj._y;
return roleobj;
}
Role move
function Moverole (Role:movieclip, X:number, Y:number) {
role.x = x;
Role.y = y;
Role.angle = Math.atan2 (role.y-role._y, role.x-role._x);
Role.dire = 1+math.round ((role.angle+math.pi)/(MATH.PI/4));
Role.dire = role.dire>6? Role.dire-6: role.dire+2;
if (role.dire>5) {
Role.dire = Role.dire = = 6? 4:role.dire = 7? 3:2;
Role._xscale =-100;
} else {
Role._xscale = 100;
}
Role.gotoandplay ("Run_" +role.dire);
Role.onenterframe = function () {
if (this.x!= this._x) {
This._x + = Math.Abs (this.x-this._x) >math.abs (This.speed*math.cos (this.angle))? This.speed*math.cos (This.angle): this.x-this._x;
}
if (this.y!= this._y) {
This._y + = Math.Abs (this.y-this._y) >math.abs (This.speed*math.sin (this.angle))? This.speed*math.sin (This.angle): this.y-this._y;
}
if (this.x = = this._x && This.y = = this._y) {
Delete This.onenterframe;
This.gotoandstop ("Stand_" +this.dire);
}
};
}
TEACH1.FLA: Click here to download the source file
Next is the production of the backend server. I'm using Microsoft Visual Studio. NET 2003. Language is VB. (Pictures and related text can not be put together-_-everybody trouble point, look up and down. )
First, build an empty project named Server (Figure 3). Right-click the project on the project's Solution Explorer, select Add (D)-Add New Item (W), add a class, and name it Server.vb (Figure 4). Write the code for the socket in the Server.vb. I was modified from the example on the website of the Micro software, and there is nothing to say.
Imports System.Net
Imports System.Net.Sockets
Namespace Ibaiy
Public Class Server
Private Lisensocket as Socket
Private Allroles as New Hashtable
Private Rolesposition as New Hashtable
' In this case I'm not going to use the database, so I built a hashtable to exist the data of the line user. If you want to deposit in the database, just add the login to verify the username password, read the database data, and then save into this hashtable. When the user does the operation, then the data processing in the Hashtable and then write to the database. The operation here is not difficult, but more troublesome, so I stole the lazy
' Start the service's main function
Public Sub StartServer (ByVal port as Integer)
Lisensocket = New Socket (addressfamily.internetwork, SocketType.Stream, protocoltype.tcp)
Dim ipen as Iphostentry = Dns.resolve (dns.gethostname)
Dim endpoint = New IPEndPoint (ipen. AddressList (0). Any, port)
Lisensocket.bind (Endpoint)
Lisensocket.listen (1000)
Lisensocket.beginaccept (AddressOf me.listen_callback, Lisensocket)
End Sub
Public Sub Listen_callback (ByVal result as IAsyncResult)
Dim s as Socket = CType (result. AsyncState, Socket)
Dim SO2 as New stateobject
So2.worksocket = s.endaccept (Result)
So2.workSocket.BeginReceive (so2.buffer, 0, so2.buffer.Length, 0, AddressOf Me.read_callback, SO2)
S.beginaccept (AddressOf me.listen_callback, s)
End Sub
Public Sub Read_callback (ByVal result as IAsyncResult)
Dim so as StateObject = CType (result. AsyncState, StateObject)
So.len = so.workSocket.EndReceive (Result)
Opmsg (SO)
So.buffer.Clear (so.buffer, 0, So.buffer.Length)
Try
So.workSocket.BeginReceive (so.buffer, 0, So.buffer.Length, Socketflags.none, AddressOf me.read_callback, so)
Catch
End Try
End Sub
' This function is the processing function that the server receives the client message for a detailed description
Public Sub opmsg (ByVal so as StateObject)
End Sub
End Class
End namespace Add a Stateobject.vb in the server project like adding Server.vb. This is a certain buffer for each joined socket, and simply made a new class. Write the following code:
Imports System.Net.Sockets
Namespace Ibaiy
Public Class StateObject
Public buffer (1024) as Byte
Public Worksocket as Socket
Public Len as Integer
End Class
End Namespace