HƯỚNG DẪN LÀM GAME ANDROID

      85
*

*

*

*

Chú ý rằng bạn đang tạo một trò nghịch 2D trên Android, bởi vì vậy bối cảnh của trò chơi yêu cầu do bạn vẽ ra, cũng chính vì vậy chúng ta không nên một file như là activity_main.xml.

Bạn đang xem: Hướng dẫn làm game android


Copy các hình ảnh này vào folder drawable của project. Tạo new thư mục raw, với copy file explosion.wavbackground.mp3 vào thư mục này.
Với trò chơi bạn cần phải sét đặt ảnh nền với một điều quan liêu trọng bạn cần phải sét chế độ FullScreen (Đầy màn hình).

package org.o7planning.android2dgame; import android.app.Activity;import android.os.Bundle;import android.view.Window;import android.view.WindowManager;public class MainActivity extends Activity
Override protected void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState); // phối fullscreen this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); // mix No Title this.requestWindowFeature(Window.FEATURE_NO_TITLE);
Tiếp theo sét để kiểu màn hình hiển thị nằm ngang (Landscape). Bạn cần phải sét để trong AndroidManifest.xml.
Tiếp theo bạn cần viết code để hiển thị nhân đồ trò chơi trên màn hình và dịch rời nó từ trái qua yêu cầu theo một gia tốc nào đó.
Với một nhân thiết bị trong trò chơi các bạn chỉ có một file ảnh, nhưng file hình ảnh được chia ra làm nhiều vùng biểu lộ các hành vi khác nhau của nhân vật.
Sử dụng code chúng ta cũng có thể vẽ một vùng hình ảnh lên đối tượng người sử dụng Canvas của trò chơi, tại tạo thành độ x, y. Thực hiện vòng lặp for để thường xuyên vẽ lại trên Canvas bạn cũng có thể tạo ra sự hoạt động của nhân vật.

Xem thêm: Game Trang Điểm Nữ Hoàng Băng Giá, Game Nu Hoang Bang Gia 3


