[Débutant] Application Android qui fait rouler des balles à l'aide de capteurs [Java]

Le cours de développement Android d'Udemy est trop rapide

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

Connaissance Java zéro OK! Cours de master pour devenir développeur Android professionnel [Compatible avec le dernier Android Studio 3! ] Commentaires faciles à comprendre et polis! Maîtrisons les bases de Java, les connaissances requises en tant qu'ingénieur Android, la vue de liste, la création de bases de données et la conception attrayante grâce à d'abondants échantillons! 3.9 (182 évaluations) 1449 étudiants inscrits Créateur Hiroaki Kaneda Dernière mise à jour 1/2019

Je prends ce cours et le rythme est trop rapide Il y avait certaines parties que je ne pouvais pas comprendre sans des explications détaillées, alors Je posterai un commentaire pour que je puisse le comprendre.

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;

/*L'écouteur d'événements garde un œil sur l'événement et le reçoit s'il existe*/
public class MainActivity extends AppCompatActivity implements SensorEventListener, SurfaceHolder.Callback {

    //Déclaration des variables membres(=Ajoutons un m inférieur au début)
    SensorManager mSensorManager;
    Sensor mAccSensor;

    //Déclaration d'une variable membre appelée mHolder de la classe SurfaceHolder
    //Considérez-le comme un support pour stocker temporairement l'écran.
    SurfaceHolder mHolder;
    int mSurfaceWidth;      //largeur de la surface
    int mSurfaceHeight;     //Hauteur SurfaceView

    //Si vous n'ajoutez pas f à la fin du numéro de type float, une erreur de compilation se produira.
    static final float RADIUS = 150.0f;     //Une constante qui représente le rayon lors du dessin d'une balle(L'unité est le pixel)
    static final int DIA = (int)RADIUS * 2; //Constante représentant le diamètre de la balle(Diffuser en type int)
    static final float COEF = 1000.0f;      //Facteur d'ajustement de la quantité de mouvement de la balle

    float mBallX;           //La coordonnée X actuelle de la balle(position)
    float mBallY;           //Coordonnée Y actuelle de la balle(position)
    float mVX;              //Accélération de la balle dans la direction de l'axe X
    float mVY;              //Accélération de la balle dans la direction de l'axe Y

    //long est une classe pour représenter le temps
    long mT0;               //Heure à laquelle l'accélération a été acquise à partir du capteur la dernière fois

    //Bitmap est une classe de gestion des images
    Bitmap mBallBitmap;     //Image du ballon

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

        //Écran fixe à affichage vertical
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

        setContentView(R.layout.activity_main);

