2017-11-29 15 views
-4

저는 Player 클래스에서 사용하기 위해 MySurfaceView에서 변수를 가져 오려고했습니다. 나는 그것을 작동하게하는 것 같지 않습니다 ... 내 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 = new MySurfaceView(); 
+0

내 플레이어 클래스의 원래 호출을 다음과 같이 바꾸면 다음 오류가 발생합니다. 오류 : (19, 35) 오류 : 생성자 MySurf MySurfaceView 클래스의 aceView는 지정된 유형에 적용 할 수 없습니다. 필수 : ​​Context, AttributeSet found : 인수 없음 이유 : 실제 및 형식 인수 목록의 길이가 다릅니다. – Frenchie

+0

'MySurfaceView.java'에서 빈 생성자 정의 –

+0

보기를 무시할 때마다 생성자도 재정의해야합니다. 플레이어에서 초기화하지 않았다면 Surfaceview –

1

재정 당신의 MySurfaceView의 다른 생성자 : 생성자 플레이어에서

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로 선언했다면 두 개 이상의 params가있는 생성자 중 하나가 OS에 의해 호출됩니다. 프로그래밍 방식으로 간단한 생성자보기 (컨텍스트) 및 설정자로 속성을 설정하여보기를 만듭니다. –

+1

@Frenchie 플레이어 클래스는 표면 뷰에 따라 다르므로, 위에서 한 것처럼 surfaceView를 플레이어 클래스에서 생성하거나 생성자를 사용하여 삽입해야합니다. 아마도이를 수행하는 가장 좋은 방법은 순서를 바꾸고 로직을 플레이어에 넣고 SurfaceView를 단순하게 만드는 것입니다 –