草庐IT

javascript - 创建 Javascript 游戏教程

coder 2025-03-28 原文

我有一个名为 Rails Across Europe 的 Facebook 游戏。它是用 PHP/MySQL/Facebook Javascript 编写的。我的游戏中缺少的重要功能之一是交互式用户教程。我有一个截屏视频,但我认为它的帮助不够。我注意到大多数开始游戏的用户在放弃之前只玩了一两轮。这是一个复杂的游戏,如果有交互式教程,它会受益匪浅。

问题是我不知道如何创建这样的教程。该游戏由一张欧洲 map 组成,其中包含欧洲城市、铁路线(例如轨道)和城市提供的商品。玩家应该 build 连接城市的轨道,沿着轨道驾驶他的火车,在一个城市提货,并将它们运送到另一个有需求的城市,届时他将获得报酬。

该游戏包含许多不同的事件处理程序,例如 build 轨道、移动火车、在城市装卸 cargo 等。

我正在努力研究如何构建本教程以使其与用户的操作保持同步(反之亦然),以及如何确定用户是否采取了允许教程继续进行的正确操作下一步以及如何知道下一步是什么。

以下是我的前端js代码示例:

var openCargoHolds = 0;
var cargoHoldsUsed = 0;
var loadCargoDialog = null;
var isIE = false;
function setBrowserIsIE(value) {
  isIE = value;
}
function moveTrainAuto() {
//debugger;
//consoleTime('moveTrainAuto');
consoleLog('moveTrainAuto');
  var ajax = new Ajax();
  ajax.responseType = Ajax.JSON;
//consoleTime('moveTrainAuto::move-trains-auto');
  ajax.ondone = function(data) {
//consoleTimeEnd('moveTrainAuto::move-trains-auto');
//consoleTimeEnd('moveTrainAuto::get-track-data');
//debugger;
    var trackColor = (data.route_owned) ? '#FF0' : '#888';
    var trains = [];
    trains[0] = data.train;
    removeTrain(trains);
    drawTrack(data.y1, data.x1, data.y2, data.x2, trackColor, trains);
//debugger;
    if(data.code == 'UNLOAD_CARGO') {
consoleLog('moveTrainAuto::unloadCargo');
      //unloadCargo();
      //myEventMoveTrainManual(null); //continue moving train until final destination is reached
      moveTrainManual();
    } else if (data.code == 'MOVE_TRAIN_AUTO') { // || data.code == 'TURN_END') {
      moveTrainAuto();
    } else if (data.code == 'TURN_END') {
consoleLog('moveTrainAuto::turnEnd');
      turnEnd();
    } else {
      /* handle error */
    }
  }
  ajax.post(baseURL + '/turn/move-train-auto-track-data');
//consoleTimeEnd('moveTrainAuto');
}
function moveTrainAutoEvent(evt) {
//debugger;
  //moveTrainAuto();
  //myEventMoveTrainManual(null, false);
  moveTrainManual();
}
function moveTrainManual() {
//consoleTime('moveTrainManual');
consoleLog('moveTrainManual');
//debugger;
  state = MOVE_TRAIN_MANUAL;
  var ajax = new Ajax();
  ajax.responseType = Ajax.JSON;

  if(!trainInTransit) {
    var actionPrompt = document.getElementById('action-prompt');
    actionPrompt.setInnerXHTML('<span><div id="action-text">'+
      'Move Train: Select destination'+
      '</div>'+
      '<div id="action-end">'+
      '<form method="POST">'+
      '<input type="button" value="Replace Demands" id="replace-demands-btn" style="width: 130px;" />'+
      '<input type="button" value="Upgrade Train" disabled="disabled" id="upgrade-train-btn" class="btn" />'+
      '<input type="button" value="Build Track" id="build-track-btn" class="btn" />'+
      '<input type="button" value="Manage Cargo" id="manage-cargo-btn" class="btn" />'+
      '</form>'+
      '</div></span>');
    var actionButton = document.getElementById('build-track-btn');
    actionButton.addEventListener('click', moveTrainEventHandler);
    actionButton = document.getElementById('replace-demands-btn');
    actionButton.addEventListener('click', moveTrainEventHandler);
    actionButton = document.getElementById('upgrade-train-btn');
    actionButton.addEventListener('click', moveTrainEventHandler);
    var loadCargoButton = document.getElementById('manage-cargo-btn');
    loadCargoButton.addEventListener('click', moveTrainEventHandler);
  } else {
    var actionPrompt = document.getElementById('action-prompt');
    actionPrompt.setInnerXHTML('<span><div id="action-text">'+
      'Train in-transit to final destination...</div></span>');
  }
  ajax.ondone = function(data) {
consoleLog('ajax.moveTrainManual');
    if(data.code == 'TURN_END') {
consoleLog('moveTrainManual::turnEnd');
      turnEnd();
    } else {
//debugger;
      //myEventMoveTrainManual(null);
    }
  }
  ajax.post(baseURL + '/turn/move-train-manual');
//consoleTimeEnd('moveTrainManual');
}
function unloadCargo() {
//debugger;
consoleLog('unloadCargo');
  var actionPrompt = document.getElementById('action-prompt');
  actionPrompt.setTextValue('Unloading cargo...');
  var ajax = new Ajax();
  ajax.responseType = Ajax.JSON;
  ajax.ondone = function(data) {
//debugger;
    if(data.unloadableCargo.length == 0) {
consoleLog('unloadableCargo == 0');
      moveTrainManual();
      //loadCargo();
    } else {
consoleLog('unloadable cargo='+dump(data.unloadableCargo));
      var i = 0;
      var j = 0;
      var ucCount = data.unloadableCargo.length;
      for(i = 0; i < ucCount; i++) {
        var cargoDialog = new Dialog();
        cargoDialog.showChoice('Unload Cargo', 'Unload  ' + data.unloadableCargo[i].goods_name + ' at ' + data.unloadableCargo[i].city_name + ' for ' + data.unloadableCargo[i].payoff + 'M euros?');
        cargoDialog.iVal = i;
        cargoDialog.onconfirm = function() {
//consoleLog('iVal='+this.iVal);
//consoleLog('unloadable cargo onconfirm='+dump(data.unloadableCargo));
          var ajax = new Ajax();
          ajax.responseType = Ajax.JSON;
          var param = {"city_id": data.unloadableCargo[this.iVal].city_id, "goods_id": data.unloadableCargo[this.iVal].goods_id, "payoff": data.unloadableCargo[this.iVal].payoff};
          ajax.ondone = function(demandData) {
            refreshDemands();
            // update balance
            setHtmlBalance(demandData.balance);
            if(demandData.post_to_wall) {
              Facebook.streamPublish('', demandData.attachment, demandData.action_links);
            }

            ajax.responseType = Ajax.JSON;
          //debugger;
            ajax.ondone = function(data) {
              if(!data.already_won && data.funds >= data.winning_balance) {
                var dialog = new Dialog().showMessage('Congratulations!', 'You have earned over '+data.winning_balance+'M euros. You have won! You may continue playing or start a new game.');
                dialog.onconfirm = function() {
                  moveTrainManual();
                }
              }
              moveTrainManual();
            }
            ajax.post(baseURL + '/turn/get-player-stats');
          }
          ajax.post(baseURL + "/turn/do-unload-cargo", param);
        }
        cargoDialog.oncancel = function() { moveTrainManual(); }
      }
    }
  }
  ajax.onerror = function() {
    var dialog = new Dialog().showMessage('Request taking too long', 'The system is taking too long to process this request. Please try refreshing the page. If this does not work, please Contact Us with a description of your problem. We are sorry for the inconvenience.');
  }
  ajax.post(baseURL + '/turn/unload-cargo');
}
function loadCargo() {
//consoleLog('Entering loadCargo()');
  var actionPrompt = document.getElementById('action-prompt');
  actionPrompt.setTextValue('Loading cargo...');
  var ajax = new Ajax();
  ajax.responseType = Ajax.JSON;
  ajax.ondone = function(data) {
//consoleLog('Entering ondone for load-cargo');
//debugger;
    ajax.responseType = Ajax.FBML;
    ajax.ondone = function(fbjsData) {
//consoleLog('Entering ondone for load-cargo-dialog-fbjs');
//debugger;
      if(data.loadableCargo.length == 0) {
//consoleLog('Calling moveTrainManual()');
        moveTrainManual();
      } else {
//consoleLog('Instantiating loadCargoDialog');
        if(loadCargoDialog == null) {
          loadCargoDialog = new Dialog();
          //if browser is IE, move dialog up 50px to compensate for bug that causes it to shift down the screen
          if(isIE) {
            //loadCargoDialog.setStyle('position', 'relative');
            //loadCargoDialog.setStyle('top', '-50px');
          }
          loadCargoDialog.showChoice('Load Cargo', fbjsData, 'Minimize', 'Pass');
        } else {
          if(isIE) {
            //loadCargoDialog.setStyle('position', 'relative');
            //loadCargoDialog.setStyle('top', '-50px');
          }
          loadCargoDialog.showChoice('Load Cargo', fbjsData, 'Minimize', 'Pass');
        }
        var dlgPrefixString = document.getElementById('dlg-prefix-string').getValue();
        //var dlgPrefixString = dlgPrefixElem.getValue();
//consoleLog('Setting dlgBtnNew');
        var dlgBtnNew = document.getElementById(dlgPrefixString+'-load-new-submit');
        dlgBtnNew.cityId = data.loadableCargo.city_id;
        dlgBtnNew.trainId = data.loadableCargo.train_id;
        dlgBtnNew.prefixString = dlgPrefixString;
        dlgBtnNew.loadCargoDialog = loadCargoDialog;
        dlgBtnNew.addEventListener('click', cargoEventHandler); //loadNewCargo);
//consoleLog('Setting dlgBtnDiscard');
        var dlgBtnDiscard = document.getElementById(dlgPrefixString+'-discard-existing-submit');
        dlgBtnDiscard.cityId = data.loadableCargo.city_id;
        dlgBtnDiscard.trainId = data.loadableCargo.train_id;
        dlgBtnDiscard.prefixString = dlgPrefixString;
        dlgBtnDiscard.loadCargoDialog = loadCargoDialog;
        dlgBtnDiscard.addEventListener('click', discardExistingCargo);
        loadCargoDialog.onconfirm = function() {
//consoleLog('Entering loadCargoDialog.onconfirm');
          // Submit the form if it exists, then hide the dialog.
          loadCargoDialog.hide();
          actionPrompt = document.getElementById('action-prompt');
          actionPrompt.setInnerXHTML('<span><div id="action-text">'+
            'The "Load cargo" dialog has been minimized'+
            '</div>'+
            '<div id="action-end">'+
            '<form action="" method="POST">'+
            '<input type="button" value="Maximize" id="next-phase" onclick="loadCargo();" />'+
            '</form>'+
            '</div></span>');
          actionButton = document.getElementById('next-phase');
          actionButton.setValue('Maximize');
          actionButton.addEventListener('click', loadCargoEventHandler);
//consoleLog('Exiting loadCargoDialog.onconfirm');
        };
        loadCargoDialog.oncancel = function() {
//consoleLog('Entering loadCargoDialog.oncancel');
          moveTrainManual();
//consoleLog('Exiting loadCargoDialog.oncancel');
        }
      }
//consoleLog('Exiting ondone for load-cargo-dialog-fbjs');
    }
    ajax.onerror = function() {
      var dialog = new Dialog().showMessage('Request taking too long', 'The system is taking too long to process this request. Please try refreshing the page. If this does not work, please Contact Us with a description of your problem. We are sorry for the inconvenience.');
    }
    ajax.post(baseURL + '/turn/load-cargo-dialog-fbjs', data);
//consoleLog('Exiting ondone for load-cargo');
  }
  ajax.onerror = function() {
    var dialog = new Dialog().showMessage('Request taking too long', 'The system is taking too long to process this request. Please try refreshing the page. If this does not work, please Contact Us with a description of your problem. We are sorry for the inconvenience.');
  }
  ajax.post(baseURL + '/turn/load-cargo');
//consoleLog('Exiting loadCargo');
}
function loadCargoEventHandler(evt) {
  if(evt.type == 'click') {
    loadCargo();
  }
}
function trackEventHandler(evt) {
  var x1 = evt.target.x1;
  var x2 = evt.target.x2;
  var y1 = evt.target.y1;
  var y2 = evt.target.y2;
  var cost = evt.target.cost;
  var prefixString = evt.target.prefixString;

  evt.target.payDialog.hide();

  ajax = new Ajax();
  ajax.responseType = Ajax.JSON;

  switch(evt.target.getId()) {
    case prefixString + '-confirm-pay-submit':
      ajax.ondone = function() {
        var empty = [];
        drawTrack(parseInt(y1), parseInt(x1), parseInt(y2), parseInt(x2), '#FF0', empty);
//new Dialog().showMessage('test', 'balance='+balance);
        balance = balance - parseInt(cost);
        setHtmlBalance(balance);
        saveCityStartElem.setSrc(publicURL + '/images/city_marker.gif');
        saveCityStartElem = null;
        var actionPrompt = document.getElementById('action-prompt');
        var innerHtml = '<span><div id="action-text">Build Track: Select a city where track building should begin</div>'+
                        '<div id="action-end">'+
                        '<form action="">'+
                        '<input type="button" value="End Track Building" id="next-phase" onClick="moveTrainAuto()" />'+
                        '</form>'+
                        '</div></span>';
        actionPrompt.setInnerXHTML(innerHtml);
        var btn = document.getElementById('next-phase');
        btn.addEventListener('click', moveTrainAutoEvent);
        state = TRACK_CITY_START;
      }
      ajax.onerror = function() {
        new Dialog().showMessage('Track Building Error', 'An error occured while building this track. Please try again.');
      }
      ajax.post(baseURL + '/turn/build-track-confirmed', {"europass_used": 0});
      break;

    case prefixString + '-cancel-pay-submit':
      saveCityStartElem.setSrc(publicURL + '/images/city_marker.gif');
      saveCityStartElem = null;
      var actionPrompt = document.getElementById('action-prompt');
      var innerHtml = '<span><div id="action-text">Build Track: Select a city where track building should begin</div>'+
                      '<div id="action-end">'+
                      '<form action="">'+
                      '<input type="button" value="End Track Building" id="next-phase" onClick="moveTrainAuto()" />'+
                      '</form>'+
                      '</div></span>';
      actionPrompt.setInnerXHTML(innerHtml);
      var btn = document.getElementById('next-phase');
      btn.addEventListener('click', moveTrainAutoEvent);
      state = TRACK_CITY_START;
      ajax.post(baseURL + '/turn/build-track-resume');
      break;

    case prefixString + '-europass-pay-submit':
      ajax.ondone = function() {
        var empty = [];
        drawTrack(parseInt(y1), parseInt(x1), parseInt(y2), parseInt(x2), '#FF0', empty);
//new Dialog().showMessage('test', 'balance='+balance);
        saveCityStartElem.setSrc(publicURL + '/images/city_marker.gif');
        saveCityStartElem = null;
        var actionPrompt = document.getElementById('action-prompt');
        var innerHtml = '<span><div id="action-text">Build Track: Select a city where track building should begin</div>'+
                        '<div id="action-end">'+
                        '<form action="">'+
                        '<input type="button" value="End Track Building" id="next-phase" onClick="moveTrainAuto()" />'+
                        '</form>'+
                        '</div></span>';
        actionPrompt.setInnerXHTML(innerHtml);
        var btn = document.getElementById('next-phase');
        btn.addEventListener('click', moveTrainAutoEvent);
        state = TRACK_CITY_START;
      }
      ajax.onerror = function() {
        new Dialog().showMessage('Track Building Error', 'An error occured while building this track. Please try again.');
      }
      ajax.post(baseURL + '/turn/build-track-confirmed', {"europass_used": 1});
      break;
  }
}
function cargoEventHandler(evt) {
  //new Dialog().showMessage('loadNewCargo', 'city id='+cityId+', train id='+trainId);
//debugger;
  var cityId = evt.target.cityId;
  var trainId = evt.target.trainId;
  var prefixString = evt.target.prefixString;

  evt.target.loadCargoDialog.hide();

  switch(evt.target.getId()) {
    case prefixString + '-load-new-submit':
//debugger;
      ajax = new Ajax();
      ajax.responseType = Ajax.JSON;
      param = { 'load-cargo-submit': "Load new goods", 'city-id': cityId, 'train-id': trainId };
      ajax.ondone = function(data) {
        openCargoHolds = data.openCargoHolds;
        cargoHoldsUsed = 0;
        ajax.responseType = Ajax.FBML;
        param = { 'openCargoHolds': data.openCargoHolds, 'cityGoods': data.cityGoods, 'trainId': data.trainId };
        ajax.ondone = function(fbjsData) {
    //debugger;
          var dialog = new Dialog().showChoice('Load Cargo', fbjsData, 'Load cargo', 'Cancel');
          var numGoods = data.cityGoods.length;
          for(var i = 1; i <= numGoods; i++) {
            var decrementGoodsArrow = document.getElementById('goods-decrement-' + i);
            decrementGoodsArrow.addEventListener('click', goodsAdjustmentHandler);
            var incrementGoodsArrow = document.getElementById('goods-increment-' + i);
            incrementGoodsArrow.addEventListener('click', goodsAdjustmentHandler);
          }
          dialog.onconfirm = function() {
//debugger;
            var goods = [];
            var goodsIds = [];
            numGoods = document.getElementById('goods-count').getValue();
            for(var i = 0; i < numGoods; i++) {
              j = i + 1;
              goods[i] = document.getElementById('goods-' + j).getValue();
              goodsIds[i] = document.getElementById('goods-id-' + j).getValue();
            }
            var trainId = document.getElementById('train-id').getValue();
            param = { "goods": goods, "goods-id": goodsIds, "train-id": trainId };
            ajax.responseType = Ajax.JSON;
            ajax.ondone = function(data) {
              loadCargo();
            }
            ajax.onerror = function() {
              var dialog = new Dialog().showMessage('Request taking too long', 'The system is taking too long to process this request. Please try refreshing the page. If this does not work, please Contact Us with a description of your problem. We are sorry for the inconvenience.');
            }
            ajax.post(baseURL + '/turn/do-load-cargo-new', param);
            //dialog.hide();
          };
          dialog.oncancel = function() {
            loadCargo();
          }
        }
        ajax.post(baseURL + '/turn/load-cargo-new-dialog-fbjs', param);
      }
      ajax.post(baseURL + '/turn/load-cargo-select', param);
      break;
    case prefixString + '-discard-existing-submit':
      ajax = new Ajax();
      ajax.responseType = Ajax.JSON;
      param = { 'load-cargo-submit': "Discard existing goods", 'city-id': cityId, 'train-id': trainId };
      ajax.ondone = function(data) {
        ajax.responseType = Ajax.FBML;
        param = { 'openCargoHolds': data.openCargoHolds, 'trainGoods': data.trainGoods, 'trainId': data.trainId };
        ajax.ondone = function(fbjsData) {
          var dialog = new Dialog().showChoice('Discard Cargo', fbjsData, 'Discard cargo', 'Cancel');
          dialog.onconfirm = function() {
//debugger;
            var goods = [];
            var goodsIds = [];
            numGoods = document.getElementById('goods-count').getValue();
            for(var i = 0; i < numGoods; i++) {
              j = i + 1;
              goods[i] = document.getElementById('goods-' + j).getValue();
              goodsIds[i] = document.getElementById('goods-id-' + j).getValue();
            }
            var trainId = document.getElementById('train-id').getValue();
            param = { "goods": goods, "goods-id": goodsIds, "train-id": trainId };
            ajax.responseType = Ajax.JSON;
            ajax.ondone = function(data) {
              loadCargo();
            }
            ajax.post(baseURL + '/turn/do-load-cargo-discard', param);
            //dialog.hide();
          };
          dialog.oncancel = function() {
            loadCargo();
          }
        }
        ajax.post(baseURL + '/turn/load-cargo-discard-dialog-fbjs', param);
      }
      ajax.post(baseURL + '/turn/load-cargo-select', param);
      break;
  }
  return true;
}

