How can I set body in action - cocos2d-x

I want to set body after move delay, I am searching something like runBlock in sprite-kit.
void MySprite::SpawnSprite( cocos2d::Layer *layer )
{
auto mySprite = Sprite::create();
auto body = PhysicsBody::create();
mySprite->setTexture("MySprite.png");
body->createCircle(arrow->getContentSize().width / 2);
body->setDynamic(false);
mySprite->setPosition( startPoint );
layer->addChild(mySprite);
auto moveTest = MoveTo::create(2, Point(200, 200) );
auto waitAction = DelayTime::create(2);
auto action = Sequence::create(moveTest, waitAction, NULL);//I want to set body after waitAction in sequence(mySprite->setPhysicsBody(body))
mySprite->runAction(action);
}
This is so simple in sprite-kit
runAction(
SKAction.sequence([
action,
SKAction.waitForDuration(2.0),
SKAction.runBlock({ //Set Body }))
])
)

What you need is to create CallFuncN and use it in your sequence like this
Fist a function you need:
void attachBody(Ref* pSender)
{
Sprite* mySprite = (Sprite*)pSender;
mySprite->setPhysiceBody(body);
//you can do whatever you want to do with your sprite here.
}
Now you sequence would be something like this
auto action = Sequence::create(moveTest, waitAction,CallFuncN::create(CC_CALLBACK_1(attachBody,this)), NULL);

void MySprite::SetBody(Sprite *sprite)
{
auto body = PhysicsBody::create();
body->createCircle(arrow->getContentSize().width / 2);
body->setDynamic(false);
sprite->setPhysicsBody(body);
}
void MySprite::SpawnSprite( cocos2d::Layer *layer )
{
auto mySprite = Sprite::create();
mySprite->setTexture("MySprite.png");
mySprite->setPosition( startPoint );
layer->addChild(mySprite);
auto moveTest = MoveTo::create(2, Point(200, 200) );
auto waitAction = DelayTime::create(2);
auto funcCallAction = CallFunc::create([=](){
MySprite::SetBody(mySprite);
});
auto action = Sequence::create(moveTest, waitAction, funcCallAction, NULL);
mySprite->runAction(action);
}

Related

How can I assign dynamic data from service via subscribe to doughnut chart in angular?

how can I dynamically assign data to doughnutchartdata. how can I link data coming from service file via subscribe method on ngOnIt to doughnutchartdata. so that I can link multisetdata to one coming dynamically without hardcoding it
Can I also show that data in center dynamically by linking to ctx.fillText
my .ts file
public doughnutChartLabels: Label[] = ['Download Sales', 'In-Store Sales', 'Mail-Order Sales'];
public doughnutChartData: MultiDataSet = [
];
radius = length * Math.SQRT2 / 2;
colors= [
{
backgroundColor: [
'#E6B01C',
'#1454A3',
'#22C3BD',
'yellow'
]
}
];
public doughnutChartType: ChartType = 'doughnut';
public doughnutChartPlugins: PluginServiceGlobalRegistrationAndOptions[] = [{
beforeDraw(chart) {
const ctx = chart.ctx;
const txt = '26';
//Get options from the center object in options
const sidePadding = 60;
const sidePaddingCalculated = (sidePadding / 100) * (this.radius * 2)
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
const centerX = ((chart.chartArea.left + chart.chartArea.right) / 2);
const centerY = ((chart.chartArea.top + chart.chartArea.bottom) / 2);
//Get the width of the string and also the width of the element minus 10 to give it 5px side padding
const stringWidth = ctx.measureText(txt).width;
const elementWidth = (this.radius * 2) - sidePaddingCalculated;
// Find out how much the font can grow in width.
const widthRatio = elementWidth / stringWidth;
const newFontSize = Math.floor(30 * widthRatio);
const elementHeight = (this.radius * 2);
// Pick a new font size so it will not be larger than the height of label.
// const fontSizeToUse = Math.min(newFontSize, elementHeight);
// ctx.font = fontSizeToUse + 'px Arial';
ctx.fillStyle = 'blue';
// Draw text in center
ctx.fillText('26', centerX, centerY);
}
}];
constructor(private roleService:RoleDashboardService) { }
ngOnInit() {
this.roleService.getWidget).subscribe((data)=>{
console.log(data)
this.doughnutChartData
console.log(this.doughnutChartData)
})
}
// events
public chartClicked({ event, active }: { event: MouseEvent, active: {}[] }): void {
console.log(event, active);
}
public chartHovered({ event, active }: { event: MouseEvent, active: {}[] }): void {
console.log(event, active);
}
Depends on what backend you use. For example, if u obtain data through php from mysql you would use the below:
array1=[];
array2=[];
//api call on backend
this.http.get('http://localhost/angular9/chartData.php').subscribe(data => {
//create array and push the data
this.array1.push(data);
//assign this array to another arraya and map it
this.array2 = this.array1[0].map(function(item, keys) {
var mixarrayy = Object.keys(item).concat(Object.values(item));
return mixarrayy;
});

Cocos2d-x run action - clicked button

enter image description here
When I click on the button it will perform the action
help me. it did not work
SpriteFrameCache::getInstance()->addSpriteFramesWithFile("run.plist", "run.png");
const int numberSprite = 6;
auto gameSprite = Sprite::createWithSpriteFrameName("run1.png");
gameSprite->setPosition(100,200);
gameSprite->setScale(2);
this->addChild(gameSprite);
Vector<SpriteFrame*> animFrames;
animFrames.reserve(numberSprite);
animFrames.pushBack(SpriteFrameCache::getInstance()->getSpriteFrameByName("run1.png"));
animFrames.pushBack(SpriteFrameCache::getInstance()->getSpriteFrameByName("run2.png"));
animFrames.pushBack(SpriteFrameCache::getInstance()->getSpriteFrameByName("run3.png"));
animFrames.pushBack(SpriteFrameCache::getInstance()->getSpriteFrameByName("run4.png"));
animFrames.pushBack(SpriteFrameCache::getInstance()->getSpriteFrameByName("run5.png"));
animFrames.pushBack(SpriteFrameCache::getInstance()->getSpriteFrameByName("run6.png"));
Animation* animation = Animation::createWithSpriteFrames(animFrames, 0.1f);
Animate* animate = Animate::create(animation);
gameSprite->runAction(RepeatForever::create(animate));
auto button = Button::create("play.png");
button->setTitleText("");
button->setScale(0.5);
button->setPosition(visibleSize / 2);
button->addTouchEventListener([&gameSprite](Ref* sender, Widget::TouchEventType type) {
switch (type)
{
case ui::Widget::TouchEventType::BEGAN:
auto moveBy3 = MoveBy::create(30, Vec2(2000, 0));
gameSprite->runAction(moveBy3);
case ui::Widget::TouchEventType::ENDED:
break;
default:
break;
}
});
this->addChild(button, 10);

as3 video buffer overflow(explosion)

ResolveVideoURL("rtmp://url");
function asyncErrorHandler(event:AsyncErrorEvent):void
{
trace(event.text);
}
function doPlay1()
{
//if( vns1 !=null )vns1.close(); vns1 = null ;
vns1 = new NetStream(vnc1);
vns1.addEventListener(AsyncErrorEvent.ASYNC_ERROR, asyncErrorHandler);
mv1.attachNetStream(vns1);
//mv1.smoothing = true;
vns1.bufferTime = 1 ;
vns1.play(CVL2);
}
function ResolveVideoURL( Url: String )
{
var tmpLOC : int = Url.lastIndexOf("/");
CVL1 = Url.slice( 0 , tmpLOC );
CVL2 = Url.slice( tmpLOC + 1 );
vnc1.connect(CVL1);
}
has anybody ever get video return bufferLength overflow? like below image
it should be very close to 1 , but get a large amount of it
it's encoding use vp6 , 800Kb(flow)
http://i.stack.imgur.com/CO2Ww.png

Multiple-page printing from datagrid

From this tutorial i've got a good result printing , and this tutorial on how to print multiple pages from html, i'm trying to do the same with a Datagrid.
my problem is when the number of rows exceed the height of Datagrid so i tried to break it down to several pages, this is my code:
protected function button3_clickHandler(event:MouseEvent):void
{
var success:Boolean = printJob.start2(disablePageRange.selected ? this.printUIOptions : null, false);
var pjo:PrintJobOptions = new PrintJobOptions;
if (methodBitmap.selected){
pjo.printMethod = PrintMethod.BITMAP;
}
else if (methodVector.selected){
pjo.printMethod = PrintMethod.VECTOR;
}
else{
pjo.printMethod = PrintMethod.AUTO;
}
if (printJob.maxPixelsPerInch > 600){
pjo.pixelsPerInch = 600;
}
updateForm();
updateThePage();
updateTheWindow();
//--------------------------------------
var b:int = 0;
var H:int = myDataGrid.rowHeight *2;
for each (var item:Object in meme as ArrayCollection ){
if (H > myDataGrid.height){
myDataGrid.dataProvider = arlst;
printJob.addPage(thePrintableArea, null, pjo);
arlst.removeAll();
H = myDataGrid.rowHeight *2;
b++;
//Alert.show(b.toString());
}else{
arlst.addItem(item);
H += myDataGrid.rowHeight;
}
}
printJob.send();
}
The result: i get the first page but the rest are just blank Datagrid:
This answers: http://help.adobe.com/en_US/flex/using/WS2db454920e96a9e51e63e3d11c0bf69084-7c7e.html
Summary:
create external Itemrenderer and populate the data to it.

Youtube Api JSON arranges results incorrectly

I'm using the Video Picker app (by LockeVN: https://github.com/lockevn/YouTube-video-picker), and the results i'm getting are not ordered like they are on the youtube website (or any other search app on github).
FOR EXAMPLE:
I type in : 'Bizarre Inc feat Angie Brown I'm Gonna Get You'.
The first video I get in youtube is: 'Bizarre Inc feat Angie Brown - I'm Gonna Get You (1992)'.
The first video I get in Video Picker app is:'BIZARRE INC - I'M GONNA GET YOU (SAVERY & MILLER MASHUP MIX)'
NOTE: Both are set to orderby=relevance and the video ordering changes when I change max-results; only when max-result is set to 1, the result is correctly ordered.
Anyone know how this can be fixed?
CODE:
(function ($) {
$.fn.YouTubePicker = function (options) {
// default option
var defaults = {
MaxResults: 10 /* number of YouTube results, per "page" */
, OrderBy: 'relevance' /* what to order the results by */
, Author: null /* Author of the video */
, PlayerNumberOp: 1
, ShowNumOfViews: true /* show number of views for the video */
, Thumbnail: 'small' /* small: 120x90 | large: 480 x 360 */
, ControlIdSuffix: '' /* should give the unique string here if you have multiply of YouTubePicker.
Using elements in this plugin will fetch by "id + ControlIdSuffix" */
, ControlQueryHolder: '.YouTubePickerQuery' /* selector to take a element to be query holder (where we take string to query YouTube) */
, ControlSearchButton: '.YouTubePickerSearch' /* selector to take a element to be SearchButton. Click this element to start search. */
, ControlVideoPlayerHolder: '.YouTubePickerVideoPlayer' /* selector to take a element to render VideoPlayer */
, ControlVideoTitleHolder: '.YouTubePickerVideoTitle'
, ControlVideoList: '.YouTubePickerVideoList' /* selector to take a element to render VideoList */
, ControlSelectedUrlHolder: '.YouTubePickerSelectedUrl' /* When user click to select a video, assign the video's url to this input */
, InitVideoUrl: '' /* Init if no search query existed, you can put YouTubeVideoId here or the full Url */
, PlayerWidth: '240' /* setting for player */
, PlayerHeight: '220' /* setting for player */
, AutoPlay: false /* AutoPlay video right after user click an item in the list */
, ShowRelated: false /* show relate video after finish playing */
, AllowFullScreen: true /* enable FullScreen button of Player */
, EnableJsApi: true /* enable Javascript Api*/
};
options = $.extend(defaults, options);
return this.each(function () {
var $container = $(this);
$(options.ControlSearchButton).click(function () {
/// <summary>
/// handler click on search button
/// </summary>
var requestUrl = 'http://gdata.YouTube.com/feeds/api/videos?alt=json&max-results=' + options.MaxResults;
try {
_RequestYouTubeVideos(requestUrl);
} catch (ex) { }
return false;
});
$(options.ControlQueryHolder).keydown(function (event) {
/// <summary>
/// handler press Enter in query textbox
/// </summary>
if ((event.which && event.which == 13) || (event.keyCode && event.keyCode == 13)) {
$(options.ControlSearchButton).trigger('click');
return false;
}
else {
return true;
}
});
//-------------------------------------------------------//
// take the init video and play it if any
// ERASED THIS PART
// $(options.ControlVideoPlayerHolder + "").html(_GetPlayerHtml(_GetYouTubeIdFromUrl(options.InitVideoUrl)));
// _AssignValueToDivOrTextBox(options.ControlSelectedUrlHolder, options.InitVideoUrl);
$('a.navigation').click(function () {
/// <summary>
/// rebind the list whenever user click to change page
/// </summary>
try {
_RequestYouTubeVideos($(this).attr('href'));
} catch (ex) { }
return false;
});
/**
* Util function, assign value to element. Element can be div, span, or input
*/
function _AssignValueToDivOrTextBox(selectorToElement, valueToAssign) {
try {
$(selectorToElement).val(valueToAssign);
} catch (ex) { }
try {
$(selectorToElement).text(valueToAssign);
} catch (ex) { }
}
function _RequestYouTubeVideos(requestUrl) {
/// <summary>
/// fire the jsonp request to get data from YouTube Search API
/// </summary>
var query = $(options.ControlQueryHolder).val();
if (options.Author != null) {
requestUrl += '&author=' + options.Author;
}
if (options.OrderBy != null) {
requestUrl += '&orderby=' + options.OrderBy;
}
if (query != null) {
requestUrl += '&q=' + query;
}
$.ajax({
type: "GET",
url: requestUrl,
cache: false,
dataType: 'jsonp',
global: false,
success: _OnYouTubeSuccess,
error: function (result) {
$(options.ControlVideoList).html('<p>Please fill in a search term</p>');
}
,
ajaxComplete: function (data) {
return false;
}
});
}
function _BuildNavigation(feed) {
/// <summary>
/// Build the navigation link Prev and Next base on the return url in the feed (if existed)
/// </summary>
if (feed.link) {
var nextLink = null;
var prevLink = null;
for (var i = 0; i < feed.link.length; i++) {
var link = feed.link[i];
if (link.rel == 'next') {
nextLink = link.href;
}
else if (link.rel == 'previous') {
prevLink = link.href;
}
}
if (nextLink) {
$('.navigation.next').attr('href', nextLink).show();
}
else {
$('.navigation.next').hide();
}
if (prevLink) {
$('.navigation.prev').attr('href', prevLink).show();
}
else {
$('.navigation.prev').hide();
}
}
}
function formatSecondsAsTime(secs) {
var hr = Math.floor(secs / 3600);
var min = Math.floor((secs - (hr * 3600)) / 60);
var sec = Math.floor(secs - (hr * 3600) - (min * 60));
if (hr < 10) {
hr = "0" + hr;
}
if (min < 10) {
min = "0" + min;
}
if (sec < 10) {
sec = "0" + sec;
}
if (hr) {
hr = "00";
}
return hr + ':' + min + ':' + sec;
}
function _ParseYouTubeFeedItem(feedData) {
/// <summary>
/// Extract what we want from YouTube feedData
/// </summary>
var dto = [];
dto.id = _StripFeature(feedData.link[0].href.substring(feedData.link[0].href.indexOf('=') + 1, feedData.link[0].href.length));
dto.url = feedData.link[0].href;
dto.title = feedData.title.$t;
if (options.Thumbnail == 'large') {
var index = 0; // first thumb is large size
} else {
var index = feedData.media$group.media$thumbnail.length - 1; // take the last small thumb
}
dto.thumbnail = feedData.media$group.media$thumbnail[index].url;
dto.description = feedData.media$group.media$description.$t;
dto.author = feedData.author[0].name.$t;
dto.duration = formatSecondsAsTime(feedData.media$group.media$content[0].duration);
if (feedData.yt$statistics) {
dto.views = feedData.yt$statistics.viewCount;
}
else if (!feedData.yt$statistics) {
dto.views = '0';
}
return dto;
}
/**
* Process the json result, render the list
*/
function _OnYouTubeSuccess(result) {
var feed = result.feed;
var rfeed = feed.entry || [];
var relVideos = [];
var $ctrVideoList = $(options.ControlVideoList);
// build the navigation
_BuildNavigation(feed);
if (rfeed.length > 0) {
$(rfeed).each(function (i) {
/// <summary>
/// from feeditem from YouTube, build the video data object
/// </summary>
relVideos[i] = _ParseYouTubeFeedItem(rfeed[i]);
}).ready(function () {
relVideos.sort(_ArraySort);
var $itemsHtml = $('<div>'); // temporary DOM node to append VideoItem to
$(relVideos).each(function (i) {
/// <summary>
/// Create each list item
/// </summary>
$itemsHtml.append('<li class="VideoItem">');
videoItem = $itemsHtml.find('.VideoItem:last');
videoItem.append('<div class="VideoThumb">');
videoThumb = videoItem.find('.VideoThumb');
$('<a>').addClass('YouTubelink').attr('href', relVideos[i].url).append('<img src="' + relVideos[i].thumbnail + '">').appendTo(videoThumb);
videoItem.append('<div class="VideoInfo">');
videoInfo = videoItem.find('.VideoInfo');
videoInfo.append('<strong>' + relVideos[i].title + ' </strong><br /><span class="VideoNumOfViews">' + relVideos[i].views + ' views</span><br /><span></span>' + relVideos[i].duration + '<br />');
});
// clear the list
$ctrVideoList.empty().append($itemsHtml.children());
});
// load inital video after finish rendering the list
// take the first video in the list, take it link, take it href, assign to the Player
// ERASED THIS PART
//var firstVid = $ctrVideoList.children("li:first-child").addClass("selected").find("a").eq(1).attr("href");
//$(options.ControlVideoPlayerHolder + "").html(_GetPlayerHtml(_GetYouTubeIdFromUrl(firstVid)));
$ctrVideoList.find("li a").unbind('click').bind('click', function () {
/// <summary>
/// load video on click of a in li
/// </summary>
try {
var selectedUrl = $(this).attr("href");
// return the selectedUrl to outside (try catch to avoid error in IE)
_AssignValueToDivOrTextBox(options.ControlSelectedUrlHolder, selectedUrl);
$(options.ControlVideoPlayerHolder + "").html(_GetPlayerHtml(_GetYouTubeIdFromUrl(selectedUrl)));
// DIT IS EEN TEST
$(options.ControlVideoTitleHolder + "").html(_GetTitleHtml(_GetYouTubeIdFromUrl(selectedUrl)));
$(this).parent().parent().parent("ul").find("li.selected").removeClass("selected");
$(this).parent().parent("li").addClass("selected");
} catch (ex) { }
return false;
});
} else {
/* if we have no YouTube videos returned, let's tell user */
$ctrVideoList.html('<p>There is no result</p>');
}
} // end _OnYouTubeSuccess
function _ArraySort(a, b) {
if (a.title < b.title) {
return -1;
}
else if (a.title > b.title) {
return 1;
}
else {
return 0;
}
}
function _StripFeature(vidID) {
var featureLoc = vidID.indexOf('&feature=YouTube_gdata');
if (featureLoc >= 0) {
return vidID.substring(0, featureLoc);
} else {
return vidID;
}
}
/**
* Create a Player HTML code to play an YouTubeID, and return it HTML string
*/
function _GetPlayerHtml(YouTubeVideoId) {
// if YouTubeVideoId is null or empty, we provide an empty div with same dimension of the Player
// This will fix a bug of IE (IE will load the swf forever if object movie is empty and/or embbed src is empty
if (!YouTubeVideoId) {
return '<div style="width:240px;height:220px">';
}
var html = '';
var PlayerNumber = options.PlayerNumberOp;
html += '<object height="220" width="240">';
html += '<param name="movie" value="http://www.YouTube.com/v/'+YouTubeVideoId+'?enablejsapi=1&rel=0&showinfo=2&iv_load_policy=3&modestbranding=1"> </param>';
html += '<param name="wmode" value="transparent"> </param>';
// I HAVE CHANGED THIS
html += '<iframe onload="floaded'+PlayerNumber+'()" id="player'+PlayerNumber+'" width="240" height="220" src="http://www.youtube.com/embed/'+YouTubeVideoId+'?enablejsapi=1&rel=0&showinfo=2&iv_load_policy=3&modestbranding=1" frameborder="0" allowfullscreen> </iframe>';
html += '</object>';
return html;
};
function _GetTitleHtml(YouTubeVideoId) {
var html = '';
var PlayerNumber = options.PlayerNumberOp;
$.getJSON('http://gdata.youtube.com/feeds/api/videos/'+YouTubeVideoId+'?v=2&alt=jsonc',function(data,status,xhr){
var video_title1=data.data.title;
var finaltext1="<div id='title1'><h5 class='redtext'>USER SELECTED</h5><h5>"+video_title1+"</h5></div>";
$('#YouTubePickerVideoTitle'+PlayerNumber+'').html(finaltext1);
});
return html;
};
function _GetYouTubeIdFromUrl(url) {
/// <summary>
/// use RegEx too grab a YouTube id from a (clean, no querystring) url (thanks to http://jquery-howto.blogspot.com/2009/05/jYouTube-jquery-YouTube-thumbnail.html)
/// <return>empty string if cannot match.</return>
/// </summary>
if (url && url != '') {
try {
var ytid = url.match("[\\?&]v=([^&#]*)");
ytid = ytid[1];
return ytid;
}
catch (ex) { }
}
return '';
};
});
};
})(jQuery);
Deniz.
I'm not sure but guess Youtube uses your preferences to filter video searches.
Try other kind of filter and see what you get.