Neuen Thread in Surface View starten (klappt nicht).

E

EnzoVincenzo

Neues Mitglied
0
Hallo Leute,

ich versuche gerade, ein Ping Pong Spiel zu programmieren. Der Thread in der Grafik Klasse soll gestoppt werden, wenn der Ball in Aus geht. Das hab ich umgesetzt, indem ich den isRunning Wert aus der while Schleife auf "false" gesetzt habe. Im Anschluss wollt ich den Thread aus der Main Activity neu starten, was ich einfach nicht hinkriege. Der Quellcode sieht wie folgt aus:
Main Activity:

Code:
package com.example.vince.myapplication;

import android.graphics.Canvas;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    RelativeLayout layout;
    ImageView imageOne, imageTwo;
    Button startButton;
    Canvas canvas;

    DisplayMetrics displaymetrics = new DisplayMetrics();//Dient dazu die Abmessungen des Bildschirms zu ermitteln

    float height;
    float width;
    int imageWith;
    Grafik grafik, game;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);
        //setContentView(R.layout.game_activity);
        //Gehört dazu die Abmessungen des Bildschirms zu ermitteln---------------------------------
        getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
        height = displaymetrics.heightPixels - 150;
        width = displaymetrics.widthPixels;


        //-----------------------------------------------------------------------------------------
        layout = (RelativeLayout) findViewById(R.id.layout);
        imageOne = (ImageView) findViewById(R.id.paddle_one);
        imageTwo = (ImageView) findViewById(R.id.paddle_two);
        startButton = (Button) findViewById(R.id.startButton);
        startButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d("Test", "Klick");
//                grafik.isRunning = true;
//                grafik.myThread.start();
//                game = new Grafik(MainActivity.this);

            }
        });

        grafik = new Grafik(this);

        imageWith = imageOne.getDrawable().getIntrinsicWidth();//Balkenbreite ermitteln

        grafik.setImageWithTwo(imageWith);//Balkenbreite an die Klasse Grafik übermitteln
        Grafik.setImageOne(imageOne);
        Grafik.setImageTwo(imageTwo);

        grafik.setPosX(imageOne.getX());
        grafik.setPosY(imageOne.getY());

        Log.d("Test","Canvas Breite ist gleich " + width);
        Log.d("Test","Canvas Höhe ist gleich " + height);
        Log.d("Test","Balken Breite ist gleich " + imageWith);
        Log.d("Test","x aus Grafik ist gleich " + grafik.getPosX());
        //Toast.makeText(getApplicationContext(),"Balken Breite = " + imageWith, Toast.LENGTH_SHORT).show();

        layout.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                int action = event.getAction();


                switch (action){
                    case MotionEvent.ACTION_DOWN:
                        if (event.getY() < height/3) {
                            imageOne.setX(event.getX()-imageWith/2);
                            imageOne.setY(event.getY()+100);
                            grafik.setPosX(imageOne.getX());
                            grafik.setPosY(imageOne.getY());
                            grafik.setStartPlayerOne(true);
                            grafik.isRunning = true;
                        }else if (event.getY() > (height - height/3)){
                            imageTwo.setX(event.getX()-imageWith/2);
                            imageTwo.setY(event.getY()-100);
                            grafik.setPosX(imageTwo.getX()+imageWith/2);
                            grafik.setPosY(imageTwo.getY()+100);
                            grafik.setStartPlayerTwo(true);
                            grafik.isRunning = true;

                        }

                        break;
                    case MotionEvent.ACTION_UP:
                        if (event.getY() < height/3) {
                            imageOne.setX(event.getX()-imageWith/2);
                            imageOne.setY(event.getY()+100);
                        }else if (event.getY() > (height - height/3)){
                            imageTwo.setX(event.getX()-imageWith/2);
                            imageTwo.setY(event.getY()-100);
                        }
                        break;
                    case MotionEvent.ACTION_MOVE:
                        if (event.getY() < height/3) {
                            imageOne.setX(event.getX()-imageWith/2);
                            imageOne.setY(event.getY()+100);
                        }else if (event.getY() > (height - height/3)){
                            imageTwo.setX(event.getX()-imageWith/2);
                            imageTwo.setY(event.getY()-100);
                        }
                        break;

                }


                return true;
            }
        });


    }

    @Override
    protected void onPause() {
        super.onPause();
        grafik.pause();
    }

    @Override
    protected void onResume() {
        super.onResume();
        grafik.resume();
    }





