Use Cocos2d-js to make a game novice boot (ii)

Source: Internet
Author: User
Tags ord

In this article, I have a blog post, "Using Cocos2d-js to make a game novice guide (a)"

First, the realization of the positioner

The purpose of the locator is to locate the nodes in the scene tree accurately, get the object instance, and get the position of the node in the interface, the size of the rectangle and so on.
Locator: In the Cocos2d (JS) game engine used to accurately describe a node in the scene tree string, its implementation of the CSS (cascading style sheet) selector design ideas, the following we will implement a simple from the locator string resolution to the node location of the entire process.

1. Locator Rules

In cocos2d can be a node name, node tag value to represent a node, in JS can also use the object's variable name such as: this[' _button '] to get the node object. There are three effective ways to represent a node object, so here corresponds to three kinds of positioning symbols, as follows:

"/": Name Locator, for example: ' a/b/c ', ' Dialoglayer/_closebutton '
"#": Tag (ID) Locator, for example: ' a#123 '
“.” : variable name (var) locator, for example: ' A._okbutton '

And to simplify the length of the locator string, draw on the sub-selectors in CSS

">": Sub (Child) Locator, for example: ' A>c '

2. Locator resolution

Only names, tags, variable names, and locators are present in the locator string, separated by a locator name, tag, and variable name. The simplest thing in JS is to use the String.Split function to separate it, but here the delimiter (/, #,. , >) How does more than one symbol be implemented? I was writing a traversal function to parse it, but it felt a little ugly. After thinking that split should not support multiple separators, and then search the next, found that I expected splite also support the regular expression of the separation rules, code from n line into 1 lines, very satisfied, more and more like JS.

var"a/b.c#1" > locator.split(/[.,//,>,#]/g‘a‘‘b‘‘c‘‘1‘ ]

In fact, the delimiter is used to decorate the name, tag, variable name, a locator with a name, so design a simple object, as follows:

{symbol: '/', Name: ' A '}

The code is as follows

//使用正则表达示分隔名字var names = str.split(/[.,//,>,#]/g);var segments = names.map(function(name) {    var index = str.indexOf(name);    var1‘>‘;    return {symbol: symbol, name: name.trim()};});

Segments is what we need, and here we are to write convenient or beautiful, between the locator and the name of a space allowed, such as: "A > B # 1"
And usually the first segment of the locator is usually a child node under the main interface, where I use ' > ' as the default locator.

3. Positioning function Implementation Details

With the above locator string parsing output, positioning is actually very easy, because Cocos2d-js has provided getchildbyname, Getwidgetbytag, Seekwidgetbyname, Seekwidgetbytag, For variable locators It is simpler, object[' name '].

/*** Anchor node * @param Locator Locator String * @param CB callback function * @returns null/node return value */Locatenode: function(Locator, CB) {    //Parse locator string    varsegments = This. parselocatorstring (Locator);if(_.isempty (segments)) {return; } cc.log ("Locator:"+ locator);varChild, node = This. _target;//this._target for retrieving the start node     for(vari =0; i < segments.length; i++) {varitem = Segments[i];Switch(Item.symbol) { Case '/': Child = Node.getchildbyname (Item.name); Break; Case '. ': Child = Node[item.name]; Break; Case ' > ': Child = XL. Uihelper.seeknodebyname (node, item.name); Break; Case ' # ': Child = XL. Uihelper.seeknodebytag (node, item.name); Break; }if(child) {node = child}Else{node =NULL; Break; }    }if(node) {CB (node);//Location node succeeded, callback returned result         This. _locatednode = node; }Else{//Location failed, wait 0.1 seconds and retry.          This. Scheduleonce ( function () {             This. Locatenode (Locator, CB); },0.1); }returnnode;}

The above code realizes the process of locating and retrieving in the scene tree, and the admission code is clear and simple. In the last paragraph of the code, when the location fails, the timer is started to retrieve the node again, in order to resolve the workaround that the UI interface has not yet been created when the boot task is switched, resulting in a location design.

Second, the hand-shaped animation and coordinate transformation

When we locate the node object in the scene tree, we can get its position, size, stroke and other information through the node properties, thus calculating the position of the node on the screen.

1. Node location and world location

position: We can get and set the position of the node in its parent node through Node.getposition (), node.setposition (), or use the properties node.x, Node.y. It is important to note that the coordinates of a node simply represent his position at the parent node, and most of the time, the node is contained in layers. We can't simply use the X\y property to get the position of a node in the screen.
World coordinates : in cocos2d all nodes are prompted from: local coordinates to the world coordinates of the mutual conversion, function for Node.converttonodespace, Node.converttoworldspace. It is important to note that we want to get the world coordinates where a node is located, using its parent node to calculate the location of the child nodes in the world.

2. Get the position and rectangle size of the anchor node in the world
 /** * Hand icon points to node nodes * @param node Node object * @param CB finger-click Callback completion function */Pointtonode: function(node, CB) {     This. Settouchnode (NULL);varPT = Node.getparent (). Converttoworldspace (Node.getposition ());//Set finger icon, specify to PT position     This. Setfinger (PT);//calculated by Node anchor point, Rectangle sizePt.x-= Node.width * NODE.ANCHORX; PT.Y-= Node.height * node.anchory; This. _touchrect = Cc.rect (Pt.x, Pt.y, Node.width, node.height);//Turn on mask display     This. Showmask ();//Save callback function to execute after node event is completed     This. _callback = cb;},
3. Hand-shaped cue animation

The hand tip animation is very simple, using the Action action cc. MoveTo can be done, but here setfighter function we sometimes pass in a point parameter, and sometimes it is possible to pass in a point array. When passing in a point array, you want the hand sprite to move in a single position, one at a time in the array.

Third, the positioning area mask display

We get to the node object, the world coordinates position, the rectangle size of this information, creating a rectangular matte is very easy. Mask display mainly use cocos2d in the Clippingnode to achieve, about clippingnode related technology, tutorials, articles have a lot of, here is not detailed description, and so I put the code to provide a fight, display mask switch is easy to use.

Four, non-locating Area touch Event Screen 1. Registering Touch events for the guide layer

About registering touch events for node nodes please refer to my other blog, "Implementing automatic Binding in Cocos2d-js Cocostudioui controls and Events (iii)"

2. Masking touch operations in the boot Layer Touchbegan event

Typically, no other action is allowed during the boot process, all UI behavior needs to be masked, and only the actions specified by the current boot step can be performed. We can already see the operational area by using the previous node positioning, coordinates conversion, rectangular area calculation, and mask display of a series of operations. The area.

Use Cc.node's Ontouchbegan event to mask the underlying event by devouring the touch event when it returns True.

Ontouchbegan: function(Touch) {    //Touch rectangular area not present, direct ingestion event    if(! This. _touchrect) {return true; }//Get touch position    varPT = Touch.getlocation ();//Check whether the touch position is within the range of the operable rectangular area    varret = Cc.rectcontainspoint ( This. _touchrect, PT);if(Ret &&!) This. _touchnode) {//Hide hand shape         This. _finger.setvisible (false);//Execute callback function         This. _callback (); }//In the operable area, do not block the lower level event    return!ret;},
V. Detection of UI events in the location area

When the guide layer is placed into the lower-level game interface with touch events, the control events in the underlying UI are normally triggered for real-world gameplay steps. At this point, we can simply assume that the current boot task is complete.
But in real projects there are a lot of problems, and sometimes users do not play according to our imagination, in the guidance of the operating area is not a click, but sliding operation will be very tragic! Because the upper level of the boot has detected that the operation has already touched, the current task is pass off, but the underlying UI event is not executed, such as creating a new interface, which will cause the boot to go.

How to solve this problem? How do I check that the underlying UI has actually triggered the event?
At present, I do not have a particularly good approach in my project, mainly using SZ. Uiloader to manage events and execute game logic when the controls are ontouchended, create interfaces, interface transitions, and more. In Sz. A hook function is reserved in the Uiloader library to intercept the control's events.

function(sender, type) {    if (type === ccui.Widget.TOUCH_ENDED) {        //使用观察者模式,发送按钮点击事件        xl.postMessage(xl.Message.BUTTON_CLICKED, sender);    }};

The Xl.postmessage encapsulates Cc.notificationcenter, which broadcasts messages to Xl.Message.BUTTON_CLICKED event observers, with parameters of the current control object.

Facilitates viewer pattern checking UI events are executed

Registers the guide Layer object as XL. The observer for the Message.button_clicked event, one but the ccui of the control. The widget.touch_ended event is triggered and the boot layer can know that the registration code is as follows:

Xl.addobserver (XL. Message.button_clicked, this, this.touchnodeclicked);

Touchnodeclicked as the Guide Layer Observer response function

touchnodeclicked: < Span class= "Hljs-keyword" >function   { if  (this . _touchnode && (Sender = = = this . _touchnode | | Sender.getname () = = = this . _touchnode.getname ())) {this . Settouchnode (null );            this . _touchrect = null ;            this . _finger.setvisible (false );            //at this time to perform a task callback function to start the next task         this . _callback (); }    },

All the details about UI positioning, prompting animations, event masking, and checking are all done.

(not finished)

Use Cocos2d-js to make a game novice boot (ii)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.