I want to develop a small game where an orange rectangle is animated from the right to the left on the display and when it is in the middle (green rectangle) the user should press a button and gets points if he/she succeeds (see Screenshot): 
Here is the code of the game class
public class Test extends Fragment implements View.OnClickListener {
/*
Game variables
*/
public static final int DELAY_IN_MILLIS = 100;
ArrayList<View_Game_Event_Rectangle> arrayList_GameEventRectangles;
private int currentTimeSlot;
private boolean gameIsRunning;
private Handler handler = new Handler();
private int timeslotsEventElementUntilTheMiddleOfTheScreen_Level1 = (int)(5.0 * (1000.0/DELAY_IN_MILLIS));
private int numberOfMillisecondsUntilTheMiddleOfTheScreen_Level1 = 5000;
//Fix parameters of the UI elements
private float horizontalPercentageOfScoreRectangle_End = 0.491f;
private float horizontalPercentageOfScoreRectangle_Start = 0.567f;
private float verticalBiasOfEventElementToBeInTheLine = 0.049f;
private float percentageHeightOfEventElement = 0.071f;
int widthDisplay;
int heightDisplay;
int helpCounterRun =0;
int helpCounterUpdateScreen =0;
int helpCounterCountDownTime =0;
private FragmentTestBinding binding;
private ConstraintLayout constraintLayout;
ConstraintSet constraintSet ;
//Variables for the single view event
View_Game_Event_Rectangle[] viewEvent;
private boolean fragmentViewHasBeenCreated = false;
private CountDownTimer cdt;
private final long DURATION = 900000L;
private final long DELAY_COUNT_DOWN_TIMER = 100;
private int numberOfTimeSlotsUntilTheEndOfScreen = (int)(numberOfMillisecondsUntilTheMiddleOfTheScreen_Level1 * 2/(DELAY_COUNT_DOWN_TIMER));
private int currentLevel;
public Test() {
// Required empty public constructor
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
arrayList_GameEventRectangles = new ArrayList<View_Game_Event_Rectangle>();
currentLevel = 1;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
binding = FragmentTestBinding.inflate(inflater, container, false);
WindowManager wm = (WindowManager) getActivity().getWindowManager();
Display display = wm.getDefaultDisplay();
Point size = new Point();
display.getSize(size);
widthDisplay = size.x;
heightDisplay = size.y;
container.getContext();
constraintLayout= binding.constraintLayout;
fragmentViewHasBeenCreated = true;
getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
constraintLayout = binding.constraintLayout;
constraintSet = new ConstraintSet();
startGame();
return binding.getRoot();
}
@Override
public void onClick(View view) {
}
public void startGame () {
gameIsRunning = true;
Log.e("LogTag_El", "-------Start Game------" );
//Create rectangle-element that should be animated from the right to the left on the screen
arrayList_GameEventRectangles.add(new View_Game_Event_Rectangle(getActivity(), "Bulb Rectangle", 100, 20));
countDownTime();
}
private void updateScreen() {
for (int currentElement =0; currentElement <arrayList_GameEventRectangles.size(); currentElement++) {
//Create view and set
if (currentTimeSlot == arrayList_GameEventRectangles.get(currentElement).getStartingTimeSlot() - 50) {
arrayList_GameEventRectangles.get(currentElement).setActive(true);
//Set the parameters and the backgrund of the view element
arrayList_GameEventRectangles.get(currentElement).setLayoutParams(new ViewGroup.LayoutParams(0, 0));
if(arrayList_GameEventRectangles.get(currentElement).getEventType().equals("Bulb Rectangle")) {
arrayList_GameEventRectangles.get(currentElement).setBackground(ContextCompat.getDrawable(getActivity(),R.drawable.game_event_rectangle_bulb_1).mutate());
}
arrayList_GameEventRectangles.get(currentElement).setId(View.generateViewId());
//Make the view invisible (before it's appearence time)
arrayList_GameEventRectangles.get(currentElement).getBackground().setAlpha(0);
// Set the ConstraintLayout programatically for the view
constraintLayout.addView(arrayList_GameEventRectangles.get(currentElement));
constraintSet.clone(constraintLayout);
constraintSet.constrainPercentHeight(arrayList_GameEventRectangles.get(currentElement).getId(), percentageHeightOfEventElement);
float widthConstrainPercentage_element1 = (float)(arrayList_GameEventRectangles.get(currentElement).getDuration() / 100.0);
float duration = arrayList_GameEventRectangles.get(currentElement).getDuration();
constraintSet.constrainPercentWidth(arrayList_GameEventRectangles.get(currentElement).getId(), widthConstrainPercentage_element1);
constraintSet.connect(arrayList_GameEventRectangles.get(currentElement).getId(),ConstraintSet.BOTTOM, ConstraintSet.PARENT_ID,ConstraintSet.BOTTOM,0);
constraintSet.connect(arrayList_GameEventRectangles.get(currentElement).getId(),ConstraintSet.TOP,ConstraintSet.PARENT_ID ,ConstraintSet.TOP,0);
constraintSet.connect(arrayList_GameEventRectangles.get(currentElement).getId(),ConstraintSet.LEFT,ConstraintSet.PARENT_ID ,ConstraintSet.LEFT,0);
constraintSet.connect(arrayList_GameEventRectangles.get(currentElement).getId(),ConstraintSet.RIGHT,ConstraintSet.PARENT_ID ,ConstraintSet.RIGHT,0);
float horizontalBias = 1.0f ;
constraintSet.setHorizontalBias(arrayList_GameEventRectangles.get(currentElement).getId(), horizontalBias);
constraintSet.setVerticalBias(arrayList_GameEventRectangles.get(currentElement).getId(), verticalBiasOfEventElementToBeInTheLine);
constraintSet.applyTo(constraintLayout);
}
//Shift the view to the right border of the display
if (currentTimeSlot == arrayList_GameEventRectangles.get(currentElement).getStartingTimeSlot() - 40) {
arrayList_GameEventRectangles.get(currentElement).setTranslationX(arrayList_GameEventRectangles.get(currentElement).getWidth());
}
//Animate view element
if (currentTimeSlot ==arrayList_GameEventRectangles.get(currentElement).getStartingTimeSlot()) {
arrayList_GameEventRectangles.get(currentElement).getBackground().setAlpha(255);
long durationForTheAnimation = (long)(numberOfMillisecondsUntilTheMiddleOfTheScreen_Level1 * 1);
arrayList_GameEventRectangles.get(currentElement).animate().setDuration(durationForTheAnimation).translationX(widthDisplay*(-1)).start();
}
helpCounterUpdateScreen++;
checkPositionsOfActiveElements();
}
}
private void countDownTime(){
cdt = new CountDownTimer(DURATION, DELAY_COUNT_DOWN_TIMER) {
boolean delay = true;
public void onTick(long millisUntilFinished) {
if(delay) {
delay = false;
} else {
helpCounterCountDownTime++;
currentTimeSlot++;
updateScreen();
delay = true;
}
}
public void onFinish() {
updateScreen();
}
}.start();
}
public void checkPositionsOfActiveElements () {
for (int currentElement =0; currentElement <arrayList_GameEventRectangles.size(); currentElement++) {
//Check if the view is still running
if (arrayList_GameEventRectangles.get(currentElement).isActive() == true && currentElement==0) {
Log.e("LogTag_FGa_CP", "currentTimeSlot: " + currentTimeSlot);
Log.e("LogTag_FGa_CP", "currentElement.getX(): " + arrayList_GameEventRectangles.get(currentElement).getX());
}
}
}
@Override
public void onDestroyView() {
super.onDestroyView();
// Reset your variable to false
fragmentViewHasBeenCreated = false;
// And clean up any postDelayed callbacks that are waiting to fire
cdt.cancel();
handler.removeCallbacksAndMessages(null);
}
}
And here is the XML-layout file:
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/constraintLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<View
android:id="@+id/imageView_TargetRectangle"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@drawable/rectangle"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHeight_percent="0.16"
app:layout_constraintHorizontal_bias="0.535"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.01"
app:layout_constraintWidth_percent="0.10" />
<Button
android:id="@+id/button_action"
android:layout_width="0dp"
android:layout_height="0dp"
android:text="Action"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHeight_percent="0.102"
app:layout_constraintHorizontal_bias="0.373"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.745"
app:layout_constraintWidth_percent="0.13" />
</androidx.constraintlayout.widget.ConstraintLayout>
To animate the view and to count down the time I use the handler CountDownTimer. Actually the animation itself works (I first shift the invisible orange rectangle to the very right and then make it visible after a certain time and animate it). To problem is, that I can not precisely determine where the orange rectangle is. I can only determine it after a certain timespan and this is not enough for what I want to do.
Here is the output of the LogTag:
2023-03-14 18:37:40.318 15544-15544/com.example.game E/LogTag_FGa_CP: currentTimeSlot: 100
2023-03-14 18:37:40.320 15544-15544/com.example.game E/LogTag_FGa_CP: currentElement.getX(): 2028.0
2023-03-14 18:37:40.617 15544-15544/com.example.game E/LogTag_FGa_CP: currentTimeSlot: 101
2023-03-14 18:37:40.618 15544-15544/com.example.game E/LogTag_FGa_CP: currentElement.getX(): 2013.0167
2023-03-14 18:37:40.857 15544-15544/com.example.game E/LogTag_FGa_CP: currentTimeSlot: 102
2023-03-14 18:37:40.857 15544-15544/com.example.game E/LogTag_FGa_CP: currentElement.getX(): 1972.158
2023-03-14 18:37:41.149 15544-15544/com.example.game E/LogTag_FGa_CP: currentTimeSlot: 103
2023-03-14 18:37:41.150 15544-15544/com.example.game E/LogTag_FGa_CP: currentElement.getX(): 1883.3052
2023-03-14 18:37:41.403 15544-15544/com.example.game E/LogTag_FGa_CP: currentTimeSlot: 104
2023-03-14 18:37:41.403 15544-15544/com.example.game E/LogTag_FGa_CP: currentElement.getX(): 1780.0686
2023-03-14 18:37:41.668 15544-15544/com.example.game E/LogTag_FGa_CP: currentTimeSlot: 105
2023-03-14 18:37:41.669 15544-15544/com.example.game E/LogTag_FGa_CP: currentElement.getX(): 1634.5706
2023-03-14 18:37:41.931 15544-15544/com.example.game E/LogTag_FGa_CP: currentTimeSlot: 106
2023-03-14 18:37:41.936 15544-15544/com.example.game E/LogTag_FGa_CP: currentElement.getX(): 1495.0557
2023-03-14 18:37:42.185 15544-15544/com.example.game E/LogTag_FGa_CP: currentTimeSlot: 107
2023-03-14 18:37:42.186 15544-15544/com.example.game E/LogTag_FGa_CP: currentElement.getX(): 1317.382
2023-03-14 18:37:42.481 15544-15544/com.example.game E/LogTag_FGa_CP: currentTimeSlot: 108
2023-03-14 18:37:42.481 15544-15544/com.example.game E/LogTag_FGa_CP: currentElement.getX(): 1088.4066
2023-03-14 18:37:42.760 15544-15544/com.example.game E/LogTag_FGa_CP: currentTimeSlot: 109
As you can see, the x-positions of the orange rectangle decrease by a huge amount of pixels when I check it (e.g. 1972.158, 1883.3052, 1780.0686). What I actually want to have is a method, that can return each of the positions of the orange rectangle, meaning: 1972, 1971, 1970, 1969 etc.. This way, I could make sure - after pressing the button - to get the exact position of the orange rectangle.
Reminder: Would anyone mind sharing his/her knowledge about how to check the positions precisely? I'll highly appreciate every input as I tried a lot and don't know how to proceed.
from How to precisely check the position of an animated element in Android
No comments:
Post a Comment