Hướng dẫn lập trình game android đơn giản

     
Mục tiêu của tư liệu chỉ dẫn chúng ta làm quen thuộc với 1 vài ba kỹ thuật đơn giản dễ dàng vào lập trình sẵn trò chơi 2 chiều Android. Bao gồm:
Sử dụng SuffaceViewVẽ bên trên CanvasChuyển động của các nhân thiết bị game.Tương tác với động tác cử chỉ của fan chơi
Trong tư liệu này tôi sẽ giải đáp các bạn lập trình sẵn từng bước, bởi vì vậy bạn cần đọc cùng thực hành tự bên trên xuống bên dưới. Chúng ta vẫn viết từng phiên bản của trò chơi từ một cho tới phiên bản sau cuối (Release).

Bạn đang xem: Hướng dẫn lập trình game android đơn giản


*

*

*

*

*

Chú ý rằng bạn đang chế tạo ra một trò chơi 2D trên Android, bởi vì vậy bối cảnh của trò đùa đề nghị vì chúng ta vẽ ra, bởi vì vậy các bạn không cần một file như là activity_main.xml.
Copy các hình ảnh này vào tlỗi mục drawable của project. Tạo new thư mục raw, và copy file explosion.wav & background.mp3 vào tlỗi mục này.
Với trò đùa bạn cần phải sét đặt hình nền với một điều đặc biệt quan trọng bạn phải sét chính sách FullScreen (Đầy màn hình).

package org.o7planning.android2dgame; import game android.tiện ích.Activity;import game 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); // Set fullscreen this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); // Set No Title this.requestWindowFeature(Window.FEATURE_NO_TITLE);
Tiếp theo sét đặt giao diện màn hình hiển thị nằm theo chiều ngang (Landscape). Quý Khách cần được sét đặt vào AndroidManifest.xml.
Tiếp theo bạn cần viết code nhằm hiển thị nhân đồ dùng trò nghịch bên trên màn hình hiển thị với dịch chuyển nó trường đoản cú trái qua nên theo một gia tốc làm sao đó.
Với một nhân thứ vào trò đùa bạn chỉ bao gồm một tệp tin hình họa, mà lại file hình họa được chia ra làm những vùng bộc lộ các hành động không giống nhau của nhân đồ.
Sử dụng code bạn có thể vẽ một vùng hình ảnh lên đối tượng người sử dụng Canvas của trò đùa, tại chế tác độ x, y. Sử dụng vòng lặp for nhằm thường xuyên vẽ lại trên Canvas chúng ta có thể tạo ra sự chuyển động của nhân vật.
Trong Khi xây dựng trò chơi các bạn cũng rất cần phải tính đến phía dịch rời của nhân đồ vật trong trò đùa, vận tốc của nhân đồ gia dụng.
package org.o7planning.android2dgame;import app android.graphics.Bitmap;public abstract class GameObject protected Bitmaps 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 Bitbản đồ createSubImageAt(int row, int col) // createBitmap(bitmaps, x, y, width, height). Bitbản đồ 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 game 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; // Velođô thị 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, Bitbản đồ 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 to 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 game 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 &và Math.abs(movingVectorX) 0 &và Math.abs(movingVectorX)
package org.o7planning.android2dgame;import game android.graphics.Canvas;import apk.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 & lochồng it. canvas = this.surfaceHolder.lockCanvas(); // Synchronized synchronized (canvas) this.gameSurface.update(); this.gameSurface.draw(canvas); catch(Exception e) // Do nothing. finally if(canvas!= null) // Unlochồng Canvas. this.surfaceHolder.unlockCanvasAndPost(canvas); long now = System.nanoTime() ; // Interval lớn redraw game // (Change nanoseconds to lớn milliseconds) long waitTime = (now - startTime)/1000000; if(waitTime
Lớp GameSurface mô phỏng tổng thể mặt phẳng của trò chơi, class này không ngừng mở rộng từ bỏ SurfaceView, SurfaceView chứa một đối tượng người tiêu dùng Canvas, những đối tượng người sử dụng trong trò đùa sẽ tiến hành vẽ lên Canvas.
package org.o7planning.android2dgame;import android.content.Context;import android.graphics.Bitmap;import apk.graphics.BitmapFactory;import app android.graphics.Canvas;import apk.view.SurfaceHolder;import apk.view.SurfaceView;public class GameSurface extends SurfaceView implements SurfaceHolder.Callbaông chồng private GameThread gameThread; private ChibiCharacter chibi1; public GameSurface(Context context) super(context); // Make trò chơi Surface focusable so it can handle events. . this.setFocusable(true); // Sét callbachồng. 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) Bitmaps 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 over of GameThread. this.gameThread.join(); catch(InterruptedException e) e.printStackTrace(); retry= true;
package org.o7planning.android2dgame;import apk.tiện ích.Activity;import android.os.Bundle;import apk.view.Window;import apk.view.WindowManager;public class MainActivity extends Activity
Override protected void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState); // Set fullscreen this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); // Set No Title this.requestWindowFeature(Window.FEATURE_NO_TITLE); this.setContentView(new GameSurface(this));
Tiếp theo bạn gồm xử lý sự khiếu nại lúc người dùng đụng vào screen, nhân vật trò nghịch vẫn đuổi theo phía các bạn đang đụng. Bạn yêu cầu xử lý sự kiện này bên 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 apk.content.Context;import game android.graphics.Bitmap;import game android.graphics.BitmapFactory;import game android.graphics.Canvas;import app android.view.MotionEvent;import app android.view.SurfaceHolder;import app android.view.SurfaceView;public class GameSurface extends SurfaceView implements SurfaceHolder.Callbaông chồng 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 callbaông xã. this.getHolder().addCallback(this); public void update() this.chibi1.update();
Override public boolean onTouchEvent(MotionEvent event) if (sự kiện.getAction() == MotionEvent.ACTION_DOWN) int x= (int)sự kiện.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.Callbaông chồng
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.Callbaông xã
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;
quý khách hoàn toàn có thể sinh sản thêm những nhân đồ vật không giống vào trò chơi, ở đây tôi thêm một nhân vật dụng thứ 2. Sửa lại code của lớp GameSurface:
package org.o7planning.android2dgame;import app android.content.Context;import android.graphics.Bitmap;import apk.graphics.BitmapFactory;import game android.graphics.Canvas;import game android.view.MotionEvent;import game android.view.SurfaceHolder;import app android.view.SurfaceView;import java.util.ArrayList;import java.util.List;public class GameSurface extends SurfaceView implements SurfaceHolder.Callback private GameThread gameThread; private final List chibiList = new ArrayList(); public GameSurface(Context context) super(context); // Make trò chơi Surface focusable so it can handle events. this.setFocusable(true); // Set callbaông xã. 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)sự kiện.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.Callbachồng
Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) // Implements method of SurfaceHolder.Callbaông chồng
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ử trí một vài ba hiệu ứng cho trò nghịch, chẳng hạn bạn đang tinh chỉnh một chiếc sản phẩm cất cánh, Lúc nó rơi xuống khu đất thứ cất cánh phát nổ, vậy nổ là 1 trong những hiệu ứng. Trong phần này tôi sẽ tế bào bỏng khi bạn va (click) vào nhân thứ Chibi, nó đang tiếng nổ lớn.
Lớp Explosion mô phỏng một vụ nổ, khi bạn clichồng vào nhân đồ Chibi, nó bị nockout thoát khỏi trò nghịch với một đối tượng người sử dụng Explosion được cung cấp trò chơi tại vị trí của nhân thiết bị Chibi vừa bị nockout vứt.

