I'm new here. I'm trying to make a game with Android Studio and I've a problem: the Android Studio emulator load every Activity and the background loop of the game, my phone doesn't the background loop game.
This is my code.
BackGround Java class
package com.example.francesco.fraedogame;
import android.graphics.Bitmap;
import android.graphics.Canvas;
public class Background {
private Bitmap image;
private int x, y, dx;
public Background(Bitmap res){
image = res;
}
public void update(){
x+=dx;
if(x<-GamePanel.WIDTH){
x = 0;
}
}
public void draw(Canvas canvas){
canvas.drawBitmap(image, x, y, null);
if(x < 0){
canvas.drawBitmap(image, x+GamePanel.WIDTH, y, null);
}
}
public void setVector(int dx){
this.dx = dx;
}
}
MainThread Java class (for the loop game)
package com.example.francesco.fraedogame;
import android.graphics.Canvas;
import android.view.SurfaceHolder;
public class MainThread extends Thread {
private int FPS = 30;
private double averageFPS;
private SurfaceHolder surfaceHolder;
private GamePanel gamePanel;
private boolean running;
private static Canvas canvas;
public MainThread(SurfaceHolder surfaceHolder, GamePanel gamePanel){
super();
this.surfaceHolder = surfaceHolder;
this.gamePanel = gamePanel;
}
#Override
public void run(){
long startTime;
long timeMillis;
long waitTime;
long totalTime = 0;
int frameCount = 0;
long targetTime = 1000/FPS;
while(running){
startTime = System.nanoTime();
canvas = null;
//Lock Canvas
try{
canvas = this.surfaceHolder.lockCanvas();
synchronized (surfaceHolder){
this.gamePanel.update();
this.gamePanel.draw(canvas);
}
}
catch(Exception e){
}
finally {
if(canvas!=null){
try{
surfaceHolder.unlockCanvasAndPost(canvas);
}
catch(Exception e){
e.printStackTrace();
}
}
}
timeMillis = (System.nanoTime() - startTime)/1000000;
waitTime = targetTime - timeMillis;
try{
this.sleep(waitTime);
}
catch(Exception e){
}
totalTime += System.nanoTime() - startTime;
frameCount++;
if(frameCount == FPS){
averageFPS = 1000/((totalTime/frameCount)/1000000);
frameCount = 0;
totalTime = 0;
System.out.println(averageFPS);
}
}
}
public void setRunning(boolean b){
running = b;
}
}
The GamePanel Java class
package com.example.francesco.fraedogame;
import android.content.Context;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class GamePanel extends SurfaceView implements SurfaceHolder.Callback{
//Image Background dimension
public static final int WIDTH = 856;
public static final int HEIGHT = 480;
private MainThread thread;
private Background bg;
public GamePanel(Context context){
super(context);
//Add the callBack to the SurfaceHolder for intercept events
getHolder().addCallback(this);
thread = new MainThread(getHolder(), this);
//GamePanel focusable for handle events
setFocusable(true);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height){
}
#Override
public void surfaceDestroyed(SurfaceHolder holder){
//End the loop
boolean retry = true;
while(retry){
try{
thread.setRunning(false);
thread.join();
}
catch(InterruptedException e){
e.printStackTrace();
}
retry = false;
}
}
#Override
public void surfaceCreated(SurfaceHolder holder){
//Set the Background
bg = new Background(BitmapFactory.decodeResource(getResources(), R.drawable.background));
bg.setVector(-5);
//Start the loop
thread.setRunning(true);
thread.start();
}
#Override
//Handle touch screen motion events
public boolean onTouchEvent(MotionEvent event){
return super.onTouchEvent(event);
}
public void update(){
bg.update();
}
#Override
public void draw(Canvas canvas) {
final float scaleFactoryX = getWidth()/WIDTH;
final float scaleFactoryY = getHeight()/HEIGHT;
if (canvas != null) {
final int savedState= canvas.save();
canvas.scale(scaleFactoryX, scaleFactoryY);
bg.draw(canvas);
canvas.restoreToCount(savedState);
}
}
}
The manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.francesco.fraedogame">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".HomePage">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".SecondHome" />
<activity android:name=".game"
android:screenOrientation="landscape"/>
<activity android:name=".options" />
<activity android:name=".records"></activity>
</application>
</manifest>
Related
When I restart my App, I mean when I press the Homebutton and start it from the Task window, or when I debug it while it is still runnning the whole screen went black!
This is my MainView:
package net.kex.toll;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
public class MainView extends SurfaceView implements SurfaceHolder.Callback{
public GameLoop gameLoop;
public Player player;
private int playerX = 50;
private int playerY = 50;
public MainView(final Context context) {
super(context);
getHolder().addCallback(this);
player = new Player();
this.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
playerX = playerX + 20;
playerY = playerY + 20;
player.play();
return false;
}
}
);
setFocusable(true);
}
public void surfaceChanged(SurfaceHolder surfaceHolder, int foramt, int width, int height){
}
public void surfaceDestroyed(SurfaceHolder surfaceHolder){
boolean retry = true;
while (true) {
try {
gameLoop.setRunning(false);
gameLoop.join();
} catch (Exception e) { e.printStackTrace();}
retry = false;
}
}
public void surfaceCreated(SurfaceHolder surfaceHolder){
gameLoop = new GameLoop(getHolder(), this);
gameLoop.setRunning(true);
gameLoop.start();
}
public void update(){
player.update();
}
public void draw(Canvas canvas){
if(canvas == null) {
return;
}
canvas.drawColor(Color.WHITE);
player.draw(canvas);
}
}
This is my GameLoop:
package net.kex.toll;
import android.graphics.Canvas;
import android.util.Log;
import android.view.SurfaceHolder;
public class GameLoop extends Thread {
public static final int MAX_FPS = 30;
private double averageFPS;
private MainView mainView;
private SurfaceHolder surfaceHolder;
private boolean running;
public static Canvas canvas;
public void setRunning(boolean running) {
this.running = running;
}
public GameLoop(SurfaceHolder surfaceHolder, MainView mainView) {
super();
this.surfaceHolder = surfaceHolder;
this.mainView = mainView;
}
#Override
public void run(){
long startTime;
long timeMillis = 1000/MAX_FPS;
long waitTime;
long frameCount = 0;
long totalTime = 0;
long targetTime = 1000/MAX_FPS;
while (running) {
startTime = System.nanoTime();
canvas = null;
try {
canvas = this.surfaceHolder.lockCanvas();
synchronized (surfaceHolder) {
this.mainView.update();
this.mainView.draw(canvas);
}
}catch (Exception e){ e.printStackTrace();}
finally {
if (canvas != null) {
try {
surfaceHolder.unlockCanvasAndPost(canvas);
}catch (Exception e){ e.printStackTrace();}
}
}
timeMillis = (System.nanoTime() - startTime)/1000000;
waitTime = targetTime - timeMillis;
try {
if (waitTime >= 0){
this.sleep(waitTime);
}
}catch (Exception e){ e.printStackTrace();}
totalTime += System.nanoTime() - startTime;
frameCount++;
if (frameCount == MAX_FPS) {
averageFPS = 1000/((totalTime/frameCount)/1000000);
frameCount = 0;
totalTime = 0;
Log.i("GameLoop", "averageFPS: " + Double.toString(averageFPS));
}
}
}
}
I don't know what to do! If you want some other class please tell me and I will send it to you!
Please help I´m sitting here and trying to solve this problem for hours!
Repaint the object, it will render it again. For example in onResume add Repaint()
I'm following the Android Game Programming for Dummies by: Derek James. It looks outdated too me because in the book it doesn't include the fragment_main. So I just copied the fragment_main and replaced it in the activity_main and deleted the fragment_main (I followed the how to get rid of fragment_main tutorial on this forum).
I'm trying to make the whack a mole game in the book.
Anyways I get two errors when I followed the book and it said I can run the program now but I am unable to do that because of:
background cannot be resolved or is not a field
title cannot be resolved or is not a field
I have everything the same as the book but why do I get these errors, I checked all over Google to find an answer or something similar but I can't find the error, I would really appreciate if someone can help me out. Sorry for writing a whole paragraph but I should let you know what I did.
This is my WhackAMoleView.java
package com.whackamole;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class WhackAMoleView extends SurfaceView implements
SurfaceHolder.Callback {
private Context myContext;
private SurfaceHolder mySurfaceHolder;
private Bitmap backgroundImg;
private int screenW = 1;
private int screenH = 1;
private boolean running = false;
private boolean onTitle = true;
private WhackAMoleThread thread;
public WhackAMoleView(Context context, AttributeSet attrs) {
super(context, attrs);
SurfaceHolder holder = getHolder();
holder.addCallback(this);
thread = new WhackAMoleThread(holder, context, new Handler()
{
#Override
public void handleMessage(Message m) {
}
});
setFocusable(true);
}
public WhackAMoleThread getThread() {
return thread;
}
class WhackAMoleThread extends Thread {
public WhackAMoleThread(SurfaceHolder surfaceHolder, Context context,
Handler handler) {
mySurfaceHolder = surfaceHolder;
myContext = context;
backgroundImg = BitmapFactory.decodeResource(
context.getResources(), R.drawable.title);
}
#Override
public void run() {
while (running) {
Canvas c = null;
try {
c = mySurfaceHolder.lockCanvas(null);
synchronized (mySurfaceHolder) {
draw(c);
}
} finally {
if (c != null) {
mySurfaceHolderunlockCanvasAndPost(c);
}
}
}
}
private void mySurfaceHolderunlockCanvasAndPost(Canvas c) {
// TODO Auto-generated method stub
}
private void draw(Canvas canvas) {
try {
canvas.drawBitmap(backgroundImg, 0, 0, null);
} catch (Exception e) {
}
}
boolean doTouchEvent(MotionEvent event) {
synchronized (mySurfaceHolder) {
int eventaction = event.getAction();
int x = (int) event.getX();
int Y = (int) event.getY();
switch (eventaction) {
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
if (onTitle) {
backgroundImg = BitmapFactory
.decodeResource(myContext.getResources(),
R.drawable.background);
backgroundImg = Bitmap.createScaledBitmap(
backgroundImg, screenW, screenH, true);
onTitle = false;
}
break;
}
}
return true;
}
public void setSurfaceSize(int width, int height) {
synchronized (mySurfaceHolder) {
screenW = width;
screenH = height;
backgroundImg = Bitmap.createScaledBitmap(backgroundImg, width,
height, true);
}
}
public void setRunning(boolean b) {
running = b;
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
return thread.doTouchEvent(event);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
thread.setSurfaceSize(width, height);
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
thread.setRunning(true);
if (thread.getState() == Thread.State.NEW) {
thread.start();
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
thread.setRunning(false);
}
}
This is my MainActivity.java
package com.whackamole;
import android.app.Activity;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;
public class MainActivity extends Activity {
private WhackAMoleView myWhackAMoleView;
/**Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags
(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.whackamole_layout);
myWhackAMoleView = (WhackAMoleView)
findViewById(R.id.mole);
myWhackAMoleView.setKeepScreenOn(true);
}
}
This is my AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.whackamole"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="19" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name">
<activity
android:name="com.whackamole.MainActivity"
android:screenOrientation="landscape"
android:configChanges="keyboardHidden|orientation"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
mySurfaceHolderunlockCanvasAndPost(c);
}
}
}
}
mySurfaceHolderunlockCanvasAndPost should be mySurfaceHolder.unlockCanvasAndPost
*private void mySurfaceHolderunlockCanvasAndPost(Canvas c) {
// TODO Auto-generated method stub
}* should not be here
What is wrong with my coding clicking settings will crash app.
I cant read default settings values from prefs.xml
image sequence working like i want and now it's
moving right to left while images continue change (like a video)
someone genious see any problems ? :)
AndroidManifest.xml
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.mywallpaper"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="7" android:targetSdkVersion="12" />
<uses-feature android:name="android.software.live_wallpaper" />
<uses-permission android:name="android.permission.SET_WALLPAPER" />
<uses-permission android:name="android.permission.BIND_WALLPAPER" />
<application
android:label="#string/app_name"
android:icon="#drawable/ic_launcher"
android:theme="#style/AppTheme">
<service
android:label="#string/app_name"
android:name=".MyWallpaperService"
android:enabled="true"
android:permission="android.permission.BIND_WALLPAPER">
<intent-filter android:priority="1">
<action
android:name="android.service.wallpaper.WallpaperService">
</action>
</intent-filter>
<meta-data
android:name="android.service.wallpaper"
android:resource="#xml/wallpaper" >
</meta-data>
</service>
<activity
android:label="myPrefs"
android:name="com.example.mywallpaper.Prefs"
android:permission="android.permission.BIND_WALLPAPER"
android:enabled="true"
android:exported="true">
<intent-filter>
<category android:name="android.intent.category.PREFERENCE" />
</intent-filter>
</activity>
</application>
</manifest>
wallpaper.xml
<wallpaper
xmlns:android="http://schemas.android.com/apk/res/android"
android:name="something"
android:thumbnail="#drawable/ic_launcher"
android:description="#string/app_name"
android:settingsActivity="com.example.mywallpaper.Prefs">
</wallpaper>
prefs.xml
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
android:title="Title Preference"
android:key="myPrefs">
<CheckBoxPreference
android:title="Touch"
android:key="touch"
android:summary="Touch enable"
android:defaultValue="true"
/>
<EditTextPreference
android:title="Speed"
android:key="speed"
android:summary="Animation speed"
android:defaultValue="500"
/>
</PreferenceScreen>
Prefs.java
package com.example.mywallpaper;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceActivity;
public class Prefs extends PreferenceActivity
implements
SharedPreferences.OnSharedPreferenceChangeListener {
#SuppressWarnings("deprecation")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getPreferenceManager().setSharedPreferencesName(MyWallpaperService.SHARED_PREFS_NAME);
addPreferencesFromResource(R.xml.prefs);
getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
}
#Override
protected void onResume() {
super.onResume();
}
#SuppressWarnings("deprecation")
#Override
protected void onDestroy() {
getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
super.onDestroy();
}
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
String key) {
// TODO Auto-generated method stub
}
}
MyWallpaperService.java
package com.example.mywallpaper;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.Handler;
import android.service.wallpaper.WallpaperService;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
public class MyWallpaperService extends WallpaperService {
public static final String SHARED_PREFS_NAME = "myPrefs";
//drawable image array
int[] myImageList = new int[]{
R.drawable.bg,
R.drawable.bg1,
R.drawable.bg2,
R.drawable.bg3,
R.drawable.bg4,
R.drawable.bg5,
R.drawable.bg6,
R.drawable.bg7,
R.drawable.bg8,
R.drawable.bg9,
R.drawable.bg10,
R.drawable.bg11,
R.drawable.bg12,
R.drawable.bg13,
R.drawable.bg14,
R.drawable.bg15,
R.drawable.bg16
};
public boolean runUp = true;
public boolean touchEnabled = true;
public int mSpeed = 100;
public int bgNumber = 0;
public int bgFrame = 0;
public int bgFrameMax = 20;
#Override
public Engine onCreateEngine() {
return new WallpaperEngine();
}
private class WallpaperEngine extends Engine
implements SharedPreferences.OnSharedPreferenceChangeListener {
private SharedPreferences mPrefs;
private boolean mVisible = false;
private Bitmap backgroundImage;
private final Handler mHandler = new Handler();
private final Runnable mUpdateDisplay = new Runnable() {
public void run() {
draw();
}
};
private void draw() {
SurfaceHolder holder = getSurfaceHolder();
Canvas c = null;
try {
c = holder.lockCanvas();
if (c != null) {
//paint black
Paint p = new Paint();
p.setColor(Color.BLACK);
c.drawRect(0, 0, c.getWidth(), c.getHeight(), p);
drawBG(c);
}
} finally {
if (c != null)
holder.unlockCanvasAndPost(c);
}
mHandler.removeCallbacks(mUpdateDisplay);
if (mVisible) {
mHandler.postDelayed(mUpdateDisplay, mSpeed);
}
}
WallpaperEngine() {
mPrefs = MyWallpaperService.this.getSharedPreferences(SHARED_PREFS_NAME, 0);
mPrefs.registerOnSharedPreferenceChangeListener(this);
onSharedPreferenceChanged(mPrefs, null);
}
#Override
public void onTouchEvent(MotionEvent event) {
//super.onTouchEvent(event);
if(touchEnabled){
bgNumber = 0;
}
}
public void drawBG(Canvas c){
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPurgeable = true;
Resources res = getResources();
backgroundImage = BitmapFactory.decodeResource(res,myImageList[bgNumber], options);
//move looping imagas (video) right to left
int CH = c.getHeight();
int CW = c.getWidth();
double BH = backgroundImage.getHeight();
double BW = backgroundImage.getWidth();
double hScale = (BH/BW);
int bgSlideX = (CW/bgFrameMax);
int wallPH = (int) (CW*hScale);
int wLeft = 0+(CW-(bgSlideX*bgFrame));
int wTop = (int) ((CH/2)-(BH/2));
int wRight = CW+(CW-(bgSlideX*bgFrame));
int wBottom = wTop+wallPH;
Rect dest = new Rect(wLeft, wTop, wRight, wBottom);
Paint paint = new Paint();
paint.setFilterBitmap(true);
c.drawBitmap(backgroundImage, null, dest, paint);
bgFrame+=1;
if (bgFrame == bgFrameMax*2){
bgFrame = 0;
}
//Loop images up and down
if (runUp = true){
bgNumber += 1;
if (bgNumber == myImageList.length){
bgNumber=0;
runUp = false;
}
}
else if(runUp = false){
bgNumber -= 1;
if (bgNumber == 0){
bgNumber+=1;
runUp = true;
}
}
backgroundImage.recycle();
}
#Override
public void onVisibilityChanged(boolean visible) {
mVisible = visible;
if (visible) {
draw();
}
else {
mHandler.removeCallbacks(mUpdateDisplay);
}
}
#Override
public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
draw();
}
#Override
public void onSurfaceDestroyed(SurfaceHolder holder) {
super.onSurfaceDestroyed(holder);
mVisible = false;
mHandler.removeCallbacks(mUpdateDisplay);
}
#Override
public void onDestroy() {
super.onDestroy();
mVisible = false;
mHandler.removeCallbacks(mUpdateDisplay);
}
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
mSpeed = Integer.valueOf(sharedPreferences.getString("speed", "5000"));
//sharedPreferences.getInt("speed", 100);
touchEnabled = sharedPreferences.getBoolean("touch", true);
//mHandler.post(mUpdateDisplay);
}
}
public void onPause(){
super.onDestroy();
}
}
Based on the code you posted I can already see that you never closed the tag in your prefs.xml. That would cause a problem. You need to add a at the end of your prefs.xml to close it.
there is class, that draws on canvas some field
package com.cerbertek;
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.graphics.Region;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class PlayGameView extends SurfaceView implements SurfaceHolder.Callback {
private CanvasThread canvasthread;
private Context mContext;
private Region firstRec;
private class CanvasThread extends Thread {
private SurfaceHolder _holder;
private boolean _run = false;
public CanvasThread(SurfaceHolder surfaceHolder) {
_holder = surfaceHolder;
}
public void setRunning(boolean run) {
_run = run;
}
#Override
public void run() {
Canvas c;
while (_run) {
c = null;
try {
c = _holder.lockCanvas(null);
synchronized (_holder) {
onDraw(c);
}
} finally {
if (c != null) {
_holder.unlockCanvasAndPost(c);
}
}
}
}
}
public PlayGameView (Context context, AttributeSet attrs) {
super(context, attrs);
SurfaceHolder holder = getHolder();
holder.addCallback(this);
canvasthread = new CanvasThread(getHolder());
setFocusable(true);
}
#Override
public void onDraw(Canvas canvas) {
Paint paint = new Paint ();
Bitmap wrench = BitmapFactory.decodeResource(getResources(), R.drawable.wrench);
canvas.drawColor(Color .BLACK);
for(int i = 0; i < 4; i++) {
for(int j = 0; j < 4; j++) {
int left = canvas.getWidth()/2 - wrench.getWidth()*2 + j*wrench.getWidth();
int top = 0 + i*wrench.getHeight();
canvas.drawBitmap(wrench, left, top, null);
Log.d(i + " " + j, left+ " " + top);
}
}
}
#Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
}
#Override
public void surfaceCreated(SurfaceHolder arg0) {
canvasthread.setRunning(true);
canvasthread.start();
}
#Override
public void surfaceDestroyed(SurfaceHolder arg0) {
boolean retry = true;
canvasthread.setRunning(false);
while (retry) {
try {
canvasthread.join();
retry = false;
} catch (InterruptedException e) {
// we will try it again and again...
}
}
}
}
so i want to detect where i click on(for exemple there is 2 rects and i want to detect what rect i click on). i can set setOnClickListener to my view, but how to get position of click?
then i want to set the regions while drawing( it is right, yeah? or not?) and in activity i'll check is click coordinates contains regions
so
1) how can i get coord of click
2) what is the pretty good way to do do all that stuff, because my ideas are poor often
Look at the setOnTouchListener.
The OnTouchListener implements a method with the following signature:
public boolean onTouch(View v, MotionEvent event)
The MotionEvent has information about where the touch actually happened. (event.getX() and event.getY())
I am making an android game that needs to run a method continiously, kind of like a timer. I need that it is being called every second. How can i make this possible???
Java code:
import java.util.ArrayList;
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.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.TextView;
import android.widget.Toast;
public class ExampleView extends SurfaceView implements SurfaceHolder.Callback
{
class ExampleThread extends Thread
{
private ArrayList<Parachuter> parachuters;
private Bitmap parachuter;
private Paint black;
private boolean running;
private SurfaceHolder mSurfaceHolder;
private Context mContext;
private Handler mHandler;
private GameScreenActivity mActivity;
private long frameRate;
private boolean loading;
public ExampleThread(SurfaceHolder sHolder, Context context, Handler handler)
{
mSurfaceHolder = sHolder;
mHandler = handler;
mContext = context;
mActivity = (GameScreenActivity) context;
parachuters = new ArrayList<Parachuter>();
parachuter = BitmapFactory.decodeResource(getResources(), R.drawable.parachuteman);
black = new Paint();
black.setStyle(Paint.Style.FILL);
black.setColor(Color.WHITE);
running = true;
// This equates to 26 frames per second.
frameRate = (long) (1000 / 26);
loading = true;
}
#Override
public void run()
{
while (running)
{
Canvas c = null;
try
{
c = mSurfaceHolder.lockCanvas();
synchronized (mSurfaceHolder)
{
long start = System.currentTimeMillis();
doDraw(c);
long diff = System.currentTimeMillis() - start;
if (diff < frameRate)
Thread.sleep(frameRate - diff);
}
} catch (InterruptedException e)
{
}
finally
{
if (c != null)
{
mSurfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
protected void doDraw(Canvas canvas)
{
canvas.drawRect(0, 0, canvas.getWidth(), canvas.getHeight(), black);
//Draw
for (int i = 0; i < parachuters.size(); i++)
{
canvas.drawBitmap(parachuter, parachuters.get(i).getX(), parachuters.get(i).getY(), null);
parachuters.get(i).tick();
}
//Remove
for (int i = 0; i < parachuters.size(); i++)
{
if (parachuters.get(i).getY() > canvas.getHeight())
parachuters.remove(i);
}
}
public boolean onTouchEvent(MotionEvent event)
{
if (event.getAction() != MotionEvent.ACTION_DOWN)
return false;
float x = event.getX();
float y = event.getY();
Parachuter p = new Parachuter(x, y);
parachuters.add(p);
Toast.makeText(getContext(), "x=" + x + " y=" + y, 15).show();
return true;
}
public void setRunning(boolean bRun)
{
running = bRun;
}
public boolean getRunning()
{
return running;
}
}
/** Handle to the application context, used to e.g. fetch Drawables. */
private Context mContext;
/** Pointer to the text view to display "Paused.." etc. */
private TextView mStatusText;
/** The thread that actually draws the animation */
private ExampleThread eThread;
public ExampleView(Context context)
{
super(context);
// register our interest in hearing about changes to our surface
SurfaceHolder holder = getHolder();
holder.addCallback(this);
// create thread only; it's started in surfaceCreated()
eThread = new ExampleThread(holder, context, new Handler()
{
#Override
public void handleMessage(Message m)
{
// mStatusText.setVisibility(m.getData().getInt("viz"));
// mStatusText.setText(m.getData().getString("text"));
}
});
setFocusable(true);
}
#Override
public boolean onTouchEvent(MotionEvent event)
{
return eThread.onTouchEvent(event);
}
public ExampleThread getThread()
{
return eThread;
}
#Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3)
{
// TODO Auto-generated method stub
}
public void surfaceCreated(SurfaceHolder holder)
{
if (eThread.getState() == Thread.State.TERMINATED)
{
eThread = new ExampleThread(getHolder(), getContext(), getHandler());
eThread.start();
}
else
{
eThread.start();
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder)
{
boolean retry = true;
eThread.setRunning(false);
while (retry)
{
try
{
eThread.join();
retry = false;
}
catch (InterruptedException e)
{
}
}
}
}
I need to add a function or a socalled "method", a public void or something like that, that should be called every second and should do the exact same code as the MotionEvent event method, the onTouchEvent.
Following Rob's commented link, consider (which is not the accepted answer, though) reviewing this from the Android Developer's site, Resources section: http://developer.android.com/resources/articles/timed-ui-updates.html
It describes how to use the android os Handler class to implement a timer, rather than using the Timer and TimerTask classes themselves.
This pretty much what you are looking for.
How to run a Runnable thread in Android?
It does sth every 1000ms using a thread.