2016-09-21 2 views
1

Für meinen Pong-Klon versuche ich eine benutzerdefinierte Ansicht von der Klasse Ball auf meine View in der Klasse GamePanel zu zeichnen. Allerdings ist es zur Laufzeit nirgendwo auf dem Bildschirm zu sehen.Wie zeichnen Sie eine benutzerdefinierte Ansicht (z. B. Kreis) in einer Ansicht?

public class Ball extends View { 

private float posX; 
private float posY; 
private float radius; 

private Paint paint; 

public Ball(Context context, float posX, float posY, float radius){ 
    super(context); 
    this.posX = posX; 
    this.posY = posY; 
    this.radius = radius; 
    setWillNotDraw(false); 
    init(); 

} 

private void init(){ 

    paint = new Paint(); 
    paint.setColor(Color.WHITE); 
} 

@Override 
protected void onDraw(Canvas canvas) { 

    canvas.drawCircle(posX, posY, radius, paint); 

} 

Jetzt ist dies meine Klasse GamePanel.

public class GamePanel extends View implements GestureDetector.OnGestureListener{ 

private Context context; 

//Screen height and width in pixels 
private static int width; 
private static int height; 

private MainThread thread; 

private Rect paddle1; 
private Rect paddle2; 

private Ball ball; 

private Paint paint; 

//Starting position paddle1 
private int xPos1; 
private int yPos1; 

// Starting position paddle2 
private int xPos2; 
private int yPos2; 

//Width and height of paddles 
private int pWidth; 
private int pHeight; 

private GestureDetectorCompat gestureDetector; 

public GamePanel(Context context) { 

    super(context); 

    this.context = context; 

    //Information we will need for positioning our objects inside the panel 
    DisplayMetrics displayMetrics = Resources.getSystem().getDisplayMetrics(); 

    width = displayMetrics.widthPixels; 
    height = displayMetrics.heightPixels; 

    //Make the GamePanel focusable 
    setFocusable(true); 

    // Thread needs information about the game panel 
    thread = new MainThread(this); 

    pWidth = 100; 
    pHeight = height/2; 

    xPos1 = width/15; 
    yPos1 = 0; 

    xPos2 = width - xPos1 - pWidth; 
    yPos1 = 0; 

    paddle1 = new Rect(xPos1, yPos1, xPos1 + pWidth, yPos1 + pHeight); 
    paddle2 = new Rect(xPos2, yPos2, xPos2 + pWidth, yPos2 + pHeight); 

    paint = new Paint(); 
    paint.setColor(Color.WHITE); 

    ball = new Ball(context, 300, 300, 300); 

    setBackgroundColor(Color.BLACK); 

    this.gestureDetector = new GestureDetectorCompat(context, this); 

    thread.setRunning(true); 
    thread.start(); 
} 


@Override 
protected void onDraw(Canvas canvas) { 

    canvas.drawRect(paddle1, paint); 
    canvas.drawRect(paddle2, paint); 

} 

Ich versuchte invalidate() aufrufen und postInvalidate() in meinem Mainthread-Thread, in dem Konstruktor von Gamepanel und im Konstruktor von Ball. Der Ball wird nie auf den Bildschirm gezogen.

Wie Sie sehen, habe ich bereits dieses Problem mit den Paddeln in Pong konfrontiert, deshalb habe ich zwei Rechtecke im GamePanel erstellt, was sehr hässlich ist.

Wie kapsle ich das Rechteck und den Kreis (Ball) so ein, dass es immer noch auf einem Canvas gezeichnet werden kann?

Antwort

4

Sie erstellen die Ball (Kreis) Blick in GamePanel Ansicht. Nur weil Sie eine Ansicht erstellen, bedeutet dies nicht, dass sie auf dem Bildschirm gezeichnet wird. Sie müssen Ihre Ansicht an das Layout anhängen. Die einfache Lösung wird Ihr Gamepanel zu Kugel

public class GamePanel extends Ball { 

} 

dann in OnDraw() Funktion des super.onDraw();

@Override 
protected void onDraw(Canvas canvas) { 
    super.onDraw(); //Will draw the circle before drawing rectangle 
    canvas.drawRect(paddle1, paint); 
    canvas.drawRect(paddle2, paint);  
} 

hinzufügen GamePanel zu verlängern, wenn Sie die super.onDraw() unter dem Platz drawRect Dann wird der Kreis nach dem Zeichnen des Rect gezeichnet.

Sie müssen auch das Grundkonzept des Hinzufügens der Ansicht zu Layout verstehen.

+0

Vielen Dank für Ihre Antwort. Ich verstehe deine Vorgehensweise. Eine Frage: Was, wenn ich mehrere benutzerdefinierte Ansichten hinzufügen und sie in GamePanel zeichnen wollte? Ich meine also, wenn ich auch die Rechtecke in eine eigene Klasse wie den Ball einkapseln würde? Würde ich GamePanel von ViewGroup oder einem Layout-Typ erweitern und die benutzerdefinierten Ansichten hinzufügen? –

+0

Lassen Sie mich die Fälle auflisten. Wenn Sie diese Formen nicht verschieben, ist es besser, das GamePanel auf ViewGroup zu erweitern und Formen als separate Ansicht zu erstellen, wie Sie "Ball" erstellt haben, und diese Ansichten zu GmePanel hinzuzufügen. Wenn Sie jedoch Formen wie Rechteck und Kreis dynamisch an eine beliebige Position in GamePanel verschieben oder verschieben, ist es besser, ihre Funktionalitäten in eine andere Klasse zu verschieben (nicht separate Ansicht) und innerhalb Ihres GamePanels zu initialisieren. Sehen Sie diese Projektbibliothek zum Beispiel https://github.com/81813780/AVLoadingIndicatorView –

+0

Ok ich sehe. Ich habe den Ball bereits in eine separate Klasse gelegt, wie Sie wissen. Ich kann sie nicht in eine ViewGroup einfügen, da sie dynamisch sein müssen. Welche Klasse müsste jetzt erweitert werden, und wo initialisiere ich sie in GamePanel/Woher soll ich den Ball im GamePanel zeichnen? Tut mir leid, dass ich so viele grundlegende Dinge gefragt habe. Ich bin neu in der Entwicklung von Android und habe gejagt, wie ich das Rechteck und den Ball tagelang einkapseln kann. Es scheint so einfach, aber ich kann es irgendwie nicht herausfinden. Vielen Dank für Ihre Hilfe –

Verwandte Themen