プログラミング

へんしん編 PHPポケモン 74

PHP PHPポケモン ポケモン
へんしん編 PHPポケモン 74

へんしんとは

今回はサムネイルに合わせて、特別技の1つ「へんしん」を実装します。 

 

へんしんを使うことで、相手ポケモンをコピーすることができますが、その全てをコピーするわけではありません。コピーできる項目とそうでない項目は以下の通りです。

コピーできる項目

  • ポケモンの種族
  • HP以外のステータス
  • ランク補正
  • 倒した際の努力値
  • 基礎経験値
  • 努力値

コピーできない項目

  • HP
  • レベル
  • ニックネーム
  • 状態異常
  • 状態変化
  • 個体値

 

現在PHPポケモンで実装されている機能をまとめました。本来のポケモン仕様ではHPを除くステータス実数値を引き継ぐことになります。ですが、PHPポケモンでは実数値を保管せず、努力値・個体値・ランク補正を使って計算しているため、こちらは独自の仕様を入れながら作成していきます。

 

へんしん処理の流れ

まずはへんしん処理をする上での流れをまとめましょう。他の技と異なり、変更しなければいけない項目が多く、種族値などポケモンが持つ値を変更してしまうと、バトル終了判定で元に戻す項目が多くなります。そうなると、本来ではなり得ない状態が出来上がってしまうことにも繋がりますので、バトルで使用しているインスタンスを置き換えることで対応します。 

× へんしん後のポケモンに書き換え

○ バトルで使用するインスタンスを置き換え

 

インスタンスを置き換えるために、へんしんを使った際に「へんしん状態のポケモンオブジェクト」を呼び出す必要があります。通常のインスタンス作成では、HPの種族値など変更できない項目がいくつかあるので、こちらはへんしん専用のインスタンス作成処理を追加することで対応します。 

へんしん用インスタンスの作成

 

それでは、1つずつ処理を見ていきましょう。

 

コピーポケモンの作成

まずはコピーポケモンのインスタンス作成処理についてです。現在はポケモンオブジェクトを呼び出す際にレベルの指定のみを引数としていましたが、第2引数を追加して「へんしん」によるオブジェクト生成ができるようにしましょう。

 

 ポケモンクラス(/Classes/Pokemon.php)
// ポケモン
abstract class Pokemon
{
--省略
 
    /**
    * へんしんフラグ
    * @var boolean
    */
    protected $transform_flg = false;
 
