How can I change the picture that draws on the screen - android

This might seem like a silly qustion but how do you change the picture that draws on the screen.I have already been able to program a app were it draws a little icon where you touch the screen.So natually after I completed that I want to make it better by adding a option menu and the ability to change what icon you were being drown but when I ran the code the icon picture stayed the same.When I looked at it I found that when you click on any of the menu item it does do it's job and change the image id but when you go back to the main screen and try to create a new image it revertes back to the old image.I have no idea why it doesn't change because when I look at it everything make sense for it to change icon properly.If any one has any idea on what i am doing wrong or any suggestion on how to do this it would be greatly appreciate
Main
public class main extends Activity {
/** Called when the activity is first created. */
MenuItem item2;
int item3=R.drawable.ic_launcher;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FrameLayout sv = new FrameLayout(this);
LinearLayout ll = new LinearLayout(this);
Panel test = new Panel(this);
//ImageButton button = new ImageButton(this);
ll.setOrientation(LinearLayout.VERTICAL);
sv.addView(test);
//ll.addView(button);
sv.addView(ll);
setContentView(sv);
}
public boolean onCreateOptionsMenu(Menu menu) {
// TODO Auto-generated method stub
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// TODO Auto-generated method stub
Log.v("test", "item3 before is: "+item3);
item3=R.drawable.box;
Log.v("test", "item3 after is: "+item3);
return super.onOptionsItemSelected(item);
}
}
Panel
public class Panel extends SurfaceView implements SurfaceHolder.Callback {
private Bitmap image;
private ViewThread mThread;
private int x;
private int y;
private ArrayList<Element> mElements = new ArrayList<Element>();
public Panel(Context context) {
super(context );
image = BitmapFactory.decodeResource(getResources(),yantz.imageapp4.R.drawable.test);
getHolder().addCallback(this);
mThread = new ViewThread(this);
}
public void doDraw(Canvas canvas) {
canvas.drawColor(Color.CYAN);
canvas.drawBitmap(image, x, y, null);
synchronized (mElements){
for(Element element : mElements){
element.doDraw(canvas);
}
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
Log.v("test", "you have touched the sreen: ");
synchronized (mElements){
mElements.add(new Element(getResources(),(int) event.getX(),(int) event.getY()));
}
return super.onTouchEvent(event);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// TODO Auto-generated method stub
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
if (!mThread.isAlive()) {
mThread = new ViewThread(this);
mThread.setRunning(true);
mThread.start();
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
if (mThread.isAlive()) {
mThread.setRunning(false);
}
}
}
Elements
public class Element extends main{
private int mX;
private int mY;
int location ;
private Bitmap mBitmap;
public Element(Resources res, int x, int y) {
Log.v("element", "item3 before location is: "+item3);
location =item3;
mBitmap = BitmapFactory.decodeResource(res, location);
mX = x - mBitmap.getWidth() / 2;
mY = y - mBitmap.getHeight() / 2;
Log.v("element", "item3 before location is: "+item3);
}
public void doDraw(Canvas canvas) {
canvas.drawBitmap(mBitmap, mX, mY, null);
}
public void setlocation(int location2){
location=location2;
}
}
ViewThread
public class ViewThread extends Thread {
private Panel mPanel;
private SurfaceHolder mHolder;
private boolean mRun = false;
public ViewThread(Panel panel) {
mPanel = panel;
mHolder = mPanel.getHolder();
}
public void setRunning(boolean run) {
mRun = run;
}
#Override
public void run() {
Canvas canvas = null;
while (mRun) {
canvas = mHolder.lockCanvas();
if (canvas != null) {
mPanel.doDraw(canvas);
mHolder.unlockCanvasAndPost(canvas);
}
}
}
}

you can use
#Override
protected void onResume() {
super.onResume();
id="what ever you want";
//and set it to imagevIew;
}
if i have understood the uestion correctly,this happens because your activity pauses when it is not focused and resumes with default values.

Related

android: collision of two bitmaps

good day... im a new programmer in android... and actually its my first time doing so...
but i have basic knowledge about java...
so here goes.. my game will have an icon that can be controlled by a joystick... and another icon that goes up and down the screen(non controllable) i want the speed to increase a little..... i have started the code but dont know where and how to start the collision.. another one is that the icon that is controllabe always passes the screen and pop out the opposite direction...
public class GameSurface1 extends SurfaceView implements SurfaceHolder.Callback {
private Context _context;
private GameThread1 _thread;
private GameControl _controls;
private GameJoystick1 _joystick;
private int y = 0;
private int xSpeed = 1;
private Bitmap _pointer, bmp;
public GameSurface1(Context context) {
super(context);
// TODO Auto-generated constructor stub
_context = context;
init();
}
private void init(){
//initialize our screen holder
SurfaceHolder holder = getHolder();
holder.addCallback( this);
//initialize our game engine
//initialize our Thread class. A call will be made to start it later
_thread = new GameThread1(holder, _context, new Handler(),this);
setFocusable(true);
_joystick = new GameJoystick1(getContext().getResources());
_pointer = (Bitmap)BitmapFactory.decodeResource(getResources(), R.drawable.icon1);
bmp = (Bitmap)BitmapFactory.decodeResource(getResources(), R.drawable.bad1);
//contols
_controls = new GameControl();
setOnTouchListener(_controls);
}
public void doDraw(Canvas canvas){
if (y == getHeight() - bmp.getHeight()) {
xSpeed = -1;
}
if (y == 0) {
xSpeed = 1;
}
y = y + xSpeed;
//update the pointer
_controls.update(null);
//draw the pointer
canvas.drawBitmap(_pointer, _controls._pointerPosition.x, _controls._pointerPosition.y, null);
//draw the joystick background
canvas.drawBitmap(_joystick.get_joystickBg(), 15,215, null);
//draw the dragable joystick
canvas.drawBitmap(_joystick.get_joystick(),_controls._touchingPoint.x - 26, _controls._touchingPoint.y - 26, null);
canvas.drawBitmap(bmp, 280, y, null);
}
//these methods are overridden from the SurfaceView super class. They are automatically called
//when a SurfaceView is created, resumed or suspended.
#Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {}
private boolean retry;
#Override
public void surfaceDestroyed(SurfaceHolder arg0) {
retry = true;
//code to end gameloop
_thread.state = GameThread1.STOPED;
while (retry) {
try {
//code to kill Thread
_thread.join();
retry = false;
} catch (InterruptedException e) {
}
}
}
#Override
public void surfaceCreated(SurfaceHolder arg0) {
if(_thread.state==GameThread1.PAUSED){
//When game is opened again in the Android OS
_thread = new GameThread1(getHolder(), _context, new Handler(),this);
_thread.start();
}else{
//creating the game Thread for the first time
_thread.start();
}
}
ill appreciate all the help you can give...
thank you

How can I bring to front an object in SurfaceView

Is there any way to get objects to foregorund in surfaceView.
for example:
canvas.drawBitmap(...);
canvas.drawText(...);
If I do that text appeared on bitmap. How can I reverse it without redrawing
Sorry for my English.
Canvas just encapsulates bitmap object and bitmap only saves colour of pixel at some position, it doesn't save separate layers. It's like to draw in MSPaint. So you can't change the Z-order of your primitives on canvas. However, why don't you just change the order of commands?
There is no method to bring elements front and back. You are trying to alter the Z-order of the elements here and this is not possible or there is no direct method in Android. All you can do is arrange them in the layout and enable and disable views so that it will give you the same effect.
You can use addView() or setVisibility(View.Visible) to bring bring elements back and front.
Please try to use bellow code.
//SurfaceView class
public class MainGamePanel extends SurfaceView implements
SurfaceHolder.Callback {
MainThread thread;
public MainGamePanel(Context context) {
super(context);
// TODO Auto-generated constructor stub
getHolder().addCallback(this);
setFocusable(true);
thread = new MainThread(getHolder(), this);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
Log.e("N", "Changed");
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
Log.e("N", "Created");
thread.setRunning(true);
thread.start();
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
Log.e("N", "Destroyed");
boolean retry = true;
while (retry) {
try {
thread.join();
retry = false;
} catch (InterruptedException e) {
// try again shutting down the thread
}
}
}
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (event.getY() > getHeight() - 50) {
thread.setRunning(false);
((Activity) getContext()).finish();
} else {
Log.d("N", "Coords: x=" + event.getX() + ",y=" + event.getY());
}
}
return super.onTouchEvent(event);
}
}
//MainThread class
public class MainThread extends Thread {
// flag to hold game state
private boolean running;
private SurfaceHolder surfaceHolder;
private MainGamePanel gamePanel;
public void setRunning(boolean running) {
this.running = running;
}
public MainThread(SurfaceHolder surfaceHolder, MainGamePanel gamePanel) {
super();
this.surfaceHolder = surfaceHolder;
this.gamePanel = gamePanel;
}
#Override
public void run() {
long tickCount = 0L;
Log.d("N", "Starting game loop");
while (running) {
tickCount++;
// update game state
// render state to the screen
}
Log.d("N", "Game loop executed " + tickCount + " times");
}
}
//Main Activity
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new MainGamePanel(this));
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}