Xem thêm: Tin Game Mobile Online Mới Nhất 2021 Cập Nhật 24/7, Game Mobile


package org.o7planning.android2dgame; import apk.graphics.Bitmap;import app 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 app android.graphics.BitmapFactory;import apk.graphics.Canvas;import app android.view.MotionEvent;import app 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 List chibiList = new ArrayList(); private final List explosionList = new ArrayList(); public GameSurface(Context context) super(context); // Make Game Surface focusable so it can handle events. this.setFocusable(true); // Sét callbachồng. this.getHolder().addCallback(this);
Override public boolean onTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) int x= (int)sự kiện.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 sầu the current element from the iterator và các mục. 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.Callbaông chồng
Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) // Implements method of SurfaceHolder.Callbaông chồng
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 cảm giác âm thanh khô vào trò đùa, ví dụ điển hình âm tkhô giòn nền của trò đùa, âm thanh khô tiếng nổ Khi nhân thứ Chibi bị phá hủy.
package org.o7planning.android2dgame;import apk.graphics.Bitmap;import apk.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, Bitmaps 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) Bitmaps bitmap= this.createSubImageAt(rowIndex,colIndex); canvas.drawBitmap(bitmaps, this.x, this.y,null); public boolean isFinish() return finish;
package org.o7planning.android2dgame;import apk.content.Context;import apk.graphics.Bitmap;import android.graphics.BitmapFactory;import app android.graphics.Canvas;import android.truyền thông.AudioAttributes;import app android.truyền thông.AudioManager;import game android.truyền thông media.SoundPool;import apk.os.Build;import apk.view.MotionEvent;import apk.view.SurfaceHolder;import apk.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 List chibiList = new ArrayList(); private final List 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 Game Surface focusable so it can handle events. this.setFocusable(true); // Sét callbaông xã. this.getHolder().addCallback(this); this.initSoundPool(); private void initSoundPool() // With Android 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 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 sầu 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.Callbachồng
Override public void surfaceCreated(SurfaceHolder holder) Bitmaps chibiBitmap1 = BitmapFactory.decodeResource(this.getResources(),R.drawable.chibi1); ChibiCharacter chibi1 = new ChibiCharacter(this,chibiBitmap1,100,50); Bitmaps 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.Callbaông chồng
Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) // Implements method of SurfaceHolder.Callbaông xã
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;