[Anfänger] Android App, die Bälle mit Sensoren rollt [Java]

Udemys Android-Entwicklungskurs ist zu schnell

https://www.udemy.com/androidjavapro/

Java Wissen Null OK! Meisterkurs zum professionellen Android-Entwickler [Kompatibel mit dem neuesten Android Studio 3! ] Leicht verständlicher und höflicher Kommentar! Lassen Sie uns die Grundlagen von Java, die als Android-Ingenieur erforderlichen Kenntnisse, die Listenansicht, die Datenbankerstellung und das attraktive Design anhand zahlreicher Beispiele beherrschen! 3,9 (182 Bewertungen) 1449 Studenten haben sich angemeldet Schöpfer Hiroaki Kaneda Letzte Aktualisierung 1/2019

Ich nehme an diesem Kurs teil und das Tempo ist zu schnell Es gab einige Teile, die ich ohne detaillierte Erklärungen nicht verstehen konnte Ich werde einen Kommentar posten, damit ich ihn verstehen kann.

python


package com.example.accball;

import android.content.Context;
import android.content.pm.ActivityInfo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

/*Der Ereignis-Listener behält das Ereignis im Auge und empfängt es, falls vorhanden*/
public class MainActivity extends AppCompatActivity implements SensorEventListener, SurfaceHolder.Callback {

    //Deklaration von Mitgliedsvariablen(=Fügen wir am Anfang ein niedrigeres m hinzu)
    SensorManager mSensorManager;
    Sensor mAccSensor;

    //Deklaration einer Mitgliedsvariablen namens mHolder der SurfaceHolder-Klasse
    //Stellen Sie sich das als Halter für die vorübergehende Speicherung des Bildschirms vor.
    SurfaceHolder mHolder;
    int mSurfaceWidth;      //Breite der Oberflächenansicht
    int mSurfaceHeight;     //SurfaceView-Höhe

    //Wenn Sie am Ende der Float-Typ-Nummer kein f hinzufügen, tritt ein Kompilierungsfehler auf.
    static final float RADIUS = 150.0f;     //Eine Konstante, die den Radius beim Zeichnen einer Kugel darstellt(Die Einheit ist Pixel)
    static final int DIA = (int)RADIUS * 2; //Konstante, die den Durchmesser der Kugel darstellt(In int-Typ umwandeln)
    static final float COEF = 1000.0f;      //Faktor zum Einstellen des Bewegungsumfangs des Balls

    float mBallX;           //Die aktuelle X-Koordinate des Balls(Position)
    float mBallY;           //Aktuelle Y-Koordinate des Balls(Position)
    float mVX;              //Beschleunigung der Kugel in Richtung der X-Achse
    float mVY;              //Beschleunigung der Kugel in Richtung der Y-Achse

    //long ist eine Klasse zur Darstellung der Zeit
    long mT0;               //Zeitpunkt, zu dem das letzte Mal die Beschleunigung vom Sensor erfasst wurde

    //Bitmap ist eine Klasse für den Umgang mit Bildern
    Bitmap mBallBitmap;     //Bild des Balls

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

        //Bildschirm zur vertikalen Anzeige korrigiert
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

        setContentView(R.layout.activity_main);

