チャッ♪チャッ♪チャージャー♪

Splathon Advent Calendar 2020 の3日目の記事になります。
昨日は TONY0922 さんの 英語コーチングサービスを受けて約50万溶かした話 でした。

恒例のゼルダBotWのany%RTAの最新状況ですが、2020年12月3日現在の世界記録は26分42.4秒だそうです。
去年から1分以上も縮まっていて時の流れを感じます。
意味がよくわからない人は過去記事をご参照ください。

チャージャー楽しいですよっていう記事

皆さんチャージャー使ってますか?
僕は最近チャージャーにハマっていてガチマッチでもメインで使っています。
今回はその魅力を皆さんにお伝えできればなと思い記事を執筆するに至った所存です。

ウデマエはエリアなら2400を超えるぐらいにはなってきました(先月)。
ただ計測後ダダ下がりしたので現在のXパワーについては聞かないでください。
フレンド申請も送ってこないでください。

続きを読む

カジュアルゲーマーを目指して

f:id:saihoooooooo:20191107203609j:plain

Splathon Advent Calendar 2019 の3日目の記事になります。

去年はゼルダBotWのRTAに関する記事を書きましたが今回は普通にスプラトゥーンのTIPSな記事を書きたいと思います。
ちなみに前回当時に約31分だったRTA世界記録は27分53.500秒!!と30分を大きく上回る更新となっているので興味のある方は是非御覧ください。

カジュアルについて

さて、本題ですがタイトルにあるカジュアルゲーマーは読んで字の如く「カジュアルなゲーム」をプレイする人の意味で使っています。
では「カジュアルなゲーム」とは一体何なのか。
これはスプラトゥーン有名プレイヤーのゆっきー氏がとある配信でバブルランチャーの即割でキルされて試合に敗けた際に「カジュアルなゲームになったなぁ」と(自身の持ちブキであるロングブラスターが通用しづらいことも含め)その環境を揶揄したのが発端となり、スプラ界隈でバズった言葉です。

ここからバブル即割そのものを「カジュアル」と呼ぶことも多くなり、ボディビルダーの大会のごとく「ナイスカジュアル!」と味方からの掛け声を貰うことが増えました。
厳密にはおちばシューターによるトーピード即割なのでしょうが、今回は私がここ最近気に入っているボトルガイザーフォイルによるスプラッシュボムでの即割を解説したいと思います。

続きを読む

TypeScriptでアプリのバージョンを取ってくる

例えばAngularでアプリを作っていて、package.json

{
  "name": "super-sharp-spa",
  "version": "0.0.1",
  ...
}

などと書いている場合。

resolveJsonModuleを使えば型定義もなしにjsonの内容をそのままオブジェクトとして取得できる。

www.typescriptlang.org

具体的には下記のように使う。

{
  ...
  "compilerOptions": {
    ...
    "resolveJsonModule": true,
    "esModuleInterop": true
  }
}
import packagejson from '/path/to/package.json';

console.log(packagejson.version); // 0.0.1

便利。

Ionic v3自作プラグインの基礎

Ionic Advent Calendar 2018 の17日目の記事になります。

Ionic界隈ではv4だのCapacitorだので盛り上がっていますが、最近書く機会があったので備忘録程度にv3にて自作プラグイン(Cordova)を追加する方法を書きたいと思います。

プロジェクトの作成

はじめにプロジェクトを作成します。

$ ionic start myApp tabs
$ cd myApp

Cordovaプラグインの作成

次に plugman を使ってCordovaプラグインの雛形を作ります。
入っていない場合はインストールしてください。

$ npm install -g plugman

自作プラグインの作業場所として適当に plugins_src ディレクトリを作ります。
ディレクトリに入り plugman create コマンドを使ってプラグインを作成します。

$ mkdir plugins_src
$ plugman create --name Hoge --plugin_id cordova-plugin-hoge --plugin_version 0.0.0 --path plugins_src

その後 plugman platform add コマンドにてプラットフォームを追加します。
今回はAndroidプラグインを作りますが、iOSの場合は適宜書き換えてください。

$ cd plugins_src/Hoge
$ plugman platform add --platform_name android

結果、下記のような構成が出来ます。

  • plugin.xml プラグインの設定
  • src/android/Hoge.java 実際のAndroidのコードを記述する
  • www/Hoge.js Webviewとのインターフェース
plugins_src/Hoge/
├── plugin.xml
├── src
│   └── android
│       └── Hoge.java
└── www
    └── Hoge.js

中身はこんな感じです。coolMethod、なんてクールな名前なんだ。
やってることは渡ってきた文字列をそのまま返しているだけですね。

