Android Game: player boundary problem

edited October 2013 in Android Mode

I'm developing a game for Android and I've ran into a problem. When the player moves past the displayHeight for y position or displayWidth for x position the player will simply stop and can no longer be controlled. I assume it has something to do with the translate I'm doing to keep the player in the center of the screen.

The player is controlled by the accelerometer and I'm using the Fisica library for physics.

This is the current formula I'm using to keep the player centered:

  cX = b.getX() - displayWidth/2;
  cY = b.getY() - displayHeight/2;

  translate(-cX, -cY)

Any help or suggestion would be awesome. Thanks.

///////////////////////Here is all off my current code //////////////////////////////////
/**
 * <p>Ketai Sensor Library for Android: http://KetaiProject.org</p>;
 *
 * <p>KetaiSensor Features:
 * <ul>
 * <li>handles incoming Sensor Events</li>
 * <li>Includes Accelerometer, Magnetometer, Gyroscope, GPS, Light, Proximity</li>
 * <li>Use KetaiNFC for Near Field Communication</li>
 * </ul>
 * <p>Updated: 2012-03-10 Daniel Sauter/j.duran</p>
 */
import android.os.Bundle;
import android.view.WindowManager;
import android.content.res.Configuration;
import android.util.DisplayMetrics; 

import fisica.*;
import ketai.sensors.*;
import android.view.MotionEvent;
import processing.opengl.*;
import ketai.ui.*;

FWorld world;
FBox obstacle;
FCircle b;

FBox asteroid;
//boundaries 
FBox left;
FBox right;
FBox top;
FBox bottom;

FLine testline;

float xVel;
float yVel;
float screenPosX;
float screenPosY;

ArrayList stars;

int savedTime;
int totalTime = 100;

int worldWidth = 3000;
int worldHeight = 2260;

KetaiSensor sensor;
KetaiGesture gesture;
float accelerometerX, accelerometerY, accelerometerZ;
float rotationX, rotationY, rotationZ;

float cX;
float cY;
float ax;
float ay;

void setup()
{
  frameRate(40);

  DisplayMetrics dm = new DisplayMetrics();
  getWindowManager().getDefaultDisplay().getMetrics(dm);
  float density = dm.density; 
  int densityDpi = dm.densityDpi;

  noSmooth();
  size(displayWidth, displayHeight);
  println("display w: " + displayWidth);
  println("display h: " + displayHeight);
  sensor = new KetaiSensor(this);
  sensor.start();
  orientation(LANDSCAPE);
  textAlign(CENTER, CENTER);
  textSize(36);

  gesture = new KetaiGesture(this);

  Fisica.init(this);
  Fisica.worldToScreen(20, 20);
  world = new FWorld();
  world.setGravity(0, 0);



  b = new FCircle(100);
  b.setPosition(0, 0);
  b.setVelocity(0, 0);
  b.setRestitution(.1);
  b.setNoStroke();
  b.setFill(0);
  world.add(b);

  //left
  left = new FBox(1, worldHeight);
  left.setPosition(-worldWidth/2, 0);
  left.setStatic(true);
  left.setFill(0);
  left.setRestitution(.1);
  left.setGroupIndex(1);
  world.add(left);

  //right
  right = new FBox(1, worldHeight);
  right.setPosition(worldWidth/2, 0);
  right.setStatic(true);
  right.setFill(0);
  right.setRestitution(.1);
  right.setGroupIndex(1);
  world.add(right);

  //top
  top = new FBox(worldWidth, 1);
  top.setPosition(0, -worldHeight/2);
  top.setStatic(true);
  top.setFill(0);
  top.setRestitution(.1);
  top.setGroupIndex(1);
  world.add(top);

  //bottom
  bottom = new FBox(worldWidth, 1);
  bottom.setPosition(0, worldHeight/2);
  bottom.setStatic(true);
  bottom.setFill(0);
  bottom.setRestitution(.1);
  bottom.setGroupIndex(1);
  world.add(bottom);

  savedTime = millis();

  stars= new ArrayList();

  for (int i = 0; i < 50; i++) {
    stars.add(new StarGen());
  }
}

void draw()
{
  background(255);



  if (b.getVelocityY() > 1000 || b.getVelocityY() < -1000) {
    ax = 0;
    //   println("vel X not working");
  }
  else {
    ax = accelerometerX*20000;
    // println("velocity X: " + b.getVelocityX());
    // println("ac X: " + ax);
  }

  if (b.getVelocityX() > 1000 || b.getVelocityX() < -1000) {
    ay = 0;
    // println("vel Y not working");
  }
  else {
    ay = accelerometerY*20000;
    // println("velocity Y: " + b.getVelocityY());
    // println("ac X: " + ax);
  }

  b.addForce(ay, ax);



  pushMatrix();

  //cX =  b.getX() - displayWidth/2;
  //cY =  b.getY() - displayHeight/2;



  ////////////////////This is what I'm having trouble with ///////////////////////
  cX = b.getX() - displayWidth/2;
  cY = b.getY() - displayHeight/2;


  // cY = b.getY() - displayHeight/2
  println("cy: " + cY);

  translate(-cX, -cY);

  //////////////////////////////////////////////////////////////////////////////////
  for (int i = stars.size()-1; i >= 0; i--) {
    StarGen s = (StarGen) stars.get(i);
    s.display();
  }
  line(-cX, -cY, b.getX(), b.getY());
  world.draw();
  world.step();



  strokeWeight(1);
  stroke(255);


  popMatrix();

  text("Frame Rate: " + frameRate, 200, 200);
}//end draw



