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

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

新規登録して質問してみよう
ただいま回答率
85.35%
スクロール

スクロールとは、ディスプレイスクリーン上において連続的にコンテンツが滑っていくことを指します。

ループ

ループとは、プログラミングにおいて、条件に合致している間、複数回繰り返し実行される箇所や、その制御構造を指します

Processing

Processingは、オープンソースプロジェクトによるCGのためのプログラミング言語です。Javaをベースにしており、グラフィック機能に特化しています。イメージの生成やアニメーションなど、視覚的なフィードバックを簡単に得ることが可能です。

Q&A

解決済

2回答

4205閲覧

processing 縦スクロールのやり方

RY54828

総合スコア2

スクロール

スクロールとは、ディスプレイスクリーン上において連続的にコンテンツが滑っていくことを指します。

ループ

ループとは、プログラミングにおいて、条件に合致している間、複数回繰り返し実行される箇所や、その制御構造を指します

Processing

Processingは、オープンソースプロジェクトによるCGのためのプログラミング言語です。Javaをベースにしており、グラフィック機能に特化しています。イメージの生成やアニメーションなど、視覚的なフィードバックを簡単に得ることが可能です。

1グッド

0クリップ

投稿2021/11/27 17:55

前提・実現したいこと

決められた範囲の中で同じ画像が縦にループするようにしたいです。

発生している問題・エラーメッセージ

範囲外に余計なものがでてきてしまう。

該当のソースコード

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/ツールのバージョンなど)

最近使い始めたばかりの初心者です。

TN8001👍を押しています

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

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

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

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

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

guest

回答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 描画先の高さ

わたしは途中で分かんなくなりました^^;
わかりやすいところから埋めて、難しいところは図でも書いて落ち着いて考えましょう。
今回の場合はsxswdxdwは自明です。shdhは同じ値になります。


あらかじめ縦に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
TN8001

総合スコア9862

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

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

TN8001

2021/11/28 00:33

マスクとかでもっと簡単にやる方法もあるんですかね?w
RY54828

2021/11/28 01:32

TN8001様 ご丁寧にありがとうございました。回答してくださった内容をもとに改めて自分で挑戦してみます。
thkana

2021/11/28 01:36

酷いですね>参照先 そもそも「自動」スクロールって何と思いますが、しばらく放置しておくと真っ黒。ちょっと動かして「あ~動いた動いた」で終わりにしたのがよくわかる。 マスクは、PGraphicsとか使って「仮想画面」の話になりがちなので、一度つかめば感覚的にはわかりやすいですが説明は結構大変かも。
TN8001

2021/11/28 01:43

@thkanaさん OpenProcessingとかを見ていてもプログラマ目線(プロではありませんがw)で見ると、「うぎゃ~!」ってのが結構あります。 でもまあアートですから「まあいいんじゃない?」と思いつつ、手元では超リファクタしちゃいますw
guest

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
thkana

総合スコア7703

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問