プログラミング

連続攻撃技と一撃必殺技編 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ポケモンでは「連続攻撃技」と「一撃必殺技」を実装しました。

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

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

 

注目の記事

本当に価値のある宣伝方法 〜多くの人が実践している【間違った努力】とは〜
マーケティング
Facebook,note,Twitter,YouTube,集客
本当に価値のある宣伝方法 〜多くの人が実践している【間違った努力】とは〜

  YouTubeやTwitter、Facebookやnoteなど、いろんなサービスを使った集客方法があります。集客という視点ではなく、それ自体に人を集めたいという人も多いでしょう。   フォロワーやチャンネル登録者数を増やすために、多くの人が様々な取り組みをしていますが、その中でもひときわ意味のないことをただ繰り返して...

PHPポケモン「バトルシステム実装編〜ダメージ計算〜」20
プログラミング
PHP,PHPポケモン,ポケモン
PHPポケモン「バトルシステム実装編〜ダメージ計算〜」20

バトルシステムの実装  今回はバトルシステムの中でもメインとなるダメージ計算と、命中判定の部分を実装していきます。   ダメージ計算  ポケモンのダメージ計算は初代から現在までそこまで大きな変化はありません。最新世代ではダメージに関係する要素(アイテム等)が多く、それにより補正値の修正はあります...

「数字を上げる」必勝マニュアル 〜再生回数・フォロワー・PV数〜
マーケティング
YouTuber,ブロガー,必勝マニュアル,自己啓発
「数字を上げる」必勝マニュアル 〜再生回数・フォロワー・PV数〜

  「継続は力なり」   色んな場面で言われます。何事も地道な努力が大事です。 しかし、地道な努力というのは成果が見えづらく、反応が得にくいことも確かです。   運良く勢いに乗れて、常に努力のし易い環境にいることで伸びていく人の確かにいます。 しかし、ほとんどの人がそうはいきません。...

有料ノートが公開停止!?プラットフォーム依存の危険性とは
雑記
note,YouTube,ブログ
有料ノートが公開停止!?プラットフォーム依存の危険性とは

  「いままでのnoteがいきなり公開停止になった」 「YouTubeであげていた人気動画が削除された」   規約変更、違反などを理由にこういった被害は年々増えています。自覚して悪意あるコンテンツを作っているユーザーであれば当然の結果だと言ってしまえば済むことですが、努力して収益化する糸口を見つけ...

【PHP7】はてな2つとは??Null合体演算子を使った存在チェック
プログラミング
PHP,プログラミング学習
【PHP7】はてな2つとは??Null合体演算子を使った存在チェック

  PHP Notice:  Undefined variable: 変数名 in /***/***.php on line 2   PHPで変数や対象のキーが存在しない配列を使おうとすれば、上記のようなエラーが吐き出されますね。PHP5.6までは初期値を設定したり、issetで判定したりしてそれを回避していましたが、2015年末にリリースされたPHP7からは新しくN...

毎日継続をするためのコツ
雑記
毎日継続をするためのコツ

定期的にコラムを書きたくなるので、今回は「毎日継続をするためのコツ」というテーマで自分が意識していることや、感じたことを書き綴っていきます。 決して開発や業務で追われていたり、PHPポケモンの大幅見直しを迫られているわけではありません。   毎日継続するために  ブログや学習など、毎日継続...

進化の石編(構成) PHPポケモン 102
プログラミング
PHP,PHPポケモン,ポケモン
進化の石編(構成) PHPポケモン 102

進化の石 ピカチュウさんもそろそろ進化したがっているので、β版の公開に向けて進化の石を実装していきます。しかし、イーブイなど特別な進化先や条件を持ったポケモンを考慮すると、少し実装が手間取りそうだったので、今回は構成部分のみのまとめとなっておりますので、ご了承ください。   アイテムクラスの作...

【変数とは】初心者が最短でPHPを使えるようになるための実践的な学び方
プログラミング
HTML,PHP,プログラミング学習
【変数とは】初心者が最短でPHPを使えるようになるための実践的な学び方

  ※PHP初心者へ向けた内容となりますので、ある程度HTMLの知識がある方を対象とした内容になります。予めご了承ください。    Webプログラミングを学ぶ方はHTML、そしてCSSを学び、そしてJavascriptや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 独立 神戸 福祉 秘密鍵 翻訳 自己啓発 英語 見積書 計算機 読書 起業 迷惑メール 配列 銀の弾丸 集客 雑学力