前提・実現したいこと
決められた範囲の中で同じ画像が縦にループするようにしたいです。
発生している問題・エラーメッセージ
範囲外に余計なものがでてきてしまう。
該当のソースコード
processing
PImage img1;
PImage img2;
float y =0, speed = 3;
void setup() {
fullScreen();
background(#42A1BC);
img1=loadImage("sekaichizu.png");
img2=loadImage("12dd5f5ec9b518b91da031fb472d446b_t.jpeg");
}
void draw() {
//image(img1, 100, 100);
image(img2,width3/4,height2/3,width/3,height/2);
//background(#42A1BC);
y += speed;
if (y>0) {
for (int i=0; i<30; i++) {
image(img2, width3/4, height2/3, width/3, y-height/2*i);
}
}
image(img1, 100, 100);
}
試したこと
スクロールに影響していると思われる部分の値や掛け方を変えてみたりした。
補足情報(FW/ツールのバージョンなど)
最近使い始めたばかりの初心者です。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答2件
0
ベストアンサー
【Processing】画像を自動スクロールさせる方法|バイラルメディア「EVENING」|note
こちらを参考にされたようですね(参考にしたものがある場合は、質問に明示してください)
しかし書かれたご本人もよくわかっていないようで、あまりいい記事とは言えませんね。。。
何事も積み重ねです。順番にやっていきましょう。
まずは単純に下がっていく画像を出してみましょう。これは簡単ですね。
image(img, 200, 100 + y);
のような感じになるでしょう。
でも下がりっぱなしで画面外に行ってしまいました。。。
ある程度下がったらまた上に戻ってくれないと、スクロールになりません。
増え続けるy
をある範囲の繰り返しにするには、剰余(%
)を使うのが常套手段です。
Reference / % (modulo) / Processing.org
image(img, 350, 100 + (y % img.height));
といった感じです(画像高さ分下がったらまた戻る)
次は下がって足りなくなった部分を補います。
もう1枚同じ画像を上に描画するようにしてみます。
Processing
1image(img, 500, 100 + (y % img.height)); 2image(img, 500, 100 + (y % img.height) - img.height);
こんな感じでしょう。もうお気づきでしょうか?
image()
関数は描画位置や大きさは指定できますが、一部を切り出すような方法はありません。
Reference / image() / Processing.org
そのため背景のスクロールのような場合はいいのですが(はみ出しても画面外)、今回のような部分スクロールにはfor
しようが引数をいじろうが絶対にならないのです。
もちろんはみ出した部分を何かで上書きして隠せる場合は、それで十分でしょう。
では方法はないのかというと、一部を切り出すような関数も用意されています。
Reference / copy() / Processing.org
非常に柔軟な指定法ができるのですが、その分引数も多いです。
copy(src, sx, sy, sw, sh, dx, dy, dw, dh)
です。
src
画像
sx
画像の使いたい位置の左上隅のX座標
sy
画像の使いたい位置の左上隅のY座標
sw
画像の使いたい幅
sh
画像の使いたい高さ
dx
描画先の左上隅のX座標
dy
描画先の左上隅のY座標
dw
描画先の幅
dh
描画先の高さ
わたしは途中で分かんなくなりました^^;
わかりやすいところから埋めて、難しいところは図でも書いて落ち着いて考えましょう。
今回の場合はsx
・sw
・dx
・dw
は自明です。sh
・dh
は同じ値になります。
あらかじめ縦に2つ並べた画像を作っておくと、だいぶ楽になるかもしれません。
copy
が1回で済みますし、ほとんどの引数が自明になってsy
だけ考えればよくなります。
Processing
1PImage img, img2; 2float y = 0; 3float speed = 1; 4 5 6void setup() { 7 size(800, 400); 8 9 // 95*95px 10 img = loadImage("https://teratail-v2.storage.googleapis.com/uploads/avatars/u13/132786/KnkDDC5A_thumbnail.jpg"); 11 12 // あらかじめ縦に2つ並べた画像を作っておく 13 PGraphics pg = createGraphics(img.width, img.height * 2); 14 pg.beginDraw(); 15 pg.image(img, 0, 0); 16 pg.image(img, 0, img.height); 17 pg.endDraw(); 18 img2 = pg.get(); 19} 20 21void draw() { 22 background(0); 23 24 // 左端 オリジナル画像 25 image(img, 50, 100); 26 27 28 // 左から2番目 単純に下げてみる 29 image(img, 200, 100 + y); 30 31 32 // 左から3番目 下がりっぱなしでなく、ちゃんとループするようにする 33 image(img, 350, 100 + (y % img.height)); 34 35 36 // 左から4番目 足りなくなるところを、もう一枚追加して補う 37 image(img, 500, 100 + (y % img.height)); 38 image(img, 500, 100 + (y % img.height) - img.height); 39 40 41 // 右端 はみ出ないように、位置・サイズを調整して描画 42 // copy(src, sx, sy, sw, sh, dx, dy, dw, dh) 43 copy(img, 0, 0, img.width, img.height - int(y % img.height), 44 650, 100 + int(y % img.height), img.width, img.height - int(y % img.height)); 45 46 copy(img, 0, img.height - int(y % img.height), img.width, int(y % img.height), 47 650, 100, img.width, int(y % img.height)); 48 49 50 // 右下 事前に縦に2つ並べた画像から1つ分を切り出す 51 // copyが1回で済むし、ほとんどの引数が自明になってsyだけ考えればよい 52 copy(img2, 0, img2.height / 2 - int(y % (img2.height / 2)), img2.width, img2.height / 2, 53 650, 250, img2.width, img2.height / 2); 54 55 // こうではない(スクロールが逆になる) 56 //copy(img2, 0, int(y % (img2.height / 2)), img2.width, img2.height / 2, 57 // 800, 100, img2.width, img2.height / 2); 58 59 60 y += speed; 61}
投稿2021/11/28 00:33
編集2023/07/29 10:24総合スコア9862
0
質問の編集画面に入り、コード部分を選択して、<code>を押してください( ヘルプを参照。スマホの場合は...知りません)。そうすると、コード部分が区切られてインデントも表示され、非常に見やすくなります(というかそうでないのが見にくい)
それと、
範囲外に余計なものがでてきてしまう。
あなたがどういう画面を得られたら満足なのか、「縦スクロール」という言葉以外には示されていませんし、あなたのローカルの画像ファイルを読み込むサンプルプログラムではどんな画になるのか私には想像もつきません。
「範囲」とはなんの範囲ですか? 「余計」とは? スクリーンショットを示すとか、あるいは手で簡単な説明の画を描いてもいいですけど、「何も知らない相手」に説明するのだ、ということを考えてみてください。
ちょっと質問の範囲からは外れるかも知れませんが
Processing
1//冒頭の操作(<code>)でこういう表示になります 2 for (int i=0; i<30; i++) { 3 image(img2, width*3/4, height*2/3, width/3, y-height/2*i); 4 } 5
image関数の第5パラメータ、画像の高さですが、例えばいわゆるFullHDのディスプレイだったとすると
y=3,i=0のとき3
y=3,i=1のとき-537
y=3,i=2のとき-1077
y=3,i=1のとき-1617
...
と、多分どんどん大きな負の値になるかと思いますが、それは意図したものですか? (画像の高さに負の値を与えるとなにが表示されるんだろう? 画像がひっくり返るんだっけ?)
TN8001さんの回答みてて、そう言えばgetで切り出しってできなかったっけ? ということで試してみたもの。ご参考まで。
Processing
1PImage single; 2PImage quad; 3int w, h; 4float x = 0, vx = 0.05; //値は適宜いじってみてください 5float y = 0, vy = -0.5; 6 7void setup() { 8 size(640, 480); 9 //文字列を切っているのは単にソースコードの横幅を抑えるため 10 single = loadImage("https://teratail-v2.storage.googleapis.com/uploads/"+ 11 "avatars/u10/107752/752e11b31475761a_thumbnail.png"); 12 w=single.width; //よく使うので見やすくするため 13 h=single.height; 14 image(single, 0, 0);//4枚並べて表示 15 image(single, 0, h); 16 image(single, w, 0); 17 image(single, w, h); 18 //画面外にはみ出す場合はgetで画素が取れないので 19 //PGraphicsで仮想画面とか考える必要あり(今回は大丈夫) 20 quad=get(0, 0, w*2, h*2);//並べた画像を取り込む 21 background(0); //小細工の証拠隠滅 22 noFill(); 23 stroke(0, 255, 0); 24} 25 26void draw() { 27 int x0=50; 28 int y0=height/2-h;//上下真ん中に表示したい 29 int x1=350; 30 int y1=height/2-h/2; 31 32 background(0); 33 34 //この2行は切り出し位置を表示しているだけ 35 image(quad, x0, y0); 36 rect(x+x0, y+y0, w, h); 37 38 //getで切り出した部分画像を表示 39 image(quad.get((int)x, (int)y, w, h), x1, y1); 40 41 //切り出し位置更新 42 x=x+vx; 43 if (x<0)x=w; 44 if (x>w)x=0; 45 y=y+vy; 46 if (y<0)y=h; 47 if (y>w)y=0; 48}
投稿2021/11/28 00:11
編集2021/11/28 02:28総合スコア7703
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/11/28 00:33
2021/11/28 01:32
2021/11/28 01:36
2021/11/28 01:43