        /* getSystemService=>Utilisez le système Android.
SENSOR dans son argument pour utiliser le capteur_Utilisez SERVICE.
Stocker le SensorManager renvoyé dans la variable membre mSensorManager*/
        mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);

        /*TYPE représentant le capteur d'accélération dans l'argument de la méthode getDefaultSensor_Spécifiez ACCELER OMETER
Stocké dans la variable membre mAccSensor*/
        mAccSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

        //Obtenez le surfaceView placé dans la disposition de l'écran et stockez-le dans la variable membre mHolder
        SurfaceView surfaceView = (SurfaceView) findViewById(R.id.surfaceView);
        mHolder = surfaceView.getHolder();

        //Écouteur d'événements lorsque surfaceHolder est modifié / détruit
        mHolder.addCallback(this);

        //Puisque l'image d'arrière-plan est préparée, rendez la toile elle-même transparente
        mHolder.setFormat(PixelFormat.TRANSLUCENT);
        surfaceView.setZOrderOnTop(true);

        //Afficher l'image de la balle
        // decodeResource()Obtenez des ressources avec méthode
        //GetResources comme argument()Peut être obtenu en spécifiant l'id de la méthode et de la ressource
        Bitmap ball = BitmapFactory.decodeResource(getResources(), R.drawable.ball);
        //Redimensionner la balle dessinée
        //DIA la hauteur verticale de la ressource acquise dans la ligne ci-dessus et stockée dans la balle avec createScaledBitmap(diamètre)、
        //Spécifiez la longueur gauche et droite comme DIA
        //Le dernier argument est un filtre(Correction de la dentelure des pixels)Appliquer ou non
        mBallBitmap = Bitmap.createScaledBitmap(ball, DIA, DIA, false);
    }

    //Une méthode appelée en cas de changement de la valeur du capteur d'accélération
    @Override
    public void onSensorChanged(SensorEvent sensorEvent) {

        //Si le capteur est un capteur d'accélération
        if (sensorEvent.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {

            /*L'accélération obtenue du capteur est x,Remplacez y
Inverser l'axe des x pour correspondre à la direction du dessin de l'écran
De plus, chaque accélération est comprise comme une accélération dans la direction de l'axe x et une accélération dans la direction de l'axe y.
En accélérant dans la direction opposée, il semble que la valeur sera négative.*/
            float x = -sensorEvent.values[0];
            float y = sensorEvent.values[1];

            /*Trouver le temps t
Au tout début de la boucle, l'heure précédente ne peut pas être prise et l'horodatage de sensorEvent est affecté à mT0.*/
            if (mT0 == 0) {
                mT0 = sensorEvent.timestamp;
                // return;Terminer par
                return;
            }

            //Vous pouvez trouver l'heure en soustrayant mT0, qui contient l'heure précédente, de l'horodatage du nouveau sensorEvent.
            float t = sensorEvent.timestamp -mT0;
            mT0 = sensorEvent.timestamp;
            t = t/ 1000000000.0f;               //Convertir des nanosecondes en secondes

            //Trouvez la distance de mouvement dans les directions x et y
            //Ce qui suit est une formule physique et vous n'avez pas à vous en souvenir
            // (Accélération dans la direction de l'axe X*temps)+(Accélération X obtenue du capteur*tempsの2乗を2で割る)Et calculez la distance parcourue
            float dx = (mVX * t) + (x * t * t/2.0f);
            // (Accélération dans la direction de l'axe Y*temps)+(Accélération Y obtenue du capteur*tempsの2乗を2で割る)Et calculez la distance parcourue
            float dy = (mVY * t) + (y * t * t/2.0f);

            //Mettre à jour la position actuelle de la balle à partir de la distance parcourue
            //COEF est un coefficient de mouvement naturel sur l'écran
            mBallX = mBallX + dx * COEF;
            mBallY = mBallY + dy * COEF;

            //Mise à jour de la vitesse de déplacement actuelle de la balle(Formule de mouvement d'accélération constante<=Ne te force pas à te souvenir)
            //la vitesse=Vitesse initiale+accélération*temps
            mVX = mVX + (x * t);
            mVY = mVY + (y * t);

            //Traitement pour empêcher le ballon de sortir de l'écran(Tout d'abord, l'axe horizontal)
            //Il devient négatif lorsque le rayon de la balle est soustrait de la coordonnée x de la position actuelle de la balle.(=Frapper le mur)
            //Et si la vitesse est négative, inversez la vitesse et rendez-la positive
            if(mBallX - RADIUS < 0 && mVX < 0){
                //Frappez le mur et ralentissez(Vitesse 1.Divisez par 5 pour ralentir)
                mVX = -mVX / 1.5f;
                //Mettre à jour les coordonnées de position de la balle à la valeur du rayon
                mBallX = RADIUS;
                //Si la somme de la coordonnée x et du rayon de la balle est supérieure à la largeur de surfaceView et que la vitesse est égale ou supérieure à 0
                // =S'il sort de l'écran dans la direction opposée
            } else if (mBallX + RADIUS > mSurfaceWidth && mVX > 0){
                //Frappez le mur et ralentissez
                mVX = -mVX / 1.5f;
                //La position de la balle à la valeur obtenue en soustrayant le rayon de la largeur de la surface(Coordonnée X de)Mise à jour
                mBallX = mSurfaceWidth - RADIUS;
            }

            //Traitement pour empêcher le ballon de sortir de l'écran(Vient ensuite l'axe vertical)
            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;
            }

            //Redessiner la balle sur la toile à la position actuelle de la balle calculée à partir de l'accélération
            drawCanvas();
        }
    }

    //Traitement pour afficher la balle à l'écran
    private void drawCanvas() {
        //Lorsque vous appelez lockCanvas et obtenez un canevas, la surface est verrouillée et vous pouvez dessiner.
        Canvas c = mHolder.lockCanvas();
        //Effacez la balle sur l'écran avec drawColor(Si vous n'effacez pas le dessin précédent, l'écran sera plein de balles)
        //En d'autres termes, drawColor()Est une méthode pour remplir quelque chose de couleur,
        //Cette fois, cela signifie remplir la toile d'une couleur transparente.
        //Le deuxième argument est apparemment requis
        c.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
        //La classe Paint est nécessaire pour définir les éléments du dessin réel tels que la couleur du dessin, l'épaisseur de la ligne, la taille des caractères et la police.
        //Cette fois, créez simplement une instance pour le moment
        Paint paint = new Paint();
        //Coordonnées du canevas Bitbit(left, top)Dessiner en fonction de la position de
        c.drawBitmap(mBallBitmap, mBallX - RADIUS, mBallY - RADIUS, paint);

        //Variable membre, mHolder, où surfaceView est stockée(titulaire)Réflexion sur l'écran et déverrouillage de la toile
        mHolder.unlockCanvasAndPost(c);
    }

    //Une méthode appelée lorsque la précision du capteur d'accélération change
    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {

    }

    //Méthode appelée lorsque l'écran est affiché
    @Override
    protected void onResume() {
        super.onResume();
    }

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

    //Appelé lors de la création de la surface
    @Override
    public void surfaceCreated(SurfaceHolder holder) {

        /*registerListener est une méthode pour commencer à surveiller le capteur d'accélération
Premier argument: qui surveille (cela fait référence à MainActivity lui-même)
Deuxième argument: capteur que vous souhaitez surveiller
Troisième argument: Fréquence de vouloir surveiller*/
        mSensorManager.registerListener(this, mAccSensor, SensorManager.SENSOR_DELAY_GAME);
    }

    //Appelé en cas de modification de la surface
    //En même temps, la position, la vitesse et l'heure de la balle sont initialisées.
    @Override
    public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
        mSurfaceWidth = i1;
        mSurfaceHeight = i2;

        //Spécifiez la position initiale de la balle
        //Si vous spécifiez la moitié de la largeur et de la hauteur de surfaceView, vous pouvez le placer au centre.
        mBallX = mSurfaceWidth / 2;
        mBallY = mSurfaceHeight / 2;

        //Initialisation de la vitesse et de l'heure initiale
        mVX = 0;
        mVY = 0;
        mT0 = 0;
    }

    //Appelé lorsque la surface est supprimée
    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {

        //Mettre fin à la surveillance lorsque l'écran est fermé//
        mSensorManager.unregisterListener(this);
    }
}

