I just graduated a few years ago. The first game module was chatting. Up to now, several games have written chat modules several times,
In the previous "Magic Dragon Knight" (also known as "God Knight") in 4399 and the "crazy bullet" launched last Saturday,
The same set of code is used. The Chat input box is replaced by symbols instead of text-to-text mixing.
The text-and-text mixing of the output panel is easy to implement because there is no mouse or mouse operation on the content, which is not discussed in this article. Of course, this article
A small part of the code can be implemented. The above two games are not encrypted. If you are interested, you can check them out,
How tired are the mouse keys, skills, shooting, and trajectory in bullets? (? ε ?? )
In particular, ballistic computing is the most complex mathematical and physical knowledge that I have used since I graduated from high school. Straight line trajectory, straight
Line Penetration Trajectory, laser trajectory, bullet trajectory, bullet penetration trajectory, energy trajectory, rectangular trajectory, fan-shaped trajectory, Circular
Trajectory, sector trajectory, virtual trajectory, parallel trajectory, and a combination of several of them. Using various geometric Equations,
There are also the translation and rotation of the plane geometric coordinate system, as well as angle, radians, vector calculation, and so on.
It is only the foundation. If you use it directly, the efficiency is very low. You can make some simplified calculations in the game to improve efficiency ......
It seems that I have run my questions. What do I want to write? Oh, it's a mix of text and text in the input box.
Now, I am playing another game called "Three Kingdoms of magic" in YY. It is expected to be launched in September. Happened to take over the chat module again,
It took two days to find out the text and text in the input box.
Supplement: For details about the text-and-text mixing of the multi-line input boxes on the private chat panel in the game (similar to the QQ chat Panel), refer to the following:
As3 chat multi-line input box text and text mixing perfect implementation
Package {import flash. display. movieclip; import flash. display. shape; import flash. display. sprite; import flash. events. event; import flash. events. keyboardevent; import flash. filters. glowfilter; import flash. geom. rectangle; import flash. text. textfield; import flash. text. textfieldtype; import flash. text. textformat; import flash. text. textformatalign; import flash. UI. keyboard; import flash. utils. getdefinitionbyname; /*** Perfect implementation of text-and-text mixing in the game chat input box * no third-party class is used. You can see that * more than one hundred lines of comments have been added to the import box. The actual code is about three hundred lines * main test point: * 1. select a part of text, and then press delete, or insert an expression, or Ctrl + X, or Ctrl + V, etc. * 2. when the text box is full, press and hold the left and right keys or drag the mouse to select the left and right to move the text box to trigger horizontal scrolling * use the above two points for testing. problems may occur in many third-party controls or browser games. * In addition, this implementation will not perform general class libraries like richtextfield. * The more common the implementation is, the lower the efficiency is. We recommend that you adjust the Code accordingly. Good luck! * @ Since 2014.6.26 * @ email [email protected] */public class inputtext extends sprite {/* placeholder for emoticons. It looks like a space, but it is not a space. The input box generally cannot block space input, however, the input of this symbol can be shielded, so it is appropriate to use it as a placeholder */private const placeholder: String = string. fromcharcode (12288); Public var textfield: textfield; // text input box private var mclayer: SPRITE; // the container used to hold the emoticon. On the text box, set Private var datalist: vector. <express>; // voprivate var begin: Int = 0; // The start index of the selected text in the input box. Private VaR End: Int = 0; // The end index of the selected text in the input box. If no text is selected, begin = end, and equal to caretindex private var scrollh: Int = 0; // The Private var keycode: uint = 0 when the text box is full and then scroll to the left; // The Last keyboard code private var defaultformat: textformat; // The default text format is private var placeformat: textformat; // The format of the placeholder emoticons/*** mix text in the game chat input box * @ Param W input box width * @ Param H input box height */Public Function inputtext (W: Number = 170, h: Number = 20) {defaultformat = new textformat (); defaultformat. colo R = 0 xffffff; defaultformat. size = 12; defaultformat. letterspacing = 0; // defaultformat cannot be omitted here. align = textformatalign. left; defaultformat. font = "simsun"; // /// adjust the placeholder width to a point larger than the emoticon width. // do not adjust the width with the placeholder size, unless your expression is about the same size as the font, how painful it is to comprehend placeformat = new textformat (); placeformat. letterspacing = 16; textfield = new textfield (); textfield. width = W; textfield. height = H; textfield. type = textfieldtype. input; textfield. d Efaulttextformat = defaultformat;/* set it to a single-line text box. We do not recommend that you use multi-line text boxes as in Xianxia road. This will make things more complex. I believe my Xianxia road is not encrypted, let's take a look at the code. When multiple lines are used, we need to handle the disgusting problem of the up/down key rollback. Generally, the game uses the up/down key to process the chat cache function, that is, the up and down keys are used to review the previous chat content to avoid repeated input of */textfield. multiline = false; textfield. wordwrap = false; textfield. mousewheelenabled = false; textfield. restrict = "^" + placeholder; // shield placeholders so that players cannot enter textfield. filters = [New glowfilter (0x0, 1, 3, 3)]; textfield. maxchars = 100; text Field. addeventlistener (event. scroll, ontextscroll); textfield. addeventlistener (event. change, afterchange); textfield. addeventlistener (keyboardevent. key_down, onkeydown); this. addchild (textfield); // It is necessary to mask. After a full row is rolled to the left, the expression may show only half var mask: Shape = new shape (); mask. graphics. beginfill (0); mask. graphics. drawrect (0, 0, W, H); mask. graphics. endfill (); this. addchild (mask); mclayer = new sprite (); mclayer. mask = mask; this. Addchild (mclayer); datalist = new vector. <express> () ;}/ *** text box scroll event, mainly for horizontal scrolling */private function ontextscroll (E: Event): void {// only for horizontal scrolling, differentiation processing is necessary. Without this judgment, recursive Stack Overflow may occur if (textfield. scrollh! = Scrollh) {scrollh = textfield. scrollh; render () ;}}/*** Keyboard Events. Do not handle backspace, delete, and other events here. Believe me */private function onkeydown (E: keyboardevent ): void {begin = textfield. selectionbeginindex; end = textfield. selectionendindex; keycode = E. keycode; // send chat data if (keycode = keyboard. enter) {If (textfield. length> 0) {var chatcontent: String = This. srccontent; // todo: Here is the logic for sending data to the server}/*** text content change event. Here is the essence. After understanding it, you will find that it is actually very simple * /Private function afterchange (E: event = NULL): void {var $ begin: Int = begin; If (begin = END) {If (keycode = keyboard. backspace) {delexpress (begin-1); $ begin = (begin> 0 )? Begin-1: 0;} else if (keycode = keyboard. delete) {delexpress (BEGIN) ;}} else // select a part of the text and delete the emoticon {for (var I: Int = begin; I <end; I ++) {delexpress (I) ;}// after deleting the emoticon, update the emoticon index updateexpressindex ($ begin); render (); keycode = 0 ;} /*** text-and-image-based rendering. length = 0) {clear (); return;}/* sets the width of the placeholder expression. As described above, do not repeat */textfield. settextformat (defaultformat, 0, textfiel D. length); var textstr: String = textfield. text; For (var I: Int = 0; I <textstr. length; I ++) {var CHAR: String = textstr. charat (I); If (char = placeholder) {textfield. settextformat (placeformat, I, I + 1) ;}}/* clear all emotices first. There is room for optimization, but it is recommended that you do not make any effort unless you study it purely */while (mclayer. numchildren> 0) {mclayer. removechildat (0);}/* when the text is full, press the Left or Right key or drag the mouse to move the left and right to trigger horizontal scrolling */var showbegin: int =-1; // the first character index in the input box var showend: Int =-1; // The last character index const sright: Int = textfield. scrollh + textfield. width; // The X coordinate of the first character displayed in the entire text line in the input box/* traverse the coordinates of each character to find the showbegin and showend values */for (I = 0; I <textfield. length; I ++) {// It is worth mentioning that no matter how the text is rolled horizontally, the coordinates of all characters are positive. Do you know why? VaR rect: rectangle = textfield. getcharboundaries (I); If (showbegin =-1 & rect. right> textfield. scrollh) {showbegin = I;} If (showend =-1 & rect. left> sright) {showend = I-1; break ;}// when the row is not full, all characters are displayed if (showend =-1) {showend = textfield. length-1;}/* adds the actual emoticons in the text box */For each (VAR data: express in datalist) {If (data. index> = showbegin & data. index <= showend) {rect = textfield. getcharboundarie S (data. index); // fine-tune the coordinates based on the emoticon and text size to center the data in the text. MC. X = rect. X + 2-textfield. scrollh; data. MC. y = rect. y-6; mclayer. addchild (data. MC) ;}}/ *** insert an emoticon * @ Param sign at the current cursor of the text box. Based on this symbol, you can create an emoticon Display object */Public Function insertexpression (sign: string): void {If (textfield. length> = textfield. maxchars) {return;} // you need to re-obtain the start and end indexes of the selected text here. The weird problem after the text box loses focus is begin = textfield. selectionbeginindex; end = textfield. selectionendinde X; // Delete the emoticon that may be contained in the selected text (var I: Int = begin; I <end; I ++) {delexpress (I );} // Replace the selected text with an emoticon placeholder. If not selected, a textfield is inserted. replacetext (begin, end, placeholder); // create and save emoticon data, and keep the order var $ I: Int =-1; for (I = 0; I <datalist. length; I ++) {var data: Express = datalist [I]; If (data. index >=begin) {$ I = I; break;} var MC: movieclip = getmovieclip (sign); if ($ I =-1) {datalist. push (New Express (begin, sign, MC);} else {datalist. splice ($ I, 0, New Express (begin, sign, MC);} // after inserting an expression, update the expression index updateexpressindex (BEGIN); render (); textfield. setselection (begin + 1, begin + 1);}/*** update emoticon data index, the index is a placeholder Index * @ Param $ begin only updates the data after the $ begin character. The previous data remains unchanged */private function updateexpressindex ($ begin: INT ): void {var $ I: Int =-1; for (var I: Int = 0; I <datalist. length; I ++) {If (datalist [I]. index >=$ begin) {$ I = I; break ;}} if ($ I! =-1) {var textstr: String = textfield. text; for (I = $ begin; I <textstr. length; I ++) {If (textstr. charat (I) = placeholder) {datalist [$ I ++]. index = I ;}}}/*** retrieve emoticon data at the specified Index * @ Param index emoticon index, that is, the placeholder Index * @ return emoticons */private function getexpress (Index: INT): Express {for each (VAR data: express in datalist) {If (data. index = index) {return data ;}} return NULL ;}/ *** Delete the emoticon data at the specified index, and remove the emoticon Display object * @ Param index emoticon Index */PR Ivate function delexpress (Index: INT): void {for (var I: Int = 0; I <datalist. length; I ++) {var data: Express = datalist [I]; If (data. index = index) {datalist. splice (I, 1); If (mclayer. contains (data. MC) {mclayer. removechild (data. MC);} return ;}}}/*** use the inserted emoticon to create an emoticon animation * @ Param sign * @ return emoticon animation */private function getmovieclip (sign: string): movieclip {/* here, the symbol can be processed based on the actual game. For example, the symbol is/: 01 and the symbol is reconstructed as chat_expression_01. As long as the constructed string is the emoticon class you export in FLA */var $ _ class: class = getdefinitionbyname (sign) as class; var $ _ item: movieclip = new $ _ class (); $ _ item. mousechildren = false; $ _ item. mouseenabled = false; return $ _ item;}/*** gets the raw data in a text-and-image mix, which is sent to the server and broadcast back */Public Function get srccontent (): string {var chararr: array = []; var textstr: String = textfield. text; For (var I: Int = 0; I <textstr. length; I ++) {var CHAR: String = textstr. chara T (I); If (char = placeholder) {var data: Express = getexpress (I); chararr. push (data. sign);} else {chararr. push (char) ;}} return chararr. join ("");}/*** sets the text-to-text hybrid arrangement of original data. It is mainly used to analyze the expression when the Chat History record is viewed by up/down keys. * The text-to-text hybrid arrangement of the output panel is used because there is no mouse-to-mouse operation, it is simpler. It is not discussed in this article. * However, I believe you will know how to do it here. */public function set srccontent (content: string): void {clear (); // The chat_expression_xx here is the expression export class in my game. You can adjust var Reg freely according to your game: regexp = new Regexp ("chat_expression _ [0-9] {2}", "ig "); Var signarr: array = content. match (REG); content = content. replace (Reg, placeholder); If (content. length> textfield. maxchars) {content = content. substr (0, textfield. maxchars) ;}for (var I: Int = 0; I <content. length; I ++) {var CHAR: String = content. charat (I); If (char = placeholder) {var sign: String = signarr. shift () as string; var MC: movieclip = getmovieclip (sign); datalist. push (New Express (I, sign, MC )) ;} Textfield. TEXT = content; render () ;}/ *** clear the text box as the relevant data */Public Function clear (): void1_textfield.html text = ""; begin = END = scrollh = keycode = 0; datalist = new vector. <express> (); If (mclayer! = NULL) {While (mclayer. numchildren> 0) {mclayer. removechildat (0 );}}}}} /* ===================================================== =========== */import flash. display. movieclip; Class express // internal class. You do not need to create a class file {public var index: int; Public var sign: string; Public var MC: movieclip; /*** emoticon data ** @ Param index emoticon index, that is, the index of the emoticon placeholder in the text * @ Param sign emoticon, used to create an emoticon animation display object * @ Param Mc emoticon animation, the Display object created with sign */Public Function Express (Index: int, sign: String, MC: movieclip) {This. index = index; this. sign = sign; this. MC = mc ;}}