We are about to switch to a new forum software. Until then we have removed the registration on this forum.
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);
}
}
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.
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's
FCircle
class 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 forFCircle
or requires changing the scrolling behavior.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