Android游戏开发---2D游戏中背景的绘制

游戏制作初始,绘制背景是其中很靠前的步骤。
类似于雷电的游戏,手机游戏屏幕大小固定,不可能采取移动飞机本身来得到移动的效果。一般都采用移动背景的办法来产生飞机动的效果。
关于移动背景,有两种做法
1. 一副大长图慢慢移动(一整个关卡就一张图)。
2. 一张上下部分能衔接着的图循环移动。
注意:后绘制的图片会覆盖先绘制的图片。 
 
第一种移动背景的方法简单,没有太多可讨论的。下面给出第二种的移动背景的实现方案。
思路:一张图绘制两遍。初始时其中一张填满屏幕,另一张在屏幕上方。然后两张图以相同速度移动,循环。


详细说明请看注释
详细代码(看注释):
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);
    }
 
}
运行效果



转载请注明出处: http://blog.csdn.net/xn4545945



  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值