Refreshing canvas?

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!

Modify and open options menu inside a SurfaceView

So im writing my first small game for Android, using a SurfaceView called Panel, which is a seperate class and not a subclass of the GameActivity. When the game ends, I'd like to modify the options menu depending on wether the player won or lost, and then open it.
Any suggestions on how to do that?
GameActivity:
public class GameActivity extends Activity {
private static final int MENU_PAUSE = 1;
private static final int MENU_RESUME = 2;
private static final int MENU_RESTART = 3;
private static final int MENU_QUIT = 4;
private Panel _panel;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
_panel = new Panel(this, 01);
setContentView(_panel);
}
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add(0, MENU_PAUSE, 0, "Pause");
menu.add(0, MENU_RESUME, 0, "Resume");
menu.add(0, MENU_RESTART, 0, "Restart");
menu.add(0, MENU_QUIT, 0, "Quit");
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case MENU_PAUSE:
_panel.pause();
return true;
case MENU_RESUME:
_panel.resume();
return true;
case MENU_RESTART:
_panel = new Panel(this, 01);
setContentView(_panel);
case MENU_QUIT:
_panel.stop();
return true;
}
return false;
}
public void openMenu(){
openOptionsMenu();
}}
Panel (shortend):
class Panel extends SurfaceView implements SurfaceHolder.Callback, SensorEventListener {
// Game Vars
public Panel(Context context, int level) {
super(context);
_holder = getHolder();
_holder.addCallback(this);
_thread = new GameThread(getHolder(), this);
_handler = new Handler();
_context = context;
setFocusable(true);
start();
}
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
public void surfaceCreated(SurfaceHolder holder) {
_thread.setRunning(true);
_thread.start();
}
public void surfaceDestroyed(SurfaceHolder holder) {
// simply copied from sample application LunarLander:
// we have to tell thread to shut down & wait for it to finish, or else
// it might touch the Surface after we return and explode
boolean retry = true;
_thread.setRunning(false);
while (retry) {
try {
_thread.join();
retry = false;
} catch (InterruptedException e) {
// we will try it again and again...
}
}
}
private void win(){
}
private void lose(){
}
}