Trong khi lập trình Game bạn cũng rất cần phải tính cho hướng di chuyển của nhân thiết bị trong trò chơi, gia tốc của nhân vật.
package org.o7planning.android2dgame;import android.graphics.Bitmap;public abstract class GameObject protected Bitmap image; protected final int rowCount; protected final int colCount; protected final int WIDTH; protected final int HEIGHT; protected final int width; protected final int height; protected int x; protected int y; public GameObject(Bitmap image, int rowCount, int colCount, int x, int y) this.image = image; this.rowCount= rowCount; this.colCount= colCount; this.x= x; this.y= y; this.WIDTH = image.getWidth(); this.HEIGHT = image.getHeight(); this.width = this.WIDTH/ colCount; this.height= this.HEIGHT/ rowCount; protected Bitmap createSubImageAt(int row, int col) // createBitmap(bitmap, x, y, width, height). Bitmap subImage = Bitmap.createBitmap(image, col* width, row* height ,width,height); return subImage; public int getX() return this.x; public int getY() return this.y; public int getHeight() return height; public int getWidth() return width;
package org.o7planning.android2dgame;import android.graphics.Bitmap;import android.graphics.Canvas;public class ChibiCharacter extends GameObject { private static final int ROW_TOP_TO_BOTTOM = 0; private static final int ROW_RIGHT_TO_LEFT = 1; private static final int ROW_LEFT_TO_RIGHT = 2; private static final int ROW_BOTTOM_TO_TOP = 3; // Row index of Image are being used. Private int rowUsing = ROW_LEFT_TO_RIGHT; private int colUsing; private Bitmap<> leftToRights; private Bitmap<> rightToLefts; private Bitmap<> topToBottoms; private Bitmap<> bottomToTops; // Velocity of game character (pixel/millisecond) public static final float VELOCITY = 0.1f; private int movingVectorX = 10; private int movingVectorY = 5; private long lastDrawNanoTime =-1; private GameSurface gameSurface; public ChibiCharacter(GameSurface gameSurface, Bitmap image, int x, int y) { super(image, 4, 3, x, y); this.gameSurface= gameSurface; this.topToBottoms = new Bitmap; // 3 this.rightToLefts = new Bitmap; // 3 this.leftToRights = new Bitmap; // 3 this.bottomToTops = new Bitmap; // 3 for(int col = 0; col= this.colCount) this.colUsing =0; // Current time in nanoseconds long now = System.nanoTime(); // Never once did draw. If(lastDrawNanoTime==-1) lastDrawNanoTime= now; // Change nanoseconds lớn milliseconds (1 nanosecond = 1000000 milliseconds). Int deltaTime = (int) ((now - lastDrawNanoTime)/ 1000000 ); // Distance moves float distance = VELOCITY * deltaTime; double movingVectorLength = Math.sqrt(movingVectorX* movingVectorX + movingVectorY*movingVectorY); // Calculate the new position of the trò chơi character. This.x = x + (int)(distance* movingVectorX / movingVectorLength); this.y = y + (int)(distance* movingVectorY / movingVectorLength); // When the game"s character touches the edge of the screen, then change direction if(this.x this.gameSurface.getWidth() -width) this.x= this.gameSurface.getWidth()-width; this.movingVectorX = - this.movingVectorX; if(this.y this.gameSurface.getHeight()- height) this.y= this.gameSurface.getHeight()- height; this.movingVectorY = - this.movingVectorY ; // rowUsing if( movingVectorX > 0 ) { if(movingVectorY > 0 && Math.abs(movingVectorX) 0 && Math.abs(movingVectorX)
package org.o7planning.android2dgame;import android.graphics.Canvas;import android.view.SurfaceHolder;public class GameThread extends Thread { private boolean running; private GameSurface gameSurface; private SurfaceHolder surfaceHolder; public GameThread(GameSurface gameSurface, SurfaceHolder surfaceHolder) this.gameSurface= gameSurface; this.surfaceHolder= surfaceHolder;
Override public void run() { long startTime = System.nanoTime(); while(running) { Canvas canvas= null; try // Get Canvas from Holder & lock it. Canvas = this.surfaceHolder.lockCanvas(); // Synchronized synchronized (canvas) this.gameSurface.update(); this.gameSurface.draw(canvas); catch(Exception e) // bởi nothing. finally if(canvas!= null) // Unlock Canvas. This.surfaceHolder.unlockCanvasAndPost(canvas); long now = System.nanoTime() ; // Interval lớn redraw trò chơi // (Change nanoseconds lớn milliseconds) long waitTime = (now - startTime)/1000000; if(waitTime
Lớp GameSurface mô rộp toàn bộ bề mặt của trò chơi, class này không ngừng mở rộng từ SurfaceView, SurfaceView cất một đối tượng người sử dụng Canvas, các đối tượng người tiêu dùng trong trò chơi sẽ tiến hành vẽ lên Canvas.
package org.o7planning.android2dgame;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.view.SurfaceHolder;import android.view.SurfaceView;public class GameSurface extends SurfaceView implements SurfaceHolder.Callback private GameThread gameThread; private ChibiCharacter chibi1; public GameSurface(Context context) super(context); // Make game Surface focusable so it can handle events. . This.setFocusable(true); // Sét callback. This.getHolder().addCallback(this); public void update() this.chibi1.update();
Override public void draw(Canvas canvas) super.draw(canvas); this.chibi1.draw(canvas); // Implements method of SurfaceHolder.Callback
Override public void surfaceCreated(SurfaceHolder holder) Bitmap chibiBitmap1 = BitmapFactory.decodeResource(this.getResources(),R.drawable.chibi1); this.chibi1 = new ChibiCharacter(this,chibiBitmap1,100,50); this.gameThread = new GameThread(this,holder); this.gameThread.setRunning(true); this.gameThread.start(); // Implements method of SurfaceHolder.Callback
Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) // Implements method of SurfaceHolder.Callback
Override public void surfaceDestroyed(SurfaceHolder holder) boolean retry= true; while(retry) try this.gameThread.setRunning(false); // Parent thread must wait until the end of GameThread. This.gameThread.join(); catch(InterruptedException e) e.printStackTrace(); retry= true;
package org.o7planning.android2dgame;import android.app.Activity;import android.os.Bundle;import android.view.Window;import android.view.WindowManager;public class MainActivity extends Activity
Override protected void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState); // mix fullscreen this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); // mix No Title this.requestWindowFeature(Window.FEATURE_NO_TITLE); this.setContentView(new GameSurface(this));
Tiếp theo các bạn có cách xử trí sự khiếu nại khi người dùng chạm vào màn hình, nhân đồ dùng trò nghịch sẽ đuổi theo hướng bạn đã chạm. Bạn phải xử lý sự kiện này trên lớp GameSurface.
Overridepublic boolean onTouchEvent(MotionEvent event) if (event.getAction() == MotionEvent.ACTION_DOWN) int x= (int)event.getX(); int y = (int)event.getY(); int movingVectorX =x- this.chibi1.getX() ; int movingVectorY =y- this.chibi1.getY() ; this.chibi1.setMovingVector(movingVectorX,movingVectorY); return true; return false;
package org.o7planning.android2dgame;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.view.MotionEvent;import android.view.SurfaceHolder;import android.view.SurfaceView;public class GameSurface extends SurfaceView implements SurfaceHolder.Callback private GameThread gameThread; private ChibiCharacter chibi1; public GameSurface(Context context) super(context); // Make game Surface focusable so it can handle events. This.setFocusable(true); // set callback. This.getHolder().addCallback(this); public void update() this.chibi1.update();
Override public boolean onTouchEvent(MotionEvent event) if (event.getAction() == MotionEvent.ACTION_DOWN) int x= (int)event.getX(); int y = (int)event.getY(); int movingVectorX =x- this.chibi1.getX() ; int movingVectorY =y- this.chibi1.getY() ; this.chibi1.setMovingVector(movingVectorX,movingVectorY); return true; return false;
Override public void draw(Canvas canvas) super.draw(canvas); this.chibi1.draw(canvas); // Implements method of SurfaceHolder.Callback
Override public void surfaceCreated(SurfaceHolder holder) Bitmap chibiBitmap1 = BitmapFactory.decodeResource(this.getResources(),R.drawable.chibi1); this.chibi1 = new ChibiCharacter(this,chibiBitmap1,100,50); this.gameThread = new GameThread(this,holder); this.gameThread.setRunning(true); this.gameThread.start(); // Implements method of SurfaceHolder.Callback
Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) // Implements method of SurfaceHolder.Callback
Override public void surfaceDestroyed(SurfaceHolder holder) boolean retry= true; while(retry) try this.gameThread.setRunning(false); // Parent thread must wait until the kết thúc of GameThread. This.gameThread.join(); catch(InterruptedException e) e.printStackTrace(); retry= true;
Bạn hoàn toàn có thể tạo thêm các nhân vật dụng khác vào trò chơi, tại chỗ này tôi thêm 1 nhân vật thứ 2. Sửa lại code của lớp GameSurface:
package org.o7planning.android2dgame;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.view.MotionEvent;import android.view.SurfaceHolder;import android.view.SurfaceView;import java.util.ArrayList;import java.util.List;public class GameSurface extends SurfaceView implements SurfaceHolder.Callback private GameThread gameThread; private final danh sách chibiList = new ArrayList(); public GameSurface(Context context) super(context); // Make game Surface focusable so it can handle events. This.setFocusable(true); // mix callback. This.getHolder().addCallback(this); public void update() for(ChibiCharacter chibi: chibiList) chibi.update();
Override public boolean onTouchEvent(MotionEvent event) if (event.getAction() == MotionEvent.ACTION_DOWN) int x= (int)event.getX(); int y = (int)event.getY(); for(ChibiCharacter chibi: chibiList) int movingVectorX =x- chibi.getX() ; int movingVectorY =y- chibi.getY() ; chibi.setMovingVector(movingVectorX, movingVectorY); return true; return false;
Override public void draw(Canvas canvas) super.draw(canvas); for(ChibiCharacter chibi: chibiList) chibi.draw(canvas); // Implements method of SurfaceHolder.Callback
Override public void surfaceCreated(SurfaceHolder holder) Bitmap chibiBitmap1 = BitmapFactory.decodeResource(this.getResources(),R.drawable.chibi1); ChibiCharacter chibi1 = new ChibiCharacter(this,chibiBitmap1,100,50); Bitmap chibiBitmap2 = BitmapFactory.decodeResource(this.getResources(),R.drawable.chibi2); ChibiCharacter chibi2 = new ChibiCharacter(this,chibiBitmap2,300,150); this.chibiList.add(chibi1); this.chibiList.add(chibi2); this.gameThread = new GameThread(this,holder); this.gameThread.setRunning(true); this.gameThread.start(); // Implements method of SurfaceHolder.Callback
Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) // Implements method of SurfaceHolder.Callback
Override public void surfaceDestroyed(SurfaceHolder holder) boolean retry= true; while(retry) try this.gameThread.setRunning(false); // Parent thread must wait until the over of GameThread. This.gameThread.join(); catch(InterruptedException e) e.printStackTrace(); retry= true;
Đôi khi bạn phải xử lý một vài hiệu ứng mang lại trò chơi, ví dụ điển hình bạn đã điều khiển một cái máy bay, lúc nó rơi xuống đất máy bay phát nổ, vậy nổ là một hiệu ứng. Vào phần này tôi đang mô phỏng khi bạn chạm (click) vào nhân thứ Chibi, nó đã phát nổ.
Lớp Explosion mô bỏng một vụ nổ, khi bạn click vào nhân thiết bị Chibi, nó bị loại ra ngoài trò đùa và một đối tượng Explosion được phân phối trò nghịch tại vị trí của nhân đồ gia dụng Chibi vừa bị loại bỏ.
package org.o7planning.android2dgame; import android.graphics.Bitmap;import android.graphics.Canvas;public class Explosion extends GameObject private int rowIndex = 0 ; private int colIndex = -1 ; private boolean finish= false; private GameSurface gameSurface; public Explosion(GameSurface GameSurface, Bitmap image, int x, int y) super(image, 5, 5, x, y); this.gameSurface= GameSurface; public void update() this.colIndex++; if(this.colIndex >= this.colCount) this.colIndex =0; this.rowIndex++; if(this.rowIndex>= this.rowCount) this.finish= true; public void draw(Canvas canvas) if(!finish) Bitmap bitmap= this.createSubImageAt(rowIndex,colIndex); canvas.drawBitmap(bitmap, this.x, this.y,null); public boolean isFinish() return finish;
package org.o7planning.android2dgame;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.view.MotionEvent;import android.view.SurfaceHolder;import android.view.SurfaceView;import java.util.ArrayList;import java.util.Iterator;import java.util.List;public class GameSurface extends SurfaceView implements SurfaceHolder.Callback { private GameThread gameThread; private final danh sách chibiList = new ArrayList(); private final các mục explosionList = new ArrayList(); public GameSurface(Context context) super(context); // Make trò chơi Surface focusable so it can handle events. This.setFocusable(true); // Sét callback. This.getHolder().addCallback(this);
Override public boolean onTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) int x= (int)event.getX(); int y = (int)event.getY(); Iterator iterator= this.chibiList.iterator(); while(iterator.hasNext()) ChibiCharacter chibi = iterator.next(); if( chibi.getX() iterator= this.explosionList.iterator(); while(iterator.hasNext()) Explosion explosion = iterator.next(); if(explosion.isFinish()) // If explosion finish, Remove the current element from the iterator và list. Iterator.remove(); continue;
Override public void draw(Canvas canvas) super.draw(canvas); for(ChibiCharacter chibi: chibiList) chibi.draw(canvas); for(Explosion explosion: this.explosionList) explosion.draw(canvas); // Implements method of SurfaceHolder.Callback
Override public void surfaceCreated(SurfaceHolder holder) Bitmap chibiBitmap1 = BitmapFactory.decodeResource(this.getResources(),R.drawable.chibi1); ChibiCharacter chibi1 = new ChibiCharacter(this,chibiBitmap1,100,50); Bitmap chibiBitmap2 = BitmapFactory.decodeResource(this.getResources(),R.drawable.chibi2); ChibiCharacter chibi2 = new ChibiCharacter(this,chibiBitmap2,300,150); this.chibiList.add(chibi1); this.chibiList.add(chibi2); this.gameThread = new GameThread(this,holder); this.gameThread.setRunning(true); this.gameThread.start(); // Implements method of SurfaceHolder.Callback
Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) // Implements method of SurfaceHolder.Callback
Override public void surfaceDestroyed(SurfaceHolder holder) boolean retry= true; while(retry) try this.gameThread.setRunning(false); // Parent thread must wait until the kết thúc of GameThread. This.gameThread.join(); catch(InterruptedException e) e.printStackTrace(); retry= true;
Tiếp theo bạn cần thêm hiệu ứng âm nhạc vào trò chơi, ví dụ điển hình âm thanh nền của trò chơi, âm thanh tiếng nổ khi nhân đồ vật Chibi bị phá hủy.
package org.o7planning.android2dgame;import android.graphics.Bitmap;import android.graphics.Canvas;public class Explosion extends GameObject private int rowIndex = 0 ; private int colIndex = -1 ; private boolean finish= false; private GameSurface gameSurface; public Explosion(GameSurface GameSurface, Bitmap image, int x, int y) super(image, 5, 5, x, y); this.gameSurface= GameSurface; public void update() this.colIndex++; // Play sound explosion.wav. If(this.colIndex==0 && this.rowIndex==0) this.gameSurface.playSoundExplosion(); if(this.colIndex >= this.colCount) this.colIndex =0; this.rowIndex++; if(this.rowIndex>= this.rowCount) this.finish= true; public void draw(Canvas canvas) if(!finish) Bitmap bitmap= this.createSubImageAt(rowIndex,colIndex); canvas.drawBitmap(bitmap, this.x, this.y,null); public boolean isFinish() return finish;
package org.o7planning.android2dgame;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.media.AudioAttributes;import android.media.AudioManager;import android.media.SoundPool;import android.os.Build;import android.view.MotionEvent;import android.view.SurfaceHolder;import android.view.SurfaceView;import java.util.ArrayList;import java.util.Iterator;import java.util.List;public class GameSurface extends SurfaceView implements SurfaceHolder.Callback { private GameThread gameThread; private final danh sách chibiList = new ArrayList(); private final menu explosionList = new ArrayList(); private static final int MAX_STREAMS=100; private int soundIdExplosion; private int soundIdBackground; private boolean soundPoolLoaded; private SoundPool soundPool; public GameSurface(Context context) super(context); // Make trò chơi Surface focusable so it can handle events. This.setFocusable(true); // Sét callback. This.getHolder().addCallback(this); this.initSoundPool(); private void initSoundPool() // With apk API >= 21. If (Build.VERSION.SDK_INT >= 21 ) AudioAttributes audioAttrib = new AudioAttributes.Builder() .setUsage(AudioAttributes.USAGE_GAME) .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) .build(); SoundPool.Builder builder= new SoundPool.Builder(); builder.setAudioAttributes(audioAttrib).setMaxStreams(MAX_STREAMS); this.soundPool = builder.build(); // With game android API iterator= this.chibiList.iterator(); while(iterator.hasNext()) ChibiCharacter chibi = iterator.next(); if( chibi.getX() iterator= this.explosionList.iterator(); while(iterator.hasNext()) Explosion explosion = iterator.next(); if(explosion.isFinish()) // If explosion finish, Remove the current element from the iterator & list. Iterator.remove(); continue;
Override public void draw(Canvas canvas) super.draw(canvas); for(ChibiCharacter chibi: chibiList) chibi.draw(canvas); for(Explosion explosion: this.explosionList) explosion.draw(canvas); // Implements method of SurfaceHolder.Callback
Override public void surfaceCreated(SurfaceHolder holder) Bitmap chibiBitmap1 = BitmapFactory.decodeResource(this.getResources(),R.drawable.chibi1); ChibiCharacter chibi1 = new ChibiCharacter(this,chibiBitmap1,100,50); Bitmap chibiBitmap2 = BitmapFactory.decodeResource(this.getResources(),R.drawable.chibi2); ChibiCharacter chibi2 = new ChibiCharacter(this,chibiBitmap2,300,150); this.chibiList.add(chibi1); this.chibiList.add(chibi2); this.gameThread = new GameThread(this,holder); this.gameThread.setRunning(true); this.gameThread.start(); // Implements method of SurfaceHolder.Callback
Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) // Implements method of SurfaceHolder.Callback
Override public void surfaceDestroyed(SurfaceHolder holder) boolean retry= true; while(retry) try this.gameThread.setRunning(false); // Parent thread must wait until the kết thúc of GameThread. This.gameThread.join(); catch(InterruptedException e) e.printStackTrace(); retry= true;
567live XoiLac TV