安卓飞机大战源码,面向对象思想,多线程,包含注释.
最近闲来无事看看安卓的api做一个飞机大战.
如有转发需声明作者:吴年和.
本代码无偿开源.
图片与声音我就不提供了.
package com.example.planebigwar.entity;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
import android.media.MediaPlayer;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import com.example.planebigwar.R;
import com.example.planebigwar.interfaces.Awarde;
import com.example.planebigwar.interfaces.Score;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
/**
* @Author: 吴年和
* @DATE: 2020/04/14 16:00:00
* 绘画世界类
* 将所有的绘画或功能在此类中实现
*/
public class PaintWorld extends View implements Runnable {
public static final short START = 0;//游戏开始状态
public static final short RUN = 1;//游戏运行状态
public static final short PAUSE = 2;//游戏暂停状态
public static final short OVER = 3;//游戏结束状态
public static float SCREEN_HEIGHT, SCREEN_WIDTH;//屏幕宽高
public static float scale;//比例屏幕系数
public static short state = START;//游戏当前状态
public static int score = 0;//显示的分数
public static int life = 30;//显示的分数
private static boolean gameOnOff = true;
private static long number = 0;//运行次数
private static Timer timer = new Timer();//时间对象
private Resources res = getResources();//画对象需要
private Random random = new Random();//随机数
private Hero hero;//英雄对象
private Sky sky;//天空对象
private Start start;//开始对象
private Pause pause;//暂停对象
private Over over;//结束对象
private Font scoreText;//分数对象
private Font lifeText;//生命对象
//private Music music;//音乐对象
/**
* 储存敌人与子弹
*/
private List<FlyObj> enemys = Collections.synchronizedList(new LinkedList<FlyObj>()),
bullets = Collections.synchronizedList(new LinkedList<FlyObj>());
/**
* 继承View所需的构造器
*
* @param context Activity调用时可直接传入this
*/
public PaintWorld(Context context) {
super(context);
/*
* 设置背景颜色
*/
setBackgroundColor(Color.BLACK);
/*
* 获取设备的屏幕宽高信息
*/
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics dm = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(dm);
SCREEN_HEIGHT = dm.heightPixels + (dm.heightPixels / 12);
SCREEN_WIDTH = dm.widthPixels;
//屏幕缩放比系数
scale = (float) (Math.sqrt(SCREEN_HEIGHT * SCREEN_WIDTH) / Math.sqrt(480 * 800));
/*
* 实例化初始对象
*/
start = new Start(800.0f, 480.0f, 0, 0, 0, 1, res);
pause = new Pause(800.0f, 480.0f, 0, 0, 0, 1, res);
over = new Over(800.0f, 480.0f, 0, 0, 0, 1, res);
sky = new Sky(800.0f, 480.0f, 0, 0, 0, 1, res);
hero = new Hero(139.0f, 97.0f, SCREEN_WIDTH / 2 - 97 * scale / 2, (float) (SCREEN_HEIGHT * 0.7), life, 0, res);
scoreText = new Font(20, 50, res);
lifeText = new Font(20, 100, res);
//music = new Music(context);
/*
* 添加事件控制玩家飞机
*/
setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
switch (state) {
case RUN:
hero.coordinate(event.getRawX(), event.getRawY());
break;
case START:
state = RUN;
break;
case PAUSE:
state = RUN;
break;
case OVER:
score = 0;
number = 0;
hero = new Hero(139.0f, 97.0f, SCREEN_WIDTH / 2 - 97 * scale / 2, (float) (SCREEN_HEIGHT * 0.7), life, 0, res);
enemys = Collections.synchronizedList(new LinkedList<FlyObj>());
bullets = Collections.synchronizedList(new LinkedList<FlyObj>());
state = START;
gameOnOff = true;
break;
}
}
return true;
}
});
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
/*
* 画上各类角色
* 使用方法与swing paint一致
*/
sky.paintObj(canvas);
switch (state) {
case RUN:
if (!hero.isRemove())
hero.paintObj(canvas);
paint(bullets, canvas);
paint(enemys, canvas);
break;
case START:
start.paintObj(canvas);
break;
case PAUSE:
pause.paintObj(canvas);
break;
case OVER:
over.paintObj(canvas);
break;
}
scoreText.paintObj(canvas);
lifeText.paintObj(canvas);
}
/**
* 画集合内的对象
* 遍历对象
*
* @param objs
* @param canvas
*/
private synchronized void paint(List<FlyObj> objs, Canvas canvas) {
for (int i = 0; i < objs.size(); i++) {
objs.get(i).paintObj(canvas);
}
}
/**
* 添加对象
*/
private void addEnemyAction() {
if (number % 30 == 0) {
int random = this.random.nextInt(100);
if (random < 1)
enemys.add(new Star(res));
else if (random < 20)
enemys.add(new BigPlane(res));
else
enemys.add(new SmallPlane(res));
}
}
/**
* 判断物体是否越界
*/
private void transboundary() {
setRemove(enemys);
setRemove(bullets);
remove(enemys);
remove(bullets);
}
/**
* 设置移除跨界对象
*
* @param objs
*/
private void setRemove(List<FlyObj> objs) {
for (int i = 0; i < objs.size(); i++) {
if (objs.get(i).getY() > (SCREEN_HEIGHT * scale) || objs.get(i).getY() < 0 - objs.get(i).getHeight() ||
objs.get(i).getX() < 0 - objs.get(i).getWidth() || objs.get(i).getX() > (SCREEN_WIDTH