Android_(游戏)打飞机01:前言
(游戏)打飞机01:前言 传送门
(游戏)打飞机02:游戏背景滚动 传送门
(游戏)打飞机03:控制玩家飞机 传送门
(游戏)打飞机04:绘画敌机、添加子弹 传送门
(游戏)打飞机05:处理子弹,击中敌机,添加计分板 传送门
(游戏)打飞机06:后续 传送门
程序已放到Github上托管 : 传送门
打飞机游戏效果

游戏中的二级缓存
android之surfaceView学习:传送门
制作游戏时,为了时刻渲染游戏场景,涉及到一个实时画图的问题了,对于实时更新UI这个问题,android的UI更新都需要在主线程中更新,但是如果将一个实时绘图的操作放在主线程,必定会出现阻塞主线程的问题,即便是不阻塞主线程,也会降低程序运行的速度
surfaceView提供了UI线程。可以自己更新UI,因此,这样我们在surfaceView中进行实时的绘画,然后通过更改其中的绘画的数据,既可以实现我们想要的实时的更新UI的这个问题了,并且消耗较小的资源
surfaceCreated:创建时需要执行的操作
surfaceView:大小改变时需要执行的操作
surfaceDestroyed:销毁时进行的操作
//视图创建时通知
public void surfaceCreated(SurfaceHolder holder) {
this.holder = holder;
runState = true;
//视图创建时开始线程
new Thread(this).start();
} //界面发生改变的时候通知
public void surfaceChanged(SurfaceHolder holder, int i, int i1, int i2) { } //销毁时通知
public void surfaceDestroyed(SurfaceHolder holder) {
runState = false;
}
线程中的方法
public void run() {
Random ran = new Random();
try{
while(true) {
//获得绘画的画布
Canvas canvas = holder.lockCanvas();
Paint p = new Paint();
p.setColor(Color.rgb(ran.nextInt(255),ran.nextInt(255),ran.nextInt(255)));
canvas.drawLine(ran.nextInt(1000),ran.nextInt(1000),ran.nextInt(1000),ran.nextInt(1000),p);
//把绘画好的内容提交上去
holder.unlockCanvasAndPost(canvas);//解锁
Thread.sleep(1000);
}
}catch (Exception e){
}
}
锁住画布时,开始编辑要绘画的内容
//锁住画布
Canvas canvas = holder.lockCanvas();
内容绘画好后,开始解锁
//把绘画好的内容提交上去
holder.unlockCanvasAndPost(canvas);//解锁
制作游戏时,为了时时渲染游戏画面,线程中常用死循环
while(true) {
//锁住画布
Canvas canvas = holder.lockCanvas();
Paint p = new Paint();
p.setColor(Color.rgb(ran.nextInt(255),ran.nextInt(255),ran.nextInt(255)));
canvas.drawLine(ran.nextInt(1000),ran.nextInt(1000),ran.nextInt(1000),ran.nextInt(1000),p);
//把绘画好的内容提交上去
holder.unlockCanvasAndPost(canvas);//解锁
Thread.sleep(1000);
}
实现效果:

package com.example.administrator.myapplication; import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.view.SurfaceHolder;
import android.view.SurfaceView; import java.util.Random; /**
* Created by Administrator on 2018/8/9.
*/ public class GameView extends SurfaceView implements Runnable, SurfaceHolder.Callback{ public GameView(Context context) {
super(context); getHolder().addCallback(this); //注册回调方法
} private boolean runState = false;
private SurfaceHolder holder = null; @Override
public void run() {
Random ran = new Random(); try{
while(true) {
//获得绘画的画布
Canvas canvas = holder.lockCanvas(); Paint p = new Paint();
p.setColor(Color.rgb(ran.nextInt(255),ran.nextInt(255),ran.nextInt(255))); canvas.drawLine(ran.nextInt(1000),ran.nextInt(1000),ran.nextInt(1000),ran.nextInt(1000),p); //把绘画好的内容提交上去
holder.unlockCanvasAndPost(canvas);//解锁
Thread.sleep(1000);
}
}catch (Exception e){ }
} //视图创建时通知
public void surfaceCreated(SurfaceHolder holder) {
this.holder = holder;
runState = true;
new Thread(this).start(); } //界面发生改变的时候通知
public void surfaceChanged(SurfaceHolder holder, int i, int i1, int i2) { } //销毁时通知
public void surfaceDestroyed(SurfaceHolder holder) {
runState = false;
} }
GameView.java
package com.example.administrator.myapplication; import android.support.v7.app.AppCompatActivity;
import android.os.Bundle; public class MainActivity extends AppCompatActivity{ @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new GameView(this)); } }
MainActivity.java
随之而来有一个问题。产生新线条的时候会让原本存在线条也会发生位置、颜色的改变,这样绘制游戏时这样不仅会产生大量的游戏内存,也容易使玩家造成晕眩效果
制作游戏常用二级缓存来解决这个问题(减少游戏运行时内存开销!!!)
二级缓存工作机制
所谓二级缓存实际上并不复杂,当Android端需要获得数据时比如获取网络中的图片,我们首先从内存中查找(按键查找),内存中没有的再从磁盘文件或sqlite中去查找,若磁盘中也没有才通过网络获取;当获得来自网络的数据,就以key-value对的方式先缓存到内存(一级缓存),同时缓存到文件或sqlite中(二级缓存)。注意:内存缓存会造成堆内存泄露,所有一级缓存通常要严格控制缓存的大小,一般控制在系统内存的1/4。
二级缓存
二级缓存:当游戏需要产生新动画时,不改变原场景游戏画面,只要把新加入的绘画内容先放到二级缓存中,绘画好后从二级缓存取出来绘画到游戏界面上
运用Bitmap实现二级缓存
private Bitmap gameBitmap = null;
gameBitmap = Bitmap.createBitmap(500,500, Bitmap.Config.ARGB_8888);
public void run() {
Random ran = new Random();
try{
while(true) {
//获得绘画的画布
Canvas canvas = holder.lockCanvas();
Paint p = new Paint();
Canvas c = new Canvas(gameBitmap);
// p.setColor(Color.WHITE);
// c.drawRect(new Rect(0,0,500,500),p); //白色背景
p.setColor(Color.rgb(ran.nextInt(255),ran.nextInt(255),ran.nextInt(255)));
c.drawLine(ran.nextInt(1000),ran.nextInt(1000),ran.nextInt(1000),ran.nextInt(1000),p);
canvas.drawBitmap(gameBitmap,0,0,new Paint());
//把绘画好的内容提交上去
holder.unlockCanvasAndPost(canvas);//解锁
Thread.sleep(1000);
}
}catch (Exception e){
}
实现效果:

产生新线条时,原本绘画线条不会发生改变
二级缓存加载图片

package com.example.administrator.myapplication; import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.view.SurfaceHolder;
import android.view.SurfaceView; import java.util.ArrayList;
import java.util.List;
import java.util.Random; /**
* Created by Administrator on 2018/8/9.
*/ public class GameView extends SurfaceView implements Runnable, SurfaceHolder.Callback{ public GameView(Context context) {
super(context); getHolder().addCallback(this); //注册回调方法 gameBitmap = Bitmap.createBitmap(1200,1024, Bitmap.Config.ARGB_8888); bitmaps.add(BitmapFactory.decodeResource(getResources(),R.drawable.a3));
bitmaps.add(BitmapFactory.decodeResource(getResources(),R.drawable.a4));
bitmaps.add(BitmapFactory.decodeResource(getResources(),R.drawable.a5));
} private List<Bitmap> bitmaps = new ArrayList<Bitmap>(); private boolean runState = false;
private SurfaceHolder holder = null;
private Bitmap gameBitmap = null; @Override
public void run() {
Random ran = new Random();
int index = 0;
try{
while(true) {
//获得绘画的画布
Canvas canvas = holder.lockCanvas();
Paint p = new Paint();
Canvas c = new Canvas(gameBitmap); c.drawBitmap( bitmaps.get(index++),0,0,p); if(index==bitmaps.size()){
index=0;
}
// p.setColor(Color.WHITE);
// c.drawRect(new Rect(0,0,500,500),p); //白色背景
// p.setColor(Color.rgb(ran.nextInt(255),ran.nextInt(255),ran.nextInt(255)));
//c.drawLine(ran.nextInt(1000),ran.nextInt(1000),ran.nextInt(1000),ran.nextInt(1000),p); canvas.drawBitmap(gameBitmap,0,0,new Paint()); //把绘画好的内容提交上去
holder.unlockCanvasAndPost(canvas);//解锁
Thread.sleep(1000);
}
}catch (Exception e){ }
} //视图创建时通知
public void surfaceCreated(SurfaceHolder holder) {
this.holder = holder;
runState = true;
new Thread(this).start(); } //界面发生改变的时候通知
public void surfaceChanged(SurfaceHolder holder, int i, int i1, int i2) { } //销毁时通知
public void surfaceDestroyed(SurfaceHolder holder) {
runState = false;
} }
GameView.java
package com.example.administrator.myapplication; import android.support.v7.app.AppCompatActivity;
import android.os.Bundle; public class MainActivity extends AppCompatActivity{ @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new GameView(this)); } }
MainActivity.java
添加图片进二级缓存中
private List<Bitmap> bitmaps = new ArrayList<Bitmap>();
bitmaps.add(BitmapFactory.decodeResource(getResources(),R.drawable.a3));
bitmaps.add(BitmapFactory.decodeResource(getResources(),R.drawable.a4));
bitmaps.add(BitmapFactory.decodeResource(getResources(),R.drawable.a5));
运行程序时
public void run() {
Random ran = new Random();
int index = 0;
try{
while(true) {
//获得绘画的画布
Canvas canvas = holder.lockCanvas();
Paint p = new Paint();
Canvas c = new Canvas(gameBitmap);
c.drawBitmap( bitmaps.get(index++),0,0,p);
if(index==bitmaps.size()){
index=0;
}
// p.setColor(Color.WHITE);
// c.drawRect(new Rect(0,0,500,500),p); //白色背景
// p.setColor(Color.rgb(ran.nextInt(255),ran.nextInt(255),ran.nextInt(255)));
//c.drawLine(ran.nextInt(1000),ran.nextInt(1000),ran.nextInt(1000),ran.nextInt(1000),p);
canvas.drawBitmap(gameBitmap,0,0,new Paint());
//把绘画好的内容提交上去
holder.unlockCanvasAndPost(canvas);//解锁
Thread.sleep(1000);
}
}catch (Exception e){
}
}
Android_(游戏)打飞机01:前言的更多相关文章
- Android_(游戏)打飞机06:后续
(游戏)打飞机01:前言 传送门 (游戏)打飞机02:游戏背景滚动 传送门 (游戏)打飞机03:控制玩家飞机 传送门 (游戏)打飞机04:绘画敌机.添加子弹 传送门 (游戏)打飞机05:处理子弹, ...
- Android_(游戏)打飞机05:处理子弹,击中敌机,添加计分板
(游戏)打飞机01:前言 传送门 (游戏)打飞机02:游戏背景滚动 传送门 (游戏)打飞机03:控制玩家飞机 传送门 (游戏)打飞机04:绘画敌机.添加子弹 传送门 (游戏)打飞机05:处理子弹, ...
- Android_(游戏)打飞机04:绘画敌机、添加子弹
(游戏)打飞机01:前言 传送门 (游戏)打飞机02:游戏背景滚动 传送门 (游戏)打飞机03:控制玩家飞机 传送门 (游戏)打飞机04:绘画敌机.添加子弹 传送门 (游戏)打飞机05:处理子弹, ...
- Android_(游戏)打飞机03:控制玩家飞机
(游戏)打飞机01:前言 传送门 (游戏)打飞机02:游戏背景滚动 传送门 (游戏)打飞机03:控制玩家飞机 传送门 (游戏)打飞机04:绘画敌机.添加子弹 传送门 (游戏)打飞机05:处理子弹, ...
- Android_(游戏)打飞机02:游戏背景滚动
(游戏)打飞机01:前言 传送门 (游戏)打飞机02:游戏背景滚动 传送门 (游戏)打飞机03:控制玩家飞机 传送门 (游戏)打飞机04:绘画敌机.添加子弹 传送门 (游戏)打飞机05:处理子弹, ...
- Python之游戏开发-飞机大战
Python之游戏开发-飞机大战 想要代码文件,可以加我微信:nickchen121 #!/usr/bin/env python # coding: utf-8 import pygame impor ...
- Python小游戏之 - 飞机大战美女 !
用Python写的"飞机大战美女"小游戏 源代码如下: # coding=utf-8 import os import random import pygame # 用一个常量来存 ...
- 01 前言/基础设施 - DevOps之路
01 前言/基础设施 - DevOps之路 文章Github地址,欢迎start:https://github.com/li-keli/DevOps-WiKi 简介 基础架构采用DevOps设计思想, ...
- 微信小游戏 demo 飞机大战 代码分析(四)(enemy.js, bullet.js, index.js)
微信小游戏 demo 飞机大战 代码分析(四)(enemy.js, bullet.js, index.js) 微信小游戏 demo 飞机大战 代码分析(一)(main.js) 微信小游戏 demo 飞 ...
随机推荐
- # 「银联初赛第一场」自学图论的码队弟弟(dfs找环+巧解n个二元一次方程)
「银联初赛第一场」自学图论的码队弟弟(dfs找环+巧解n个二元一次方程) 题链 题意:n条边n个节点的连通图,边权为两个节点的权值之和,没有「自环」或「重边」,给出的图中有且只有一个包括奇数个结点的环 ...
- SpringMVC实现全局异常处理器 (转)
出处: SpringMVC实现全局异常处理器 我们知道,系统中异常包括:编译时异常和运行时异常RuntimeException,前者通过捕获异常从而获取异常信息,后者主要通过规范代码开发.测试通过手 ...
- docopt 安装及基本应用
什么是 docopt docopt是一种python 编写的命令行执行脚本的交互语言. 它是一种语言! 它是一种语言! 它是一种语言! 使用这种语言可以在自己的脚本中,添加一些规则限制,这样脚本在执行 ...
- node工具之http-proxy-middleware
简介 一个轻松的配置代理服务器的中间件,让Node.js代理变得简单 url路径 foo://example.com:8042/over/there?name=ferret#nose \_/ \___ ...
- C中的函数指针的用法
include<stdio.h> typedef int (*Cal)(int a,int b);//定义一个函数指针,第一个int是指向函数的返回值的类型,后面括号里面的两个int是指指 ...
- Mysql学习(三)之数据库管理工具Navicat
前言 mysql安装完后默认只有命令行工具,所以我们可以下载一些数据库管理工具Navicat Navicat使用 首先建立一个连接选择mysql,填写信息 发现多了一个localhost,双击,打开连 ...
- hdu 6399 City Development
vjudge 读进来可能会有相同的\(n_i\),不过在相同的\(n_i\)中只有最后一个是有用的,所以其他的要缩起来,缩完后这些\(n\)的数量不会超过19个 可以发现一个城市的答案为所有城市初始权 ...
- 深入简出mysql--第一部分
第二章: 1.sql分类 DDL(Data Definition Languages)语句:数据定义语言,这些语句定义了不同的数据段.数据库.表.列.索引等数据库对象的定义. 常用的语句关键字主要包括 ...
- 31C3 CTF web关writeup
0x00 背景 31c3 CTF 还是很人性化的,比赛结束了之后还可以玩.看题解做出了当时不会做的题目,写了一个writeup. 英文的题解可以看这:https://github.com/ctfs/w ...
- pyquery:轻松、灵活的处理html
介绍 pyquery是一个专门用来解析html的库,从名字很容易想到jQuery,没错,这完全是仿照jQuery的语法实现的.如果用过jQuery,那么pyquery也很容易上手 初始化html py ...