AntiAircraft - Android tutorial
|
|
|
- Rosalind Ferguson
- 10 years ago
- Views:
Transcription
1 AntiAircraft - Android tutorial 1 Introduction The goal of this tutorial is to show how to realize Android application from a very pragmatic point of view. For this purpose, I will assume that the reader is familiar with Java terminology and programming techniques and knows how to use Eclipse (at least the basics). The tutorial has been modelled in six incremental steps that will lead the reader from few elements to the whole application. In each step every created or modified class will be presented so that the reader can compare his own code and don t get lost. Moreover this tutorial comes with a package containing the code of the six steps and the graphic/sound material described. This will help the reader during development. Since before this tutorial I didn t know how to develop Android application, I want to thank my friend JuanMa Cuevas Caminero for his precious advices, examples and materials. The rest of the document is organized as follows: Summary The table of contents of the document itself. Get ready How to download Android SDK, how to set up Android tools and emulators. AntiAircraft A step- by- step incremental tutorial about how to create a non- trivial Android application. Further improvement Some opportunities to deepen Android programming techniques while improving the game. Conclusions A summary of the concepts and techniques we have learnt. Appendix The code of the project after the last step is provided divided into classes for all the needs of the reader. Page 1 of 68
2 2 Summary 1 Introduction 1 2 Summary 2 3 Get ready 3 Android SDK 3 ADT Plugin 4 Configure the pluging 5 Create an AVD 6 4 AntiAircraft 8 Step 1 Game basics 8 Step 2 Cannon movements 15 Step 3 Shoot! 22 Step 4 Aliens! 29 Step 5 Hit! 35 Step 6 Sounds 44 5 Further improvement 53 6 Conclusions 53 Appendix Final classes code 55 Bullet 55 GameActivity 56 GameThread 57 GameView 61 Hud 61 InputObject 63 SoundManager 64 Tank 65 Ufo 67 Page 2 of 68
3 3 Get ready Android SDK 1) Go to 2) Go to SDK tab and download SDK 3) Unpack SDK 4) Open the folder called tools and execute android 5) Download platform Usually it s a good practice to download the most updated version but Android 3.0 (Honeycomb) is a tablet- oriented release so choose Android 2.3 (Gingerbread). During 2011 it will probably be released Android 4, codename Ice Cream Sandwich, a combination of Gingerbread and Honeycomb, therefore it will be a good idea to work on Page 3 of 68
4 that platform. ADT Plugin 1) Start Eclipse, then select Help > Install New Software... 2) Click Add, in the top- right corner. 3) In the Add Repository dialog that appears, enter "ADT Plugin" for the Name and the following URL for the Location: ssl.google.com/android/eclipse/ If you have trouble acquiring the plugin, try using "http" in the Location URL, instead of "https" (https is preferred for security reasons). 4) Click OK. 5) In the Available Software dialog, select the checkbox next to Developer Tools and click Next. 6) In the next window, you'll see a list of the tools to be downloaded. Click Next. 7) Read and accept the license agreements, then click Finish. 8) When the installation completes, restart Eclipse. Page 4 of 68
5 Configure the pluging 1) Open Eclipse preferences. 2) Open Android tab. Page 5 of 68
6 3) Set SDK location by browsing your file system Create an AVD In this tutorial, you will run your application in the Android Emulator. Before you can launch the emulator, you must create an Android Virtual Device (AVD). An AVD defines the system image and device settings used by the emulator. To create an AVD: 1) In Eclipse, choose Window > Android SDK and AVD Manager. 2) Select Virtual Devices in the left panel. 3) Click New. 4) The Create New AVD dialog appears. 5) Type the name of the AVD 6) Choose a target that is the platform you want to run on the emulator. 7) Click Create AVD. Page 6 of 68
7 Page 7 of 68
8 4 AntiAircraft AntiAircraft is an Android application where the user has to fire down alien ships with a tank. The user can rotate and shoot touching the screen. The shot power depends from how the duration of the press and the trajectory follows physics rules. Step 1 Game basics In this first step we want to set up the game view and draw the tank. We need the following components: GameActivity Manages the actions related to the Activity that is the class that responsible for the window actions (creation, pause, etc.). For further details on Activities check GameView Manages the View that is the basic user interface element. GameThread The class in charge for managing the game flow. Invokes redraw operations. Tank The class responsible for the tank element. First of all create a new Android project and fill in the required fields. Page 8 of 68
9 We can now start implementing the four components. Let s start from the class will be first launched when application starts: GameActivity. 1) In src folder go inside your package and create a new class called GameActivity. 2) This class has to extend Activity and implement the method onstart() that is invoked when the activity becomes visible to the user. 3) We will define the View in a xml file called main. For the moment let s assume it exists and use it. 4) This class has to register an handle to the thread GameThread package pmm.antiaircraft1; import android.app.activity; public class GameActivity extends Activity{ private GameThread mgamethread; public void onstart() { super.onstart(); setcontentview(r.layout.main); // mgamethread = something 5) We want also our application to be shown in full screen so let s add these two lines: requestwindowfeature(window.feature_no_title); getwindow().setflags(windowmanager.layoutparams.flag_fullscreen, WindowManager.LayoutParams.FLAG_FULLSCREEN); For the moment this is all we can do so let s pass to define another class: GameView. 1) In src folder go inside your package and create a new class called GameView. 2) This class will extend SurfaceView and implement SurfaceHolder.callback so that we can draw on it from our thread. 3) The GameView constructor has to register the holder and add a callback to it (for the same reason explained above) and create a thread. 4) When creating the thread we will pass the holder and the context. 5) We have register the thread and to create a method to return it (to the main activity that will use it in case of pause of restart for example). 6) Three methods have to be implemented as required by SurfaceHolder.Callback: a. surfacecreated starts the thread b. surfacechanged we won t use this c. surfacedestroyed we won t use this Finally, the GameView class should look like this. It contains some inexistent methods, related to GameThread, that we will create in few minutes. public class GameView extends SurfaceView implements SurfaceHolder.Callback { private GameThread thread; Page 9 of 68
10 public GameView(Context context, AttributeSet attrs) { super(context, attrs); SurfaceHolder holder = getholder(); holder.addcallback(this); thread = new GameThread(holder, context,null); public GameThread getthread() { return thread; public void surfacecreated(surfaceholder holder) { thread.setrunning(true); public void surfacechanged(surfaceholder holder, int format, int width, int height) public void surfacedestroyed(surfaceholder holder) { Before proceeding with the GameThread we have to complete the GameActivity where we have to implement the commented part: adding reference to the thread. To do this we first need to define the view main. 1) Create a new XML file inside res/layout and call it main. 2) Define a frame layout. 3) Add the GameView with a fill_parent layout_width and layout_height to make it as big as possible. 4) Add a id reference to the GameView so that we can retrieve it univocally. <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android=" android:layout_width="fill_parent" android:layout_height="fill_parent"> <pmm.antiaircraft1.gameview android:id="@+id/game" android:layout_width="fill_parent" android:layout_height="fill_parent"/> </FrameLayout> Now we can get the thread using the getthread method in the GameView. 1) In GameActivity substitute the commented code with the following one. mgamethread = ((GameView) findviewbyid(r.id.game)).getthread(); 2) Now as a last operation of onstart() let s create the graphics invoking creategraphics(), a method we will define in GameThread soon. The final code for GameActivity should be like this: package pmm.antiaircraft1; Page 10 of 68
11 import android.app.activity; import android.view.window; import android.view.windowmanager; public class GameActivity extends Activity{ private GameThread mgamethread; public void onstart() { super.onstart(); requestwindowfeature(window.feature_no_title); getwindow().setflags(windowmanager.layoutparams.flag_fullscreen, WindowManager.LayoutParams.FLAG_FULLSCREEN); setcontentview(r.layout.main); mgamethread = ((GameView) findviewbyid(r.id.game)).getthread(); mgamethread.creategraphics(); Although the code has some errors for callings to inexistent methods, we have a basic idea of the preliminary operations: a (Game)View with FrameLayout is created, it creates and register the game thread and when it is ready it starts the thread itself. The view is found by GameActivity from its ID and from the method getthread() of the view the GameThread is registered. GameActivity then invokes the creation of Graphics to the GameThread. We have now to define the code for GameThread. 1) In src folder go inside your package and create a new class called GameThread. 2) GameThread is a thread which means it has to extend the class Thread 3) Besides constructor it contains 4 methods: a. Run responsible for the execution of the game and the repainting operations b. setrunning sets a flag that indicates if the thread is running or not c. draw draws the elements on the canvas d. creategraphics creates the elements of the game The code for this class is provided below. Take a look, we discuss some parts after the code itself. package pmm.antiaircraft1; import android.content.context; import android.content.res.resources; import android.graphics.bitmap; import android.graphics.bitmapfactory; import android.graphics.canvas; import android.os.handler; import android.util.displaymetrics; import android.view.surfaceholder; Page 11 of 68
12 public class GameThread extends Thread { private SurfaceHolder msurfaceholder; public DisplayMetrics metrics = new DisplayMetrics(); private static Bitmap mbackgroundimage; public static Bitmap tankimg; public static Bitmap cannonimg; public static boolean mrun = false; private Tank tank; public static Resources res; public GameThread(SurfaceHolder surfaceholder, Context context, Handler handler) { msurfaceholder = surfaceholder; Resources res = context.getresources(); mbackgroundimage = BitmapFactory.decodeResource(res,R.drawable.background); tankimg = BitmapFactory.decodeResource(res,R.drawable.tank); cannonimg = public void run() { while (mrun) { Canvas c = null; try { c = msurfaceholder.lockcanvas(null); synchronized (msurfaceholder) { draw(c); finally { if (c!= null) { msurfaceholder.unlockcanvasandpost(c); public void setrunning(boolean b) { mrun = b; private void draw(canvas canvas) { canvas.drawbitmap(mbackgroundimage, 0, 0, null); tank.draw(canvas); public void creategraphics() { mbackgroundimage=bitmap.createbitmap(mbackgroundimage); tank = new Tank(); In the constructor we getresources (rsc folder) and then invoke decoderesource. The parameters of this method are the graphic resources we will use for our application. For the moment we will use the images summarized in the following table. Page 12 of 68
13 Background Tank Cannon I created this png images (png is the recommended encoding for Android images) using Photoshop. The reader can also use other applications or download similar assets from the web. The cannon is separated from the tank because we want to rotate it. Since the application will be published for devices with 320x480 monitor resolution, then the background has these dimensions. Usually it is a good practice to adapt the image to the monitor but for this tutorial we won t consider these kind of techniques. It is important to notice that the canvas is obtained from the surfaceholder. Finally notice the steps required to draw an element: 1) Get the context 2) Get the resources 3) Decode the image 4) Create the bitmap 5) Draw the bitmap on the canvas For the background we did all the previous operations but for the tank we delegate this duty to the Tank class. Let s define it. 1) In src folder go inside your package and create a new class called Tank. 2) This class has some dimensions of used images set as constant because they will be used in position calculus. 3) The constructor creates bitmap and register those in GameThread 4) The method draw (yes the one we invoked in GameThread) is in charge of drawing operations Page 13 of 68
14 5) The draw method uses Matrix for place the cannon because it will be very useful in the next code iteration. package pmm.antiaircraft1; import android.graphics.bitmap; import android.graphics.canvas; import android.graphics.matrix; public class Tank { private static final int TANK_HEIGHT = 50; private static final int TANK_WIDTH = 50; private static final int TANK_TOP = TANK_HEIGHT; private static final int CANNON_WIDTH = 10; public Tank(){ GameThread.tankImg=Bitmap.createBitmap(GameThread.tankImg); GameThread.cannonImg=Bitmap.createBitmap(GameThread.cannonImg); public void draw(canvas c) { c.drawbitmap(gamethread.tankimg, (320-TANK_WIDTH)/2, TANK_TOP, null); Matrix m = new Matrix(); m.posttranslate((320-cannon_width)/2, TANK_TOP - 30); c.drawbitmap(gamethread.cannonimg, m, null); Note the calculus will place the tank at the bottom- center of our 320x480 screen. Finally, if we Run our application as Android Application we will see something like this. This concludes the first step: we have our running application that doesn t do anything! Page 14 of 68
15 Step 2 Cannon movements In this step we ll realize the cannon movements so we need a class to manage user interaction: InputObject. 1) In src folder go inside your package (for this step the package has been renamed to pmm.antiaircraft2) and create a new class called InputObject. 2) Create a method useevent for MotionEvent that has to register the type of action, the time it happened and its coordinates. 3) The constructor registers an ArrayBlockingQueue of InputObject. We ll see later when it is called. 4) A method adds the InputObject to the ArrayBlockingQueue of InputObject. This class is not difficult but requires an understanding of the Android touch events. The reader can get information at events.html. The final class should look like this. package pmm.antiaircraft2; import java.util.concurrent.arrayblockingqueue; import android.view.motionevent; public class InputObject { public static final byte EVENT_TYPE_KEY = 1; public static final byte EVENT_TYPE_TOUCH = 2; public static final int ACTION_KEY_DOWN = 1; public static final int ACTION_KEY_UP = 2; public static final int ACTION_TOUCH_DOWN = 3; public static final int ACTION_TOUCH_MOVE = 4; public static final int ACTION_TOUCH_UP = 5; public ArrayBlockingQueue<InputObject> pool; public byte eventtype; public long time; public int action; public int keycode; public int x; public int y; public InputObject(ArrayBlockingQueue<InputObject> pool) { this.pool = pool; public void useevent(motionevent event) { eventtype = EVENT_TYPE_TOUCH; int a = event.getaction(); switch (a) { case MotionEvent.ACTION_DOWN: action = ACTION_TOUCH_DOWN; break; case MotionEvent.ACTION_MOVE: action = ACTION_TOUCH_MOVE; break; case MotionEvent.ACTION_UP: action = ACTION_TOUCH_UP; break; default: action = 0; Page 15 of 68
16 time = event.geteventtime(); x = (int) event.getx() ; y = (int) event.gety(); public void useeventhistory(motionevent event, int historyitem) { eventtype = EVENT_TYPE_TOUCH; action = ACTION_TOUCH_MOVE; time = event.gethistoricaleventtime(historyitem); x = (int) event.gethistoricalx(historyitem); y = (int) event.gethistoricaly(historyitem); public void returntopool() { pool.add(this); Now let s edit our GameActivity class: 1) Add a method for creating the InputObject queue. 2) Call this method as the last onstart action. 3) Override ontouchevent method to manage event queue and related action. The 2 method are the following. private void createinputobjectpool() { inputobjectpool = new ArrayBlockingQueue<InputObject>(INPUT_QUEUE_SIZE); for (int i = 0; i < INPUT_QUEUE_SIZE; i++) { inputobjectpool.add(new public boolean ontouchevent(motionevent event) { try { int hist = event.gethistorysize(); for (int i = 0; i < hist; i++) { InputObject input = inputobjectpool.take(); input.useeventhistory(event, i); mgamethread.feedinput(input); InputObject input = inputobjectpool.take(); input.useevent(event); mgamethread.feedinput(input); catch (InterruptedException e) { try { Thread.sleep(16); catch (InterruptedException e) { return true; The class should now look like this: Page 16 of 68
17 package pmm.antiaircraft2; import java.util.concurrent.arrayblockingqueue; import android.app.activity; import android.view.motionevent; import android.view.window; import android.view.windowmanager; public class GameActivity extends Activity{ private GameThread mgamethread; public static final int INPUT_QUEUE_SIZE = 30; public ArrayBlockingQueue<InputObject> inputobjectpool; public void onstart() { super.onstart(); requestwindowfeature(window.feature_no_title); getwindow().setflags(windowmanager.layoutparams.flag_fullscreen, WindowManager.LayoutParams.FLAG_FULLSCREEN); setcontentview(r.layout.main); mgamethread = ((GameView) findviewbyid(r.id.game)).getthread(); mgamethread.creategraphics(); createinputobjectpool(); private void createinputobjectpool() { inputobjectpool = new ArrayBlockingQueue<InputObject>(INPUT_QUEUE_SIZE); for (int i = 0; i < INPUT_QUEUE_SIZE; i++) { inputobjectpool.add(new public boolean ontouchevent(motionevent event) { try { int hist = event.gethistorysize(); for (int i = 0; i < hist; i++) { InputObject input = inputobjectpool.take(); input.useeventhistory(event, i); mgamethread.feedinput(input); InputObject input = inputobjectpool.take(); input.useevent(event); mgamethread.feedinput(input); catch (InterruptedException e) { try { Thread.sleep(16); catch (InterruptedException e) { return true; As we have seen some modification must be performed on GameThread: Page 17 of 68
18 1) New method to feedinput. 2) New method to processinput. 3) New method to processmotionevent, for the moment it takes care only of cannon movement but it contains 3 different behaviours because this will be necessary for firing operation. The methods are defined as follows. public void feedinput(inputobject input) { synchronized(inputqueuemutex) { try { inputqueue.put(input); catch (InterruptedException e) { private void processinput() { synchronized(inputqueuemutex) { ArrayBlockingQueue<InputObject> inputqueue = this.inputqueue; while (!inputqueue.isempty()) { try { InputObject input = inputqueue.take(); if (input.eventtype == InputObject.EVENT_TYPE_TOUCH) { processmotionevent(input); input.returntopool(); catch (InterruptedException e) { private void processmotionevent(inputobject input) { if( input.action==inputobject.action_touch_down){ tank.settarget(input.x, input.y); else if( input.action==inputobject.action_touch_move) { tank.settarget(input.x, input.y); else if( input.action==inputobject.action_touch_up){ tank.settarget(input.x, input.y); 4) In run() invoke processinput just before the draw invocation. Now the class should look like follows: package pmm.antiaircraft2; import java.util.concurrent.arrayblockingqueue; Page 18 of 68
19 import android.content.context; import android.content.res.resources; import android.graphics.bitmap; import android.graphics.bitmapfactory; import android.graphics.canvas; import android.os.handler; import android.util.displaymetrics; import android.view.surfaceholder; public class GameThread extends Thread { private SurfaceHolder msurfaceholder; public DisplayMetrics metrics = new DisplayMetrics(); private static Bitmap mbackgroundimage; public static Bitmap tankimg; public static Bitmap cannonimg; public static boolean mrun = false; private Tank tank; public static Resources res; private Object inputqueuemutex = new Object(); private ArrayBlockingQueue<InputObject> inputqueue = new ArrayBlockingQueue<InputObject>(30); public GameThread(SurfaceHolder surfaceholder, Context context, Handler handler) { msurfaceholder = surfaceholder; Resources res = context.getresources(); mbackgroundimage = BitmapFactory.decodeResource(res,R.drawable.background); tankimg = BitmapFactory.decodeResource(res,R.drawable.tank); cannonimg = public void run() { while (mrun) { Canvas c = null; try { c = msurfaceholder.lockcanvas(null); synchronized (msurfaceholder) { processinput(); draw(c); finally { if (c!= null) { msurfaceholder.unlockcanvasandpost(c); public void setrunning(boolean b) { mrun = b; private void draw(canvas canvas) { canvas.drawbitmap(mbackgroundimage, 0, 0, null); tank.draw(canvas); Page 19 of 68
20 public void creategraphics() { mbackgroundimage=bitmap.createbitmap(mbackgroundimage); tank = new Tank(); public void feedinput(inputobject input) { synchronized(inputqueuemutex) { try { inputqueue.put(input); catch (InterruptedException e) { private void processinput() { synchronized(inputqueuemutex) { ArrayBlockingQueue<InputObject> inputqueue = this.inputqueue; while (!inputqueue.isempty()) { try { InputObject input = inputqueue.take(); if (input.eventtype == InputObject.EVENT_TYPE_TOUCH) { processmotionevent(input); input.returntopool(); catch (InterruptedException e) { private void processmotionevent(inputobject input) { if( input.action==inputobject.action_touch_down){ tank.settarget(input.x, input.y); else if( input.action==inputobject.action_touch_move) { tank.settarget(input.x, input.y); else if( input.action==inputobject.action_touch_up){ tank.settarget(input.x, input.y); Last but not less important we have to define the motion of the cannon itself in Tank class. 1) Create settarget method. Use arctang to calculate the angle but pay attention to division by 0 and similar cases. 2) Rotate the cannon using this value before drawing it. It s not difficult but some attention is required in order to avoid mathematical errors. The use of debug may come in handy. This is the final version of the class: package pmm.antiaircraft2; Page 20 of 68
21 import android.graphics.bitmap; import android.graphics.canvas; import android.graphics.matrix; public class Tank { private static final int TANK_HEIGHT = 50; private static final int TANK_WIDTH = 50; private static final int TANK_TOP = TANK_HEIGHT; private static final int CANNON_WIDTH = 10; private float angle; public Tank(){ GameThread.tankImg=Bitmap.createBitmap(GameThread.tankImg); GameThread.cannonImg=Bitmap.createBitmap(GameThread.cannonImg); public void draw(canvas c) { c.drawbitmap(gamethread.tankimg, (320-TANK_WIDTH)/2, TANK_TOP, null); Matrix m = new Matrix(); m.posttranslate((320-cannon_width)/2, TANK_TOP - 30); m.postrotate((float) ((-angle)*180 /Math.PI),160,446); c.drawbitmap(gamethread.cannonimg, m, null); public void settarget(int x, int y) { if (x==160) angle=0; else{ if(y>=446){ angle=(float)math.pi/2; if(x>160) angle-=2*angle; else angle = (float) Math.atan((float)(x-160)/(float)(y-446)); We can now run the application and interact with it moving the cannon. Page 21 of 68
22 Step 3 Shoot! Now we can move the cannon but the tank is not ready yet: it s time to shoot! As usual, we want to create a new class to model the bullet: 1) In src folder go inside your package (for this step the package has been renamed to pmm.antiaircraft3) and create a new class called Bullet. 2) This class defines some constants to identify the status of the bullet and its size. 3) This class has the variables needed to identify the position of the bullet, its velocity and the direction. 4) There is a method to update all this variables in relation of time passed. 5) We want to model also the explosion of the bullet after X milliseconds. 6) There is a method draw that takes care of drawing a circle representing the bullet itself. 7) We can calculate the new position with the following formula posx=(float) (posx0 + inispeedx*t2); posy=(float) (posy0 - (inispeedy*t2 - (9.8 *Math.pow(t2, 2)/2))); The final Bullet class should be similar to the one below. package pmm.antiaircraft3; import android.graphics.canvas; import android.graphics.color; import android.graphics.paint; public class Bullet { private static final int STATUS_FLYING = 0; private static final int STATUS_BOOM = 1; private static final int STATUS_OVER = 2; Page 22 of 68
23 private static final int BULLET_RADIUS = 4; private static final long TIME_EXPLODING = 100; private long time; private int status; private int power; private float posx0; private float posy0; private float posx; private float posy; private float inispeedx; private float inispeedy; private Paint paint; private long explodingtimer; public Bullet(int power,float angle,int x0,int y0){ time=0; paint = new Paint(); this.power = power; posx0 = x0; posy0 = y0; inispeedy=(float) (Math.sin(angle)*power*1.5) ; inispeedx=(float) (Math.cos(angle)*power*1.5); public void draw(canvas c) { paint.setcolor(color.red); if (status == STATUS_FLYING) paint.setcolor(color.black); c.drawcircle(posx, posy, BULLET_RADIUS, paint); public void update(long elapsedtime) { switch (status){ case STATUS_FLYING: time+=elapsedtime; double t2=(double)(time)/100; posx=(float) (posx0 + inispeedx*t2); posy=(float) (posy0 - (inispeedy*t2 - (9.8 *Math.pow(t2, 2)/2))); if (posy>=480) { status=status_boom; posy = 480; explodingtimer = 0; break; case STATUS_BOOM: explodingtimer+=elapsedtime; if (explodingtimer>time_exploding) status=status_over; break; Page 23 of 68
24 public void setimpact(){ status = STATUS_BOOM; explodingtimer=0; public float getposx() { return posx; public float getposy() { return posy; public boolean isflying(){ return (status == STATUS_FLYING); public boolean isexploding() { return (status==status_boom); public boolean isover() { return (status==status_over); Now we have to update the GameThread in order to insert the callings to fire methods and physics (that will be in Tank) 1) Update processmotionevent as follows private void processmotionevent(inputobject input) { if( input.action==inputobject.action_touch_down){ tank.pressfire(); tank.settarget(input.x, input.y); if( input.action==inputobject.action_touch_up){ tank.settarget(input.x, input.y); tank.releasefire(); if( input.action==inputobject.action_touch_move) tank.settarget(input.x, input.y); 2) The class constructor should now create a list of bullets. 3) The method run has to calculate the time passed and invoke updatephysics method after processed the input. 4) The updatephysics method calls methods to update the status of our objects if they are related to time as the bullet and the tank. Why also the tank? Because as we will see it will have methods to calculate the initial velocity of the bullet based on the duration of the finger tap on device screen. 5) The draw method has to be updated in order to draw all the bullets in the list. Page 24 of 68
25 The final code for this class is this: package pmm.antiaircraft3; import java.util.arraylist; import java.util.iterator; import java.util.concurrent.arrayblockingqueue; import android.content.context; import android.content.res.resources; import android.graphics.bitmap; import android.graphics.bitmapfactory; import android.graphics.canvas; import android.os.handler; import android.util.displaymetrics; import android.view.surfaceholder; public class GameThread extends Thread { private SurfaceHolder msurfaceholder; public DisplayMetrics metrics = new DisplayMetrics(); private static Bitmap mbackgroundimage; public static Bitmap tankimg; public static Bitmap cannonimg; public static boolean mrun = false; private Tank tank; public static Resources res; private Object inputqueuemutex = new Object(); private ArrayBlockingQueue<InputObject> inputqueue = new ArrayBlockingQueue<InputObject>(30); private static ArrayList<Bullet> bullets; private long lastupdatetime; public GameThread(SurfaceHolder surfaceholder, Context context, Handler handler) { msurfaceholder = surfaceholder; Resources res = context.getresources(); mbackgroundimage = BitmapFactory.decodeResource(res,R.drawable.background); tankimg = BitmapFactory.decodeResource(res,R.drawable.tank); cannonimg = BitmapFactory.decodeResource(res,R.drawable.cannon); bullets = new public void run() { while (mrun) { Canvas c = null; try { c = msurfaceholder.lockcanvas(null); synchronized (msurfaceholder) { long currenttime = System.currentTimeMillis(); long delta = (long) (currenttime - lastupdatetime); lastupdatetime = currenttime; processinput(); updatephysics(delta); draw(c); finally { if (c!= null) { Page 25 of 68
26 msurfaceholder.unlockcanvasandpost(c); public void setrunning(boolean b) { mrun = b; private void draw(canvas canvas) { canvas.drawbitmap(mbackgroundimage, 0, 0, null); for(iterator<bullet> it = bullets.iterator();it.hasnext();){ Bullet b = (Bullet) it.next(); if (b!=null) b.draw(canvas); tank.draw(canvas); public void creategraphics() { mbackgroundimage=bitmap.createbitmap(mbackgroundimage); tank = new Tank(); private void updatephysics(long timer) { timer=(long) (timer); tank.update(timer); Bullet b ; int i=0; while (!bullets.isempty() && bullets.size()>i){ b = bullets.get(i); if (b.isover()) bullets.remove(i); else { b.update(timer); i++; public void feedinput(inputobject input) { synchronized(inputqueuemutex) { try { inputqueue.put(input); catch (InterruptedException e) { private void processinput() { synchronized(inputqueuemutex) { ArrayBlockingQueue<InputObject> inputqueue = this.inputqueue; while (!inputqueue.isempty()) { try { InputObject input = inputqueue.take(); if (input.eventtype == InputObject.EVENT_TYPE_TOUCH) { Page 26 of 68
27 processmotionevent(input); input.returntopool(); catch (InterruptedException e) { private void processmotionevent(inputobject input) { if( input.action==inputobject.action_touch_down){ tank.pressfire(); tank.settarget(input.x, input.y); if( input.action==inputobject.action_touch_up){ tank.settarget(input.x, input.y); tank.releasefire(); if( input.action==inputobject.action_touch_move) tank.settarget(input.x, input.y); public static void shootbullet(float angle, int power,int x, int y) { bullets.add(new Bullet(power, angle, x, y)); Note we draw the bullet before the tank so the bullet is behind it. Finally we have to create the firing methods in Tank. 1) Create methods pressfire and releasefire used to calculate the power between the two events. 2) Create update method to calculate the power at any call. Set a maximum boundary to avoid too fast shots. 3) Add variables to track the coordinates of the cannon end so that we can make the bullet start from there. These variables have to be updated every time the cannon moves. The Tank class should now look like this. package pmm.antiaircraft3; import android.graphics.bitmap; import android.graphics.canvas; import android.graphics.matrix; public class Tank { private static final int TANK_HEIGHT = 50; private static final int TANK_WIDTH = 50; private static final int TANK_TOP = TANK_HEIGHT; private static final int CANNON_WIDTH = 10; private static final int GUNBARREL_LENGTH = 46; private static final int STATUS_IDLE=0; private static final int STATUS_POWERING=1; private static final long POWERING_TIMER_LIMIT = 1200; private float angle; Page 27 of 68
28 public static int cannonendx; public static int cannonendy; private int status; private long poweringtimer; private int power; private int lastbulletpower; public Tank(){ GameThread.tankImg=Bitmap.createBitmap(GameThread.tankImg); GameThread.cannonImg=Bitmap.createBitmap(GameThread.cannonImg); public void draw(canvas c) { c.drawbitmap(gamethread.tankimg, (320-TANK_WIDTH)/2, TANK_TOP, null); Matrix m = new Matrix(); m.posttranslate((320-cannon_width)/2, TANK_TOP - 30); m.postrotate((float) ((-angle)*180 /Math.PI),160,446); c.drawbitmap(gamethread.cannonimg, m, null); cannonendx = (int) (160 + (Math.cos(angle) * GUNBARREL_LENGTH)); cannonendy = (int) (446 - (Math.sin(angle) * GUNBARREL_LENGTH)); public void settarget(int x, int y) { if (x==160) angle=0; else{ if(y>=446){ angle=(float)math.pi/2; if(x>160) angle-=2*angle; else angle = (float) Math.atan((float)(x-160)/(float)(y-446)); public void update(long elapsedtime){ if (status == STATUS_POWERING){ poweringtimer=poweringtimer+elapsedtime; if (poweringtimer>powering_timer_limit) poweringtimer=powering_timer_limit; power = (int) (((float)poweringtimer / POWERING_TIMER_LIMIT) *100); public void pressfire( ) { status = STATUS_POWERING; power = 0; poweringtimer = 0; public void releasefire() { GameThread.shootBullet(angle+(float)Math.PI/2,40+power*60/100,160,446); lastbulletpower = power; status = STATUS_IDLE; power = 0; Page 28 of 68
29 At the end of this step we have a tank with moving cannon that shoots big black bullets according to physics rules! Step 4 Aliens! The tank is ready to fight! Now we need enemies. Directly from science fiction: UFO! Fist of all we need to draw our flying saucers using Photoshop or another graphic application. I did the following image in 5 minutes; the reader can use it or make a better one. As always we have to create a specific class, let s call it Ufo. 1) In src folder go inside your package (for this step the package has been renamed to pmm.antiaircraft4) and create a new class called Ufo. 2) The constructor has to define the initial position of the ufo and its speed, and these values have to be randomly generated. 3) The method update updates all the values related to the ufo movement, if its status is flying, however for the moment this is the only possible status. 4) There has to be a method to draw the ufo. Below there is the Ufo class. Page 29 of 68
30 package pmm.antiaircraft4; import android.graphics.bitmap; import android.graphics.canvas; import android.graphics.matrix; public class Ufo { private static final int STATUS_FLYING = 0; private static final int STATUS_OVER = 1; private static final float TIME_FLYING = 5; private float lowerposition; private long time; private int status; private float posx; private float posy; private double inispeedx; private double inispeedy; private float posx0; private float drawx; private float drawy; private int angle; private int direction; private static float acceleration; public Ufo(){ time = 0; angle = 0; status = STATUS_FLYING; direction = (Math.random()<0.5?1:-1); posx0 = (float) (160 + (320*-direction*Math.random())); lowerposition = 480; acceleration = (float) (lowerposition/math.pow(time_flying/2,2)); inispeedx = (320 / TIME_FLYING); inispeedy = (TIME_FLYING * acceleration / 2) - 1 / TIME_FLYING; GameThread.ufoImg = Bitmap.createBitmap(GameThread.ufoImg); public void draw(canvas c) { Matrix m = new Matrix(); m.posttranslate(drawx, drawy); if (status == STATUS_FLYING) c.drawbitmap(gamethread.ufoimg, m, null); public void update(long elapsedtime) { double t2; switch (status){ case STATUS_FLYING: time+=elapsedtime; t2=(double)(time)/1000; posx = (float) (posx0 + inispeedx*t2*direction); Page 30 of 68
31 posy = (float) (inispeedy * t2 - (acceleration/2 * Math.pow(t2,2) )); angle = (direction>0?180:0) + (int) (Math.atan((iniSpeedYacceleration*t2)/iniSpeedX*direction)*180/Math.PI); if (posy<0) status=status_over; break; drawx = posx - 30; drawy = posy - 20; public boolean isover() { return (status==status_over); public boolean isflying(){ return (status == STATUS_FLYING); We now have to update the GameThread in a way it is now able to generate Ufo instances and invoke the related methods. 1) There is a new image to decode in the constructor. 2) Create a new list of Ufo. 3) Add the code for drawing the Ufo in the draw method. 4) In updatephysics add a section where a new Ufo instance is created every X seconds and invoke the ufo update method for each ufo in the list. Now the GameThread should look like this: package pmm.antiaircraft4; import java.util.arraylist; import java.util.iterator; import java.util.concurrent.arrayblockingqueue; import android.content.context; import android.content.res.resources; import android.graphics.bitmap; import android.graphics.bitmapfactory; import android.graphics.canvas; import android.os.handler; import android.util.displaymetrics; import android.view.surfaceholder; public class GameThread extends Thread { private SurfaceHolder msurfaceholder; public DisplayMetrics metrics = new DisplayMetrics(); private static Bitmap mbackgroundimage; public static Bitmap tankimg; public static Bitmap cannonimg; public static Bitmap ufoimg; public static boolean mrun = false; Page 31 of 68
32 private Tank tank; public static Resources res; private Object inputqueuemutex = new Object(); private ArrayBlockingQueue<InputObject> inputqueue = new ArrayBlockingQueue<InputObject>(30); private static ArrayList<Bullet> bullets; private static ArrayList<Ufo> ufos; private long lastupdatetime; private long newufotimer; public GameThread(SurfaceHolder surfaceholder, Context context, Handler handler) { msurfaceholder = surfaceholder; Resources res = context.getresources(); mbackgroundimage = BitmapFactory.decodeResource(res,R.drawable.background); tankimg = BitmapFactory.decodeResource(res,R.drawable.tank); cannonimg = BitmapFactory.decodeResource(res,R.drawable.cannon); ufoimg= BitmapFactory.decodeResource(res,R.drawable.ufo); bullets = new ArrayList<Bullet>(); ufos = new public void run() { while (mrun) { Canvas c = null; try { c = msurfaceholder.lockcanvas(null); synchronized (msurfaceholder) { long currenttime = System.currentTimeMillis(); long delta = (long) (currenttime - lastupdatetime); lastupdatetime = currenttime; processinput(); updatephysics(delta); draw(c); finally { if (c!= null) { msurfaceholder.unlockcanvasandpost(c); public void setrunning(boolean b) { mrun = b; private void draw(canvas canvas) { canvas.drawbitmap(mbackgroundimage, 0, 0, null); for(iterator<bullet> it = bullets.iterator();it.hasnext();){ Bullet b = (Bullet) it.next(); if (b!=null) b.draw(canvas); for(iterator<ufo> it = ufos.iterator();it.hasnext();){ Ufo a = (Ufo) it.next(); Page 32 of 68
33 if (a!=null) a.draw(canvas); tank.draw(canvas); public void creategraphics() { mbackgroundimage=bitmap.createbitmap(mbackgroundimage); tank = new Tank(); private void updatephysics(long timer) { timer=(long) (timer); tank.update(timer); Bullet b ; int i=0; while (!bullets.isempty() && bullets.size()>i){ b = bullets.get(i); if (b.isover()) bullets.remove(i); else { b.update(timer); i++; Ufo a ; i=0; while (!ufos.isempty() && ufos.size()>i){ a = ufos.get(i); a.update(timer); i++; newufotimer+=timer; if (newufotimer>3000){ ufos.add(new Ufo()); newufotimer=0; public void feedinput(inputobject input) { synchronized(inputqueuemutex) { try { inputqueue.put(input); catch (InterruptedException e) { private void processinput() { synchronized(inputqueuemutex) { ArrayBlockingQueue<InputObject> inputqueue = this.inputqueue; while (!inputqueue.isempty()) { try { InputObject input = inputqueue.take(); if (input.eventtype == InputObject.EVENT_TYPE_TOUCH) { Page 33 of 68
34 processmotionevent(input); input.returntopool(); catch (InterruptedException e) { private void processmotionevent(inputobject input) { if( input.action==inputobject.action_touch_down){ tank.pressfire(); tank.settarget(input.x, input.y); if( input.action==inputobject.action_touch_up){ tank.settarget(input.x, input.y); tank.releasefire(); if( input.action==inputobject.action_touch_move) tank.settarget(input.x, input.y); public static void shootbullet(float angle, int power,int x, int y) { bullets.add(new Bullet(power, angle, x, y)); At the end of this iteration we have created our enemies with a specific movements but, for the moment, they are invulnerable to our bullets. Page 34 of 68
35 Step 5 Hit! In this step we will manage the collision between bullets and enemies. We want also to keep the count of victims and other indicators, as shooting power. First of all there is the need of a new class for displaying the crucial information on the screen. We will call it head- up display, in short HUD. 1) In src folder go inside your package (for this step the package has been renamed to pmm.antiaircraft5) and create a new class called Hud. 2) This class contains the position on the screen of the text and the other visual elements we want to present. 3) The most important method is draw that contains the code for the correct display of information. 4) The information are: angle, power and number of impacts (enemies destroyed). For this purpose we need a method that registers the handle of the tank. 5) There is a method addimpact that raises the number of impacts. The code of this class is therefore similar to the following one. package pmm.antiaircraft5; import android.graphics.canvas; import android.graphics.color; import android.graphics.lineargradient; import android.graphics.paint; import android.graphics.paint.style; import android.graphics.rectf; import android.graphics.shader; public class Hud { private static final int BAR_POWER_LEFT_MARGIN = 10; private static final int BAR_POWER_RIGHT_MARGIN = 200; private static final int BAR_POWER_BOTTOM_MARGIN = 10; private static final int BAR_POWER_HEIGHT = 10; private static final int TEXT_INFO_LEFT_MARGIN = 10; private static final int TEXT_ANGLE_TOP_MARGIN = 25; private static final int TEXT_POWER_TOP_MARGIN = 50; private static final int TEXT_COUNTER_TOP_MARGIN = 75; private static final int TEXT_SIZE = 20; private float barpwrleft; private float barpwrtop; private float barpwrright; private float barpwrbottom; private int impactcounter; LinearGradient gradient; Paint paint; private Tank tank; public Hud(){ paint = new Paint(); barpwrleft = BAR_POWER_LEFT_MARGIN; barpwrtop = BAR_POWER_BOTTOM_MARGIN - BAR_POWER_HEIGHT; barpwrright = BAR_POWER_RIGHT_MARGIN; barpwrbottom = BAR_POWER_HEIGHT; impactcounter =0; Page 35 of 68
36 gradient= new LinearGradient (barpwrleft, barpwrtop, barpwrright, barpwrtop, new int[]{color.green,color.yellow, Color.RED,null, Shader.TileMode.CLAMP); public void draw(canvas c){ int progress = ((int) (barpwrleft + tank.getpower() * (barpwrrightbarpwrleft) /100)); paint.setalpha(255); paint.setshader(gradient); paint.setstyle(style.fill); c.drawroundrect(new RectF(barPwrLeft, barpwrtop, progress, barpwrbottom), 4, 4, paint); paint.setshader(null); paint.setstyle(style.stroke); paint.setcolor(color.black); paint.setstrokewidth(0); c.drawroundrect(new RectF(barPwrLeft, barpwrtop, barpwrright, barpwrbottom), 4, 4, paint); paint.setcolor(color.black); paint.setstyle(paint.style.stroke); paint.setstrokewidth(0); paint.setantialias(true); paint.settextsize(text_size); int powerinfo=(tank.getpower()==0?tank.getlastbulletpower():tank.getpower()); c.drawtext("angle: "+Math.abs((int) (tank.getangle()*180/math.pi))+"º", TEXT_INFO_LEFT_MARGIN, TEXT_ANGLE_TOP_MARGIN, paint); c.drawtext("power: "+powerinfo, TEXT_INFO_LEFT_MARGIN, TEXT_POWER_TOP_MARGIN, paint); c.drawtext("impacts: "+impactcounter, TEXT_INFO_LEFT_MARGIN, TEXT_COUNTER_TOP_MARGIN, paint); public void register(tank tank) { this.tank = tank; public void addimpact() { impactcounter++; Note how we drawn a power charging bar. Now we have to update the GameThread class to call Hud methods. 1) First of all draw has to invoke the draw of hud. 2) In creategraphics a new Hud object is created and the tank is registered. 3) In updatephysics we have to add a check for collisions between bullets and ufos. 4) If a collision has been detected then the addimpact method of the Hud and the setimpact methods of ufo and bullet are called. The updated class has the following code. package pmm.antiaircraft5; Page 36 of 68
37 import java.util.arraylist; import java.util.iterator; import java.util.concurrent.arrayblockingqueue; import android.content.context; import android.content.res.resources; import android.graphics.bitmap; import android.graphics.bitmapfactory; import android.graphics.canvas; import android.os.handler; import android.util.displaymetrics; import android.view.surfaceholder; public class GameThread extends Thread { private SurfaceHolder msurfaceholder; public DisplayMetrics metrics = new DisplayMetrics(); private static Bitmap mbackgroundimage; public static Bitmap tankimg; public static Bitmap cannonimg; public static Bitmap ufoimg; public static boolean mrun = false; private Tank tank; public static Resources res; private Object inputqueuemutex = new Object(); private ArrayBlockingQueue<InputObject> inputqueue = new ArrayBlockingQueue<InputObject>(30); private static ArrayList<Bullet> bullets; private static ArrayList<Ufo> ufos; private long lastupdatetime; private long newufotimer; private Hud hud; public GameThread(SurfaceHolder surfaceholder, Context context, Handler handler) { msurfaceholder = surfaceholder; Resources res = context.getresources(); mbackgroundimage = BitmapFactory.decodeResource(res,R.drawable.background); tankimg = BitmapFactory.decodeResource(res,R.drawable.tank); cannonimg = BitmapFactory.decodeResource(res,R.drawable.cannon); ufoimg= BitmapFactory.decodeResource(res,R.drawable.ufo); bullets = new ArrayList<Bullet>(); ufos = new public void run() { while (mrun) { Canvas c = null; try { c = msurfaceholder.lockcanvas(null); synchronized (msurfaceholder) { long currenttime = System.currentTimeMillis(); long delta = (long) (currenttime - lastupdatetime); lastupdatetime = currenttime; processinput(); updatephysics(delta); draw(c); Page 37 of 68
38 finally { if (c!= null) { msurfaceholder.unlockcanvasandpost(c); public void setrunning(boolean b) { mrun = b; private void draw(canvas canvas) { canvas.drawbitmap(mbackgroundimage, 0, 0, null); for(iterator<bullet> it = bullets.iterator();it.hasnext();){ Bullet b = (Bullet) it.next(); if (b!=null) b.draw(canvas); for(iterator<ufo> it = ufos.iterator();it.hasnext();){ Ufo a = (Ufo) it.next(); if (a!=null) a.draw(canvas); tank.draw(canvas); hud.draw(canvas); public void creategraphics() { mbackgroundimage=bitmap.createbitmap(mbackgroundimage); tank = new Tank(); hud = new Hud(); hud.register(tank); private void updatephysics(long timer) { timer=(long) (timer); tank.update(timer); Bullet b ; int i=0; while (!bullets.isempty() && bullets.size()>i){ b = bullets.get(i); if (b.isover()) bullets.remove(i); else { b.update(timer); i++; Ufo a ; i=0; while (!ufos.isempty() && ufos.size()>i){ a = ufos.get(i); Page 38 of 68
39 if (a.isover()) ufos.remove(i); else { a.update(timer); int j=0; while (j<bullets.size()){ b = bullets.get(j); if (a.isflying() && b.isflying()) if(a.impactdetected(b)){ hud.addimpact(); a.setimpact(); b.setimpact(); ufos.add(new Ufo()); j++; i++; newufotimer+=timer; if (newufotimer>3000){ ufos.add(new Ufo()); newufotimer=0; public void feedinput(inputobject input) { synchronized(inputqueuemutex) { try { inputqueue.put(input); catch (InterruptedException e) { private void processinput() { synchronized(inputqueuemutex) { ArrayBlockingQueue<InputObject> inputqueue = this.inputqueue; while (!inputqueue.isempty()) { try { InputObject input = inputqueue.take(); if (input.eventtype == InputObject.EVENT_TYPE_TOUCH) { processmotionevent(input); input.returntopool(); catch (InterruptedException e) { private void processmotionevent(inputobject input) { if( input.action==inputobject.action_touch_down){ tank.pressfire(); tank.settarget(input.x, input.y); if( input.action==inputobject.action_touch_up){ Page 39 of 68
40 tank.settarget(input.x, input.y); tank.releasefire(); if( input.action==inputobject.action_touch_move) tank.settarget(input.x, input.y); public static void shootbullet(float angle, int power,int x, int y) { bullets.add(new Bullet(power, angle, x, y)); So now we have to add the described methods to Ufo class. 1) Add a method to detect impacts. 2) Add a method to change the status of the bullet. The code of the class is below here. package pmm.antiaircraft5; import android.graphics.bitmap; import android.graphics.canvas; import android.graphics.matrix; public class Ufo { private static final int STATUS_FLYING = 0; private static final int STATUS_OVER = 1; private static final float TIME_FLYING = 5; private float lowerposition; private long time; private int status; private float posx; private float posy; private double inispeedx; private double inispeedy; private float posx0; private float drawx; private float drawy; private int angle; private int direction; private static float acceleration; public Ufo(){ time = 0; angle = 0; status = STATUS_FLYING; direction = (Math.random()<0.5?1:-1); posx0 = (float) (160 + (320*-direction*Math.random())); lowerposition = 480; acceleration = (float) (lowerposition/math.pow(time_flying/2,2)); inispeedx = (320 / TIME_FLYING); Page 40 of 68
41 inispeedy = (TIME_FLYING * acceleration / 2) - 1 / TIME_FLYING; GameThread.ufoImg = Bitmap.createBitmap(GameThread.ufoImg); public void draw(canvas c) { Matrix m = new Matrix(); m.posttranslate(drawx, drawy); if (status == STATUS_FLYING) c.drawbitmap(gamethread.ufoimg, m, null); public void update(long elapsedtime) { double t2; switch (status){ case STATUS_FLYING: time+=elapsedtime; t2=(double)(time)/1000; posx = (float) (posx0 + inispeedx*t2*direction); posy = (float) (inispeedy * t2 - (acceleration/2 * Math.pow(t2,2) )); angle = (direction>0?180:0) + (int) (Math.atan((iniSpeedYacceleration*t2)/iniSpeedX*direction)*180/Math.PI); if (posy<0) status=status_over; break; drawx = posx - 30; drawy = posy - 20; public boolean isover() { return (status==status_over); public boolean isflying(){ return (status == STATUS_FLYING); public boolean impactdetected(bullet b) { boolean impact = false; float diffx=math.abs(posx-b.getposx()); float diffy=math.abs(posy-b.getposy()); if (diffx<19 && diffy<19){ impact = true; return impact; public void setimpact(){ status = STATUS_OVER; Page 41 of 68
42 Finally, in Tank class we need to add the getters so that the hud can retrieve up to date information. 1) Add getangle method. 2) Add getpower method. 3) Add getlastbulletpower method. At this point the Tank class should look like this. package pmm.antiaircraft5; import android.graphics.bitmap; import android.graphics.canvas; import android.graphics.matrix; public class Tank { private static final int TANK_HEIGHT = 50; private static final int TANK_WIDTH = 50; private static final int TANK_TOP = TANK_HEIGHT; private static final int CANNON_WIDTH = 10; private static final int GUNBARREL_LENGTH = 46; private static final int STATUS_IDLE=0; private static final int STATUS_POWERING=1; private static final long POWERING_TIMER_LIMIT = 1200; private float angle; public static int cannonendx; public static int cannonendy; private int status; private long poweringtimer; private int power; private int lastbulletpower; public Tank(){ GameThread.tankImg=Bitmap.createBitmap(GameThread.tankImg); GameThread.cannonImg=Bitmap.createBitmap(GameThread.cannonImg); public void draw(canvas c) { c.drawbitmap(gamethread.tankimg, (320-TANK_WIDTH)/2, TANK_TOP, null); Matrix m = new Matrix(); m.posttranslate((320-cannon_width)/2, TANK_TOP - 30); m.postrotate((float) ((-angle)*180 /Math.PI),160,446); c.drawbitmap(gamethread.cannonimg, m, null); cannonendx = (int) (160 + (Math.cos(angle) * GUNBARREL_LENGTH)); cannonendy = (int) (446 - (Math.sin(angle) * GUNBARREL_LENGTH)); public void settarget(int x, int y) { if (x==160) angle=0; else{ if(y>=446){ angle=(float)math.pi/2; if(x>160) angle-=2*angle; else Page 42 of 68
43 angle = (float) Math.atan((float)(x-160)/(float)(y-446)); public void update(long elapsedtime){ if (status == STATUS_POWERING){ poweringtimer=poweringtimer+elapsedtime; if (poweringtimer>powering_timer_limit) poweringtimer=powering_timer_limit; power = (int) (((float)poweringtimer / POWERING_TIMER_LIMIT) *100); public void pressfire( ) { status = STATUS_POWERING; power = 0; poweringtimer = 0; public void releasefire() { GameThread.shootBullet(angle+(float)Math.PI/2,40+power*60/100,160,446); lastbulletpower = power; status = STATUS_IDLE; power = 0; public int getpower() { return power; public float getangle() { return angle; public int getlastbulletpower() { return lastbulletpower; At this point our game is complete: we have a Tank that shoots Bullets against Ufo(s) and all the information is shown by a Hud. But we want to make our game more intriguing so let s proceed with the last step. Page 43 of 68
44 Step 6 Sounds Let s add some sounds to improve quality and fun! An obvious pre- requirement for this step is to actually have the sound for: the main theme of gameplay; the shoot; the motion of the cannon; the explosion of the enemy. Once we found/created this sounds, we can design a new class for managing the sounds. 1) In src folder go inside your package (for this step the package has been renamed to pmm.antiaircraft6) and create a new class called SoundManager. 2) In the constructor the sounds are loaded. 3) There are specific methods to play the different sounds. 4) There is a method called update to restart the main theme and manage the sound of the cannon motion. The code of the class is provided here. package pmm.antiaircraft6; import android.content.context; import android.media.audiomanager; import android.media.mediaplayer; import android.media.soundpool; public class SoundManager { Page 44 of 68
45 private static SoundPool sounds; private static int shoot; private static int explode; private static int movegun; private static boolean movegunplaying ; private static long moveguntimer; private static MediaPlayer musictheme; private static int theme; public static void loadsound(context context) { movegunplaying = false; sounds = new SoundPool(5, AudioManager.STREAM_MUSIC, 0); shoot = sounds.load(context, R.raw.shoot, 1); explode = sounds.load(context, R.raw.explode, 1); movegun = sounds.load(context, R.raw.movegun, 1); musictheme = MediaPlayer.create(context, R.raw.theme); public static final void playmusictheme() { if (!musictheme.isplaying()) { musictheme.seekto(0); musictheme.start(); public static final void pausemusic() { if (musictheme.isplaying()) musictheme.pause(); public static void playshoot() { sounds.play(shoot, 1, 1, 1, 0, 1); public static void playexplode() { sounds.play(explode, 1, 1, 1, 0, 1); public static void playmovegun() { if (!movegunplaying){ sounds.play(movegun, 1, 1, 1, 0, 1); movegunplaying = true; moveguntimer=0; public static void update(long time){ playmusictheme(); if (movegunplaying){ moveguntimer+=time; if (moveguntimer>302){ movegunplaying=false; moveguntimer=0; Page 45 of 68
46 Now we can invoke this methods in the other classes. In GameThread. 1) We create an instance of the SoundManager when the thread is created. 2) During his run we invoke update. 3) When we shoot a bullet we playshoot. The final GameThread class his the following one. package pmm.antiaircraft6; import java.util.arraylist; import java.util.iterator; import java.util.concurrent.arrayblockingqueue; import android.content.context; import android.content.res.resources; import android.graphics.bitmap; import android.graphics.bitmapfactory; import android.graphics.canvas; import android.os.handler; import android.util.displaymetrics; import android.view.surfaceholder; public class GameThread extends Thread { private SurfaceHolder msurfaceholder; public DisplayMetrics metrics = new DisplayMetrics(); private static Bitmap mbackgroundimage; public static Bitmap tankimg; public static Bitmap cannonimg; public static Bitmap ufoimg; public static boolean mrun = false; private Tank tank; public static Resources res; private Object inputqueuemutex = new Object(); private ArrayBlockingQueue<InputObject> inputqueue = new ArrayBlockingQueue<InputObject>(30); private static ArrayList<Bullet> bullets; private static ArrayList<Ufo> ufos; private long lastupdatetime; private long newufotimer; private Hud hud; public GameThread(SurfaceHolder surfaceholder, Context context, Handler handler) { msurfaceholder = surfaceholder; Resources res = context.getresources(); mbackgroundimage = BitmapFactory.decodeResource(res,R.drawable.background); tankimg = BitmapFactory.decodeResource(res,R.drawable.tank); cannonimg = BitmapFactory.decodeResource(res,R.drawable.cannon); ufoimg= BitmapFactory.decodeResource(res,R.drawable.ufo); bullets = new ArrayList<Bullet>(); ufos = new ArrayList<Ufo>(); SoundManager.loadSound(context); Page 46 of 68
47 @Override public void run() { while (mrun) { Canvas c = null; try { c = msurfaceholder.lockcanvas(null); synchronized (msurfaceholder) { long currenttime = System.currentTimeMillis(); long delta = (long) (currenttime - lastupdatetime); lastupdatetime = currenttime; processinput(); updatephysics(delta); SoundManager.update(delta); draw(c); finally { if (c!= null) { msurfaceholder.unlockcanvasandpost(c); public void setrunning(boolean b) { mrun = b; private void draw(canvas canvas) { canvas.drawbitmap(mbackgroundimage, 0, 0, null); for(iterator<bullet> it = bullets.iterator();it.hasnext();){ Bullet b = (Bullet) it.next(); if (b!=null) b.draw(canvas); for(iterator<ufo> it = ufos.iterator();it.hasnext();){ Ufo a = (Ufo) it.next(); if (a!=null) a.draw(canvas); tank.draw(canvas); hud.draw(canvas); public void creategraphics() { mbackgroundimage=bitmap.createbitmap(mbackgroundimage); tank = new Tank(); hud = new Hud(); hud.register(tank); private void updatephysics(long timer) { timer=(long) (timer); tank.update(timer); Bullet b ; Page 47 of 68
48 int i=0; while (!bullets.isempty() && bullets.size()>i){ b = bullets.get(i); if (b.isover()) bullets.remove(i); else { b.update(timer); i++; Ufo a ; i=0; while (!ufos.isempty() && ufos.size()>i){ a = ufos.get(i); if (a.isover()) ufos.remove(i); else { a.update(timer); int j=0; while (j<bullets.size()){ b = bullets.get(j); if (a.isflying() && b.isflying()) if(a.impactdetected(b)){ hud.addimpact(); a.setimpact(); b.setimpact(); ufos.add(new Ufo()); j++; i++; newufotimer+=timer; if (newufotimer>3000){ ufos.add(new Ufo()); newufotimer=0; public void feedinput(inputobject input) { synchronized(inputqueuemutex) { try { inputqueue.put(input); catch (InterruptedException e) { private void processinput() { synchronized(inputqueuemutex) { ArrayBlockingQueue<InputObject> inputqueue = this.inputqueue; while (!inputqueue.isempty()) { try { InputObject input = inputqueue.take(); if (input.eventtype == InputObject.EVENT_TYPE_TOUCH) { Page 48 of 68
49 processmotionevent(input); input.returntopool(); catch (InterruptedException e) { private void processmotionevent(inputobject input) { if( input.action==inputobject.action_touch_down){ tank.pressfire(); tank.settarget(input.x, input.y); if( input.action==inputobject.action_touch_up){ tank.settarget(input.x, input.y); tank.releasefire(); if( input.action==inputobject.action_touch_move) tank.settarget(input.x, input.y); public static void shootbullet(float angle, int power,int x, int y) { bullets.add(new Bullet(power, angle, x, y)); SoundManager.playShoot(); In Tank. 1) When we set the new target we calculate the difference between the previous and the actual angle and if it is not 0 then we playmovegun. The final class for Tank follows here. package pmm.antiaircraft6; import android.graphics.bitmap; import android.graphics.canvas; import android.graphics.matrix; public class Tank { private static final int TANK_HEIGHT = 50; private static final int TANK_WIDTH = 50; private static final int TANK_TOP = TANK_HEIGHT; private static final int CANNON_WIDTH = 10; private static final int GUNBARREL_LENGTH = 46; private static final int STATUS_IDLE=0; private static final int STATUS_POWERING=1; private static final long POWERING_TIMER_LIMIT = 1200; private float angle; public static int cannonendx; public static int cannonendy; private int status; private long poweringtimer; private int power; Page 49 of 68
50 private int lastbulletpower; public Tank(){ GameThread.tankImg=Bitmap.createBitmap(GameThread.tankImg); GameThread.cannonImg=Bitmap.createBitmap(GameThread.cannonImg); public void draw(canvas c) { c.drawbitmap(gamethread.tankimg, (320-TANK_WIDTH)/2, TANK_TOP, null); Matrix m = new Matrix(); m.posttranslate((320-cannon_width)/2, TANK_TOP - 30); m.postrotate((float) ((-angle)*180 /Math.PI),160,446); c.drawbitmap(gamethread.cannonimg, m, null); cannonendx = (int) (160 + (Math.cos(angle) * GUNBARREL_LENGTH)); cannonendy = (int) (446 - (Math.sin(angle) * GUNBARREL_LENGTH)); public void settarget(int x, int y) { float previousangle=angle; if (x==160) angle=0; else{ if(y>=446){ angle=(float)math.pi/2; if(x>160) angle-=2*angle; else angle = (float) Math.atan((float)(x-160)/(float)(y-446)); if (Math.abs( (int) ((previousangle-angle)*180/math.pi))>0) SoundManager.playMovegun(); public void update(long elapsedtime){ if (status == STATUS_POWERING){ poweringtimer=poweringtimer+elapsedtime; if (poweringtimer>powering_timer_limit) poweringtimer=powering_timer_limit; power = (int) (((float)poweringtimer / POWERING_TIMER_LIMIT) *100); public void pressfire( ) { status = STATUS_POWERING; power = 0; poweringtimer = 0; public void releasefire() { GameThread.shootBullet(angle+(float)Math.PI/2,40+power*60/100,160,446); lastbulletpower = power; status = STATUS_IDLE; power = 0; public int getpower() { Page 50 of 68
51 return power; public float getangle() { return angle; public int getlastbulletpower() { return lastbulletpower; In Ufo 1) When an impact is detected playexplode has to be invoked. The final Ufo class is the following. package pmm.antiaircraft6; import android.graphics.bitmap; import android.graphics.canvas; import android.graphics.matrix; public class Ufo { private static final int STATUS_FLYING = 0; private static final int STATUS_OVER = 1; private static final float TIME_FLYING = 5; private float lowerposition; private long time; private int status; private float posx; private float posy; private double inispeedx; private double inispeedy; private float posx0; private float drawx; private float drawy; private int angle; private int direction; private static float acceleration; public Ufo(){ time = 0; angle = 0; status = STATUS_FLYING; direction = (Math.random()<0.5?1:-1); posx0 = (float) (160 + (320*-direction*Math.random())); lowerposition = 480; acceleration = (float) (lowerposition/math.pow(time_flying/2,2)); inispeedx = (320 / TIME_FLYING); inispeedy = (TIME_FLYING * acceleration / 2) - 1 / TIME_FLYING; Page 51 of 68
52 GameThread.ufoImg = Bitmap.createBitmap(GameThread.ufoImg); public void draw(canvas c) { Matrix m = new Matrix(); m.posttranslate(drawx, drawy); if (status == STATUS_FLYING) c.drawbitmap(gamethread.ufoimg, m, null); public void update(long elapsedtime) { double t2; switch (status){ case STATUS_FLYING: time+=elapsedtime; t2=(double)(time)/1000; posx = (float) (posx0 + inispeedx*t2*direction); posy = (float) (inispeedy * t2 - (acceleration/2 * Math.pow(t2,2) )); angle = (direction>0?180:0) + (int) (Math.atan((iniSpeedYacceleration*t2)/iniSpeedX*direction)*180/Math.PI); if (posy<0) status=status_over; break; drawx = posx - 30; drawy = posy - 20; public boolean isover() { return (status==status_over); public boolean isflying(){ return (status == STATUS_FLYING); public boolean impactdetected(bullet b) { boolean impact = false; float diffx=math.abs(posx-b.getposx()); float diffy=math.abs(posy-b.getposy()); if (diffx<19 && diffy<19){ impact = true; SoundManager.playExplode(); return impact; public void setimpact(){ status = STATUS_OVER; Now we can play our game with sounds. That s great! Page 52 of 68
53 5 Further improvement There are a lot of possible improvements that allow the reader to improve their skills as Android developers. Among the others: scale graphics to allow more screen resolutions; create different enemies with different abilities and different rewards; allow buying of tank upgrades (different bullets, different cannons, etc.); move the tank. 6 Conclusions In this tutorial we have moved the firsts steps of Android development, learning what is necessary to download and how to set up the software artefacts. Then we learnt some Android programming techniques and we created, step by step, a non- trivial application. In particular the reader should now have understood how to: create and run projects using Android emulators; create Activities; manage Views; use custom graphics; place objects; interact with touch events; Page 53 of 68
54 display information on screen; manage interaction between game elements; use sounds. A list of possible improvements has been provided in order to encourage the user to deepen Android SDK and tools. Page 54 of 68
55 Appendix Final classes code The final classes are reported here to allow the user to access the final code quickly without the need to go back and forth. Bullet package pmm.antiaircraft6; import android.graphics.canvas; import android.graphics.color; import android.graphics.paint; public class Bullet { private static final int STATUS_FLYING = 0; private static final int STATUS_BOOM = 1; private static final int STATUS_OVER = 2; private static final int BULLET_RADIUS = 4; private static final long TIME_EXPLODING = 100; private long time; private int status; private int power; private float posx0; private float posy0; private float posx; private float posy; private float inispeedx; private float inispeedy; private Paint paint; private long explodingtimer; public Bullet(int power,float angle,int x0,int y0){ time=0; paint = new Paint(); this.power = power; posx0 = x0; posy0 = y0; inispeedy=(float) (Math.sin(angle)*power*1.5) ; inispeedx=(float) (Math.cos(angle)*power*1.5); public void draw(canvas c) { paint.setcolor(color.red); if (status == STATUS_FLYING) paint.setcolor(color.black); c.drawcircle(posx, posy, BULLET_RADIUS, paint); public void update(long elapsedtime) { switch (status){ Page 55 of 68
56 case STATUS_FLYING: time+=elapsedtime; double t2=(double)(time)/100; posx=(float) (posx0 + inispeedx*t2); posy=(float) (posy0 - (inispeedy*t2 - (9.8 *Math.pow(t2, 2)/2))); if (posy>=480) { status=status_boom; posy = 480; explodingtimer = 0; break; case STATUS_BOOM: explodingtimer+=elapsedtime; if (explodingtimer>time_exploding) status=status_over; break; public void setimpact(){ status = STATUS_BOOM; explodingtimer=0; public float getposx() { return posx; public float getposy() { return posy; public boolean isflying(){ return (status == STATUS_FLYING); public boolean isexploding() { return (status==status_boom); public boolean isover() { return (status==status_over); GameActivity package pmm.antiaircraft6; import java.util.concurrent.arrayblockingqueue; import android.app.activity; import android.view.motionevent; import android.view.window; Page 56 of 68
57 import android.view.windowmanager; public class GameActivity extends Activity{ private GameThread mgamethread; public static final int INPUT_QUEUE_SIZE = 30; public ArrayBlockingQueue<InputObject> inputobjectpool; public void onstart() { super.onstart(); requestwindowfeature(window.feature_no_title); getwindow().setflags(windowmanager.layoutparams.flag_fullscreen, WindowManager.LayoutParams.FLAG_FULLSCREEN); setcontentview(r.layout.main); mgamethread = ((GameView) findviewbyid(r.id.game)).getthread(); mgamethread.creategraphics(); createinputobjectpool(); private void createinputobjectpool() { inputobjectpool = new ArrayBlockingQueue<InputObject>(INPUT_QUEUE_SIZE); for (int i = 0; i < INPUT_QUEUE_SIZE; i++) { inputobjectpool.add(new public boolean ontouchevent(motionevent event) { try { int hist = event.gethistorysize(); for (int i = 0; i < hist; i++) { InputObject input = inputobjectpool.take(); input.useeventhistory(event, i); mgamethread.feedinput(input); InputObject input = inputobjectpool.take(); input.useevent(event); mgamethread.feedinput(input); catch (InterruptedException e) { try { Thread.sleep(16); catch (InterruptedException e) { return true; GameThread package pmm.antiaircraft6; import java.util.arraylist; import java.util.iterator; import java.util.concurrent.arrayblockingqueue; Page 57 of 68
58 import android.content.context; import android.content.res.resources; import android.graphics.bitmap; import android.graphics.bitmapfactory; import android.graphics.canvas; import android.os.handler; import android.util.displaymetrics; import android.view.surfaceholder; public class GameThread extends Thread { private SurfaceHolder msurfaceholder; public DisplayMetrics metrics = new DisplayMetrics(); private static Bitmap mbackgroundimage; public static Bitmap tankimg; public static Bitmap cannonimg; public static Bitmap ufoimg; public static boolean mrun = false; private Tank tank; public static Resources res; private Object inputqueuemutex = new Object(); private ArrayBlockingQueue<InputObject> inputqueue = new ArrayBlockingQueue<InputObject>(30); private static ArrayList<Bullet> bullets; private static ArrayList<Ufo> ufos; private long lastupdatetime; private long newufotimer; private Hud hud; public GameThread(SurfaceHolder surfaceholder, Context context, Handler handler) { msurfaceholder = surfaceholder; Resources res = context.getresources(); mbackgroundimage = BitmapFactory.decodeResource(res,R.drawable.background); tankimg = BitmapFactory.decodeResource(res,R.drawable.tank); cannonimg = BitmapFactory.decodeResource(res,R.drawable.cannon); ufoimg= BitmapFactory.decodeResource(res,R.drawable.ufo); bullets = new ArrayList<Bullet>(); ufos = new ArrayList<Ufo>(); public void run() { while (mrun) { Canvas c = null; try { c = msurfaceholder.lockcanvas(null); synchronized (msurfaceholder) { long currenttime = System.currentTimeMillis(); long delta = (long) (currenttime - lastupdatetime); lastupdatetime = currenttime; processinput(); updatephysics(delta); SoundManager.update(delta); draw(c); finally { if (c!= null) { Page 58 of 68
59 msurfaceholder.unlockcanvasandpost(c); public void setrunning(boolean b) { mrun = b; private void draw(canvas canvas) { canvas.drawbitmap(mbackgroundimage, 0, 0, null); for(iterator<bullet> it = bullets.iterator();it.hasnext();){ Bullet b = (Bullet) it.next(); if (b!=null) b.draw(canvas); for(iterator<ufo> it = ufos.iterator();it.hasnext();){ Ufo a = (Ufo) it.next(); if (a!=null) a.draw(canvas); tank.draw(canvas); hud.draw(canvas); public void creategraphics() { mbackgroundimage=bitmap.createbitmap(mbackgroundimage); tank = new Tank(); hud = new Hud(); hud.register(tank); private void updatephysics(long timer) { timer=(long) (timer); tank.update(timer); Bullet b ; int i=0; while (!bullets.isempty() && bullets.size()>i){ b = bullets.get(i); if (b.isover()) bullets.remove(i); else { b.update(timer); i++; Ufo a ; i=0; while (!ufos.isempty() && ufos.size()>i){ a = ufos.get(i); if (a.isover()) ufos.remove(i); else { Page 59 of 68
60 a.update(timer); int j=0; while (j<bullets.size()){ b = bullets.get(j); if (a.isflying() && b.isflying()) if(a.impactdetected(b)){ hud.addimpact(); a.setimpact(); b.setimpact(); ufos.add(new Ufo()); j++; i++; newufotimer+=timer; if (newufotimer>3000){ ufos.add(new Ufo()); newufotimer=0; public void feedinput(inputobject input) { synchronized(inputqueuemutex) { try { inputqueue.put(input); catch (InterruptedException e) { private void processinput() { synchronized(inputqueuemutex) { ArrayBlockingQueue<InputObject> inputqueue = this.inputqueue; while (!inputqueue.isempty()) { try { InputObject input = inputqueue.take(); if (input.eventtype == InputObject.EVENT_TYPE_TOUCH) { processmotionevent(input); input.returntopool(); catch (InterruptedException e) { private void processmotionevent(inputobject input) { if( input.action==inputobject.action_touch_down){ tank.pressfire(); tank.settarget(input.x, input.y); if( input.action==inputobject.action_touch_up){ tank.settarget(input.x, input.y); tank.releasefire(); Page 60 of 68
61 if( input.action==inputobject.action_touch_move) tank.settarget(input.x, input.y); public static void shootbullet(float angle, int power,int x, int y) { bullets.add(new Bullet(power, angle, x, y)); SoundManager.playShoot(); GameView package pmm.antiaircraft6; import android.content.context; import android.util.attributeset; import android.view.surfaceholder; import android.view.surfaceview; public class GameView extends SurfaceView implements SurfaceHolder.Callback { private GameThread thread; public GameView(Context context, AttributeSet attrs) { super(context, attrs); SurfaceHolder holder = getholder(); holder.addcallback(this); thread = new GameThread(holder, context,null); public GameThread getthread() { return thread; public void surfacecreated(surfaceholder holder) { thread.setrunning(true); public void surfacechanged(surfaceholder holder, int format, int width, int height) public void surfacedestroyed(surfaceholder holder) { Hud package pmm.antiaircraft6; import android.graphics.canvas; import android.graphics.color; import android.graphics.lineargradient; import android.graphics.paint; import android.graphics.paint.style; Page 61 of 68
62 import android.graphics.rectf; import android.graphics.shader; public class Hud { private static final int BAR_POWER_LEFT_MARGIN = 10; private static final int BAR_POWER_RIGHT_MARGIN = 200; private static final int BAR_POWER_BOTTOM_MARGIN = 10; private static final int BAR_POWER_HEIGHT = 10; private static final int TEXT_INFO_LEFT_MARGIN = 10; private static final int TEXT_ANGLE_TOP_MARGIN = 25; private static final int TEXT_POWER_TOP_MARGIN = 50; private static final int TEXT_COUNTER_TOP_MARGIN = 75; private static final int TEXT_SIZE = 20; private float barpwrleft; private float barpwrtop; private float barpwrright; private float barpwrbottom; private int impactcounter; LinearGradient gradient; Paint paint; private Tank tank; public Hud(){ paint = new Paint(); barpwrleft = BAR_POWER_LEFT_MARGIN; barpwrtop = BAR_POWER_BOTTOM_MARGIN - BAR_POWER_HEIGHT; barpwrright = BAR_POWER_RIGHT_MARGIN; barpwrbottom = BAR_POWER_HEIGHT; impactcounter =0; gradient= new LinearGradient (barpwrleft, barpwrtop, barpwrright, barpwrtop, new int[]{color.green,color.yellow, Color.RED,null, Shader.TileMode.CLAMP); public void draw(canvas c){ int progress = ((int) (barpwrleft + tank.getpower() * (barpwrrightbarpwrleft) /100)); paint.setalpha(255); paint.setshader(gradient); paint.setstyle(style.fill); c.drawroundrect(new RectF(barPwrLeft, barpwrtop, progress, barpwrbottom), 4, 4, paint); paint.setshader(null); paint.setstyle(style.stroke); paint.setcolor(color.black); paint.setstrokewidth(0); c.drawroundrect(new RectF(barPwrLeft, barpwrtop, barpwrright, barpwrbottom), 4, 4, paint); paint.setcolor(color.black); paint.setstyle(paint.style.stroke); paint.setstrokewidth(0); paint.setantialias(true); paint.settextsize(text_size); int powerinfo=(tank.getpower()==0?tank.getlastbulletpower():tank.getpower()); c.drawtext("angle: "+Math.abs((int) (tank.getangle()*180/math.pi))+"º", Page 62 of 68
63 TEXT_INFO_LEFT_MARGIN, TEXT_ANGLE_TOP_MARGIN, paint); c.drawtext("power: "+powerinfo, TEXT_INFO_LEFT_MARGIN, TEXT_POWER_TOP_MARGIN, paint); c.drawtext("impacts: "+impactcounter, TEXT_INFO_LEFT_MARGIN, TEXT_COUNTER_TOP_MARGIN, paint); public void register(tank tank) { this.tank = tank; public void addimpact() { impactcounter++; InputObject package pmm.antiaircraft6; import java.util.concurrent.arrayblockingqueue; import android.view.motionevent; public class InputObject { public static final byte EVENT_TYPE_KEY = 1; public static final byte EVENT_TYPE_TOUCH = 2; public static final int ACTION_KEY_DOWN = 1; public static final int ACTION_KEY_UP = 2; public static final int ACTION_TOUCH_DOWN = 3; public static final int ACTION_TOUCH_MOVE = 4; public static final int ACTION_TOUCH_UP = 5; public ArrayBlockingQueue<InputObject> pool; public byte eventtype; public long time; public int action; public int keycode; public int x; public int y; public InputObject(ArrayBlockingQueue<InputObject> pool) { this.pool = pool; public void useevent(motionevent event) { eventtype = EVENT_TYPE_TOUCH; int a = event.getaction(); switch (a) { case MotionEvent.ACTION_DOWN: action = ACTION_TOUCH_DOWN; break; case MotionEvent.ACTION_MOVE: action = ACTION_TOUCH_MOVE; break; case MotionEvent.ACTION_UP: action = ACTION_TOUCH_UP; break; Page 63 of 68
64 default: action = 0; time = event.geteventtime(); x = (int) event.getx() ; y = (int) event.gety(); public void useeventhistory(motionevent event, int historyitem) { eventtype = EVENT_TYPE_TOUCH; action = ACTION_TOUCH_MOVE; time = event.gethistoricaleventtime(historyitem); x = (int) event.gethistoricalx(historyitem); y = (int) event.gethistoricaly(historyitem); public void returntopool() { pool.add(this); SoundManager package pmm.antiaircraft6; import android.content.context; import android.media.audiomanager; import android.media.mediaplayer; import android.media.soundpool; public class SoundManager { private static SoundPool sounds; private static int shoot; private static int explode; private static int movegun; private static boolean movegunplaying ; private static long moveguntimer; private static MediaPlayer musictheme; private static int theme; public static void loadsound(context context) { movegunplaying = false; sounds = new SoundPool(5, AudioManager.STREAM_MUSIC, 0); shoot = sounds.load(context, R.raw.shoot, 1); explode = sounds.load(context, R.raw.explode, 1); movegun = sounds.load(context, R.raw.movegun, 1); musictheme = MediaPlayer.create(context, R.raw.theme); public static final void playmusictheme() { if (!musictheme.isplaying()) { musictheme.seekto(0); musictheme.start(); Page 64 of 68
65 public static final void pausemusic() { if (musictheme.isplaying()) musictheme.pause(); public static void playshoot() { sounds.play(shoot, 1, 1, 1, 0, 1); public static void playexplode() { sounds.play(explode, 1, 1, 1, 0, 1); public static void playmovegun() { if (!movegunplaying){ sounds.play(movegun, 1, 1, 1, 0, 1); movegunplaying = true; moveguntimer=0; public static void update(long time){ playmusictheme(); if (movegunplaying){ moveguntimer+=time; if (moveguntimer>302){ movegunplaying=false; moveguntimer=0; Tank package pmm.antiaircraft6; import android.graphics.bitmap; import android.graphics.canvas; import android.graphics.matrix; public class Tank { private static final int TANK_HEIGHT = 50; private static final int TANK_WIDTH = 50; private static final int TANK_TOP = TANK_HEIGHT; private static final int CANNON_WIDTH = 10; private static final int GUNBARREL_LENGTH = 46; private static final int STATUS_IDLE=0; private static final int STATUS_POWERING=1; private static final long POWERING_TIMER_LIMIT = 1200; private float angle; public static int cannonendx; public static int cannonendy; private int status; Page 65 of 68
66 private long poweringtimer; private int power; private int lastbulletpower; public Tank(){ GameThread.tankImg=Bitmap.createBitmap(GameThread.tankImg); GameThread.cannonImg=Bitmap.createBitmap(GameThread.cannonImg); public void draw(canvas c) { c.drawbitmap(gamethread.tankimg, (320-TANK_WIDTH)/2, TANK_TOP, null); Matrix m = new Matrix(); m.posttranslate((320-cannon_width)/2, TANK_TOP - 30); m.postrotate((float) ((-angle)*180 /Math.PI),160,446); c.drawbitmap(gamethread.cannonimg, m, null); cannonendx = (int) (160 + (Math.cos(angle) * GUNBARREL_LENGTH)); cannonendy = (int) (446 - (Math.sin(angle) * GUNBARREL_LENGTH)); public void settarget(int x, int y) { float previousangle=angle; if (x==160) angle=0; else{ if(y>=446){ angle=(float)math.pi/2; if(x>160) angle-=2*angle; else angle = (float) Math.atan((float)(x-160)/(float)(y-446)); if (Math.abs( (int) ((previousangle-angle)*180/math.pi))>0) SoundManager.playMovegun(); public void update(long elapsedtime){ if (status == STATUS_POWERING){ poweringtimer=poweringtimer+elapsedtime; if (poweringtimer>powering_timer_limit) poweringtimer=powering_timer_limit; power = (int) (((float)poweringtimer / POWERING_TIMER_LIMIT) *100); public void pressfire( ) { status = STATUS_POWERING; power = 0; poweringtimer = 0; public void releasefire() { GameThread.shootBullet(angle+(float)Math.PI/2,40+power*60/100,160,446); lastbulletpower = power; status = STATUS_IDLE; power = 0; Page 66 of 68
67 public int getpower() { return power; public float getangle() { return angle; public int getlastbulletpower() { return lastbulletpower; Ufo package pmm.antiaircraft6; import android.graphics.bitmap; import android.graphics.canvas; import android.graphics.matrix; public class Ufo { private static final int STATUS_FLYING = 0; private static final int STATUS_OVER = 1; private static final float TIME_FLYING = 5; private float lowerposition; private long time; private int status; private float posx; private float posy; private double inispeedx; private double inispeedy; private float posx0; private float drawx; private float drawy; private int angle; private int direction; private static float acceleration; public Ufo(){ time = 0; angle = 0; status = STATUS_FLYING; direction = (Math.random()<0.5?1:-1); posx0 = (float) (160 + (320*-direction*Math.random())); lowerposition = 480; acceleration = (float) (lowerposition/math.pow(time_flying/2,2)); inispeedx = (320 / TIME_FLYING); inispeedy = (TIME_FLYING * acceleration / 2) - 1 / TIME_FLYING; GameThread.ufoImg = Bitmap.createBitmap(GameThread.ufoImg); Page 67 of 68
68 public void draw(canvas c) { Matrix m = new Matrix(); m.posttranslate(drawx, drawy); if (status == STATUS_FLYING) c.drawbitmap(gamethread.ufoimg, m, null); public void update(long elapsedtime) { double t2; switch (status){ case STATUS_FLYING: time+=elapsedtime; t2=(double)(time)/1000; posx = (float) (posx0 + inispeedx*t2*direction); posy = (float) (inispeedy * t2 - (acceleration/2 * Math.pow(t2,2) )); angle = (direction>0?180:0) + (int) (Math.atan((iniSpeedYacceleration*t2)/iniSpeedX*direction)*180/Math.PI); if (posy<0) status=status_over; break; drawx = posx - 30; drawy = posy - 20; public boolean isover() { return (status==status_over); public boolean isflying(){ return (status == STATUS_FLYING); public boolean impactdetected(bullet b) { boolean impact = false; float diffx=math.abs(posx-b.getposx()); float diffy=math.abs(posy-b.getposy()); if (diffx<19 && diffy<19){ impact = true; SoundManager.playExplode(); return impact; public void setimpact(){ status = STATUS_OVER; Page 68 of 68
How to develop your own app
How to develop your own app It s important that everything on the hardware side and also on the software side of our Android-to-serial converter should be as simple as possible. We have the advantage that
ADT Plugin for Eclipse
ADT Plugin for Eclipse Android Development Tools (ADT) is a plugin for the Eclipse IDE that is designed to give you a powerful, integrated environment in which to build Android applications. ADT extends
Android Environment SDK
Part 2-a Android Environment SDK Victor Matos Cleveland State University Notes are based on: Android Developers http://developer.android.com/index.html 1 2A. Android Environment: Eclipse & ADT The Android
How to build your first Android Application in Windows
APPLICATION NOTE How to build your first Android Application in Windows 3/30/2012 Created by: Micah Zastrow Abstract This application note is designed to teach the reader how to setup the Android Development
Advantages. manage port forwarding, set breakpoints, and view thread and process information directly
Part 2 a Android Environment SDK Victor Matos Cleveland State University Notes are based on: Android Developers http://developer.android.com/index.html 1 Android Environment: Eclipse & ADT The Android
Mocean Android SDK Developer Guide
Mocean Android SDK Developer Guide For Android SDK Version 3.2 136 Baxter St, New York, NY 10013 Page 1 Table of Contents Table of Contents... 2 Overview... 3 Section 1 Setup... 3 What changed in 3.2:...
Android Environment SDK
Part 2-a Android Environment SDK Victor Matos Cleveland State University Notes are based on: Android Developers http://developer.android.com/index.html 1 Android Environment: Eclipse & ADT The Android
Android Application Development: Hands- On. Dr. Jogesh K. Muppala [email protected]
Android Application Development: Hands- On Dr. Jogesh K. Muppala [email protected] Wi-Fi Access Wi-Fi Access Account Name: aadc201312 2 The Android Wave! 3 Hello, Android! Configure the Android SDK SDK
MMI 2: Mobile Human- Computer Interaction Android
MMI 2: Mobile Human- Computer Interaction Android Prof. Dr. [email protected] Mobile Interaction Lab, LMU München Android Software Stack Applications Java SDK Activities Views Resources Animation
Android Development Setup [Revision Date: 02/16/11]
Android Development Setup [Revision Date: 02/16/11] 0. Java : Go to the URL below to access the Java SE Download page: http://www.oracle.com/technetwork/java/javase/downloads/index.html Select Java Platform,
How To Develop An Android App On An Android Device
Lesson 2 Android Development Tools = Eclipse + ADT + SDK Victor Matos Cleveland State University Portions of this page are reproduced from work created and shared by Googleand used according to terms described
Android Development Tutorial. Nikhil Yadav CSE40816/60816 - Pervasive Health Fall 2011
Android Development Tutorial Nikhil Yadav CSE40816/60816 - Pervasive Health Fall 2011 Database connections Local SQLite and remote access Outline Setting up the Android Development Environment (Windows)
ANDROID APPS DEVELOPMENT FOR MOBILE AND TABLET DEVICE (LEVEL I)
ANDROID APPS DEVELOPMENT FOR MOBILE AND TABLET DEVICE (LEVEL I) Who am I? Lo Chi Wing, Peter Lecture 1: Introduction to Android Development Email: [email protected] Facebook: http://www.facebook.com/peterlo111
Creating a 2D Game Engine for Android OS. Introduction
Creating a 2D Game Engine for Android OS Introduction This tutorial will lead you through the foundations of creating a 2D animated game for the Android Operating System. The goal here is not to create
Getting Started with Android Development
Getting Started with Android Development By Steven Castellucci (v1.1, January 2015) You don't always need to be in the PRISM lab to work on your 4443 assignments. Working on your own computer is convenient
Mobile Application Development
Mobile Application Development (Android & ios) Tutorial Emirates Skills 2015 3/26/2015 1 What is Android? An open source Linux-based operating system intended for mobile computing platforms Includes a
Android Development. http://developer.android.com/develop/ 吳 俊 興 國 立 高 雄 大 學 資 訊 工 程 學 系
Android Development http://developer.android.com/develop/ 吳 俊 興 國 立 高 雄 大 學 資 訊 工 程 學 系 Android 3D 1. Design 2. Develop Training API Guides Reference 3. Distribute 2 Development Training Get Started Building
directory to "d:\myproject\android". Hereafter, I shall denote the android installed directory as
1 of 6 2011-03-01 12:16 AM yet another insignificant programming notes... HOME Android SDK 2.2 How to Install and Get Started Introduction Android is a mobile operating system developed by Google, which
Tutorial for developing the Snake Game in Android: What is Android?
Tutorial for developing the Snake Game in Android: What is Android? Android is a software stack for mobile devices that includes an operating system, middleware and key applications. The Android SDK provides
Getting Started: Creating a Simple App
Getting Started: Creating a Simple App What You will Learn: Setting up your development environment Creating a simple app Personalizing your app Running your app on an emulator The goal of this hour is
ECWM511 MOBILE APPLICATION DEVELOPMENT Lecture 1: Introduction to Android
Why Android? ECWM511 MOBILE APPLICATION DEVELOPMENT Lecture 1: Introduction to Android Dr Dimitris C. Dracopoulos A truly open, free development platform based on Linux and open source A component-based
Now that we have the Android SDK, Eclipse and Phones all ready to go we can jump into actual Android development.
Android Development 101 Now that we have the Android SDK, Eclipse and Phones all ready to go we can jump into actual Android development. Activity In Android, each application (and perhaps each screen
PubMatic Android SDK. Developer Guide. For Android SDK Version 4.3.5
PubMatic Android SDK Developer Guide For Android SDK Version 4.3.5 Nov 25, 2015 1 2015 PubMatic Inc. All rights reserved. Copyright herein is expressly protected at common law, statute, and under various
Arduino & Android. A How to on interfacing these two devices. Bryant Tram
Arduino & Android A How to on interfacing these two devices Bryant Tram Contents 1 Overview... 2 2 Other Readings... 2 1. Android Debug Bridge -... 2 2. MicroBridge... 2 3. YouTube tutorial video series
Developing NFC Applications on the Android Platform. The Definitive Resource
Developing NFC Applications on the Android Platform The Definitive Resource Part 1 By Kyle Lampert Introduction This guide will use examples from Mac OS X, but the steps are easily adaptable for modern
Developing Android Applications Introduction to Software Engineering Fall 2015. Updated 7 October 2015
Developing Android Applications Introduction to Software Engineering Fall 2015 Updated 7 October 2015 Android Lab 1 Introduction to Android Class Assignment: Simple Android Calculator 2 Class Plan Introduction
Mobile App Sensor Documentation (English Version)
Mobile App Sensor Documentation (English Version) Mobile App Sensor Documentation (English Version) Version: 1.2.1 Date: 2015-03-25 Author: email: Kantar Media spring [email protected] Content Mobile App
Epidefender Studio Installation notice
Institut de Médecine et de Physiologie Spatiales Epidefender Studio Installation notice MEDES Institut de Médecine et Physiologie Spatiales CHU Rangueil - 1 avenue du Professeur Jean Poulhès - 31403 Toulouse
The first step is to upload the Helicopter images from a strip. 1) Click on Resources > Create Sprite 2) Name it spr_helicopter 3) Click Edit Sprite
GAME:IT Helicopter Objectives: Review skills in making directional sprites Create objects that shoot and destroy for points Create random enemies on the scene as game challenges Create random enemies on
Android Java Live and In Action
Android Java Live and In Action Norman McEntire Founder, Servin Corp UCSD Extension Instructor [email protected] Copyright (c) 2013 Servin Corp 1 Opening Remarks Welcome! Thank you! My promise
Hello World. by Elliot Khazon
Hello World by Elliot Khazon Prerequisites JAVA SDK 1.5 or 1.6 Windows XP (32-bit) or Vista (32- or 64-bit) 1 + more Gig of memory 1.7 Ghz+ CPU Tools Eclipse IDE 3.4 or 3.5 SDK starter package Installation
Android Tutorial. Larry Walters OOSE Fall 2011
Android Tutorial Larry Walters OOSE Fall 2011 References This tutorial is a brief overview of some major concepts Android is much richer and more complex Developer s Guide http://developer.android.com/guide/index.html
1. Introduction to Android
1. Introduction to Android Brief history of Android What is Android? Why is Android important? What benefits does Android have? What is OHA? Why to choose Android? Software architecture of Android Advantages
Mobile App Tutorial Animation with Custom View Class and Animated Object Bouncing and Frame Based Animation
Mobile App Tutorial Animation with Custom View Class and Animated Object Bouncing and Frame Based Animation Description of View Based Animation and Control-Model-View Design process In mobile device programming,
Dreamweaver and Fireworks MX Integration Brian Hogan
Dreamweaver and Fireworks MX Integration Brian Hogan This tutorial will take you through the necessary steps to create a template-based web site using Macromedia Dreamweaver and Macromedia Fireworks. The
Programming with Android: SDK install and initial setup. Dipartimento di Informatica: Scienza e Ingegneria Università di Bologna
Programming with Android: SDK install and initial setup Luca Bedogni Marco Di Felice Dipartimento di Informatica: Scienza e Ingegneria Università di Bologna SDK and initial setup: Outline Ø Today: How
Getting Started With Android
Getting Started With Android Author: Matthew Davis Date: 07/25/2010 Environment: Ubuntu 10.04 Lucid Lynx Eclipse 3.5.2 Android Development Tools(ADT) 0.9.7 HTC Incredible (Android 2.1) Preface This guide
Oracle FLEXCUBE Direct Banking Android Tab Client Installation Guide Release 12.0.3.0.0
Oracle FLEXCUBE Direct Banking Android Tab Client Installation Guide Release 12.0.3.0.0 Part No. E52543-01 April 2014 Oracle Financial Services Software Limited Oracle Park Off Western Express Highway
IOIO for Android Beginners Guide Introduction
IOIO for Android Beginners Guide Introduction This is the beginners guide for the IOIO for Android board and is intended for users that have never written an Android app. The goal of this tutorial is to
Getting Started with Android Programming (5 days) with Android 4.3 Jelly Bean
Getting Started with Android Programming (5 days) with Android 4.3 Jelly Bean Course Description Getting Started with Android Programming is designed to give students a strong foundation to develop apps
Login with Amazon Getting Started Guide for Android. Version 2.0
Getting Started Guide for Android Version 2.0 Login with Amazon: Getting Started Guide for Android Copyright 2016 Amazon.com, Inc., or its affiliates. All rights reserved. Amazon and the Amazon logo are
How to Set Up Your PC for Android Application Development
Introduction Application Note How to Set Up Your PC for Android Application Development Supported Environments: Windows 7 (32/64 bit), Windows Vista (32/64 bit), Windows XP * This application note was
Installing the Android SDK
Installing the Android SDK To get started with development, we first need to set up and configure our PCs for working with Java, and the Android SDK. We ll be installing and configuring four packages today
Affdex SDK for Android. Developer Guide For SDK version 1.0
Affdex SDK for Android Developer Guide For SDK version 1.0 www.affdex.com/mobile-sdk 1 August 4, 2014 Introduction The Affdex SDK is the culmination of years of scientific research into emotion detection,
An Introduction to 3D Computer Graphics, Stereoscopic Image, and Animation in OpenGL and C/C++ Fore June
An Introduction to 3D Computer Graphics, Stereoscopic Image, and Animation in OpenGL and C/C++ Fore June Appendix C Android Graphics C.1 Introduction If you were not shut off from the world in the past
! Sensors in Android devices. ! Motion sensors. ! Accelerometer. ! Gyroscope. ! Supports various sensor related tasks
CSC 472 / 372 Mobile Application Development for Android Prof. Xiaoping Jia School of Computing, CDM DePaul University [email protected] @DePaulSWEng Outline Sensors in Android devices Motion sensors
ID TECH UniMag Android SDK User Manual
ID TECH UniMag Android SDK User Manual 80110504-001-A 12/03/2010 Revision History Revision Description Date A Initial Release 12/03/2010 2 UniMag Android SDK User Manual Before using the ID TECH UniMag
Android Programming: 2D Drawing Part 1: Using ondraw
2012 Marty Hall Android Programming: 2D Drawing Part 1: Using ondraw Originals of Slides and Source Code for Examples: http://www.coreservlets.com/android-tutorial/ Customized Java EE Training: http://courses.coreservlets.com/
Chapter 2 Getting Started
Welcome to Android Chapter 2 Getting Started Android SDK contains: API Libraries Developer Tools Documentation Sample Code Best development environment is Eclipse with the Android Developer Tool (ADT)
Introduction to Android Development
2013 Introduction to Android Development Keshav Bahadoor An basic guide to setting up and building native Android applications Science Technology Workshop & Exposition University of Nigeria, Nsukka Keshav
Download and Installation Instructions. Android SDK and Android Development Tools (ADT) Microsoft Windows
Download and Installation Instructions for Android SDK and Android Development Tools (ADT) on Microsoft Windows Updated May, 2012 This document will describe how to download and install the Android SDK
Tutorial #1. Android Application Development Advanced Hello World App
Tutorial #1 Android Application Development Advanced Hello World App 1. Create a new Android Project 1. Open Eclipse 2. Click the menu File -> New -> Other. 3. Expand the Android folder and select Android
App Development for Smart Devices. Lec #2: Android Tools, Building Applications, and Activities
App Development for Smart Devices CS 495/595 - Fall 2011 Lec #2: Android Tools, Building Applications, and Activities Tamer Nadeem Dept. of Computer Science Objective Understand Android Tools Setup Android
Lab 0 (Setting up your Development Environment) Week 1
ECE155: Engineering Design with Embedded Systems Winter 2013 Lab 0 (Setting up your Development Environment) Week 1 Prepared by Kirill Morozov version 1.2 1 Objectives In this lab, you ll familiarize yourself
How to Create an Android Application using Eclipse on Windows 7
How to Create an Android Application using Eclipse on Windows 7 Kevin Gleason 11/11/11 This application note is design to teach the reader how to setup an Android Development Environment on a Windows 7
Android Introduction. Hello World. @2010 Mihail L. Sichitiu 1
Android Introduction Hello World @2010 Mihail L. Sichitiu 1 Goal Create a very simple application Run it on a real device Run it on the emulator Examine its structure @2010 Mihail L. Sichitiu 2 Google
AdFalcon Android SDK 2.1.4 Developer's Guide. AdFalcon Mobile Ad Network Product of Noqoush Mobile Media Group
AdFalcon Android SDK 214 Developer's Guide AdFalcon Mobile Ad Network Product of Noqoush Mobile Media Group Table of Contents 1 Introduction 3 Supported Android version 3 2 Project Configurations 4 Step
Android Introduction
Android Introduction CSCI 4237 - Software Design For Handheld Devices http://www.atomicrhubarb.com/handheld Lecture 6 Beginning Android Development Android Uses Eclipse + a bunch of plug-ins. Probably
INTRODUCTION TO ANDROID CSCI 4448/5448: OBJECT-ORIENTED ANALYSIS & DESIGN LECTURE 11 02/15/2011
INTRODUCTION TO ANDROID CSCI 4448/5448: OBJECT-ORIENTED ANALYSIS & DESIGN LECTURE 11 02/15/2011 1 Goals of the Lecture Present an introduction to the Android Framework Coverage of the framework will be
Developing In Eclipse, with ADT
Developing In Eclipse, with ADT Android Developers file://v:\android-sdk-windows\docs\guide\developing\eclipse-adt.html Page 1 of 12 Developing In Eclipse, with ADT The Android Development Tools (ADT)
Microsoft Tag Scanning SDK for iphone & Android Apps
Microsoft Tag Scanning SDK for iphone & Android Apps This document provides an overview of the functionality of the Microsoft Tag Scanning SDK, used to integrate Tag scanning into mobile apps on the ios
SMART Board Tips & Tricks (version 9.0) Getting Started. SMART Tools vs. SMART Notebook software
SMART Board Tips & Tricks (version 9.0) Getting Started SMART Tools vs. SMART Notebook software Click the SMART Board icon (in the system tray at the bottom right of your screen) to access the SMART Board
COURSE CONTENT. GETTING STARTED Select Android Version Create RUN Configuration Create Your First Android Activity List of basic sample programs
COURSE CONTENT Introduction Brief history of Android Why Android? What benefits does Android have? What is OHA & PHA Why to choose Android? Software architecture of Android Advantages, features and market
How To Run A Hello World On Android 4.3.3 (Jdk) On A Microsoft Ds.Io (Windows) Or Android 2.7.3 Or Android 3.5.3 On A Pc Or Android 4 (
Developing Android applications in Windows Below you will find information about the components needed for developing Android applications and other (optional) software needed to connect to the institution
2. Click the download button for your operating system (Windows, Mac, or Linux).
Table of Contents: Using Android Studio 1 Installing Android Studio 1 Installing IntelliJ IDEA Community Edition 3 Downloading My Book's Examples 4 Launching Android Studio and Importing an Android Project
The "Eclipse Classic" version is recommended. Otherwise, a Java or RCP version of Eclipse is recommended.
Installing the SDK This page describes how to install the Android SDK and set up your development environment for the first time. If you encounter any problems during installation, see the Troubleshooting
Personal Cloud. Support Guide for Mac Computers. Storing and sharing your content 2
Personal Cloud Support Guide for Mac Computers Storing and sharing your content 2 Getting started 2 How to use the application 2 Managing your content 2 Adding content manually 3 Renaming files 3 Moving
Download and Installation Instructions. Android SDK and Android Development Tools (ADT)
Download and Installation Instructions for Android SDK and Android Development Tools (ADT) on Mac OS X Updated October, 2012 This document will describe how to download and install the Android SDK and
Android and OpenGL. Android Smartphone Programming. Matthias Keil. University of Freiburg
Android and OpenGL Android Smartphone Programming Matthias Keil Institute for Computer Science Faculty of Engineering 16. Dezember 2013 Outline 1 OpenGL Introduction 2 Displaying Graphics 3 Interaction
ios App for Mobile Website! Documentation!
ios App for Mobile Website Documentation What is IOS App for Mobile Website? IOS App for Mobile Website allows you to run any website inside it and if that website is responsive or mobile compatible, you
Android: Setup Hello, World: Android Edition. due by noon ET on Wed 2/22. Ingredients.
Android: Setup Hello, World: Android Edition due by noon ET on Wed 2/22 Ingredients. Android Development Tools Plugin for Eclipse Android Software Development Kit Eclipse Java Help. Help is available throughout
Setting Up Your Android Development Environment. For Mac OS X (10.6.8) v1.0. By GoNorthWest. 3 April 2012
Setting Up Your Android Development Environment For Mac OS X (10.6.8) v1.0 By GoNorthWest 3 April 2012 Setting up the Android development environment can be a bit well challenging if you don t have all
UP L18 Enhanced MDM and Updated Email Protection Hands-On Lab
UP L18 Enhanced MDM and Updated Email Protection Hands-On Lab Description The Symantec App Center platform continues to expand it s offering with new enhanced support for native agent based device management
Q1. What method you should override to use Android menu system?
AND-401 Exam Sample: Q1. What method you should override to use Android menu system? a. oncreateoptionsmenu() b. oncreatemenu() c. onmenucreated() d. oncreatecontextmenu() Answer: A Q2. What Activity method
How to Set Up Your PC for Android Application Development
Introduction Application Note How to Set Up Your PC for Android Application Development Supported Environments: Windows 7 (32/64-bit), Windows Vista (32/64-bit), Windows XP * This application note was
Android Application Development - Exam Sample
Android Application Development - Exam Sample 1 Which of these is not recommended in the Android Developer's Guide as a method of creating an individual View? a Create by extending the android.view.view
How to Install Applications (APK Files) on Your Android Phone
How to Install Applications (APK Files) on Your Android Phone Overview An Android application is stored in an APK file (i.e., a file named by {Application Name}.apk). You must install the APK on your Android
Introduction: The Xcode templates are not available in Cordova-2.0.0 or above, so we'll use the previous version, 1.9.0 for this recipe.
Tutorial Learning Objectives: After completing this lab, you should be able to learn about: Learn how to use Xcode with PhoneGap and jquery mobile to develop iphone Cordova applications. Learn how to use
Omnitapps Cloud Request Version 1.0 Manual
Omnitapps Cloud Request Version 1.0 Manual rev: 1.1 1. Start here 3 2. Configure Omnirequest with a cloud account 3 2.1 Licenses 4 2.2 Systems 5 2.3 Configurations 6 2.3.1 General settings 7 2.3.2 Startpage
Download and Installation Instructions. Android SDK and Android Development Tools (ADT) Microsoft Windows
Download and Installation Instructions for Android SDK and Android Development Tools (ADT) on Microsoft Windows Updated September, 2013 This document will describe how to download and install the Android
How To Test Your Web Site On Wapt On A Pc Or Mac Or Mac (Or Mac) On A Mac Or Ipad Or Ipa (Or Ipa) On Pc Or Ipam (Or Pc Or Pc) On An Ip
Load testing with WAPT: Quick Start Guide This document describes step by step how to create a simple typical test for a web application, execute it and interpret the results. A brief insight is provided
App Inventor Tutorial 4 Cat & Mouse Game
App Inventor Tutorial 4 Cat & Mouse Game This is an app that will let you get familiar with using image sprites, canvas, sound, clock and the accelerometer (Movement Sensor) within a Game in App Inventor.
060010702 Mobile Application Development 2014
Que 1: Short question answer. Unit 1: Introduction to Android and Development tools 1. What kind of tool is used to simulate Android application? 2. Can we use C++ language for Android application development?
RESCO MOBILE CRM USER GUIDE. Access your CRM data on any mobile platform ipad, iphone, Android, Windows Phone or Win XP/Vista/7/8
RESCO MOBILE CRM USER GUIDE Access your CRM data on any mobile platform ipad, iphone, Android, Windows Phone or Win XP/Vista/7/8 Contents Synchronization... 1 1.1. How to synchronize your device... 1 1.2.
Table of Contents. Adding Build Targets to the SDK 8 The Android Developer Tools (ADT) Plug-in for Eclipse 9
SECOND EDITION Programming Android kjj *J} Zigurd Mednieks, Laird Dornin, G. Blake Meike, and Masumi Nakamura O'REILLY Beijing Cambridge Farnham Koln Sebastopol Tokyo Table of Contents Preface xiii Parti.
Tutorial on Basic Android Setup
Tutorial on Basic Android Setup EE368/CS232 Digital Image Processing, Spring 2015 Windows Version Introduction In this tutorial, we will learn how to set up the Android software development environment
Creating Animated Apps
Chapter 17 Creating Animated Apps This chapter discusses methods for creating apps with simple animations objects that move. You ll learn the basics of creating two-dimensional games with App Inventor
Flash Tutorial Part I
Flash Tutorial Part I This tutorial is intended to give you a basic overview of how you can use Flash for web-based projects; it doesn t contain extensive step-by-step instructions and is therefore not
LCD MONITOR TOUCH PANEL DRIVER 2 OPERATION MANUAL. for Mac. Version 1.0 PN-L703A/PN-70TA3/PN-L703B/PN-70TB3/PN-L603A/PN-60TA3/PN-L603B/PN-60TB3
LCD MONITOR TOUCH PANEL DRIVER 2 OPERATION MANUAL for Mac Version 1.0 Applicable models PN-L703A/PN-70TA3/PN-L703B/PN-70TB3/PN-L603A/PN-60TA3/PN-L603B/PN-60TB3 Contents Introduction...3 System Requirements...3
Running a Program on an AVD
Running a Program on an AVD Now that you have a project that builds an application, and an AVD with a system image compatible with the application s build target and API level requirements, you can run
Admin. Mobile Software Development Framework: Android Activity, View/ViewGroup, External Resources. Recap: TinyOS. Recap: J2ME Framework
Admin. Mobile Software Development Framework: Android Activity, View/ViewGroup, External Resources Homework 2 questions 10/9/2012 Y. Richard Yang 1 2 Recap: TinyOS Hardware components motivated design
Android Programming Basics
2012 Marty Hall Android Programming Basics Originals of Slides and Source Code for Examples: http://www.coreservlets.com/android-tutorial/ Customized Java EE Training: http://courses.coreservlets.com/
2012 Nolio Ltd. All rights reserved
2012 Nolio Ltd. All rights reserved The information contained herein is proprietary and confidential. No part of this document may be reproduced without explicit prior written permission from Nolio Ltd.
INTEGRATING MICROSOFT DYNAMICS CRM WITH SIMEGO DS3
INTEGRATING MICROSOFT DYNAMICS CRM WITH SIMEGO DS3 Often the most compelling way to introduce yourself to a software product is to try deliver value as soon as possible. Simego DS3 is designed to get you
Islamic University of Gaza. Faculty of Engineering. Computer Engineering Department. Mobile Computing ECOM 5341. Eng. Wafaa Audah.
Islamic University of Gaza Faculty of Engineering Computer Engineering Department Mobile Computing ECOM 5341 By Eng. Wafaa Audah June 2013 1 Setting Up the Development Environment and Emulator Part 1:
