https://www.udemy.com/androidjavapro/
Java knowledge zero OK! Master course to become a professional Android developer [Compatible with the latest Android Studio 3! ] Easy-to-understand and polite commentary! Let's master the basics of Java, the knowledge required as an Android engineer, list view, database creation, and attractive design through abundant samples! 3.9 (182 ratings) 1449 students registered Creator Hiroaki Kaneda Last updated 1/2019
I'm taking this course and the pace is too fast There were some parts that I couldn't understand without detailed explanations, so I'll post a comment so that I can understand it.
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;
/*The event listener keeps an eye on the event and receives it if it exists*/
public class MainActivity extends AppCompatActivity implements SensorEventListener, SurfaceHolder.Callback {
//Declaration of member variables(=Add a lowercase m at the beginning)
SensorManager mSensorManager;
Sensor mAccSensor;
//Declaration of a member variable called mHolder of the SurfaceHolder class
//Think of it as a holder for temporarily storing the screen.
SurfaceHolder mHolder;
int mSurfaceWidth; //width of surfaceView
int mSurfaceHeight; //height of surfaceView
//If you do not add f at the end of the float type number, a compile error will occur.
static final float RADIUS = 150.0f; //A constant that represents the radius when drawing a ball(The unit is pixel)
static final int DIA = (int)RADIUS * 2; //A constant representing the diameter of the ball(Cast to int type)
static final float COEF = 1000.0f; //Coefficient for adjusting the amount of movement of the ball
float mBallX; //The current X coordinate of the ball(position)
float mBallY; //The current Y coordinate of the ball(position)
float mVX; //Acceleration of the ball in the X-axis direction
float mVY; //Acceleration of the ball in the Y-axis direction
//long is a class for representing time
long mT0; //The time when the acceleration was acquired from the sensor last time
//Bitmap is a class for handling images
Bitmap mBallBitmap; //Image of the ball
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Fixed screen to vertical display
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
setContentView(R.layout.activity_main);
/* getSystemService=>Use the android system.
SENSOR in its argument to use the sensor_Use SERVICE.
Store the returned SensorManager in the member variable mSensorManager*/
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
/*TYPE representing the accelerometer in the argument of the getDefaultSensor method_Specify ACCELEROMETER
Stored in member variable mAccSensor*/
mAccSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
//Get the surfaceView placed in the screen layout and store it in the member variable mHolder
SurfaceView surfaceView = (SurfaceView) findViewById(R.id.surfaceView);
mHolder = surfaceView.getHolder();
//Event listener when surfaceHolder is changed / destroyed
mHolder.addCallback(this);
//Since the background image is prepared, make the canvas itself transparent
mHolder.setFormat(PixelFormat.TRANSLUCENT);
surfaceView.setZOrderOnTop(true);
//Show image of the ball
// decodeResource()Get resources with method
//GetResources as an argument()Can be obtained by specifying the id of the method and resource
Bitmap ball = BitmapFactory.decodeResource(getResources(), R.drawable.ball);
//Resize the drawn ball
//DIA the vertical height of the resource acquired in the above line and stored in the ball with createScaledBitmap(diameter)、
//Specify the left and right length as DIA
//The last argument is a filter(Correction for pixel jaggedness)Whether or not to apply
mBallBitmap = Bitmap.createScaledBitmap(ball, DIA, DIA, false);
}
//Method called when the value of the accelerometer changes
@Override
public void onSensorChanged(SensorEvent sensorEvent) {
//If the sensor is an accelerometer
if (sensorEvent.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
/*X the acceleration obtained from the sensor,Substitute for y
Invert the x-axis to match the drawing direction of the screen
It should be noted that each acceleration is understood as an acceleration in the x-axis direction and an acceleration in the y-axis direction.
When accelerating in the opposite direction, it seems that the value will be negatively multiplied.*/
float x = -sensorEvent.values[0];
float y = sensorEvent.values[1];
/*Find time t
At the very beginning of the loop, the last time cannot be taken, so the timestamp of sensorEvent is assigned to mT0.*/
if (mT0 == 0) {
mT0 = sensorEvent.timestamp;
// return;End with
return;
}
//You can find the time by subtracting mT0, which contains the previous time, from the timestamp of the new sensorEvent.
float t = sensorEvent.timestamp -mT0;
mT0 = sensorEvent.timestamp;
t = t/ 1000000000.0f; //Convert nanoseconds to seconds
//Find the distance traveled in the x and y directions
//The following is a physics formula and you don't have to remember it
// (Acceleration in the X-axis direction*time)+(Acceleration of x obtained from the sensor*timeの2乗を2で割る)And calculate the distance traveled
float dx = (mVX * t) + (x * t * t/2.0f);
// (Acceleration in the Y-axis direction*time)+(Acceleration of y obtained from the sensor*timeの2乗を2で割る)And calculate the distance traveled
float dy = (mVY * t) + (y * t * t/2.0f);
//Update the current ball position from the distance traveled
//COEF is a coefficient for natural movement on the screen
mBallX = mBallX + dx * COEF;
mBallY = mBallY + dy * COEF;
//Updated current ball movement speed(Constant acceleration motion formula<=Don't force yourself to remember)
//speed=Initial velocity+acceleration*time
mVX = mVX + (x * t);
mVY = mVY + (y * t);
//Processing to prevent the ball from going off the screen(First, the horizontal axis)
//It becomes negative when the radius of the ball is subtracted from the x coordinate of the current position of the ball.(=Hitting the wall)
//And if the speed is negative, reverse the speed and make it positive.
if(mBallX - RADIUS < 0 && mVX < 0){
//Hit the wall and slow down(Speed 1.Divide by 5 to slow down)
mVX = -mVX / 1.5f;
//Update the ball position coordinates to the radius value
mBallX = RADIUS;
//If the sum of the x-coordinate and radius of the ball is larger than the width of the surfaceView and the velocity is 0 or more
// =If it goes off the screen in the opposite direction
} else if (mBallX + RADIUS > mSurfaceWidth && mVX > 0){
//Hit the wall and slow down
mVX = -mVX / 1.5f;
//The position of the ball to the value obtained by subtracting the radius from the width of surfaceVIew(X coordinate of)Update
mBallX = mSurfaceWidth - RADIUS;
}
//Processing to prevent the ball from going off the screen(Next is the vertical axis)
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;
}
//Redraw the ball on the canvas at the current position of the ball calculated from the acceleration
drawCanvas();
}
}
//The process of displaying the ball on the screen
private void drawCanvas() {
//When you call lockCanvas and get canvas, the surface is locked and you can draw it.
Canvas c = mHolder.lockCanvas();
//Clear the ball on the screen with drawColor(If you do not clear the previous drawing, the screen will be full of balls)
//In other words, drawColor()Is a method of filling something with some color,
//This time it means to fill the canvas with a transparent color.
//The second argument is apparently required
c.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
//The Paint class is necessary to set elements for actual drawing such as drawing color, line thickness, character size and font.
//This time just create an instance for the time being
Paint paint = new Paint();
//Coordinates of canvas canvas(left, top)Draw based on the position of
c.drawBitmap(mBallBitmap, mBallX - RADIUS, mBallY - RADIUS, paint);
//Member variable, mHolder, where surfaceView is stored(holder)Reflection on the screen and unlock of canvas
mHolder.unlockCanvasAndPost(c);
}
//A method called when the accuracy of the accelerometer changes
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
//Method called when the screen is displayed
@Override
protected void onResume() {
super.onResume();
}
@Override
protected void onPause() {
super.onPause();
}
//Called when the Surface is created
@Override
public void surfaceCreated(SurfaceHolder holder) {
/*registerListener is a method to start monitoring the accelerometer
First argument: Who monitors (this refers to MainActivity itself)
Second argument: Sensor you want to monitor
Third argument: Frequency you want to monitor*/
mSensorManager.registerListener(this, mAccSensor, SensorManager.SENSOR_DELAY_GAME);
}
//Called when there is a change in the Surface
//At the same time, initialize the position, speed, and time of the ball.
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
mSurfaceWidth = i1;
mSurfaceHeight = i2;
//Specify the initial position of the ball
//If you specify half the width and height of the surfaceView, you can place it in the center.
mBallX = mSurfaceWidth / 2;
mBallY = mSurfaceHeight / 2;
//Initial speed and time initialization
mVX = 0;
mVY = 0;
mT0 = 0;
}
//Called when the Surface is deleted
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
//End monitoring when the screen is closed//
mSensorManager.unregisterListener(this);
}
}
To execute, click the> execute button on the upper right.
Select an emulator. If you want to try it on an actual device, you need to make settings on the actual device before connecting the actual device via USB (omitted).If you select "..." at the bottom right and then select Virtual sensors You can tilt the emulator and play like this
If you try running the emulator, you can see that it works according to the sensor. However, since the bound processing is performed but the stop processing is not performed, the ball continues to bounce little by little even if the emulator is fixed. It's a specification, not a bug.
There seems to be a way to set a threshold at the deceleration process and set the acceleration to 0 to stop it completely.
I will try it when I get a little better understanding.
Recommended Posts