//    @Override
//    public void onWindowFocusChanged(boolean hasFocus) {
//        super.onWindowFocusChanged(hasFocus);
//        imageWith = imageOne.getWidth();
//    }

}

Und die Grafik Klasse:

Code:
package com.example.vince.myapplication;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.Toast;

/**
* Created by vince on 05.06.2016.
*/
public class Grafik extends SurfaceView implements Runnable{
    private static ImageView imageOne, imageTwo;
    Bitmap ball;
    float x, y;
    private static float posX, posY;
    boolean directionX = true;
    boolean directionY = true;
    private static boolean startPlayerOne = false;
    private static boolean startPlayerTwo = false;
    private static int imageWithTwo;

    SurfaceHolder myHolder;
    Thread myThread;
    boolean isRunning = true;


    public Grafik(Context context) {
        super(context);
        init(null, 0);
    }

    public Grafik(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(attrs, 0);
    }

    public Grafik(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(attrs, defStyleAttr);
    }

    private void init(AttributeSet attrs, int i) {
        ball = BitmapFactory.decodeResource(getResources(), R.drawable.tennisball);

        //Log.d("Test","x aus Grafik ist gleich " + posX);
        x = 0;
        y = 0;
        myHolder = getHolder();
        isRunning = true;
        myThread = new Thread(this);
        myThread.setPriority(Thread.MAX_PRIORITY);
        myThread.start();
    }