void onTap(float x, float y)
{
  //DASH
  b.setVelocity(0, 0);
  x += cX;
  y += cY;
  float a = atan2(y - b.getY(), x - b.getX() );
  float tx = cos(a) * 2000000;
  float ty = sin(a) * 2000000;
  b.addForce(tx, ty);
  //end dash


  /*
  asteroid = new FBox(150, 150);
   asteroid.setPosition(x + cX, y + cY);
   asteroid.setStatic(true);
   asteroid.setGroupIndex(2);
   asteroid.setFill(0);
   asteroid.setRestitution(1);
   world.add(asteroid);
   */
}//end onTap

void onDoubleTap(float x, float y)
{
  obstacle = new FBox(150, 150);
  obstacle.setPosition(x + cX, y + cY);
  obstacle.setStatic(true);
  obstacle.setGroupIndex(3);
  obstacle.setFill(0);
  obstacle.setRestitution(5);
  world.add(obstacle);
}

void contactStarted(FContact c) {
  FBody ball = null;

  FBody body1 = c.getBody1();
  FBody body2 = c.getBody2();

  if (body2.getGroupIndex() == 1 || body1.getGroupIndex() == 1) {
    println("hit boundary");
  }//end if

  else if (body2.getGroupIndex() == 2 || body1.getGroupIndex() == 2) {
    if (c.getBody1() == b) {
      ball = c.getBody2();
    } 
    else if (c.getBody2() == b) {
      ball = c.getBody1();
    }

    if (ball == null) {
      return;
    }
    world.remove(ball);
    println("kill Asteroid");
  }//end else if

  else if (body2.getGroupIndex() == 3 || body1.getGroupIndex() == 3 ) {
    println("hit Obstacle");
  }//end else if
}//end contact started //

void contactPersisted(FContact c) {
}

void contactEnded(FContact c) {
}

void onGyroscopeEvent(float x, float y, float z)
{
  rotationX = x;
  rotationY = y;
  rotationZ = z;
}

void onAccelerometerEvent(float x, float y, float z)
{
  accelerometerX = x;
  accelerometerY = y;
  accelerometerZ = z;
}

public boolean surfaceTouchEvent(MotionEvent event) {

  //call to keep mouseX, mouseY, etc updated
  super.surfaceTouchEvent(event);

  //forward event to class for processing
  return gesture.surfaceTouchEvent(event);
}

void onCreate(Bundle bundle) {
  super.onCreate(bundle);
  getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
public void onConfigurationChanged(Configuration newConfig) {
  super.onConfigurationChanged(newConfig);
}


class StarGen{

 float x;
 float y;
 float velX;
 float velY;

 StarGen(){
   x = random(-worldWidth/2, worldWidth/2);
   y = random(-worldHeight/2, worldHeight/2);
 }

 void display(){
   stroke(0);
   strokeWeight(10);
  ellipse(x,y,10,10);
  fill(0);
//  textSize(20);
  //text(x +","+ y,x+10,y+10);

 }

}
Tagged:

Answers

  • Moved to the Android section, because you use lot of libraries, some of them specific to this platform.

    And reformatted your code. Select it and hit the C button above the textarea to do it yourself in future messages, please.

  • Thanks for moving it and formatting it. I figured I should put in the other forum because I assume the project is about logic, not a problem specific to Android.

  • edited October 2013 Answer ✓

    I haven't worked with the Fiscia library before, but if I had to guess, based on the behavior that you describe, I'd say that Fiscia'sFCircleclass has internal limitations that constrain the object's location on the screen (with or withouttranslate()) to within the physical visible boundaries. Perhaps there is a way to remove this behavior, or perhaps you need to find an alternative solution, whether it involves creating a substitute class forFCircleor requires changing the scrolling behavior.

  • edited October 2013

    Thanks for the help. I took at look at the reference again and found something I missed. You can set the world size in the FWorld constructor. I'm an idiot for missing it. For whatever reason there are two constructors in the reference, with the one showing custom dimensions much further down the page.

    public FWorld()

    Parameters:

    topLeftX - the horizontal coordinate of the top left corner of the world

    topLeftY - the vertical coordinate of the top left corner of the world

    bottomRightX - the horizontal coordinate of the bottom right corner of the world

    bottomRightY - the vertical coordinate of the bottom right corner of the world

Sign In or Register to comment.