    /**
    * インスタンス作成時に実行される処理
    * @param param:mixed
    * @param transform:object|null::Pokemon
    * @return void
    */
    public function __construct($param=null, $transform=null)
    {
        if(is_object($transform)){
            // へんしん用処理
            $this->transform($param, $transform);
        }else{
            // 初期化
            $this->init($param);
        }
    }

 

もし第2引数で対象のポケモンオブジェクトが指定されていた場合、へんしんの特別処理としてtransformのメソッドを呼び出しています。記述量が多いので、こちらはトレイト分けしました。

 

へんしん処理用トレイト(/App/Traits/Class/Pokemon/ClassPokemonTransformTrait.php
<?php
// へんしん処理専用トレイト
trait ClassPokemonTransformTrait
{
 
    /**
    * へんしんによるインスタンスの作成処理
    * @param pokemon:object::Pokemon
    * @param enemy:object::Pokemon
    * @return void
    */
    private function transform(object $pokemon, object $enemy)
    {
        // へんしんでコピーするステータス
        $this->rank = $enemy->getRank();                    # ランク
        $this->iv = $enemy->getIv();                        # 個体値
        $this->ev = $enemy->getEv();                        # 努力値
        $this->move = $enemy->getMove(null, 'array');       # 覚えている技
        // へんしんでコピーされないステータス
        $this->level = $pokemon->getLevel();                # レベル
        $this->sa = $pokemon->getSa();                      # 状態異常
        $this->sc = $pokemon->getSc();                      # 状態変化
        $this->position = $pokemon->getPosition();          # 立場
        $this->nickname = $pokemon->getNickName();          # ニックネーム
        $this->remaining_hp = $pokemon->getRemainingHp();   # 残りHP
        $this->exp = $pokemon->getExp();                    # 現在の経験値
        /**
        * へんしん時に書き換えする処理
        */
        // へんしんフラグ
        $this->transform_flg = true;
        // HPは元ポケモンのステータスを引き継ぐ
        $this->base_stats['HP'] = $pokemon->getBaseStats()['HP'];
        $this->iv['HP'] = $pokemon->getIv()['HP'];
        $this->ev['HP'] = $pokemon->getEv()['HP'];
        // 技の残りPPを5にする
        $this->move = array_map(function($move){
            $move['remaining'] = 5;
            return $move;
        }, $this->move);
        // 覚える技・進化レベルを空にする(念の為)
        $this->level_move = [];
        if(isset($this->evolve_level)){
            $this->evolve_level = null;
        }
    }
}

 

ステータスの実数値を引き継げるように、個体値・努力値は相手ポケモンのものを受け取っていますHPのステータス変更は入らないため、書き換え後に上書きで自ポケモンのものと置き換えています。

また、へんしん後にレベルアップ処理が入った際にも同様の演出ができるように、現在の経験値も元ポケモンから引き継いでいます。

技のPPはへんしん後にオール5になるので、array_mapを使って書き換えています。

 

プロパティの置き換え

現在バトルコントローラーで使用してるポケモンのオブジェクトは、pokemonというプロパティに格納されています。こちらを置き換えることで、元ポケモンのオブジェクトはparty内、バトル用はpokemonというように扱い、元オブジェクトを書き換えることなく処理をします。

 

バトルコントローラー用トレイト(/App/Traits/Controller/BattleControllerTrait.php
/**
* 引き継ぎ処理
* @return void
*/
protected function inheritance()
{
    // バトル状態の引き継ぎ
    if(isset($_SESSION['__data']['battle_state'])){
        $battle_state = unserializeObject($_SESSION['__data']['battle_state']);
        // ターン最初の状態へ初期化
        $battle_state
        ->turnInit();
        // グローバルにセット
        setBattleState($battle_state);
    }else{
        // バトル状態の初期化
        initBattleState();
    }
    // ポケモン番号の引き継ぎ
    $this->order = $_SESSION['__data']['order'];
    // 敵ポケモンの引き継ぎ
    if(isset($_SESSION['__data']['enemy'])){
        $this->enemy = unserializeObject($_SESSION['__data']['enemy']);
        // 前ターンの状態をプロパティに格納
        $this->before['enemy'] = clone $this->enemy;
    }
    // 戦闘中のポケモンをプロパティにセット
    $transform = getBattleState()->getTransform('friend');
    if($transform){
        // へんしん状態の場合はBattleStateからポケモン情報を取得
        $this->pokemon = $transform;
    }else{
        $this->pokemon = $this->party[$this->order];
    }
    // 前ターンの状態をプロパティに格納
    $this->before['friend'] = clone $this->pokemon;
}

 

もしへんしん状態であれば、格納するオブジェクトをパーティーからではなく、バトル状態へ格納したポケモンオブジェクトから参照するように分岐をさせました。

 

バトル状態クラス(/Classes/BattleState.php
<?php
/**
* バトル状態クラス
*/
class BattleState
{
 
--省略
 
    /**
    * へんしん情報
    * @var array
    */
    private $transforms;
 
 
    /**==================================================================
    * 初期化・初期値
    ==================================================================**/
 
    /**
    * 初期化
    * @return void
    */
    public function init() :void
    {
        $this->run = 0;
        $this->dafaultFields();
        $this->dafaultTurnDamages();
        $this->dafaultTransforms();
        $this->dafaultLastMoves();
    }
 
--省略
 
    /**
    * へんしん状態の初期値
    * @return void
    */
    public function dafaultTransforms() :void
    {
        $this->transforms = [
            'friend' => [],
            'enemy' => [],
        ];
    }
 
--省略
    /**==================================================================
    * へんしん状態
    ==================================================================**/
 
    /**
    * へんしん状態の格納
    * @param pokemon:object::Pokemon
    * @param enemy:object::Pokemon
    * @return object::Pokemon
    */
    public function setTransform(object $pokemon, object $enemy): object
    {
        $class = get_class($enemy);
        $this->transforms[$pokemon->getPosition()] = new $class($pokemon, $enemy);
        // へんしん後のポケモンインスタンスを返却
        return $this->transforms[$pokemon->getPosition()];
    }
 
    /**
    * へんしん状態の取得
    * @param position:string::friend|enemy
    * @return mixed
    */
    public function getTransform(string $position)
    {
        return $this->transforms[$position];
    }
   
}

 

へんしん状態でレベルアップ処理や状態異常の処理が入った場合、両方に同じように処理を加える必要があります。なので、こちらはそれぞれ処理終了直前に整合性を取るための処理を追加します。

 

バトルコントローラー用トレイト(/App/Traits/Controller/BattleControllerTrait.php
/**
* バトル結果判定
*
* @return void
*/
private function judgment()
{
    if($this->fainting['friend']){
        // 味方がひんし状態になった
        setMessage('目の前が真っ暗になった');
    }else{
        // 相手がひんし状態になった(味方はひんし状態ではない)
        // 経験値の計算
        $exp = $this->calExp($this->pokemon, $this->enemy);
        // 経験値をポケモンにセット
        $this->party[$this->order]
        ->setExp($exp);
        // 努力値を獲得
        $this->party[$this->order]
        ->setEv($this->enemy->getRewardEv());
        // もしポケモンが「へんしん状態」であれば変更後の状態を引き継ぎ
        if($this->pokemon->checkSc('ScTransform')){
            $this->pokemon
            ->judgmentTransform($this->party[$this->order]);
        }
    }
    // 散らばったお金の取得
    $money = getBattleState()->getMoney();
    if($money){
        setMessage($this->player->getName().'は、'.$money.'円拾った');
        $this->player
        ->addMoney($money);
    }
    // バトル終了判定用メッセージの格納
    setEmptyMessage('battle-end');
}
 
/**
* デストラクタ直前の処理
* @return void
*/
private function checkBeforeDestruct()
{
    $transform = getBattleState()->getTransform('friend');
    // もし「へんしん状態」であれば、残HPと状態異常を元ポケモンに反映
    if($transform){
        $this->party[$this->order]
        ->mirroringTransform($transform);
    }
}

 

へんしん用トレイト(/App/Traits/Class/Pokemon/ClassPokemonTransformTrait.php
/**
* へんしん状態のステータスを元ポケモンに反映させる処理
* @param trans_pokemon:object::Pokemon
* @return void
*/
public function mirroringTransform(object $trans_pokemon)
{
    if($this->checkSc('ScTransform')){
        $this->sa = $trans_pokemon->getSa('all');                 # 状態異常
        $this->remaining_hp = $trans_pokemon->getRemainingHp();   # 残HP
    }
}
 
/**
* バトル判定後の状態をへんしん状態のポケモンに反映させる処理
* @param base_pokemon:object::Pokemon
* @return void
*/
public function judgmentTransform(object $base_pokemon)
{
    $this->ev = $base_pokemon->getEv();         # 努力値
    $this->level = $base_pokemon->getLevel();   # レベル
    $this->exp = $base_pokemon->getExp();       # 経験値
}

 

レベルアップ処理については、パーティー内のオブジェクトに対して直接処理を行い、へんしんポケモンには値のみを引き継ぐようにしています。

状態異常と残りHPはへんしんポケモンを基準として、パーティー内の元ポケモンに値を反映させました。これで、両方が同じ状態で進行するように整合性を保っています。

 

次に、バトル処理中のオブジェクトについてです。もしへんしんを先手で発動した場合、防御ターンにそのタイプやステータスが反映されている必要があります。オブジェクトは参照されていますが、プロパティの値そのものが変更される場合は、既に配列に格納されたオブジェクトからはアクセスができなくなってしまいます。

なので、バトル処理内でも「へんしん」が行われたかを判定するための分岐を追加して、プロパティ自体を変更しましょう。

 

たたかう用サービス(/App/Services/Battle/FightService.php
/**
* 行動順に攻撃処理
*
* @return boolean (false: ひんしポケモン有り)
*/
private function actionAttack($orders)
{
    foreach($orders as list($atk, $def, $move)){
        // 攻撃ポケモンの怒り解除
        $atk->releaseSc('ScRage');
        // 先手が「へんしん」を使って成功した場合のオブジェクト置き換え処理
        if(!$def->getTransformFlg() && $def->checkSc('ScTransform')){
            // 防御ポケモンのへんしんフラグがfalse且つ、状態変化で「へんしん」がセットされている場合
            $def = $this->battle_state
            ->getTransform($def->getPosition());
        }
        // 攻撃(返り値に使用した技を受け取る)
        $attack_move = $this->attack($atk, $def, $move);
        // 最後に使用した技を格納
        $this->battle_state
        ->setLastMove($atk->getPosition(), $attack_move);
        // バトル終了のレスポンスチェック(交代技など)
        if(getResponse('end')){
            break;
        }
        // ひんしチェック
        $this->fainting = [
            $atk->getPosition() => $this->checkFainting($atk),
            $def->getPosition() => $this->checkFainting($def),
        ];
        // どちらかがひんし状態なら処理終了
        if($this->fainting['friend'] || $this->fainting['enemy']){
            $result = false;
            break;
        }
    } # endforeach
    // 結果返却
    return $result ?? true;
}

 

これで、プロパティの値を変更する処理が整いました。

 

へんしんの特別処理

次に、へんしんを使った際の特別処理を見ていきましょう。まずは、技クラスと状態変化クラスについてです。

 

へんしん:技(/Classes/Move/MoveTransform.php
<?php
$root_path = __DIR__.'/../..';
require_once($root_path.'/Classes/Move.php');
 
// へんしん
class MoveTransform extends Move
{
 
    /**
    * 正式名称
    * @var string
    */
    protected $name = 'へんしん';
 
    /**
    * 説明文
    * @var string
    */
    protected $description = '相手のポケモンに変身する。';
 
    /**
    * タイプ
    * @var string
    */
    protected $type = 'TypeNormal';
 
    /**
    * 分類
    * @var string(physical:物理|special:特殊|status:変化)
    */
    protected $species = 'status';
 
    /**
    * 威力
    * @var integer|null
    */
    protected $power = null;
 
    /**
    * 命中率
    * @var integer|null
    */
    protected $accuracy = null;
 
    /**
    * 使用回数
    * @var integer
    */
    protected $pp = 10;
 
    /**
    * 対象
    * @var string
    */
    protected $target = 'enemy';
 
    /**
    * へんしんの専用効果
    * @param atk:object::Pokemon
    * @param def:object::Pokemon
    * @param battle_state:object::BattleState バトル状態
    * @return void
    */
    public function exTransform(object $atk, object $def, object $battle_state)
    {
        if(!$atk->checkSc('ScTransform')){
            // 現在へんしん状態でなければ実行
            $atk->setSc('ScTransform', 0, get_class($def)); # 先に状態変化(へんしん)をセット
            $battle_state->setTransform($atk, $def);
            return true;
        }else{
            // 現在へんしん状態であれば失敗
            return false;
        }
    }
 
}

 

へんしん:状態変化(/Classes/StateChange/ScTransform.php
<?php
$root_path = __DIR__.'/../..';
require_once($root_path.'/Classes/StateChange.php');
 
// へんしん
class ScTransform extends StateChange
{
 
    /**
    * 正式名称
    * @var string
    */
    protected $name = 'へんしん';
 
}

 

へんしんオブジェクトを作成する際に状態変化をコピーしているため、オブジェクト生成前に状態変化をセットしています。へんしんループを防ぐために、PHPポケモンではへんしん状態からのへんしんは失敗するようにしました。

 

次に、攻撃トレイト内での処理について見てみましょう。

 

攻撃トレイト(/App/Traits/Service/Battle/ServiceBattleAttackTrait.php
// attackメソッド内
//
// 攻撃メッセージを格納
$this->atk_msg_id = issueMsgId();
setMessage(
    $atk_pokemon->getPrefixName().'は'.$move->getName().'を使った!',
    $this->atk_msg_id
);
// 「へんしん」の特別処理
if(get_class($move) === 'MoveTransform'){
    $this->exTransform($atk_pokemon, $def_pokemon, $move);
    return $move;
}

 

へんしん使用メッセージは必要になるため、攻撃メッセージ生成直後に返信の特別処理を呼び出しています。

 

特別処理用トレイト(/App/Traits/Service/Battle/ServiceBattleExTrait.php
/**
* へんしんの特別処理
*
* @param atk:object::Pokemon
* @param def:object::Pokemon
* @param move:object::Move
* @return void
*/
protected function exTransform(object $atk, object $def, object $move): void
{
    // へんしんの特別処理を呼び出し
    $result = $move->exTransform($atk, $def, $this->battle_state);
    if($result){
        // へんしん
        setResponse([
            'param' => get_class($def),
            'action' => 'transform',
            'target' => $atk->getPosition(),
        ], $this->atk_msg_id);
        // 成功
        setMessage($atk->getPrefixName().'は'.$def->getName().'にへんしんした');
        // プロパティの書き換え
        if($atk->getPosition() === 'friend'){
            // 味方
            $this->pokemon = $this->battle_state
            ->getTransform('friend');
        }else{
            // 相手
            $this->enemy = $this->battle_state
            ->getTransform('enemy');
        }
    }else{
        // 失敗
        setMessage('しかし上手く決まらなかった');
    }
}

 

へんしん後はポケモンの画像を変更する必要があるので、レスポンスには対象ポケモンのクラス名、actiontransformtargetに自身を選択しています。サービス自体のプロパティの置き換え処理は、このタイミングで行っています。

 

画像の置き換え

次に画像の置き換え処理についてです。こちらはjsでレスポンスの値に合わせてsrcを書き換えます。現在のポケモンの判定がしやすいように、data要素として現在のポケモンクラスを持たせました。

 

バトル画面(/Resources/Page/Battle.php
<?php # 自ポケモン詳細 ?>
<div class="col-6 text-center">
    <input type="image"
    id="friend-pokemon-image"
    class="action-img-btn"
    src="/Assets/img/pokemon/dots/back/<?=get_class($before_pokemon)?>.gif"
    alt="<?=$before_pokemon->getName()?>"
    data-pokemon="<?=get_class($before_pokemon)?>"
    data-toggle="modal"
    data-target="#friend-battle-state-modal" />
</div>

 

バトルメッセージ用JS/Public/Assets/js/Battle/message.js
// ==============================================
// へんしん処理 =================================
//
/**
* @param json
* @return Promise
**/
var doAnimateTransform = function (target, param){
    return new Promise ((resolve, reject) => {
        // 対象のポケモン画像を指定
        var img = $('#' + target + '-pokemon-image');
        // へんしん前のポケモンクラスを取得
        var before = img.data('pokemon');
        // srcを書き換える
        var src = img.attr('src').replace(before, param);
        img.attr('src', src);
        resolve();
    });
}

 

メッセージのアクション分岐にtransformを追加し、へんしん用のアニメーション処理へ分岐させるようにしました。jsでの処理は画像を変更するだけなので、受け取ったポケモンクラスを、現在のポケモンクラスと置き換えるように、srcに対してreplaceをして新しい画像パスへと変更しています。

 

では、実際にへんしんによる技効果を見てみましょう。

 

しっかり対象ポケモンにへんしん、技を引き継ぐことができました。

 

メタモンの作成

へんしんを追加することができたので、ここで久々に新しいポケモン「メタモン」を追加しましょう。

 

メタモン(/Classes/Pokemon/Metamon.php
<?php
require_once(__DIR__.'/../Pokemon.php');
 
// メタモン
class Metamon extends Pokemon
{
 
    /**
    * 正式名称
    * @var string(min:1 max:5)
    */
    protected $name = 'メタモン';
 
    /**
    * ニックネーム
    * @var string(min:1 max:5)
    */
    protected $nickname = '';
 
    /**
    * タイプ
    * @var array
    */
    protected $types = ['TypeNormal'];
 
    /**
    * 初期レベル
    * @var array
    */
    protected $default_level = [
        5
    ];
 
    /**
    * 基礎経験値
    * @var integer
    */
    protected $base_exp = 101;
 
    /**
    * レベルアップで覚える技
    * @var array
    */
    protected $level_move = [
        [1, 'MoveTransform'],             # へんしん
    ];
 
    /**
    * 種族値
    * @var array
    */
    protected $base_stats = [
        'HP' => 48,
        'Attack' => 48,
        'Defense' => 48,
        'SpAtk' => 48,
        'SpDef' => 48,
        'Speed' => 48,
    ];
 
    /**
    * 獲得努力値
    * @var array
    */
    protected $reward_ev = [
        'HP' => 1,
    ];
 
}

 

技はへんしんのみです。実際に相手がへんしんを使った場合でも、正常な処理がされるかどうかを検証するために用意しました。では、相手ポケモンとしてメタモンを登場させて戦ってみましょう。

  

こちらが持っている技をコピーして戦っていることが確認できました。へんしん後は獲得努力値と経験値も引き継いでいるため、それぞれが高いポケモンで挑めば効率よく稼ぐことができます。しかし技構成がコピーされてしまうため、HPの状態やレベル、急所の発動頻度によっては自分の首を締める結果にもなるので注意が必要です。

 

メタモンについては、近々本番環境へも反映予定ですので、ぜひ遊んでみてくださいね。

 

まとめ

いかがだったでしょうか。

今回のPHPポケモンでは「へんしん」の実装方法をご紹介しました。

ポケモンに興味がある方、プログラミング学習に挑戦しようと考えている方は、ぜひ参考にしてみてくださいね。

 

注目の記事

PHPポケモン「レスポンス機能編」メッセージの返却 12
プログラミング
PHP,PHPポケモン,ポケモン
PHPポケモン「レスポンス機能編」メッセージの返却 12

  第12回PHPポケモンは「レスポンス機能編」です。 メッセージやデータのやり取り部分を、よりシステム風に作成していきます。   第1回はコチラ   レスポンス(Response)の実装  今までは結果(メッセージ等)はechoを使って出力していましたが処理が行われたタイミングで出力されてしまうため...

【無料】早起きをして神戸へ行こう!「為になる雑談朝活」
イベント
三宮,朝活,神戸
【無料】早起きをして神戸へ行こう!「為になる雑談朝活」

  朝活を実施することになりましたので、その目的な概要をまとめました。 神戸三宮での開催を予定しておりますので、もしお近くにお住まいの方で日時が会いましたらご参加ください。 土日祝辺りで週1日程度の不定期開催を予定しています。学びにつながる、けど参加しやすい雑談形式ということを主としています...

PHPポケモン「タイプ実装編」15
プログラミング
PHP,PHPポケモン,ポケモン
PHPポケモン「タイプ実装編」15

ポケモンのタイプについて  2020年剣盾シリーズでのポケモンでは、全18タイプが実装されています。初代では15タイプ(あく、はがね、フェアリーを除く)からスタートして、たった3つのタイプしか増えていない、と感じる方もいるかも知れませんが、この追加に関してもバトルの歴史を大きく動かしてきたのです...

両隣のポケモン取得編(配列の隣の要素)PHPポケモン 92
プログラミング
PHP,PHPポケモン,ポケモン
両隣のポケモン取得編(配列の隣の要素)PHPポケモン 92

両隣のポケモンを判別する パーティーの中からID指定でポケモンを特定するためのメソッドは実装されていましたが、その両隣にどんなポケモンが控えているのかを判別する手段がありませんでしたね。 なので、今回は両隣のポケモンを判別するためのメソッドを準備して活用していきましょう。   パーティー まずは...

データベース定義は超重要!システム開発を始める前に知っておきたい構造と構成の考え方
プログラミング
MySQL,データベース,プログラミング学習
データベース定義は超重要!システム開発を始める前に知っておきたい構造と構成の考え方

  システムやアプリ開発をする場合、そのほとんどでデータベースを使用しますね。 それぞれのデータを連携させるためにも、その構造をどうするかは重要で、設計が甘ければシステムそのものの保守性はもちろん、想定していた仕組みを実現するのが難しくなることもあります。   今回は、これからデータベースを...

PHPポケモン(α)攻略wiki「最初のポケモン」
雑記
PHPポケモン,wiki,ポケモン
PHPポケモン(α)攻略wiki「最初のポケモン」

リリースから一ヶ月、遂にPHPポケモン(α)の攻略Wiki(仮)が公開です!   というのは大嘘で、内部の大幅変更の関係上、今回はPHPポケモンをプレイするにあたってのオススメなどをまとめて見た次第です。 ちなみに、バトルシステム自体は本家に沿って作成しているので、種族値や技性能に精通している人はブラウザ...

わざマシン編 作成 PHPポケモン104
プログラミング
PHP,PHPポケモン,ポケモン
わざマシン編 作成 PHPポケモン104

わざマシンとは ポケモンはレベルアップ以外でも技を習得することができます。それが「わざマシン」というアイテムです。  わざマシン(ポケモンwiki) https://wiki.ポケモン.com/wiki/わざマシン   最新世代では「技レコード」というものが有り、使い切りとなっています。初代ではわざマシン自体も使い...

ブラウザで遊べる「PHPポケモン」
プログラミング
PHP,PHPポケモン,ポケモン
ブラウザで遊べる「PHPポケモン」

PHPポケモン 約1ヶ月半をかけて作り込んできたPHPポケモンですが、ある程度遊べるぐらいのレベルになったので、みなさまにも体験・楽しんでいただけるよう本日(2020年10月12日)より一般公開します。   PHPポケモンへのリンクは本記事の最後に用意しておりますので、プレイする前に注意事項等に目を通し...

カテゴリ

SEO対策 イベント デザイン ネットワーク ビジネスモデル フリーランス プログラミング マーケティング ライティング 動画編集 雑記

タグ

5G Adobe AfterEffects AI ajax amazon Animate api artisan atom Automator AWS Bluetooth CSS CVR description EC-CUBE4 ECショップ ESLint Facebook feedly foreach function Google Google AdSense Honeycode htaccess HTML IEEE 802.11ax Illustrator Instagram IoT JavaScript jQuery jQuery UI keyword LAN Laravel Linux MacBook MAMP meta MLM MySQL NoCode note OS OSI参照モデル Paypal Photoshop PHP phpMyAdmin PHPポケモン PremierePro rss SEO SEO対策 Sequel Pro Skype SNS SSH Symfony TCP/IP title Toastr Trait Twig Twitter UCC V系 WAN WebSub Wi-Fi wiki Windows WordPress XAMPP xml Xserver YouTube YouTuber Zoom アーティスト アウトプット アクセス層 アニメーション アフィリエイト イーブイ インターネット インプット エンジニア オブジェクト指向 お金配り クリック単価 クリック数 コミュニケーション能力 コロナ コンサルティング サムネイル システムエンジニア スタートアップ スタイルシート スパム データベース ディープフェイク デザイナー デザイン テレワーク ナンパ ニュース ネットワークモデル ノマドワーク バナー ピカチュウ ビジネス フィード フリーランス ブロガー ブログ プログラマー プログラミング プログラミング学習 プログラミング教育 プロトコル ホームページ制作 ポケモン マークアップ マーケティング メール リモートワーク レンダリング 三井住友 三宮 仕事依頼 児童デイ 児童デイサービス 児童発達支援 公開鍵 初心者 助成金 勉強法 営業 広告 広告収入 必勝マニュアル 放課後等デイサービス 朝活 楽天 深層学習 無線LAN 独立 神戸 福祉 秘密鍵 翻訳 自己啓発 英語 見積書 計算機 読書 起業 迷惑メール 配列 銀の弾丸 集客 雑学力