Android animation acting strange with .sleep() onTouchEvent

I currently have (among others) these classes:
public class Main extends Activity {
Panel p;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
p = new Panel(this);
setContentView(p);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
p.onTouchEvent(event);
// Make your UI thread sleep.
try {
Thread.sleep(30);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return true;
}
and
public class Panel extends SurfaceView implements SurfaceHolder.Callback {
private ViewThread mThread;
private ArrayList<GraphicsElement> mElements = new ArrayList<GraphicsElement>();
public static int panelHeight;
public static int panelWidth;
private int numberOfElements = 0;
private Paint mPaint;
public Panel(Context context) {
super(context);
getHolder().addCallback(this);
mThread = new ViewThread(this);
mPaint = new Paint();
mPaint.setColor(Color.CYAN);
mPaint.setTextSize(20);
}
public void doDraw(long elapsed, Canvas canvas) {
canvas.drawColor(Color.parseColor("#003045"));
if (!(mElements.size() > 15)) {
synchronized (mElements) {
for (GraphicsElement element : mElements) {
element.doDraw(canvas);
}
canvas.drawText("FPS: " + Math.round(1000f / elapsed) + " Elements: " + numberOfElements, 10, 30, mPaint);
}
} else {
mElements.clear();
numberOfElements = 0;
}
}
public void animate(long elapsedTime) {
synchronized (mElements) {
for (GraphicsElement element : mElements) {
element.animate(elapsedTime);
}
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
int xspeed = 0;
int yspeed = 0;
if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_MOVE) {
if (event.getX() > panelWidth / 2) {
xspeed = 5;
} else if (event.getX() < panelWidth / 2) {
xspeed = -5;
}
synchronized (mElements) {
for (GraphicsElement element : mElements) {
element.changeSpeed(xspeed, yspeed);
}
}
}
return true;
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
#Override
public void surfaceCreated(SurfaceHolder holder) {
if (!mThread.isAlive()) {
mThread = new ViewThread(this);
mThread.setRunning(true);
mThread.start();
}
mElements.add(new GraphicsElement(getResources(), 80, 300));
numberOfElements += 1;
}
public void surfaceDestroyed(SurfaceHolder holder) {
I also have ViewThread, just my animation thread, and GraphicsElement, which defines the moving object. My animation is going very slow(on touch), and I think it has something to do with my .sleep() method. Could anyone please help me ?
Edit: I'm using .sleep() because I don't want to flood TouchEvents.
i'm trying to get it like: Check for TouchEvent, Sleep, Check for TouchEvent, Sleep.. etc...
I've had the same issues with touch slowing things down and ended up with a similar approach to yours (sleeping the UI thread on touch events, as recommended by a Google game developer). The thing that seemed to help me was playing with the length of the sleep time. Try increasing it to 70 ms or even more and see if that helps. Most apps don't need a super high sample rate for touch input.
Firstly, you should initialize your Panel inside your onCreate() method.
Panel p = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
p = new Panel(this);
setContentView(p);
}
Secondly, I do not understand why you are doing a sleep in your onTouchEvent() handler. Try taking that out, and things should speed up, especially if you think that may be the cause!

Categories

Resources