Android遊戲開發—2D遊戲中背景的繪制

遊戲制作初始,繪制背景是其中很靠前的步驟。

類似於雷電的遊戲,手機遊戲屏幕大小固定,不可能采取移動飛機本身來得到移動的效果。一般都采用移動背景的辦法來產生飛機動的效果。

關於移動背景,有兩種做法:

1. 一副大長圖慢慢移動(一整個關卡就一張圖)。

2. 一張上下部分能銜接著的圖循環移動。

註意:後繪制的圖片會覆蓋先繪制的圖片。 

 

第一種移動背景的方法簡單,沒有太多可討論的。下面給出第二種的移動背景的實現方案。

思路:一張圖繪制兩遍。初始時其中一張填滿屏幕,另一張在屏幕上方。然後兩張圖以相同速度移動,循環。

 

詳細說明請看註釋:

[java]  

詳細代碼(看註釋):  

import android.content.Context;  

import android.graphics.Bitmap;  

import android.graphics.BitmapFactory;  

import android.graphics.Canvas;  

import android.graphics.Color;  

import android.graphics.Rect;  

import android.view.KeyEvent;  

import android.view.MotionEvent;  

import android.view.SurfaceHolder;  

import android.view.SurfaceView;  

   

public class GameView extends SurfaceView implements SurfaceHolder.Callback,  

        Runnable  

{  

    private SurfaceHolder holder;  

    private Canvas canvas;  

    private Bitmap background;  

    private Bitmap player;  

    private boolean isRunning = true;  

    private int dy, dy2 = -480;        //用於背景移動  

    private Rect srcRect;            //用於放大圖片, 和存儲圖片的位置  

    private Rect destRect;  

    private Rect destRect2;  

    private float playerX, playerY;//飛機的初始位置  

   

    public GameView(Context context)  

    {  

        super(context);  

        this.setFocusable(true);  

        holder = this.getHolder();//這個this指的是這個Surface  

        holder.addCallback(this); //這個this表示實現瞭Callback接口  

        srcRect = new Rect(0, 0, 242, 480);//原始圖片大小  

        destRect = new Rect(0, dy, 320, 480);//目標屏幕大小. 並帶有移動變量dy. 對應圖片1   

        destRect2 = new Rect(0, dy2, 320, 0);//屏幕上方的圖片,對應圖片2  

        background = BitmapFactory.decodeResource(getResources(),  

                R.drawable.background);  

        player = BitmapFactory  

                .decodeResource(getResources(), R.drawable.player);  

    }  

   

    @Override  

    public void run()  

    {  

        while (isRunning)  

        {  

            drawView();  

            try  

            {  

                Thread.sleep(100);  

            } catch (InterruptedException e)  

            {  

                e.printStackTrace();  

            }  

        }  

    }  

   

    private void drawView()  

    {  

        try  

        {  

            if (holder != null)  

            {  

                canvas = holder.lockCanvas();  

                canvas.drawColor(Color.BLACK);  

                //畫背景, 並使其移動  

                dy += 3;  

                dy2 += 3;  

                destRect.set(0, dy, 320, 480 + dy);  

                destRect2.set(0, dy2, 320, 480 + dy2);  

                canvas.drawBitmap(background, srcRect, destRect, null);  

                canvas.drawBitmap(background, srcRect, destRect2, null);  

                //判斷是否到達屏幕底端, 到達瞭則使其回到屏幕上端  

                if (dy >= 480)  

                    dy = -480;  

                if (dy2 >= 480)  

                    dy2 = -480;  

                //畫飛機  

                canvas.drawBitmap(player, playerX, playerY, null);  

            }  

   

        } catch (Exception e)  

        {  

            e.printStackTrace();  

        } finally  

        {  

            if (canvas != null)  

                holder.unlockCanvasAndPost(canvas);  

        }  

   

    }  

   

    @Override  

    public void surfaceCreated(SurfaceHolder holder)  

    {  

        new Thread(this).start();  

        isRunning = true;  

        //初始值必須放到這裡才行, 因為SurfaceView創建成功後才能獲取高寬  

        playerX = (this.getWidth() – player.getWidth()) / 2;  

        playerY = this.getHeight() – player.getHeight();  

    }  

   

    @Override  

    public void surfaceChanged(SurfaceHolder holder, int format, int width,  

            int height)  

    {  

   

    }  

   

    @Override  

    public void surfaceDestroyed(SurfaceHolder holder)  

    {  

        isRunning = false;  

    }  

   

    @Override  

    public boolean onKeyDown(int keyCode, KeyEvent event)  

    {  

        if (keyCode == KeyEvent.KEYCODE_BACK)  

            isRunning = false;  

        return super.onKeyDown(keyCode, event);  

    }  

   

    @Override  

    public boolean onTouchEvent(MotionEvent event)  

    {  

        playerX = event.getX() – player.getWidth() / 2; //使點擊的位置在飛機中央  

        playerY = event.getY() – player.getHeight() / 2;  

        return super.onTouchEvent(event);  

    }  

   

}  

運行效果:

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *