a small time based question > I want to get timer in activity I already tryed this code but it runs so fast I offen get " 0 " I want to program to run with no sleep . but to count from 0 to 60 sec
package com.okok;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.os.Handler;
import android.os.SystemClock;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.SurfaceHolder.Callback;
import android.widget.Chronometer;
class GameView extends SurfaceView {
//private Bitmap bmp;
// Chronometer mChronometer;
private SurfaceHolder holder;
private GameLoopThread gameLoopThread;
private List<Sprite> sprites = new ArrayList<Sprite>();
private long lastClick;
private Bitmap bmpBlood;
Handler m_handler;
Runnable m_handlerTask ;
private List<TempSprite> temps = new ArrayList<TempSprite>();
public GameView(Context context) {
super(context);
gameLoopThread = new GameLoopThread(this);
holder = getHolder();
holder.addCallback(new Callback() {
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
createSprites();
gameLoopThread.setRunning(true);
gameLoopThread.start();
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
}
});
bmpBlood = BitmapFactory.decodeResource(getResources(), R.drawable.blast2);
}
private void createSprites() {
sprites.add(createSprite(R.drawable.greenenact));
// sprites.add(createSprite(R.drawable.greenenact));
// sprites.add(createSprite(R.drawable.greenenact));
}
private Sprite createSprite(int resouce) {
Bitmap bmp = BitmapFactory.decodeResource(getResources(), resouce);
return new Sprite(this, bmp);
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.rgb(21, 181, 195));
for (int i = temps.size() - 1; i >= 0; i--) {
temps.get(i).onDraw(canvas);
}
final int count=0;
m_handler = new Handler();
m_handlerTask = new Runnable()
{
#Override
public void run() {
// do something
if(count=60)
{
m_handler.removeCallbacks(m_handlerTask);
}
count++;
m_handler.postDelayed(m_handlerTask, 5000);
for (Sprite sprite : sprites) {
sprite.onDraw(canvas);
}
}
};
m_handlerTask.run();
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if (System.currentTimeMillis() - lastClick > 500) {
lastClick = System.currentTimeMillis();
synchronized (getHolder()) {
float x = event.getX();
float y =event.getY();
for (int i = sprites.size() - 1; i >= 0; i--) {
Sprite sprite = sprites.get(i);
if (sprite.isCollition(x, y)) {
sprites.remove(sprite);
temps.add(new TempSprite(temps, this, x, y, bmpBlood));
break;
}
}
}
}
return true;
}
}
this is my program I have only one error
can not change count from int to a boolean error
I don't want to use sleep method because my application have sleep method that affect my animation
or give me a program that counts 0 to 60 sec and displays which runs without a sleep method
Use chronometer instead. Here is example ,
Example 2
Use a Handler
Handler m_handler;
Runnable m_handlerTask ;
int count=0;
m_handler = new Handler();
m_handlerTask = new Runnable()
{
#Override
public void run() {
// do something
if(count=60)
{
m_handler.removeCallbacks(m_handlerTask);
}
count++:
m_handler.postDelayed(m_handlerTask, 1000);
// repeat some task every 1 second
}
};
m_handlerTask.run();
Related
I am making this simple 2D canvas game using SurfaceView for android and am having this problem with my game loop: the fps immensely lowers as time goes on. I found the design for the game loop from this article: deWiTTERS Game Loop.
GamePanel.java
package jacobmahoney.guardianofearth;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Point;
import android.view.Display;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.WindowManager;
public class GamePanel extends SurfaceView implements SurfaceHolder.Callback {
private MainThread thread;
private SpaceshipObject spaceship;
private LeftCircle leftCircle;
private RightCircle rightCircle;
private int screenWidth;
private int screenHeight;
public GamePanel(Context context) {
super(context);
getHolder().addCallback(this);
thread = new MainThread(getHolder(), this);
setFocusable(true);
getScreenSize(context);
spaceship = new SpaceshipObject(screenWidth, screenHeight);
leftCircle = new LeftCircle(screenWidth, screenHeight);
rightCircle = new RightCircle(screenWidth, screenHeight);
}
public void getScreenSize(Context context) {
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
Point size = new Point();
display.getRealSize(size);
screenWidth = size.x;
screenHeight = size.y;
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
thread = new MainThread(getHolder(), this);
thread.setRunning(true);
thread.start();
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
while (retry) {
try {
thread.setRunning(false);
thread.join();
} catch(Exception e) {
e.printStackTrace();
}
retry = false;
}
}
public void update() {
rightCircle.update();
}
#Override
public void draw(Canvas canvas) {
super.draw(canvas);
canvas.drawColor(Color.BLUE);
spaceship.draw(canvas);
leftCircle.draw(canvas);
rightCircle.draw(canvas);
}
}
MainThread.java
package jacobmahoney.guardianofearth;
import android.graphics.Canvas;
import android.util.Log;
import android.view.SurfaceHolder;
public class MainThread extends Thread {
private SurfaceHolder surfaceHolder;
private GamePanel gamePanel;
private boolean running;
public static Canvas canvas;
public void setRunning(boolean running) {
this.running = running;
}
public MainThread(SurfaceHolder surfaceHolder, GamePanel gamePanel) {
super();
this.surfaceHolder = surfaceHolder;
this.gamePanel = gamePanel;
}
#Override
public void run() {
int TICKS_PER_SECOND = 50;
int SKIP_TICKS = 1000 / TICKS_PER_SECOND;
int MAX_FRAMESKIP = 10;
long next_game_tick = System.currentTimeMillis();
int loops;
long prev = System.currentTimeMillis();
while (running) {
Log.d("MainThread", "" + (System.currentTimeMillis() - prev)); // this value drastically increases over time
prev = System.currentTimeMillis();
loops = 0;
while (System.currentTimeMillis() > next_game_tick && loops < MAX_FRAMESKIP) {
this.gamePanel.update();
next_game_tick += SKIP_TICKS;
loops++;
}
canvas = this.surfaceHolder.lockCanvas();
this.gamePanel.draw(canvas);
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
Any help would be greatly appreciated, thanks!
EDIT:
After commenting out all the instances of the game objects: leftCircle, rightCircle, and spaceship completely from GamePanel.java, I didn't have the issue where the game gets increasingly laggy over time, which I guess is obvious. Then when I put just the spaceship game object back into the mix, the game still got increasingly laggy over time, but at a smaller rate than it was when I had all three game objects drawing to the canvas.
I am completely stumped, I have literally no idea what could be causing this... any ideas?
EDIT2:
removed
EDIT3:
Found out what the issue was. It was a problem with the code I was using to draw paths for each object. I forgot to place a path.reset() and path.close() before and after the code I used to draw the path. Also I removed my edit2 because I made a comment in the heat of my frustration, that was unwarranted.
I am trying do develop may first android game in 2d. I intend to build it from scratch without the use of an engine. I have manage to create the following thread:
import android.graphics.Canvas;
import android.view.SurfaceHolder;
public class MainThread extends Thread {
private int FPS = 30;
private double averageFPS;
private GamePanel gamePanel;
private SurfaceHolder surfaceHolder;
private boolean running;
public 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;
// how many milliseconds it take to run through the loop
long targetTime = 1000 / FPS;
while (running) {
startTime = System.nanoTime();
canvas = null;
// try to lock the canvas for pixel editing
try {
canvas = this.surfaceHolder.lockCanvas();
synchronized (surfaceHolder) {
// the main game loop
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 {
System.out.println(waitTime);
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);
}
}
}
The problem I have is that the averageFPS keeps dropping when adding stuff to my game. With only the background it works at 30 on my Nexus 5 but upon adding character and obstacles it drops to 22-21.
Is there anyway I can do to optimize this ?
Thank you
UPDATE: my GamePanel looks like this:
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.Rect;
import android.graphics.Typeface;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import java.util.ArrayList;
import java.util.Random;
public class GamePanel extends SurfaceView implements SurfaceHolder.Callback {
public static final int WIDTH = 1920;
public static final int HEIGHT = 1080;
public static float MOVESPEED = -12;
private Random rand = new Random();
private MainThread thread;
private Background bg;
private Treadmill tm;
private Player player;
private ArrayList<Box> boxes;
private int minDistance = 600;
private int score;
public GamePanel(Context context) {
super(context);
// add callback service to the holder to intercept events
getHolder().addCallback(this);
// make gamePanel focusable so it can handle events
setFocusable(true);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
while (retry) {
try {
thread.setRunning(false);
thread.join();
retry = false;
thread = null;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
// instantiate objects
thread = new MainThread(getHolder(), this);
bg = new Background(BitmapFactory.decodeResource(getResources(), R.drawable.background));
tm = new Treadmill(BitmapFactory.decodeResource(getResources(), R.drawable.ground));
player = new Player(BitmapFactory.decodeResource(getResources(), R.drawable.character));
boxes = new ArrayList<Box>();
//start game loop
thread.setRunning(true);
thread.start();
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (player.jump == false) {
player.setVelocity(-14f);
player.setJump(true);
}
return true;
}
return super.onTouchEvent(event);
}
public void update() {
bg.update();
tm.update();
player.update();
if (boxes.size() == 0) {
boxes.add(new Box(BitmapFactory.decodeResource(getResources(), R.drawable.box),
WIDTH));
} else if (boxes.get(boxes.size() - 1).getX() < WIDTH) {
if (WIDTH - boxes.get(boxes.size() - 1).getX() < minDistance) {
boxes.add(new Box(BitmapFactory.decodeResource(getResources(), R.drawable.box),
rand.nextInt(400 - 50) + WIDTH + minDistance));
}
}
for (int i = 0; i < boxes.size(); i++) {
if (boxes.get(i).getX() <= player.getX() && boxes.get(i).getX() >= player.getX() - 12) {
score++;
MOVESPEED -= 0.2;
System.out.println(MOVESPEED);
}
if (collision(boxes.get(i), player)) {
boxes.remove(i);
break;
}
if (boxes.get(i).getX() < -100) {
boxes.remove(i);
break;
}
}
for (int i = 0; i < boxes.size(); i++) {
boxes.get(i).update();
}
}
#Override
public void draw(Canvas canvas) {
final float scaleFactorX = getWidth() / (WIDTH * 1.f);
final float scaleFactorY = getHeight() / (HEIGHT * 1.f);
if (canvas != null) {
final int saveState = canvas.save();
canvas.scale(scaleFactorX, scaleFactorY);
// draw the background
bg.draw(canvas);
tm.draw(canvas);
player.draw(canvas);
for (Box bx : boxes) {
bx.draw(canvas);
}
drawText(canvas);
canvas.restoreToCount(saveState);
}
}
public boolean collision(GameObject a, GameObject b) {
if (Rect.intersects(a.getRectangle(), b.getRectangle())) {
return true;
}
return false;
}
public void drawText(Canvas canvas) {
Paint paint = new Paint();
paint.setColor(Color.BLACK);
paint.setTextSize(50);
paint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.BOLD));
canvas.drawText("Score: " + (score), 15, HEIGHT - 20, paint);
}
Thank you for all the help so far
The problem doesn't seem to be in the Main Thread Activity, you followed tutorial fine (Except for the line - System.out.println(waitTime); - but i don't think thats the problem cause.)
The problem is most likely in the GamePanel. ;)
Don't ever use Thread.sleep() in game loops. It is not guaranteed to sleep for the specified amount of time.
Anyway, I think that this is pretty much expected behaviour when using Canvas. If I were you I'd consider using OpenGL ES for anything like graphics rendering. Definitely, this makes it much more complex (even though Android has a lot of things already done for you). But the benefit is quite obvious - you get actual real-time graphics performance.
I was trying to draw some balloons on screeen using canvas in SurfaceView class, I was successfully able to draw Multiple balloons on canvas and animate them by swapping different images. The problem is When I try touching on Oneballoon I need to remove it from screen .Here I get this exception and I am stuck
Code:
MainActivity:
package com.pradhul.game.touchball;
import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new GameView(this));
/*TODO Hide the bottom navigation bar */
}
}
GameView.java
package com.pradhul.game.touchball;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class GameView extends SurfaceView implements SurfaceHolder.Callback, View.OnTouchListener {
private static final int NUM_OF_BALLOONS = 5; //TODO for more than one balloons animations dont work(?)
/*use SurfaceView because we want complete control over the screen.
* unlike extending View class the oDraw() Method will not be called automatically
* from the method onSurfaceCreated() we have to call it Manually and pass a canvas object into it
* */
private final SurfaceHolder holder;
private GameLoopThread gameLoopThread;
private List<Balloon> balloons = new ArrayList<>();
public GameView(Context context) {
super(context);
gameLoopThread = new GameLoopThread(this);
holder = getHolder();
holder.addCallback(this);
createBalloons(NUM_OF_BALLOONS);
this.setOnTouchListener(this);
}
private void createBalloons(int count) {
for(int i=0 ; i< count ;i++){
balloons.add(createBalloon());
}
}
#Override
protected void onDraw(Canvas canvas) {
if(canvas != null) {
canvas.drawColor(Color.WHITE);
for(Balloon balloon : balloons){
try {
gameLoopThread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
balloon.onDraw(canvas);
}
}
}
#SuppressLint("WrongCall")
#Override
public void surfaceCreated(SurfaceHolder holder) {
/*this is called when the view is created*/
gameLoopThread.setRunning(true);
gameLoopThread.start();
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
/*pausing game Thread*/
gameLoopThread.setRunning(false);
while (true){
try {
gameLoopThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private Balloon createBalloon(){
return new Balloon(this);
}
#Override
public synchronized boolean onTouch(View v, MotionEvent event) {
Log.d("OnTouch real -", "x: " + event.getX() + ", Y: " + event.getY());
/* for (int i = balloons.size()-1; i >= 0; i--) {
Balloon balloon = balloons.get(i);
Log.d("OnTouch collision -", !balloon.isCollision(event.getX(), event.getY())+"");
if (!balloon.isCollision(event.getX(), event.getY())) {
balloons.remove(0);
break;
}
}*/
Iterator<Balloon> balloonIterator = balloons.iterator();
while(balloonIterator.hasNext()){
Balloon balloon = balloonIterator.next();
balloons.remove(0);
}
return true;
}
}
GameLoopThread.java
package com.pradhul.game.touchball;
import android.annotation.SuppressLint;
import android.graphics.Canvas;
public class GameLoopThread extends Thread {
private GameView view;
private boolean running = false;
public GameLoopThread(GameView view){
this.view = view;
}
public void setRunning(boolean run){
running = run;
}
#SuppressLint("WrongCall")
public void run(){
while (running){
Canvas canvas = null;
try{
canvas = view.getHolder().lockCanvas();
synchronized (view.getHolder()){
view.onDraw(canvas);
}
}finally{
if(canvas != null) {
view.getHolder().unlockCanvasAndPost(canvas);
}
}
}
}
}
Balloon.java
package com.pradhul.game.touchball;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.util.Log;
import java.util.Random;
public class Balloon {
private static final int BALLOON_SPEED = 10;
private int y = 0;
private int x = 0;
private int speed = 1;
private GameView gameView;
private Bitmap balloon;
public Bitmap[] normalBalloons;
private int balloonIndex = 0;
private int normalImages[] = {R.drawable.normal_01,R.drawable.normal_02,R.drawable.normal_03,
R.drawable.normal_04,R.drawable.normal_05,R.drawable.normal_06,R.drawable.normal_07,
R.drawable.normal_08,
};
private int crackingImages[] = {R.drawable.crack_01,R.drawable.crack_02,R.drawable.crack_03,
R.drawable.crack_04, R.drawable.crack_05,R.drawable.crack_04,R.drawable.crack_03,
R.drawable.crack_02
};
private boolean reverseSwap = false;
public Balloon(GameView gameView){
this.gameView = gameView;
normalBalloons = new Bitmap[8];
setUpImages();
}
public void onDraw(Canvas canvas){
/*draws the balloon in canvas */
animateBalloon();
update(canvas.getWidth());
canvas.drawBitmap(balloon, x, y, null);
}
public boolean isCollision(float x2, float y2) {
return x2 > x && x2 < x + balloon.getWidth() && y2 > y && y2 < y + balloon.getHeight();
}
private int getRandomX(int maxVal) {
Random rand = new Random();
return rand.nextInt(maxVal);
}
private void animateBalloon() {
/*Animates the balloon by swapping resource image at each call*/
this.balloon = getBalloons();
Log.d("Balloon",balloonIndex % normalBalloons.length + "");
}
private void update(int canvasWidth) {
/*updates the y position for moving the balloon*/
if (y <= 0){
/*so that the balloon starts from bottom
* gameView will return a height only after the View is ready
* getting 0 in constructor of this class*/
y = gameView.getHeight();
/*x is assigned a random between the width od the canvas
* so that the balloons will appear random positions from below*/
x = getRandomX(canvasWidth - balloon.getWidth());
}
if (y > gameView.getHeight() - balloon.getHeight() - speed) {
speed = -BALLOON_SPEED;
}
y = y + speed;
Log.d("Balloon","Positions:"+x+","+y);
}
private Bitmap getBalloons() {
if(balloonIndex == normalBalloons.length-1) {
reverseSwap = true;
}
if(balloonIndex == 0){
reverseSwap = false;
}
balloonIndex = reverseSwap?balloonIndex-1:balloonIndex+1;
return normalBalloons[balloonIndex];
}
private void setUpImages() {
/*setting up resources array*/
for(int count =0; count < normalImages.length; count++){
Bitmap balloon = BitmapFactory.decodeResource(gameView.getResources(), normalImages[count]);
normalBalloons[count] = balloon;
}
}
}
I am confused that why it causes an error like this , Can anybody can take look at it and suggest me a solution, is this the right way to remove ?
please share any suggestion
Thanks
It's the wrong way to remove.
If you iterate over a Collection / List, and want to remove the current element, you must use Iterator.remove() method.
In your case, simply call balloonIterator.remove() instead of balloons.remove(0)
Even simpler, since you want to remove all elements from the list - you should simply call balloons.clear() and remove the loop completely.
This exception is due to concurrent modification of list balloons.
As soon as you touch surface view onDraw() gets invoked with onTouch(), in which you are working on list balloons.
I think you should add touch listener to balloon instead of GameView.
okay ,
I need to wrap all my code inside a synchronized holder inorder this to work
(don't know much about it)
#Override
public boolean onTouch(View v, MotionEvent event) {
Log.d("OnTouch","x:"+event.getX()+"Y:"+event.getY());
synchronized (getHolder()){
for (int i=0 ;i<balloons.size();i++){
balloons.remove(0);
break;
}
}
return true;
}
I am trying to update the position of a bitmap with an onTouch event. The image displays in the initial spot correctly. The logs show that the onTouch event is updating the coordinate and also show that onDraw is being called.
My Activity:
package com.miker.haminvaders;
import android.app.Activity;
import android.os.Bundle;
public class HamInvadersActivity extends Activity
{
private DrawView drawView;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
drawView = (DrawView) findViewById(R.id.drawView);
}
#Override
public void onPause()
{
super.onPause();
drawView.stopGame();
}
#Override
protected void onDestroy()
{
super.onDestroy();
drawView.releaseResources();
}
}
My Thread Class:
package com.miker.haminvaders;
import android.graphics.Canvas;
import android.util.Log;
import android.view.SurfaceHolder;
public class MainThread extends Thread
{
private boolean running;
SurfaceHolder surfaceHolder;
DrawView drawView;
public void setRunning(boolean r)
{
this.running = r;
}
#Override
public void run()
{
Canvas canvas = null;
while(running)
{
//Log.v("HAM", "tick!");
try
{
canvas = surfaceHolder.lockCanvas();
synchronized(surfaceHolder)
{
drawView.onDraw(canvas);
drawView.updatePositions();
}
}
finally
{
if(canvas != null)
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
public MainThread(SurfaceHolder surface, DrawView draw)
{
super();
surfaceHolder = surface;
drawView = draw;
}
}
My SurfaceView class:
package com.miker.haminvaders;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.graphics.BitmapFactory;
import android.util.Log;
public class DrawView extends SurfaceView implements SurfaceHolder.Callback
{
private MainThread myThread;
private int screenWidth;
private int screenHeight;
private Paint textPaint;
private Paint backPaint;
private float x, y;
private Bitmap bmpHam;
public DrawView(Context context, AttributeSet attrs)
{
super(context, attrs);
SurfaceHolder holder = getHolder();
holder.addCallback(this);
textPaint = new Paint();
backPaint = new Paint();
myThread = new MainThread(holder, this);
bmpHam = BitmapFactory.decodeResource(getResources(), R.drawable.lilhamstrich);
}
#Override
protected void onSizeChanged( int w, int h, int oldw, int oldh)
{
super.onSizeChanged(w, h, oldw, oldh);
screenWidth = w;
screenHeight = h;
textPaint.setTextSize(w/20);
backPaint.setColor(Color.WHITE);
newGame();
}
public void newGame()
{
x = screenWidth/2;
y = screenHeight/2;
}
public void updatePositions()
{
}
public void onDraw(Canvas canvas)
{
canvas.drawColor(Color.WHITE);
canvas.drawBitmap(bmpHam, x, y, null);
Log.v("HAM", "Draw! " + x + " " + y);
}
public void stopGame()
{
if(myThread != null)
myThread.setRunning(false);
}
public void releaseResources()
{
//soundPool stuff
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
{
}
#Override
public void surfaceCreated(SurfaceHolder holder)
{
myThread.setRunning(true);
myThread.start();
}
#Override
public void surfaceDestroyed(SurfaceHolder holder)
{
boolean retry = true;
myThread.setRunning(false);
while(retry)
{
try
{
myThread.join();
retry = false;
}
catch(InterruptedException e)
{
}
}
}
#Override
public boolean onTouchEvent (MotionEvent event)
{
int action = event.getAction();
if( action == MotionEvent.ACTION_DOWN)
{
x = event.getX();
y = event.getY();
Log.v("HAM","Down! " + x + " " + y);
}
return true;
}
}
Is there anything else that I need to include?
Call invalidate() in the onTouchEvent(), it should cause a redraw.
I am making an android game that should drag an image after my touch cordinates in onTouchEvent(MotionEvent event) method. So far i have managed to move it by clicking, but not by dragging, how can i do this? Please help me and thanks so much in advance! Check out my onTouchEvent(MotionEvent event) method in this code:
package com.mysoftwaremobileapps.TriangleUnlocker;
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.media.MediaPlayer;
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 GameScreenActivity extends SurfaceView implements SurfaceHolder.Callback
{
class ExampleThread extends Thread
{
private ArrayList<Triangle> triangles;
private Bitmap TriangleImage;
private Paint black;
private boolean running;
private SurfaceHolder mSurfaceHolder;
private Context mContext;
private Context mContext1;
private Handler mHandler;
private Handler mHandler1;
private TriangleUnlockerActivity mActivity;
private long frameRate;
private boolean loading;
public float x;
public float y;
public float x1;
public float y1;
public MediaPlayer mp1;
public int parachuterIndexToResetAndDelete;
public int canvasGetWidth;
public int livesLeftValue;
public ExampleThread(SurfaceHolder sHolder, Context context, Handler handler)
{
mSurfaceHolder = sHolder;
mHandler = handler;
mHandler1 = handler;
mContext = context;
mActivity = (TriangleUnlockerActivity) context;
triangles = new ArrayList<Triangle>();
TriangleImage = BitmapFactory.decodeResource(getResources(), R.drawable.triangle);
black = new Paint();
black.setStyle(Paint.Style.FILL);
black.setColor(Color.GRAY);
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);
canvasGetWidth = canvas.getWidth();
//Draw
for (int i = 0; i < triangles.size(); i++)
{
canvas.drawBitmap(TriangleImage, triangles.get(i).getX(), triangles.get(i).getY(), null);
}
}
public boolean onTouchEvent(MotionEvent event)
{
if (event.getAction() != MotionEvent.ACTION_DOWN)
Toast.makeText(getContext(), "onTouchEvent invoked. X= " + event.getX() + " Y= " + event.getY(), 15).show();
x1 = event.getX();
y1 = event.getY();
for (Triangle p: triangles) {
Toast.makeText(getContext(), "Moving the triangle after touch cordinates", 25).show();
p.posX = event.getX();
p.posY = event.getY();
return false;
}
return loading;
}
public void displayTriangles()
{
//Parachuter nr.1
x = 14;
y = 28;
Triangle p = new Triangle(x, y);
triangles.add(p);
}
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 GameScreenActivity(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)
{
}
}
}
}
if (event.getAction() == MotionEvent.ACTION_DOWN)
//set the x and y of your object here when action down
p.posX = event.getX();
p.posY = event.getY();
}
you can listen to the ACTION_MOVE event with GestureDetector http://developer.android.com/reference/android/view/GestureDetector.html