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

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

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

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Eclipse

Eclipseは、IBM社で開発された統合開発環境のひとつです。2001年11月にオープンソース化されました。 たくさんのプラグインがあり自由に機能を追加をすることができるため、開発ツールにおける共通プラットフォームとして位置づけられています。 Eclipse自体は、Javaで実装されています。

Processing

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

Q&A

解決済

1回答

2303閲覧

ProcessingのPAppletが正しく機能しない

tarutarupop

総合スコア20

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Eclipse

Eclipseは、IBM社で開発された統合開発環境のひとつです。2001年11月にオープンソース化されました。 たくさんのプラグインがあり自由に機能を追加をすることができるため、開発ツールにおける共通プラットフォームとして位置づけられています。 Eclipse自体は、Javaで実装されています。

Processing

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

0グッド

0クリップ

投稿2018/11/27 16:27

PApplet内の変数g(Pgraphics)がNullのまま処理が行われる。

Processingのアニメーションを練習するため簡単なクラスを作ったのですが、なぜかPAppletクラスの変数である

PGraphics g 

という変数が初期化されず、Nullのままなため、PAppletクラスを継承したTestPVectorellpse()を呼び出したときにPApplet
java.lang.NullPointerExceptionが発生します。
ざっとデバックしてみたのですが、なぜnullのままなのかまったくわかりません。そもそもPApplet内のどこでgが初期化されているのかすらわかりませんでした。

画面は、フレームは表示されるが、まったく更新されず灰色のまま特に動くことはありません。

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

java.lang.NullPointerException at processing.core.PApplet.ellipse(PApplet.java:12103) at usingProcessing.TestPVector.draw(TestPVector.java:40) at usingProcessing.RandomSpreadParticle.draw(RandomSpreadParticle.java:34) at processing.core.PApplet.handleDraw(PApplet.java:2429) at processing.awt.PSurfaceAWT$12.callDraw(PSurfaceAWT.java:1557) at processing.core.PSurfaceNone$AnimationThread.run(PSurfaceNone.java:313)

該当のソースコード

Processing

