I have problem, with rendering blocks after reScalling (zoom in-out) whole thing in my game
(sorry with my eng syntax , cuz Eng not my native language)
first look at my video
>Error Rendering Video
there are problem , When it's rendering blocks after change blocks scale to some specific number
look at my code
GameLoopThread.java
public class GameLoopThread extends Thread {
static long FPS = 20;
private GameView view;
private boolean running = false;
public GameLoopThread ( GameView view ) {
this.view = view;
}
#Override
public void run () {
long ticksPS = 1000 / GameLoopThread.FPS; // 0.05 second (50) ;
long startTime;
long delayDelta = 0;
long tmpDelta = 0;
while (this.running) {
Canvas c = null;
startTime = System.currentTimeMillis();
try {
c = this.view.getHolder().lockCanvas();
synchronized (this.view.getHolder()) {
this.view.onDraw(c);
}
ClientCoreStatic.clientGear.updateWorlds();
}
catch (NullPointerException e) {
e.printStackTrace();
}
finally {
if (c != null) this.view.getHolder().unlockCanvasAndPost(c);
}
// 50
// sleepTime = ticksPS - (System.currentTimeMillis() - startTime);
tmpDelta = (System.currentTimeMillis() - startTime);
// time use Should below than 50
try {
if (tmpDelta > ticksPS) delayDelta += tmpDelta - ticksPS;
// d.pl("gameloop thread + " + delayDelta);
if (delayDelta > 0) {
//Thread.sleep(10);
if (ticksPS >= tmpDelta) {
delayDelta -= ticksPS - tmpDelta;
}
}
else {
delayDelta = 0;
Thread.sleep(ticksPS - tmpDelta);
}
if (this.view.hashCode() != ClientStatic.gameView.hashCode()) {
this.setRunning(false);
GameView.parentActivity.finish();
break;
}
}
catch (Exception e) {
e.printStackTrace();
d.pl("gameloop error");
}
}
}
GameView.java
#Override
public boolean onTouchEvent ( MotionEvent event ) {
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE:
// true
if (event.getPointerCount() == 1 ) {
if (GameView.spriteKeypadcircle.isCollition(
event.getX(),
event.getY()) == true) // d.pl("true..");
return true;
if (GameView.spriteBlocks.isCollition(event.getX(), event.getY())) {
// check
GameView.spriteBlocks.isCollitionOnBlock(event.getX(),event.getY());
d.pl("touching at "+ event.getX() + "," + event.getY());
return true;
}
}
if (event.getPointerCount() == 2 ) {
d.pl("distance 1 " +
GameView.distance1XY[0][0] +
"," +
GameView.distance1XY[0][1] +
" + " +
GameView.distance1XY[1][0] +
"," +
GameView.distance1XY[1][1] +
" | " +
GameView.distance2XY[0][0] +
"," +
GameView.distance2XY[0][1] +
" + " +
GameView.distance2XY[1][0] +
"," +
GameView.distance2XY[1][1]);
for (int size = event.getPointerCount(), i = 0; i < size; i++) {
// PointF point = mActivePointers.get(event.getPointerId(i));
// if (point != null) {
// point.x = event.getX(i);
// point.y = event.getY(i);
// }
float x = event.getX(i);
float y = event.getY(i);
if (!GameView.spriteBlocks.isCollition(x, y)) break;
GameView.distance2XY[i][0] = x;
GameView.distance2XY[i][1] = y;
} // for
// after get position
// check distance
double tmp1 = Math.sqrt((Math.pow(GameView.distance1XY[0][0] -
GameView.distance1XY[1][0], 2)) +
(Math.pow(GameView.distance1XY[0][1] -
GameView.distance1XY[1][1], 2)));
double tmp2 = Math.sqrt((Math.pow(GameView.distance2XY[0][0] -
GameView.distance2XY[1][0], 2)) +
(Math.pow(GameView.distance2XY[0][1] -
GameView.distance2XY[1][1], 2)));
GameView.newDistance = Math.abs(tmp1 - tmp2);
if (GameView.newDistance > 200) { // change too much
GameView.distance1XY[0][0] = GameView.distance2XY[0][0];
GameView.distance1XY[0][1] = GameView.distance2XY[0][1];
GameView.distance1XY[1][0] = GameView.distance2XY[1][0];
GameView.distance1XY[1][1] = GameView.distance2XY[1][1];
return true;
}
// if (newDistance < 100) break;
// if (newD < 100) break;
if (tmp1 < tmp2)
SpriteBlocks.viewScale += GameView.newDistance / 1000;
else
SpriteBlocks.viewScale -= GameView.newDistance / 1000;
if (SpriteBlocks.viewScale < 0.2) SpriteBlocks.viewScale = 0.2;
if (SpriteBlocks.viewScale > 10) SpriteBlocks.viewScale = 10;
GameView.spriteBlocks.updateScale();
GameView.distance1XY[0][0] = GameView.distance2XY[0][0];
GameView.distance1XY[0][1] = GameView.distance2XY[0][1];
GameView.distance1XY[1][0] = GameView.distance2XY[1][0];
GameView.distance1XY[1][1] = GameView.distance2XY[1][1];
return true;
}
return true;
case MotionEvent.ACTION_DOWN:
return true;
case MotionEvent.ACTION_UP:
return true;
}
return false;
}
#Override
protected void onDraw ( Canvas canvas ) {
canvas.drawColor(Color.GRAY);
GameView.spriteBlocks.onDraw(canvas);
GameView.spriteCharStand.onDraw(canvas);
GameView.spriteKeypadcircle.onDraw(canvas);
}
SpriteBlocks.java
public SpriteBlocks ( GameView gameView, Bitmap bmp ) {
this.bmp = bmp;
SpriteBlocks.width = bmp.getWidth() / SpriteBlocks.BMP_COLUMNS;
SpriteBlocks.height = bmp.getHeight() / SpriteBlocks.BMP_ROWS;
SpriteBlocks.widthPixels = Resources.getSystem().getDisplayMetrics().widthPixels;
SpriteBlocks.heightPixels = Resources.getSystem().getDisplayMetrics().heightPixels;
SpriteBlocks.centerXScreen = SpriteBlocks.widthPixels / 2;
SpriteBlocks.centerYScreen = SpriteBlocks.heightPixels / 2;
// System.out.println("fififi " + this.weightPixels + "," +
// this.heightPixels);
updateScale();
src2 = new Rect(0, 0, 400, 400);
paintTextPlayCur.setColor(Color.BLACK);
paintTextPlayCur.setTextSize(32);
paintTextSelectBlock.setColor(Color.RED);
paintTextSelectBlock.setTextSize(32);
}
public void updateScale () {
// SpriteBlocks.viewScale = 1;
SpriteBlocks.curBlockWidth = SpriteBlocks.viewScale *
SpriteBlocks.width;
SpriteBlocks.xBlockCount = Math.round(SpriteBlocks.widthPixels /
SpriteBlocks.curBlockWidth);
SpriteBlocks.yBlockCount = Math.round(SpriteBlocks.heightPixels /
SpriteBlocks.curBlockWidth);
SpriteCharStand.curPlayerRenderHeight = SpriteCharStand.playerRenderHeight *
SpriteBlocks.viewScale;
SpriteCharStand.curPlayerRenderWidth = SpriteCharStand.playerRenderWidth *
SpriteBlocks.viewScale;
SpriteCharStand.playerLeftTopX = SpriteBlocks.centerXScreen -
(SpriteCharStand.curPlayerRenderWidth / 2);
SpriteCharStand.playerLeftTopY = SpriteBlocks.centerYScreen -
(SpriteCharStand.curPlayerRenderHeight / 2);
SpriteCharStand.playerRightDownX = SpriteBlocks.centerXScreen +
(SpriteCharStand.curPlayerRenderWidth / 2);
SpriteCharStand.playerRightDownY = SpriteBlocks.centerYScreen +
(SpriteCharStand.curPlayerRenderHeight / 2);
d.pl("viewScale = " +
SpriteBlocks.viewScale +
", width = " +
SpriteBlocks.curBlockWidth);
}
#Override
public void onDraw ( Canvas canvas ) {
update();
if (ClientStatic.minePlayer == null) {
ClientStatic.minePlayer = ClientStatic.playerList
.get(ClientStatic.mineID);
if (ClientStatic.playerList.get(ClientStatic.mineID) == null) {
d.pl(" uuuu " + ClientStatic.mineID);
return;
}
}
// center screen point is this location
minePlayerX = ClientStatic.minePlayer.getLocation().getX();// + 0.5;
minePlayerY = ClientStatic.minePlayer.getLocation().getY();// + 1;
double adderPoint = 0.1;
for ( double adder = 0 ; adder <= 1 ; adder += adderPoint) {
minePlayerX += adderPoint;
// left top of screen is this location
bX = ((minePlayerX) - (SpriteBlocks.xBlockCount / 2) - 1);
bY = ((minePlayerY) + (SpriteBlocks.yBlockCount / 2) + 1);
// right down of screen is this position
cX = ((minePlayerX) + (SpriteBlocks.xBlockCount / 2) + 1);
cY = ((minePlayerY) - (SpriteBlocks.yBlockCount / 2) - 1);
// (SpriteCharStand.curPlayerRenderWidth / 2)
Material me;
Block bbo;
leftXdiff = (minePlayerX * 100) % 100;
leftYdiff = (minePlayerY * 100) % 100;
/*
* leftXdiff = Math.abs(leftXdiff);
* leftYdiff = Math.abs(leftYdiff);
*/
// calculating them from scale
leftXdiff = (curBlockWidth * leftXdiff) / 100;
leftYdiff = (curBlockWidth * leftYdiff) / 100;
// d.pl("cur x " + minePlayerX + " |m " + leftXdiff + " |bx " + bX);
for (double xloop = bX; xloop <= cX; xloop++) { // loop all position X
//for (double yloop = bY; yloop >= cY; yloop--) { // loop all position
// Y
for (double yloop = 140.5 ; yloop == 140.5 ; yloop ++) {
// range Y
if ((yloop < 0) || yloop > (FixVariable.CHUNK_HEIGHT - 1)) {
continue;
}
// get block of that location
bbo = ClientStatic.minePlayer
.getLocation()
.getWorld()
.getBlockAt(((xloop)), ((yloop)));
me = Material.getMaterial(bbo.getTypeId());
srcX = me.getX(bbo.getData()) * SpriteBlocks.width;
srcY = me.getY(bbo.getData()) * SpriteBlocks.height;
srcKey = ((double) srcX * 10) + ((double) (srcY));
src = srcList.get(srcKey);
if (src == null) {
src = new Rect(srcX, srcY, srcX + SpriteBlocks.width, srcY +
SpriteBlocks.height);
srcList.put(srcKey, src);
}
// position to drawing
if (xloop == 5 && yloop == 140.5) {
d.pl("SPY!! " + tmpXPosition + " = " + xloop + " - " + bX + " ) * 200 -" + leftXdiff);
}
tmpXPosition = ((xloop - bX) * SpriteBlocks.curBlockWidth) -
(leftXdiff );
if (xloop == 5 && yloop == 140.5) {
if (me != Material.BED){
d.pl("bed is spy");
}
if (Math.abs(lastTmpXPosition- tmpXPosition) < 1 &&
(Math.abs(lastTmpXPosition- tmpXPosition) > 0)) {
System.out.println("WT " + (Math.abs(lastTmpXPosition- tmpXPosition)));
}
d.pl("lastTmpXPos = " + lastTmpXPosition + " | " + tmpXPosition);
if (lastTmpXPosition != tmpXPosition) {
lastTmpXPosition = tmpXPosition;
}
}
tmpYPosition = (((SpriteBlocks.yBlockCount) - (yloop - cY + (10*adder) )) * SpriteBlocks.curBlockWidth) +
(leftYdiff);
if (dst == null) {
dst = new Rect();
}
dst.set(
(int) tmpXPosition,
(int) tmpYPosition,
(int) (tmpXPosition + SpriteBlocks.curBlockWidth),
(int) (tmpYPosition + SpriteBlocks.curBlockWidth));
canvas.drawBitmap(bmp, src, dst, null);
dst2.set(
(int) (tmpXPosition),
(int) (tmpYPosition),
(int) (tmpXPosition + SpriteBlocks.curBlockWidth),
(int) (tmpYPosition + SpriteBlocks.curBlockWidth));
canvas.drawBitmap(GameView.bmpRect, src2, dst2, null);
// break;
}
} // for
bbo = ClientStatic.minePlayer
.getLocation()
.getWorld()
.getBlockAt(
ClientStatic.minePlayer.getLocation().getX(),
ClientStatic.minePlayer.getLocation().getY());
me = Material.getMaterial(bbo.getTypeId());
srcX = me.getX(bbo.getData()) * SpriteBlocks.width;
srcY = me.getY(bbo.getData()) * SpriteBlocks.height;
srcKey = ((double) srcX * 10) + ((double) (srcY));
tmpXPosition = 5;
tmpYPosition = 5;
dst.set(
(int) tmpXPosition,
(int) tmpYPosition,
(int) (tmpXPosition + SpriteBlocks.curBlockWidth),
(int) (tmpYPosition + SpriteBlocks.curBlockWidth));
canvas.drawText(
"playLoc " +
ClientStatic.minePlayer.getLocation().getX() +
"," +
ClientStatic.minePlayer.getLocation().getY(),
200,
200,
paintTextPlayCur);
canvas.drawBitmap(bmp, src, dst, null);
canvas.drawText(
"block " +
ClientStatic.minePlayer
.getLocation()
.getWorld()
.getBlockAt(
ClientStatic.minePlayer
.getLocation()
.getX(),
ClientStatic.minePlayer
.getLocation()
.getY())
.getTypeId() +
" | chunk " +
ClientStatic.minePlayer
.getLocation()
.getWorld()
.getChunkAt(
ClientStatic.minePlayer
.getLocation()
.getX())
.getChunkNumberX() +
" | " +
ClientStatic.minePlayer
.getLocation()
.getWorld()
.getChunkAt(
ClientStatic.minePlayer
.getLocation()
.getX()).getX()
,
200,
300,
paintTextPlayCur);
canvas.drawBitmap(bmp, src, dst, null);
// draw touch block
if (blockTouching != null) {
canvas.drawText("touch " +
blockTouching.getX() +
"," +
blockTouching.getY() +
" = " +
blockTouching.getTypeId() +
":" +
blockTouching.getData()
, 300, 400, paintTextSelectBlock);
}
} // adder
}
Related
I have a for-loop code:
try
{
outputStream = new FileOutputStream("/sdcard/output1.txt");
Writer out = new OutputStreamWriter(outputStream);
Point point;
for (int i = 48; i <= 66; i++)
{
point = landmarks.get(i);
int pointX = (int) (point.x * resizeRatio);
int pointY = (int) (point.y * resizeRatio);
Log.d(TAG, "My points:(" + pointX + "," + pointY + ")");
point = landmarks.get(i + 1);
int pointXX = (int) (point.x * resizeRatio);
int pointYY = (int) (point.y * resizeRatio);
canvas.drawLine(pointX, pointY, pointXX, pointYY,mFaceLandmardkPaint);
out.write(Integer.toString(pointX));
String h = ",";
out.write(h);
out.write(Integer.toString(pointY));
String j = ",";
out.write(j);
}
out.write("\n");
out.close();
}
In this i need to start from 48 limit after the first 66 limit gets over.How can i again starts from 48th limit???
use recursion.
create a method to execute your forloop and at the end of loop call the method again.
like
if(i==65){
callMethodAgain();
}
and to break the loop store a temp variable to do the count ex.
if(i==65&& temp<2){
temp++;
callMethodAgain();
}
Try following code :
for(int j=0; j<2; j++){
for (int i = 48; i <= 66; i++)
{
if(j == 0){
point = landmarks.get(i);
int pointX = (int) (point.x * resizeRatio);
int pointY = (int) (point.y * resizeRatio);
Log.d(TAG, "My points:(" + pointX + "," + pointY + ")");
point = landmarks.get(i + 1);
int pointXX = (int) (point.x * resizeRatio);
int pointYY = (int) (point.y * resizeRatio);
canvas.drawLine(pointX, pointY, pointXX, pointYY,mFaceLandmardkPaint);
out.write(Integer.toString(pointX));
String h = ",";
out.write(h);
out.write(Integer.toString(pointY));
String j = ",";
out.write(j);
}
else{
// do your stuff
}
}
}
I am trying to make real time application based on canvas writing here multiple device will be connected with this application if i write something on canvas it should reflect on other devices which are connected with this app here my issue is i am able to write on canvas and its also writes smooth but when it comes to receiving end its getting disjoint segment not clear path visible on canvas.
I am using thread using moveTo() and quadTo()to and receiving points from server
here images for reference
Source writing
Receiving end
Here is my code which i am trying
onDraw method
#Override
protected void onDraw(final Canvas canvas) {
normal_canvas_draw=true;
bckimage = getBackground();
String col = "#333333".substring(1);
col = col.toLowerCase();
col = "#ff" + col;
mc.setcanvas(canvas);
paint1.setAntiAlias(true);
paint1.setDither(true);
paint1.setStyle(Paint.Style.STROKE);
paint1.setStrokeJoin(Paint.Join.ROUND);
paint1.setStrokeCap(Paint.Cap.ROUND);
paint1.setPathEffect(new CornerPathEffect(30) ); // set the path effect when they join.
paint.setDither(true); // set the dither to true
paint.setStyle(Paint.Style.STROKE); // set to STOKE
paint.setStrokeJoin(Paint.Join.ROUND); // set the join to round you want
paint.setStrokeCap(Paint.Cap.ROUND); // set the paint cap to round too
paint.setPathEffect(new CornerPathEffect(30) ); // set the path effect when they join.
paint.setAntiAlias(true);
mCanvas.drawPath(path, paint);
mCanvas.drawPath(path1, paint1);
/*
for(Path p :paths)
{
mCanvas.drawPath(p, paint1);
}*/
//mCanvas.drawPath(path1, paint1);
//s = paths.size();
s = type.size();
Log.d("BLOCK", s + " , " + leftval.size());
int j = 0, k = 0;
canvas.drawBitmap(img, 0, 0, null);
canvas.drawText(mc.getDisplaymsg(), mCanvas.getWidth()-200, 25, painttext);
r = new Rect(10, 600, 100, 650);
}
onTouchEvent
#Override
public boolean onTouchEvent(MotionEvent event) {
if (mIsScrolling)
sv.requestDisallowInterceptTouchEvent(false);
else
sv.requestDisallowInterceptTouchEvent(true);
float eventX = event.getX();
float eventY = event.getY();
boolean touchcaptured = false;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
path.reset();
// path.moveTo(eventX, eventY);
boolean l = r.contains((int) event.getX(), (int) event.getY());
if (markerMode)
{
isEraserDown="false";
isPenDown="false";
isMarkerDown="true";
path.moveTo(eventX,eventY);
startX=eventX/scalefactor;
startY=eventY/scalefactor;
mX=eventX;
mY=eventY;
MainActivity.super.loadUrl("javascript:eraserfunction(" + eventX / scalefactor + "," + eventY / scalefactor + "," + mc.getdrawAttributes1() + ")");
}
else if (eraseMode)
{
isEraserDown="true";
isPenDown="false";
isMarkerDown="false";
System.out.println("--Eraserfromtouch");
path.moveTo(eventX,eventY);
startX=eventX/scalefactor;
startY=eventY/scalefactor;
mX=eventX;
mY=eventY;
MainActivity.super.loadUrl("javascript:eraserfunction(" + eventX / scalefactor + "," + eventY / scalefactor + "," + mc.getdrawAttributes1() + ")");
}
else if (blockerase) {
// left=(int) event.getX();
// right=left+1;
// top=(int) event.getY();
// bottom=top+1;
rx = (int) event.getX();
ry = (int) event.getY();
}
/*------------------- Pendown when we touch on mobile screen------*/
else if (penmode) {
isPenDown="true";
isEraserDown="false";
isMarkerDown="false";
System.out.println("---pen-down---"+eventX+","+eventY);
int historySize = event.getHistorySize();
if(isPenDown=="true")
{
path.moveTo(eventX,eventY);
mX = eventX;
mY = eventY;
startX=eventX/scalefactor;
startY=eventY/scalefactor;
mc.setXY(eventX / scalefactor, eventY / scalefactor);
MainActivity.super.loadUrl("javascript:penDown(0,0,'pen')");
}
else
{
}
// System.out.println(" Lcal x"+eventX+" y"+eventY+" x2"+eventX+" y2"+eventY);
} else if (rectanglemode) {
rx = (int) event.getX();
ry = (int) event.getY();
} else if (linemode) {
rx = (int) event.getX();
ry = (int) event.getY();
} else if (circlemode) {
cx = (int) event.getX();
cy = (int) event.getY();
MainActivity.super.loadUrl("javascript:circleDown(" + cx / scalefactor + "," + cy / scalefactor + ")");
} else if (textmode) {
cx = (int) event.getX();
cy = (int) event.getY();
//MainActivity.super.loadUrl("javascript:drawtext(" +cx + "," + cy+","+"Hello World"+")");
}
//invalidate();
break;
case MotionEvent.ACTION_MOVE:
if (markerMode) {
if (isMarkerDown.equals("true")) {
System.out.println("Marker Move");
Log.d("MARKER", "Hi im marker");
String col = mc.getdrawAttributes().substring(1);
col = col.toLowerCase();
col = "#ff" + col;
int coll = Color.parseColor(col);
paint.setColor(coll);
paint.setAlpha(10);
paint.setStrokeWidth(20);
if (bckimage == null) {
} else {
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.XOR));
}
MainActivity.super.loadUrl("javascript:marker1(" + eventX / scalefactor + "," + eventY / scalefactor + ")");
}
else{
}
path.quadTo(mX,mY,(mX+event.getX())/2,(mY+event.getY())/2);
mX=event.getX();
mY=event.getY();
}
else if (eraseMode)
{
if(isEraserDown=="true")
{
System.out.println("--Eraserfromtouch--MOVE");
System.out.println("Marker Move");
Log.d("Eraser", "Im eraser");
String thh = mc.getdrawAttributes1();
float f = Float.parseFloat(thh);
paint.setStrokeWidth(f);
if (bckimage == null) {
paint.setColor(Color.WHITE); //Toast.makeText(getContext(),"ERASE",Toast.LENGTH_LONG).show();
} else {
// setLayerType(View.LAYER_TYPE_SOFTWARE, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
MainActivity.super.loadUrl("javascript:eraserfunction1(" + eventX / scalefactor + "," + eventY / scalefactor + "," + mc.getdrawAttributes1() + ")");
}
path.quadTo(mX,mY,(mX+event.getX())/2,(mY+event.getY())/2);
mX=event.getX();
mY=event.getY();
}
else
{
}
}
else if (blockerase) {
qx = (int) event.getX();
qy = (int) event.getY();
}
/*------------------Pen move on the screen following by finger-------------*/
else if (penmode) {
if(isPenDown=="true")
{
String thh1 = mc.getdrawAttributes1();
float width = Float.parseFloat(thh1);
paint.setStrokeWidth(width);
paint.setColor(color);
paint.setDither(true); // set the dither to true
paint.setStyle(Paint.Style.STROKE); // set to STOKE
paint.setStrokeJoin(Paint.Join.ROUND); // set the join to round you want
paint.setStrokeCap(Paint.Cap.ROUND); // set the paint cap to round too
paint.setPathEffect(new CornerPathEffect(30) ); // set the path effect when they join.
paint.setAntiAlias(true);
// Line current = lines.get(lines.size() - 1);
System.out.println("---penmove---");
float dx = Math.abs((int) event.getX() - mX);
float dy = Math.abs((int) event.getY() - mY);
System.out.println("--Value of dx-dy-"+dx+"-"+dy);
if (dx >= 4 || dy >= 4) {
// setXY function set X and Y values to be used in JS File
mc.setXY((int) event.getX() / scalefactor, (int) event.getY() / scalefactor);
MainActivity.super.loadUrl("javascript:penMove(0,0,'pen')");
path.quadTo(mX,mY,(mX+event.getX())/2,(mY+event.getY())/2);
mX=event.getX();
mY=event.getY();
}
else
{
}
}
} else if (rectanglemode) {
qx = (int) event.getX();
qy = (int) event.getY();
} else if (linemode) {
qx = (int) event.getX();
qy = (int) event.getY();
} else if (circlemode) {
//MainActivity.super.loadUrl("javascript:circleDown(" + eventX + "," + eventY + ")");
}
break;
case MotionEvent.ACTION_UP:
boolean ll = r.contains((int) event.getX(), (int) event.getY());
if (markerMode)
MainActivity.super.loadUrl("javascript:marker12()");
else if (eraseMode) {
MainActivity.super.loadUrl("javascript:penUp()");
isEraserDown="false";
isMarkerDown="false";
System.out.println("--Eraserfromtouch---actionup");
path.lineTo(mX,mY);
mCanvas.drawPath(path,paint);
path= new Path();
// path1= new Path();
paths.add(path);
// MainActivity.super.loadUrl("javascript:eraserfunction1(" + eventX / scalefactor + "," + eventY / scalefactor + "," + mc.getdrawAttributes1() + ")");
}else if (blockerase) {
qx = (int) event.getX();
qy = (int) event.getY();
MainActivity.super.loadUrl("javascript:bigeraserfunction1(" + rx / scalefactor + "," + ry / scalefactor + "," + qx / scalefactor + "," + qy / scalefactor + ")");
}
/*---------------------Pen up for writing on canvas------------------*/
else if (penmode) {
MainActivity.super.loadUrl("javascript:penUp()");
isPenDown="false";
System.out.println("---pen--up---");
path.lineTo(mX,mY);
mCanvas.drawPath(path,paint);
path= new Path();
// path1= new Path();
paths.add(path);
} else if (rectanglemode) {
qx = (int) event.getX();
qy = (int) event.getY();
MainActivity.super.loadUrl("javascript:rectangle(" + rx / scalefactor + "," + ry / scalefactor + "," + qx / scalefactor + "," + qy / scalefactor + ",'" + Prefs.getString(Elucido_APP_CONSTANTS.shared_user_name, "") + "')");
} else if (linemode) {
qx = (int) event.getX();
qy = (int) event.getY();
MainActivity.super.loadUrl("javascript:line(" + rx / scalefactor + "," + ry / scalefactor + "," + qx / scalefactor + "," + qy / scalefactor + ",'" + Prefs.getString(Elucido_APP_CONSTANTS.shared_user_name, "") + "')");
} else if (circlemode) {
c1x = (int) event.getX();
c1y = (int) event.getY();
MainActivity.super.loadUrl("javascript:circleup(" + c1x / scalefactor + "," + c1y / scalefactor + ")");
} else if (textmode) {
cx = (int) event.getX();
cy = (int) event.getY();
opentextDialog((int) (cx / scalefactor), (int) (cy / scalefactor));
}
break;
default:
return false;
}
invalidate();
return true;
}
draw() Method is in thread for continuously receiving points path
public boolean draw() {
//------------------------ Starting Reciving points--------------------------
String s1 = mc.getdrawlinesdual();
words1 = s1.split(",");
float xx11 = Float.parseFloat(words1[0].replaceAll("[\\(\\)\\[\\]\\{\\}]", "")) * scalefactor;
float yy11 = Float.parseFloat(words1[1]) * scalefactor;
float xx21 = Float.parseFloat(words1[2]) * scalefactor;
float yy21 = Float.parseFloat(words1[3].replaceAll("[\\(\\)\\[\\]\\{\\}]", "")) * scalefactor;
System.out.println("---------x" + xx11 + " y" + yy11 + " x2" + xx21 + " y2" + yy21);
if (a1 == 0)
{
System.out.println("----paint from pen--a1 == 0");
Log.d("TAGG", "INTEGER value " + mc.getdrawAttributes());
if (mc.getdrawTypeAttributes().toString().compareTo("eraser") == 0) {
System.out.println("Eraser--a1==0---ifllop");
Log.d("Eraser", "Im eraser");
String thh = mc.getdrawThAttributes();
float f = Float.parseFloat(thh);
paint1.setStrokeWidth(f);
if (bckimage == null) {
paint1.setColor(Color.WHITE); //Toast.makeText(getContext(),"ERASE",Toast.LENGTH_LONG).show();
} else {
paint1.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
}
} else {
System.out.println("Eraser--a1==0---elsellop");
String th = mc.getdrawThAttributes();
float f = Float.parseFloat(th);
paint1.setColor(color);
}
String t = mc.getdrawTypeAttributes().trim();
if ((t.compareTo("marker") == 0)) {
Log.d("MARKER", "Hi im marker");
String col = mc.getdrawColorAttributes().substring(1);
col = col.toLowerCase();
col = "#ff" + col.trim();
int coll = Color.parseColor(col);
paint1.setColor(coll);
paint1.setAlpha(10);
paint1.setStrokeWidth(20);
if (bckimage == null) {
} else {
paint1.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.XOR));
}
}
path1.moveTo(xx11, yy11);
// path1.lineTo(xx21, yy21);
path1.quadTo(xx11, yy11, (xx11 + xx21) / 2, (yy11 + yy21) / 2);
// invalidate();
// type.add("Line");
path1 = new Path();
a1 = xx11;
b1 = yy11;
c1 = xx21;
d1 = yy21;
}
else if (a1 == xx11)
{
//il.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
System.out.println("----paint from pen--a1 == xx11");
MainActivity.this.blankwhiteboard = 1;
path1.moveTo(c1, d1);
// float x = c+(xx2-c)/2;
// float y= d+(yy2-d)/2;
path1.quadTo(c1, d1, (c1 + xx21) / 2, (d1 + yy21) / 2);
// path1.lineTo(xx21, yy21);
invalidate();
c1 = xx21;
d1 = yy21;
}
else
{
type.add("Line");
System.out.println("----paint from pen");
path1 = new Path();
paint1 = new Paint();
paint1.setAntiAlias(true);
String th = mc.getdrawThAttributes();
paint1.setStyle(Paint.Style.STROKE);
paint1.setStrokeJoin(Paint.Join.ROUND);
paint1.setStrokeCap(Paint.Cap.ROUND);
paint1.setPathEffect(new CornerPathEffect(30));
paint1.setDither(true);
String t = mc.getdrawTypeAttributes();
if (mc.getdrawTypeAttributes().toString().compareTo("eraser") == 0)
{
System.out.println("Eraser--a1!=0---ifllop");
System.out.println("inside cuming erase");
//float val = 20;
String thh = mc.getdrawThAttributes();
float f = Float.parseFloat(thh);
paint1.setStrokeWidth(f);
Log.d("Eraser", "Im in eraser");
if (bckimage == null) {
paint1.setColor(Color.WHITE); //Toast.makeText(getContext(),"ERASE",Toast.LENGTH_LONG).show();
} else
paint1.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
invalidate();
}
else
{
System.out.println("Eraser--a1!=0---elsellop");
float f = Float.parseFloat(th);
paint1.setStrokeWidth(f);
String col = mc.getdrawColorAttributes().substring(1);
col = col.toLowerCase();
col = "#ff" + col;
int coll = Color.parseColor(col);
paint1.setColor(coll);
if ((t.compareTo("marker") == 0))
{
Log.d("MARKER", "Hi im marker");
paint1.setAlpha(10);
paint1.setStrokeWidth(20);
if (bckimage == null)
{
}
else
{
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.XOR));
}
paint1.setStrokeWidth(f);
mc.getTelephoneNumber(Integer.toHexString(color).substring(2));
MainActivity.super.loadUrl("javascript:colorSelectListener('')");
}
else
{
}
}
path1.moveTo(xx11, yy11);
// path1.lineTo(xx21,yy21);
path1.quadTo(xx11, yy11, (xx11 + xx21) / 2, (yy11 + yy21) / 2);
a1 = xx11;
b1 = yy11;
c1 = xx21;
d1 = yy21;
}
invalidate();
//------------------------ End Reciving points--------------------------
}
I am worked on Bus Ticket Booking Application. I write code for seat layout but seats display in one column. I don't know why only one column display. but I want to look like below image
code that i used
void prepareSeatChart() {
try {
RelativeLayout[] r = new RelativeLayout[]{(RelativeLayout) findViewById(R.id.lowerDeckRelativeLayout), (RelativeLayout) findViewById(R.id.upperDeckRelativeLayout)};
int i = this._cellWidth;
if (this._cellWidth < 1) {
int totalHorizontalMargin = getResources().getDimensionPixelSize(R.dimen.activity_horizontal_margin) * 2;
this._cellWidth = (getWindowManager().getDefaultDisplay().getWidth() - totalHorizontalMargin) / this._cols;
if (this._cols < 6) {
this._cellWidth = (getWindowManager().getDefaultDisplay().getWidth() - totalHorizontalMargin) / 6;
}
this._cellHeight = (this._cellWidth * 82) / Constants.AppCompatTheme_ratingBarStyle;
}
if (this._hasCompartments[0]) {
findViewById(R.id.lowerDeckLinearLayout).setVisibility(View.VISIBLE);
findViewById(R.id.upperDeckLinearLayout).setVisibility(View.GONE);
findViewById(R.id.lowerDeckRelativeLayout).setVisibility(View.GONE);
findViewById(R.id.upperDeckRelativeLayout).setVisibility(View.GONE);
} else {
findViewById(R.id.lowerDeckLinearLayout).setVisibility(View.GONE);
findViewById(R.id.upperDeckLinearLayout).setVisibility(View.GONE);
findViewById(R.id.lowerDeckRelativeLayout).setVisibility(View.VISIBLE);
findViewById(R.id.upperDeckRelativeLayout).setVisibility(View.GONE);
}
if (this._seatWidth == 0) {
this._seatWidth = ((r[0].getWidth() - 20 - this._margin * 2 * this._cols) / this._cols);
if (this._cols < 6) {
this._seatWidth = ((r[0].getWidth() - 20 - this._margin * 2 * 6) / 6);
}
}
int w1 = this._seatWidth;
View emptyView = new View(this);
emptyView.setId((((this._rows * 10) + Constants.AUTH_API_INVALID_CREDENTIALS) + this._cols) + 2);
ImageView imageView = new ImageView(this);
imageView.setImageResource(R.drawable.steering_icon);
imageView.setScaleType(ScaleType.CENTER);
imageView.setId((((this._rows * 10) + Constants.AUTH_API_INVALID_CREDENTIALS) + this._cols) + 1);
int width = (this._cellWidth * 64) / Constants.AppCompatTheme_ratingBarStyle;
int height = (this._cellWidth * 72) / Constants.AppCompatTheme_ratingBarStyle;
int mLeft = (this._cellWidth * 21) / Constants.AppCompatTheme_ratingBarStyle;
int mRight = mLeft;
int mTop = (int) (((double) ((this._cellWidth * 5) / Constants.AppCompatTheme_ratingBarStyle)) * 1.5d);
int mBottom = mTop;
if (this._cellWidth != (width + mLeft) + mRight) {
width = (this._cellWidth + width) - ((width + mLeft) + mRight);
}
if (this._cellHeight != (height + mTop) + mBottom) {
height = (this._cellHeight + height) - ((height + mTop) + mBottom);
}
emptyView.setLayoutParams(new RelativeLayout.LayoutParams(this._cellWidth * (this._cols - 1), height));
r[0].addView(emptyView);
RelativeLayout.LayoutParams imageViewParams = new RelativeLayout.LayoutParams(width, height);
imageViewParams.setMargins(mLeft, mTop, 0, mBottom);
imageViewParams.addRule(10, -1);
imageViewParams.addRule(1, emptyView.getId());
imageView.setLayoutParams(imageViewParams);
r[0].addView(imageView);
for (int d = 0; d < 2; d++) {
if (!this._hasCompartments[d]) {
int i4 = 0;
while (true) {
if (i4 >= this._rows) {
break;
}
int j = 0;
while (true) {
if (j >= this._cols) {
break;
}
if (this._seat[d][i4][j] == null) {
PrivateBusSeatGeSe s = new PrivateBusSeatGeSe();
s.setDeck(d);
s.setSeatColumns(j);
s.setSeatRows(i4);
s.setID((((s.getDeck() * BaseActivity.RESULT_CODE_ERROR) + (s.getSeatRows() * 10)) + s.getSeatColumns()) + 1);
this._seat[d][i4][j] = s;
}
if ((((d * BaseActivity.RESULT_CODE_ERROR) + (i4 * 10)) + j) + 1 == this._seat[d][i4][j].getID()) {
Button button = new Button(this);
button.setTextColor(getResources().getColor(R.color.btn_text_shadow));
if (this._seat[d][i4][j].getSelected()) {
button.setText(this._seat[d][i4][j].getSeatNo());
}
button.setId(this._seat[d][i4][j].getID());
button.setBackgroundResource(getSeatBackGroundResource(d, i4, j));
if (this._seat[d][i4][j].getAvailable()) {
button.setTag(this._seat[d][i4][j].getSeatNo());
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View paramAnonymousView) {
try {
PrivateBusSeatLayout.this.onSeatButtonClick(paramAnonymousView);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
int w;
int h;
int mL;
int mR;
int mT;
int mB;
ViewGroup.MarginLayoutParams layoutParams;
if (this._seat[d][i4][j].getSeatWidth() == 2) {
w = (this._cellWidth * 154) / Constants.AppCompatTheme_ratingBarStyle;
h = (this._cellWidth * 54) / Constants.AppCompatTheme_ratingBarStyle;
mL = (this._cellWidth * 29) / Constants.AppCompatTheme_ratingBarStyle;
mR = mL;
mT = (this._cellWidth * 14) / Constants.AppCompatTheme_ratingBarStyle;
mB = mT;
if (this._cellWidth * 2 != (w + mL) + mR) {
w = ((this._cellWidth * 2) + w) - ((w + mL) + mR);
}
i = this._cellHeight;
if (this._cellHeight != (h + mT) + mB) {
h = (this._cellHeight + h) - ((h + mT) + mB);
}
layoutParams = new RelativeLayout.LayoutParams(w, h);
layoutParams.setMargins(mL, mT, mR, mB);
} else {
if (this._seat[d][i4][j].getSeatHeight() == 2) {
w = (this._cellWidth * 54) / Constants.AppCompatTheme_ratingBarStyle;
h = (this._cellWidth * 154) / Constants.AppCompatTheme_ratingBarStyle;
mL = (this._cellWidth * 26) / Constants.AppCompatTheme_ratingBarStyle;
mR = mL;
mT = (this._cellWidth * 5) / Constants.AppCompatTheme_ratingBarStyle;
mB = mT;
i = this._cellWidth;
if (this._cellWidth != (w + mL) + mR) {
w = (this._cellWidth + w) - ((w + mL) + mR);
}
if (this._cellHeight * 2 != (h + mT) + mB) {
h = ((this._cellHeight * 2) + h) - ((h + mT) + mB);
}
layoutParams = new RelativeLayout.LayoutParams(w, h);
layoutParams.setMargins(mL, mT, mR, mB);
} else {
w = (this._cellWidth * 64) / Constants.AppCompatTheme_ratingBarStyle;
h = (this._cellWidth * 72) / Constants.AppCompatTheme_ratingBarStyle;
mL = (this._cellWidth * 21) / Constants.AppCompatTheme_ratingBarStyle;
mR = mL;
mT = (this._cellWidth * 5) / Constants.AppCompatTheme_ratingBarStyle;
mB = mT;
i = this._cellWidth;
if (this._cellWidth != (w + mL) + mR) {
w = (this._cellWidth + w) - ((w + mL) + mR);
}
i = this._cellHeight;
if (this._cellHeight != (h + mT) + mB) {
h = (this._cellHeight + h) - ((h + mT) + mB);
}
layoutParams = new RelativeLayout.LayoutParams(w, h);
layoutParams.setMargins(mL, mT, mR, mB);
}
}
if (i4 == 0) {
if (d == 0) {
((RelativeLayout.LayoutParams) layoutParams).addRule(3, imageView.getId());
} else {
((RelativeLayout.LayoutParams) layoutParams).addRule(10, -1);
}
}
if (j == 0) {
((RelativeLayout.LayoutParams) layoutParams).addRule(9, -1);
}
if (i4 > 0) {
((RelativeLayout.LayoutParams) layoutParams).addRule(3, this._seat[d][i4 - 1][j].getID());
}
if (j > 0) {
((RelativeLayout.LayoutParams) layoutParams).addRule(1, this._seat[d][i4][j - 1].getID());
}
button.setPadding(0, 0, 0, 0);
((Button) button).setTextSize(10.0f);
button.setLayoutParams(layoutParams);
r[d].addView(button);
}
j++;
}
i4++;
}
} else {
prepareSeatChartWithCompartments(d);
}
}
}catch (Exception e)
{
e.printStackTrace();
}
}
void prepareSeatChartWithCompartments(int d) {
LinearLayout[] l = new LinearLayout[]{(LinearLayout) findViewById(R.id.lowerDeckLinearLayout), (LinearLayout) findViewById(R.id.upperDeckLinearLayout)};
int w = ((getWindowManager().getDefaultDisplay().getWidth() - (this._margin * 6)) - 10) / 6;
int seatCount = 0;
Log.d("prpeare compartments","" + this._seatList.size());
for (int i = 0; i < this._seatList.size(); i++) {
PrivateBusSeatGeSe s = this._seatList.get(i);
if (s.getDeck() == d) {
View v;
LinearLayout.LayoutParams params;
if (seatCount % 2 == 0 && seatCount > 0) {
v = new View(this);
v.setBackgroundColor(getResources().getColor(R.color.gray));
int width = s.getSeatWidth() * w;
params = new LinearLayout.LayoutParams(-1, 1);
params.setMargins(w, 4, 0, 4);
v.setPadding(0, 0, 0, 0);
v.setLayoutParams(params);
l[d].addView(v);
}
if (seatCount % 2 == 1) {
v = new View(this);
params = new LinearLayout.LayoutParams(s.getSeatWidth() * w, (s.getSeatHeight() * w) / 2);
params.setMargins(w, 0, 0, 0);
v.setPadding(0, 0, 0, 0);
v.setLayoutParams(params);
l[d].addView(v);
}
Button v2 = new Button(this);
v2.setTextColor(getResources().getColor(R.color.btn_text_shadow));
if (s.getSelected()) {
v2.setText(s.getSeatNo());
}
v2.setId(s.getID());
v2.setBackgroundResource(getSeatBackGroundResourceWithSeat(s));
params = new LinearLayout.LayoutParams(s.getSeatWidth() * w, s.getSeatHeight() * w);
if (s.getSeatWidth() == 2) {
params.setMargins((this._margin * 2) + w, this._margin, this._margin * 2, this._margin);
} else if (s.getSeatHeight() == 2) {
params.setMargins(this._margin + w, this._margin * 2, this._margin, this._margin * 2);
} else {
params.setMargins(this._margin + w, this._margin, this._margin, this._margin);
}
v2.setPadding(0, 0, 0, 0);
v2.setTextSize(10.0f);
v2.setLayoutParams(params);
if (s.getAvailable()) {
v2.setTag(s.getSeatNo());
v2.setOnClickListener(new View.OnClickListener()
{
public void onClick(View paramAnonymousView)
{
try {
PrivateBusSeatLayout.this.onSeatButtonClick(paramAnonymousView);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
l[d].addView(v2);
seatCount++;
}
}
}
int getSeatBackGroundResourceWithSeat(PrivateBusSeatGeSe s) {
String seatTypeStr = "";
String seatDirectionStr = "";
String seatGenderStr = "";
String seatStatusStr = "";
if(!s.getEmpty())
{
if (s.getSleeper()) {
seatTypeStr = Constants.GA_PRODUCT_VARIANT_SLEEPER;
if (s.getSeatWidth() == 2) {
seatDirectionStr = "_h";
} else if (s.getSeatHeight() == 2) {
seatDirectionStr = "_v";
}
} else if (s.getSeatNo().trim().length() > 0) {
seatTypeStr = Constants.GA_PRODUCT_VARIANT_SEATER;
}
if (s.getSelected()) {
seatStatusStr = "_selected";
} else {
if (s.getAvailable()) {
seatStatusStr = "_available";
} else {
seatStatusStr = "_booked";
}
if (s.getLadies()) {
seatGenderStr = "_female";
} else {
seatGenderStr = "_male";
}
}
if (seatTypeStr.trim().length() > 0) {
return this._seatLegendMap.get("ico_" + seatTypeStr + seatStatusStr + seatGenderStr + seatDirectionStr);
}
if (this._emptyColomn == -1 && s.getSeatColumns() > 0 && s.getSeatColumns() < this._cols) {
this._emptyColomn = s.getSeatColumns();
}
}
return 0;
}
I'm developing a game using SurfaceView which listens to touch events. The onTouchEvent method in SurfaceView works fine for many of the devices, but in some devices, sometimes it doesn't get called (Moto X Style is the one) and my app also stops responding.
I guess that this might be due to the overloading of main thread due to which onTouchEvent is starving.
Could some Android experts over here give me some tips to reduce the load on main thread if it's getting overloaded, or there might be some other reason which may cause this
The code is quite complex but still I'm posting some if you want to go through it
GameLoopThread
public class GameLoopThread extends Thread{
private GameView view;
// desired fps
private final static int MAX_FPS = 120;
// maximum number of frames to be skipped
private final static int MAX_FRAME_SKIPS = 5;
// the frame period
private final static int FRAME_PERIOD = 1000 / MAX_FPS;
private boolean running = false;
public GameLoopThread(GameView view){
this.view = view;
}
public void setRunning(boolean running){
this.running = running;
}
public boolean isRunning() {
return running;
}
#Override
public void run() {
Canvas canvas;
long beginTime; // the time when the cycle begun
long timeDiff; // the time it took for the cycle to execute
int sleepTime; // ms to sleep (<0 if we're behind)
int framesSkipped; // number of frames being skipped
while (running) {
canvas = null;
// try locking the canvas for exclusive pixel editing
// in the surface
try {
canvas = view.getHolder().lockCanvas();
synchronized (view.getHolder()) {
beginTime = System.nanoTime();
framesSkipped = 0; // resetting the frames skipped
// update game state
// render state to the screen
// draws the canvas on the panel
this.view.draw(canvas);
// calculate how long did the cycle take
timeDiff = System.nanoTime() - beginTime;
// calculate sleep time
sleepTime = (int)(FRAME_PERIOD - timeDiff/1000000);
if (sleepTime > 0) {
// if sleepTime > 0 we're OK
try {
// send the thread to sleep for a short period
// very useful for battery saving
Thread.sleep(sleepTime);
} catch (InterruptedException e) {}
}
while (sleepTime < 0 && framesSkipped < MAX_FRAME_SKIPS) {
// update without rendering
// add frame period to check if in next frame
sleepTime += FRAME_PERIOD;
framesSkipped++;
}
}
}
finally {
// in case of an exception the surface is not left in
// an inconsistent state
view.getHolder().unlockCanvasAndPost(canvas);
} // end finally
}
}
}
GameView
public class GameView extends SurfaceView {
ArrayList<Bitmap> circles = new ArrayList<>();
int color;
public static boolean isGameOver;
public GameLoopThread gameLoopThread;
Circle circle; // Code for Circle class is provided below
public static int score = 0;
public static int stars = 0;
final Handler handler = new Handler();
int remainingTime;
boolean oneTimeFlag;
Bitmap replay;
Bitmap home;
Bitmap star;
int highScore;
boolean isLeaving;
public GameView(Context context, ArrayList<Bitmap> circles, int color) {
super(context);
this.circles = circles;
this.color = color;
oneTimeFlag = true;
gameLoopThread = new GameLoopThread(GameView.this);
getHolder().addCallback(new SurfaceHolder.Callback() {
#Override
public void surfaceCreated(SurfaceHolder holder) {
if (!gameLoopThread.isRunning()) {
gameLoopThread.setRunning(true);
gameLoopThread.start();
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
gameLoopThread.setRunning(false);
gameLoopThread = new GameLoopThread(GameView.this);
}
});
initializeCircles();
if(!gameLoopThread.isRunning()) {
gameLoopThread.setRunning(true);
gameLoopThread.start();
}
}
public void initializeCircles() {
ArrayList<String> numbers = new ArrayList<>();
for(int i=0;i<10;i++)
numbers.add(i+"");
Random random = new Random();
int position = random.nextInt(4);
numbers.remove(color + "");
int p1 = position;
int r1 = Integer.valueOf(numbers.get(random.nextInt(9)));
numbers.remove(r1+"");
int r2 = Integer.valueOf(numbers.get(random.nextInt(8)));
numbers.remove(r2 + "");
int r3 = Integer.valueOf(numbers.get(random.nextInt(7)));
ArrayList<Bitmap> bitmaps = new ArrayList<>();
if(position == 0) {
bitmaps.add(circles.get(color));
bitmaps.add(circles.get(r1));
bitmaps.add(circles.get(r2));
bitmaps.add(circles.get(r3));
}
else if(position == 1) {
bitmaps.add(circles.get(r1));
bitmaps.add(circles.get(color));
bitmaps.add(circles.get(r2));
bitmaps.add(circles.get(r3));
}
else if(position == 2) {
bitmaps.add(circles.get(r1));
bitmaps.add(circles.get(r2));
bitmaps.add(circles.get(color));
bitmaps.add(circles.get(r3));
}
else {
bitmaps.add(circles.get(r1));
bitmaps.add(circles.get(r2));
bitmaps.add(circles.get(r3));
bitmaps.add(circles.get(color));
}
numbers = new ArrayList<>();
for(int i=0;i<10;i++)
numbers.add(i+"");
position = random.nextInt(4);
numbers.remove(color + "");
r1 = Integer.valueOf(numbers.get(random.nextInt(9)));
numbers.remove(r1 + "");
r2 = Integer.valueOf(numbers.get(random.nextInt(8)));
numbers.remove(r2 + "");
r3 = Integer.valueOf(numbers.get(random.nextInt(7)));
if(position == 0) {
bitmaps.add(circles.get(color));
bitmaps.add(circles.get(r1));
bitmaps.add(circles.get(r2));
bitmaps.add(circles.get(r3));
}
else if(position == 1) {
bitmaps.add(circles.get(r1));
bitmaps.add(circles.get(color));
bitmaps.add(circles.get(r2));
bitmaps.add(circles.get(r3));
}
else if(position == 2) {
bitmaps.add(circles.get(r1));
bitmaps.add(circles.get(r2));
bitmaps.add(circles.get(color));
bitmaps.add(circles.get(r3));
}
else {
bitmaps.add(circles.get(r1));
bitmaps.add(circles.get(r2));
bitmaps.add(circles.get(r3));
bitmaps.add(circles.get(color));
}
circle = new Circle(this, bitmaps, circles, p1, position, color, getContext());
}
#Override
public void draw(Canvas canvas) {
if(canvas != null) {
super.draw(canvas);
canvas.drawColor(Color.WHITE);
if(!isGameOver && timer != null)
stopTimerTask();
try {
circle.draw(canvas);
} catch (GameOverException e) {
isGameOver = true;
if(isLeaving)
gameOver(canvas);
else if(GameActivity.counter > 0) {
gameOver(canvas);
GameActivity.counter++;
} else {
if (oneTimeFlag) {
int size1 = 200 * GameActivity.SCREEN_HEIGHT / 1280;
int size2 = 125 * GameActivity.SCREEN_HEIGHT / 1280;
float ratio = (float) GameActivity.SCREEN_HEIGHT / 1280;
replay = GameActivity.decodeSampledBitmapFromResource(getResources(), R.drawable.replay, size1, size1);
home = GameActivity.decodeSampledBitmapFromResource(getResources(), R.drawable.home, size2, size2);
continueButton = GameActivity.decodeSampledBitmapFromResource(getContext().getResources(), R.drawable.button, (int) (540 * ratio), (int) (100 * ratio));
star = GameActivity.decodeSampledBitmapFromResource(getContext().getResources(), R.drawable.star1, (int) (220 * ratio), (int) (220 * ratio));
int w = (int) ((float) GameActivity.SCREEN_WIDTH * 0.9);
oneTimeFlag = false;
}
if (askPurchaseScreen == 2) {
gameOver(canvas);
} else {
canvas.drawColor(Circle.endColor);
}
}
}
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
circle.onTouch(x, y);
return true;
}
}
Circle
public class Circle {
int x;
int y1;
int y2;
public static float speedY1 = 12.5f*(float)GameActivity.SCREEN_HEIGHT/1280;
public static float speedY2 = 12.5f*(float)GameActivity.SCREEN_HEIGHT/1280;
ArrayList<Bitmap> bitmaps;
GameView gameView;
int p1; // Position of required circle in slot 1
int p2; // Position of required circle in slot 2
int color;
int tempColor;
int width;
Context context;
// Centers of required circle
float centerX1;
float centerX2;
float centerY1;
float centerY2;
ArrayList<Bitmap> circles = new ArrayList<>();
boolean touchedFirst;
boolean touchedSecond;
int count1 = 1; // Slot 1 circle radius animation
int count2 = 1; // Slot 2 circle radius animation
float tempSpeedY1;
float tempSpeedY2;
boolean stopY1;
boolean stopY2;
int barCounter = 1;
int loopCount = 0;
int endGameCount = 0; // Count to move circle upwards
double limit;
float endRadiusSpeed;
int endSlot; // Where you died
int endRadiusCount = 0; // Count to increase circle radius
int barEndCounter = 1;
final Handler handler = new Handler();
boolean exception;
public static int endColor;
public Circle(GameView gameView, ArrayList<Bitmap> bitmaps, ArrayList<Bitmap> circles, int p1, int p2, int color, Context context) {
this.gameView = gameView;
this.bitmaps = bitmaps;
this.circles = circles;
this.p1 = p1;
this.p2 = p2;
this.color = color;
this.context = context;
width = GameActivity.SCREEN_WIDTH / 4 - 10;
x = 10;
y1 = 0;
y2 = -(GameActivity.SCREEN_HEIGHT + width) / 2;
centerX1 = x + p1 * (10 + width) + width / 2;
centerY1 = y1 + width / 2;
centerX2 = x + p2 * (10 + width) + width / 2;
centerY2 = y2 + width / 2;
}
public void update() throws GameOverException {
y1+= speedY1;
y2+= speedY2;
centerY1+= speedY1;
centerY2+= speedY2;
float ratio = (float)GameActivity.SCREEN_HEIGHT/1280;
limit = width/(20*ratio);
if(y1 >= gameView.getHeight()) {
loopCount++;
if(touchedFirst)
touchedFirst = false;
else {
speedY1 = speedY2 = -(12.5f * ratio);
endColor = bitmaps.get(p1).getPixel(width/2, width/2);
endGameCount += 1;
endSlot = 1;
}
if(endGameCount == 0) {
if (stopY1) {
tempSpeedY1 = speedY1;
speedY1 = 0;
ArrayList<Integer> numbers = new ArrayList<>();
for (int i = 0; i < 10; i++) {
if (i != color)
numbers.add(i);
}
tempColor = numbers.get(new Random().nextInt(9));
}
y1 = -(gameView.getWidth() / 4 - 10);
count1 = 1;
setBitmaps(1);
}
}
else if(y2 >= gameView.getHeight()) {
loopCount++;
if(touchedSecond)
touchedSecond = false;
else {
speedY1 = speedY2 = -(12.5f * ratio);
endColor = bitmaps.get(p2 + 4
).getPixel(width/2, width/2);
endGameCount += 1;
endSlot = 2;
}
if(endGameCount == 0) {
if (stopY2) {
tempSpeedY2 = speedY2;
speedY2 = 0;
}
y2 = -(gameView.getWidth() / 4 - 10);
count2 = 1;
setBitmaps(2);
}
}
}
public void setBitmaps(int slot) {
ArrayList<String> numbers = new ArrayList<>();
for(int i=0;i<10;i++)
numbers.add(i+"");
Random random = new Random();
int position = random.nextInt(4);
numbers.remove(color + "");
int r1 = Integer.valueOf(numbers.get(random.nextInt(9)));
numbers.remove(r1+"");
int r2 = Integer.valueOf(numbers.get(random.nextInt(8)));
numbers.remove(r2 + "");
int r3 = Integer.valueOf(numbers.get(random.nextInt(7)));
if(position == 0) {
bitmaps.set((slot - 1)*4, circles.get(color));
bitmaps.set((slot - 1)*4 + 1, circles.get(r1));
bitmaps.set((slot - 1)*4 + 2, circles.get(r2));
bitmaps.set((slot - 1)*4 + 3, circles.get(r3));
}
else if(position == 1) {
bitmaps.set((slot - 1)*4, circles.get(r1));
bitmaps.set((slot - 1)*4 + 1, circles.get(color));
bitmaps.set((slot - 1)*4 + 2, circles.get(r2));
bitmaps.set((slot - 1)*4 + 3, circles.get(r3));
}
else if(position == 2) {
bitmaps.set((slot - 1)*4, circles.get(r1));
bitmaps.set((slot - 1)*4 + 1, circles.get(r2));
bitmaps.set((slot - 1)*4 + 2, circles.get(color));
bitmaps.set((slot - 1)*4 + 3, circles.get(r3));
} else {
bitmaps.set((slot - 1)*4,circles.get(r1));
bitmaps.set((slot - 1)*4 + 1,circles.get(r2));
bitmaps.set((slot - 1)*4 + 2,circles.get(r3));
bitmaps.set((slot - 1)*4 + 3,circles.get(color));
}
if(slot == 1) {
p1 = position;
centerX1 = x+position*(10 + width) + width/2;
centerY1 = y1 + width/2;
}
else if(slot == 2) {
p2 = position;
centerX2 = x+position*(10 + width) + width/2;
centerY2 = y2 + width/2;
}
}
public void onTouch(float X, float Y) {
int radius = (gameView.getWidth() / 4 - 10) / 2;
if(endGameCount == 0) {
if ((X >= centerX1 - radius) && (X <= centerX1 + radius) && (Y >= centerY1 - radius) && (Y <= centerY1 + radius)) {
GameView.score++;
touchedFirst = true;
centerX1 = centerY1 = -1;
if(p1 == (timerCount - 1) && timer != null && starSlot == 1) {
GameView.stars++;
starCollected = true;
timerCount = 0;
stopTimerTask(0);
}
} else if ((X >= centerX2 - radius) && (X <= centerX2 + radius) && (Y >= centerY2 - radius) && (Y <= centerY2 + radius)) {
GameView.score++;
touchedSecond = true;
centerX2 = centerY2 = -1;
if(p2 == (timerCount - 1) && timer != null && starSlot == 2) {
GameView.stars++;
starCollected = true;
timerCount = 0;
stopTimerTask(0);
}
} else {
endSlot = 0;
if ((Y >= centerY1 - radius) && (Y <= centerY1 + radius)) {
endSlot = 1;
if (X >= 10 && X <= 10 + 2 * radius) {
p1 = 0;
centerX1 = 10 + radius;
} else if (X >= 20 + 2 * radius && X <= 20 + 4 * radius) {
p1 = 1;
centerX1 = 20 + 3 * radius;
} else if (X >= 30 + 4 * radius && X <= 30 + 6 * radius) {
p1 = 2;
centerX1 = 30 + 5 * radius;
} else if (X >= 40 + 6 * radius && X <= 40 + 8 * radius) {
p1 = 3;
centerX1 = 40 + 2 * radius;
} else
endSlot = 0;
} else if ((Y >= centerY2 - radius) && (Y <= centerY2 + radius)) {
endSlot = 2;
if (X >= 10 && X <= 10 + 2 * radius) {
p2 = 0;
centerX2 = 10 + radius;
} else if (X >= 20 + 2 * radius && X <= 20 + 4 * radius) {
p2 = 1;
centerX2 = 20 + 3 * radius;
} else if (X >= 30 + 4 * radius && X <= 30 + 6 * radius) {
p2 = 2;
centerX2 = 30 + 5 * radius;
} else if (X >= 40 + 6 * radius && X <= 40 + 8 * radius) {
p2 = 3;
centerX2 = 40 + 2 * radius;
} else
endSlot = 0;
}
if (endSlot != 0) {
speedY1 = speedY2 = 0;
limit = endGameCount = 6;
if (endSlot == 1) {
endColor= bitmaps.get(p1).getPixel(width/2, width/2);
} else {
endColor = bitmaps.get(p2 + 4).getPixel(width/2, width/2);
}
}
}
if (GameView.score % 5 == 0 && GameView.score <= 110 && barCounter == 1) {
float ratio = (float)GameActivity.SCREEN_HEIGHT/1280;
speedY1 += ratio*0.5;
speedY2 += ratio*0.5;
}
if (GameView.score > 0 && GameView.score % 15 == 14) {
if(isOddScore)
stopY1 = true;
else
stopY2 = true;
}
if (GameView.score > 0 && GameView.score % 15 == 0 && barCounter == 1) {
if(isOddScore)
stopY2 = true;
else
stopY1 = true;
}
if (GameView.score % 15 == 1)
barCounter = 1;
}
}
public void draw(Canvas canvas) throws GameOverException {
GameView.isGameOver = false;
if(exception)
throw new GameOverException(color);
update();
for(int i=0;i<bitmaps.size();i++) {
if(i<4) {
Rect rect = new Rect(x+i*(10 + width),y1,(x+width)*(i+1),y1+width);
if(endGameCount == Math.ceil(limit) && endSlot == 1) {
if(i == p1) {
endRadiusCount += 1;
if (endRadiusCount > 23) {
star.recycle();
loopCount = loopCount%starInterval;
Cryptography.saveFile((loopCount + "").getBytes(), context, "interval");
endGameCount = 0;
exception = true;
throw new GameOverException(color);
}
rect = new Rect(x + i * (10 + width) - endRadiusCount*(int)Math.ceil(endRadiusSpeed), y1 - endRadiusCount*(int)Math.ceil(endRadiusSpeed), (x + width) * (i + 1) + endRadiusCount*(int)Math.ceil(endRadiusSpeed), y1 + width + endRadiusCount*(int)Math.ceil(endRadiusSpeed));
canvas.drawBitmap(bitmaps.get(i), null, rect, null);
}
}
// TOUCH ANIMATION : DIMINISH CIRCLE
else if(i==p1 && touchedFirst) {
rect = new Rect(x + i * (10 + width) + 3*count1 + ((int)speedY1-15), y1 + 3*count1 + ((int)speedY1-15), (x + width) * (i + 1) - 3*count1 - ((int)speedY1-15), y1 + width - 3*count1 - ((int)speedY1-15));
canvas.drawBitmap(bitmaps.get(i), null, rect, null);
count1++;
}
else if(endSlot != 2) {
canvas.drawBitmap(bitmaps.get(i), null, rect, null);
if(timerCount > 0 && starSlot == 1) {
int size = width * 30 / 50;
int difference = (width - size) / 2;
Rect starRect = new Rect(x + (timerCount - 1) * (10 + width) + difference, y1 + difference, (x + width) * (timerCount) - difference, y1 + width - difference);
canvas.drawBitmap(star, null, starRect, null);
}
}
}
if(i >= 4) {
Rect rect = new Rect(x + (i % 4) * (10 + width), y2, (x + width) * ((i % 4) + 1), y2 + width);
if(endGameCount == Math.ceil(limit) && endSlot == 2) {
if((i%4)==p2) {
endRadiusCount += 1;
if (endRadiusCount > 23) {
star.recycle();
loopCount = loopCount%starInterval;
Cryptography.saveFile((loopCount + "").getBytes(), context, "interval");
endGameCount = 0;
exception = true;
throw new GameOverException(color);
}
rect = new Rect(x + (i % 4) * (10 + width) - endRadiusCount*(int)Math.ceil(endRadiusSpeed), y2 - endRadiusCount*(int)Math.ceil(endRadiusSpeed), (x + width) * ((i % 4) + 1) + endRadiusCount*(int)Math.ceil(endRadiusSpeed), y2 + width + endRadiusCount*(int)Math.ceil(endRadiusSpeed));
canvas.drawBitmap(bitmaps.get(i), null, rect, null);
}
}
else if((i%4)==p2 && touchedSecond) {
rect = new Rect(x + (i % 4) * (10 + width) + 3*count2 + ((int)speedY1-15), y2 + 3*count2 + ((int)speedY1-15), (x + width) * ((i % 4) + 1) - 3*count2 - ((int)speedY1-15), y2 + width - 3*count2 - ((int)speedY1-15));
canvas.drawBitmap(bitmaps.get(i), null, rect, null);
count2++;
}
else if(endSlot != 1) {
canvas.drawBitmap(bitmaps.get(i), null, rect, null);
if(timerCount > 0 && starSlot == 2) {
int size = width * 30 / 50;
int difference = (width - size) / 2;
Rect starRect = new Rect(x + (timerCount - 1) * (10 + width) + difference, y2 + difference, (x + width) * (timerCount) - difference, y2 + width - difference);
canvas.drawBitmap(star, null, starRect, null);
}
}
}
}
Rect src = new Rect(circles.get(color).getWidth()/2 - 10,circles.get(color).getHeight()/2 - 10,circles.get(color).getWidth()/2 + 10,circles.get(color).getHeight()/2 + 10);
Rect dst;
Paint paint = new Paint();
paint.setColor(Color.WHITE);
paint.setTextAlign(Paint.Align.RIGHT);
paint.setTypeface(Typeface.SANS_SERIF);
paint.setTextSize(72 * ratio);
canvas.drawText(GameView.score + " ", GameActivity.SCREEN_WIDTH, width / 2, paint);
dst = new Rect(5,5, (int) (120 * ratio - 5), (int) (120 * ratio - 5));
canvas.drawBitmap(star,null,dst,null);
paint.setTextAlign(Paint.Align.LEFT);
canvas.drawText("" + GameView.stars, 120 * ratio, width/2, paint);
}
}
Don't override draw(). That's used to render the View, not the Surface, and you generally shouldn't override that method even if you're creating a custom View:
When implementing a view, implement onDraw(android.graphics.Canvas) instead of overriding this method.
SurfaceViews have two parts, the Surface and the View. The View part is handled like any other View, but is generally just a transparent "hole" in the layout. The Surface is a separate layer that, by default, sits behind the View layer. Whatever you draw on the Surface "shows through" the transparent hole.
By overriding draw() you're drawing on the View whenever the View UI is invalidated. You're also calling draw() from the render thread, so you're drawing on the Surface, but with default Z-ordering you can't see that because the View contents are fully opaque. You will reduce your impact on the UI thread by not drawing everything in two different layers.
Unless you're deliberately drawing on the View, it's best to avoid subclassing SurfaceView entirely, and just use it as a member.
Because your draw code is synchronized, the two draw passes will not execute concurrently. That means your View layer draw call will block waiting for the Surface layer rendering to complete. Canvas rendering on a Surface is not hardware-accelerated, so if you're touching a lot of pixels it can get slow, and the UI thread will have to wait for it to run. That wouldn't be so bad, but you're holding on to the mutex while you're sleeping, which means the only opportunity for the main UI thread to run comes during the brief instant when the loop wraps around. The thread scheduler does not guarantee fairness, so it's entirely possible to starve the main UI thread this way.
If you change #override draw() to myDraw() things should get better. You should probably move your sleep call out of the synchronized block just on general principles, or work to eliminate it entirely. You might also want to consider using a custom View instead of SurfaceView.
On an unrelated note, you should probably avoid doing this every update:
Random random = new Random();
for the reasons noted here.
Successfully solved the issue. Can't imagine that the solution would be this much simple as compared to the problem that I was considering that complex. Just reduced the frame rate from 120 to 90 and guess what, it worked like charm!
Due to a high frame rate, the SurfaceView was busy doing all the drawing and onTouchEvent() method had to starve
I am trying to use the accelerometer to simply detect flipping the phone in 4 different angles from face down (left, right, right side up, upside down) and whether it is done fast or slow. I also want to stop checking after about 30 degrees of flipping the phone.
My problem is getting some stability. It will work once in a while and then not work.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
}
#Override
protected void onResume() {
super.onResume();
...
mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_UI);
}
#Override
public void onSensorChanged(SensorEvent event) {
preTS = TS;
preX = X;
preY = Y;
preZ = Z;
realX = event.values[0];
realY = event.values[1];
realZ = event.values[2];
X = Math.abs(event.values[0]);
Y = Math.abs(event.values[1]);
Z = Math.abs(event.values[2]);
TS = event.timestamp;
if (X < 2 && Y < 1) {
npsX = ((TS - preTS) * Math.abs(X - preX)) / 100000;
npsY = ((TS - preTS) * Math.abs(Y - preY)) / 100000;
npsZ = ((TS - preTS) * Math.abs(Z - preZ)) / 100000;
}
maxX = (maxX > npsX) ? maxX : npsX;
maxY = (maxY > npsY) ? maxY : npsY;
maxZ = (maxZ > npsZ) ? maxZ : npsZ;
if(X < 1 && Y < 1 && Z > 9) {
maxX = 0;
maxY = 0;
maxZ = 0;
dir = "";
speed = "";
}
if (Objects.equals(dir, "") || Objects.equals(speed, "")) {
if (realX >= 2) {
dir = "left";
} else if (realX <= -2) {
dir = "right";
} else if (realY >= 2) {
dir = "up";
} else if (realY <= -2) {
dir = "down";
}
if (maxX > 250 || maxY > 250 || maxZ > 250)
speed = "fast";
else
speed = "slow";
}
Log.i("MA", (int) maxX + " " + (int) maxY + " " + (int) maxZ + " " + X + " " + Y + " " +
Z + " " + speed + " " + dir + " " + realX + " " + realY + " " + realZ);
}