<?xml version='1.0' encoding='utf-8'?>
<plugin id="cordova-plugin-hoge" version="0.0.0" xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android">
    <name>Hoge</name>
    <js-module name="Hoge" src="www/Hoge.js">
        <clobbers target="cordova.plugins.Hoge" />
    </js-module>
    <platform name="android">
        <config-file parent="/*" target="res/xml/config.xml">
            <feature name="Hoge">
                <param name="android-package" value="cordova-plugin-hoge.Hoge" />
            </feature>
        </config-file>
        <config-file parent="/*" target="AndroidManifest.xml">
        </config-file>
        <source-file src="src/android/Hoge.java" target-dir="src/cordova-plugin-hoge/Hoge" />
    </platform>
</plugin>
var exec = require('cordova/exec');

exports.coolMethod = function (arg0, success, error) {
    exec(success, error, 'Hoge', 'coolMethod', [arg0]);
};
package cordova-plugin-hoge;

import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CallbackContext;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

/**
 * This class echoes a string called from JavaScript.
 */
public class Hoge extends CordovaPlugin {

    @Override
    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
        if (action.equals("coolMethod")) {
            String message = args.getString(0);
            this.coolMethod(message, callbackContext);
            return true;
        }
        return false;
    }

    private void coolMethod(String message, CallbackContext callbackContext) {
        if (message != null && message.length() > 0) {
            callbackContext.success(message);
        } else {
            callbackContext.error("Expected one non-empty string argument.");
        }
    }
}

今回はこれをちょっと編集してメソッドの実行時に一瞬バイブするよう書き換えたいと思います。
ついでにパッケージ名を変更。

     <platform name="android">
         <config-file parent="/*" target="res/xml/config.xml">
             <feature name="Hoge">
-                <param name="android-package" value="cordova-plugin-hoge.Hoge" />
+                <param name="android-package" value="com.example.hoge.Hoge" />
             </feature>
         </config-file>
         <config-file parent="/*" target="AndroidManifest.xml">
+            <uses-permission android:name="android.permission.VIBRATE" />
         </config-file>
         <source-file src="src/android/Hoge.java" target-dir="src/cordova-plugin-hoge/Hoge" />
     </platform>
-package cordova-plugin-hoge;
+package com.example.hoge;

 import org.apache.cordova.CordovaPlugin;
 import org.apache.cordova.CallbackContext;
@@ -7,6 +7,9 @@ import org.json.JSONArray;
 import org.json.JSONException;
 import org.json.JSONObject;

+import android.content.Context;
+import android.os.Vibrator;
+
 /**
  * This class echoes a string called from JavaScript.
  */