    public void pause(){
        isRunning = false;
        while (true){
            try {
                myThread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            break;
        }
    }

    public void resume (){
        isRunning = true;
        myThread = new Thread(this);
        myThread.setPriority(Thread.MAX_PRIORITY);
        myThread.start();
    }

    @Override
    public void run() {

        while (isRunning){
            if (!myHolder.getSurface().isValid())
                continue;

            Canvas canvas = myHolder.lockCanvas();
            canvas.drawColor(Color.BLACK);

            canvas.drawBitmap(ball, x, y, null);
            //Log.d("Test", "x = " + x);

            //x Richtung des Balls------------------------------------------------------------------
            if (x < canvas.getWidth()-ball.getWidth()/2 && directionX){
                x +=5;
            }else {
                x -= 5;
                directionX = false;
            }
            if (x > 0 && !directionX){
                x -= 5;
            }else {
                x +=5;
                directionX = true;
            }
            //--------------------------------------------------------------------------------------
            //y Richtung des Balls------------------------------------------------------------------
            if (directionY){
                y += 5;
            }else {
                y -= 5;
                directionY = false;
            }
            if (!directionY){
                y -= 5;
            } else {
                y += 5;
                directionY = true;
            }
            //--------------------------------------------------------------------------------------
            //Abprallen des Balls von den Schlägern-------------------------------------------------
            if (x > imageOne.getX() && x < imageOne.getX()+imageOne.getWidth()
                    && y < imageOne.getY()+imageOne.getHeight()
                    && y > imageOne.getY()){
                directionY = true;
            }
            if (x > imageTwo.getX() && x < imageTwo.getX()+imageTwo.getWidth()
                    && y > imageTwo.getY()-ball.getWidth()
                    && y < imageTwo.getY()+imageTwo.getHeight()){
                directionY = false;
            }
            //--------------------------------------------------------------------------------------
//            Log.d("Test", "y = " + imageTwo.getY());
//            Log.d("Test", "y1 = " + (imageTwo.getY()-ball.getWidth()));
//            Log.d("Test", "y2 = " + (imageTwo.getY()+imageTwo.getHeight()));

            Log.d("Test", "y = " + imageOne.getY());
            Log.d("Test", "y1 = " + (imageOne.getY()+imageOne.getHeight()));
            Log.d("Test", "y2 = " + (imageOne.getY()+imageOne.getHeight()+ball.getHeight()));

            //Stopp wenn der Ball ins Aus geht------------------------------------------------------
            if (y < -100 && !directionY){
                imageTwo.setX(canvas.getWidth()/2 - imageTwo.getWidth()/2);
                imageTwo.setY(canvas.getHeight()-150);
                canvas.drawBitmap(ball, imageTwo.getX()+imageTwo.getWidth()/2-ball.getWidth()/2, imageTwo.getY()-ball.getHeight(), null);
                isRunning = false;
                myThread.interrupt();
            }
            if (y > canvas.getHeight()+100 && directionY){
                imageTwo.setX(canvas.getWidth()/2 - imageTwo.getWidth()/2);
                imageTwo.setY(canvas.getHeight()-150);
                canvas.drawBitmap(ball, imageTwo.getX()+imageTwo.getWidth()/2-ball.getWidth()/2, imageTwo.getY()-ball.getHeight(), null);
                isRunning = false;
                myThread.interrupt();
            }


            myHolder.unlockCanvasAndPost(canvas);
        }
    }



    public void abprallen (){

        float paddleOneX = Grafik.imageOne.getX();
        float paddleOneY = Grafik.imageOne.getY();
        float paddleTwoX = Grafik.imageTwo.getX();
        float paddleTwoY = Grafik.imageTwo.getY();

        //Log.d("Test", "PaddleOne berührt");
        if (x > paddleOneX && x < paddleOneX + Grafik.imageOne.getWidth() && y < paddleOneY + Grafik.imageOne.getHeight()){
            //Log.d("Test", "PaddleOne berührt");
            directionY = true;
//            if (y < paddleOneX){
//                Log.d("Test", "Ball im oberen Aus");
//
//            }
//            else invalidate();

        }
        if (x > paddleTwoX && x < paddleTwoX + Grafik.imageTwo.getWidth() && y > paddleTwoY - Grafik.imageTwo.getHeight()){
            directionY = false;

        }else if (y > paddleTwoY - Grafik.imageTwo.getHeight()){
            directionY = true;
        }
    }

    public float getPosX() {
        return posX;
    }

    public void setPosX(float posX) {
        this.posX = posX;
    }

    public float getPosY() {
        return posY;
    }

    public void setPosY(float posY) {
        this.posY = posY;
    }

    public int getImageWithTwo() {
        return imageWithTwo;
    }

    public void setImageWithTwo(int imageWithTwo) {
        this.imageWithTwo = imageWithTwo;
    }

    public static ImageView getImageOne() {
        return imageOne;
    }

    public static void setImageOne(ImageView imageOne) {
        Grafik.imageOne = imageOne;
    }

    public static ImageView getImageTwo() {
        return imageTwo;
    }

    public static void setImageTwo(ImageView imageTwo) {
        Grafik.imageTwo = imageTwo;
    }

    public boolean isStartPlayerOne() {
        return startPlayerOne;
    }

    public void setStartPlayerOne(boolean startPlayerOne) {
        this.startPlayerOne = startPlayerOne;
    }

    public boolean isStartPlayerTwo() {
        return startPlayerTwo;
    }

    public void setStartPlayerTwo(boolean startPlayerTwo) {
        this.startPlayerTwo = startPlayerTwo;
    }


}

Habt ihr einen Tip (oder mehrere :)) für mich?
Viele Grüße

Vincenzo
 
Kritische Fragen und Anmerkungen:

-Deine Grafik Klasse macht viel zu viel mMn.Und warum hast du davon 2 Objekte?
-kriegst du keinen Fehler/Hinweis wenn du den Thread-start nicht in try-catch machst?Warum ist kein Try Catch während du auf der Surfaceview malst?
-warum mischst du so viele Views und Viewgroups mit der Surfaceview?


Führe eine isPaused variable ein und lasse den Thread einfach 100-200ms schlafen. Denn dein Problem ist ja dass dein Thread wenn er mal durchgelaufen ist nicht erneut gestartet werden kann.(Rheinwerk Computing :: Java ist auch eine Insel – 14.3 Thread-Eigenschaften und -Zustände)

Mit isPaused steuerst du die Pausen des Threads und isRunning ist dafür dann da um den Thread vollständig zu beenden.


hoffe das hilft erstmal
 

Ähnliche Themen

D
Antworten
3
Aufrufe
469
jogimuc
J
A
Antworten
4
Aufrufe
1.546
jogimuc
J
retrozap
  • retrozap
Antworten
0
Aufrufe
788
retrozap
retrozap
Zurück
Oben Unten