プログラミング

連続攻撃技と一撃必殺技編 PHPポケモン39

PHP PHPポケモン ポケモン
連続攻撃技と一撃必殺技編 PHPポケモン39

連続攻撃技とは

追加効果だけでは処理できない技が、初代に限定していても数多くあります。その一つが「連続攻撃技」です。 

連続攻撃技はさらに4パターンに分かれる。

  1. 攻撃回数が2回固定であるもの
  2. 攻撃回数が3回固定であるもの
  3. 攻撃回数が2回から5回までの間で決まるもの
  4. 攻撃回数が最大3回で外れるまで攻撃するもの

 

急所判定も攻撃のたびなので、少なくとも1回は急所に当たる確率は通常のわざより高い

 

初代の連続攻撃技は「2回固定」と「攻撃回数が2〜5回」のどちらかに分類されます。

それでは、連続攻撃技を実装していきましょう。

 

ヒット回数の算出

それでは、連続攻撃技のサンプルとして「れんぞくパンチ」を実装します。最新世代では無くなってしまった技の1つですが、初代ではしっかりと現存していたで用意しましょう。

 

れんぞくパンチ(/Classes/Move/CometPunch.php
<?php
$root_path = __DIR__.'/../..';
require_once($root_path.'/Classes/Move.php');
 
// れんぞくパンチ
class CometPunch extends Move
{
 
    /**
    * 正式名称
    * @var string
    */
    protected $name = 'れんぞくパンチ';
 
    /**
    * 説明文
    * @var string
    */
    protected $description = '2〜5回連続で攻撃する';
 
    /**
    * タイプ
    * @var string
    */
    protected $type = 'Normal';
 
    /**
    * 分類
    * @var string(physical:物理|special:特殊|status:変化)
    */
    protected $species = 'physical';
 
    /**
    * 威力
    * @var integer
    */
    protected $power = 18;
 
    /**
    * 命中率
    * @var integer
    */
    protected $accuracy = 85;
 
    /**
    * 使用回数
    * @var integer
    */
    protected $pp = 15;
 
    /**
    * 優先度
    * @var integer
    */
    protected $priority = 0;
 
    /**
    * 連続攻撃回数
    *
    * @return integer
    */
    public function times()
    {
        return random_int(2, 5);
    }
 
}

 

他の技との変更点は「times」という技回数取得用のメソッドがあることです。連続攻撃技以外は1回を返せるように、親クラスのmoveにもtimesメソッドを作成しておきましょう。

 

技クラス(/Classes/Move.php
<?php
$root_path = __DIR__.'/..';
require_once($root_path.'/App/Traits/InstanceTrait.php');
require_once($root_path.'/App/Traits/ResponseTrait.php');
 
// 技
abstract class Move
{
    use InstanceTrait;
    use ResponseTrait;
 
--省略
    /**
    * 技回数
    *
    * @return integer
    */
    public function times()
    {
        // デフォルトは1回
        return 1;
    }

 

これでtimesメソッドを使って技回数を取得した際、通常技なら1回、連続攻撃技なら各技クラスに割り当てられた回数を取得することができます。

 

繰り返し処理

次に連続攻撃の繰り返し処理についてです。連続技の場合、算出した回数分攻撃を繰り返すことになりますが、そのままattackメソッドを回数分実行するわけにはいきません。なぜなら、命中判定は毎回実行されるわけではないからです。

※一部の技を除きます

なので、命中判定移行の処理を回数分繰り返しましょう。

 

攻撃用トレイト(/App/Traits/Service/Battle/ServiceBattleTrait.php
/**
* 攻撃
* (攻撃→ダメージ計算→ひんし判定)
*
* @param object $atk_pokemon
* @param object $def_pokemon
* @param object $move
* @return void
*/
protected function attack($atk_pokemon, $def_pokemon, $move)
{
    // (省略)ここで命中判定(checkHit)終了
   
    // 技を回数分実行
    $times = $move->times();
    for($i = 0; $i < $times; $i++){
        // 攻撃判定成功時の処理
        $this->attackSuccess($atk_pokemon, $def_pokemon, $move);
    }
    // 連続技はヒット回数のメッセージを返却
    if($times > 1){
        return $this->setMessage($times.'回当たった');
    }
}

 

ダメージ計算処理を、attackSuccessというメソッドにまとめ、forを使ってループさせました。通常技はtimesメソッドで1回が返ってくるので、ループは1度だけ実行され、連続攻撃技は、取得できた回数分実行されるという仕組みです。

連続攻撃技の場合は、最後にヒット回数をメッセージとして表示するので、取得した回数が1回以上であればメッセージを返却しておきましょう。

 

ダメージ計算補正値の変更

ダメージ計算処理をまとめたattackSuccessメソッドの処理を確認する前に、1点修正をしなければならない箇所があります。それが「補正値」についてです。

今まで、補正値はすべてプロパティ(m)に格納していましたが、これだと連続攻撃の回数分補正値が上書きされてしまいます

例えば、ダメージ計算前に行なっているタイプ一致の補正値や、急所判定などが上書きされてしまえば回数を重ねる度にダメージは大きくなりますし、乱数補正に関しては回数を重ねる毎にダメージ量が減っていくことになります。

そうならないように、attackSuccess内で生成する補正値は$mというローカル変数を用意してそこに格納していきます。

 

攻撃用トレイト(/App/Traits/Service/Battle/ServiceBattleTrait.php
/**
* 攻撃判定成功時の処理
*
* @param object $atk_pokemon
* @param object $def_pokemon
* @param object $move
* @return void
*/
private function attackSuccess($atk_pokemon, $def_pokemon, $move)
{
    // ローカル変数として補正値を用意
    $m = 1;
    // 必要ステータスの取得
    $stats = $this->getStats($move->getSpecies(), $atk_pokemon, $def_pokemon);
    // ダメージ計算
    if($move->getSpecies() !== 'status'){
        /**
        * 物理,特殊技
        */
        if(!is_null($move->getPower())){
            // 急所判定(固定ダメージ技は判定不要)
            $critical = $this->checkCritical($move->getCritical());
            if($critical){
                // 補正値を乗算
                $m *= $critical;
                $this->setMessage('急所に当たった!');
            }
        }
        // 乱数補正値の計算
        $rand = $this->calRandNum();
        if($rand){
            // 補正値を乗算
            $m *= $rand;
        }
        // タイプ一致補正の計算
        $this->calMatchType($move->getType(), $atk_pokemon->getTypes());
        // ダメージ計算
        $damage = $this->calDamage(
            $atk_pokemon->getLevel(),   # 攻撃ポケモンのレベル
            $stats['a'],                # 攻撃ポケモンの攻撃値
            $stats['d'],                # 防御ポケモンの防御値
            $move->getPower(),          # 技の威力
            $this->m * $m,              # 補正値(プロパティ*ローカル)
        );
        // やけど補正
        if(($move->getSpecies() === 'physical') && ($atk_pokemon->getSa() === 'SaBurn')){
            // 物理且つやけど状態ならダメージを半減
            $damage *= 0.5;
        }
        // タイプ相性のメッセージを返却
        $this->setMessage($this->type_comp_msg);
    }else{
        /**
        * 変化技
        */
        $damage = 0;
    }
    // ダメージ計算
    $def_pokemon->calRemainingHp('sub', $damage);
    // 追加効果(相手にHPが残っていれば)
    if($def_pokemon->getRemainingHp()){
        // 追加効果
        $move->effects($atk_pokemon, $def_pokemon);
        // 追加効果のメッセージをセット
        $this->setMessage($move->getMessages());
        $move->resetMessage();
        return;
    }
}

 

メソッドの冒頭で$m(初期値1)を用意しておき、もし補正が発生すればそこに乗算、最終的なダメージ計算時にはプロパティのmとローカル変数の$mを乗算した値を引数に指定しています。

 

これに合わせて、補正値計算のメソッド(急所判定、乱数補正、タイプ一致)の返り値もそれぞれ変更しましょう。

 

攻撃用トレイト(/App/Traits/Service/Battle/ServiceBattleTrait.php
/**
* 急所判定
*
* @param object $move
* @return mixed (numeric|boolean)
*/
private function checkCritical(...$rank)
{
    switch (array_sum($rank)) {
        // 急所ランク+0
        case 0:
        $chance = 4.17; #(%)
        break;
        // 急所ランク+1
        case 1:
        $chance = 12.5; #(%)
        break;
        // 急所ランク+2
        case 2:
        $chance = 50; #(%)
        break;
        // 急所ランク+3以上
        default:
        $chance = 100; #(%)
        break;
    }
    /**
    * 0〜10000からランダムで数値を取得して、それより小さければ急所
    * 確率($chance)は*100して整数で比較する
    */
    if(($chance * 100) >= (mt_rand(0, 10000))){
        // 急所に当たった
        return 1.5;
    }
    // 急所に当たらなかった
    return false;
}
 
/**
* 乱数補正値の計算
*
* @return numeric
*/
private function calRandNum()
{
    // 85〜100の乱数をかけ、その後100で割る
    return (mt_rand(85, 100) / 100);
}
 
/**
* タイプ一致補正値の計算(一致→1.5倍)
*
* @param string $move_type 技タイプ
* @param array $pokemon_types 攻撃ポケモンのタイプ
* @return mixed (numeric|boolean)
*/
private function calMatchType($move_type, $pokemon_types)
{
    if(in_array($move_type, $pokemon_types, true)){
        // 攻撃ポケモンのタイプと技タイプが一致
        return 1.5;
    }
    // タイプ一致ではない
    return false;
}

 

これで補正値が引き継がれてしまうことはありません。それでは実際に技を使って確認してみましょう。

 

 

 

 現状、多弾ヒットしているかどうかはダメージ量でしか計算できませんが、しっかりと回数が表示されていることは確認できました。

 

一撃必殺技とは

ポケモン初代から現在までも引き継がれている歴史的な技の一つに「一撃必殺技」というものがあります。こちらは名前の通り、一撃で相手を倒すことができる技なのですが、一部現状作成した技判定とは異なる部分があります。なので、こちらも別処理を作成しましょう。

一撃必殺技(ポケモンwiki

命中率は低いが、当たればどんなにステータスに差があったとしてもひんしにさせることができるわざが該当する。単に威力の高いわざで相手を一撃で倒したとしても、そのわざは一撃必殺技とはよばれない。命中すると「いちげき ひっさつ!(漢字:一撃必殺!)という特殊なメッセージが表示される。

 

今回の検証では「じわれ」を使います。

 

じわれ(/Classes/Move/Fissure.php
<?php
$root_path = __DIR__.'/../..';
require_once($root_path.'/Classes/Move.php');
 
// じわれ
class Fissure extends Move
{
 
    /**
    * 正式名称
    * @var string
    */
    protected $name = 'じわれ';
 
    /**
    * 説明文
    * @var string
    */
    protected $description = '一撃必殺技';
 
    /**
    * タイプ
    * @var string
    */
    protected $type = 'Ground';
 
    /**
    * 分類
    * @var string(physical:物理|special:特殊|status:変化)
    */
    protected $species = 'physical';
 
    /**
    * 威力
    * @var integer
    */
    protected $power = null;
 
    /**
    * 命中率
    * @var integer
    */
    protected $accuracy = 30;
 
    /**
    * 使用回数
    * @var integer
    */
    protected $pp = 5;
 
    /**
    * 優先度
    * @var integer
    */
    protected $priority = 0;
 
    /**
    * 一撃必殺技確認用フラグ
    * @var boolean
    */
    protected $one_hit_knockout_flg = true;
 
}

 

一撃必殺技ではダメージ計算を行わないため、威力にはnullをセットしておきます。更に、一撃必殺技だということがわかるように、one_hit_knockout_flgというプロパティを持たせてtrueをセットしておきましょう。合わせて、親クラスにも初期プロパティをセットしておきましょう。

 

技クラス(/Classes/Move.php
<?php
$root_path = __DIR__.'/..';
require_once($root_path.'/App/Traits/InstanceTrait.php');
require_once($root_path.'/App/Traits/ResponseTrait.php');
 
// 技
abstract class Move
{
 
--省略
 
    /**
    * 一撃必殺確認用フラグ
    * @var boolean
    */
    protected $one_hit_knockout_flg = false;

  

命中率の計算

一撃必殺には30%という命中率が設定されていますが、これは一律の数値ではありません。なぜなら、レベル差によってこの確率は変動するからです。 

命中率 = 30 + (攻撃側のレベル – 相手側のレベル)

ランク補正、命中率を上下させる効果の影響を受けない。

相手側が攻撃側よりレベルが高い場合は無効。

 

レベルが高ければ、そのレベルの差分が命中率に上乗せされるという仕様です。なので、通常の命中率取得処理とは別に、一撃必殺用の命中率取得処理を用意しましょう。

 

技クラス(/Classes/Move.php
/**
* 一撃必殺の命中率を計算
*
* @param string $pokemon
* @return integer
*/
public function getOneHitKnockoutAccuracy($atk, $def)
{
    if($atk->getLevel() > $def->getLevel()){
        return $this->accuracy + ($atk->getLevel() - $def->getLevel());
    }
    return $this->accuracy;
}

 

もしレベルが相手よりも上回っていれば、差分を加えた値を返却しています。

 

無効化処理

一撃必殺技は、相手のレベルが上回っていれば無効化されます。その際には「ぜんぜん効いていない」というメッセージが表示されるため、こちらも分岐を分けて作成しなければなりません。攻撃が外れた際のメッセージと合わせて、技クラスに追加しておきます。

 

技クラス(/Classes/Move.php
<?php
$root_path = __DIR__.'/..';
require_once($root_path.'/App/Traits/InstanceTrait.php');
require_once($root_path.'/App/Traits/ResponseTrait.php');
 
// 技
abstract class Move
{
    use InstanceTrait;
    use ResponseTrait;
 
    /**
    * チャージ技確認用フラグ
    * @var boolean
    */
    protected $charge_flg = false;
 
    /**
    * 一撃必殺確認用フラグ
    * @var boolean
    */
    protected $one_hit_knockout_flg = false;
 
    /**
    * 攻撃失敗時のメッセージ
    * @var string
    */
    protected $failed_msg = 'しかし::pokemonの攻撃は外れた!';
 
    /**
    * 一撃必殺失敗時のメッセージ
    * @var string
    */
    protected $one_hit_knockout_failed_msg = '::pokemonには全然効いていない!';

    /**
    * インスタンス作成時に実行される処理
    *
    * @return void
    */
    public function __construct()
    {
        //
    }
 
    /**
    * チャージ効果
    *
    * @return void
    */
    public function charge($atk)
    {
        // チャージ不要
        return false;
    }
 
    /**
    * 技回数
    *
    * @return integer
    */
    public function times()
    {
        // デフォルトは1
        return 1;
    }
 
    /**
    * 追加効果(ダメージ計算後に実行)
    *
    * @return void
    */
    public function effects(...$args)
    {
        //
    }
 
    /**
    * 名称の取得
    *
    * @return string
    */
    public function getName()
    {
        return $this->name;
    }
 
    /**
    * 説明文の取得
    *
    * @return string
    */
    public function getDescription()
    {
        return $this->description;
    }
 
    /**
    * タイプの取得
    *
    * @return object
    */
    public function getType()
    {
        return $this->getInstance($this->type);
    }
 
    /**
    * 分類の取得
    *
    * @return string
    */
    public function getSpecies()
    {
        return $this->species;
    }
 
    /**
    * 威力の取得
    *
    * @return string
    */
    public function getPower()
    {
        return $this->power;
    }
 
    /**
    * 命中率の取得
    *
    * @return integer
    */
    public function getAccuracy()
    {
        return $this->accuracy;
    }
 
    /**
    * 一撃必殺の命中率を計算
    *
    * @param string $pokemon
    * @return integer
    */
    public function getOneHitKnockoutAccuracy($atk, $def)
    {
        if($atk->getLevel() > $def->getLevel()){
            return $this->accuracy + ($atk->getLevel() - $def->getLevel());
        }
        return $this->accuracy;
    }
 
    /**
    * 使用回数の取得
    *
    * @param integer $correction 補正値
    * @return integer
    */
    public function getPp(int $correction=0)
    {
        return $this->pp + (int)(floor($this->pp / 5) * $correction);
    }
 
    /**
    * 優先度の取得
    *
    * @return integer
    */
    public function getPriority()
    {
        return $this->priority;
    }
 
    /**
    * 急所ランクの取得
    *
    * @return integer
    */
    public function getCritical()
    {
        return $this->critical ?? 0;
    }
 
    /**
    * チャージフラグの取得
    *
    * @return boolean
    */
    public function getChargeFlg()
    {
        return $this->charge_flg;
    }
 
    /**
    * 一撃必殺フラグの取得
    *
    * @return boolean
    */
    public function getOneHitKnockoutFlg()
    {
        return $this->one_hit_knockout_flg;
    }
 
    /**
    * 攻撃失敗時のメッセージを取得
    *
    * @param string $pokemon
    * @return string
    */
    public function getFailedMessage($pokemon)
    {
        return str_replace('::pokemon', $pokemon, $this->failed_msg);
    }
 
    /**
    * 一撃必殺失敗時(命中率が0)のメッセージを取得
    *
    * @param string $pokemon
    * @return string
    */
    public function getOneHitKnockoutFailedMessage($pokemon)
    {
        return str_replace('::pokemon', $pokemon, $this->one_hit_knockout_failed_msg);
    }
 
}

 

こちらが技クラスの最終コードです。状態異常などと同様に、メッセージを取得するためのメソッドを追加しました。

 

次に、命中判定処理を修正しましょう。

 

攻撃用トレイト(/Traits/Service/Battle/AttackTrait.php
/**
* 命中判定
*
* @param object $atk
* @param object $def
* @param object $move
* @return boolean
*/
private function checkHit($atk, $def, $move)
{
    // 一撃必殺技のチェック
    if($move->getOneHitKnockoutFlg()){
        if($atk->getLevel() < $def->getLevel()){
            // 相手の方がレベルが高ければ無効
            $this->setMessage($move->getOneHitKnockoutFailedMessage($def->getPrefixName()));
            return false;
        }
        // レベル差計算を含めた命中率を取得
        $accuracy = $move->getOneHitKnockoutAccuracy($atk, $def);
 
    }else{
        // 命中率取得
        $accuracy = $move->getAccuracy();
    }
    // nullの場合は命中率関係無し
    if(is_null($accuracy)){
        return true;
    }
    /**
    * 0〜100からランダムで数値を取得して、それより小さければ命中
    * 例:命中80%→mt_randで60が生成されたら成功、90なら失敗
    */
    if($accuracy >= mt_rand(0, 100)){
        // 攻撃成功
        return true;
    }
    // 攻撃失敗
    $this->setMessage($move->getFailedMessage($atk->getPrefixName()));
    return false;
}

 

最初に一撃必殺フラグを使って分岐を行い、もし一撃必殺であればレベル差を確認、一撃必殺用の命中率を取得するという処理を追加しました。その後、通常の命中判定に入っています。

checkHitメソッドの引数が変更になっているので、呼び出し箇所(attackメソッド内)も合わせて修正しておきましょう。

// 命中判定
if(!$this->checkHit($atk_pokemon, $def_pokemon, $move)){
    // 攻撃失敗
    return;
}

 

ダメージ計算

最後に一撃必殺技のダメージ判定です。命中判定が終わればダメージ計算に入りますが、一撃必殺ではそれは不要です。なぜなら、どんな相手であっても技が当たれば一撃で倒すことができるからです。

※持ち物や特性などによる判定は除く

 

なので、ダメージ計算前に再度一撃必殺技かどうかを判定する分岐を追加しましょう。

 

攻撃用トレイト:attackメソッド内(/Traits/Service/Battle/AttackTrait.php
// 一撃必殺
if($move->getOneHitKnockoutFlg()){
    $def_pokemon->calRemainingHp('death');
    $this->setMessage('一撃必殺');
    return;
}
// 技を回数分実行
$times = $move->times();
for($i = 0; $i < $times; $i++){
    // 攻撃判定成功時の処理
    $this->attackSuccess($atk_pokemon, $def_pokemon, $move);
}
// 連続技はヒット回数のメッセージを返却
if($times > 1){
    return $this->setMessage($times.'回当たった');
}

 

calRemainingHpメソッドに用意しているdeathを使って相手のHPを0にしています。それでは一撃必殺技を使って確認してみましょう。

 

自分のレベル以下の相手

 

 

自分のレベル超過の相手

 

 

しっかり判定通りの結果が返ってきましたね。ちなみにライチュウ戦のデバッガーのレベルがリセットされている理由は、無策でライチュウ相手に挑んだところ、でんきショックで葬られたからです。

 

まとめ

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

今回のPHPポケモンでは「連続攻撃技」と「一撃必殺技」を実装しました。

初代だけでもかなりのバリエーションを備えた技があり、そのすべての仕様を作るとなればかなりの作業量になりそうです。

ゲームづくりに興味がある人や、ポケモンが好きな人は、ぜひ参考にしてみてくださいね。

 

注目の記事

アウトプットのための3つの習慣【3対7を成立させよう】
雑記
アウトプットのための3つの習慣【3対7を成立させよう】

  インプットとアウトプットの比率は3対7がベストだと言われています。 しかし、簡単にできるインプットに比べて、アウトプットは習慣化させておくことが大切です。それができていない人の多くが、膨大に本を読んだり学習に取り組んでも身につかず、趣味のレベルで終わってしまうのです。   今回は、そんな...

LANとWANについて【第2回 ド素人のためのネットワーク講座】
ネットワーク
IoT,LAN,WAN,Wi-Fi
LANとWANについて【第2回 ド素人のためのネットワーク講座】

  YQUALがお送りする、ド素人のためのネットワーク講座。 栄えある第2回は「LANとWANについて」です。   フロントエンジニアや現在プログラミングを学習中の方を中心に、ネットワークについての基礎的理解を深めていくための内容になっています。 ざっくりとした説明で物足りない、または細かく見ていった...

起業・独立を考えている人に向けた具体的なアドバイス3選
雑記
起業・独立を考えている人に向けた具体的なアドバイス3選

  「どのタイミングで起業すべき?」 「会社を作るためにはどういったことをすればいいの?」   あなたはこんな悩みを抱えていませんか? 今回は、これから独立・起業をしようと考えている方や、そういった野望をいだいている人に向けて、自らの経験を元に具体的なアドバイスを3つピックアップしてご紹...

ひとのものをとったらどろぼう!編 PHPポケモン 99
プログラミング
PHP,PHPポケモン,ポケモン
ひとのものをとったらどろぼう!編 PHPポケモン 99

ひとの ものを とったら どろぼう! ポケモンの中でも有名なセリフの1つです。モンスターボールを投げることでポケモンを捕まえることができますが、既に別トレーナーが所有しているポケモンを捕まえることはできません。 初代から、トレーナー戦でモンスターボールを投げると「ひとの ものを とったら どろぼう!...

お金を生む仕組みを理解しよう【知っておきたい3つのポイント】
マーケティング
お金を生む仕組みを理解しよう【知っておきたい3つのポイント】

  どんなビジネスが儲かるのか・・・   一度はこういった悩みを持ったことがあるのではないでしょうか。 それを知るためには、どういった要素がお金を生むために作用しているのかを理解しておく必要があります。 今回は「お金を生む仕組み」について、知っておいてためになる基礎的な部分をわかりやすく...

未経験からWeb系エンジニアとしてフリーランスになる現実的な方法教えます【軌道に乗れば起業も可能】
フリーランス
エンジニア,フリーランス,プログラミング学習,独立,起業
未経験からWeb系エンジニアとしてフリーランスになる現実的な方法教えます【軌道に乗れば起業も可能】

  セカンドキャリアとしてプログラミングやデザインを学習したい   そう考えてスクールを受講したり、独学で始める人が増えていますが、そのほとんどが実らずに挫折してしまいます。 ですが、学習方法と経験の積み方や職の選び方さえ間違えなければ、技術を身につけてフリーランスとして活動することも難しく...

PHPポケモン「UI(Bootstrap4の導入)編」コード配布・デモ有り 13
プログラミング
PHP,PHPポケモン,ポケモン
PHPポケモン「UI(Bootstrap4の導入)編」コード配布・デモ有り 13

  第13回のPHPポケモンは「UI編」ということで、CSSの大人気フレームワークBootstrapさんにお手伝いいただきます。 また、前回実装したレスポンス機能により進化のアクションに一部不具合が出ていたので、このあたりも合わせて修正をしながら進めていきましょう。   Bootstrapを導入するにあたり、今までin...

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

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

カテゴリ

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 独立 神戸 福祉 秘密鍵 翻訳 自己啓発 英語 見積書 計算機 読書 起業 迷惑メール 配列 銀の弾丸 集客 雑学力