うしブログ

うしブログ

趣味で運営する、GeoGebraの専門ブログ。

(作業メモ)StartPoint要検証(2行の場合;テキスト変更時未定義問題)

(要修復)ToggleButton・RollPolygonWithoutSlipping・貯金時計・直感力トレーニング

true or false game

点をクリックして楽しもう。

遊び方は、あえてプレイヤーにお任せします。 

設計

あらかじめ作成したオブジェクトは、数値オブジェクトnumberのみで、その他のオブジェクトは、全てJavaScriptを通じて作成・削除・変更を制御しています。ただし、下記URLの音素材は、事前にアップロードしておきました。

https://www.geogebra.org/material/show/id/zzxwytqu

グローバルJavaスクリプト
//headNameを頭文字にもつ特定のタイプのオブジェクトname1, name3, name4が存在しているならば、配列[1,3,4]を返す。
function getExistingObjIndex(headName,objType){
  var allObjNames = ggbApplet.getAllObjectNames(objType);
  var targets =allObjNames.filter(function(item){
    if(item.indexOf(headName)!=-1) return true;
  });
  targets.map( function(value, index, array){
    array[index] = eval(value.substr(headName.length));
  });
  return targets;
}

//nameを名前に含む特定のタイプのオブジェクトを全て削除する。
function deleteExistingObj(headName,objType){
  var targets = getExistingObjIndex(headName,objType);
  for(var k = 0; k < targets.length; k++){
    ggbApplet.deleteObject(headName+targets[k]);
  }
}

//indexごとに異なる数式によって、動的な色をセットする
function setSequenceDynamicColor(headName, objType, redScript, greenScript, blueScript, index){
  var targets = getExistingObjIndex(headName,objType);
  index = RegExp(index,'g');
  for(var k = 0; k < targets.length; k++){
    ggbApplet.evalCommand('SetDynamicColor['+headName+''+targets[k]+', '+redScript.replace(index,targets[k])+', '+greenScript.replace(index,targets[k])+', '+blueScript.replace(index,targets[k])+']');
  }
}

//GeoGebra Scriptをセットする。handlerは、'click'ならonClick、それ以外ならonUpdate
function setGgbScript(objName, handler, script){
  //オブジェクト存在確認
  var isexist = ggbApplet.exists(objName);
  if(isexist){
    var objType = ggbApplet.getObjectType(objName);
    var onwhat = (handler=='click') ? 'val' : 'onUpdate'; 
    var xmlText = '<element type=\"'+objType+'\" label=\"'+objName+'\"><ggbscript '+onwhat+'=\"'+script+'\"/></element>';
  ggbApplet.evalXML(xmlText);
  }
}

//indexごとに異なるスクリプトをセットする
function setSequenceGgbScript(headName, objType, handler, script, index){
  var targets = getExistingObjIndex(headName,objType);
  index = RegExp(index,'g');
  for(var k = 0; k < targets.length; k++){
    setGgbScript(headName+targets[k], handler, script.replace(index,targets[k]));
  }
}

//indexごとに異なるGeoGebra Commandを実行する。str command〔例:'POINTα=(α,0)'〕, str index〔例:'α'〕, int 実行回数
function evalSequenceCommand(command,index,time){
index = RegExp(index,'g');
  for(var k = 1; k<=time; k++){
    ggbApplet.evalCommand(command.replace(index,k));
  }
}

//指定した個数だけ自由な点POINT+kを作成
function makePOINTs(number){
  //半径はここで指定
  var radius = 4;
  //点を作成
  evalSequenceCommand('POINTα=CopyFreeObject[Rotate[(0,'+radius+'),2 π*α /'+number+']]', 'α', number);
}

//指定した個数だけBOOL+kを作成
function makeBOOLs(number){
  evalSequenceCommand('BOOLα=true', 'α', number);
}

//既存のすべてのFUNCのproductを足して、0ならfalse,それ以外ならtrue
function isFuncWell(){
  var result=0;
  var targets = getExistingObjIndex('FUNC','list');
  for(var k = 0; k<targets.length; k++)
  result += ggbApplet.getValue('Product[FUNC'+targets[k]+']');
  if(result==0){return false;}
  else{return true;}
}

//指定した個数だけFUNC+kを作成
function makeFUNCs(number){
  do {
    evalSequenceCommand('FUNCα=CopyFreeObject[Sequence[If[t==α,true,RandomElement[{true, false}]], t, 1, '+number+']]', 'α', number);
  } while (isFuncWell())
}

//以下、ボタン用の特殊関数

//既存のオブジェクトを削除
function deleteWorld(){
  deleteExistingObj('POINT','point');
  deleteExistingObj('BOOL','boolean');
  deleteExistingObj('FUNC','list');
  deleteExistingObj('SEG','segment');
}

//新たにオブジェクトを作成
function createWorld(){
  var number = ggbApplet.getValue('number');
  makePOINTs(number);
  makeBOOLs(number);
  makeFUNCs(number);
  //線分を作成
  for(var point1 =1; point1<number; point1++){
    for(var point2 = 2; point2<=number; point2++){
      if(point1!=point2){
        ggbApplet.evalCommand('SEG'+point1+'and'+point2+'=Segment[POINT'+point1+',POINT'+point2+']');
        ggbApplet.evalCommand('SetConditionToShowObject[SEG'+point1+'and'+point2+',BOOL'+point1+'==true&&BOOL'+point2+'==true]');
        ggbApplet.setFixed('SEG'+point1+'and'+point2, false, false);
      }
    }
  }
}

//スクリプトをセット
function setScript(){
  var targets = getExistingObjIndex('POINT','point');
  targets.map( function(value, index, array){
    array[index] = 'If[Element[FUNCα,'+value+']==true,SetValue[BOOL'+value+',¬BOOL'+value+']]';
  });
  var script = '';
  targets.map( function(value) {
    script += value+'\n';
  });
  script += 'PlaySound[false]\nPlaySound[&quot;#zzxwytqu&quot;]';
  setSequenceGgbScript('POINT', 'point', 'click', script, 'α');
}

//色をセット
function setColor(){
  setSequenceDynamicColor('POINT', 'point', 'If[BOOLα==true,1,0]', 'If[BOOLα==true,0,0]', 'If[BOOLα==true,1,0]', 'α');
}
new game ボタンのOn Click スクリプトJavaScript
//既存のオブジェクトを削除
deleteWorld();

//新たにオブジェクトを作成
createWorld();

//スクリプトをセット
setScript();

//色をセット
setColor();

 

以上