        /* getSystemService=>Verwenden Sie das Android-System.
SENSOR in seinem Argument, den Sensor zu verwenden_Verwenden Sie SERVICE.
Speichern Sie den zurückgegebenen SensorManager in der Mitgliedsvariablen mSensorManager*/
        mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);

        /*TYP, der den Beschleunigungssensor im Argument der Methode getDefaultSensor darstellt_Geben Sie ACCELER OMETER an
In der Mitgliedsvariablen mAccSensor gespeichert*/
        mAccSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

        //Platzieren Sie die Oberflächenansicht im Bildschirmlayout und speichern Sie sie in der Elementvariablen mHolder
        SurfaceView surfaceView = (SurfaceView) findViewById(R.id.surfaceView);
        mHolder = surfaceView.getHolder();

        //Ereignis-Listener, wenn surfaceHolder geändert / zerstört wird
        mHolder.addCallback(this);

        //Da das Hintergrundbild vorbereitet ist, machen Sie die Leinwand selbst transparent
        mHolder.setFormat(PixelFormat.TRANSLUCENT);
        surfaceView.setZOrderOnTop(true);

        //Bild des Balls anzeigen
        // decodeResource()Ressourcen mit Methode abrufen
        //GetResources als Argument()Kann durch Angabe der ID der Methode und Ressource abgerufen werden
        Bitmap ball = BitmapFactory.decodeResource(getResources(), R.drawable.ball);
        //Ändern Sie die Größe der gezogenen Kugel
        //DIA die vertikale Höhe der Ressource, die in der obigen Zeile erfasst und mit createScaledBitmap im Ball gespeichert wurde(Durchmesser)、
        //Geben Sie die linke und rechte Länge als DIA an
        //Das letzte Argument ist ein Filter(Korrektur für Pixelzackigkeit)Ob Sie sich bewerben möchten oder nicht
        mBallBitmap = Bitmap.createScaledBitmap(ball, DIA, DIA, false);
    }

    //Eine Methode, die aufgerufen wird, wenn sich der Wert des Beschleunigungssensors ändert
    @Override
    public void onSensorChanged(SensorEvent sensorEvent) {

        //Wenn der Sensor ein Beschleunigungssensor ist
        if (sensorEvent.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {

            /*Die vom Sensor erhaltene Beschleunigung beträgt x,Ersatz für y
Invertieren Sie die x-Achse, um sie an die Zeichenrichtung des Bildschirms anzupassen
Es ist zu beachten, dass jede Beschleunigung als Beschleunigung in Richtung der x-Achse und als Beschleunigung in Richtung der y-Achse verstanden wird.
Beim Beschleunigen in die entgegengesetzte Richtung scheint der Wert negativ zu sein.*/
            float x = -sensorEvent.values[0];
            float y = sensorEvent.values[1];

            /*Zeit finden t
Ganz am Anfang der Schleife kann die vorherige Zeit nicht genommen werden, und der Zeitstempel von sensorEvent wird mT0 zugewiesen.*/
            if (mT0 == 0) {
                mT0 = sensorEvent.timestamp;
                // return;Ende mit
                return;
            }

            //Sie können die Zeit ermitteln, indem Sie mT0, das die vorherige Zeit enthält, vom Zeitstempel des neuen sensorEvent abziehen.
            float t = sensorEvent.timestamp -mT0;
            mT0 = sensorEvent.timestamp;
            t = t/ 1000000000.0f;               //Konvertieren Sie Nanosekunden in Sekunden

            //Finden Sie die Bewegungsentfernung in x- und y-Richtung
            //Das Folgende ist eine Physikformel und Sie müssen sich nicht daran erinnern
            // (Beschleunigung in Richtung der X-Achse*Zeit)+(X-Beschleunigung vom Sensor erhalten*Zeitの2乗を2で割る)Und berechnen Sie die zurückgelegte Strecke
            float dx = (mVX * t) + (x * t * t/2.0f);
            // (Beschleunigung in Richtung der Y-Achse*Zeit)+(Vom Sensor erhaltene Y-Beschleunigung*Zeitの2乗を2で割る)Und berechnen Sie die zurückgelegte Strecke
            float dy = (mVY * t) + (y * t * t/2.0f);

            //Aktualisieren Sie die aktuelle Ballposition aus der zurückgelegten Strecke
            //COEF ist ein Koeffizient für die natürliche Bewegung auf dem Bildschirm
            mBallX = mBallX + dx * COEF;
            mBallY = mBallY + dy * COEF;

            //Die aktuelle Ballbewegungsgeschwindigkeit wurde aktualisiert(Bewegungsformel für konstante Beschleunigung<=Zwinge dich nicht, dich zu erinnern)
            //Geschwindigkeit=Anfangsgeschwindigkeit+Beschleunigung*Zeit
            mVX = mVX + (x * t);
            mVY = mVY + (y * t);

            //Verarbeitung, um zu verhindern, dass der Ball vom Bildschirm verschwindet(Erstens die horizontale Achse)
            //Es wird negativ, wenn der Radius des Balls von der x-Koordinate der aktuellen Position des Balls abgezogen wird.(=Die Wand treffen)
            //Und wenn die Geschwindigkeit negativ ist, kehren Sie die Geschwindigkeit um und machen Sie sie positiv.
            if(mBallX - RADIUS < 0 && mVX < 0){
                //Schlagen Sie gegen die Wand und verlangsamen Sie(Geschwindigkeit 1.Teilen Sie durch 5, um langsamer zu werden)
                mVX = -mVX / 1.5f;
                //Aktualisieren Sie die Positionskoordinaten des Balls auf den Wert des Radius
                mBallX = RADIUS;
                //Wenn die Summe aus x-Koordinate und Radius der Kugel größer als die Breite der Oberflächenansicht ist und die Geschwindigkeit 0 oder mehr beträgt
                // =Wenn es in entgegengesetzter Richtung vom Bildschirm verschwindet
            } else if (mBallX + RADIUS > mSurfaceWidth && mVX > 0){
                //Schlagen Sie gegen die Wand und verlangsamen Sie
                mVX = -mVX / 1.5f;
                //Die Position der Kugel auf den Wert, der durch Subtrahieren des Radius von der Breite der Oberfläche erhalten wird(X-Koordinate von)Aktualisieren
                mBallX = mSurfaceWidth - RADIUS;
            }

            //Verarbeitung, um zu verhindern, dass der Ball vom Bildschirm verschwindet(Als nächstes kommt die vertikale Achse)
            if(mBallY - RADIUS < 0 && mVY < 0){
                mVY = - mVY / 1.5f;
                mBallY = RADIUS;
            } else if (mBallY + RADIUS > mSurfaceHeight && mVY > 0){
                mVY = -mVY / 1.5f;
                mBallY = mSurfaceHeight - RADIUS;
            }

            //Zeichnen Sie den Ball auf der Leinwand an der aktuellen Position des Balls neu, die aus der Beschleunigung berechnet wurde
            drawCanvas();
        }
    }

    //Verarbeitung, um den Ball auf dem Bildschirm anzuzeigen
    private void drawCanvas() {
        //Wenn Sie lockCanvas aufrufen und Canvas abrufen, wird die Oberfläche gesperrt und Sie können zeichnen.
        Canvas c = mHolder.lockCanvas();
        //Lösche den Ball auf dem Bildschirm mit drawColor(Wenn Sie die vorherige Zeichnung nicht löschen, ist der Bildschirm voller Kugeln)
        //Mit anderen Worten, drawColor()Ist eine Methode, um etwas mit etwas Farbe zu füllen,
        //Diesmal bedeutet es, die Leinwand mit einer transparenten Farbe zu füllen.
        //Das zweite Argument ist anscheinend erforderlich
        c.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
        //Die Paint-Klasse ist erforderlich, um Elemente für die tatsächliche Zeichnung festzulegen, z. B. Zeichnungsfarbe, Linienstärke, Zeichengröße und Schriftart.
        //Dieses Mal erstellen Sie vorerst nur eine Instanz
        Paint paint = new Paint();
        //Bitbit-Canvas-Koordinaten(left, top)Zeichnen Sie basierend auf der Position von
        c.drawBitmap(mBallBitmap, mBallX - RADIUS, mBallY - RADIUS, paint);

        //Mitgliedsvariable mHolder, in der surfaceView gespeichert ist(Halter)Reflexion auf dem Bildschirm und Entsperren der Leinwand
        mHolder.unlockCanvasAndPost(c);
    }

    //Eine Methode, die aufgerufen wird, wenn sich die Genauigkeit des Beschleunigungssensors ändert
    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {

    }

    //Methode, die aufgerufen wird, wenn der Bildschirm angezeigt wird
    @Override
    protected void onResume() {
        super.onResume();
    }

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

    //Wird aufgerufen, wenn die Oberfläche erstellt wird
    @Override
    public void surfaceCreated(SurfaceHolder holder) {

        /*registerListener ist eine Methode zum Starten der Überwachung des Beschleunigungssensors
Erstes Argument: Wer überwacht (dies bezieht sich auf MainActivity selbst)
Zweites Argument: Sensor, den Sie überwachen möchten
Drittes Argument: Häufigkeit der Überwachung*/
        mSensorManager.registerListener(this, mAccSensor, SensorManager.SENSOR_DELAY_GAME);
    }

    //Wird aufgerufen, wenn sich die Oberfläche ändert
    //Gleichzeitig werden Position, Geschwindigkeit und Zeit des Balls initialisiert.
    @Override
    public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
        mSurfaceWidth = i1;
        mSurfaceHeight = i2;

        //Geben Sie die Ausgangsposition des Balls an
        //Wenn Sie die Hälfte der Breite und Höhe der Oberflächenansicht angeben, können Sie sie in der Mitte platzieren.
        mBallX = mSurfaceWidth / 2;
        mBallY = mSurfaceHeight / 2;

        //Initialisierung von Geschwindigkeit und Zeit
        mVX = 0;
        mVY = 0;
        mT0 = 0;
    }

    //Wird aufgerufen, wenn die Oberfläche gelöscht wird
    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {

        //Beenden Sie die Überwachung, wenn der Bildschirm geschlossen ist//
        mSensorManager.unregisterListener(this);
    }
}