Essayez de courir

image.png

Pour exécuter, cliquez sur le bouton> exécuter en haut à droite.

image.png Sélectionnez un émulateur. Si vous souhaitez l'essayer sur un appareil réel, vous devez effectuer les réglages sur l'appareil réel avant de connecter l'appareil réel via USB (omis). image.png

Si vous sélectionnez "..." en bas à droite, puis sélectionnez Capteurs virtuels image.png Vous pouvez jouer en inclinant l'émulateur comme ceci

À propos des petites limites

Si vous essayez d'exécuter l'émulateur, vous pouvez voir qu'il fonctionne en fonction du capteur. Cependant, comme le processus lié est effectué mais que le processus d'arrêt n'est pas effectué, la balle continue de rebondir petit à petit même si l'émulateur est fixe. C'est une spécification, pas un bug.

Il semble y avoir un moyen de définir un seuil lors du processus de décélération et de régler l'accélération à 0 pour l'arrêter complètement.

J'essaierai quand j'aurai un peu mieux compris.

Recommended Posts

[Débutant] Application Android qui fait rouler des balles à l'aide de capteurs [Java]
Connexion SSH à l'aide de SSHJ à partir de l'application Java 6
Créer une image docker pour exécuter une application Java simple
Faire un diamant en utilisant Java
[Android] Créer un calendrier à l'aide de GridView
J'ai créé une application shopify @java
Télécharger des fichiers à l'aide de Java HttpURLConnection
Créer un projet Java à l'aide d'Eclipse
J'ai créé une application correspondante (application Android)
[Android] J'ai créé une application de podomètre.
Une application Java autonome qui envoie des journaux à CloudWatch Logs avec slf4j / logback
Un débutant Java a essayé de créer une application Web simple à l'aide de Spring Boot
Consolidez les applications JavaFX dans des fichiers jar qui fonctionnent à la fois sur Java 8/11
[Rails6] Créer une nouvelle application avec Rails [Débutant]
Filtre Sobel utilisant OpenCV sur Android (Java)
Créer une application TODO dans Java 7 Créer un en-tête
Créons une application de calcul avec Java
Déployer des applications Web Java sur Heroku
J'ai créé une application de calculatrice sur Android
[Rails 5] Créer une nouvelle application avec Rails [Débutant]
J'ai créé une application Janken avec Android
Un mémo qui a touché Spring Boot
Modèle MVC
Un exemple simple du modèle MVC
[Note personnelle] J'ai appris à la légère sur les modificateurs
Une histoire qui sépare la logique métier et le modèle
Un mémo pour moi que l'orientation de l'objet est quelque chose
Un mémo qui gère une classe créée indépendamment avec ArrayList
Qu'est-ce qu'un modèle MVC?
[Débutant] Application Android qui fait rouler des balles à l'aide de capteurs [Java]
[Azure] J'ai essayé de créer une application Java pour la création d'applications Web gratuites - [Débutant]