public MainPage()
{
InitializeComponent();
PivotMain.Items.Clear();
for (int k = 1; k < 157; k++)
{
p = new PivotItem();
Image i = new Image();
i.Source = new BitmapImage(new Uri(#"Resources/Images/"+k+".jpg", UriKind.Relative));
p.Margin = new Thickness(0, -100, 0, -2);
p.Content = i;
p.Header = k.ToString()+". ";
p.Name = "page" + k;
PivotMain.Items.Add(p);
}
But looks like it has its own limitations? No mater how I load pivot items ( Databinding Vs xml, runtime in code ). It gives out of memory exception if items are more then 40.
How can i fix it?
It is recommended not to have more than 5 pivot items, memory consumption may by one of the reasons. You can try loading the image on each pivot tab when the tab is selected and setting images on all the other tabs to null (or removing from the tab), this may help.
If you want to built something like a gallery, I recommend the SlideView control from Telerik, it works fine with large datasets.
Related
Hello everyone so I am having some trouble with this I have Platforms that I add to the stage which are different sizes in Width. What I am trying to do in my for Loop is add more platforms on the right side of the current platforms x position on stage. I am having trouble because they are different sizes so they end up over lapping each other on this side-scroller game. I align the Platform MC's to the right of the registration like so:
here is the smaller size Movie clip:
I am doing this because I want to add different obstacles to each frame inside the Platform Movie Clip.
add Initial platform:
private function addInitPlatform():void
{
platforms = new mcPlatforms();
platforms.x = (stage.stageWidth / 2) - 380;
platforms.y = (stage.stageHeight / 2) + 175;
addChildAt(platforms, 1);
aPlatformArray.push(platforms);
}
Then add new platforms:
private function addPlatForms():void
{
//Loop trhough Platform Array
for (var i:int = 0; i < aPlatformArray.length; i++)
{
var currentPlat:mcPlatforms = aPlatformArray[i];
nOffSetX += currentPlat.width + 50;
//Add platforms
platforms = new mcPlatforms();
platforms.x = nOffSetX;
platforms.y = (stage.stageHeight / 2) + 175;
addChildAt(platforms, 1);
aPlatformArray.push(platforms);
break;
}
trace(aPlatformArray.length + " NPLATFORMS");
}
I am trying to get the current platform which is the last platform I added to the stage and get its width so i can add it at the end but it still is doing something weird and overlapping over time,
So I was wondering if anyone knows how I should go about solving this so whenever I add on a new platform Movie Clip to the stage it aligns on the right side of the last platform Movie clip added to the stage with some space in between like so:
Thank you in advance!
I'm guessing that you have bunch of different platforms in your library with Linkage names set. Not sure if you want them to be in random order or not, but anyways you probably want to pick them up from an array, so:
var aPlatformsArray:Array = [p1,p2,p3]; //Platform Mc's from library
var addedPlatforms:Array = new Array(); //Array where we store added platforms
The first method was to simply raise offset after adding each platform:
var offsetX:Number = 0; //Starting x for the first platform
for(var i:int=0; i<10; i++){
//Just picking random ones from the Linkage array:
var platform:MovieClip = new aPlatformsArray[Math.floor(Math.random() * aPlatformsArray.length)]();
platform.y = 200;
platform.x = offsetX;
offsetX = platform.x + platform.width + 50;
addChild(platform);
addedPlatforms.push(platform);
}
And actually you don't need to worry about the second method as it's technically slower.
But the main difference is that now we have an array where we pick platforms to the stage, and another array where we push added platforms. The second array is not needed at this point, but you'll probably need it later.
And for offset calculations we use x and width of the "previous" element +fixed gap.
And if you just needed fixed order for the platforms, you'd use similar condition for the loop as you already did, and pick platforms in correct order:
for(var i:int=0; i<aPlatformsArray.length; i++){
var platform:MovieClip = aPlatformsArray[i];
Let me know if this does the job or if I got something wrong.
I can only find methods to create Button:s from disk-based image files.
How would I set/change a button's normal/highlighted states from in-memory data like Texture2D, Image etc?
Cocos2D-x v3.5
Update 20160408:
I Googled this again, and Google suggested this page... and I have to thank my past self :-)
This time I wrote a handy tool function:
void Mjcocoshelper::rendernodetospriteframecache(Node* node, std::string nameincache) {
const Size SIZE = node->getBoundingBox().size;
auto render = RenderTexture::create(SIZE.width, SIZE.height);
render->begin();
const Vec2 POS_BEFORE = node->getPosition();
const bool IGNORE_BEFORE = node->isIgnoreAnchorPointForPosition();
const float SCALEY_BEFORE = node->getScaleY();
node->ignoreAnchorPointForPosition(false);
node->setPosition(SIZE.width * 0.5f, SIZE.height * 0.5f);
node->setScaleY(-1.0f); // Or it gets upside down?
node->visit();
node->ignoreAnchorPointForPosition(IGNORE_BEFORE);
node->setPosition(POS_BEFORE);
node->setScaleY(SCALEY_BEFORE);
render->end();
auto spriteNew = render->getSprite();
Texture2D* texture2d = spriteNew->getTexture();
SpriteFrame* spriteframeOff = SpriteFrame::createWithTexture(texture2d, Rect(0, 0, texture2d->getContentSize().width, texture2d->getContentSize().height));
SpriteFrameCache::getInstance()->addSpriteFrame(spriteframeOff, nameincache);
}
Old:
I figured out this kinda neat workaround:
std::string framenameOff;
{
Texture2D* texture2d = mjpromobuttonx.textureOff();
SpriteFrame* spriteframeOff = SpriteFrame::createWithTexture(texture2d, Rect(0, 0, texture2d->getContentSize().width, texture2d->getContentSize().height));
framenameOff = "autobutton_off_" + std::to_string(++buttonsaddedtocacheoff);
SpriteFrameCache::getInstance()->addSpriteFrame(spriteframeOff, framenameOff);
}
std::string framenameOn;
{
Texture2D* texture2d = mjpromobuttonx.textureOff();
SpriteFrame* spriteframeOn = SpriteFrame::createWithTexture(texture2d, Rect(0, 0, texture2d->getContentSize().width, texture2d->getContentSize().height));
framenameOn = "autobutton_on_" + std::to_string(++buttonsaddedtocacheon);
SpriteFrameCache::getInstance()->addSpriteFrame(spriteframeOn, framenameOn);
}
Button* item = Button::create(framenameOff, framenameOn, framenameOff, TextureResType::PLIST);
So what it does, it adds spriteframes on the fly to the sprite frame cache. We have to make sure that the names we store them with don't overwrite anything else, and we also have to keep creating new names for each image we add to the cache. On some extreme sad occasion maybe this would overwrite some existing image, so I'll give this some more thouhght... maybe... sometime...
Bonus:
I did have a ObjC framework I created earlier that fetches images from a remote server... um for now I reused it, and also needed to convert the UIImage:s the framework ended up with to something I could pass to C++ and then Cocos2D-x... so I used this, it works pretty well:
Texture2D* getTexture2DFromUIImage(UIImage *photo) {
#warning TODO: Make use of this baby later? Does it work? Do we need to free after malloc?
// https://stackoverflow.com/a/15134000/129202
Image *imf = new Image();
NSData *imgData = UIImagePNGRepresentation(photo);
NSUInteger len = [imgData length];
Byte *byteData = (Byte*)malloc(len);
memcpy(byteData, [imgData bytes], len);
imf->initWithImageData(byteData,imgData.length);
imf->autorelease();
Texture2D* pTexture = new Texture2D();
pTexture->initWithImage(imf);
pTexture->autorelease();
return pTexture;
}
Now I'm just guessing that the malloc in that function should really have a free somewhere after it... but that's another issue.
I want to ask how to give jProgressBar in my code. i used netbeans interface. progressBar will end after it reach maximum_iteration.
jProgressBar already in other class. how can i fix it? Thank you. Please help.
train() is placed in other class.
public void train(){
for(int iteration=0; iteration<this.max_iteration; iteration++){
//int percent = (iteration/this.max_iteration) * 100;
//cs.jProgressBar1.setValue(percent);
for(int index=0; index<this.hms; index++){
Node[] newChord = {};
double random = Math.random();
/*process HS*/
if(this.original_chord != null){
// ensure the fist note of the new chord is not altered
newChord[0].notes = new int[first_chord_notes.length];
for(int j=0; j<first_chord_notes.length; j++){
newChord[0].notes[j] = first_chord_notes[j];
}
}
// evaluate new chord and substitute the worst one in hs if new chord is better
double newFitness = this.nodeListFitness(this.original_chord, newChord);
int worstIndex = this.worst_index();
double worstFitness = this.fitness[worstIndex];
if(newFitness > worstFitness){
this.hm[worstIndex] = newChord;
this.fitness[worstIndex] = newFitness;
}
}
System.out.println("Harmony Memory " + (iteration+1));
this.debug();
System.out.println("");
//JProgressBar jProgressBar1 = new JProgressBar();
//cs.jProgressBar1.setValue(iteration);
//cs.jProgressBar1.setEnabled(true);
}
}
I'm not sure at 100% but a Swing Component can be updated only inside the EventDispatcherThread, which is the Thread that run the GUI. For this reason, it will probably be better that you call the method train() inside you GUI, so it run into the EDT. Also, I can't understand why do you call the constructor of the JProgessBar, if you say that it is already in other class, probably the other class (I image it is the GUI) has already created a new instance of the progress bar.
I have some basic questions about some Problems in cocos2d-x v3.
1.) when I create sprites like that:
cocos2d::Sprite *sprite1 = cocos2d::Sprite::create("test.png");
auto sprite2 = cocos2d::Sprite::create("test.png");
How I have to to erease them proplery? Should I use autorelease (it crashes when I use it after create it)? Can I for both variants just use:
sprite1->removeFromParentAndCleanup(true);
sprite2->removeFromParentAndCleanup(true);
2.) When I want an Animation have active in my HelloWorldScene, so that i can use it when i want, how can I do it? I tried something like that:
void HelloWorld::runAnimationWalk() {
auto spritebatch = cocos2d::SpriteBatchNode::create("robo.png");
auto cache = cocos2d::SpriteFrameCache::getInstance();
cache->addSpriteFramesWithFile("robo.plist");
//spritebatch->addChild(worker);
Vector<SpriteFrame *> animFrames(5);
char str[100] = {0};
for(int i = 1; i <= 5; i++)
{
sprintf(str, "robot%i.png", i);
cocos2d::SpriteFrame* frame = cache->getSpriteFrameByName( str );
animFrames.pushBack(frame);
}
auto animWalk = cocos2d::Animation::createWithSpriteFrames(animFrames, 0.1f);
vector<Worker>::iterator it = workerVector.begin();
for(int k = 0; k<workerVector.size();k++) {
if(it->getType() == 1)
it->getWorker()->runAction(RepeatForever::create(Animate::create(animWalk)));
it++;
}
}
That works, but i have to call the function always after I want to change the animation. I tried to save the spritebatch, cache etc... global, but the animation dissaperars after a few time.
Answer 1) Yes. This is a full scenario:
//Create
Sprite *sprite1 = cocos2d::Sprite::create("test.png");
this->addChild(sprite1);
// Deleter Later
sprite1->removeFromParent();
Answer 2) You can create an animation ( Animation* ) and run it on any sprite.
some note:
If you want the animation play again and again, you can make a infinite version of your animation with RepeatForever::create(YourAnimation).
If you want to create the animation but use(display) it later. you can create your Animation* and retain() it until you run it on some target(sprite). (don't forget ro release it when running on target)
Hey everyone so having a little trouble trying to accomplish this. I understand how to add lives and display them through a Dynamic Text Field on the stage. My game is set up right now to where this happens and whenever the player dies a live decrements so it works fine.
But I want to display and Image of all 3 lives a custom Movie Clip that I drew in Flash CS6 to represent the lives. So All 3 lives will be displayed in the game and once the player dies one of the lives images is removed.
I have some idea on what to do. For instance I created a "for loop" to display all 3 images on the screen and created variables to place them horizontally next to each other with a space of 30 pixels.
But I'm not sure if this is the correct way to approach this. Also kind of confused on how I would remove one of the images when the player dies?
Her is my code so far:
public var playerLives:mcPlayerLives;
private var nLives:Number = 3;
private var startPoint:Point;
private var aPlayerLivesArray:Array;
In my main class Engine:
aPlayerLivesArray = new Array;
addPlayerLivesToStage();
Then the addplayerlivestostage function:
public function addPlayerLivesToStage():void
{
var startPoint:Point = new Point((stage.stageWidth / 2) - 300, (stage.stageHeight / 2) - 200);
var xSpacing:Number = 30;
for (var i = 0; i < nLives; i++)
{
trace(aPlayerLivesArray.length);
playerLives = new mcPlayerLives();
stage.addChild(playerLives);
playerLives.x = startPoint.x + (xSpacing * i);
playerLives.y = startPoint.y;
aPlayerLivesArray.push(playerLives);
}
}
So like i stated above everything works fine and it does display the 3 images that represent the lives, but would this be the correct approach or is there an easier method?
i think you're using right way to add lives.
and for removing them, you don't need to remove all and add new lives, you can remove the last element of lives array, so, it's done, i think thats already an easy method
so, you can implement this
for (var i = 0; i < nLives; i++)
to make a better usage for "adding lives in-game (earning lives)"
something like
for (var i = aPlayerLivesArray.length; i < nLives; i++)
but don't forget to decrease array length by 1 after removing last element of livesArray when player dies
Looks pretty close to a reasonable approach. I would have a blank container movieclip on stage where you want the lives icons to display. Create one life icon in your library and link it for export with actionscript. When you generate your game view, you can populate this container with the starting value of three lives. Place the first one, then place the subsequent ones based on the first location.
Some untested code:
NOTE: The following presumes your container clip for the lives is named lives_container and your link instance name for the life icon in the library is Life_icon.
var numberOfLives:Number = 3;
var iconSpacing:Number = 5;
var nextX:Number = 0;
for(var i:int = 0; i < numberOfLives; i++ )
{
var icon:MovieClip = new Life_icon();
icon.x = nextX;
lives_container.addChild( icon );
nextX += icon.width + iconSpacing;
}
This way you could add extra lives easily if the player gained any by adding new icons at the last nextX value, like so:
function addLife():void
{
var icon:MovieClip = new Life_icon();
icon.x = nextX;
lives_container.addChild( icon );
nextX += icon.width + iconSpacing;
}
or remove them as the player loses them:
function removeLife():void
{
var numberOfLivesDisplayed:Number = lives_container.numChildren();
lives_container.removeChildAt( numberOfLivesDisplayed - 1 );
nextX -= icon.width + iconSpacing;
}
Using a container clip for the lives icons makes adjusting the location of the life icons easier if it becomes necessary later.