EBS3 – 探索完成・追加、作戦補正変更

EBS3の探索が完成しました!

とりあえず、ダンジョン「初心者の森」を初期設定しました。
あんまり難易度も高くないし、出てくるMobも弱め。
宝箱から初期装備(第2進化)がでてきます。
キャプチャ

キャプチャ2

作成補正を以下の通りに変更しました。(詳細はhttp://rei-farms.jp/ebs/info_open)
作戦名 必要Lv *AT *DEF +MT *SP その他
通常攻撃 0 1 1 0 1
突撃 5 1.1 0.8 0 1
防御 18 0.8 1.5 0 1
ヒットアンドアウェイ 60 0.9 1 5 1.1
集中 120 0.9 1 20 0.9
捨て身 200 1.5 0 0 1
見切り 250 0.8 0.5 10 1.3
全力 300 1 1 5 1 WP NUM×2, WP EN×2

EBS時代の補正値に戻しました。
強すぎた防御を緩和、ほぼ倍数での計算になっています。

それではでは。

EBS3 – 探索作成中、あとはMob出現と宝箱の設定のみ

マップは今の所こんな感じになってます。
キャプチャ
どうやら、風来のシレンに似てるようです。

EBS3のメインコンテンツは戦争(勢力)です。
ただ、人が集まらないとただの色塗りゲーになるので、
人がいない時間帯でも楽しく(?)遊んでもらえるようにしたいと思ってます。

ダンジョンクリアで経験値やゴールドも貰えるようにする予定です。
「レアアイテムもダンジョンで拾える!」
「レアMobに会える!」(Exp、Goldいっぱい+レアアイテム獲得の可能性)
とかを画策してます。

MMO・・・というよりMOか。

ただし、単純に強い武器が拾える、または単純に強くなれるのではなく、
戦争での選択肢を増やせるようなコンテンツにしていきたいですね。

次のブログで完成報告、公開できるようがんばります。

EBS3 – 探索自動マップ生成完成

作成中だった「自動マップ生成」が完成しました!
完全にダンジョン

コードは上下・左右の2種類で分けて書いています。(1種類にしたい)
なかなか時間がかかりましたが、これで探索ができそうです。

戦闘モジュール化もしたので、歩いていたら確率でMobが出てきます。
あとは出口。マップ中のどこか1つに設置する。
レアが入っている宝箱も作りたい・・・!

コードは今の所以下のようになってます。使う人いないと思うけどどうぞ。

            $html_hunt .= "マップ生成<br>";
            
            // 基礎データ設定
            $HRM = []; // Map
            $HRM2 = []; // 通路専用
            
            // 部屋数、大きさ決定
            $set_num = mt_rand(3,10);
            $set_width = mt_rand(10,12);
            $set_base = []; // 部屋の位置:$set_base["$x,$y"] = $i;
            $set_room = []; // 部屋の位置、大きさ:$set_room[$i] = "$x_st,$y_st!$x_wd,$y_wd";
            $set_root = []; // ルート設定:"$x1_st,$y1_st!$x1_ed,$y1_ed?$x2_st,$y2_st!$x2_ed,$y2_ed"; // 2本あり
            
            // 基礎マップを生成
            $x_set = $y_set = null;
            $x_bef = $y_bef = null;
            $set_rand = null;
            for($i=0; $i<$set_num; $i++)
            {
                // 配置設定
                $x_set = $x_set = null;
                if($i == 0) // 初期設定
                {
                    $x_set = 0;
                    $y_set = 0;
                }
                else
                {
                    // 配置検索
                    $set_check = 0;
                    while(1)
                    {
                        // キー検索
                        $set_base_rand = mt_rand(0, count($set_base)-1);
                        $key = array_search($set_base_rand, $set_base);
                        
                        // 空き地検索地設定
                        $pos = explode(",", $key);
                        $x = $x_bef = $pos[0];
                        $y = $y_bef = $pos[1];
                        
                        // 検索開始
                        $while_n = 0;
                        while(1)
                        {
                            $set_rand = mt_rand(0, 3);
                            switch($set_rand)
                            {
                                case 0: // 上
                                $str = ($x) . ',' . ($y+1);
                                if(!isset($set_base[$str]))
                                {
                                    $x_set = $x;
                                    $y_set = $y+1;
                                    $set_check = 1;
                                }
                                break;
                                case 1: // 右
                                $str = ($x+1) . ',' . ($y);
                                if(!isset($set_base[$str]))
                                {
                                    $x_set = $x+1;
                                    $y_set = $y;
                                    $set_check = 1;
                                }
                                break;
                                case 2: // 下
                                $str = ($x) . ',' . ($y-1);
                                if(!isset($set_base[$str]))
                                {
                                    $x_set = $x;
                                    $y_set = $y-1;
                                    $set_check = 1;
                                }
                                break;
                                case 3: // 左
                                $str = ($x-1) . ',' . ($y);
                                if(!isset($set_base[$str]))
                                {
                                    $x_set = $x-1;
                                    $y_set = $y;
                                    $set_check = 1;
                                }
                                break;
                            }
                            
                            // break
                            if($set_check){break 2;}
                            if($while_n > 5){break;}
                            $while_n++;
                        }
                    }
                }
                
                // 位置
                $set_base["$x_set,$y_set"] = $i;
                
                // 部屋大きさ
                $x_room = mt_rand($set_width/3, $set_width - 3);
                $y_room = mt_rand($set_width/3, $set_width - 3);
                $x_st = mt_rand(1, $set_width - $x_room - 2);
                $y_st = mt_rand(1, $set_width - $y_room - 2);
                $x_wd = $x_room;
                $y_wd = $y_room;
                $set_room[$i] = "$x_st,$y_st!$x_wd,$y_wd";
                
                // 設定
                $x_room_bs = $set_width * $x_set + $x_st;
                $y_room_bs = $set_width * $y_set + $y_st;
                for($n=0; $n<=$x_wd; $n++)
                {
                    for($o=0; $o<=$y_wd; $o++)
                    {
                        $keys = ($x_room_bs + $n) .','. ($y_room_bs + $o);
                        $HRM[$keys] = 1;
                    }
                }
                
                // ルート設定
                if($i != 0) // $set_rand : 0上,1右,2下,3左
                {
                    // 設定
                    $b_room = explode("!", $set_room[$set_base_rand]);
                    $b_st = explode(",", $b_room[0]);
                    $b_wd = explode(",", $b_room[1]);
                    $b_pos = explode(",", array_search($set_base_rand, $set_base));
                    
                    $n_room = explode("!", $set_room[$i]);
                    $n_st = explode(",", $n_room[0]);
                    $n_wd = explode(",", $n_room[1]);
                    $n_pos = explode(",", array_search($i, $set_base));
                    
                    switch($set_rand)
                    {
                        case 0: // 上(b下、n上)
                            $u_st_x = $b_pos[0]*$set_width + mt_rand(0, $b_wd[0]) + $b_st[0];
                            $u_st_y = $b_pos[1]*$set_width + $b_st[1] + $b_wd[1];
                            $d_st_x = $n_pos[0]*$set_width + mt_rand(0, $n_wd[0]) + $n_st[0];
                            $d_st_y = $n_pos[1]*$set_width + $n_st[1];
                            $a_ed_y = $n_pos[1]*$set_width - 1;
                        break;
                        case 1: // 右
                            $l_st_x = $b_pos[0]*$set_width + $b_st[0] + $b_wd[0];
                            $l_st_y = $b_pos[1]*$set_width + mt_rand(0, $b_wd[1]) + $b_st[1];
                            $r_st_x = $n_pos[0]*$set_width + $n_st[0];
                            $r_st_y = $n_pos[1]*$set_width + mt_rand(0, $n_wd[1]) + $n_st[1];
                            $a_ed_x = $n_pos[0]*$set_width - 1;
                        break;
                        case 2: // 下
                            $u_st_x = $n_pos[0]*$set_width + mt_rand(0, $n_wd[0]) + $n_st[0];
                            $u_st_y = $n_pos[1]*$set_width + $n_st[1] + $n_wd[1]; // 0まで上に
                            $d_st_x = $b_pos[0]*$set_width + mt_rand(0, $b_wd[0]) + $b_st[0];
                            $d_st_y = $b_pos[1]*$set_width + $b_st[1]; // 0まで下に
                            $a_ed_y = $b_pos[1]*$set_width - 1;
                        break;
                        case 3: // 左
                            $l_st_x = $n_pos[0]*$set_width + $n_st[0] + $n_wd[0];
                            $l_st_y = $n_pos[1]*$set_width + mt_rand(0, $n_wd[1]) + $n_st[1];
                            $r_st_x = $b_pos[0]*$set_width + $b_st[0];
                            $r_st_y = $b_pos[1]*$set_width + mt_rand(0, $b_wd[1]) + $b_st[1];
                            $a_ed_x = $b_pos[0]*$set_width - 1;
                        break;
                    }
                    
                    if($set_rand == 0 || $set_rand == 2)
                    {
                        print "({$i}と" . ($set_base_rand) . ")基準線 y={$a_ed_y}<br>";
                        print "上開始座標({$u_st_x},{$u_st_y})<br>";
                        print "下開始座標({$d_st_x},{$d_st_y})<br>";
                        
                        // 横線作成
                        if($u_st_x != $d_st_x)
                        {
                            $hl_st = $hl_ed = null;
                            if($u_st_x > $d_st_x)
                            {
                                $hl_st = $d_st_x;
                                $hl_ed = $u_st_x;
                            }
                            elseif($u_st_x < $d_st_x)
                            {
                                $hl_st = $u_st_x;
                                $hl_ed = $d_st_x;
                            }
                            
                            // 追加
                            for($n=$hl_st; $n<=$hl_ed; $n++)
                            {
                                $HRM["{$n},{$a_ed_y}"] = 1;
                                $HRM2["{$n},{$a_ed_y}"] = 1;
                            }
                        }
                        
                        // 縦線作成(上)
                        for($n=$u_st_y; $n<=$a_ed_y; $n++)
                        {
                            $HRM["{$u_st_x},{$n}"] = 1;
                            $HRM2["{$u_st_x},{$n}"] = 1;
                        }
                        
                        // 縦線作成(下)
                        for($n=$a_ed_y; $n<=$d_st_y; $n++)
                        {
                            $HRM["{$d_st_x},{$n}"] = 1;
                            $HRM2["{$d_st_x},{$n}"] = 1;
                        }
                    }
                    elseif($set_rand == 1 || $set_rand == 3)
                    {
                        print "({$i}と" . ($set_base_rand) . ")基準線 x={$a_ed_x}<br>";
                        print "左開始座標({$l_st_x},{$l_st_y})<br>";
                        print "右開始座標({$r_st_x},{$r_st_y})<br>";
                        
                        // 上線作成
                        if($l_st_y != $r_st_y)
                        {
                            $hl_st = $hl_ed = null;
                            if($l_st_y > $r_st_y)
                            {
                                $hl_st = $r_st_y;
                                $hl_ed = $l_st_y;
                            }
                            elseif($l_st_y < $r_st_y)
                            {
                                $hl_st = $l_st_y;
                                $hl_ed = $r_st_y;
                            }
                            
                            // 追加
                            for($n=$hl_st; $n<=$hl_ed; $n++)
                            {
                                $HRM["{$a_ed_x},{$n}"] = 1;
                                $HRM2["{$a_ed_x},{$n}"] = 1;
                            }
                        }
                        
                        // 横線作成(左)
                        for($n=$l_st_x; $n<=$a_ed_x; $n++)
                        {
                            $HRM["{$n},{$l_st_y}"] = 1;
                            $HRM2["{$n},{$l_st_y}"] = 1;
                        }
                        
                        // 横作成(右)
                        for($n=$a_ed_x; $n<=$r_st_x; $n++)
                        {
                            $HRM["{$n},{$r_st_y}"] = 1;
                            $HRM2["{$n},{$r_st_y}"] = 1;
                        }
                    }
                }
            }
            
            // 表示
            print "部屋の数{$set_num}個、部屋の大きさ{$set_width}<br>";
            
            foreach($set_base as $key => $val)
            {
                print "{$key}=>{$val}<br>";
            }
            print "<br>";
            //print_r($set_room);
            //print "<br>";
            
            //
            foreach($HRM as $key => $val)
            {
                print "{$key}<br>";
            }
            
            // div
            $div = 10;
            $div_base = 300;
            foreach($set_room as $key => $val)
            {
                // タイプ取得
                $type = explode("!", $val); // 0st,1wd
                $pos = explode(",", $type[0]);
                $wd = explode(",", $type[1]);
                
                // 基礎キー取得
                $base_key = explode("," ,array_search($key, $set_base));
                
                // 設定
                
                // 表示
                $pos_x = ($pos[0] + $set_width * $base_key[0]) * $div + $div_base;
                $pos_y = ($pos[1] + $set_width * $base_key[1]) * $div + $div_base;
                $wd_x = ($wd[0]) * $div;
                $wd_y = ($wd[1]) * $div;
                // 基礎設定
                $bp_x = ($set_width * $base_key[0]) * $div + $div_base;
                $bp_y = ($set_width * $base_key[1]) * $div + $div_base;
                $bs_x = $set_width * $div;
                $bs_y = $set_width * $div;
                
                // 表示
                print "<div style='position: absolute; left: {$pos_x}px; top: {$pos_y}px; width: {$wd_x}px; height: {$wd_y}px; background-color: red; z-index: 1;'>$key</div>\n";
                // 基礎表示
                print "<div style='position: absolute; left: {$bp_x}px; top: {$bp_y}px; width: {$bs_x}px; height: {$bs_y}px; background-color: blue; z-index: 0;'>$key</div>\n";
            }
            
            // HRM
            foreach($HRM as $key => $val)
            {
                // 設定
                $hrm_pos = explode(",", $key);
                
                // 表示
                $hrm_pos_x = $hrm_pos[0] * $div + $div_base;
                $hrm_pos_y = $hrm_pos[1] * $div + $div_base;
                print "<div style='position: absolute; left: {$hrm_pos_x}px; top: {$hrm_pos_y}px; width: {$div}px; height: {$div}px; background-color: gray; z-index: 2;' title='{$hrm_pos[0]},{$hrm_pos[1]}'></div>\n";
            }
            
            // HRM2
            foreach($HRM2 as $key => $val)
            {
                // 設定
                $hrm_pos = explode(",", $key);
                
                // 表示
                $hrm_pos_x = $hrm_pos[0] * $div + $div_base;
                $hrm_pos_y = $hrm_pos[1] * $div + $div_base;
                print "<div style='position: absolute; left: {$hrm_pos_x}px; top: {$hrm_pos_y}px; width: {$div}px; height: {$div}px; background-color: red; z-index: 3;' title='{$hrm_pos[0]},{$hrm_pos[1]}'></div>\n";
            }

EBS3 – 探索作成中(一時詰んだ状態)

探索用の「ダンジョンマップ自動生成」アルゴリズムを作成中です。
hunt
※部屋ごとの枠が青、実際の部屋は赤で表示

探索するとき、ずっと同じマップ形式だったらつまらないですよね!

ということで、マインクラフト的な(?)マップ自動生成アルゴリズムをつくってます。
最初の方はこちらを参考にしていました。

ですが、
(1)分割するのめんどくさい(‘A`)どうすんの・・・これ
(2)なんか形同じになるんじゃね?
という技術的問題と危惧があったので上の図のようにしてます。

上の図は、
(1)とりあえず0,0にmap0を作る
(2)設定してあるマップをランダムに選び、隣接地のいずれかに重複しないマップ(map1~)を1つ作る
(3)(2)を繰り返す
という感じで作ってます。

ということで、運が良ければ(?)蛇みたいに細長いものもできたりします。
hunt2

一時詰んだ状態になってるのは、
マップ同士をつなぐ通路つくるアルゴリズム的な何かを作るのがすごくめんどくさいとなっているためです。

(上下左右で条件分岐するとコード汚くなる・・・1つのコードでやるにはsinとかcosでできそうだけどフハア>(‘A`)

現状報告まで。

EBS3 – 公開開始

ENDLESS BATTLE 3の公開を開始しました!

コンセプトは以下の3点。
・多vs多の戦略シミュレーション
・“最強”は要らない
・“THINK”(考え、行動せよ)

ゲーム内容、予定も含めてます。
・個人・国家間の戦略シミュレーションゲーム
・アクション性なし(クリックのみで完結、誰でも時間があればできる)
・装備はタイプ別に強い装備があるが、総合的に強いものはなし
・能力、HP、EN(MP)制
・無料、プログラム基礎版は配布予定(多様なゲーム性があるようにしたい)
・プレイヤーとの戦い。NPCは少量+イベント用に極少量。

注意は以下の通りです。
・この公開はテストです。そのため、正式公開時にはデータをリセットする予定です。予めご了承ください。
(削除はしない予定です。テストに参加していただいた方には、何かを正式公開時にプレゼントする予定です。)
・データや機能は予告なく変更します。
(探索、タイマンなどがないので追加していきます。)
・迷惑行為を行わないでください。
・武器の種類は3種、防具の種類は3種類しかありません。
(正式公開時には、テストのデータを鑑みて上限や装備傾向を作っていきます。種類も今の5倍にはなるかと。)
・勢力は、建国・亡命はできますが布告できません。
(人数増加で変更します。)

装備のタイプは以下の通りです。
・武器のタイプ
短剣:攻撃低、軽い
長剣:攻撃普通、重量普通
槍:攻撃高い、重い
・防具のタイプ
服:防御低、軽い、硬度低
甲冑:防御高め、重い→軽い、硬度普通
鎧:防御高、重い、硬度高

不具合報告などはツイッターやブログにコメントいただけるとありがたいです。
基礎プログラム(CakePHP版)は近日公開します。

EBS3 – 基礎完成?

以前書いたコレの不具合っぽいところとか、EBSに必要だと考えていた基礎的な機能をすべて追加しました。

これでバグがなければとりあえずは基礎の完成とします。
一応できる機能だけ説明しますね。

・勢力(国vs国)
 これはマップが可変です。
 編集もある程度簡単にできるので、将来的には公募して一般マップを決めたいと思ってます。

 ↓こんな変なマップもわりと簡単にできます
1

 ↓データ編集画面はこちら
2

 ↓今のところは三国志(古代中国)のマップを採用しています
3

 戦闘は一般的なEBSと変わらないです。
 戦争時のみ1クリックで相手が表示されるので、白熱した戦いに・・・なるのか?
5

 歴史も結構流れる・・・?(国名はネタです、悪しからず)
9

・ステータス画面
 普通のEBSと同じ感じ。
 フレーム不使用で上下にページを分割しなくしました。(フレームだと携帯ブラウザ対応がめんどくさいので)
4

・装備画面
 普通といえば普通。
 購入、売却、倉庫、武器進化と普通です。
6

 ↓再分配だけ変なシステムですが、これがないとマンネリ化するしね。
7

 ↓カスタム、機体強化(HP変更、EN強化)、再分配
 カスタムは成長方針や機体画像などを変更できます。
 機体強化はHP変更(上下可)、EN強化できます。
 再分配はLv1にして経験値を還元し、STをALL1にします。機体のST分配で有利不利がはっきりあるので、最強っていうのは難しいんじゃないかな。(最強が出たら修正する予定)
 8

こんな感じです。
宿題が終わったら本体をアップロードしてみます。(多分今日中には・・・)
以上!

以下は機能のリストを挙げときます。
・メイン
index(top page)
main(status page)
regist

・戦闘
・マップ(勢力)
move
info
・マップ>戦争
decl(布告)
sup(制圧)
downfall(滅亡)
・マップ>国
exile(亡命)

・情報
country
id(個人情報)
・歴史

・装備
store
sell
・倉庫
in
out
lock
ex(拡張)

・機体
custom
training
reset

・管理
weapon_renew
map_maker

割りと少ない気がしますが、Controllerだけで4330行いってるので機能としてはぼちぼちあるんじゃないでしょうか。
(スパゲッティコードな感は否めませんが!)

EBS3 大幅に追加追加

EBS3にいろいろ追加してました。
・戦闘
 ・見やすく(したつもり)
・勢力
 ・都市制圧、国滅亡
 ・亡命
 ・制圧時の強制送還
 ・支配権移行時間設定(数秒でオセロにならないように)
・歴史
 ・何かしたら記録されるように(ID登録、建国、宣戦布告等)
・装備
 ・基礎的な武器(3系統)、防具(3系統)を追加
 ・耐久などの性能追加
 ・LvUP、LvUP時の性能上昇
 ・進化

まだまだ足りないような気がしますし、これ書いてても自分しかわからない状態だし・・・ということで、
4月末には未完成でもとりあえず公開してみます。
初めてcakePHPをオンライン上で動かすのもあって色々と試したいこともありますしね。

このゲームは、人が居れば「勢力」(国vs国)は面白いコンテンツになる予定のゲームです。
「勢力」はほぼRTSでユーザー間の交流(意思伝達)があった方が強いので、交流が生まれるかなあと思ってます。
(暇人が有利にならないような施策を行うべきだとは思います。社会人は夜しかできないしね。)

でもって、基礎となる1vs1がクソゲーだとどうしようもないので改良していく予定です。

しかしながら、現状では1vs1も、ゲーム自体もクソゲーです。(断言)
初期装備で殴り合いするとダメージがほとんど出ないのと、遊べるコンテンツがない&育成要素がない。
とりあえずレベリングだけは実装しときたいですが・・・。
機体も何体か持てる仕様なんですが、その機能も実装してません。(汗)

ということで、現状問題があるととらえている以下を改良したいなあと思ってます。
・戦闘(1vs1)
・表示
 スマホだけ対応とかクソでした、すみません。
・プログラムコード
 cakePHPはMVC(モデル・ビュー・コントローラー)だっけ?複数人で開発できんのこのコードで?
 →無理です。すみません。
  モデル・コントローラだけで動く漢字で、ビューがほぼおまけ状態となりデザインを変えにくいです。
  付け加えるとコードの書き方も統一してないスパゲッティです。

全然だめじゃーん\(^o^)/

・・・全く関係ないですが、一応参考にさせていただいたゲームを書いておきます。
基礎:ENDLESS BATTLE、Dest、三国志遊戯
勢力:三国志遊戯、Hearts of Iron 2、Age of Empireシリーズ、大戦略シリーズ、神獄のヴァルハラゲート、Crash of Clan等
・・・まあこれだけのゲームで遊んでたから作るの遅くなってるんだけどね。
今はネットが学校にしかないので制作がはかどります。(==;

@3/28追記
熊本大学の卒業式が25に終わって、26に飛行機のつもりが飛ばなくて、27夕方の臨時便に乗って・・・現在横浜です。
栃木にはネット回線が今の所ない(他ゲーで遊べない)ので、4月末には基礎型がほぼ完成していると思います。
バグがないようにがんばろー。

EBS 宣戦布告と防衛

国vs国(勢力)でちょっとずつ追加しています。
とりあえず実装予定だった「隣国(縦横4マス)に布告・制圧できるようにする(空き地は無血占領可)」を実装しました。

で・・・敵国に布告されており、こちらから布告していない状態でも攻撃できるようにしてます。
専守防衛というやつですね。

↓「無国籍」相手に布告しているときに、他の国に布告された場合
0311_1

↓隣接マップで防衛ができるようになります。
0311_2

まだ表示が分かりにくい(攻撃、防衛が分けて表示される)ので変更予定です。
↓なぜこうなったのか・・・
0311_3

順調なのかなこれは

EBS3 勢力の基礎はこんな感じで

今のところ、国vs国の戦い(勢力)がメインコンテンツになる予定です。

そのため、
・一目で支配している国(の色)がわかるように、旗をPOMOさんから用意
(ほとんどの国の色を黒になってるのは初期設定するのを忘れてたからです(汗))
・地形(攻撃/防御補正有)も分かるように画像で表示
(RPGツクール系のマップチップ画像を利用)
・マップ移動に少し時間がかかる
(現行は1座標あたり1分)
・勢力のマップは変更可能
(一般配布する時はマップデータも別に配布したいなあとも。マップデータ例:三国志(古代中国)、戦国時代(室町→江戸日本)、世界大戦などなど)

0306
表示は後で変えれるので適当に作っておきましょう。。

あとは・・・
・隣国(縦横4マス)に布告・制圧できるようにする
(空き地は無血占領可)
・領地ごとに要塞をつくる
(占領地ごと・戦闘からの収入(国庫は統一)で強化可能に)
・補給線の考え方を追加する
(首都から補給していると考えて、HP/ENの回復遅延や所属領地が制圧された場合の首都帰還時間を遅延する)

人数多いと領地は大きくなるけど・・・みたいな感じで。(いたって普通)
戦略シミュレーションだからいろいろできないとね。