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

     
Mục tiêu của tư liệu gợi ý các bạn làm quen với một vài chuyên môn đơn giản và 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 rượu cồn của những nhân đồ dùng game.Tương tác với hành động của bạn chơi
Trong tài liệu này tôi đã gợi ý các bạn xây dựng từng bước, chính vì vậy bạn phải gọi và thực hành tự bên trên xuống bên dưới. Chúng ta sẽ viết từng phiên bạn dạng của trò đùa từ là 1 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


*

*

*

*

*

Crúc ý rằng bạn đang chế tạo một trò nghịch 2D trên Android, chính vì vậy hình ảnh của trò nghịch bắt buộc bởi bạn vẽ ra, cũng chính vì vậy chúng ta ko phải một file như thể activity_main.xml.
Copy những ảnh này vào thỏng mục drawable của project. Tạo bắt đầu thỏng mục raw, cùng copy file explosion.wav & background.mp3 vào thỏng mục này.
Với trò chơi bạn cần phải sét đặt ảnh trên nền cùng một điều đặc trưng bạn cần phải sét chế độ FullScreen (Đầy màn hình).

package org.o7planning.android2dgame; import app android.phầm mềm.Activity;import app 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);
Tiếp theo sét đặt kiểu dáng màn hình nằm theo chiều ngang (Landscape). Quý Khách cần được sét đặt trong AndroidManifest.xml.
Tiếp theo bạn cần viết code để hiển thị nhân đồ vật trò chơi bên trên screen với di chuyển nó từ trái qua phải theo một vận tốc nào kia.
Với một nhân đồ vật vào trò nghịch các bạn chỉ bao gồm một file hình ảnh, tuy vậy file hình họa được chia ra có tác dụng những vùng biểu thị các hành vi khác nhau của nhân thiết bị.

Xem thêm: Hướng Dẫn Sử Dụng Nồi Cơm Sharp Ks Zt18, Cách Sử Dụng Nồi Cơm Điện Sharp Ks Zt 18


