I am currently building a game in AndEngine, but my collision detection seems a bit off. It works.. most of the time, but seems like when there is a collision with one object, it wont do the other. It's hard to explain and it's very unpredictable.
for (int i = 0; i < rManager.carArray.length; i++)
{
if (rManager.getInstance().snowArray[0].getSnowSprite().collidesWith(rManager.getInstance().carArray[i].getCarSprite()))
{
Log.e("SNOW", "snow 0 collided with " + rManager.getInstance().carArray[i].ToString());
rManager.getInstance().carArray[i].setCarSpeed(0.1f);
break;
}
if (rManager.getInstance().iceArray[0].getIceSprite().collidesWith(rManager.getInstance().carArray[i].getCarSprite()))
{
Log.e("ICE", "ice 0 collided with " + rManager.getInstance().carArray[i].ToString());
rManager.getInstance().carArray[i].setCarSpeed(1f);
break;
}
else
{
rManager.getInstance().carArray[i].setCarSpeed(0.5f);
}
}
Is there anything wrong with my code? Currently, both enemy arrays only have 1 element. That is why I am only checking 0.
It is because of the "break" keyword. When that is called it "breaks out" of the surrounding for loop. So if the first if statement detects a collision, it will not ever call the second if statement.
Related
I am making an app using ML KIT. I am currently implementing counting while doing squats. The problem is that it counts when it goes down to a certain angle, but because it is a real-time tracking, it counts multiple times rather than once. In other words, practically when I do one squat, the counting is much more than that.
So I tried solving the problem using a timer handler. But I failed. Here is my code What should I do?
//going down
if((rightKneeAngle<=90 && leftKneeAngle<=90) || (rightHipAngle<=135 && leftHipAngle<=135)){
//Timer setting
mTimer.schedule(new CustomTimer(), 2000);
Log.d("PoseGraphic.class", "goingdown"+"rightKneeAngle : " + rightKneeAngle+ " leftKneeAngle : " + leftKneeAngle);
Log.d("PoseGraphic.class","leftHip"+leftHipAngle+"RighHip"+rightHipAngle);
Log.d("PoseGraphic.class", "cnt: " + cnt);
//going up
if((rightKneeAngle>170 && leftKneeAngle>90)|| (rightHipAngle>135 && leftHipAngle>135)){
Log.d("PoseGraphic.class", "going up"+"rightKneeAngle : " + rightKneeAngle+ " leftKneeAngle : " + leftKneeAngle);
Log.d("PoseGraphic.class","leftHip"+leftHipAngle+"RightHip"+rightHipAngle);
if(cnt==12) {
canvas.drawText("complete!", x, y, textPaint);
//ExerciseCount.cnt = 0;
cnt=0;
}
}
}
// TIMER handler class
class CustomTimer extends TimerTask
#Override
public void run() {
cnt++;
}
I cannot fully understand how you do it without seeing more code.
An suggestion would be:
Instead of +1 to the count when the pose is in squat_down state, record the entering of that state with a boolean and +1 to the count only once the user exit squat_down and enter squat_up state. Then reset the state boolean.
By doing this, you will only +1 when user finish an entire cycle from squat_down to up.
Actually, ML Kit just launched an example for squat and pushup classification and rep-counting. Here is the app you can try. If you want to classify some other poses, here is some guide and a Colab.
In my android program, I have 3 functions that will be continuously repeated until the user exits the app. Currently, it is able to update a value(position) every second.
I was wondering if having lots of if else condition in one of the function will slow down the performance of my app i.e. it might take way longer than a second for the updates to kick in.
Note that 2 of the if else function will execute only once. All the if-else function have very little code in it. Below is the code
public void positionUpdated(Coordinate userPosition, int accuracy) {
// GETS EXECUTED ONCE //
if(nameList.size() == 0) {nameList = indoorsFragment.getZones();}
if(end == null) {
for(int i=0 ; i < nameList.size() ; i++) if(nameList.get(i).equals(name)) end = nameList.get(i).getZonePoints().get(0);
}
// GETS EXECUTED ONCE //
if(Math.abs(userPosition.x - end.x) >500) {Toast.makeText(this,"WALK " + Math.abs(end.x - userPosition.x)/1000 + " Meters" , Toast.LENGTH_SHORT).show();return;}
if(turn) {
if ((userPosition.y - end.y) < 0) {Toast.makeText(this, "STOP AND TURN RIGHT", Toast.LENGTH_LONG).show();turn=false;return;}
if ((userPosition.y - end.y) > 0) {Toast.makeText(this, "STOP AND TURN LEFT" , Toast.LENGTH_LONG).show();turn=false;return;}
}
if((Math.abs(userPosition.y - end.y) < 500)) Toast.makeText(this, "WALK", Toast.LENGTH_LONG).show();
}
Hope to receive some feedback regarding this , thanks
Haziq
The number of statements doesn't really matter, in fact they're executed in fractions of nanoseconds. what matters is if you have many nested loops or recursions.
If you don't want much work to be done in the foreground thread, use an AsyncTask or Runnable then update the UI in the main thread.
I've been fighting this problem for a while now and thought I'd ask for some advice.
The purpose of this code is to generate a Json file with the information about how the user moved in the app. Everytime I get a touch event, I write to an arraylist of Json objects with the following information:
{"action", "timestamp", "index", "y", "x"}
The action is what kind of action it is (down, up, etc.), timestamp is the time from the start of the touch recording, index is supposed to be what finger, (x,y) is the position of the finger.
The problem however, is that I can't seem to make it work with multi-touch. Eventually this Json file will be used to make a video, showing the movements of the user. One finger works perfectly but when there's several fingers involved, I need to have the information about what finger this specific data comes from.
Currently, it tracks a finger and if I use another finger, it will start to track that instead, ignoring the first one.
public void writeTouchJSON(MotionEvent event, float time) {
int pointerCount = event.getPointerCount();
JSONObject object = new JSONObject();
try {
String action;
action = new String();
switch(event.getAction()) {
case MotionEvent.ACTION_DOWN:
action = "down";
break;
case MotionEvent.ACTION_UP:
action = "up";
break;
default:
action = "" + event.getActionMasked();
}
for (int i = 0; i < pointerCount; i++) {
//int index = event.getPointerId(i);
object.put("x", (int) event.getX(i)); // X-pos of finger
object.put("y", (int) event.getY(i)); // Y-pos of finger
object.put("timestamp", (int) (0.000001*(time - timeAtAppLaunch))); // Time since recording started
object.put("action", action); // What kind of action ("up", "down" or a constant)
object.put("index", i + 1); // What finger
}
Log.d("Wrote JSON to list", object.toString());
} catch (JSONException e) {
e.printStackTrace();
Log.d("ERROR: json.", ""+e);
}
jsonobjects.add(object);
}
I hope the code attached is enough. In the method
onTouchEvent(MotionEvent event)
I check if the app is recording, if it is I send event to logTouchEvents(event) which eventually ends up in the writeTouchJSON method.
My personal theory is that I mess up the meaning of pointers. From what I've understood a pointer is a finger? So an event has an array of pointers where 0 will give you information about the first finger who touched the screen, 1 about the second, etc. but maybe this is wrong?
If you're interested in why I'm doing this it's because I'm making a user experience testing apk for school where you can record how a person navigates through your app and get a video displaying this.
Thank you for your time! Appreciate any help I can get!
On the for loop each variable is getting overwriten by its previous value. You should create an array with one element for each pointer (finger).
I have a 10-field average lap calculator. However, in testing, someone said they normally only run X laps in practice, vs. 10 (let's say 7).
I think I could use an if statement, but there'd be at least 10 of them and a bunch of clumsy code, and I'm not sure on arrays/switch statements exactly. I think all of those might be possible, but my low level of experience has yet to fully comprehend these useful tools.
CURRENT CODE:
double tenLapAvgVar = ((lap1Var + lap2Var + lap3Var + lap4Var + lap5Var + lap6Var + lap7Var + lap8Var + lap9Var + lap10Var) / 10);
So essentially, if someone leaves a field or fields blank, I want to calculate the average based on the populated fields, not 10 (if they leave 3 fields blank, calculate based on 7, for instance). Any help you guys could provide would be much appreciated, thanks!
You could have an ArrayList<EditText> object and a method which iterates over it and adds up the values. Something like:
public double getLapAverage()
{
int noOfCompletedLaps = 0;
double lapAve = 0;
double lapsTotal = 0;
for(EditText text : textBoxes)
{
if(text.getText().toString().length() > 0)
{
//psuedo code, and assuming text is numerical
lapsTotal += Double.parse(text.getText().toString());
noOfCompletedLaps++;
}
}
if( noOfCompletedLaps > 0)
{
lapAve = lapsTotal / noOfCompletedLaps;
}
return lapAve;
}
Maybe it would be better if you used an array instead of 10 different variables.
Then you can use a for statement and initialize them to 0, afterwords let the user fill the array and count how many are not zero.
Finally sum up all the array and divide by the count you previously calculated.
I am using a Pool to manage Bullets in my game. The only problem is when a Bullet is obtained from the pool having just been recycled because it was involved in a collision, although it's Body's location is reset using Body.setTransform() when it is initialized, the Bullet's Sprite's location (which is used to detect collisions using Sprite.collidesWith(otherSprite)) is not reset quick enough (as it's updated in a Physics thread). This means the newly created bullet causes a collision the instant it is created, resulting in a single bullet causing more than one collision.
I tried calling Bullet.sprite.setPosition(0,0) when it is initialized, but this clearly interferes, as Bullets fail to be displayed at all with that line of code in place. What should I do to prevent this problem?
Bullet Creation:
bullets[bulletCounter] = bulletPool.obtainPoolItem();
bullets[bulletCounter].getBody().setTransform(shipBody.getTransform().getPosition(),0);
bullets[bulletCounter].getBody().setLinearVelocity(shipBody.getLinearVelocity());
bullets[bulletCounter].activate();
Collision Detection:
for(int i = 0; i < BULLET_MAX; i++){
if(bullets[i] != null && bullets[i].isActive()){
for(int j = 0; j < enemies.size(); j++){
//check for collision!
if(bullets[i].getSprite().collidesWith(enemies.get(j).getSprite())){
//-snip-
break;
}
}
}
}
I'd be interested to see what you're doing around the time you invoke onHandleObtainItem to get a bullet from the pool.
Would it not make sense to set the sprite position to some offscreen value when you invoke onHandleRecycleItem, something like:
#Override
protected void onHandleRecycleItem(final Bullet pBullet) {
pBullet.disable();
pBullet.getSprite().setPosition(-1, -1);
}