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

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

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

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

Q&A

解決済

2回答

1910閲覧

弾幕ゲームの作成に関して

plarex

総合スコア12

Processing

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

0グッド

0クリップ

投稿2018/05/02 07:02

processingでのゲーム作成

初めて投稿します。
最近processingを勉強し始め、ゲームを作るという課題が出て、私は弾幕シューティングゲームを作ろうと思い、作成している最中なのですが、弾を放射状に打ち出すことはできたのですがこれを画面上部(上部にボス的なものを配置する予定)から、なおかつ連続で打ち出すにはどのようにコードを書けばいいのでしょうか?

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

### 該当のソースコード Bullet bullet; ArrayList danmaku; void setup() { size(320, 480); frameRate(30); noCursor(); // clear mouse cursor bullet = new Bullet(width/2, height/2, 10, 0, 0 ); //クラスからインスタンスを生成 danmaku = new ArrayList(); //クラスから36個インスタンスを生成 for (int i = 0; i < 360; i+= 10) { float rad = radians(i); danmaku.add(new Bullet(width/2, height/2, 10, cos(rad), sin(rad))); } } // my ship function void ship(int x, int y) { stroke(255, 255, 255); noFill(); triangle(x, y -7, x - 10, y + 7, x + 10, y + 7); if (mousePressed) { line(x, y - 7, x, 0); } } // Bullet class class Bullet { float tx, ty, tr, dx, dy; Bullet(float x, float y, float r, float temp_dx, float temp_dy ) { tx = x; ty = y; tr = r; dx = temp_dx; dy = temp_dy; } void update() { tx += dx; ty += dy; stroke(255, 0, 0); ellipse(tx, ty, tr, tr); } } void draw() { background(0); // clear ship(mouseX, mouseY); for (int i = danmaku.size() -1; i >= 0; i--) { Bullet b = (Bullet)danmaku.get(i); b.update(); } } ```ここに言語名を入力 processing ### 試したこと ### 補足情報(FW/ツールのバージョンなど)

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

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

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

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

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

guest

回答2

0

ベストアンサー

上部にボス的なものを配置する予定

こういう場合(文章中に主語が出てきた場合)は専用のクラスを作成するとコードの管理が楽になります。
今回の場合はBossクラスになるかと。
Bossクラスは任意のタイミングで、弾幕を貼る。そのようなコードになります。

発射した弾の生存管理方法はいろいろな手法がありますが、
描画範囲外になったら生存フラグをfalseにして、描画時にリストから削除する形が楽かと。

あと変数の型をdouble型ではなくfloat型で宣言するのは、
宗教上の理由などがある場合を除き、float型の精度に起因する余計なトラブルを持ち込みむため、避けたほうが無難です。
この精度についての問題について、日本語で体系的に纏まっている情報としては2008年に出版された本ですが、「ゲームプログラマになる前に覚えておきたい技術」が纏まっています。
「ゲームプログラマになる前に覚えておきたい技術 float 中途半端な数による誤差」でキーワード検索してみてくださいな。

サンプルコードです。ご参考まで。

Java