Sử dụng code bạn cũng có thể vẽ một vùng hình ảnh lên đối tượng người tiêu dùng Canvas của trò nghịch, trên sản xuất độ x, y. Sử dụng vòng lặp for nhằm liên tiếp vẽ lại bên trên Canvas bạn cũng có thể tạo sự hoạt động của nhân vật.
Trong lúc xây dựng Game chúng ta cũng rất cần được tính đến phía di chuyển của nhân vật trong trò nghịch, vận tốc của nhân vật dụng.
package org.o7planning.android2dgame;import game android.graphics.Bitmap;public abstract class GameObject protected Bitbản đồ 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 Bitmaps createSubImageAt(int row, int col) // createBitmap(bitmaps, x, y, width, height). Bitbản đồ subImage = Bitbản đồ.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 game 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_TOPhường = 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; // Velothành phố 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 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 && Math.abs(movingVectorX) 0 && Math.abs(movingVectorX)
package org.o7planning.android2dgame;import game android.graphics.Canvas;import game 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 và 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) // Unlock Canvas. this.surfaceHolder.unlockCanvasAndPost(canvas); long now = System.nanoTime() ; // Interval to redraw game // (Change nanoseconds to milliseconds) long waitTime = (now - startTime)/1000000; if(waitTime
Lớp GameSurface mô bỏng toàn bộ mặt phẳng của trò đùa, class này không ngừng mở rộng từ bỏ SurfaceView, SurfaceView cất một đối tượng người dùng Canvas, các đối tượng người dùng vào trò nghịch sẽ tiến hành vẽ lên Canvas.
package org.o7planning.android2dgame;import game android.content.Context;import game android.graphics.Bitmap;import game 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 trò chơi Surface focusable so it can handle events. . this.setFocusable(true); // Sét callbaông chồ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.Callbachồng
Override public void surfaceCreated(SurfaceHolder holder) Bitbản đồ 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.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;
package org.o7planning.android2dgame;import apk.phầm mềm.Activity;import app android.os.Bundle;import app 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); this.setContentView(new GameSurface(this));
Tiếp theo chúng ta có xử lý sự kiện khi người tiêu dùng chạm vào screen, nhân vật dụng trò chơi vẫn chạy theo hướng bạn vẫn chạm. Quý khách hàng yêu cầu xử trí sự khiếu nại này bên trên lớp GameSurface.
Overridepublic boolean onTouchEvent(MotionEvent event) if (event.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;
package org.o7planning.android2dgame;import app android.nội dung.Context;import apk.graphics.Bitmap;import apk.graphics.BitmapFactory;import app android.graphics.Canvas;import android.view.MotionEvent;import android.view.SurfaceHolder;import game android.view.SurfaceView;public class GameSurface extends SurfaceView implements SurfaceHolder.Callbachồ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 callbachồng. 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)sự kiện.getX(); int y = (int)sự kiện.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) 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 end of GameThread. this.gameThread.join(); catch(InterruptedException e) e.printStackTrace(); retry= true;
quý khách hàng rất có thể sản xuất thêm các nhân đồ dùng khác vào trò chơi, tại đây tôi thêm một nhân trang bị thứ hai. Sửa lại code của lớp GameSurface:
package org.o7planning.android2dgame;import android.nội dung.Context;import app android.graphics.Bitmap;import app android.graphics.BitmapFactory;import game android.graphics.Canvas;import apk.view.MotionEvent;import apk.view.SurfaceHolder;import game android.view.SurfaceView;import java.util.ArrayList;import java.util.List;public class GameSurface extends SurfaceView implements SurfaceHolder.Callbaông chồng private GameThread gameThread; private final List chibiList = new ArrayList(); public GameSurface(Context context) super(context); // Make Game Surface focusable so it can handle events. this.setFocusable(true); // Set callbaông chồng. this.getHolder().addCallback(this); public void update() for(ChibiCharacter chibi: chibiList) chibi.update();
Override public boolean onTouchEvent(MotionEvent event) if (sự kiện.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.Callbaông chồng
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 xã
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;
thường thì bạn phải giải pháp xử lý một vài ba hiệu ứng mang lại trò chơi, ví dụ điển hình ai đang điều khiển một chiếc sản phẩm bay, Khi nó rơi xuống khu đất đồ vật cất cánh tiếng nổ lớn, vậy nổ là một trong hiệu ứng. Trong phần này tôi sẽ tế bào phỏng khi bạn đụng (click) vào nhân đồ gia dụng Chibi, nó vẫn phát nổ.
Lớp Explosion mô phỏng một vụ nổ, khi bạn click vào nhân đồ gia dụng Chibi, nó bị loại bỏ thoát khỏi trò nghịch và một đối tượng người sử dụng Explosion được phân phối trò chơi tại địa điểm của nhân thiết bị Chibi vừa bị nockout quăng quật.
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.nội dung.Context;import game android.graphics.Bitmap;import apk.graphics.BitmapFactory;import android.graphics.Canvas;import app android.view.MotionEvent;import game 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.Callbachồng { private GameThread gameThread; private final List chibiList = new ArrayList(); private final List 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 callbaông xã. this.getHolder().addCallback(this);
Override public boolean onTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) int x= (int)event.getX(); int y = (int)sự kiện.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 & danh sách. 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.Callbaông chồng
Override public void surfaceCreated(SurfaceHolder holder) Bitbản đồ 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 xã
Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) // Implements method of SurfaceHolder.Callbachồ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 phải thêm hiệu ứng âm tkhô cứng vào trò đùa, ví dụ điển hình âm tkhô hanh nền của trò đùa, âm thanh phát nổ lúc nhân vật Chibi bị hủy diệt.
package org.o7planning.android2dgame;import apk.graphics.Bitmap;import game 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, 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 game android.content.Context;import app android.graphics.Bitmap;import android.graphics.BitmapFactory;import app android.graphics.Canvas;import app android.media.AudioAttributes;import apk.media.AudioManager;import android.truyền thông.SoundPool;import app android.os.Build;import app android.view.MotionEvent;import game android.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.Callbachồng { 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 chồng. 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 & danh sách. 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) Bitbản đồ chibiBitmap1 = BitmapFactory.decodeResource(this.getResources(),R.drawable.chibi1); ChibiCharacter chibi1 = new ChibiCharacter(this,chibiBitmap1,100,50); Bitbản đồ 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;