集めた仲間によって評価が変わるRPGの作成~マップ作成編~
はじめまして、東京経済大学3年のSTです。
このブログでは、私が研究ノートで取り組んでいるプログラム開発の記録を日誌形式で公開していきます。
まず最初は「集めた仲間によって評価が変わるRPG」~マップ作成編~です。
とりあえず、フラグやストーリの前にマップを作成してみました。次回から少しずつフラグ建築やストーリー性を作成していきたいと思います。最終的に隠し要素や裏技的なものまで仕込むことができたらいいなと思います。
~マップ作成~
1.マップの説明
まだマップのみで何も仕組みはないです。
マップの順番は3×4で
0,1,2,11
3,4,5,10
6,7,8,9
タイルIDは ============================================================
タイルID仕様(01〜):見た目・通行判定の基準となる辞書
「描画」は fieldpaint() 内で ID→画像 を対応
「通行可否」は landWalk / seaTiles / blocked で制御
============================================================
歩行(陸): 01=草, 02=床, 03=石床, 04=花1, 05=花2, 13=石床2, 14=石床3, 32=丸太1(上陸ポイント)
自然: 06=木, 07=周り岩, 08=湖(海として使用), 09=水壁
建物: 10=井戸, 11=テントA, 12=テントB
石壁: 20=石壁1, 21=石壁2, 22=石壁3, 23=石壁4, 24=石壁5
海他: 30=暗い海1, 31=暗い海2, 33=丸太2, 34=石柱1, 35=石柱2, 36=石柱3, 37=草むら1,
38=食材1, 39=食材2, 40=水岩(障害物), 41=船(左), 42=船(右), 43=船(上), 44=船(下)
市: 50=売店1, 51=売店2, 52=売店3, 53=売店4, 54=売店5, 55=木箱, 56=木箱2
洞窟: 60=洞窟入口(通行可), 61=洞窟壁, 62=洞窟壁2,
63=洞窟床1(可), 64=洞窟床2(可), 65=洞窟床3(可),
66=洞窟岩1, 67=洞窟岩2, 68=洞窟岩3, 69=洞窟穴, 70=洞窟骸骨,
71=トロッコ1, 72=トロッコ2, 73=剣立て, 74=槍立て, 75=防具
マップ0 初期画面
マップ2
2.コード説明
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Buddy Assemble</title>
<style>
body{background:#1b2a1b;margin:0;display:flex;justify-content:center;align-items:center;height:100vh}
canvas{image-rendering:pixelated;border:2px solid #2f4f2f;background:#2a3f2a}
</style>
HTML5宣言と
<head>開始。UTF-8指定で日本語の文字化けを防止。
タイトルはゲーム名。
CSSは最小構成:画面を中央寄せ
canvasはドットが滲まないimage-rendering: pixelatedと枠・背景のみ。 <script>
var map0 = [
[06,12,11,11,12,12,12,11,11,12,11,40,40,40,40,40,40,40,06,06],
[06,11,11,11,12,11,11,12,12,11,11,40,08,08,08,08,08,40,06,06],
[06,02,02,02,02,02,02,02,02,02,02,40,08,08,08,08,08,40,06,06],
[06,02,02,02,02,02,02,02,02,02,02,40,08,08,08,08,08,40,06,06],
[06,11,11,12,11,12,12,02,02,02,02,40,40,40,40,40,40,40,06,06],
[06,11,12,12,11,11,11,02,02,02,02,02,02,02,02,02,02,02,02,02],
[06,02,02,02,02,02,02,02,02,02,02,02,02,02,03,12,12,12,11,06],
[06,05,05,05,05,05,05,02,02,02,02,02,02,02,03,11,12,11,12,06],
[06,05,05,05,05,05,05,02,02,02,02,02,02,02,03,03,03,03,03,06],
[06,05,05,05,05,05,05,02,02,02,02,02,02,02,03,03,03,03,03,06],
[06,06,06,06,06,06,06,06,06,02,02,02,06,06,06,06,06,06,06,06],
];
var map1 = [
[06,06,06,06,06,06,06,06,06,06,06,06,06,06,06,06,06,06,06,06],
[06,11,11,12,11,11,12,11,73,73,73,74,74,75,75,75,73,73,73,06],
[06,01,01,01,01,01,01,01,01,01,01,01,01,01,01,01,01,01,01,06],
[06,11,11,11,12,12,11,11,01,01,01,01,01,11,12,12,12,11,11,06],
[06,01,01,01,01,01,01,01,01,01,01,01,01,01,01,01,01,01,01,06],
[01,01,01,01,01,01,01,01,01,01,01,01,01,01,01,01,01,01,01,01],
[06,04,04,04,04,33,01,01,01,01,01,01,01,01,01,01,01,01,01,06],
[06,04,04,04,04,33,01,01,01,01,01,01,01,71,72,71,72,72,71,06],
[06,04,04,04,04,33,01,01,01,01,01,01,01,72,71,71,72,71,72,06],
[06,04,04,04,04,33,01,01,01,01,01,01,01,71,71,72,72,72,71,06],
[06,06,06,06,06,06,06,06,06,06,01,06,06,06,06,06,06,06,06,06],
];
var map2 = [
[23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23],
[13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,23],
[13,13,22,13,13,23,23,23,23,23,23,23,23,13,13,23,23,23,13,23],
[13,13,22,13,13,23,13,13,13,13,13,13,23,13,13,23,13,13,13,23],
[23,23,22,13,13,23,23,23,22,22,22,13,23,13,13,23,13,13,13,23],
[13,13,13,13,13,21,13,13,13,13,13,13,23,13,13,23,13,13,13,23],
[23,23,13,23,23,23,13,13,13,13,13,13,23,13,13,23,13,13,13,23],
[13,22,13,23,13,13,13,13,13,13,13,23,23,13,13,23,13,13,13,23],
[13,22,13,23,23,23,23,23,23,23,13,13,13,13,13,23,13,13,13,23],
[13,22,13,13,13,13,13,13,13,23,13,13,13,13,13,23,13,13,13,23],
[13,13,13,13,13,13,13,13,13,23,13,23,23,23,23,23,13,13,13,23],
];
var map3 = [
[51,50,51,50,50,51,55,50,50,13,13,13,50,50,51,55,51,50,51,51],
[52,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13],
[52,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13],
[50,55,51,50,55,50,51,50,51,13,13,13,50,51,51,51,50,51,50,55],
[53,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13],
[53,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13],
[54,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13],
[51,50,51,50,50,55,50,50,55,13,13,13,51,51,50,50,51,55,51,51],
[52,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13],
[54,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13],
[50,51,55,50,51,51,50,50,51,13,13,13,50,51,51,51,50,51,55,51],
];
var map4 = [
[06,06,06,06,06,06,06,06,06,06,01,06,06,06,06,06,06,06,06,06],
[06,11,11,11,12,11,01,01,01,01,01,01,55,55,56,55,56,10,10,06],
[06,01,01,01,01,01,01,01,01,01,01,01,55,56,56,56,55,01,01,06],
[06,11,11,12,12,12,01,01,01,01,01,01,01,01,01,01,01,01,01,06],
[01,01,01,01,01,01,01,01,01,01,01,01,01,01,01,01,01,01,01,06],
[01,01,01,01,01,01,01,01,01,01,01,01,01,01,01,01,01,01,01,06],
[01,01,01,01,01,01,01,01,01,01,01,01,01,01,01,01,01,01,01,06],
[06,04,05,04,05,04,05,04,05,04,05,04,05,04,05,04,05,04,05,06],
[06,05,04,05,04,05,04,05,04,05,04,05,04,05,04,05,04,05,04,06],
[06,04,05,04,05,04,05,04,05,04,05,04,05,04,05,04,05,04,05,06],
[06,06,06,06,06,06,06,06,06,06,06,06,06,06,06,06,06,06,06,06],
];
var map5 = [
[23,23,23,23,23,23,23,23,23,23,13,23,23,23,23,23,23,23,23,23],
[23,13,13,14,22,13,13,14,23,13,13,14,23,13,13,14,23,13,13,23],
[23,13,23,13,22,23,23,13,23,14,23,13,23,13,23,14,23,13,23,23],
[23,13,23,14,13,13,13,13,14,13,13,13,13,14,23,13,13,14,21,23],
[23,13,23,23,22,13,23,23,13,14,22,23,22,13,14,23,22,13,21,23],
[23,13,14,13,13,23,13,13,13,13,23,13,14,13,13,22,13,13,13,13],
[23,23,23,13,23,13,22,22,22,13,23,23,23,14,21,23,22,13,23,23],
[23,13,13,14,22,13,13,13,23,13,13,14,13,13,13,13,23,13,13,23],
[23,23,13,14,23,13,23,13,23,23,23,13,23,22,23,14,23,13,22,23],
[23,13,13,13,13,14,13,13,13,13,13,14,13,13,13,13,13,13,13,23],
[23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23],
];
var map6 = [
[51,51,51,50,55,51,55,51,51,13,13,13,50,50,50,50,50,55,50,50],
[52,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13],
[52,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13],
[50,55,50,50,55,51,50,51,55,13,13,13,55,55,51,51,50,51,50,55],
[53,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13],
[53,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13],
[54,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13],
[50,51,51,50,50,55,50,50,55,13,13,13,50,55,51,50,51,51,55,51],
[52,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13],
[54,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13],
[50,50,55,50,51,50,51,50,55,13,13,13,55,50,51,51,50,50,50,51],
];
var map7 = [
[13,32,30,30,40,40,40,40,40,40,40,31,31,31,31,31,31,31,40,31],
[13,32,31,30,31,31,31,40,31,31,40,30,31,31,30,40,40,31,31,40],
[13,32,40,40,40,31,31,31,31,31,40,30,40,31,30,40,31,30,40,31],
[13,32,31,30,40,31,40,31,31,31,31,30,40,40,31,31,40,31,30,31],
[13,32,31,30,31,31,30,40,40,40,40,30,31,40,31,31,31,40,31,31],
[13,32,42,30,40,40,30,40,31,30,40,30,31,40,31,31,40,30,40,30],
[13,32,31,31,40,31,30,40,40,30,40,31,31,40,31,40,30,31,31,30],
[13,32,31,40,40,31,30,31,40,30,40,40,40,40,31,30,31,31,40,30],
[13,32,31,40,31,31,30,31,40,30,31,31,31,31,30,40,31,31,40,31],
[13,32,31,40,40,40,40,40,40,30,31,30,31,31,30,40,40,40,31,31],
[13,32,31,31,31,31,31,31,31,31,31,30,31,31,30,40,31,31,31,40],
];
var map8 = [
[31,40,40,31,31,31,30,31,31,30,30,30,30,30,30,40,40,40,40,40],
[30,30,31,31,40,40,40,30,31,30,40,30,30,30,30,31,31,30,31,40],
[40,40,30,40,40,30,40,40,30,40,31,30,30,40,40,40,40,30,31,40],
[30,40,30,30,30,30,30,30,40,31,31,40,40,40,40,40,40,30,30,31],
[31,30,30,30,40,30,30,40,31,31,30,40,31,40,40,30,40,30,31,30],
[31,30,30,30,30,40,40,31,31,40,30,30,31,40,30,30,40,40,31,30],
[31,30,30,30,30,31,40,31,30,30,40,40,40,40,30,30,30,40,31,40],
[30,31,40,40,30,30,40,30,30,30,30,30,30,31,30,40,31,31,31,40],
[30,40,31,40,40,40,40,30,30,30,30,30,31,31,30,30,31,40,30,40],
[40,30,31,30,31,31,40,30,30,40,40,30,40,40,30,40,40,30,30,40],
[30,30,30,30,30,30,30,30,40,30,30,30,30,30,30,30,40,40,40,40],
];
var map9 = [
[61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61],
[61,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,61],
[61,63,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,63,61],
[61,63,61,63,63,63,63,63,63,63,61,61,61,61,63,63,63,61,63,61],
[61,63,61,63,63,63,63,63,63,63,61,61,61,61,63,63,63,61,63,61],
[61,63,61,63,63,63,63,63,63,63,61,61,61,61,63,63,63,61,63,61],
[61,63,61,63,63,63,63,63,63,63,61,61,61,61,63,63,63,61,63,61],
[61,63,61,63,63,63,63,63,63,63,61,61,61,61,63,63,63,61,63,61],
[61,63,61,61,61,61,61,63,63,63,61,61,61,61,63,61,61,61,63,61],
[61,63,63,63,63,63,63,63,63,63,61,61,61,61,63,63,63,63,63,61],
[61,61,61,61,61,61,61,61,61,61,61,61,61,61,60,61,61,61,61,61],
];
var map10 = [
[61,61,61,61,61,61,61,61,61,61,61,61,61,61,60,61,61,61,61,61],
[63,61,63,63,64,63,64,63,61,64,63,63,63,63,64,63,63,63,63,63],
[63,61,63,63,63,63,63,63,61,61,63,64,63,63,63,61,61,61,61,63],
[63,61,61,61,61,63,64,61,63,61,63,63,61,63,64,61,64,63,61,64],
[63,63,61,64,63,63,61,64,63,63,61,64,61,63,63,61,64,64,61,63],
[63,61,61,61,63,61,63,64,61,63,63,63,61,63,63,61,63,63,61,61],
[63,61,64,63,63,63,63,63,63,61,63,61,63,63,61,63,63,64,61,63],
[63,63,63,61,61,63,63,61,64,61,63,61,63,61,63,63,63,64,61,64],
[63,61,61,61,61,63,61,63,63,61,63,61,63,63,63,63,61,61,61,63],
[63,61,64,63,61,61,61,63,64,61,63,63,61,61,63,63,61,63,64,63],
[63,61,64,63,63,63,61,64,63,64,63,63,61,63,60,63,63,64,64,63],
];
var map11 = [
[40,31,31,31,31,31,31,32,61,61,61,61,61,61,60,61,61,61,61,61],
[31,40,31,30,30,30,31,32,63,63,63,63,63,63,63,63,63,63,63,63],
[31,31,40,30,31,30,30,32,64,63,64,63,64,63,64,63,64,63,64,63],
[31,30,30,40,30,31,30,32,63,64,63,64,63,64,63,64,63,64,63,63],
[31,30,30,30,40,30,30,32,64,63,64,63,64,63,64,63,64,63,64,63],
[31,30,30,30,30,30,41,32,63,63,63,63,63,63,63,63,63,63,63,63],
[31,30,30,30,40,30,30,32,63,63,63,63,63,63,63,63,63,63,63,63],
[31,30,30,40,31,30,30,32,64,63,64,63,64,63,64,63,64,63,64,63],
[31,31,40,30,30,30,30,32,63,64,63,64,63,64,63,64,63,64,63,63],
[31,40,31,30,31,30,31,32,64,63,64,63,64,63,64,63,64,63,64,63],
[40,31,31,31,31,31,31,32,63,63,63,63,63,63,63,63,63,63,63,63],
];
マップ0~11はそれぞれ異なる地形でできています。
地形(タイル)マップの2次元配列(20×11)を3面ぶん定義。
配列の数字=タイルID(後で画像と当たり判定に使う)。
const COLS = 4;
const ROWS = 3;
var map = [map0,map1,map2,map9, map3,map4,map5,map10, map6,map7,map8,map11];
function neighborIndex(idx, dir) {
var r = Math.floor(idx/COLS), c = idx%COLS;
if (dir==='left' && c>0) return idx-1;
if (dir==='right' && c<COLS-1) return idx+1;
if (dir==='up' && r>0) return idx-COLS;
if (dir==='down' && r<ROWS-1) return idx+COLS;
return null;
}
エリアの並びを1本の配列に格納(上段から順に)。
neighborIndexは現在のエリアindexから上下左右の隣を計算。グリッド(COLS/ROWS)に依存する汎用ロジック。
var cv, gc, stage=0, px=10, py=5;
var onBoat = false;
var boatDir = 'up';
var landWalk = [1,2,3,4,5,13,14,32,60,63,64,65];
var seaTiles = [8,30,31];
var boatTiles = [41,42,43,44];
var blocked = [
6,7,9,10,11,12,20,21,22,23,24,34,35,36,37,38,39,40,50,51,52,53,54,55,56,
61,62,66,67,68,69,70,71,72,73,74,75
];
stage:現在エリア(map配列のindex)、px/py:プレイヤーのタイル座標。onBoat:乗船中か、boatDir:船の描画向き。当たり判定の中核徒歩OK:
landWalk(床・石床・花・丸太(上陸)・洞窟床・洞窟入口)船OK:
seaTiles(湖/暗い海)船タイル:
boatTiles(設置船;乗り込み用に踏み込める)完全不可:
blocked(木・壁・障害物・装飾) var imgForest, imgOnion, imgFloor, imgStone, imgWater, imgWell, imgTentA, imgTentB, imgFlower1, imgFlower2,
imgLake, imgRockEdge, imgWall1, imgWall2, imgWall3, imgWall4, imgWall5,
imgDarkSea1, imgDarkSea2, imgLog1, imgLog2, imgPillar1, imgPillar2, imgPillar3,
imgBush1, imgFood1, imgFood2, imgWaterRock, imgBoatL, imgBoatR, imgBoatU, imgBoatD,
imgShop1, imgShop2, imgShop3, imgShop4, imgShop5, imgCrate, imgCrate2,
imgStone2, imgStone3,
imgCaveGate, imgCaveWall1, imgCaveWall2, imgCaveFloor1, imgCaveFloor2, imgCaveFloor3,
imgCaveRock1, imgCaveRock2, imgCaveRock3, imgCaveHole, imgCaveSkel,
imgMinecart1, imgMinecart2, imgWeaponRack, imgSpearRack, imgArmor;
function init() {
cv = document.getElementById("field");
gc = cv.getContext("2d");
if ('imageSmoothingEnabled' in gc) gc.imageSmoothingEnabled = false;
imgForest = document.getElementById("imgForest");
imgOnion = document.getElementById("imgOnion");
imgFloor = document.getElementById("imgFloor");
imgStone = document.getElementById("imgStone");
imgWater = document.getElementById("imgWater");
imgWell = document.getElementById("imgWell");
imgTentA = document.getElementById("imgTentA");
imgTentB = document.getElementById("imgTentB");
imgFlower1 = document.getElementById("imgFlower1");
imgFlower2 = document.getElementById("imgFlower2");
imgLake = document.getElementById("imgLake");
imgRockEdge = document.getElementById("imgRockEdge");
imgWall1 = document.getElementById("imgWall1");
imgWall2 = document.getElementById("imgWall2");
imgWall3 = document.getElementById("imgWall3");
imgWall4 = document.getElementById("imgWall4");
imgWall5 = document.getElementById("imgWall5");
imgDarkSea1 = document.getElementById("imgDarkSea1");
imgDarkSea2 = document.getElementById("imgDarkSea2");
imgLog1 = document.getElementById("imgLog1");
imgLog2 = document.getElementById("imgLog2");
imgPillar1 = document.getElementById("imgPillar1");
imgPillar2 = document.getElementById("imgPillar2");
imgPillar3 = document.getElementById("imgPillar3");
imgBush1 = document.getElementById("imgBush1");
imgFood1 = document.getElementById("imgFood1");
imgFood2 = document.getElementById("imgFood2");
imgWaterRock = document.getElementById("imgWaterRock");
imgBoatL = document.getElementById("imgBoatL");
imgBoatR = document.getElementById("imgBoatR");
imgBoatU = document.getElementById("imgBoatU");
imgBoatD = document.getElementById("imgBoatD");
imgShop1 = document.getElementById("imgShop1");
imgShop2 = document.getElementById("imgShop2");
imgShop3 = document.getElementById("imgShop3");
imgShop4 = document.getElementById("imgShop4");
imgShop5 = document.getElementById("imgShop5");
imgCrate = document.getElementById("imgCrate");
imgCrate2= document.getElementById("imgCrate2");
imgStone2 = document.getElementById("imgStone2");
imgStone3 = document.getElementById("imgStone3");
imgCaveGate = document.getElementById("imgCaveGate");
imgCaveWall1 = document.getElementById("imgCaveWall1");
imgCaveWall2 = document.getElementById("imgCaveWall2");
imgCaveFloor1= document.getElementById("imgCaveFloor1");
imgCaveFloor2= document.getElementById("imgCaveFloor2");
imgCaveFloor3= document.getElementById("imgCaveFloor3");
imgCaveRock1 = document.getElementById("imgCaveRock1");
imgCaveRock2 = document.getElementById("imgCaveRock2");
imgCaveRock3 = document.getElementById("imgCaveRock3");
imgCaveHole = document.getElementById("imgCaveHole");
imgCaveSkel = document.getElementById("imgCaveSkel");
imgMinecart1 = document.getElementById("imgMinecart1");
imgMinecart2 = document.getElementById("imgMinecart2");
imgWeaponRack= document.getElementById("imgWeaponRack");
imgSpearRack = document.getElementById("imgSpearRack");
imgArmor = document.getElementById("imgArmor");
window.addEventListener("keydown", onKey);
fieldpaint();
}
<body>でプリロードした<img id="...">を全部まとめて取得し、描画で使い回し。Canvasの補間OFFでドットを鮮明に。
キーボード入力を
onKeyに登録→初回描画。 function onKey(e){
var code=e.keyCode;
if(code===90){
toggleBoat();
return;
}
var dx=px, dy=py, moved=false;
if(code===37){ dx--; boatDir='left'; moved=true; }
else if(code===38){ dy--; boatDir='up'; moved=true; }
else if(code===39){ dx++; boatDir='right'; moved=true; }
else if(code===40){ dy++; boatDir='down'; moved=true; }
else return;
if(inBounds(stage,dx,dy)){
if(canStep(stage,dx,dy)){
px=dx; py=dy;
afterMove(stage,px,py);
fieldpaint();
}
return;
}
var dir=edgeDirection(dx,dy), next=neighborIndex(stage,dir); if(next==null) return;
var nx=px, ny=py;
if(dir==='left'){nx=19;ny=py;} else if(dir==='right'){nx=0;ny=py;} else if(dir==='up'){nx=px;ny=10;} else if(dir==='down'){nx=px;ny=0;}
if(inBounds(next,nx,ny) && canStep(next,nx,ny)){
stage=next; px=nx; py=ny;
afterMove(stage,px,py);
fieldpaint();
}
}
function tileAt(st,x,y){ return map[st][y][x]; }
function isBlocked(t){ return blocked.indexOf(t)!==-1; }
function canStep(st,x,y){
var t = tileAt(st,x,y);
if(isBlocked(t)) return false;
if(onBoat){
return seaTiles.indexOf(t)!==-1 || t===32 || boatTiles.indexOf(t)!==-1;
}else{
return landWalk.indexOf(t)!==-1 || boatTiles.indexOf(t)!==-1;
}
}
function toggleBoat(){
var t = tileAt(stage,px,py);
if(!onBoat){
if(boatTiles.indexOf(t)!==-1) onBoat=true;
}else{
if(landWalk.indexOf(t)!==-1) onBoat=false;
}
fieldpaint();
}
function afterMove(st,x,y){
var t = tileAt(st,x,y);
if(onBoat && landWalk.indexOf(t)!==-1) onBoat=false;
}
function inBounds(st,x,y){ return y>=0 && y<map[st].length && x>=0 && x<map[st][y].length; }
function edgeDirection(x,y){ if(x<0)return'left'; if(x>19)return'right'; if(y<0)return'up'; if(y>10)return'down'; return null; }
onKey:矢印で移動/Zで乗降。
端を越えたら隣のエリアへ(着地点も通行チェック)。
canStep
blockedは即不可。乗船中は海/上陸/船タイルOK。
徒歩中はlandWalk/船タイルOK(船に乗るため踏み込める)。
toggleBoat:船タイル上で乗船、陸上で下船。
afterMove:陸に入った瞬間は自動下船(テンポよく)。
inBounds / edgeDirection:範囲&端方向のユーティリティ。
function fieldpaint(){
gc.fillStyle="#225522"; gc.fillRect(0,0,800,440);
for(var y=0;y<map[stage].length;y++){
for(var x=0;x<map[stage][y].length;x++){
var t = map[stage][y][x];
if(t===1||t===2) gc.drawImage(imgFloor,x*40,y*40,40,40);
else if(t===3) gc.drawImage(imgStone,x*40,y*40,40,40);
else if(t===13) gc.drawImage(imgStone2,x*40,y*40,40,40);
else if(t===14) gc.drawImage(imgStone3,x*40,y*40,40,40);
else if(t===4) gc.drawImage(imgFlower1,x*40,y*40,40,40);
else if(t===5) gc.drawImage(imgFlower2,x*40,y*40,40,40);
else if(t===6) gc.drawImage(imgForest,x*40,y*40,40,40);
else if(t===7) gc.drawImage(imgRockEdge,x*40,y*40,40,40);
else if(t===8) gc.drawImage(imgLake,x*40,y*40,40,40);
else if(t===9) gc.drawImage(imgWater,x*40,y*40,40,40);
else if(t===10) gc.drawImage(imgWell,x*40,y*40,40,40);
else if(t===11) gc.drawImage(imgTentA,x*40,y*40,40,40);
else if(t===12) gc.drawImage(imgTentB,x*40,y*40,40,40);
else if(t===20) gc.drawImage(imgWall1,x*40,y*40,40,40);
else if(t===21) gc.drawImage(imgWall2,x*40,y*40,40,40);
else if(t===22) gc.drawImage(imgWall3,x*40,y*40,40,40);
else if(t===23) gc.drawImage(imgWall4,x*40,y*40,40,40);
else if(t===24) gc.drawImage(imgWall5,x*40,y*40,40,40);
else if(t===30) gc.drawImage(imgDarkSea1,x*40,y*40,40,40);
else if(t===31) gc.drawImage(imgDarkSea2,x*40,y*40,40,40);
else if(t===32) gc.drawImage(imgLog1,x*40,y*40,40,40);
else if(t===33) gc.drawImage(imgLog2,x*40,y*40,40,40);
else if(t===34) gc.drawImage(imgPillar1,x*40,y*40,40,40);
else if(t===35) gc.drawImage(imgPillar2,x*40,y*40,40,40);
else if(t===36) gc.drawImage(imgPillar3,x*40,y*40,40,40);
else if(t===37) gc.drawImage(imgBush1,x*40,y*40,40,40);
else if(t===38) gc.drawImage(imgFood1,x*40,y*40,40,40);
else if(t===39) gc.drawImage(imgFood2,x*40,y*40,40,40);
else if(t===40) gc.drawImage(imgWaterRock,x*40,y*40,40,40);
else if(t===41) gc.drawImage(imgBoatL,x*40,y*40,40,40);
else if(t===42) gc.drawImage(imgBoatR,x*40,y*40,40,40);
else if(t===43) gc.drawImage(imgBoatU,x*40,y*40,40,40);
else if(t===44) gc.drawImage(imgBoatD,x*40,y*40,40,40);
else if(t===50) gc.drawImage(imgShop1,x*40,y*40,40,40);
else if(t===51) gc.drawImage(imgShop2,x*40,y*40,40,40);
else if(t===52) gc.drawImage(imgShop3,x*40,y*40,40,40);
else if(t===53) gc.drawImage(imgShop4,x*40,y*40,40,40);
else if(t===54) gc.drawImage(imgShop5,x*40,y*40,40,40);
else if(t===55) gc.drawImage(imgCrate,x*40,y*40,40,40);
else if(t===56) gc.drawImage(imgCrate2,x*40,y*40,40,40);
else if(t===60) gc.drawImage(imgCaveGate, x*40,y*40,40,40);
else if(t===61) gc.drawImage(imgCaveWall1, x*40,y*40,40,40);
else if(t===62) gc.drawImage(imgCaveWall2, x*40,y*40,40,40);
else if(t===63) gc.drawImage(imgCaveFloor1,x*40,y*40,40,40);
else if(t===64) gc.drawImage(imgCaveFloor2,x*40,y*40,40,40);
else if(t===65) gc.drawImage(imgCaveFloor3,x*40,y*40,40,40);
else if(t===66) gc.drawImage(imgCaveRock1, x*40,y*40,40,40);
else if(t===67) gc.drawImage(imgCaveRock2, x*40,y*40,40,40);
else if(t===68) gc.drawImage(imgCaveRock3, x*40,y*40,40,40);
else if(t===69) gc.drawImage(imgCaveHole, x*40,y*40,40,40);
else if(t===70) gc.drawImage(imgCaveSkel, x*40,y*40,40,40);
else if(t===71) gc.drawImage(imgMinecart1,x*40,y*40,40,40);
else if(t===72) gc.drawImage(imgMinecart2,x*40,y*40,40,40);
else if(t===73) gc.drawImage(imgWeaponRack,x*40,y*40,40,40);
else if(t===74) gc.drawImage(imgSpearRack, x*40,y*40,40,40);
else if(t===75) gc.drawImage(imgArmor, x*40,y*40,40,40);
else gc.drawImage(imgForest,x*40,y*40,40,40);
}
}
if(onBoat){
var boatImg = (boatDir==='left')?imgBoatL : (boatDir==='right')?imgBoatR : (boatDir==='up')?imgBoatU : imgBoatD;
gc.drawImage(boatImg, px*40, py*40, 40, 40);
}else{
gc.drawImage(imgOnion, px*40, py*40, 40, 40);
}
}
</script>
</head>
<body onload="init()">
<canvas id="field" width="800" height="440"></canvas>
<img id="imgForest" src="大きな木.png" style="display:none" />
<img id="imgOnion" src="人間.png" style="display:none" />
<img id="imgFloor" src="床.png" style="display:none" />
<img id="imgStone" src="石タイル.png" style="display:none" />
<img id="imgStone2" src="石タイル2.png" style="display:none" />
<img id="imgStone3" src="石タイル3.png" style="display:none" />
<img id="imgWater" src="水壁.png" style="display:none" />
<img id="imgWell" src="井戸.png" style="display:none" />
<img id="imgTentA" src="テントpng.png" style="display:none" />
<img id="imgTentB" src="テント2.png" style="display:none" />
<img id="imgFlower1" src="花1.png" style="display:none" />
<img id="imgFlower2" src="花2.png" style="display:none" />
<img id="imgLake" src="湖.png" style="display:none" />
<img id="imgRockEdge" src="周り岩.png" style="display:none" />
<img id="imgWall1" src="石壁1.png" style="display:none" />
<img id="imgWall2" src="石壁2.png" style="display:none" />
<img id="imgWall3" src="石壁3.png" style="display:none" />
<img id="imgWall4" src="石壁4.png" style="display:none" />
<img id="imgWall5" src="石壁5.png" style="display:none" />
<img id="imgDarkSea1" src="暗い海1.png" style="display:none" />
<img id="imgDarkSea2" src="暗い海2.png" style="display:none" />
<img id="imgLog1" src="丸太1.png" style="display:none" />
<img id="imgLog2" src="丸太2.png" style="display:none" />
<img id="imgPillar1" src="石柱1.png" style="display:none" />
<img id="imgPillar2" src="石柱2.png" style="display:none" />
<img id="imgPillar3" src="石柱3.png" style="display:none" />
<img id="imgBush1" src="草むら1.png" style="display:none" />
<img id="imgFood1" src="食材1.png" style="display:none" />
<img id="imgFood2" src="食材2.png" style="display:none" />
<img id="imgWaterRock" src="水岩.png" style="display:none" />
<img id="imgBoatL" src="船1.png" style="display:none" />
<img id="imgBoatR" src="船2.png" style="display:none" />
<img id="imgBoatU" src="船3.png" style="display:none" />
<img id="imgBoatD" src="船4.png" style="display:none" />
<img id="imgShop1" src="売店1.png" style="display:none" />
<img id="imgShop2" src="売店2.png" style="display:none" />
<img id="imgShop3" src="売店3.png" style="display:none" />
<img id="imgShop4" src="売店4.png" style="display:none" />
<img id="imgShop5" src="売店5.png" style="display:none" />
<img id="imgCrate" src="木箱.png" style="display:none" />
<img id="imgCrate2" src="木箱2.png" style="display:none" />
<img id="imgCaveGate" src="洞窟入口.png" style="display:none" />
<img id="imgCaveWall1" src="洞窟壁.png" style="display:none" />
<img id="imgCaveWall2" src="洞窟壁2.png" style="display:none" />
<img id="imgCaveFloor1" src="洞窟床1.png" style="display:none" />
<img id="imgCaveFloor2" src="洞窟床2.png" style="display:none" />
<img id="imgCaveFloor3" src="洞窟床3.png" style="display:none" />
<img id="imgCaveRock1" src="洞窟岩1.png" style="display:none" />
<img id="imgCaveRock2" src="洞窟岩2.png" style="display:none" />
<img id="imgCaveRock3" src="洞窟岩3.png" style="display:none" />
<img id="imgCaveHole" src="洞窟穴.png" style="display:none" />
<img id="imgCaveSkel" src="洞窟骸骨.png" style="display:none" />
<img id="imgMinecart1" src="トロッコ1.png" style="display:none" />
<img id="imgMinecart2" src="トロッコ2.png" style="display:none" />
<img id="imgWeaponRack" src="剣立て.png" style="display:none" />
<img id="imgSpearRack" src="槍立て.png" style="display:none" />
<img id="imgArmor" src="防具.png" style="display:none" />
</body>
</html>
fieldpaint:表示中エリアの20×11マスを走査し、タイルID→対応画像を描画。
最後にプレイヤー(徒歩=人、船=向きに合うスプライト)を重ねる。
<body onload="init()">で初期化。<img id="...">群は全スプライトのプリロード(display:none)。init()でID取得→drawImageへ。3.動作について(起動〜描画の流れ)
-
ページ読込 →
body onload="init()"が発火。 -
init():-
Canvas 取得&補間OFF
-
画像をIDで束ね取得
-
キーイベント登録
-
fieldpaint()実行
-
-
fieldpaint():-
表示中エリア(
stage)の20×11マスをIDに基づき描画 -
最後にプレイヤー(徒歩 or 船)を重ねる
-
-
キー入力:
-
矢印:移動→当たり判定→必要ならエリア遷移→再描画
-
Z:乗降(+上陸で自動下船)
4,参考文献・引用サイト
ぴぽや倉庫
ドット絵世界
DOT ILLOST
効果音ラボ