2017-11-29 14 views
-4

私は今、MySurfaceViewから変数を取得してPlayerクラスで使用しようとしています。私はそれを動作させることができないようです...私は私のMainActivityクラスからタッチ情報を取得しようとしましたが、それは本当に私がそれを望んでいないとも動作するように見えることができませんでした。どんな助けもありがとう!誰もがこのクラスから変数を得ることができない理由をいくつか明かすことができますか?

MySurfaceView.java

package com.Frenchie.SurfaceView; 

import ... 

public class MySurfaceView extends SurfaceView implements Runnable { 

    Bitmap bitmap; 
    SurfaceHolder surfaceHolder; 
    int LastTouchx; 

    Player player; 

    public MySurfaceView(Context context, AttributeSet attributeSet) { 
     super(context, attributeSet); 

     player = new Player(context); 

     surfaceHolder = getHolder(); 

     //Starts the run() 
     Thread TestThread = new Thread(this); 
     TestThread.start(); 
    } 


    @Override 
    public void run() { 
     //TODO movement here when display is working 
     while (true){ 
      Update(); 
      DrawPlayer(); 
     } 
    } 

    public void Update(){ 
     player.Update(); 
    } 

    public void DrawPlayer(){ 

     Canvas canvas = surfaceHolder.lockCanvas(); 

     if (surfaceHolder.getSurface().isValid()) { 

      canvas.drawColor(Color.BLUE); 
      canvas.drawBitmap(player.getBitmap(), player.getX(), player.getY(), null); 
      surfaceHolder.unlockCanvasAndPost(canvas); 
     } 
     else{ 

      Log.d("DrawPlayer", "Surface Not Valid"); 
     } 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     LastTouchx = (int)event.getX(); 
     //LastTouchy= (int)event.getY(); 
     Log.d("Touch Value ",LastTouchx+""); 
     return false; 
    } 

    public int getLastTouchx() { 
     return LastTouchx; 
    } 

} 

Player.java

package com.Frenchie.SurfaceView; 

import ... 

public class Player { 
    //Bitmap to get character from image 
    private Bitmap bitmap; 

    //coordinates 
    private int x; 
    private int y; 

    //motion speed of the character 
    private int speed = 0; 

    MySurfaceView mySurfaceView; 

    //constructor 
    public Player(Context context) { 
     x = 75; 
     y = 500; 

     //Getting bitmap from drawable resource 
     bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.player); 
    } 

    //Method to update coordinate of character 
    public void Update(){ 

     //updating x coordinate 

     if (x > mySurfaceView.getLastTouchx()){ 
      x++; 
     } 
     else if (x < mySurfaceView.getLastTouchx()){ 
      x--; 
     } 
     else{ 

      Log.d("Update","Else triggered"); 
     } 

    } 

    public Bitmap getBitmap() { 
     return bitmap; 
    } 

    public int getX() { 
     return x; 
    } 

    public int getY() { 
     return y; 
    } 
} 

メッセージ

E/AndroidRuntime: FATAL EXCEPTION: Thread-4 
    Process: com.Frenchie.SurfaceView, PID: 26348 
    java.lang.NullPointerException: Attempt to invoke virtual method 'int com.Frenchie.SurfaceView.MySurfaceView.getLastTouchx()' on a null object reference 
     at com.Frenchie.SurfaceView.Player.Update(Player.java:36) 
     at com.Frenchie.SurfaceView.MySurfaceView.Update(MySurfaceView.java:68) 
     at com.Frenchie.SurfaceView.MySurfaceView.run(MySurfaceView.java:62) 
     at java.lang.Thread.run(Thread.java:762) 

これではなかったです投稿の重複が示唆された。

答えて

0

試してみてください。あなたのMySurfaceViewで

MySurfaceView mySurfaceView = new MySurfaceView(); 
+0

プレーヤークラスの元の呼び出しをこれで置き換えると、次のエラーが表示されます。エラー:(19、35)エラー:コンストラクターMySurfクラスMySurfaceViewのaceViewは、指定された型には適用できません。 必須:コンテキスト、AttributeSet found:引数なし 理由:実際の引数リストと仮引数リストの長さが異なる – Frenchie

+0

空のコンストラクタを 'MySurfaceView.java'で定義してみてください –

+0

ビューをオーバーライドするときはいつでも、コンストラクタもオーバーライドする必要があります。あなたのプレーヤーであなたはmySurfaceViewを初期化していません –

1

オーバーライド別のコンストラクタ:コンストラクタでのプレーヤーで

public class MySurfaceView extends SurfaceView 
    ... 
    public MySurfaceView(Context context) { 
     this(context, (AttributeSet)null) 
    } 

    public MySurfaceView(Context context, AttributeSet attributeSet) { 
      super(context, attributeSet); 
      player = new Player(context, this); 
      bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.player); 
      surfaceHolder = getHolder(); 
      //Starts the run() 
      Thread TestThread = new Thread(this); 
      TestThread.start(); 
     } 
     ... 

あなたがsurfaceViewを渡すことができます:初期化するので、必要はありません:

MySurfaceView mySurfaceView; 

    //constructor 
    public Player(Context context, MySurfaceView surfaceView) { 
     this.mySurfaceView = surfaceView; 
     x = 75; 
     ... 
+0

本当にありがとうございました!あなたはこの作品の仕方についていくつかの光を当てることができるでしょうか?正解とマークする。 – Frenchie

+1

@Frenchieビュー自体は、親のコンストラクタをオーバーライドする必要があります。カスタムビューをxmlで宣言した場合、2つ以上のparamsを持つコンストラクタの1つがOSによって呼び出されます。プログラムでは、単純なコンストラクタのView(コンテキスト)を使用してビューを作成し、setterを使用して属性を設定します。 –

+1

@Frenchieあなたのプレーヤクラスはサーフェイスビューに依存しますので、上記のようにサーフェイスビューをプレーヤクラスで作成するか、コンストラクタを使用して挿入する必要があります。おそらくこれを行う最良の方法は、順序を変更してロジックをPlayerに置き、SurfaceViewを単純化することです –

関連する問題