1Bullet bullet; 2private Boss boss = new Boss(100, 150); 3private ArrayList<Bullet> danmaku = new ArrayList<Bullet>(); 4 5void setup() { 6 size(320, 480); 7 8 frameRate(30); 9 10 noCursor(); // clear mouse cursor 11 12 bullet = new Bullet(width/2, height/2, 10, 0, 0 ); //クラスからインスタンスを生成 13 14} 15// my ship function 16 17void ship(int x, int y) { 18 19 stroke(255, 255, 255); 20 21 noFill(); 22 23 triangle(x, y -7, x - 10, y + 7, x + 10, y + 7); 24 25 if (mousePressed) { 26 line(x, y - 7, x, 0); 27 } 28} 29class Boss { 30 private int tx, ty; 31 private int dx, dy; 32 private long routine = 0; 33 Boss(int x, int y) { 34 tx = x; 35 ty = y; 36 dx = 1; 37 dy = -5; 38 } 39 void move(){ 40 tx += dx; 41 ty += dy; 42 if(tx < 0 || tx > width){ 43 dx*= -1; 44 } 45 if(ty < 0 || ty > height){ 46 dy*= -1; 47 } 48 } 49 void doShinking(){ 50 routine++; 51 if(routine % 10 == 0){ 52 move(); 53 } 54 if(routine % 30 == 0){ 55 danmaku.addAll(this.shot()); 56 println("#shot!!" +routine + ":" + tx + "," + ty); 57 } 58 } 59 ArrayList<Bullet> shot() { 60 ArrayList<Bullet> danmaku = new ArrayList(); 61 for (int i = 0; i < 360; i+= 10) { 62 double rad = radians(i); 63 danmaku.add(new Bullet(this.tx, this.ty, 10, Math.cos(rad), Math.sin(rad))); 64 } 65 return danmaku; 66 } 67} 68// Bullet class 69 70class Bullet { 71 72 private double tx, ty; 73 private final double tr; 74 private double dx, dy; 75 private boolean is_alive = true; 76 Bullet(double x, double y, double r, double temp_dx, double temp_dy ) { 77 tx = x; 78 ty = y; 79 tr = r; 80 dx = temp_dx; 81 dy = temp_dy; 82 } 83 boolean isAlive(){ 84 return is_alive; 85 } 86 void update() { 87 tx += dx; 88 ty += dy; 89 if(Math.min(tx, ty) < 0){ 90 is_alive = false; 91 //println("#" + tx + "," + ty); 92 return ; 93 } 94 if(tx > width || ty > height){ 95 is_alive = false; 96 return ; 97 } 98 stroke(255, 0, 0); 99 100 ellipse((float)tx, (float)ty, (float)tr, (float)tr); 101 } 102} 103 void draw() { 104 background(0); // clear 105 106 ship(mouseX, mouseY); 107 boss.doShinking(); 108 109 for (int i = danmaku.size() -1; i >= 0; i--) { 110 Bullet b = (Bullet)danmaku.get(i); 111 if(!b.isAlive()){ 112 danmaku.remove(i); 113 continue; 114 } 115 b.update(); 116 } 117 }

投稿2018/05/02 12:26

編集2018/05/03 10:17
umyu

総合スコア5846

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

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

KSwordOfHaste

2018/05/04 05:51

Processing固有の仕様なのですが、doubleよりfloatを優先しているのはご存知と思います。Processing固有の初等関数(cos, sinとか)も引数型はfloatなんですよね・・・。自分も初めて触った時「なぜfloat?」と思ったのですが、高精度な計算を必要としない応用が多いのかなぁなんて思いました。
plarex

2018/05/04 07:32 編集

もしよろしければ、もう1つの質問も答えてくださると幸いです。
KSwordOfHaste

2018/05/04 07:20 編集

もう1つの回答とは?ひょっとして自分のコメントに関係しますでしょうか? --- 失礼しました。勘違いしてました。
umyu

2018/05/04 07:36

>KSwordOfHasteさんへ どうなんでしょうねー。Processingの登場が2001年なので、その当時のマシンスペックではfloat型で扱うのが正義だった可能性もあるかと。
KSwordOfHaste

2018/05/04 07:52

初リリースが2008年とかだったのでそうまで古くないのかと思ってましたが2001年なんですか!なんだか宗教上の理由な気がw;
guest

0

setupはアプリケーション開始時に一度だけ、drawは何度も(フレームレートに指定した頻度で)呼び出されます。

ゲーム中に自動的に(連続的に)何かをする(弾を発射する)ならdrawに何かを書かないといけないことになるでしょう。

弾はある時間間隔で発射すると考えればよいでしょうね。というわけでdrawが呼び出された時、「今弾を発射すべきか」「まだ発射すべきでないか」を判断する必要があります。

ご質問のコードではフレームレートを30にしているのでdrawは1秒間に概ね30回ほど呼び出されます。仮にdrawが呼び出される度に1ずつ値を増加させるような変数を用意しておくと、その変数が15増える度に弾を発射することにすれば(概ね)0.5秒ごとに弾が発射できる・・・こんなふうに考えます。

また弾の位置はBulletクラスのコンストラクターの第一、第二引数に指定してますね?今のコードではwidth/2, height/2を指定しています。この式の意味はわかりますね?では上の方の座標を指定するのはどうしたらよいでしょうか?考えてみてください。

このように、どうしたら「必要な処理」「必要な判定」「必要な値の計算」が行えるか考えながらプログラムを作ってみてください。

投稿2018/05/02 07:24

KSwordOfHaste

総合スコア18394

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問