質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

1485閲覧

配列の表示をずらしたい

nano_09

総合スコア15

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2020/10/22 12:23

前提・実現したいこと

sub = getSubMap( 0, 0, MAP_WIDTH, MAP_HEIGHT );
この一つ目の引数を変更すると描画をずらすことができますが、引数の二つ目を変更しても上下にずらして描画することができません。
これはなぜでしょうか。
ご教授よろしくお願いいたします。

該当のソースコード

HTML

1<!DOCTYPE html> 2<html> 3 <head> 4 <meta charset="utf-8"> 5 <link rel="stylesheet" href="main.css"> 6 <script src="../../jquery-3.5.1.min.js"></script> 7 </head> 8 <body> 9 <canvas id="canvas"></canvas> 10 <script type="text/javascript" src="main.js"></script> 11 </body> 12</html>

JavaScript

1var map = [ 2 [ 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5], 3 [ 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6], 4 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 5 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 6 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 7 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 8 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 9 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 11 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 12 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 13 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 14 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 15 [ 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5], 16 [ 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6], 17]; 18 19var CHIP_WIDTH = 32; 20var CHIP_HEIGHT = 32; 21var IMG_CACHE = {}; 22 23var MAP_WIDTH = 29; 24var MAP_HEIGHT= 14; 25 26const 27 X_MAX = 33, 28 Y_MAX = 14 29; 30 31function getSubMap( left, top, width=3, height=3 ) { 32 let rect = [], tmp; 33 if( top > Y_MAX - height ) { 34 top = Y_MAX - height; 35 } 36 if( left > X_MAX - width ) { 37 left = X_MAX - width; 38 } 39 40 for( let y = top; y < top+height; ++y ) { 41 for( let x = left; x < left+width; ++x ) { 42 if( x == left ) { rect.push(tmp=[]); } 43 tmp.push( map[y][x] ); 44 } 45 } 46 return rect; 47} 48 49function main() { 50 var canvas = document.getElementById('canvas'); 51 canvas.width = CHIP_WIDTH * MAP_WIDTH; 52 canvas.height = CHIP_HEIGHT * MAP_HEIGHT; 53 54 var ctx = canvas.getContext('2d'); 55 56 IMG_CACHE["ground"] = new Image(); 57 IMG_CACHE["ground"].src = 'img/yuka1.png'; 58 59 ctx.fillStyle = "rgb( 0, 0, 0 )"; 60 ctx.fillRect(0, 0, CHIP_WIDTH*32, CHIP_HEIGHT*32); 61 62 sub = getSubMap( 0, 0, MAP_WIDTH, MAP_HEIGHT ); 63 64 for (var y=0; y<sub.length; y++) { 65 for (var x=0; x<sub[y].length; x++) { 66 if (sub[y][x] === 0) 67 ctx.drawImage(IMG_CACHE["ground"], 68 0, 0,CHIP_WIDTH, CHIP_HEIGHT, 69 CHIP_WIDTH*x,CHIP_HEIGHT*y,CHIP_WIDTH,CHIP_HEIGHT); 70 } 71 } 72 73 window.requestAnimationFrame( main ); 74 } 75window.addEventListener('load', main(), false); 76

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

AkitoshiManabe

2020/10/23 02:29

(0, 0) から、どのように変更させたのでしょうか。
nano_09

2020/10/23 13:21

左側は大丈夫なのですが、右側の値を正に増加させると変わらなく、負の増加させると真っ暗になります。 ここではないのでしょうか。
guest

回答1

0

ベストアンサー

これはなぜでしょうか。

getSubMap()関数の引数は、二次元配列 map のインデックス指定になります。
コードをよく読み、二次元配列のインデックスを考えてください。

負数任意の値に対応するmapから上下左右が繋がったような結果を得る)には、配列添字(インデックス値)の範囲を超えた場合についての 演算が必要です。

配列のインデックス値(配列添字)が取りうる範囲は ゼロ以上の整数ですので、
X, Y の両方について、1次方程式 を考えて書き換えてください。

