I have program where i use my SurfaceView class. But i want to add ad in my game.To do it i must add xml and use it (i never use xml file and know few about it). Help me pls whith it.
Main Activity on create:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ThisActivity=this;
new Game(this);
setContentView(Game.game);
}
Game:
public class S_Game extends SurfaceView implements CallBack{
public S_Game(Context context){
super(context);
getHolder().addCallback(this);
game=this;
sinh0=false;
sinh1=false;
sinh2=true;
String abas=" "+"";
spacekey=abas.hashCode();
paint=new Paint();
paint.setColor(0xffff0000);
paint.setTextSize(20);
pickx=new AtomicInteger[3];
picky=new AtomicInteger[3];
ifpick0=new AtomicBoolean[3];
for(int i=0;i<3;i++){
pickx[i]=new AtomicInteger();
picky[i]=new AtomicInteger();
ifpick0[i]=new AtomicBoolean();
}
pickt=new AtomicInteger();
NewTimer();
}
public void NewTimer(){
upd=new S_Updater(this);
timer=new Timer();
timer.schedule(upd,250,40);
}
public void Init(){
if(getHeight()>getWidth()){
S_Graff.thisindgraff=0;
}else{
S_Graff.thisindgraff=1;
}
DisplayMetrics metrics = new DisplayMetrics();
MainActivity.ThisActivity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
xdpi=SK(metrics.xdpi);
ydpi=SK(metrics.ydpi);
xdpi=SK(metrics.densityDpi);
float sm=xdpi/3;
float sms=(55/sm);
dpi=sms;
wind=new S_Window(0,0,760,1430);
Board.psize=KonK(18);
Board.DY/=sms;
if(dpi<=0.55){
dpi=0.55f;
}
String s="|";
Board.LINE=s.hashCode();
}
public void Update(Canvas cnv){
if(getHeight()>getWidth()){
maxx=smaxx;
maxy=smaxy;
kx=maxx/getWidth();
ky=maxy/getHeight();
kk=kx;
S_Graff.thisindgraff=0;
debug0=""+maxy+"/"+getHeight();
debug1=""+maxx+"/"+getWidth();
}else{
maxx=smaxy;
maxy=smaxx;
kx=maxx/getWidth();
ky=maxy/getHeight();
kk=ky;
S_Graff.thisindgraff=1;
}
if(binit){LInit();binit=false;}
for(int i=0;i<3;i++){
if(!ifpick0[i].get()){
float px=pickx[i].get();
px/=1000;
float py=picky[i].get();
py/=1000;
ifpick0[i].set(true);
S_Window.Pick(px,py,i);
}
}
S_Graff.OnRotAll();
cnv.drawColor(0xffffffff);
//I draw all S_Graffs in Update
S_Graff.Update(cnv);
Board.UpdateText(cnv);
}
#Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {}
#Override
public void surfaceCreated(SurfaceHolder holder) {
//new Timer().schedule(upd,250,40);
/*Canvas c = getHolder().lockCanvas();
Update(c);
getHolder().unlockCanvasAndPost(c);*/
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
}
S_Updater:
public class S_Updater extends TimerTask{
public S_Game game;
public SurfaceHolder surfaceHolder;
static boolean isrun=true,ispause;
public S_Updater(S_Game g) {
game=g;
surfaceHolder=g.getHolder();
}
#Override
public void run() {
Canvas canvas=null;
try {
synchronized (surfaceHolder) {
if(surfaceHolder.getSurface().isValid()){
canvas=surfaceHolder.lockCanvas(null);
if(canvas!=null){
game.Update(canvas);
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
}
finally {}
}
}
Related
In my android app i have activity containing a surfaceview. I want to start the surfaceview thread when the surfaceview/activity is visible to user. I have tried starting the thread in OnSurfaceCreated. That works but on some mobiles(samsung) The activity takes many seconds to become visible.The screen turns black when i resume activity. So i googled and found that when a view becomes visible onFocusChanged is called. I tried implementing OnFocusChanged in surfaceview but it is never called. below is my surfaceview class.
public class ImageSurface extends SurfaceView implements SurfaceHolder.Callback {
private DrawThread drawThread;
private SurfaceHolder sHolder;
private ImageHolder imageHolder;
Bitmap mybit;
Bitmap orgiBitmap;// ;)
int message;
Context context;
private String valMagField;
public ImageSurface(Context context, AttributeSet attrs) {
super(context, attrs);
this.context=context;
SurfaceHolder holder = getHolder();
holder.addCallback(this);
setFocusable(true);
clearFocus();
drawThread = new DrawThread(context);
}
public void setImageHolder(ImageHolder imageHolder){
this.imageHolder = imageHolder;
}
public void setBitmap(String filePath){
}
public void resume(){
drawThread.resumeThread();
}
#Override
public void onFocusChanged(boolean focus,int direction,Rect rect){
super.onFocusChanged(focus, direction, rect);
Log.d("in focus changed","onfocuschanged"+System.currentTimeMillis());
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
drawThread.setSurfaceSize(width, height);
resume();
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
long startTime, stopTime;
startTime = System.currentTimeMillis();
sHolder = holder;
drawThread.setRunning(true);
if(drawThread.getState()==Thread.State.NEW){
drawThread.start();
}
if(drawThread.getState()==Thread.State.TERMINATED){
drawThread = new DrawThread(context);
drawThread.setRunning(true);
drawThread.start();
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
drawThread.pauseThread();
}
class DrawThread extends Thread{
int value=0;
private Boolean drun;
int valSize =30;
Context context;
private int sHeight , sWidth;
int lastmessage;
boolean threadPaused= false;
public DrawThread(Context context){
drun = false;
this.context = context;
}
public void pauseThread(){
synchronized(this){
threadPaused = true;
this.notify();
}
}
public void resumeThread(){
synchronized(this){
threadPaused = false;
this.notify();
}
}
public void setRunning(Boolean run){
drun = run;
}
public boolean isRunning(){
return drun;
}
public void setSurfaceSize(int width , int height){
sWidth = width;
sHeight = height;
}
#Override
public void run(){
while(drun){
Canvas c = null;
//Log.d("yes","thread is running");
try{
synchronized(this){
if(threadPaused)
try {
this.wait();
} catch (InterruptedException e) {
Log.d("in wait of surface view thread","error"+e.toString());
}
}
c = sHolder.lockCanvas(null);
synchronized(sHolder){
updateCanvas(c);
}
}finally {
if(c!=null){
sHolder.unlockCanvasAndPost(c);
}
}
}
}
private void updateCanvas(Canvas canvas){
try{
if(imageHolder.dispBit!= null){
int x=(sWidth-imageHolder.dispBit.getWidth())/2,y=(sHeight-imageHolder.dispBit.getHeight())/2;
imageHolder.applyEffects();
if(canvas!=null)
canvas.drawBitmap(imageHolder.dispBit, x,y,null);
}
else if(imageHolder!=null)
imageHolder.setDisplaySize(sWidth, sHeight);
}catch(Exception e){
e.printStackTrace();
}
}
}
}
I try to display one from list of bitmaps during onDraw.
When i'm passing list to the canvas all are display and stay in their places.
When I pass one random bitmaps it's redrawing canvas all the time.
All works when i'm using public void drawEnemy(Canvas canvas) but not exactly like I want when using public void drawEn(Canvas canvas).
I want to display one random bitmap, then after a few seconds, delete it and display other bitmap. I think the problem is how I implemented onDrow() method. It's redrawing canvas all the time.
Activity:
public class NewGameActivity extends Activity{
NewGame newgame;
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
// Landscape mode
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
// no title
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
// content Newgame.java
newgame = new NewGame(this);
setContentView(newgame);
}
Thread:
public class MainThread extends Thread{
private SurfaceHolder surfaceHolder;
private NewGame screen;
public MainThread(SurfaceHolder surfaceHolder, NewGame ekran) {
super();
this.surfaceHolder = surfaceHolder;
this.screen= screen;
}
private boolean running;
public void setRunning(boolean running) {
this.running = running;
}
#Override
public void run() {
Canvas canvas;
while (running) {
canvas = null;
try {
canvas = this.surfaceHolder.lockCanvas();
synchronized (surfaceHolder) {
this.screen.onDraw(canvas);
}
} finally {
if (canvas != null) {
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
}
}
SurfaceView:
public class NewGame extends SurfaceView implements SurfaceHolder.Callback{
private MainThread thread;
private EnemyManager manager;
public NewGame(Context context) {
super(context);
getHolder().addCallback(this);
thread = new MainThread(getHolder(), this);
manager = new EnemyManager();
// TODO Auto-generated constructor stub
//adding enemy
Enemy e1 = new Enemy(BitmapFactory.decodeResource(getResources(), R.drawable.card), 1);
Enemy e2 = new Enemy(BitmapFactory.decodeResource(getResources(), R.drawable.horse), 2);
EnemyLocation l1 = new EnemyLocation(60, 180);
EnemyLocation l2 = new EnemyLocation(60, 50);
manager.AddEnemy(e1, l1);
manager.AddEnemy(e2, l2);
setFocusable(true);
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.saloon), 0, 0, null);
manager.drawEn(canvas);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
thread.setRunning(true);
thread.start();
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
thread.setRunning(false);
thread.stop();
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
manager.handleActionDown((int)event.getX(), (int)event.getY());
}
return true;
}
}
EnemyManager:
public class EnemyManager {
private ArrayList<Enemy> enemyList;
private ArrayList<Enemy> suspects;
private Enemy cow;
private String message;
private int suspectID;
private Random rnd;
public String getMessage() {
return message;
}
public EnemyManager(){
enemyList = new ArrayList<Enemy>();
suspects = new ArrayList<Enemy>();
}
public void AddEnemy(Enemy enemy, EnemyLocation loc){
// set x,y enemy localization
enemy.setX(loc.getX());
enemy.setY(loc.getY());
enemyList.add(enemy);
}
public void clearEnemy() {
enemyList.clear();
}
// message if enemy touched
public void handleActionDown(int x, int y) {
for (Enemy enemy: enemyList) {
if (enemy.wasTouched(x, y)) {
message = enemy.getId();
return;
}
}
}
public void PrepareEnemy(){
suspectID = enemyList.get(rnd.nextInt(enemyList.size()+1)).getId();
suspects = new ArrayList<Enemy>();
suspects.add(getSuspectByID(suspectID));
}
private Enemy SingleEnemy(){
Double i = 1 + Math.random() * ((enemyList.size()-1)+1);
cow = getSuspectByID(i.intValue());
return cow;
}
private Enemy getSuspectByID(int suspectID) {
for (Enemy s: enemyList) {
if (s.getId() == suspectID) {
return s;
}
}
return null;
}
public void drawEn(Canvas canvas){
try {
Enemy k = SingleEnemy();
canvas.drawBitmap(cow.picture, cow.x, cow.y, null);
} catch (Exception e) {
// TODO: handle exception
}
}
// draw enemy
public void drawEnemy(Canvas canvas) {
try {
for (Enemy enemy: enemyList) {
canvas.drawBitmap(enemy.picture, enemy.x, enemy.y, null);
}
} catch (Exception e) {
// TODO: handle exception
}
}
}
das
As for as understand you are trying to do something like this (if it's not, please correct me):
This is rendering the canvas with all components:
Draw background
Draw enemy
To "refresh" the canvas you simply do something like this:
Draw background
Update
To pause the rendering you could do something like this:
int lastUpdateTime;
int delayTime = 2000; 2 seconds
if(System.currenttimeMillis() > lastUpdateTime + delayTime) {
// Finished waiting
}
You should only define lastUpdateTime when you want to wait and not in every iteration.
NB: Don't call Thread.sleep() in a rendering thread!
I want to add image to Surface view. So i used below code
public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback{
Bitmap myicon;
Canvas canvas;
private Paint mBitmapPaint;
Paint p= new Paint();
#Override
protected void onDraw(Canvas canvas) {
Bitmap myicon=BitmapFactory.decodeResource(getResources(),R.drawable.icon);
canvas.drawColor(Color.BLACK);
canvas.drawBitmap(myicon, 0,0, p);
// canvas.drawBitmap(myicon, 0,0, null);
// canvas.drawBitmap(myicon, 25,25, null);
}
public MySurfaceView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub
}
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
}
public void surfaceDestroyed(SurfaceHolder arg0) {
// TODO Auto-generated method stub
}
}
But it shows black screen. I didn't get what i did wrong in above code.
Please solve the problem
Thanks in advance.
Here is your solution Buddy, Also look at this link from where I got the solution
MainAct.java
public class MainAct extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mySurfaceView mySurfaceView = new mySurfaceView(getApplicationContext());
setContentView(mySurfaceView);
}
}
mySurfaceView.java
public class mySurfaceView extends SurfaceView implements
SurfaceHolder.Callback {
private TutorialThread _thread;
public mySurfaceView(Context context) {
super(context);
getHolder().addCallback(this);
_thread = new TutorialThread(getHolder(), this);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Bitmap _scratch = BitmapFactory.decodeResource(getResources(),
R.drawable.icon);
canvas.drawColor(Color.BLACK);
canvas.drawBitmap(_scratch, 10, 10, null);
}
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
}
public void surfaceCreated(SurfaceHolder arg0) {
_thread.setRunning(true);
_thread.start();
}
public void surfaceDestroyed(SurfaceHolder arg0) {
boolean retry = true;
_thread.setRunning(false);
while (retry) {
try {
_thread.join();
retry = false;
} catch (InterruptedException e) {
}
}
}
class TutorialThread extends Thread {
private SurfaceHolder _surfaceHolder;
private mySurfaceView _panel;
private boolean _run = false;
public TutorialThread(SurfaceHolder surfaceHolder, mySurfaceView panel) {
_surfaceHolder = surfaceHolder;
_panel = panel;
}
public void setRunning(boolean run) {
_run = run;
}
#Override
public void run() {
Canvas c;
while (_run) {
c = null;
try {
c = _surfaceHolder.lockCanvas(null);
synchronized (_surfaceHolder) {
_panel.onDraw(c);
}
} finally {
if (c != null) {
_surfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
}
}
EDIT :
droidnova website is not available anymore.I have found alternative website here which is having same source.
I hope it will be helpful !!
There are some changes to your class
package com.sample;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class MSurface extends SurfaceView implements SurfaceHolder.Callback {
public MSurface(Context context) {
super(context);
getHolder().addCallback(this);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Bitmap icon = BitmapFactory.decodeResource(getResources(),R.drawable.icon);
canvas.drawColor(Color.BLACK);
canvas.drawBitmap(icon, 10, 10, new Paint());
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// TODO Auto-generated method stub
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
Canvas canvas = null;
try {
canvas = holder.lockCanvas(null);
synchronized (holder) {
onDraw(canvas);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (canvas != null) {
holder.unlockCanvasAndPost(canvas);
}
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
}
}
But I am not sure you need SurfaceView, cause it used not to draw bitmap once, but to draw a lot of times after user interaction
If your view is not interactive, would be better if you extend View instead of SurfaceView
Cheers
I am have some bitmaps which i want to display serially one after another but my code displays only last bitmap.Can anybody tell me why is it happening?
here is the code
class Panel extends SurfaceView implements SurfaceHolder.Callback {
private boolean _run = false;
public Panel(Context context) {
super(context);
getHolder().addCallback(this);
_run = true;
}
#Override
public void onDraw(Canvas canvas) {
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
Log.i("Read","surfaceChanged is called");
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
Log.i("Read","surfaceCreated is called");
while (_run ) {
display();
}
}
public void display() {
Canvas c;
c = null;
try {
c = getHolder().lockCanvas(null);
synchronized (getHolder()) {
onPreviewFrame();
invalidate();
c.drawColor(Color.BLACK);
c.drawBitmap(bmp, 10, 10, null);
//panel.surfaceDestroyed(panel.getHolder());
}
} finally {
if (c != null) {
getHolder().unlockCanvasAndPost(c);
}
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
Log.i("Read","surfaceDestroyed is called");
_run = false;
}
}
I am not sure what your requirement is but if your are trying to create a continous horizontal image scroll. Take a look at this
https://github.com/blessenm/SlideshowDemo
Here is my main:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
LinearLayout layout = (LinearLayout) findViewById(R.id.mainView);
TextView text= (TextView) findViewById(R.id.text);
text.setText("This is a Test!");
firstCircle first = new firstCircle(this);
secondCircle second = new secondCircle(this);
layout.addView(first);
layout.addView(second);
}
Here is my firstCircleClass:
public class firstCircle extends SurfaceView implements SurfaceHolder.Callback {
private firstThread _firstThread;
private secondThread _secondThread;
private SurfaceHolder surfaceHolder;
public firstCircle (Context context, AttributeSet attrs){
super(context,attrs);
getHolder().addCallback(this);
setFocusable(true);
_firstThread= new firstThread(getHolder(),this);
}
public firstCircle (Context context){
super(context);
getHolder().addCallback(this);
setFocusable(true);
_firstThread= new firstThread(getHolder(),this);
}
#Override
public void onDraw(Canvas c){
String tag="My Activity";
Paint paint = new Paint();
paint.setColor(Color.BLUE);
c.drawCircle(100,100,100,paint);
}
#Override
public void surfaceCreated(SurfaceHolder holder){
_firstThread.setRunning(true);
_firstThread.start();
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height){
}
#Override
public void surfaceDestroyed(SurfaceHolder holder){
boolean retry = true;
_firstThread.setRunning(false);
while (retry){
try{
_firstThread.join();
retry = false;
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
}
I have a secondCircle class that is the exact same as above with the name changed and the color of the circle being Red.
Here is my firstThread class:
public class firstThread extends Thread {
private SurfaceHolder _surfaceHolder;
private firstClass _firstClass;
private boolean _run = false;
public firstThread (SurfaceHolder surfaceHolder, firstClass first){
_surfaceHolder = surfaceHolder;
_firstClass= first;
}
public void setRunning (boolean run){
_run = run;
}
#Override
public void run(){
while(_run){
Canvas c=null;
try{
c = _surfaceHolder.lockCanvas(null);
synchronized(_surfaceHolder){
_firstThread.onDraw(c);
}
} finally {
}
if (c!=null){
_surfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
I have a secondThread class that is the same as above with a different name and that calls secondCircle's onDraw().
When i run this program it only shows the blue circle and not the red circle. Why is this?
when you add the views, add them with layout parameters. Its possible the 1st view is filling the parent, leaving no space for the second view.
you could do something like
LinearLayout.LayoutParams p = new LinearLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
layout.addView(first,p);
layout.addView(second,p);