@@ -24,6 +27,7 @@ public class Hoge extends CordovaPlugin {

     private void coolMethod(String message, CallbackContext callbackContext) {
         if (message != null && message.length() > 0) {
+            ((Vibrator) cordova.getActivity().getSystemService(Context.VIBRATOR_SERVICE)).vibrate(100);
             callbackContext.success(message);
         } else {
             callbackContext.error("Expected one non-empty string argument.");

最後にプラグインのインストール時に必要となるpackage.jsonを下記のコマンドで作成します。

$ plugman createpackagejson .

CordovaプラグインのIonic Native化

これでCordovaプラグインは完成しましたがIonicで使うためにIonic Native化(Typescript化)します。
任意の場所に ionic-team/ionic-native を置きます。
今回は例として本家を直接サブモジュール化していますが実際使うならフォークしたものを使用してください。
gulp plugin:create -n [プラグイン名]で雛形を作成します。

$ cd ../..
$ git submodule add https://github.com/ionic-team/ionic-native plugins_src/ionic-native
$ cd plugins_src/ionic-native/
$ npm install
$ gulp plugin:create -n Hoge

src/@ionic-native/plugins/hoge/index.tsが出来上がるので下記の様に編集します。
import文はtslintさんが怒ってくるので。

  *
  */
 import { Injectable } from '@angular/core';
-import { Plugin, Cordova, CordovaProperty, CordovaInstance, InstanceProperty, IonicNativePlugin } from '@ionic-native/core';
+import { Cordova, CordovaInstance, CordovaProperty, InstanceProperty, IonicNativePlugin, Plugin } from '@ionic-native/core';
 import { Observable } from 'rxjs/Observable';

 /**
@@ -36,24 +36,23 @@ import { Observable } from 'rxjs/Observable';
  */
 @Plugin({
   pluginName: 'Hoge',
-  plugin: '', // npm package name, example: cordova-plugin-camera
-  pluginRef: '', // the variable reference to call the plugin, example: navigator.geolocation
+  plugin: 'cordova-plugin-hoge', // npm package name, example: cordova-plugin-camera
+  pluginRef: 'cordova.plugins.Hoge', // the variable reference to call the plugin, example: navigator.geolocation
   repo: '', // the github repository URL for the plugin
   install: '', // OPTIONAL install command, in case the plugin requires variables
   installVariables: [], // OPTIONAL the plugin requires variables
-  platforms: [] // Array of platforms supported, example: ['Android', 'iOS']
+  platforms: ['Android'] // Array of platforms supported, example: ['Android', 'iOS']
 })
 @Injectable()
 export class Hoge extends IonicNativePlugin {

   /**
    * This function does something
-   * @param arg1 {string} Some param to configure something
-   * @param arg2 {number} Another param to configure something
+   * @param message {string} Some param to configure something
    * @return {Promise<any>} Returns a promise that resolves when something happens
    */
   @Cordova()
-  functionName(arg1: string, arg2: number): Promise<any> {
+  coolMethod(message: string): Promise<any> {
     return; // We add return; here to avoid any IDE / Compiler errors
   }

ビルドします。
成果物は dist/@ionic-native/hoge に置かれます。
これで準備は整ったのでプロジェクト直下に戻ります。

$ npm run build hoge
$ cd ../..

Ionicで実装

最後に実際に使うIonic側のコードを記述します。
src/app/app.module.ts に登録した後、 src/pages/home/home.ts にメソッドを追加してボタンで呼ぶようにします。

 import { StatusBar } from '@ionic-native/status-bar';
 import { SplashScreen } from '@ionic-native/splash-screen';
+import { Hoge } from '@ionic-native/hoge';

 @NgModule({
   declarations: [
@@ -34,6 +35,7 @@ import { SplashScreen } from '@ionic-native/splash-screen';
   providers: [
     StatusBar,
     SplashScreen,
+    Hoge,
     {provide: ErrorHandler, useClass: IonicErrorHandler}
   ]
 })
 import { Component } from '@angular/core';
 import { NavController } from 'ionic-angular';
+import { Hoge } from '@ionic-native/hoge';

 @Component({
   selector: 'page-home',
@@ -7,8 +8,14 @@ import { NavController } from 'ionic-angular';
 })
 export class HomePage {

-  constructor(public navCtrl: NavController) {
+  constructor(public navCtrl: NavController, public hoge: Hoge) {

   }

+  coolMethod() {
+    this.hoge.coolMethod('aaaa').then(message => {
+      alert(message);
+    });
+  }
+
     Take a look at the <code>src/pages/</code> directory to add or change tabs,
     update any existing page or create new pages.
   </p>
+  <button ion-button (click)="coolMethod()">coolMethod</button>
 </ion-content>

プラグインをインスールして実機で確認。

$ ionic cordova plugin add plugins_src/Hoge
$ npm install plugins_src/ionic-native/dist/@ionic-native/hoge
$ ionic cordova run android --device

COOLMETHODボタンを押すたびに端末がブルブルと震えるようになりました。
やったね。

f:id:saihoooooooo:20181214164955j:plain:w300

まとめ

初歩の初歩ですが割と簡単にできたと思います。
Capacitorだともっと楽にネイティブの機能を呼び出せるっぽいので期待ですね。

ゼルダの伝説BotWのRTAが俺を惹きつけてやまない

※この記事はスプラトゥーンの話題を含みません。
※この記事はゼルダの伝説BotWのネタバレを含みます。

Splathon Advent Calendar 2018 の11日目の記事になります。

まえがき

ゼルダの伝説BotW面白いですね。
「記憶をなくしてもっかいやりたい」なんて声がちらほら聞こえてくる正真正銘のザ・神ゲーです。
僕も発売当時はSplathonの#zeldaチャンネル、#zelda_netabareチャンネルに入り浸り、そしてハイラルに入り浸り、やがて現実との区別がつかなくなり、仕事中にもかかわらず「早く現実(ハイラル)に戻りたい...早く...」と呟きながらポロポロと涙をこぼしていました。

RTAとAny%について

そんなゼルダの伝説BotWの面白さのひとつがとにかく「自由」であるということ。
自由すぎてチュートリアル終了後はストーリーを全無視していきなりラスボスに挑戦することも可能だったりします。
ツール等を使わずに人力でのゲームクリアまでのタイムを競うことをRTA(Real Time Attack)と呼びますが、ゼルダの伝説BotWはとってもRTA向きなゲームだと言えるでしょう。

また一口にRTAと言っても複数のレギュレーションが存在しており、その中でも今回は最も一般的であろうAny%というレギュレーションに注目したいと思います。
これは要するにダンジョンやイベントの進行度、そのルート等を一切考慮しない純粋なクリア時間を競うもので、ゼルダの伝説BotWではオープニングムービーが終わってリンクを操作できるようになった瞬間から魔獣ガノンに最後の光の矢が当たるまでの時間を計測します。

Any%の世界記録

現在の記録は果たしてどれほどなのか、タイムアタックの記録集積サイトのspeedrun.comで確認してみましょう。

続きを読む