追記)
map を大きなデータ(せめて 32x32マス分にするなど)にして試してください。
ご質問の map のサイズは 横x縦 で 29x18 であるのに対して、getSubMap( 0, 0, 29, 14 ); となっていますので、本来は上下方向に動き、左右方向に動かないのが正しいように思いますが。


なぜ?」と感じるのはプログラミングする上で大事なのですが、
徹底的に検証する事のほうが、もっと大事です。
以下のように、console.log() も活用して原因を究明します。

javascript

1function getSubMap( left, top, width=3, height=3 ) { 2 let rect = [], tmp; 3 /* omitted */ 4 for( let y = top; y < top+height; ++y ) { 5 for( let x = left; x < left+width; ++x ) { 6 if( x == left ) { rect.push(tmp=[]); } 7 8console.log( map.length, map[0].ength, x, y ); // 気になるデータを console に表示してみる 9 tmp.push( map[y][x] ); // map[y][x] を参照している 10 // => left, top に負数を与えると配列添字の範囲外なので「有り得ない」 11 // map.length ..... 15 (y の取りうる範囲は 0-14) 12 // map[y].length .. 29 (x の取りうる範囲は 0-28) 13 } 14 } 15 return rect; 16} 17 18 19/* omitted */ 20 21var sub = getSubMap( 0, 0, MAP_WIDTH, MAP_HEIGHT ); 22console.log( sub ); // 抽出した二次元配列を確認する。 23

意図した範囲を抽出できるまでは、画像を用いず、テキストでデータ表示するなど、データ加工処理に集中されたほうが良いと思います。
うまく動くようになってから、ctx.fillRect()でシンプルに表示、問題なければ画像に差し替えるという手順にする。

※ゲーム進行である window.requestAnimationFrame( main ); はコメントアウトし、正しく表示されるデータ加工ができてから実行します。

投稿2020/10/23 21:57

編集2020/10/25 22:44
AkitoshiManabe

総合スコア5434

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nano_09

2020/10/25 02:54

1次方程式を考えるということですが、では、topの値は整数ではだめだということですか?
AkitoshiManabe

2020/10/25 04:05

> topの値は整数ではだめだということですか いえ。整数です。「取りうる範囲は ゼロ以上の整数」と回答しています。 getSubMap() の if 文で left, top の範囲を制限しているはずですので、この条件式を考えて書き直す必要があります。
nano_09

2020/10/25 13:52

一応できたのですが、 なぜleftは正負どちらでも大丈夫なのにtopは負の整数になるとだめになるのでしょうか。
nano_09

2020/10/26 05:39

leftで配列の範囲を超えた値(-1や40等)を入れた場合、ずれて黒い画面とマップの描画がでますが、topで-1や30を入れた場合真っ黒になります。(こちらはわかる) 積分で上端下端での示し方はわからないのですみません。
AkitoshiManabe

2020/10/26 05:46

配列のインデックス (配列番号)に相当する引数に -1 を入れてはいけません。 コメント付きで追記していますのでコードを読み解いてください。 グローバル変数 map の二次元配列と、そこから取り出される sub(二次元配列)との関係、添字番号に注目してください。
AkitoshiManabe

2020/10/26 10:49 編集

ご質問では mapサイズ≒表示サイズなので、「そもそも、ずらす意味が無い」ように思います。 せめて32x32などの「大きいmap」を作り「ずらす意味をもたせる」データを考えるべきです。 例えば 初代ドラゴンクエストのフィールドマップは「120x120マス、画面表示は 13x13マス、チップサイズは8x8ピクセル」というように、参考にしたいゲームがあれば細かな数値を調査してデータを作成します。MAP https://codepen.io/AkitoshiManabe/pen/RwPZKJE (この例も、8x8のfillRect()だけで始めました)。 https://ja.wikipedia.org/wiki/%E3%83%89%E3%83%A9%E3%82%B4%E3%83%B3%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88 (ドラゴンクエストはチュンソフト、エニックス、スクエアエニックスの登録商標です)。 追記)https://codepen.io/AkitoshiManabe/pen/vYKxgjR
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問