cocos2dxでaddChildについて

このQ&Aのポイント
  • cocos2dx3.6を使ってアプリの開発を最近始めたのですが、addChildをforループの中で呼び出すと[Assert failed: child already added. It can't be added again]とメッセージがデバッグログに表示されてエラー停止してしまいます。
  • 2回addchildを呼び出しているからというのはわかったのですが、じゃあどうやってこれを回避したらよいのだろうということで悩んでいます。
  • やりたいことのイメージはシミュレーションゲームのようにマップチップを並べることだけなのですが、中々上手くいかないです。別ツールでマップチップを並べてでは無くプログラムの中で作成したいのでお手数ですがごご助力頂けないでしょうか。
回答を見る
  • ベストアンサー

cocos2dxでaddChildについて

cocos2dx3.6を使ってアプリの開発を最近始めたのですが、addChildをforループの中で呼び出すと[Assert failed: child already added. It can't be added again]とメッセージがデバッグログに表示されてエラー停止してしまいます。 2回addchildを呼び出しているからというのはわかったのですが、じゃあどうやってこれを回避したらよいのだろうということで悩んでいます。 以下ソースの★の部分です。 bool Scene::init() { if (!Layer::init()) { return false; } cocos2d::SpriteBatchNode *mapTile = SpriteBatchNode::create("grass.png"); this->addChild(mapTile); this->setMapTileBatchNode(mapTile); this->addMapTile(); // 関数呼び出し return true; } Sprite* Scene::addMapTile() { auto winSize = Director::getInstance()->getWinSize(); // タイル横を選択 int mapTypeWidth = rand() % static_cast<int>(TileWidth::COUNT); // タイル縦を選択 int mapTypeHeight = rand() % static_cast<int>(TileHeight::COUNT); // テクスチャサイズ取り出し auto texturesize = _mapTileBatchNode->getTextureAtlas()->getTexture()->getContentSize(); // テクスチャを個数で割る auto mapWidth = texturesize.width / static_cast<int>(TileWidth::COUNT); auto mapHeight = texturesize.height / static_cast<int>(TileHeight::COUNT); auto Tile = Sprite::createWithTexture(_mapTileBatchNode->getTexture(), Rect(mapWidth * mapTypeWidth, mapHeight * mapTypeHeight, mapWidth, mapHeight)); for (int i = 256; i < 259; i++) { int col = i % 64; int row = i / 64; int x = 64 * col; int y = 64 * row; Tile->setPosition(x, y); ★ _mapTileBatchNode->addChild(Tile); } } やりたいことのイメージはシミュレーションゲームのようにマップチップを並べることだけなのですが、中々上手くいかないです。。 別ツールでマップチップを並べてでは無くプログラムの中で作成したいのでお手数ですがごご助力頂けないでしょうか。よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
noname#247307
noname#247307
回答No.1

Cocos2d-xはちょっと触ったぐらいしか経験がないのですが……。 ざっと見たところ、★のところでTileを二重にaddChildしてしまっている、ということなのですよね? Tileは、forの外側にありますから、for内でaddChildすれば二重に組み込まれてしまうのは当たり前です。 auto Tile = Sprite::createWithTexture~の部分をfor内に記述すればいいと思いますが、それではまずいですか? Sprite自体は、同じテクスチャを使うとしても毎回createしてaddChildするものだと思いますが……。

6gggggg
質問者

お礼

ご回答ありがとうございます。 ご指摘の通り、for内にcreateを入れたらエラーはでなくなりました。 一度createしたらもうcreateする必要はないと思い込んでいました。。。 何でも試してみないといけないですね。 お時間いただきありがとうございました。

関連するQ&A

  • C# ListView 自作列幅調整 描画されない

    いつもお世話になっております。 今回はC#のListViewで皆様にお聞きしたいことがあり、 質問させて頂きました。 ListViewに3列追加しListViewの幅が変更された際に 2列目のみを引き延ばすものを作りたいと思っています。 しかし、以下操作を行うと、ListViewのリサイズ等で 描画更新されない状態になってしまいます。 (また、リストアイテムをクリックするとその列は描画されるのですが、 アイテムの描画開始Y位置がおかしくなっています。)  1.縦スクロールバーが表示されるまで縮小する  2.スクロールバーのノブを下に移動  3.縦スクロールバーの表示が消えるまで拡大する サンプルコード及び画像を添付いたします。 内容は、  3列のListViewに適当なアイテムを10個追加し、  OnClientSizeChangedでClientSize.Widthと1列3列の幅から  2列目の幅を算出・設定しています。 ※画像は、以下コントロールをFormに張り付けただけのもので  問題の起こる操作をした際のものになります。 class MyListView : ListView {   public const int COL_1_WIDTH  = 30;   public const int COL_3_WIDTH  = 75;   enum LISTVIEW_COL   {     COL1,     COL2,     COL3,     NUM   }   public MyListView() {     Dock = DockStyle.Fill;     HeaderStyle = ColumnHeaderStyle.None;     FullRowSelect = true;     HideSelection = false;     View = System.Windows.Forms.View.Details;     //ヘッダ追加     ColumnHeader column1 = new ColumnHeader();     ColumnHeader column2 = new ColumnHeader();     ColumnHeader column3 = new ColumnHeader();     ColumnHeader[] columnHeaders = { column1, column2, column3 };     this.Columns.AddRange( columnHeaders );     //ヘッダ幅追加     this.Columns[( int )LISTVIEW_COL.COL1].Width = COL_1_WIDTH;  //1列固定     this.Columns[( int )LISTVIEW_COL.COL3].Width = COL_3_WIDTH; //3列固定     int width = ClientRectangle.Width;     for( int i = 0; i < Columns.Count; i++ ) {       if( i == ( int )LISTVIEW_COL.COL2 ) { continue; }       width -= Columns[i].Width;     }     //2列 リストビューの幅いっぱいになるように調節     this.Columns[( int )LISTVIEW_COL.COL2].Width = width;     //適当にアイテム追加     for( int i = 0; i < 10; i++ ) {       string[] strs = { "COL1", "COL2", "COL3" };       ListViewItem item = new ListViewItem( strs );       this.Items.Add( item );     }   }   protected override void OnClientSizeChanged( EventArgs e ) {     base.OnClientSizeChanged( e );     //2列の幅を調整     int width = ClientRectangle.Width;     for( int i = 0; i < Columns.Count; i++ ) {       if( i == ( int )LISTVIEW_COL.COL2 ) { continue; }       width -= Columns[i].Width;     }     Columns[( int )LISTVIEW_COL.COL2].Width = width;   } } 何故このようになってしまうのかご存知の方いらっしゃいましたら教えてください。

  • Cygwinでg++がグローバル関数をはじいてしまう

    現在Win XP上にGygwinを導入し C++の勉強をしています。 書籍を購入し、以下のプログラムを試したところ グローバル関数宣言をしているにもかかわらず main() とfunc1()中で変数”count”が undeclared (first use this function) として弾かれてしまいます。 どうしてなのでしょうか? よろしくお願いします。 //example global variavle. #include<iostream> using namespace std; void func1(); void func2(); static int count; //This is global variavle. int main() { int i; //This is local variavle. for(i=0; i<10 ; i++){ count = i * 2; func1(); //calling func1(). } return 0; } void func1() { cout << "count: " << count; //access global "count" cout << "\n"; func2(); //calling func2(). } void func2() { int count; //define local "count" for(count=0;count<3;count++) { cout << "."; } }

  • appletを使ったプログラミング2

    前回も違う質問をさせて頂いたのですが、bubble sortとselection sortを ボタンを押す事によって順次長方形を左から右に動かしたいのですが、 どのようにしたら良いのか止まってしまいました。 import java.awt.*; import java.applet.*; import java.awt.event.*; import java.util.Random; import java.io.*; public class GUI extends Applet { public void update(Graphics g) { paint(g); } Button button = new Button("Sort Me"); Label text = new Label("Pink: Selection Sort" + "\n" + "Green: Inseration Sort"); int[] store = new int[20]; public static int[] findValue(int [] store){ int rand; for (int i = 0; i < store.length; i ++){ do{ rand = (int)(Math.random()*51)+10; } while(doesExists(rand, store, i)); store[i] = rand; } return store; } private static boolean doesExists(int rand, int[] arr, int i){ if(i != 0){ for(int j =0; j < i; j++){ if(rand == arr[j]){ return true; } } } return false; } int Counter = 0; int xScale = 0; public void displayRectangles(Graphics g) { if(Counter < 20) { xScale += 12; int x = 80 + xScale; int H = store[Counter]; g.setColor(Color.pink); g.fillRect(x, (140 - H), 10, H); g.setColor(Color.green); g.fillRect(x, 140, 10, H); Counter++; } } private void Rectangles(int xScale, int y, int W, int Counter){ this.xScale = xScale; this.Counter = Counter; } public void setxScale(int xScale){ this.xScale = xScale; } public void setCounter(int Counter){ this.Counter = Counter; } public int getxScale(){ return xScale; } public int getCounter(){ return Counter; } public void selectionSort(int[] list){ int min,temp; int n = list.length; for(int p = 0; p < n-1; p++){ min = p; for (int i = p+1; i < n; i++){ if (list[i]<list[min]) min = i; if (p != min){ temp = list[p]; list[p] = list[min]; list[min] = temp; } } } } public void insertionSort (int[] list){ int i,temp; int n = list.length; for(int k = 1;k < n; k++){ temp = list[k]; i = k; while (i > 0 && temp < list[i-1]){ list[i] = list[i -1]; i--; } list[i] = temp; } } public void init() { setSize(500, 350); setBackground(Color.WHITE); add(button); add(text); button.addActionListener(new buttonHandler()); store = findValue(store); } int c = 0; public void paint(Graphics g) { //scrambleRectangles(store); // scrambled array will be newStore[] c++; displayRectangles(g); if(c < 20) { repaint(); } } int count = 0; class buttonHandler implements ActionListener{ public void actionPerformed(ActionEvent e){ count ++; button.setLabel("pass " + count); if(e.getActionCommand()=="pass") repaint(); } } } 最終形は以下のリンクの様にしたいのですが、どのようにしたら良いのか分かりません。 http://hills.ccsf.cc.ca.us/~cconner/Java/Sorts/S … どなたかアドバイス頂けますでしょうか? よろしくお願い致します。

  • if・・・break文について教えて下さい♪

    ---------------------------------------------------------------- public class A { static int prime(int number){ int count=0; for(int i=1; i<=number; i+=2){ if(number%i==0) count++; } return count; } } ----------------------------------------------------------------  上に書いたプログラムのprime()メソッド内に、if…break文を使いたいのですが、どう書いたらイイのですか??  上のプログラムをコピーしてからif…break文を付け加えて欲しいです★

    • ベストアンサー
    • Java
  • javascriptのenchantの打ちミス

    javascriptのenchantで打ちミスをしてつまづいてます。 だけど、どこがどうミスしてるのかわかりません。 プログラム作成で利用しているサイトはこちらです。 http://code.9leap.net/codes/edit/83463 参考書はこれです。↓↓ http://www.amazon.co.jp/s/ref=nb_sb_noss_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&url=search-alias%3Daps&field-keywords=javascript+%E3%82%B2%E3%83%BC%E3%83%A0&rh=i%3Aaps%2Ck%3Ajavascript+%E3%82%B2%E3%83%BC%E3%83%A0 ソースはこれです。↓↓ enchant(); var game; var scoreLabel; var timeLabel; var mogura =new Array(9); function rand(num){ return Math.floor(Math.random()*num); } Mogura =Class.create(Sprite,{ initialize:function(x,y){ Sprite.call(this,80,80); this.image =game.assets["mogura.png"]; this.x=x; this.y=y; this.status=-rand(200); }, onenterframe:function(){ this.staus++; if(this.status<0){ this.frame=0; }else if(this.status==0){ this.frame=1; }else if(this.status == 30){ this.status=-rand(200); } }, ontouchend:function(){ if(this.frame==1){ this.frame=2; this.status=0; scoreLabel.score+100; } } }); window.onload=function(){ game=new Game(320,320); game.rootScene.backgroundColor="rgb(144,198,116)"; game.preload("mogura.png"); game.onload =function(){ for(var i=0; i<9;i++){ mogura[i]=new Mogura( 20+i%3*100, 50+Mathfloor(i/3)*80); game.rootScene.addChild(mogura[i]); } scoreLabel = new ScoreLabel(5,5); scoreLabel.score=0; game.rootScene.addChild(scoreLAbel); timeLabel =new TimeLabel(5,25,"countdown"); timeLabel.time =10; timeLabel.onenterframe =function(){ if(timeLabel.time<=0){ game.end(); } } game.rootScene.addChild(timeLabel); } game.start(); } このソースの15行目の }else if(this.status==0){で黄色の三角マークが出ているのですが、 どこが間違ってるのかまったくわかりません。 全部消してやり直しても同じところで同じマークが出てしまいます。 どこが間違ってて、どうすればいいのか、教えてください。

  • ループの正誤

    金種表のソースを書きました。 表示ループのif文(枚数0枚の場合表示しない)を実行しない場合は 正確の結果が出てくれるんですが、 このまま実行したら、たとえば引数は222の場合は 実行した結果は 「100円 2枚」、10円と1円の枚数を表示してくれなっかです。 原因を教えて頂けますか? ループのどこが間違えたのがわかりません… import java.io.*; public class ex1 { public static final int[] YEN_TYPES = {10000,5000,1000,500,100,50,10,5,1}; public static int[] getYenCount(int yen, int[] yentype) { int[] count = new int[yentype.length]; for (int i = 0; i < yentype.length; i++) { count[i] = yen / yentype[i]; //商 yen = yen % yentype[i]; //剰余 } return count; } public static void main(String args[]) throws IOException { int yen = Integer.parseInt(args[0]); int[] count = getYenCount(yen, YEN_TYPES); for (int i = 0; i < YEN_TYPES.length; i++) { if(count[i] == 0) { i++; }else{ System.out.println(YEN_TYPES[i] + "円\t" + count[i] + "枚"); } } } }

    • ベストアンサー
    • Java
  • プログラムの説明

    C++の初心者です。 ↓のプログラムの動作はさっぱりわかりませんが、それについての説明は具体的に教えていただきたいです。(できれば、詳しく) #include <iostream> #include <string> int getNinzu(int ARGC, char *ARGV[]) throw (char const *){ if(ARGC!=2){ throw "Needs only one argument."; } int ninzu=std::atoi(ARGV[1]); if(ninzu<=0){ throw "Value is too small."; } return ninzu; } #include <cstdlib> #include <ctime> int randfive(){ static bool firsttime=true; if(firsttime){ firsttime=false; std::srand(std::time(NULL)); } return static_cast<int>(static_cast<double>(std::rand())/RAND_MAX*(5+1)); } #include <iomanip> int main(int ARGC, char* ARGV[]){ std::string cmdname=ARGV[0]; int ninzu; try{ ninzu=getNinzu(ARGC,ARGV); std::cout << std::setfill('0'); for (int i = 1; i <= ninzu; ++i) { int score = 0; for (int k = 0; k < 20; ++k) score += randfive(); std::cout << "C" << std::setw(5) << i << " " << score << '\n'; } }catch(char const *str){ std::cerr << str << std::endl << "Usage: " << cmdname << " ninzu" << std::endl; return 1; } }

  • セグメンテーションエラーがでます

    今、cでオセロゲームを作っています。 コンピュータと対戦できるようにしたいのですが、セグメンテーション違反になってしまいます。 p[LEN*LEN]を大域変数にするとうまく動きますが、以下のように局所変数にして関数で受け渡しをすると、 数回ループさせたところでエラーで強制終了します。 おそらく関数find_legal_moveへのp[]の渡し方が悪いのだと思いますが、なぜか分かりません。 以下にプログラムの一部を載せますので、お手数ですが原因を教えていただけないでしょうか。 よろしくお願いします。 #define LEN 10 /* ボードの1辺 */ #define opponent(player) (3-(player)) /* 1の相手は2, 2の相手は1 */ typedef struct {  int row; /* 行 */  int col; /* 列 */  int dr, dc; /* 行, 列の向き */ } Position; // 裏返る石の個数 int count_turn_over(int board[][LEN], int player, Position p) {  int i;  for (i=1; board[p.row+i*p.dr][p.col+i*p.dc]==opponent(player); i++);  if (board[p.row+i*p.dr][p.col+i*p.dc] == player)   return i - 1;  else   return 0; } // playerが(row, col)に石を置けるかどうかをチェック int is_legal_move(int board[][LEN], int player, Position p) {  if ((p.row < 1 || p.row > 8) || (p.col < 1 || p.col > 8))   return 0;  if (board[p.row][p.col] != 0) return 0;  for (p.dr = -1; p.dr <= 1; p.dr++)   for (p.dc = -1; p.dc <= 1; p.dc++)    if (count_turn_over(board, player, p) != 0)     return 1;  return 0; } // playerがどこに石を置けるか int find_legal_move(int board[][LEN], int player, Position p[]) {  Position pos;  int i = 0;  for (pos.row = 1; pos.row < LEN - 1; pos.row++)   for (pos.col = 1; pos.col < LEN - 1; pos.col++)    if (is_legal_move(board, player, pos) != 0) {     p[i].row = pos.row;     p[i].col = pos.col;     i++;    }  return i; } // computerの入力 void computer(int board[][LEN], int player, Position *pos) {  int i, num, max;  Position p[LEN * LEN];  printf("コンピュータの番です\n");  // 一番多く取れるところを取る  num = find_legal_move(board, player, p);  max = count_turn_over(board, player, p[0]);  pos->row = p[0].row;  pos->col = p[0].col;  for (i = 1; i < num; i++) {   int tmp = count_turn_over(board, player, p[i]);   if (max < tmp) {    pos->row = p[i].row;    pos->col = p[i].col;   }  } }

  • ソースコードの流れについて

    下記ソースコードの流れを詳しく解説していただけませんか。表示結果が理解できません。 class Th extends Thread{ public void run(){ for(int i = 0; i < 2; i++)System.out.print(" "+ Main4_1_49.count + i); } } public class Main4_1_49{ static int count = 0; public static void main(String[] args){ Th[] tr = new Th[6]; for(int i = 0; i < 5; i++){ count++; tr[i] = new Th(); tr[i].setPriority(i * 2 + 1 ); tr[i].start(); } } }

  • appletを使ったJavaプログラミング

    Java初心者なのですが、ランダムユニークナンバーをarrayに代入し、長方形の高さが全て違う様に表記したいのですが、全く表記出来ません。 おそらく、arrayに代入する時点までは大丈夫だとは思うのですが、どのようにしたら長方形に高さを代入してappletで表記出来るのでしょうか? import java.awt.*; import java.applet.*; import java.awt.event.*; import java.util.Random; import java.io.*; public class GUI extends Applet { public void update(Graphics g) { paint(g); } Button button = new Button("Sort Me"); Label text = new Label("Pink: Selection Sort" + "\n" + "Green: Inseration Sort"); int[] store = new int[20]; public static int[] findValue(int [] store){ int rand; for (int i = 0; i < store.length; i ++){ do{ rand = (int)(Math.random()*21)+10; } while(doesExists(rand, store, i)); store[i] = rand; } return store; } private static boolean doesExists(int rand, int[] arr, int i){ if(i != 0){ for(int j =0; j < i; j++){ if(rand == arr[j]){ return true; } } } return false; } int Counter = 0; int xScale = 0; public void displayRectangles(Graphics g) { if(Counter < 20) { xScale += 15; int x = 80 + xScale; int H = store[Counter]; g.setColor(Color.pink); g.fillRect(x, (140 - H), 10, H); g.setColor(Color.green); g.fillRect(x, 140, 10, H); Counter++; } } public void init() { setSize(500, 350); setBackground(Color.WHITE); add(button); add(text); button.addActionListener(new buttonHandler()); } int c = 0; public void paint(Graphics g) { c++; displayRectangles(g); if(c < 20) { repaint(); } } int count = 0; class buttonHandler implements ActionListener{ public void actionPerformed(ActionEvent e){ count ++; button.setLabel("pass " + count); if(e.getActionCommand()=="pass") repaint(); } } } 最終的にはボタンをクリックするたびに、長方形の長さが右側になるにつれて大きくなってソートされます。 http://hills.ccsf.cc.ca.us/~cconner/Java/Sorts/SortsWithButton.html どうしたら良いのかどうしても分かりません。 よろしくお願い致します。

    • ベストアンサー
    • Java

専門家に質問してみよう