最佳答案

任何人都需要一段时间才能理解您的代码,因此我认为为您的具体情况提供准确的代码示例有点困难,但对于一些一般性想法...

例如,教程中的每个步骤都可以有一组要求。单击此按钮,执行此操作。因此,要知道用户何时做了某事,您需要在这些操作上添加事件监听器并让它们更改当前“步骤”的状态。

一旦您的步骤的要求得到满足,它就会被下一步简单地替换掉。此时,事件处理程序等将更新以跟踪新步骤的要求。

例如,假设您有一个步骤,用户必须在其中构建一条从 A 到 B 的轨道,然后让火车通过它。在这种情况下,您可能会要求火车必须开往 A,然后再开往 B。因此您的游戏应该在火车到达指定车站时发生某种事件,并且您会跟踪该事件。

希望这对您有所帮助。

关于javascript - 创建 Javascript 游戏教程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6405426/

有关javascript - 创建 Javascript 游戏教程的更多相关文章

  1. ruby - 如何在 Ruby 中顺序创建 PI - 2

    出于纯粹的兴趣,我很好奇如何按顺序创建PI,而不是在过程结果之后生成数字,而是让数字在过程本身生成时显示。如果是这种情况,那么数字可以自行产生,我可以对以前看到的数字实现垃圾收集,从而创建一个无限系列。结果只是在Pi系列之后每秒生成一个数字。这是我通过互联网筛选的结果:这是流行的计算机友好算法,类机器算法:defarccot(x,unity)xpow=unity/xn=1sign=1sum=0loopdoterm=xpow/nbreakifterm==0sum+=sign*(xpow/n)xpow/=x*xn+=2sign=-signendsumenddefcalc_pi(digits

  2. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  3. ruby - 使用 Vim Rails,您可以创建一个新的迁移文件并一次性打开它吗? - 2

    使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta

  4. ruby-on-rails - 无法使用 Rails 3.2 创建插件? - 2

    我对最新版本的Rails有疑问。我创建了一个新应用程序(railsnewMyProject),但我没有脚本/生成,只有脚本/rails,当我输入ruby./script/railsgeneratepluginmy_plugin"Couldnotfindgeneratorplugin.".你知道如何生成插件模板吗?没有这个命令可以创建插件吗?PS:我正在使用Rails3.2.1和ruby​​1.8.7[universal-darwin11.0] 最佳答案 随着Rails3.2.0的发布,插件生成器已经被移除。查看变更日志here.现在

  5. ruby - 如何使用 RSpec::Core::RakeTask 创建 RSpec Rake 任务? - 2

    如何使用RSpec::Core::RakeTask初始化RSpecRake任务?require'rspec/core/rake_task'RSpec::Core::RakeTask.newdo|t|#whatdoIputinhere?endInitialize函数记录在http://rubydoc.info/github/rspec/rspec-core/RSpec/Core/RakeTask#initialize-instance_method没有很好的记录;它只是说:-(RakeTask)initialize(*args,&task_block)AnewinstanceofRake

  6. ruby - 为什么 SecureRandom.uuid 创建一个唯一的字符串? - 2

    关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion为什么SecureRandom.uuid创建一个唯一的字符串?SecureRandom.uuid#=>"35cb4e30-54e1-49f9-b5ce-4134799eb2c0"SecureRandom.uuid方法创建的字符串从不重复?

  7. ruby - 有人可以帮助解释类创建的 post_initialize 回调吗 (Sandi Metz) - 2

    我正在阅读SandiMetz的POODR,并且遇到了一个我不太了解的编码原则。这是代码:classBicycleattr_reader:size,:chain,:tire_sizedefinitialize(args={})@size=args[:size]||1@chain=args[:chain]||2@tire_size=args[:tire_size]||3post_initialize(args)endendclassMountainBike此代码将为其各自的属性输出1,2,3,4,5。我不明白的是查找方法。当一辆山地自行车被实例化时,因为它没有自己的initialize方法

  8. ruby - 使用多个数组创建计数 - 2

    我正在尝试按0-9和a-z的顺序创建数字和字母列表。我有一组值value_array=['0','1','2','3','4','5','6','7','8','9','a','b','光盘','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','','u','v','w','x','y','z']和一个组合列表的数组,按顺序,这些数字可以产生x个字符,比方说三个list_array=[]和一个当前字母和数字组合的数组(在将它插入列表数组之前我会把它变成一个字符串,]current_combo['0','0','0']

  9. Observability:从零开始创建 Java 微服务并监控它 (二) - 2

    这篇文章是继上一篇文章“Observability:从零开始创建Java微服务并监控它(一)”的续篇。在上一篇文章中,我们讲述了如何创建一个Javaweb应用,并使用Filebeat来收集应用所生成的日志。在今天的文章中,我来详述如何收集应用的指标,使用APM来监控应用并监督web服务的在线情况。源码可以在地址 https://github.com/liu-xiao-guo/java_observability 进行下载。摄入指标指标被视为可以随时更改的时间点值。当前请求的数量可以改变任何毫秒。你可能有1000个请求的峰值,然后一切都回到一个请求。这也意味着这些指标可能不准确,你还想提取最小/

  10. postman接口测试工具-基础使用教程 - 2

    1.postman介绍Postman一款非常流行的API调试工具。其实,开发人员用的更多。因为测试人员做接口测试会有更多选择,例如Jmeter、soapUI等。不过,对于开发过程中去调试接口,Postman确实足够的简单方便,而且功能强大。2.下载安装官网地址:https://www.postman.com/下载完成后双击安装吧,安装过程极其简单,无需任何操作3.使用教程这里以百度为例,工具使用简单,填写URL地址即可发送请求,在下方查看响应结果和响应状态码常用方法都有支持请求方法:getpostputdeleteGet、Post、Put与Delete的作用get:请求方法一般是用于数据查询,

随机推荐