Versuche zu rennen

image.png

Klicken Sie zum Ausführen oben rechts auf die Schaltfläche> Ausführen.

image.png Wählen Sie einen Emulator aus. Wenn Sie es auf einem tatsächlichen Gerät ausprobieren möchten, müssen Sie Einstellungen am tatsächlichen Gerät vornehmen, bevor Sie das tatsächliche Gerät über USB anschließen (weggelassen). image.png

Wenn Sie unten rechts "..." und dann Virtuelle Sensoren auswählen image.png Sie können spielen, indem Sie den Emulator wie folgt neigen

Über kleine Grenzen

Wenn Sie versuchen, den Emulator auszuführen, können Sie sehen, dass er je nach Sensor funktioniert. Da jedoch der gebundene Prozess ausgeführt wird, der Stoppprozess jedoch nicht ausgeführt wird, springt der Ball nach und nach weiter, selbst wenn der Emulator fixiert ist. Es ist eine Spezifikation, kein Fehler.

Es scheint eine Möglichkeit zu geben, beim Verzögerungsprozess einen Schwellenwert festzulegen und die Beschleunigung auf 0 zu setzen, um sie vollständig zu stoppen.

Ich werde es versuchen, wenn ich etwas besser verstehe.

Recommended Posts

[Anfänger] Android App, die Bälle mit Sensoren rollt [Java]
SSH-Verbindung mit SSHJ aus der Java6-App
Erstellen Sie ein Docker-Image, um eine einfache Java-App auszuführen
Machen Sie einen Diamanten mit Java
[Android] Erstellen Sie einen Kalender mit GridView
Ich habe eine shopify App @java erstellt
Laden Sie Dateien mit Java HttpURLConnection hoch
Erstellen Sie ein Java-Projekt mit Eclipse
Ich habe eine passende App erstellt (Android App)
[Android] Ich habe eine Schrittzähler-App erstellt.
Eine eigenständige Java-App, die Protokolle mit slf4j / logback an CloudWatch-Protokolle sendet
Java-Anfänger haben versucht, mit Spring Boot eine einfache Webanwendung zu erstellen
Konsolidieren Sie JavaFX-Apps in JAR-Dateien, die auf Java 8/11 funktionieren
[Rails6] Erstelle eine neue App mit Rails [Anfänger]
Sobel-Filter mit OpenCV unter Android (Java)
Erstellen Sie eine TODO-App in Java 7 Create Header
Lassen Sie uns eine Taschenrechner-App mit Java erstellen
Stellen Sie eine Java-Web-App für Heroku bereit
Ich habe eine Taschenrechner-App für Android erstellt
[Rails 5] Erstelle eine neue App mit Rails [Anfänger]
Ich habe eine Janken App mit Android gemacht
Ein Memo, das Spring Boot berührte
MVC-Modell
Ein einfaches Beispiel für das MVC-Modell
[Persönliches Memo] Ich habe etwas über Modifikatoren gelernt
Eine Geschichte, die Geschäftslogik und Modell trennt
Ein Memo für mich, dass Objektorientierung etwas ist
Ein Memo, das eine Klasse behandelt, die unabhängig mit ArrayList erstellt wurde
Was ist ein MVC-Modell?
[Anfänger] Android App, die Bälle mit Sensoren rollt [Java]
[Azure] Ich habe versucht, eine Java-App für die Erstellung von kostenlosen Web-Apps zu erstellen. [Anfänger]