1public class RandomSpreadParticle extends PApplet { 2 int num = 1000; 3 TestPVector[] mys = new TestPVector[num]; 4 5 public static void main(String[] args) { 6 // TODO 自動生成されたメソッド・スタブ 7 PApplet.main(new String[] {RandomSpreadParticle.class.getName()}); 8 } 9 10 public void settings() { 11 size(800,600); 12 } 13 public void setup() { 14 frameRate(60); 15 for(int i = 0; i < num; i++) { 16 mys[i] = new TestPVector(); 17 mys[i].location.set(width/2.0f, height/2.0f); 18 mys[i].acceleration.set(random(-10, 10), random(-10, 10)); 19 mys[i].gravity.set(0.0f,0.1f); 20 mys[i].friction = 0.01f; 21 } 22 } 23 public void draw() { 24 fill(0, 31); 25 rect(0, 0, width, height); 26 noStroke(); 27 fill(255); 28 for(int i = 0; i < num; i++) { 29 mys[i].update_loc(); 30 mys[i].draw(); 31 mys[i].bounce(); 32 } 33 } 34} 35-------------------------------------------------------------------------------------------------------- 36 37public class TestPVector extends PApplet { 38 PVector location; 39 PVector acceleration; 40 PVector velocity; 41 PVector gravity; 42 PVector min; 43 PVector max; 44 float mass; 45 float friction; 46 float radius; 47 48 public TestPVector() { 49 mass = 1.0f; 50 friction = 0.01f; 51 radius = 4.0f; 52 //位置、加速度、速度、質量、初期の力を初期化 53 location = new PVector(0f, 0f); 54 velocity = new PVector(0f, 0f); 55 gravity = new PVector(0f, 0f); 56 acceleration = new PVector(0f, 0f); 57 //運動範囲 58 min = new PVector(0.0f,0.0f); 59 max = new PVector(width,height); 60 } 61 62 public void draw() { 63 ellipse(location.x, location.y,mass * radius * 2, mass * radius * 2); 64 } 65 66 public void update_loc() { 67 //加速度に重力を追加 68 acceleration.add(gravity); 69 //速度に運動量を追加 70 velocity.add(acceleration); 71 //運動量に摩擦力をかける 72 velocity.mult(1.0f-friction); 73 //位置に運応用を追加 74 location.add(velocity); 75 //加速度0 76 acceleration.set(0 ,0); 77 } 78 79 public void bounce() { 80 if(location.x > max.x) { 81 location.x = max.x; 82 velocity.x *= -1; 83 } 84 if(location.x < min.x) { 85 location.x = min.x; 86 velocity.x *= -1; 87 } 88 if(location.y > max.y) { 89 location.y = max.y; 90 velocity.y *= -1; 91 } 92 if(location.y < min.y) { 93 location.y = min.y; 94 velocity.y *= -1; 95 } 96 } 97 public void throughWall() { 98 if(location.x > max.x) { 99 location.x = max.x; 100 } 101 if(location.x < min.x) { 102 location.x = min.x; 103 } 104 if(location.y > max.y) { 105 location.y = max.y; 106 } 107 if(location.y < min.y) { 108 location.y = min.y; 109 } 110 } 111} 112

試したこと

入門本を参考に書いてるため難しいことはしていません。なので、ほとんどサンプルコードを参考に書いてます。デバッグはしたのですが、PApplet以外の箇所でnullが発生していることはなかったです。

補足情報(FW/ツールのバージョンなど)

eclipse32bit版の環境で動かしています。pleiadesでダウンロードしたので、おそらくjavaも32bit版だと思います。

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

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

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

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

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

guest

回答1

0

ベストアンサー

入門本を参考に書いてるため難しいことはしていません。

とはおっしゃいますが、ProcessingのプログラムをJavaとして記述している点、少々難しいことをしていると思います。ProcessingのフロントエンドはIDEとして貧弱なのでJavaのIDEを使いたくなる気持ちはわかりますが...

原因

ProcessingのプログラムをJavaで記述する場合、PAppletを継承したクラスは一つしか書かないようにすべきですが、ご質問のプログラムでは2つのクラスがそれぞれPAppletを継承したクラスとして定義されています。それが原因です。

Processingのプログラムを書いたり動かしたりする最も普通の方法は

(1) JavaのIDEではなくProcessingのフロントエンドを起動
(2) 変数や関数やクラスをトップレベルに直接記述する
(3) 長いプログラムになった場合は複数のタブに分けて記述する
(4) Processingのフロントエンドからプログラムを起動する

なのですが、これをJavaプログラムとして作成する場合、Processingのちょっとしたトリックについて知っておく必要があります。そのトリックとは

  • (A) Processingは暗黙的にスケッチのメインクラスを定義する

ご質問のコードでいえばRandomSpreadParticleがこれに当たります。

  • (B) トップレベルに記述した変数, 関数はメインクラスのフィールド, メソッドになる

RandomSpreadParticleのsetupやdrawなどがこれに当たります。

  • (C) トップレベルに記述したクラスはメインクラスの内部クラスになる

TestPVectorがこれに当たります。

質問者さんのコードは(A),(B)には対処しておられますが、(C)の配慮ができていません。

対処

TestPVectorを次のようにRandomSpreadParticleのinner class(※)として定義すると、Processingのフロントエンドで作成したプログラムと同様に動作します。

Java

1public class RandomSpreadParticle extends PApplet { 2 ... 3 4 class TestPVector { // PAppletを継承してはならない。またstaticであってはならない。 5 ... 6 void 任意のメソッド() { // drawという名前でもよいが任意の名前でよい。 7 ellipse(...); // PAppletのメソッドを呼び出せる 8 } 9 } 10}

つまりTestPVectorから呼び出した描画メソッドは実際はRandomSpreadParticleのインスタンスへの描画と解釈されるようになります。

※: inner class
Java言語仕様の用語です。個人ブログなどにはあるクラスの内側に定義したクラスのことを内部クラスと呼んでいるものがありますが、言語仕様ではそれをnested class(入れ子のクラス)と呼んでいます。言語仕様で定義されているinner classはstaticがついていないクラスのことですのでご注意ください。本件ではinner classでないとダメです。


余談:

対処にはinner classにする方法を書いたのですが・・・Javaのプログラムとしてみた場合この方法は嬉しくない点もあります。プログラムが複雑になるにつれ「一つのソースコードが巨大になりすぎる」点です。質問者さんの元のコードのように別のソースファイルに分けて記述したい場合もままあります。それに配慮した別の解決法も(正統的な方法から怪しい方法まで)いくつか考えられますが、長くなるので本回答では省略します。

投稿2018/11/27 22:06

KSwordOfHaste

総合スコア18394

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問