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

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

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

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

Q&A

解決済

2回答

1726閲覧

Javaのスーパークラスとサブクラスに関する質問。

hikatyu1029

総合スコア7

Java

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

0グッド

0クリップ

投稿2015/07/04 08:39

今回、javaの課題でもぐら叩きのゲームを作るというものがでてきました。
ソースコードを変えたり書き足したりでもっといいものにしろというものです。
私はこのソースコードにすこし書き足しました。
それが以下のものになります。

特になんですがMoguraBの部分です。
新しく表示時間の短いものを作成したのはいいのですが左上に表示されるスコアが更新されません。
スーパークラスとサブクラスでのメソッドの扱いがわるいのでしょうか?

おねがいします。


import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.MouseEvent;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class MoguraPanel2 extends JPanel {
//もぐらたたきのターゲット
public class Mogura extends Canvas implements Runnable
{

//表示非表示を行うスレッド //新しいスレッドに変えると古いスレッドが停止する //run()ノif文参照 protected Thread thread; public Mogura(){ //MouseAdapterのmousePressed //processMouseEventを使うのに必要 enableEvents(MouseEvent.MOUSE_PRESSED); //初期化 init(); } //いったん非表示にして状態を初期化 //オブジェクト作成時とマウスでたたかれたときに使われる protected void init(){ //非表示 setVisible(false); //表示非表示スレッドを実行&threadに設定 //threadが上書きされ個々までのスレッドは停止する thread = new Thread(this); thread.start(); } //canvasクラスからのオーバーライド //MouseEventを扱うMouseAdapter以外のもうひとつの方法 //使うイベントをenableEventsで登録しておく //(コンストラクタ参照) protected void processMouseEvent(MouseEvent e){ //MousePressedの際に。 if(e.getID() == MouseEvent.MOUSE_PRESSED){ //得点を追加して(MoguraPanel2のメソッド) incScore(); //非表示にして状態を初期化 init(); } } //Runnableインターフェイスからのオーバーライド //表示非表示を繰り返す public void run(){ //無限ループ、threadが書き換わったら終了 for(;;){ int r=0; for ( int i = 0; i < 10; i++ ) { r = (int)(Math.random() * 3000) + 1; } try{ Thread.sleep(r); }catch(InterruptedException e){ e.printStackTrace(); } if(Thread.currentThread()!=thread){ break; } //見た目を設定して表示or非表示 //thread変数をチェック int r1=0,r2=0; for ( int i = 0; i < 10; i++ ) { r1 = (int)(Math.random() * 50) + 1; r2 = (int)(Math.random() * 50) + 1; } setBounds(r1*10,r2*10,50,50); setBackground(Color.RED); setVisible(!isVisible()); } } } //得点 protected int score = 0; public MoguraPanel2(){ //モグラたたきのエリアの設定 setPreferredSize(new Dimension(600,600)); //モグラいったいの配置 add(new Mogura()); add(new MoguraB()); add(new Mogura()); } //得点を得たときの挙動 protected void incScore(){ //得点更新 ++score; //得点表示更新 repaint(); } //Jpanelからのオーバーライド //中身の描写 public void paint(Graphics g){ //得点を表示 g.drawString("score:"+ score,10,10); //背景を描写 for(int i = 1;i <= 10; ++i){ g.drawOval(50-10*i, 50-10*i, 20*i, 20*i); } } public static void main(String[] args){ JFrame frame = new JFrame("Mogura"); frame.setContentPane(new MoguraPanel2()); frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE); frame.pack(); frame.setVisible(true); } public class MoguraB extends Mogura{//得点が4点のMoguraBを作成 public MoguraB(){ //MouseAdapterのmousePressed //processMouseEventを使うのに必要 enableEvents(MouseEvent.MOUSE_PRESSED); //初期化 init(); } protected void processMouseEvent(MouseEvent e){ //MousePressedの際に。 if(e.getID() == MouseEvent.MOUSE_PRESSED){ //得点を追加して(MoguraPanel2のメソッド) incScore2(); //非表示にして状態を初期化 init(); } } protected void incScore2(){ //得点更新 score=score+4; //得点表示更新 repaint(); } public void run(){ //無限ループ、threadが書き換わったら終了 for(;;){ int r=0; for ( int i = 0; i < 10; i++ ) { r = (int)(Math.random() * 1000) + 1; } try{ Thread.sleep(r); }catch(InterruptedException e){ e.printStackTrace(); } if(Thread.currentThread()!=thread){ break; } //見た目を設定して表示or非表示 //thread変数をチェック int r1=0,r2=0; for ( int i = 0; i < 10; i++ ) { r1 = (int)(Math.random() * 50) + 1; r2 = (int)(Math.random() * 50) + 1; } setBounds(r1*10,r2*10,50,50); setBackground(Color.BLUE); setVisible(!isVisible()); } } }

}

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

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

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

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

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

guest

回答2

0

ベストアンサー

スーパークラスとサブクラスで、
どのメソッドの扱いが変わるかを想定されているか分かりませんが、
端的に問題箇所を指摘するなら、

lang

1protected void incScore2(){ 2//得点更新 3score=score+4; 4//得点表示更新 5repaint(); 6}

MoguraBクラスのメソッドになっていることと思います。
動作させてはいないので、確実ではないですが、incScoreメソッドの直後に移動するなどして
MoguraPanel2のメソッドにすれば、得点表示は更新されると思います。

incScore2を移動しない場合、
repaintメソッドの呼び出しが.、MoguraBrepaintになるので、
MoguraBのみ再描画されてしまっているのだと思います。

incScore2を移動しないでも、repaint();MoguraPanel2.this.repaint();に変えれば、
動くとは思いますが、incScore2を移動する方がおすすめです。

投稿2015/07/04 10:05

編集2015/07/04 10:43
eripong

総合スコア1546

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

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

argius

2015/07/04 11:50

横から失礼します。 実際に動作させて、MoguraPanel2にincScore2を移動することで得点表示は更新されることを確認しましたのでお知らせします。
eripong

2015/07/04 11:53

おお、ありがとうございました!
hikatyu1029

2015/07/06 04:18

丁寧な回答ありがとうございます!! わからない部分がりかいできてたすかりました。
guest

0

一見した時に気になったのは
incScore() に synchronized が指定されていない
事です。
score の値更新処理 IncScore() は、複数のスレッドから呼ばれると思います。
その場合、incScore() に synchronized を指定しておかないと、
incScore() を呼んでも score 値が思ったとうりに更新されない事が発生すると思います。

投稿2015/07/04 12:22

katoy

総合スコア22324

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

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

eripong

2015/07/04 13:22

incScoreは、processMouseEventからしか呼ばれず、 processMouseEventは描画スレッドのみから呼び出されるので、 ここは問題ないはずです。 それより、initメソッドでスレッドを起こして、 その内部で描画コンポーネントを操作している(setBoundsなど)方が、 本当は気になります。 本来は、SwingUtilities.invokeLaterなど、使うべきところとは思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問