master
*** 4 years ago
parent c8f8c863cf
commit c5b077e7ed

@ -0,0 +1,16 @@
*.iml
.gradle
.idea
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
.externalNativeBuild
.cxx
/release

Binary file not shown.

@ -0,0 +1,2 @@
/build
/release

@ -0,0 +1,111 @@
apply plugin: 'com.android.application'
static def releaseTime() {
return new Date().format("yyyyMMdd HH_mm_ss", TimeZone.getDefault())
}
android {
compileSdkVersion 30
buildToolsVersion "29.0.3"
defaultConfig {
applicationId "com.cwj.we"
minSdkVersion 22
targetSdkVersion 30
versionCode 26
versionName "1.3.2"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
multiDexEnabled true//65535
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
// AS3.0 APK
applicationVariants.all { variant ->
variant.outputs.all {
outputFileName = "我们-v${variant.versionName}-${releaseTime()}-${variant.buildType.name}.apk"
}
}
useLibrary 'org.apache.http.legacy'
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
testImplementation 'junit:junit:4.13.1'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
//butterknife
implementation 'com.jakewharton:butterknife:10.2.0'
annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.0'
//
implementation 'com.jaeger.statusbarutil:library:1.5.1'
//
implementation 'com.yanzhikai:TextPathView:0.2.1'
//
implementation 'com.contrarywind:Android-PickerView:4.1.9'
//65535
implementation 'androidx.multidex:multidex:2.0.0'
//
implementation 'de.hdodenhof:circleimageview:3.1.0'
//gson
implementation 'com.google.code.gson:gson:2.7'
//
implementation 'com.github.goweii:PictureSelector:v2.3.1'
//
implementation 'com.github.bumptech.glide:glide:4.6.1'
annotationProcessor 'com.github.bumptech.glide:compiler:4.6.1'
//Bmob
implementation 'cn.bmob.android:bmob-sdk:3.7.8'
implementation 'com.google.android.material:material:1.0.0-rc01'
implementation 'cn.bmob.android:bmob-sdk:3.7.8'
implementation "io.reactivex.rxjava2:rxjava:2.2.8"
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
implementation 'com.squareup.okhttp3:okhttp:3.14.1'
implementation 'com.squareup.okio:okio:2.2.2'
implementation 'com.google.code.gson:gson:2.8.5'
//
implementation 'com.github.yoyoyaobin:PreventKeyboardBlockUtil:1.0.8'
//cardView
implementation 'androidx.cardview:cardview:1.0.0'
/*retrofit、rxjava*/
implementation 'com.squareup.retrofit2:retrofit:2.6.2'
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.4.0'
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
implementation 'com.squareup.okhttp3:logging-interceptor:3.4.1'
/*YUtils*/
implementation 'com.github.yechaoa:YUtils:2.1.0'
/*BRVAH*/
implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.50'
/*banner*/
implementation 'com.youth.banner:banner:1.4.10'
//
implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.0.5.1'
//recyclerview
implementation 'androidx.recyclerview:recyclerview:1.0.0'
//
implementation 'com.github.maning0303:MNUpdateAPK:V2.0.3'
//bugly
implementation 'com.tencent.bugly:crashreport:3.2.3'
//
implementation 'com.github.moo611:OpenCamera:1.0.6'
//
implementation 'com.zackratos.ultimatebarx:ultimatebarx:0.2.0'
//
implementation 'com.permissionx.guolindev:permissionx:1.3.0'
//xpopup
implementation 'com.lxj:xpopup:2.0.8-rc5'
}

@ -0,0 +1,22 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

@ -0,0 +1,27 @@
package com.cwj.we;
import android.content.Context;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
assertEquals("com.cwj.we", appContext.getPackageName());
}
}

@ -0,0 +1,119 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.cwj.we">
<uses-permission android:name="android.permission.INTERNET" /> <!-- 连接互联网Internet权限 -->
<uses-permission android:name="android.permission.CAMERA" /> <!-- 拍照权限 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- 获取GSM2g、WCDMA联通3g等网络状态的信息 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <!-- 获取wifi网络状态的信息 -->
<uses-permission android:name="android.permission.WAKE_LOCK" /> <!-- 保持CPU 运转,屏幕和键盘灯有可能是关闭的,用于文件上传和下载 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <!-- 获取sd卡写的权限用于文件上传和下载 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" /> <!-- 允许程序访问电话状态 -->
<!-- 集成百度自动更新安装必须权限 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <!-- 读取设备外部存储空间内置SDcard和外置SDCard的文件 -->
<uses-permission android:name="android.permission.REPLACE_EXISTING_PACKAGE" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" /> <!-- 8.0必要权限 -->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission
android:name="android.permission.READ_LOGS"
tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-feature android:name="android.hardware.camera" />
<application
android:name=".app.App"
android:allowBackup="true"
android:icon="@drawable/logo"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme"
android:usesCleartextTraffic="true">
<activity
android:name=".module.ljxj.OpenCameraActivity"
android:screenOrientation="portrait"
tools:ignore="LockedOrientationActivity" />
<activity
android:name=".module.lpclock.LPClockActivity"
android:screenOrientation="portrait"
tools:ignore="LockedOrientationActivity" />
<activity
android:name=".module.activity.ChangePasswordActivity"
android:screenOrientation="portrait"
tools:ignore="LockedOrientationActivity" />
<activity
android:name=".module.activity.RegisterActivity"
android:screenOrientation="portrait"
tools:ignore="LockedOrientationActivity" />
<activity
android:name=".module.activity.LoginActivity"
android:launchMode="singleTask"
android:screenOrientation="portrait"
tools:ignore="LockedOrientationActivity" />
<activity
android:name=".module.activity.GobangActivity"
android:screenOrientation="portrait"
tools:ignore="LockedOrientationActivity" />
<activity
android:name=".module.activity.PuzzleActivity"
android:screenOrientation="portrait"
tools:ignore="LockedOrientationActivity" />
<activity
android:name=".module.about.AboutActivity"
android:screenOrientation="portrait"
tools:ignore="LockedOrientationActivity" />
<activity
android:name=".module.activity.ClockActivity"
android:screenOrientation="portrait"
tools:ignore="LockedOrientationActivity" />
<activity
android:name=".module.activity.CompassActivity"
android:screenOrientation="portrait"
tools:ignore="LockedOrientationActivity" />
<activity
android:name=".module.activity.GameActivity"
android:screenOrientation="portrait"
tools:ignore="LockedOrientationActivity" />
<activity
android:name=".module.activity.AircraftBattleActivity"
android:screenOrientation="portrait"
tools:ignore="LockedOrientationActivity" />
<activity
android:name=".module.activity.CalculatorActivity"
android:screenOrientation="portrait"
tools:ignore="LockedOrientationActivity" />
<activity
android:name=".module.activity.HomeActivity"
android:launchMode="singleTask"
android:screenOrientation="portrait"
tools:ignore="LockedOrientationActivity" />
<activity
android:name=".module.activity.SetTimeActivity"
android:screenOrientation="portrait"
tools:ignore="LockedOrientationActivity" />
<activity
android:name=".module.activity.WebViewActivity"
android:screenOrientation="portrait"
tools:ignore="LockedOrientationActivity" />
<activity
android:name=".module.activity.SplashActivity"
android:screenOrientation="portrait"
tools:ignore="LockedOrientationActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider
android:name="cn.bmob.v3.util.BmobContentProvider"
android:authorities="com.cwj.we.BmobContentProvider" /> <!-- 设置BmobAppKey -->
<meta-data
android:name="Bmob_APP_KEY"
android:value="6b641f364905d608449772bae45f7b60" />
</application>
</manifest>

@ -0,0 +1,78 @@
img.preloadImg {
display: block; outline: none; border: none;
width: 100%; height: 100%;
-webkit-transition-property: -webkit-transform; -webkit-transition-duration: 1s;
-moz-transition-property: -moz-transform; -moz-transition-duration: 1s;
transition-property: transform; transition-duration: 1s;
-webkit-animation-name: rotate; -webkit-animation-duration: 2s; -webkit-animation-iteration-count: infinite; -webkit-animation-timing-function: linear;
-moz-animation-name: rotate; -moz-animation-duration: 2s; -moz-animation-iteration-count: infinite; -moz-animation-timing-function: linear;
animation-name: rotate; animation-duration: 2s; animation-iteration-count: infinite; animation-timing-function: linear;
}
@-webkit-keyframes rotate {
from {-webkit-transform: rotate(0deg);}
to {-webkit-transform: rotate(360deg);}
}
@-moz-keyframes rotate {
from {-moz-transform: rotate(0deg);}
to {-moz-transform: rotate(360deg);}
}
@keyframes rotate {
from {transform: rotate(0deg);}
to {transform: rotate(360deg);}
}
.loadingTxt {
position: absolute;
top: -20%;
left: 0px;
line-height: 50%;
text-align: center;
font-family: Neuropol, Arial;
width: 100%;
height: 100%;
color: #ff0000;
}
img, #score {
outline: none;
border: none;
opacity: 0.9;
-webkit-user-drag: none;
-khtml-user-drag: none;
-moz-user-drag: none;
-o-user-drag: none;
user-drag: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-o-user-select: none;
user-select: none;
}
#inputdiv {
position: fixed;
overflow: hidden;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
}
@font-face {
font-family: 'Neuropol';
src: url('../font/Neuropol-Regular.eot');
src: url('../font/Neuropol-Regular.eot?#iefix') format('embedded-opentype'),
url('../font/Neuropol-Regular.woff2') format('woff2'),
url('../font/Neuropol-Regular.woff') format('woff'),
url('../font/Neuropol-Regular.ttf') format('truetype'),
url('../font/Neuropol-Regular.svg#Neuropol-Regular') format('svg');
font-weight: normal;
font-style: normal;
}
#btnHome { position: absolute;width: 35%;height: 24.5%;top: 28%;left: 31.5%;cursor: pointer; display: none; }
#btnHome img { position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; }
#btnStart { position: absolute; width: 45%; height: 31%; top: 60%; left: 26.5%; cursor: pointer; }
#btnStart img { position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; }
#btnSound { position: fixed; top: 0; right: 0; 10%; height: 10%; display: block; z-index: 3; background-image: url('../img/sound.png'); background-size: 300px 89px; }
#score { position: absolute; top: 10%; left: 10%; width: 80%; height: 30%; color: #fff; font-family: Neuropol, Consolas; text-align: center;font-size: 250%; }
#curtain { width: 100%; height: 100%; background-color: #000; z-index: 100; position: fixed; top: 0px; left: 0px; }
#progress { width: 0%; height: 100%; overflow: hidden; position: absolute; top: 0px; left: 0px; }
#imgBkg { width: 100%; height: 100%; position: absolute; }

@ -0,0 +1,17 @@
html, body {
overflow: hidden;
width: 100%;
height: 100%;
margin: 0;
padding: 0;
background-color: #000;
}
#renderCanvas {
position: fixed;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
outline: 0;
}

@ -0,0 +1,23 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="mobile-web-app-capable" content="yes" />
<title>H5霓虹球3D滚动游戏</title>
<script src="js/bjs.js"></script>
<script src="js/babylon.gui.min.js"></script>
<script src="js/howler.min.js"></script>
<script src="js/TweenLite.min.js"></script>
<link href="css/stylesheet.css" rel="stylesheet" />
<link href="css/extrastyles.css" rel="stylesheet" />
</head>
<body>
<canvas id="renderCanvas"></canvas>
<script src="js/game.min.js"></script>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 983 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1,62 @@
var GameUtils=function(){};GameUtils.detectIE=function(){var d=window.navigator.userAgent,f=d.indexOf("MSIE "),k=d.indexOf("Trident/");d=d.indexOf("Edge/");return 0<f||0<k||0<d?!0:!1};GameUtils.getParameterByName=function(d,f){f||(f=window.location.href);d=d.replace(/[\[\]]/g,"\\$&");return(d=(new RegExp("[?&]"+d+"(=([^&#]*)|&|#|$)")).exec(f))?d[2]?decodeURIComponent(d[2].replace(/\+/g," ")):"":null};
GameUtils.isMobile=function(){return/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|ipad|iris|kindle|Android|Silk|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(navigator.userAgent)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(navigator.userAgent.substr(0,
4))?!0:!1};GameUtils.RandomInt=function(d,f){return d+Math.floor((f-d+1)*Math.random())|0};GameUtils.RandomFloat=function(d,f){return d===f?d:d+(f-d+1)*Math.random()};GameUtils.Shuffle=function(d){var f;for(f=d.length-1;0<f;f--){var k=Math.floor(Math.random()*(f+1));var h=d[f];d[f]=d[k];d[k]=h}};GameUtils.RoundTo=function(d,f){var k=!1;void 0===f&&(f=0);0>d&&(k=!0,d*=-1);var h=Math.pow(10,f);d=parseFloat((d*h).toFixed(11));d=(Math.round(d)/h).toFixed(f);k&&(d=(-1*d).toFixed(f));return parseFloat(d)};var SoundManager=function(){var d=new Howl({src:["sound/loop.mp3","sound/loop.ogg"],loop:!0,autoplay:!0,volume:.3}),f=!0,k=GameUtils.detectIE(),h=[new Howl({src:["sound/ping1.mp3","sound/ping1.ogg"],volume:.8}),new Howl({src:["sound/click.mp3","sound/click.ogg"],volume:.3}),new Howl({src:["sound/whoop.mp3","sound/whoop.ogg"],volume:.3}),new Howl({src:["sound/whoop2.mp3","sound/whoop2.ogg"],volume:.3}),new Howl({src:["sound/whoop3.mp3","sound/whoop3.ogg"],volume:.3}),new Howl({src:["sound/balldie.mp3",
"sound/balldie.ogg"],volume:.5}),new Howl({src:["sound/speedup.mp3","sound/speedup.ogg"],volume:.4}),new Howl({src:["sound/balldie2.mp3","sound/balldie2.ogg"],volume:.5})];this.play=function(c,d,n){f&&(k&&1<d&&(d=1),void 0!==c&&(void 0!==d&&(h[c]._volume=d),void 0!==n&&(h[c]._loop=n),h[c].play(),void 0!==d&&(h[c]._volume=d)))};this.stop=function(c,d){d?(h[c]._originalVolume=h[c]._volume,h[c].fade(h[c]._volume,0,800),h[c].once("fade",function(){h[c].stop();h[c]._volume=h[c]._originalVolume})):h[c].stop()};
this.stopMusic=function(){d.pause()};this.playMusic=function(){d.play()};this.mute=function(){f=!1;d.pause()};this.unmute=function(){f=!0;d.play()};this.isMuted=function(){return f};this.soundOn=f};var HTMLGUI=function(d){var f=document.createElement("div");f.id="htmlgui";document.body.appendChild(f);f=d.isMobile;var k=!0;document.getElementById("htmlgui").innerHTML='<div id="inputdiv"><div id="scorebox" style="opacity: 0.0; position: fixed; z-index: 30; display: inline-block;"><img style="width: 100%; height: 100%;" src="img/scorebox.png" /><div id="progress">\t<img id="imgprogress" src="img/gameprogress.png" /></div><div id="score">0000</div></div></div><div id="menuDiv" style="display: none; z-index: 2; position: fixed;">\t<img id="imgBkg" src="img/menubkg.png" />\t<div id="btnHome">\t\t<img class="play0" src="img/home.png" />\t</div>\t<div id="btnStart">\t\t<img class="play0" src="img/play0.png" />\t</div></div><div id="btnSound"></div><div id="curtain" style="opacity: 1;"></div>';
var h=document.getElementById("menuDiv"),c=window.innerHeight<window.innerWidth?window.innerHeight:window.innerWidth;h.style.width=c/1.8*.7+"px";h.style.height=c/1.8+"px";h.style.left=(window.innerWidth-window.innerHeight/1.8*.7)/2+"px";h.topInPixels=(window.innerHeight-window.innerHeight/1.8)/3.8;h.style.top=h.topInPixels+"px";var A=document.getElementById("btnHome"),n=document.getElementById("btnStart"),l=document.getElementById("btnSound"),u=document.getElementById("curtain"),q=document.getElementById("scorebox"),
r=document.getElementById("progress"),y=document.getElementById("imgprogress"),C=document.getElementById("score"),D=function(a,c){a?(h.style.display="block",!0===c?(A.style.display="block",O(!1)):A.style.display="none"):(h.style.display="none",A.style.display="none")},G=function(){k=!0;D(!1);u.style.display="block";u.style.opacity="0";TweenLite.to(u.style,.3,{opacity:1,onComplete:function(){d.showHomeScene();TweenLite.to(u.style,.3,{opacity:0,onComplete:function(){u.style.display="none"}})}})},K=
function(a,c){a?(u.style.display="block",TweenLite.to(u.style,.3,{opacity:1,onComplete:function(){c&&c()}})):TweenLite.to(u.style,.3,{opacity:0,onComplete:function(){u.style.display="none";c&&c()}})},O=function(a){var d=window.innerHeight,h=window.innerWidth;c=d<h?d:h;a?(S(c/8,.5),TweenLite.to(q.style,.5,{opacity:1})):(S(c/12,.5),TweenLite.to(q.style,.5,{opacity:.5}))};A.addEventListener(f?"touchstart":"mousedown",function(){TweenLite.to(q.style,.4,{opacity:0});G();d.sound.play(1)});l.addEventListener(f?
"touchstart":"mousedown",function(){d.sound.isMuted()?(l.style.backgroundPosition="98% 0%",d.sound.mute()):(l.style.backgroundPosition="0% 0%",d.sound.unmute());d.sound.play(1)});var E=function(a){a=Math.ceil(a);return 9>a?"000"+a:99>a?"00"+a:999>a?"0"+a:""+a},a=function(){TweenLite.killTweensOf(d);d.score=0;C.innerHTML=E(d.score)},v=function(){a();D(!1);d.startNewGame(k);k=!1};n.addEventListener(f?"touchstart":"mousedown",function(){d.sound.play(1);k?v():K(!0,v)});var S=function(a,c){TweenLite.to(q.style,
c,{height:a+"px",width:2.4*a+"px",left:(window.innerWidth-2.4*a)/2+"px"});TweenLite.to(y,c,{width:2.4*a,height:a});TweenLite.to(C.style,c,{fontSize:a/2.625+"px"})},H=-1,L=-1;this.setScore=function(a){TweenLite.to(d,100>a?.1:.4,{score:"+="+a,roundProps:"score",onUpdate:function(){C.innerHTML=E(d.score)}})};this.resetScore=a;this.setProgress=function(a){r.style.width=a};this.resetProgress=function(){r.style.width="0%"};this.toggleMenu=D;this.toggleCurtain=K;this.toggleScoreBox=O;this.resize=function(a){H!==
window.innerWidth&&(H=window.innerWidth,L=window.innerHeight,c=L<H?L:H,a=L>H?1.4:1.8,h.style.width=c/a*.7+"px",h.style.height=c/a+"px",h.style.left=(H-c/a*.7)/2+"px",h.topInPixels=(L-c/a)/2,h.style.top=h.topInPixels+"px",l.style.height=l.style.width=c/8+"px",l.style.top=l.style.right=c/8/8+"px",l.style.backgroundSize=c/7.9*2+"px "+c/7.9+"px",c/=d.isRunning?8:12,q.style.width=y.width=2.4*c+"px",q.style.height=y.height=c+"px",q.style.left=(H-2.4*c)/2+"px",C.style.fontSize=c/2.625+"px")}};var GUI=function(d){var f=!0,k=BABYLON.GUI,h=k.AdvancedDynamicTexture.CreateFullscreenUI("gameui",!0,d.scene);h.idealWidth=window.innerWidth;h.fontFamily="Neuropol";var c=new BABYLON.GUI.Rectangle;c.cornerRadius=0;c.thickness=0;var A=new k.Image("menuHeaderImg","img/menubkg.png");A.stretch=k.Image.STRETCH_UNIFORM;A.horizontalAlignment=k.Control.HORIZONTAL_ALIGNMENT_CENTER;A.verticalAlignment=k.Control.VERTICAL_ALIGNMENT_CENTER;c.addControl(A);h.addControl(c);c.isVisible=!1;var n=[],l=new k.Image("btnHome",
"img/home.png");l.isVisible=!1;l.width="35%";l.height="24.5%";l.top="28%";c.addControl(l);n.push(l);A=new k.Image("btnHome","img/play0.png");A.width="45%";A.height="31%";A.top="60%";c.addControl(A);n.push(A);n.forEach(function(a){a.stretch=k.Image.STRETCH_UNIFORM;a.horizontalAlignment=k.Control.HORIZONTAL_ALIGNMENT_CENTER;a.verticalAlignment=k.Control.VERTICAL_ALIGNMENT_TOP;a.thickness=0});var u=new k.Image("btnHome","img/soundon.png");h.addControl(u);var q=new k.Image("btnHome","img/soundoff.png");
q.isVisible=!1;h.addControl(q);u.stretch=q.stretch=k.Image.STRETCH_UNIFORM;u.horizontalAlignment=q.horizontalAlignment=k.Control.HORIZONTAL_ALIGNMENT_RIGHT;u.verticalAlignment=q.verticalAlignment=k.Control.VERTICAL_ALIGNMENT_TOP;u.thickness=q.thickness=0;var r=new k.Rectangle;r.height="40px";r.cornerRadius=0;r.thickness=0;r.alpha=0;r.verticalAlignment=k.Control.VERTICAL_ALIGNMENT_TOP;h.addControl(r);n=new k.Image("scorebox","img/scorebox.png");r.addControl(n);var y=new k.Rectangle;y.horizontalAlignment=
k.Control.HORIZONTAL_ALIGNMENT_LEFT;y.width="100%";y.height="100%";y.cornerRadius=0;y.thickness=0;y.top="0px";y.left="0px";var C=new k.Image("progress","img/gameprogress.png");C.horizontalAlignment=k.Control.HORIZONTAL_ALIGNMENT_LEFT;y.addControl(C);r.addControl(y);n=function(a){var c=new k.Rectangle;c.thickness=0;c.top="-12%";c.width="16%";c.height="40%";c.horizontalAlignment=k.Control.HORIZONTAL_ALIGNMENT_LEFT;var d=new k.Image("num","img/font.png");d.width="100%";d.height="1000%";d.verticalAlignment=
k.Control.VERTICAL_ALIGNMENT_TOP;d.paddingTop="0%";c.addControl(d);a.addControl(c);this.setValue=function(a){d.top=100*-a+"%"};this.setLeft=function(a){c.left=a}};var D=new n(r);D.setLeft("20%");var G=new n(r);G.setLeft("35.5%");var K=new n(r);K.setLeft("51%");var O=new n(r);O.setLeft("66%");var E=function(a){a=Math.floor(a);for(var c=[];0<a;)c.unshift(a%10*1),a=Math.floor(a/10);return c},a=new k.Image("curtain","img/black.png");a.width="100%";a.height="100%";h.addControl(a);var v=function(a,d){a?
(c.isVisible=!0,!0===d?(l.isVisible=!0,L(!1)):l.isVisible=!1):(c.isVisible=!1,l.isVisible=!1)},S=function(){f=!0;v(!1,!1,!1);a.isVisible=!0;a.alpha=0;TweenLite.to(a,.3,{alpha:1,onComplete:function(){d.showHomeScene();TweenLite.to(a,.3,{alpha:0,onComplete:function(){a.isVisible=!1}})}})},H=function(c,d){c?(a.isVisible=!0,TweenLite.to(a,.3,{alpha:1,onComplete:function(){d&&d()}})):TweenLite.to(a,.3,{alpha:0,onComplete:function(){a.isVisible=!1;d&&d()}})},L=function(a){var c=window.innerHeight,d=window.innerWidth;
dim=c<d?c:d;a?(TweenLite.to(r,.5,{alpha:1,height:dim/8+"px",width:dim/8*2.4+"px"}),TweenLite.to(C,.5,{height:dim/8+"px",width:dim/8*2.4+"px"})):(TweenLite.to(r,.5,{alpha:.5,height:dim/12+"px",width:dim/12*2.4+"px"}),TweenLite.to(C,.5,{height:dim/12+"px",width:dim/12*2.4+"px"}))};l.onPointerDownObservable.add(function(){TweenLite.to(r,.4,{alpha:0});S();d.sound.play(1)});var ha=function(a){a?(u.isVisible=!1,q.isVisible=!0,d.sound.mute()):(u.isVisible=!0,q.isVisible=!1,d.sound.unmute())};u.onPointerDownObservable.add(function(){ha(!0);
d.sound.play(1)});q.onPointerDownObservable.add(function(){ha(!1);d.sound.play(1)});var ia=function(a){a=d.score+=a;a=Math.ceil(a);9>a?(D.setValue(0),G.setValue(0),K.setValue(0),O.setValue(a)):99>a?(D.setValue(0),G.setValue(0),a=E(a),K.setValue(a[0]),O.setValue(a[1])):999>a?(D.setValue(0),a=E(a),G.setValue(a[0]),K.setValue(a[1]),O.setValue(a[2])):(a=E(a),D.setValue(a[0]),G.setValue(a[1]),K.setValue(a[2]),O.setValue(a[3]))},ja=function(){TweenLite.killTweensOf(d);d.score=0;ia(d.score)},ka=function(){r.top=
"0px";r.alpha=0;ja();v(!1,!1,!1);d.startNewGame(f);f=!1};A.onPointerDownObservable.add(function(){d.sound.play(1);f?ka():H(!0,ka)});this.setScore=ia;this.resetScore=ja;this.setProgress=function(a){y.width=a};this.resetProgress=function(){y.width="0px"};this.toggleMenu=v;this.toggleCurtain=H;this.toggleScoreBox=L;this.resize=function(a){h.idealWidth=window.innerWidth;a=window.innerHeight;var f=window.innerWidth;dim=a<f?a:f;f=a>f?1.4:1.8;c.width=dim/f*.7+"px";c.height=dim/f+"px";c.topInPixels=(a-dim/
f)/3.2;c.top=c.topInPixels+"px";u.height=q.height=dim/8+"px";u.width=q.width=dim/8+dim/8/8+"px";u.top=u.paddingRight=q.top=q.paddingRight=dim/8/8+"px";a=d.isRunning?8:12;r.height=dim/a+"px";r.width=dim/a*2.4+"px";C.width=dim/a*2.4+"px";C.height=dim/a+"px"}};(function(){new function(){var d=document.getElementById("renderCanvas"),f=!0,k=!0,h=new BABYLON.Engine(d,!0,{preserveDrawingBuffer:!1,disableWebGL2Support:!0}),c=new BABYLON.Scene(h),A,n,l,u,q=new SoundManager,r,y=!0,C=1,D=!1,G=GameUtils.isMobile(),K=0,O="0% 14% 21% 28% 35% 42% 49% 56% 63% 70% 77% 84% 89% 94%".split(" "),E,a,v,S,H,L,ha,ia,ja,ka,va,wa,xa,ya,za,oa,Aa,Ba,Ca,la=[],P,Q,da=!1,g=GameUtils.getParameterByName("glow");null!==g&&""!==g&&(da="true"===g);var Da=!1;g=GameUtils.getParameterByName("glowd");
null!==g&&""!==g&&(Da="true"===g);var ra=!0;g=GameUtils.getParameterByName("sky");null!==g&&""!==g&&(ra="true"===g);var T=!0;g=GameUtils.getParameterByName("mirror");null!==g&&""!==g&&(T="true"===g);var ma=!0;g=GameUtils.getParameterByName("tpe");null!==g&&""!==g&&(ma="true"===g);var sa=!0;g=GameUtils.getParameterByName("epe");null!==g&&""!==g&&(sa="true"===g);var ta=!0;g=GameUtils.getParameterByName("hgui");null!==g&&""!==g&&(ta="true"===g);var Ea=!0;g=GameUtils.getParameterByName("aop");null!==
g&&""!==g&&(Ea="true"===g);var ea=function(b){!D||0===a.velocity.length()||.73>a.position.y||(1==C?(C=0,a.velocity.set(P,0,0),a.rotSpeed.set(0,0,Q)):(C=1,a.velocity.set(0,0,P),a.rotSpeed.set(Q,0,0)),q.play(GameUtils.RandomInt(2,4)))},W=this;if(ta){var J=new HTMLGUI(W);document.getElementById("inputdiv").addEventListener(G?"touchstart":"pointerdown",ea);var U=document.createElement("div");U.style.position="absolute";var R=document.createElement("img");R.src="img/loader.jpg";R.className="preloadImg";
U.appendChild(R);var Z=document.createElement("div");Z.id="loadedpercent";Z.className="loadingTxt";Z.innerHTML="0%";U.appendChild(Z);document.getElementById("curtain").appendChild(U);var na=function(){U.style.width=U.style.height=(window.innerWidth>window.innerHeight?window.innerHeight/6:window.innerWidth/6)+"px";Z.style.fontSize=(window.innerWidth>window.innerHeight?window.innerHeight/30:window.innerWidth/30)+"px";var a=window.innerWidth/2-R.width/2;U.style.top=window.innerHeight/2-R.height/2+"px";
U.style.left=a+"px"};na();window.addEventListener("resize",na);window.addEventListener("deviceorientation",na)}else J=new GUI(W),c.preventDefaultOnPointerDown=!0,document.addEventListener(G?"touchstart":"pointerdown",function(a){ea()}),G&&document.addEventListener("touchmove",function(a){a=a.originalEvent||a;1!==a.scale&&a.preventDefault()},!1);G||document.addEventListener("keydown",ea);var w=BABYLON.Color4,z=BABYLON.Color3,Fa=BABYLON.Texture,B=BABYLON.Vector3,X=BABYLON.StandardMaterial;g=new BABYLON.AssetsManager(c);
g.useDefaultLoadingScreen=!1;g.onProgress=function(a,c,d){document.getElementById("loadedpercent").innerHTML=100-Math.ceil(100*a/c)+"%"};var aa=function(a,d,f){var b=new X(a,c);b.diffuseTexture=d;console.log(da);da&&(b.emissiveTexture=b.diffuseTexture,b.emissiveColor=z.FromHexString(f));b.specularColor=z.Black();b.freeze();switch(a){case "ball1Mat":S=b;ha=b.clone("ball1MatClone");break;case "ball2Mat":H=b;break;case "ball3Mat":L=b}},F=g.addTextureTask("ball1Tex","img/ball1.png");F.onSuccess=function(a){aa("ball1Mat",
a.texture,"#ffff00")};F=g.addTextureTask("ball2Tex","img/ball2.png");F.onSuccess=function(a){aa("ball2Mat",a.texture,"#00f011")};F=g.addTextureTask("ball3Tex","img/ball3.png");F.onSuccess=function(a){aa("ball3Mat",a.texture,"#dc0000")};var ba=function(a,d){var b=new X(a,c);b.diffuseTexture=d;b.backFaceCulling=!1;b.cameraExposure=2;b.cameraContrast=1.3;b.freeze();switch(a){case "sky1Mat":oa=b;la.push(oa);break;case "sky2Mat":Aa=b;la.push(Aa);break;case "sky3Mat":Ba=b;la.push(Ba);break;case "sky4Mat":Ca=
b,la.push(Ca)}};g.addTextureTask("sky1Tex","img/sky/1.jpg").onSuccess=function(a){ba("sky1Mat",a.texture)};g.addTextureTask("sky2Tex","img/sky/2.jpg").onSuccess=function(a){ba("sky2Mat",a.texture)};g.addTextureTask("sky13Tex","img/sky/3.jpg").onSuccess=function(a){ba("sky3Mat",a.texture)};g.addTextureTask("sky4Tex","img/sky/4.jpg").onSuccess=function(a){ba("sky4Mat",a.texture)};var M=function(a,d){var b=new X(a,c);b.diffuseTexture=b.specularTexture=d;switch(a){case "bmat1":ia=b;break;case "bmat2":ja=
b;break;case "bmat3":ka=b;break;case "bmat4":va=b;break;case "bmat5":wa=b;break;case "bmat6":xa=b;break;case "bmat7":ya=b;break;case "bmat8":za=b}};F=g.addTextureTask("tile1Tex","img/tiles1.jpg");F.onSuccess=function(a){M("bmat1",a.texture)};F=g.addTextureTask("tile2Tex","img/tiles2.jpg");F.onSuccess=function(a){M("bmat2",a.texture)};F=g.addTextureTask("tile3Tex","img/tiles3.jpg");F.onSuccess=function(a){M("bmat3",a.texture)};g.addTextureTask("tile4Tex","img/tiles4.jpg").onSuccess=function(a){M("bmat4",
a.texture)};g.addTextureTask("tile5Tex","img/tiles5.jpg").onSuccess=function(a){M("bmat5",a.texture)};g.addTextureTask("tile6Tex","img/tiles6.jpg").onSuccess=function(a){M("bmat6",a.texture)};g.addTextureTask("tile7Tex","img/tiles7.jpg").onSuccess=function(a){M("bmat7",a.texture)};g.addTextureTask("tile8Tex","img/tiles8.jpg").onSuccess=function(a){M("bmat8",a.texture)};g.onFinish=function(b){function g(a,c){trailParticles=new BABYLON.ParticleSystem("particles",800,c);trailParticles.particleTexture=
new BABYLON.Texture("img/star.jpg",c);trailParticles.emitter=a;trailParticles.minEmitBox=new B(-.15,.01,-.15);trailParticles.maxEmitBox=new B(.15,-.01,.15);trailParticles.color1=new w(.9,.1,0,1);trailParticles.color2=new w(.9,.2,0,1);trailParticles.colorDead=new w(0,0,1,0);trailParticles.minSize=.1;trailParticles.maxSize=.2;trailParticles.minLifeTime=.1;trailParticles.maxLifeTime=.3;trailParticles.emitRate=350;trailParticles.blendMode=BABYLON.ParticleSystem.BLENDMODE_ONEONE;trailParticles.gravity=
new B(0,-.5,0);trailParticles.direction1=new B(-.1,.5,-.1);trailParticles.direction2=new B(.1,.5,.1);trailParticles.minAngularSpeed=0;trailParticles.maxAngularSpeed=Math.PI;trailParticles.minEmitPower=.5;trailParticles.maxEmitPower=1.5;trailParticles.updateSpeed=.005}this.canvas=d;this.isMobile=G;var F=[{x:-.42,z:-.95},{x:-2.5,z:-.55},{x:-1.14,z:.44},{x:2.43,z:-.51},{x:-1.41,z:-.61},{x:-.48,z:.8},{x:2.06,z:-.93},{x:1.6,z:.79},{x:-.07,z:-.55},{x:-.1,z:.69}],M={l1:{tile:ia,particles:[new w(.5,1,1,1),
new w(.5,1,1,1)],diamond:new z(.5,1,1)},l2:{tile:ja,particles:[new w(1,.2,1,1),new w(1,.2,1,1)],diamond:new z(1,.2,1)},l3:{tile:ka,particles:[new w(1,1,0,1),new w(1,1,0,1)],diamond:new z(1,1,0)},l4:{tile:va,particles:[new w(1,1,0,1),new w(1,1,0,1)],diamond:new z(1,1,0)},l5:{tile:wa,particles:[new w(1,.5,0,1),new w(1,.5,0,1)],diamond:new z(1,.5,0)},l6:{tile:xa,particles:[new w(1,0,0,1),new w(1,0,0,1)],diamond:new z(1,0,0)},l7:{tile:ya,particles:[new w(.1,1,.1,1),new w(.1,1,.1,1)],diamond:new z(.1,
1,.1)},l8:{tile:za,particles:[new w(1,1,1,1),new w(1,1,1,1)],diamond:new z(1,1,1)}};c.clearColor=new z(.18,.18,.18);var fa=[];if(sa)for(b=0;8>b;++b){var e=new BABYLON.ParticleSystem("particles",300,c);e.particleTexture=new Fa("img/star.jpg",c);e.emitter=B.Zero();e.createSphereEmitter(.6);e.color1=new w(1,.1,0,1);e.color2=new w(1,.1,0,1);e.colorDead=new w(.2,0,0,0);e.minSize=.1;e.maxSize=.18;e.minLifeTime=.4;e.maxLifeTime=.8;e.emitRate=2E3;e.gravity=new B(0,-8.5,0);e.blendMode=BABYLON.ParticleSystem.BLENDMODE_ONEONE;
e.minAngularSpeed=.2;e.maxAngularSpeed=Math.PI;e.minEmitPower=1;e.maxEmitPower=3;e.updateSpeed=.01;fa.push(e)}n=new BABYLON.ArcRotateCamera("Camera",3.9925,.6938,10,B.Zero(),c);A=new BABYLON.HemisphericLight("dirlight",new B(0,1,0),c);c.workerCollisions=!0;P=.07;Q=.15;a=BABYLON.Mesh.CreateSphere("ball",10,.5,c);a.position.y=-.6;a.position.x=-.4;a.velocity=new B(0,0,0);a.rotSpeed=new B(0,0,0);a.checkCollisions=!0;a.ellipsoid=new B(.25,.25,.25);a.isPickable=!1;a.material=S;v=BABYLON.Mesh.CreateSphere("ball2",
10,.5,c);v.position.y=-.6;v.position.z=-.3;v.position.x=-2;v.velocity=new B(0,0,0);v.rotSpeed=new B(0,0,0);v.material=H;v.isPickable=!1;ball3=BABYLON.Mesh.CreateSphere("ball3",10,.5,c);ball3.position.y=-.6;ball3.position.z=-.3;ball3.position.x=2;ball3.velocity=new B(0,0,0);ball3.rotSpeed=new B(0,0,0);ball3.material=L;ball3.isPickable=!1;var R=new B(0,0,0),t=[];b=new BABYLON.Mesh("speedUp1",c);b.level={moveSpeed:.084,rotSpeed:.19};b.val=50;b.ball=a;b.setVerticesData("position",new Float32Array([-4.8,
-.5,2.7,0,-.5,3.3,-4.8,-.5,1.3,4.8,-.5,2.7,0,-.5,4.7,-4.8,-.5,-.3,0,-.5,.3,-4.8,-.5,-1.7,4.8,-.5,-.3,0,-.5,1.7,-4.8,-.5,-3.2,0,-.5,-2.6,-4.8,-.5,-4.6,4.8,-.5,-3.2,0,-.5,-1.2,0,.5,3.3,-4.8,.5,2.7,-4.8,.5,1.3,4.8,.5,2.7,0,.5,4.7,0,.5,.3,-4.8,.5,-.3,-4.8,.5,-1.7,4.8,.5,-.3,0,.5,1.7,0,.5,-2.6,-4.8,.5,-3.2,-4.8,.5,-4.6,4.8,.5,-3.2,0,.5,-1.2,4.8,.5,-4.6,4.8,-.5,-4.6,4.8,.5,-1.7,4.8,-.5,-1.7,4.8,.5,1.3,4.8,-.5,1.3]));b.setVerticesData("normal",new Float32Array([-.665,-.601,.4433,0,-.8047,-.5936,-.4598,-.5594,
-.6897,.665,-.601,.4433,0,-.6299,.7766,-.665,-.601,.4433,0,-.8047,-.5936,-.4598,-.5594,-.6897,.665,-.601,.4433,0,-.6299,.7766,-.665,-.601,.4433,0,-.8047,-.5936,-.4598,-.5594,-.6897,.665,-.601,.4433,0,-.6299,.7766,0,.8047,-.5936,-.665,.601,.4433,-.4598,.5594,-.6897,.665,.601,.4433,0,.6299,.7766,0,.8047,-.5936,-.665,.601,.4433,-.4598,.5594,-.6897,.665,.601,.4433,0,.6299,.7766,0,.8047,-.5936,-.665,.601,.4433,-.4598,.5594,-.6897,.665,.601,.4433,0,.6299,.7766,.4598,.5594,-.6897,.4598,-.5594,-.6897,.4598,
.5594,-.6897,.4598,-.5594,-.6897,.4598,.5594,-.6897,.4598,-.5594,-.6897]));b.setIndices(new Int16Array([0,1,2,3,1,4,5,6,7,8,6,9,10,11,12,13,11,14,15,16,17,15,18,19,20,21,22,20,23,24,25,26,27,25,28,29,10,29,14,5,24,9,0,19,4,13,30,31,8,32,33,3,34,35,31,25,11,33,20,6,35,15,1,14,28,13,9,23,8,4,18,3,12,26,10,7,21,5,2,16,0,11,27,12,6,22,7,1,17,2,0,4,1,3,35,1,5,9,6,8,33,6,10,14,11,13,31,11,15,19,16,15,34,18,20,24,21,20,32,23,25,29,26,25,30,28,10,26,29,5,21,24,0,16,19,13,28,30,8,23,32,3,18,34,31,30,25,33,
32,20,35,34,15,14,29,28,9,24,23,4,19,18,12,27,26,7,22,21,2,17,16,11,25,27,6,20,22,1,15,17]));b.material=new X("speedUpMat",c);b.material.specularColor=z.Black();b.material.emissiveColor=z.FromHexString("#cccc00");b.material.diffuseColor=z.FromHexString("#ffff00");b.isPickable=!1;t.push(b);e=b.clone("speedUp11");e.level={moveSpeed:.091,rotSpeed:.21};e.val=150;e.ball=a;e.isPickable=!1;t.push(e);e=b.clone("speedUp12");e.level={moveSpeed:.1,rotSpeed:.23};e.val=200;e.ball=a;e.isPickable=!1;t.push(e);e=
b.clone("speedup13");e.level={moveSpeed:.107,rotSpeed:.25};e.val=250;e.ball=a;e.isPickable=!1;t.push(e);e=b.clone("speedUp2");e.level={moveSpeed:.114,rotSpeed:.27};e.val=300;e.ball=v;e.material=new X("speedUp2Mat",c);e.material.specularColor=z.Black();e.material.emissiveColor=z.FromHexString("#00c60f");e.material.diffuseColor=z.FromHexString("#00f011");e.isPickable=!1;t.push(e);var N=e.clone("speedUp21");N.level={moveSpeed:.121,rotSpeed:.29};N.val=350;N.ball=v;N.isPickable=!1;t.push(N);N=e.clone("speedUp22");
N.level={moveSpeed:.128,rotSpeed:.31};N.val=400;N.ball=v;N.isPickable=!1;t.push(N);e=e.clone("speedUp23");e.level={moveSpeed:.135,rotSpeed:.33};e.val=450;e.ball=v;e.isPickable=!1;t.push(e);b=b.clone("speedUp3");b.level={moveSpeed:.142,rotSpeed:.35};b.val=500;b.ball=ball3;b.material=new BABYLON.StandardMaterial("speedUp2Mat",c);b.material.specularColor=BABYLON.Color3.Black();b.material.emissiveColor=z.FromHexString("#c60000");b.material.diffuseColor=z.FromHexString("#dc0000");b.isPickable=!1;t.push(b);
e=b.clone("speedUp31");e.level={moveSpeed:.15,rotSpeed:.37};e.val=550;e.ball=ball3;e.isPickable=!1;t.push(e);e=b.clone("speedUp32");e.level={moveSpeed:.152,rotSpeed:.39};e.val=600;e.ball=ball3;e.isPickable=!1;t.push(e);b=b.clone("speedUp33");b.level={moveSpeed:.156,rotSpeed:.43};b.val=800;b.ball=ball3;b.isPickable=!1;t.push(b);for(b=0;b<t.length;++b)t[b].material.freeze(),t[b].position.x=-999999;var Z=function(a){if(sa){var c=fa.pop();c.emitter.copyFrom(a);c.start();setTimeout(function(){c.stop();
fa.unshift(c)},50)}},ba=new BABYLON.Mesh("mesh",c);ma&&g(ba,c);var Y=BABYLON.Mesh.CreateSphere("diamond",1,.18,c);Y.convertToFlatShadedMesh();Y.material=new X("diamondMat",c);Y.material.diffuseColor=z.FromHexString("#00e20b");Y.freezeWorldMatrix();Y.setEnabled(!1);var ca=BABYLON.Mesh.CreateBox("box0",1,c);ca.material=new X("boxMat",c);ca.material=M.l6.tile;ca.position.z=2;ca.freezeWorldMatrix();ca.setEnabled(!1);var p=[],m=[];for(b=0;10>b;++b)e=Y.createInstance("diamond"+b),e.isPickable=!1,m.push(e);
for(b=0;38>b;++b)e=ca.createInstance("box"+b),e.checkCollisions=!0,e.scaling.set(0,0,0),e.isPickable=!1,p.push(e);var x=BABYLON.Mesh.CreateGround("Mirror",12,12,1,c);x.scaling.set(3.6,1,3.6);x.position.y=-.7;x.position.x=0;x.position.z=0;x.checkCollisions=!0;x.isPickable=!1;l=BABYLON.Mesh.CreateGround("sky",1,1,1,c);l.scaling.set(150,1,150);l.position.y=10;l.position.x=0;l.position.z=0;if(T){E=new X("mirrorMat",c);E.reflectionTexture=new BABYLON.MirrorTexture("mirror",256,c,!0);E.reflectionTexture.mirrorPlane=
new BABYLON.Plane(0,-1,0,-.7);E.reflectionTexture.level=1.3;E.reflectionTexture.samples=1;E.reflectionTexture.blurKernel=10;x.material=E;A.excludedMeshes.push(x);x.material.reflectionTexture.renderList=[a,v,ball3,l];for(b=0;b<p.length;++b)x.material.reflectionTexture.renderList.push(p[b]);for(b=0;b<m.length;++b)x.material.reflectionTexture.renderList.push(m[b])}else x.setEnabled(!1),l.setEnabled(!1);ra||l.setEnabled(!1);for(b=0;b<c.meshes.length;++b)c.meshes[b].isPickable=!1;var I=[],V=[],ea=function(a){a=
M["l"+a];ca.material=a.tile;var c=GameUtils.RandomInt(0,3);l.material=la[c];Y.material.diffuseColor=a.diamond;da&&Da&&(Y.material.emissiveColor=a.diamond);ma&&(trailParticles.color1=a.particles[0],trailParticles.color2=a.particles[1]);for(c=0;c<fa.length;++c)fa[c].color1=a.particles[0],fa[c].color2=a.particles[1]};da&&(u=new BABYLON.GlowLayer("glow",c));var pa=new B(0,0,0),qa=new B(0,0,0),aa=function(){y=!0;T&&(x.position.y=E.reflectionTexture.mirrorPlane.d=-.7);ua();J.toggleCurtain(!1);pa.y=0;TweenLite.killTweensOf(a.velocity);
TweenLite.killTweensOf(a.rotSpeed);a.velocity.set(0,0,0);a.rotSpeed.set(0,0,0);R.set(-.35,-.18,.69);n.setTarget(R);n.alpha=3.99;n.beta=.87;n.position.set(-3.6,4.03,-3.05);n.radius=window.innerWidth<window.innerHeight?window.innerHeight/window.innerWidth*6:6.5;for(var c=0;c<p.length;++c)p[c].scaling.set(0,0,0);p[0].position.set(0,0,2);p[1].position.set(1,0,2);p[2].position.set(-1,0,2);p[3].position.set(-2,0,2);p[4].position.set(-2,0,3);p[5].position.set(-3,0,3);p[6].position.set(2,0,2);p[7].position.set(3,
0,2);p[8].position.set(3,0,1);for(c=0;c<m.length;++c)m[c].scaling.set(0,0,0),m[c].rotation.set(GameUtils.RandomFloat(Math.PI/6,Math.PI),GameUtils.RandomFloat(Math.PI/3,Math.PI),GameUtils.RandomFloat(Math.PI/2,Math.PI)),m[c].position.set(F[c].x,-.61,F[c].z);ball3.position.set(3,.75,.75);ball3.scaling.set(0,0,0);ball3.rotation.set(.2,4.9,2.45);v.position.set(0,.75,1.75);v.scaling.set(0,0,0);a.position.set(-2,.75,1.75);a.scaling.set(0,0,0);a.material=S;T&&(x.position.x=a.position.x+2,x.position.z=a.position.z+
2,l.position.x=a.position.x+48,l.position.z=a.position.z+48);for(c=0;c<t.length;++c)t[c].scaling.set(0,0,0),t[c].position.x=-1E5;ea(GameUtils.RandomInt(1,8));for(c=0;9>c;++c)8>c?TweenLite.to(p[c].scaling,.2,{delay:(c+1)/40,x:1,y:1,z:1}):TweenLite.to(p[c].scaling,.2,{delay:(c+1)/40,x:1,y:1,z:1,onComplete:function(){for(var c=0;c<m.length;++c)c<m.length-1?TweenLite.to(m[c].scaling,.2,{delay:(c+1)/40,x:1,y:1,z:1}):TweenLite.to(m[c].scaling,.2,{delay:(c+1)/40,x:1,y:1,z:1,onComplete:function(){TweenLite.to(a.scaling,
.2,{x:1,y:1,z:1,onComplete:function(){TweenLite.to(v.scaling,.2,{x:1,y:1,z:1,onComplete:function(){TweenLite.to(ball3.scaling,.2,{x:1,y:1,z:1,onComplete:function(){J.toggleMenu(!0,!1);r&&(r.reset(),r.start())}})}})}})}})}})},oa=function(){D&&(D=!1,TweenLite.to([a.velocity,a.rotSpeed],2,{x:0,z:0}),T?q.play(5):q.play(7),ma&&trailParticles.stop(),R.copyFrom(a.position),setTimeout(function(){J.toggleMenu(!0,!0,!0)},500))};h.runRenderLoop(function(){if(f){a.position.addInPlace(a.velocity);ba.position.copyFrom(a.position);
a.rotateAround(a.position,0!=a.rotSpeed.x?BABYLON.Axis.X:BABYLON.Axis.Z,0!=a.rotSpeed.x?a.rotSpeed.x:-a.rotSpeed.z);a.moveWithCollisions(pa);D?(T&&(x.position.x=a.position.x+8,x.position.z=a.position.z+8,l.position.x=a.position.x+28,l.position.z=a.position.z+28),n.setTarget(a.position)):n.setTarget(R);if(!y)for(var d=0;d<m.length;d++)m[d].rotation.y+=.02,m[d].rotation.x+=.03;-.2>a.position.y&&oa();l.rotation.y+=2E-4;if(c.frustumPlanes&&P){if(!p[0].isInFrustum(c.frustumPlanes)&&p[0].position.x<a.position.x&&
p[0].position.z<a.position.z){var b=p.shift();d=I.shift();var e=I.shift();b.position.x=d;b.position.z=e;p.push(b)}!m[0].isInFrustum(c.frustumPlanes)&&m[0].position.x<a.position.x&&m[0].position.z<a.position.z&&(b=m.shift(),d=V.shift(),e=V.shift(),b.position.x=d,b.position.z=e,m.push(b))}for(b=0;b<t.length;++b)if(a.position.subtractToRef(t[b].position,qa),1>qa.length()&&Q<t[b].level.rotSpeed){q.play(6);J.setScore(t[b].val);J.setProgress(O[++K]);a.material=t[b].ball.material;Q=t[b].level.rotSpeed;P=
t[b].level.moveSpeed;1==C?(a.velocity.set(0,0,P),a.rotSpeed.set(Q,0,0)):(a.velocity.set(P,0,0),a.rotSpeed.set(0,0,Q));break}for(b=0;b<m.length;++b)if(a.position.subtractToRef(m[b].position,qa),.4>qa.length()){q.play(0);Z(m[b].position);J.setScore(15);d=V.shift();e=V.shift();m[b].position.x=d;m[b].position.z=e;break}c.render()}});W.sound=q;W.startNewGame=function(c){K=0;J.resetProgress();var b=function(){T&&(x.position.y=E.reflectionTexture.mirrorPlane.d=-1);J.toggleCurtain(!1);TweenLite.killTweensOf(a.velocity);
TweenLite.killTweensOf(a.rotSpeed);D=!0;pa.y=0;a.scaling.set(0,0,0);a.position.set(0,.7525,0);a.level=0;a.material=S;a.velocity.set(0,0,0);a.rotSpeed.set(0,0,0);P=Q=0;n.position.set(-3.916,7.6882,-4.808);n.alpha=3.94;n.beta=.69;n.setTarget(a.position);n.radius=window.innerWidth<window.innerHeight?window.innerHeight/window.innerWidth*5.2:9;9>n.radius&&(n.radius=9);C=1;for(var b=0;b<p.length;++b)p[b].scaling.set(0,0,0);for(b=0;b<m.length;++b)m[b].scaling.set(0,0,0);for(b=0;b<t.length;++b)t[b].scaling.set(0,
0,0);t.sort(function(a,b){return a.level.moveSpeed-b.level.moveSpeed});I.length=0;V.length=0;var d=function(a,b){--a;--b;for(var c=0;3>c;++c)for(var d=0;3>d;++d)I.push(a+d),I.push(b+c)};d(0,0);var e=0,f=2;for(b=9;13>b;++b)I.push(0),I.push(f++);--f;var g=!0,h=0;b=function(a,b,c){g=!0;for(var k=0;k<a;++k){for(var m=k===a-1?4:GameUtils.RandomInt(b,c),l=0;l<m;++l)g?++e:++f,I.push(e),I.push(f),0===GameUtils.RandomInt(1,300)%4&&(V.push(e),V.push(f));g=!g}e=g?e:e+2;f=g?f+2:f;t[h].position.set(e,.45,f);t[h].scaling.set(.2,
.2,.2);t[h].rotation.y=g?0:Math.PI/2;h++;d(e,f);e=g?e:e+1;f=g?f+1:f;for(a=9;13>a;++a)I.push(g?e:++e),I.push(g?++f:f);g||--e};b(15,2,4);b(18,1,3);b(21,2,4);b(23,2,3);b(25,2,3);b(25,2,4);b(27,2,3);b(30,2,4);b(35,3,4);b(38,3,5);b(40,2,4);b(45,2,3);(function(){for(var a=0;a<m.length;++a)m[a].position.x=V.shift(),m[a].position.z=V.shift(),m[a].position.y=.8;for(a=0;a<p.length;++a)p[a].position.x=I.shift(),p[a].position.z=I.shift()})();c||ea(GameUtils.RandomInt(1,8));for(b=0;b<p.length;++b)p[b].position.y=
0,b<p.length-1?TweenLite.to(p[b].scaling,.1,{delay:(b+1)/30,x:1,y:1,z:1}):TweenLite.to(p[b].scaling,.1,{delay:(b+1)/30,x:1,y:1,z:1,onComplete:function(){TweenLite.to(a.scaling,.3,{x:1,y:1,z:1});for(var b=0;b<m.length;++b)TweenLite.to(m[b].scaling,.1,{delay:(b+1)/30,x:1,y:1,z:1});J.toggleScoreBox(!0);y=!1;setTimeout(function(){pa.y=-.1;Q=.15;P=.07;a.velocity.set(0,0,P);a.rotSpeed.set(Q,0,0);ma&&trailParticles.start()},500)}})};c?TweenLite.to(a.scaling,.1,{x:0,y:0,z:0,onComplete:function(){TweenLite.to(v.scaling,
.1,{x:0,y:0,z:0,onComplete:function(){TweenLite.to(ball3.scaling,.1,{x:0,y:0,z:0,onComplete:function(){for(var a=0;9>a;++a)8>a?TweenLite.to(p[a].scaling,.1,{delay:(a+1)/40,x:0,y:0,z:0}):TweenLite.to(p[a].scaling,.1,{delay:(a+1)/40,x:0,y:0,z:0,onComplete:function(){for(var a=0;a<m.length;++a)a<m.length-1?TweenLite.to(m[a].scaling,.1,{delay:(a+1)/40,x:0,y:0,z:0}):TweenLite.to(m[a].scaling,.1,{delay:(a+1)/40,x:0,y:0,z:0,onComplete:function(){J.toggleCurtain(!0,b)}})}})}})}})}}):b()};W.showHomeScene=
aa;W.score=0;W.isRunning=D;W.scene=c;b=function(){f=!1;k=q.isMuted();q.mute()};e=function(){f=!0;k&&q.unmute()};window.onblur=b;window.onfocus=e;document.onblur=b;document.onfocus=e;var ua=function(){winW=window.innerWidth;winH=window.innerHeight;n&&(y?n.radius=winW<winH?winH/winW*6.5:6.5:(n.radius=winW<winH?winH/winW*6.5*5.2:8,8>n.radius&&(n.radius=8)));h.resize();J.resize()};window.addEventListener("resize",ua);window.addEventListener("orientationchange",ua);ta?(document.getElementById("curtain").removeChild(U),
window.removeEventListener("resize",na),window.removeEventListener("deviceorientation",na),setTimeout(function(){aa()},200)):aa();Ea&&(b=new BABYLON.SceneOptimizerOptions(55,1500),b.addOptimization(new BABYLON.HardwareScalingOptimization(1,1.25)),b.addOptimization(new BABYLON.HardwareScalingOptimization(2,1.5)),da&&b.addCustomOptimization(function(){u&&u.dispose();return!0},function(){return"Turned glow off"}),ra&&b.addCustomOptimization(function(){l.setEnabled(!1);return!0},function(){return"Removed sky"}),
T&&b.addCustomOptimization(function(){x.material.reflectionTexture=null;x.checkCollisions=!1;a.material=ha;x.setEnabled(!1);T=!1;l.setEnabled(!1);return!0},function(){return"Removed mirror"}),r=new BABYLON.SceneOptimizer(c,b),r.onSuccessObservable.add(function(){console.log("State: Done")}),r.onNewOptimizationAppliedObservable.add(function(a){console.log(a.getDescription())}),r.onFailureObservable.add(function(){console.log("State: Failed. Frame rate was "+r.currentFrameRate)}));window.scene=c};g.load()}})();

File diff suppressed because one or more lines are too long

@ -0,0 +1,106 @@
package com.cwj.we.app;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.text.TextUtils;
import android.util.Log;
import androidx.multidex.MultiDex;
import com.scwang.smartrefresh.layout.SmartRefreshLayout;
import com.scwang.smartrefresh.layout.api.DefaultRefreshFooterCreator;
import com.scwang.smartrefresh.layout.api.DefaultRefreshHeaderCreator;
import com.scwang.smartrefresh.layout.api.RefreshFooter;
import com.scwang.smartrefresh.layout.api.RefreshHeader;
import com.scwang.smartrefresh.layout.api.RefreshLayout;
import com.scwang.smartrefresh.layout.footer.ClassicsFooter;
import com.scwang.smartrefresh.layout.header.ClassicsHeader;
import com.tencent.bugly.crashreport.CrashReport;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import cn.bmob.v3.Bmob;
public class App extends BaseApplication {
private static Context context;
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
@Override
public void onCreate() {
super.onCreate();
Bmob.initialize(this, "6db49e4b74caba7f1782c11002dfcfd7");
Context context = getApplicationContext();
// 获取当前包名
String packageName = context.getPackageName();
// 获取当前进程名
String processName = getProcessName(android.os.Process.myPid());
// 设置是否为上报进程
CrashReport.UserStrategy strategy = new CrashReport.UserStrategy(context);
strategy.setUploadProcess(processName == null || processName.equals(packageName));
// 初始化Bugly
CrashReport.initCrashReport(context, "7132a5d9a0", false, strategy);
}
/**
*
*
* @param pid
* @return
*/
private static String getProcessName(int pid) {
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader("/proc/" + pid + "/cmdline"));
String processName = reader.readLine();
if (!TextUtils.isEmpty(processName)) {
processName = processName.trim();
}
return processName;
} catch (Throwable throwable) {
throwable.printStackTrace();
} finally {
try {
if (reader != null) {
reader.close();
}
} catch (IOException exception) {
exception.printStackTrace();
}
}
return null;
}
public static Context getContext() {
return context;
}
//static 代码段可以防止内存泄露
static {
//设置全局的Header构建器
SmartRefreshLayout.setDefaultRefreshHeaderCreator(new DefaultRefreshHeaderCreator() {
@Override
public RefreshHeader createRefreshHeader(Context context, RefreshLayout layout) {
// layout.setPrimaryColorsId(R.color.colorPrimary, android.R.color.white);//全局设置主题颜色
return new ClassicsHeader(context);//.setTimeFormat(new DynamicTimeFormat("更新于 %s"));//指定为经典Header默认是 贝塞尔雷达Header
}
});
//设置全局的Footer构建器
SmartRefreshLayout.setDefaultRefreshFooterCreator(new DefaultRefreshFooterCreator() {
@Override
public RefreshFooter createRefreshFooter(Context context, RefreshLayout layout) {
//指定为经典Footer默认是 BallPulseFooter
return new ClassicsFooter(context).setDrawableSize(20);
}
});
}
}

@ -0,0 +1,20 @@
package com.cwj.we.app;
import androidx.multidex.MultiDexApplication;
import cn.bmob.v3.Bmob;
public class BaseApplication extends MultiDexApplication {
private static BaseApplication instance;
public static BaseApplication getInstance() {
return instance;
}
@Override
public void onCreate() {
super.onCreate();
instance = this;
}
}

@ -0,0 +1,100 @@
package com.cwj.we.base;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.view.LayoutInflater;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import com.cwj.we.utils.ActivityCollector;
import com.yechaoa.yutils.YUtils;
import butterknife.ButterKnife;
/**
* Description : BaseActivity
*
* @author XuCanyou666
* @date 2020/2/7
*/
public abstract class BaseActivity<P extends BasePresenter> extends AppCompatActivity implements BaseView {
protected P presenter;
protected abstract P createPresenter();
protected abstract int getLayoutId();
protected abstract void initView();
protected abstract void initData();
@SuppressLint("SourceLockedOrientationActivity")
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//设置竖屏
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
setContentView(LayoutInflater.from(this).inflate(getLayoutId(), null));
ButterKnife.bind(this);
presenter = createPresenter();
initView();
initData();
//onCreate中增加Activity到任务管理器
ActivityCollector.addActivity(this);
}
@Override
protected void onResume() {
super.onResume();
initListener();
}
@Override
protected void onDestroy() {
super.onDestroy();
//销毁时,解除绑定
if (presenter != null) {
presenter.detachView();
ActivityCollector.removeActivity(this);
}
}
protected void initListener() {
}
@Override
public void showLoading() {
YUtils.showLoading(this, "加载中");
}
@Override
public void hideLoading() {
YUtils.dismissLoading();
}
/**
*
*/
@Override
public void onErrorCode(BaseBean bean) {
}
/**
* activity
*
* @param activity
* @param isFinish
*/
public void startActivity(Class<?> activity, boolean isFinish) {
Intent intent = new Intent(this, activity);
startActivity(intent);
if (isFinish) {
finish();
}
}
}

@ -0,0 +1,30 @@
package com.cwj.we.base;
import java.io.Serializable;
/**
* Description : BaseBean
*
* @author XuCanyou666
* @date 2020/2/7
*/
public class BaseBean<T> implements Serializable {
/**
* data :
* errorCode : 0
* errorMsg :
*/
public int code;
public String msg;
public T data;
public BaseBean(int code, String data) {
this.code = code;
this.data = (T) data;
}
}

@ -0,0 +1,61 @@
package com.cwj.we.base;
import java.io.IOException;
/**
* Description : BaseException
*
* @author XuCanyou666
* @date 2020/2/7
*/
public class BaseException extends IOException {
/**
*
*/
public static final String PARSE_ERROR_MSG = "解析数据失败";
/**
*
*/
public static final String BAD_NETWORK_MSG = "网络问题";
/**
*
*/
public static final String CONNECT_ERROR_MSG = "连接错误";
/**
*
*/
public static final String CONNECT_TIMEOUT_MSG = "连接超时";
/**
*
*/
public static final String OTHER_MSG = "未知错误";
private String errorMsg;
private int errorCode;
public String getErrorMsg() {
return errorMsg;
}
public int getErrorCode() {
return errorCode;
}
public BaseException(String message) {
this.errorMsg = message;
}
public BaseException(String errorMsg, Throwable cause) {
super(errorMsg, cause);
this.errorMsg = errorMsg;
}
public BaseException(int errorCode, String message) {
this.errorMsg = message;
this.errorCode = errorCode;
}
}

@ -0,0 +1,95 @@
package com.cwj.we.base;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import com.yechaoa.yutils.ActivityUtil;
import com.yechaoa.yutils.YUtils;
import butterknife.ButterKnife;
import butterknife.Unbinder;
/**
* Description : BaseFragment
*
* @author XuCanyou666
* @date 2020/2/7
*/
public abstract class BaseFragment<P extends BasePresenter> extends Fragment implements BaseView {
private Unbinder unbinder;
protected Context mContext;
protected P presenter;
protected abstract P createPresenter();
protected abstract int getLayoutId();
protected abstract void initView();
protected abstract void initData();
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(getLayoutId(), container, false);
unbinder = ButterKnife.bind(this, view);
//得到context,在后面的子类Fragment中都可以直接调用
mContext = ActivityUtil.getCurrentActivity();
presenter = createPresenter();
initView();
initData();
return view;
}
@Override
public void onResume() {
super.onResume();
initListener();
}
@Override
public void onDestroyView() {
super.onDestroyView();
//do something
unbinder.unbind();
//销毁时,解除绑定
if (presenter != null) {
presenter.detachView();
}
}
private void initListener() {
}
@Override
public void onErrorCode(BaseBean bean) {
}
/**
*
*/
@Override
public void showLoading() {
if(ActivityUtil.getCurrentActivity() != null){
YUtils.showLoading(ActivityUtil.getCurrentActivity(), "加载中");
}
}
/**
*
*/
@Override
public void hideLoading() {
YUtils.dismissLoading();
}
}

@ -0,0 +1,109 @@
package com.cwj.we.base;
import com.google.gson.JsonParseException;
import org.json.JSONException;
import java.io.InterruptedIOException;
import java.net.ConnectException;
import java.net.UnknownHostException;
import java.text.ParseException;
import io.reactivex.observers.DisposableObserver;
import retrofit2.HttpException;
/**
* Description : BaseObserver
*
* @author XuCanyou666
* @date 2020/2/7
*/
public abstract class BaseObserver<T> extends DisposableObserver<T> {
protected BaseView view;
private boolean isShowDialog;
protected BaseObserver(BaseView view) {
this.view = view;
}
/**
*
*
* @param view view
* @param isShowDialog
*/
protected BaseObserver(BaseView view, boolean isShowDialog) {
this.view = view;
this.isShowDialog = isShowDialog;
}
@Override
protected void onStart() {
if (view != null && isShowDialog) {
view.showLoading();
}
}
@Override
public void onNext(T o) {
onSuccess(o);
}
@Override
public void onError(Throwable e) {
if (view != null && isShowDialog) {
view.hideLoading();
}
BaseException be;
if (e != null) {
//自定义异常
if (e instanceof BaseException) {
be = (BaseException) e;
//回调到view层 处理 或者根据项目情况处理
if (view != null) {
// 处理登录失效 更新
view.onErrorCode(new BaseBean(be.getErrorCode(), be.getErrorMsg()));
} else {
onError(be.getErrorMsg());
}
//系统异常
} else {
if (e instanceof HttpException) {
//HTTP错误
be = new BaseException(BaseException.BAD_NETWORK_MSG, e);
} else if (e instanceof ConnectException || e instanceof UnknownHostException) {
//连接错误
be = new BaseException(BaseException.CONNECT_ERROR_MSG, e);
} else if (e instanceof InterruptedIOException) {
//连接超时
be = new BaseException(BaseException.CONNECT_TIMEOUT_MSG, e);
} else if (e instanceof JsonParseException || e instanceof JSONException || e instanceof ParseException) {
//解析错误
be = new BaseException(BaseException.PARSE_ERROR_MSG, e);
} else {
be = new BaseException(BaseException.OTHER_MSG, e);
}
}
} else {
be = new BaseException(BaseException.OTHER_MSG);
}
onError(be.getErrorMsg());
}
@Override
public void onComplete() {
if (view != null && isShowDialog) {
view.hideLoading();
}
}
public abstract void onSuccess(T o);
public abstract void onError(String msg);
}

@ -0,0 +1,64 @@
package com.cwj.we.base;
import com.cwj.we.http.API;
import com.cwj.we.http.RetrofitService;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.schedulers.Schedulers;
/**
* Description : BasePresenter
*
* @author XuCanyou666
* @date 2020/2/7
*/
public class BasePresenter<V extends BaseView> {
private CompositeDisposable compositeDisposable;
public V baseView;
/**
* ExampleapiServer.login(username, password)
*/
protected API apiServer = RetrofitService.getInstance().getApiService();
public BasePresenter(V baseView) {
this.baseView = baseView;
}
/**
*
*/
public void detachView() {
baseView = null;
removeDisposable();
}
/**
* view
*/
public V getBaseView() {
return baseView;
}
public void addDisposable(Observable<?> observable, BaseObserver observer) {
if (compositeDisposable == null) {
compositeDisposable = new CompositeDisposable();
}
compositeDisposable
.add(observable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(observer));
}
private void removeDisposable() {
if (compositeDisposable != null) {
compositeDisposable.dispose();
}
}
}

@ -0,0 +1,60 @@
package com.cwj.we.base;
import android.widget.CompoundButton;
import com.chad.library.adapter.base.BaseQuickAdapter;
import java.util.Collection;
/**
* RecyclerView Adapter
*/
public abstract class BaseRVAdapter<T> extends BaseQuickAdapter<T, BaseRVHolder> {
public BaseRVAdapter(int layoutResId) {
super(layoutResId);
}
@Override
public void onBindViewHolder(BaseRVHolder holder, int position) {
super.onBindViewHolder(holder, position);
}
@Override
protected void convert(BaseRVHolder helper, T item) {
onBindVH(helper, item, helper.getLayoutPosition() - getHeaderLayoutCount());
}
public abstract void onBindVH(final BaseRVHolder holder, T data, int position);
protected void setCheckedChange(CompoundButton cb, final int position) {
cb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (onViewCheckedChangeListener != null) {
onViewCheckedChangeListener.onViewCheckedChanged(buttonView, isChecked, position);
}
}
});
}
/**
* @param onViewClickListener
*/
public OnViewCheckedChangeListener onViewCheckedChangeListener;
public void setOnViewCheckedChangeListener(OnViewCheckedChangeListener onViewCheckedChangeListener) {
this.onViewCheckedChangeListener = onViewCheckedChangeListener;
}
public interface OnViewCheckedChangeListener {
void onViewCheckedChanged(CompoundButton buttonView, boolean isChecked, int position);
}
public void removeAllData(Collection<? extends T> datas) {
mData.removeAll(datas);
notifyDataSetChanged();
}
}

@ -0,0 +1,213 @@
package com.cwj.we.base;
import android.graphics.Bitmap;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.view.View;
import android.widget.Adapter;
import android.widget.AdapterView;
import android.widget.CompoundButton;
import androidx.annotation.IdRes;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
/**
* ViewHolder
*/
public class BaseRVHolder extends BaseViewHolder {
public BaseRVHolder(View view) {
super(view);
}
public <T extends View> T $(int id) {
return getView(id);
}
/**
*
* @param viewId
* @param visible
* @return
*/
@Override
public BaseRVHolder setVisible(@IdRes int viewId, boolean visible) {
View view = getView(viewId);
view.setVisibility(visible ? View.VISIBLE : View.GONE);
return this;
}
public BaseRVHolder setSelected(@IdRes int viewId, boolean selected) {
View view = getView(viewId);
view.setSelected(selected);
return this;
}
@Override
public BaseRVHolder setText(int viewId, CharSequence value) {
return (BaseRVHolder) super.setText(viewId, value);
}
@Override
public BaseRVHolder setText(int viewId, int strId) {
return (BaseRVHolder) super.setText(viewId, strId);
}
@Override
public BaseRVHolder setImageResource(int viewId, int imageResId) {
return (BaseRVHolder) super.setImageResource(viewId, imageResId);
}
@Override
public BaseRVHolder setBackgroundColor(int viewId, int color) {
return (BaseRVHolder) super.setBackgroundColor(viewId, color);
}
@Override
public BaseRVHolder setBackgroundRes(int viewId, int backgroundRes) {
return (BaseRVHolder) super.setBackgroundRes(viewId, backgroundRes);
}
@Override
public BaseRVHolder setTextColor(int viewId, int textColor) {
return (BaseRVHolder) super.setTextColor(viewId, textColor);
}
@Override
public BaseRVHolder setImageDrawable(int viewId, Drawable drawable) {
return (BaseRVHolder) super.setImageDrawable(viewId, drawable);
}
@Override
public BaseRVHolder setImageBitmap(int viewId, Bitmap bitmap) {
return (BaseRVHolder) super.setImageBitmap(viewId, bitmap);
}
@Override
public BaseRVHolder setAlpha(int viewId, float value) {
return (BaseRVHolder) super.setAlpha(viewId, value);
}
@Override
public BaseRVHolder setGone(int viewId, boolean visible) {
return (BaseRVHolder) super.setGone(viewId, visible);
}
@Override
public BaseRVHolder linkify(int viewId) {
return (BaseRVHolder) super.linkify(viewId);
}
@Override
public BaseRVHolder setTypeface(int viewId, Typeface typeface) {
return (BaseRVHolder) super.setTypeface(viewId, typeface);
}
@Override
public BaseRVHolder setTypeface(Typeface typeface, int... viewIds) {
return (BaseRVHolder) super.setTypeface(typeface, viewIds);
}
@Override
public BaseRVHolder setProgress(int viewId, int progress) {
return (BaseRVHolder) super.setProgress(viewId, progress);
}
@Override
public BaseRVHolder setProgress(int viewId, int progress, int max) {
return (BaseRVHolder) super.setProgress(viewId, progress, max);
}
@Override
public BaseRVHolder setMax(int viewId, int max) {
return (BaseRVHolder) super.setMax(viewId, max);
}
@Override
public BaseRVHolder setRating(int viewId, float rating) {
return (BaseRVHolder) super.setRating(viewId, rating);
}
@Override
public BaseRVHolder setRating(int viewId, float rating, int max) {
return (BaseRVHolder) super.setRating(viewId, rating, max);
}
@Override
public BaseRVHolder setOnClickListener(int viewId, View.OnClickListener listener) {
return (BaseRVHolder) super.setOnClickListener(viewId, listener);
}
public BaseRVHolder addOnClickListener(int viewId) {
return (BaseRVHolder) super.addOnClickListener(viewId);
}
public BaseRVHolder setNestView(int viewId) {
return (BaseRVHolder) super.setNestView(viewId);
}
public BaseRVHolder addOnLongClickListener(int viewId) {
return (BaseRVHolder) super.addOnLongClickListener(viewId);
}
@Override
public BaseRVHolder setOnTouchListener(int viewId, View.OnTouchListener listener) {
return (BaseRVHolder) super.setOnTouchListener(viewId, listener);
}
@Override
public BaseRVHolder setOnLongClickListener(int viewId, View.OnLongClickListener listener) {
return (BaseRVHolder) super.setOnLongClickListener(viewId, listener);
}
@Override
public BaseRVHolder setOnItemClickListener(int viewId, AdapterView.OnItemClickListener listener) {
return (BaseRVHolder) super.setOnItemClickListener(viewId, listener);
}
@Override
public BaseRVHolder setOnItemLongClickListener(int viewId, AdapterView.OnItemLongClickListener listener) {
return (BaseRVHolder) super.setOnItemLongClickListener(viewId, listener);
}
@Override
public BaseRVHolder setOnItemSelectedClickListener(int viewId, AdapterView.OnItemSelectedListener listener) {
return (BaseRVHolder) super.setOnItemSelectedClickListener(viewId, listener);
}
@Override
public BaseRVHolder setOnCheckedChangeListener(int viewId, CompoundButton.OnCheckedChangeListener listener) {
return (BaseRVHolder) super.setOnCheckedChangeListener(viewId, listener);
}
@Override
public BaseRVHolder setTag(int viewId, Object tag) {
return (BaseRVHolder) super.setTag(viewId, tag);
}
@Override
public BaseRVHolder setTag(int viewId, int key, Object tag) {
return (BaseRVHolder) super.setTag(viewId, key, tag);
}
@Override
public BaseRVHolder setChecked(int viewId, boolean checked) {
return (BaseRVHolder) super.setChecked(viewId, checked);
}
@Override
public BaseRVHolder setAdapter(int viewId, Adapter adapter) {
return (BaseRVHolder) super.setAdapter(viewId, adapter);
}
@Override
protected BaseRVHolder setAdapter(BaseQuickAdapter adapter) {
return (BaseRVHolder) super.setAdapter(adapter);
}
}

@ -0,0 +1,19 @@
package com.cwj.we.base;
/**
* Description : BaseView
*
* @author XuCanyou666
* @date 2020/2/7
*/
public interface BaseView {
void showLoading();
void hideLoading();
void onErrorCode(BaseBean bean);
}

@ -0,0 +1,51 @@
package com.cwj.we.bean;
import cn.bmob.v3.BmobObject;
public class Day extends BmobObject {
private User author;
private String togetherTime;//在一起的时间
private String getMarriedTime;//结婚时间农历 格式2018年三月初八
private String getMarriedTime2;//结婚时间农历 格式2018-03-08
private String getMarriedTime3;//结婚时间公历
public String getTogetherTime() {
return togetherTime;
}
public User getAuthor() {
return author;
}
public void setAuthor(User author) {
this.author = author;
}
public void setTogetherTime(String togetherTime) {
this.togetherTime = togetherTime;
}
public String getGetMarriedTime() {
return getMarriedTime;
}
public void setGetMarriedTime(String getMarriedTime) {
this.getMarriedTime = getMarriedTime;
}
public String getGetMarriedTime2() {
return getMarriedTime2;
}
public void setGetMarriedTime2(String getMarriedTime2) {
this.getMarriedTime2 = getMarriedTime2;
}
public String getGetMarriedTime3() {
return getMarriedTime3;
}
public void setGetMarriedTime3(String getMarriedTime3) {
this.getMarriedTime3 = getMarriedTime3;
}
}

@ -0,0 +1,27 @@
package com.cwj.we.bean;
public class GameBean {
private String name;
private int img;
public GameBean(String name, int img) {
this.name = name;
this.img = img;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getImg() {
return img;
}
public void setImg(int img) {
this.img = img;
}
}

@ -0,0 +1,7 @@
package com.cwj.we.bean;
public interface GetDataType {
int GETDATA=1;
int REFRESH=2;
int LOADMORE=3;
}

@ -0,0 +1,135 @@
package com.cwj.we.bean;
public class LatestBean {
/**
* name :
* version : 11
* changelog :
* updated_at : 1589016775
* versionShort : 1.1.8
* build : 11
* installUrl : https://download.jappstore.com/apps/5e77278df9454809b991dfda/install?download_token=1d4098da8015603c7b0aa9c0f3fb71ea&source=update
* install_url : https://download.jappstore.com/apps/5e77278df9454809b991dfda/install?download_token=1d4098da8015603c7b0aa9c0f3fb71ea&source=update
* direct_install_url : https://download.jappstore.com/apps/5e77278df9454809b991dfda/install?download_token=1d4098da8015603c7b0aa9c0f3fb71ea&source=update
* update_url : http://jappstore.com/dfyr
* binary : {"fsize":11900042}
*/
private String name;
private String version;
private String changelog;
private int updated_at;
private String versionShort;
private String build;
private String installUrl;
private String install_url;
private String direct_install_url;
private String update_url;
private BinaryBean binary;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getChangelog() {
return changelog;
}
public void setChangelog(String changelog) {
this.changelog = changelog;
}
public int getUpdated_at() {
return updated_at;
}
public void setUpdated_at(int updated_at) {
this.updated_at = updated_at;
}
public String getVersionShort() {
return versionShort;
}
public void setVersionShort(String versionShort) {
this.versionShort = versionShort;
}
public String getBuild() {
return build;
}
public void setBuild(String build) {
this.build = build;
}
public String getInstallUrl() {
return installUrl;
}
public void setInstallUrl(String installUrl) {
this.installUrl = installUrl;
}
public String getInstall_url() {
return install_url;
}
public void setInstall_url(String install_url) {
this.install_url = install_url;
}
public String getDirect_install_url() {
return direct_install_url;
}
public void setDirect_install_url(String direct_install_url) {
this.direct_install_url = direct_install_url;
}
public String getUpdate_url() {
return update_url;
}
public void setUpdate_url(String update_url) {
this.update_url = update_url;
}
public BinaryBean getBinary() {
return binary;
}
public void setBinary(BinaryBean binary) {
this.binary = binary;
}
public static class BinaryBean {
/**
* fsize : 11900042
*/
private int fsize;
public int getFsize() {
return fsize;
}
public void setFsize(int fsize) {
this.fsize = fsize;
}
}
}

@ -0,0 +1,7 @@
package com.cwj.we.bean;
import cn.bmob.v3.BmobUser;
public class User extends BmobUser {
}

@ -0,0 +1,45 @@
package com.cwj.we.game.aircraftbattle;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
/**
* 线Sprite
*/
public class AutoSprite extends Sprite {
//每帧移动的像素数,以向下为正
private float speed = 2;
public AutoSprite(Bitmap bitmap){
super(bitmap);
}
public void setSpeed(float speed){
this.speed = speed;
}
public float getSpeed(){
return speed;
}
@Override
protected void beforeDraw(Canvas canvas, Paint paint, GameView gameView) {
if(!isDestroyed()){
//在y轴方向移动speed像素
move(0, speed * gameView.getDensity());
}
}
protected void afterDraw(Canvas canvas, Paint paint, GameView gameView){
if(!isDestroyed()){
//检查Sprite是否超出了Canvas的范围如果超出则销毁Sprite
RectF canvasRecF = new RectF(0, 0, canvas.getWidth(), canvas.getHeight());
RectF spriteRecF = getRectF();
if(!RectF.intersects(canvasRecF, spriteRecF)){
destroy();
}
}
}
}

@ -0,0 +1,54 @@
package com.cwj.we.game.aircraftbattle;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
/**
*
*/
public class Award extends AutoSprite {
public static int STATUS_DOWN1 = 1;
public static int STATUS_UP2 = 2;
public static int STATUS_DOWN3 = 3;
private int status = STATUS_DOWN1;
public Award(Bitmap bitmap){
super(bitmap);
setSpeed(7);
}
@Override
protected void afterDraw(Canvas canvas, Paint paint, GameView gameView) {
//在afterDraw中不调用super.afterDraw方法
if(!isDestroyed()){
//在绘制一定次数后要改变方向或速度
int canvasHeight = canvas.getHeight();
if(status != STATUS_DOWN3){
float maxY = getY() + getHeight();
if(status == STATUS_DOWN1){
//第一次向下
if(maxY >= canvasHeight * 0.25){
//当第一次下降到临界值时改变方向,向上
setSpeed(-5);
status = STATUS_UP2;
}
}
else if(status == STATUS_UP2){
//第二次向上
if(maxY+this.getSpeed() <= 0){
//第二次上升到临界值时改变方向,向下
setSpeed(13);
status = STATUS_DOWN3;
}
}
}
if(status == STATUS_DOWN3){
if(getY() >= canvasHeight){
destroy();
}
}
}
}
}

@ -0,0 +1,16 @@
package com.cwj.we.game.aircraftbattle;
import android.graphics.Bitmap;
/**
*
*/
public class BigEnemyPlane extends EnemyPlane {
public BigEnemyPlane(Bitmap bitmap){
super(bitmap);
setPower(10);//大敌机抗抵抗能力为10即需要10颗子弹才能销毁大敌机
setValue(30000);//销毁一个大敌机可以得30000分
}
}

@ -0,0 +1,14 @@
package com.cwj.we.game.aircraftbattle;
import android.graphics.Bitmap;
/**
*
*/
public class BombAward extends Award {
public BombAward(Bitmap bitmap){
super(bitmap);
}
}

@ -0,0 +1,15 @@
package com.cwj.we.game.aircraftbattle;
import android.graphics.Bitmap;
/**
* 沿线
*/
public class Bullet extends AutoSprite {
public Bullet(Bitmap bitmap){
super(bitmap);
setSpeed(-10);//负数表示子弹向上飞
}
}

@ -0,0 +1,14 @@
package com.cwj.we.game.aircraftbattle;
import android.graphics.Bitmap;
/**
*
*/
public class BulletAward extends Award {
public BulletAward(Bitmap bitmap){
super(bitmap);
}
}

@ -0,0 +1,212 @@
package com.cwj.we.game.aircraftbattle;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.RectF;
import java.util.List;
/**
*
*/
public class CombatAircraft extends Sprite {
private boolean collide = false;//标识战斗机是否被击中
private int bombAwardCount = 0;//可使用的炸弹数
//双发子弹相关
private boolean single = true;//标识是否发的是单一的子弹
private int doubleTime = 0;//当前已经用双子弹绘制的次数
private int maxDoubleTime = 140;//使用双子弹最多绘制的次数
//被撞击后闪烁相关
private long beginFlushFrame = 0;//要在第beginFlushFrame帧开始闪烁战斗机
private int flushTime = 0;//已经闪烁的次数
private int flushFrequency = 16;//在闪烁的时候每隔16帧转变战斗机的可见性
private int maxFlushTime = 10;//最大闪烁次数
public CombatAircraft(Bitmap bitmap){
super(bitmap);
}
@Override
protected void beforeDraw(Canvas canvas, Paint paint, GameView gameView) {
if(!isDestroyed()){
//确保战斗机完全位于Canvas范围内
validatePosition(canvas);
//每隔7帧发射子弹
if(getFrame() % 7 == 0){
fight(gameView);
}
}
}
//确保战斗机完全位于Canvas范围内
private void validatePosition(Canvas canvas){
if(getX() < 0){
setX(0);
}
if(getY() < 0){
setY(0);
}
RectF rectF = getRectF();
int canvasWidth = canvas.getWidth();
if(rectF.right > canvasWidth){
setX(canvasWidth - getWidth());
}
int canvasHeight = canvas.getHeight();
if(rectF.bottom > canvasHeight){
setY(canvasHeight - getHeight());
}
}
//发射子弹
public void fight(GameView gameView){
//如果战斗机被撞击了或销毁了,那么不会发射子弹
if(collide || isDestroyed()){
return;
}
float x = getX() + getWidth() / 2;
float y = getY() - 5;
if(single){
//单发模式下发射单发黄色子弹
Bitmap yellowBulletBitmap = gameView.getYellowBulletBitmap();
Bullet yellowBullet = new Bullet(yellowBulletBitmap);
yellowBullet.moveTo(x, y);
gameView.addSprite(yellowBullet);
}
else{
//双发模式下发射两发蓝色子弹
float offset = getWidth() / 4;
float leftX = x - offset;
float rightX = x + offset;
Bitmap blueBulletBitmap = gameView.getBlueBulletBitmap();
Bullet leftBlueBullet = new Bullet(blueBulletBitmap);
leftBlueBullet.moveTo(leftX, y);
gameView.addSprite(leftBlueBullet);
Bullet rightBlueBullet = new Bullet(blueBulletBitmap);
rightBlueBullet.moveTo(rightX, y);
gameView.addSprite(rightBlueBullet);
doubleTime++;
if(doubleTime >= maxDoubleTime){
single = true;
doubleTime = 0;
}
}
}
//战斗机如果被击中,执行爆炸效果
//具体来说首先隐藏战斗机然后创建爆炸效果爆炸用28帧渲染完成
//爆炸效果完全渲染完成后,爆炸效果消失
//然后战斗机会进入闪烁模式,战斗机闪烁一定次数后销毁
protected void afterDraw(Canvas canvas, Paint paint, GameView gameView){
if(isDestroyed()){
return;
}
//在飞机当前还没有被击中时,要判断是否将要被敌机击中
if(!collide){
List<EnemyPlane> enemies = gameView.getAliveEnemyPlanes();
for(EnemyPlane enemyPlane : enemies){
Point p = getCollidePointWithOther(enemyPlane);
if(p != null){
//p为战斗机与敌机的碰撞点如果p不为null则表明战斗机被敌机击中
explode(gameView);
break;
}
}
}
//beginFlushFrame初始值为0表示没有进入闪烁模式
//如果beginFlushFrame大于0表示要在第如果beginFlushFrame帧进入闪烁模式
if(beginFlushFrame > 0){
long frame = getFrame();
//如果当前帧数大于等于beginFlushFrame才表示战斗机进入销毁前的闪烁状态
if(frame >= beginFlushFrame){
if((frame - beginFlushFrame) % flushFrequency == 0){
boolean visible = getVisibility();
setVisibility(!visible);
flushTime++;
if(flushTime >= maxFlushTime){
//如果战斗机闪烁的次数超过了最大的闪烁次数,那么销毁战斗机
destroy();
//Game.gameOver();
}
}
}
}
//在没有被击中的情况下检查是否获得了道具
if(!collide){
//检查是否获得炸弹道具
List<BombAward> bombAwards = gameView.getAliveBombAwards();
for(BombAward bombAward : bombAwards){
Point p = getCollidePointWithOther(bombAward);
if(p != null){
bombAwardCount++;
bombAward.destroy();
//Game.receiveBombAward();
}
}
//检查是否获得子弹道具
List<BulletAward> bulletAwards = gameView.getAliveBulletAwards();
for(BulletAward bulletAward : bulletAwards){
Point p = getCollidePointWithOther(bulletAward);
if(p != null){
bulletAward.destroy();
single = false;
doubleTime = 0;
}
}
}
}
//战斗机爆炸
private void explode(GameView gameView){
if(!collide){
collide = true;
setVisibility(false);
float centerX = getX() + getWidth() / 2;
float centerY = getY() + getHeight() / 2;
Explosion explosion = new Explosion(gameView.getExplosionBitmap());
explosion.centerTo(centerX, centerY);
gameView.addSprite(explosion);
beginFlushFrame = getFrame() + explosion.getExplodeDurationFrame();
}
}
//获取可用的炸弹数量
public int getBombCount(){
return bombAwardCount;
}
//战斗机使用炸弹
public void bomb(GameView gameView){
if(collide || isDestroyed()){
return;
}
if(bombAwardCount > 0){
List<EnemyPlane> enemyPlanes = gameView.getAliveEnemyPlanes();
for(EnemyPlane enemyPlane : enemyPlanes){
enemyPlane.explode(gameView);
}
bombAwardCount--;
}
}
public boolean isCollide(){
return collide;
}
public void setNotCollide(){
collide = false;
}
}

@ -0,0 +1,78 @@
package com.cwj.we.game.aircraftbattle;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point;
import java.util.List;
/**
* 沿线
*/
public class EnemyPlane extends AutoSprite {
private int power = 1;//敌机的抗打击能力
private int value = 0;//打一个敌机的得分
public EnemyPlane(Bitmap bitmap){
super(bitmap);
}
public void setPower(int power){
this.power = power;
}
public int getPower(){
return power;
}
public void setValue(int value){
this.value = value;
}
public int getValue(){
return value;
}
@Override
protected void afterDraw(Canvas canvas, Paint paint, GameView gameView) {
super.afterDraw(canvas, paint, gameView);
//绘制完成后要检查自身是否被子弹打中
if(!isDestroyed()){
//敌机在绘制完成后要判断是否被子弹打中
List<Bullet> bullets = gameView.getAliveBullets();
for(Bullet bullet : bullets){
//判断敌机是否与子弹相交
Point p = getCollidePointWithOther(bullet);
if(p != null){
//如果有交点,说明子弹打到了飞机上
bullet.destroy();
power--;
if(power <= 0){
//敌机已经没有能量了,执行爆炸效果
explode(gameView);
return;
}
}
}
}
}
//创建爆炸效果后会销毁敌机
public void explode(GameView gameView){
//创建爆炸效果
float centerX = getX() + getWidth() / 2;
float centerY = getY() + getHeight() / 2;
Bitmap bitmap = gameView.getExplosionBitmap();
Explosion explosion = new Explosion(bitmap);
explosion.centerTo(centerX, centerY);
gameView.addSprite(explosion);
//创建爆炸效果完成后向GameView中添加得分并销毁敌机
gameView.addScore(value);
destroy();
}
}

@ -0,0 +1,56 @@
package com.cwj.we.game.aircraftbattle;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
/**
*
*/
public class Explosion extends Sprite {
private int segment = 14;//爆炸效果由14个片段组成
private int level = 0;//最开始处于爆炸的第0片段
private int explodeFrequency = 2;//每个爆炸片段绘制2帧
public Explosion(Bitmap bitmap){
super(bitmap);
}
@Override
public float getWidth() {
Bitmap bitmap = getBitmap();
if(bitmap != null){
return bitmap.getWidth() / segment;
}
return 0;
}
@Override
public Rect getBitmapSrcRec() {
Rect rect = super.getBitmapSrcRec();
int left = (int)(level * getWidth());
rect.offsetTo(left, 0);
return rect;
}
@Override
protected void afterDraw(Canvas canvas, Paint paint, GameView gameView) {
if(!isDestroyed()){
if(getFrame() % explodeFrequency == 0){
//level自加1用于绘制下个爆炸片段
level++;
if(level >= segment){
//当绘制完所有的爆炸片段后,销毁爆炸效果
destroy();
}
}
}
}
//得到绘制完整爆炸效果需要的帧数即28帧
public int getExplodeDurationFrame(){
return segment * explodeFrequency;
}
}

@ -0,0 +1,695 @@
package com.cwj.we.game.aircraftbattle;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import com.cwj.we.R;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class GameView extends View {
private Paint paint;
private Paint textPaint;
private CombatAircraft combatAircraft = null;
private List<Sprite> sprites = new ArrayList<Sprite>();
private List<Sprite> spritesNeedAdded = new ArrayList<Sprite>();
//0:combatAircraft
//1:explosion
//2:yellowBullet
//3:blueBullet
//4:smallEnemyPlane
//5:middleEnemyPlane
//6:bigEnemyPlane
//7:bombAward
//8:bulletAward
//9:pause1
//10:pause2
//11:bomb
private List<Bitmap> bitmaps = new ArrayList<Bitmap>();
private float density = getResources().getDisplayMetrics().density;//屏幕密度
public static final int STATUS_GAME_STARTED = 1;//游戏开始
public static final int STATUS_GAME_PAUSED = 2;//游戏暂停
public static final int STATUS_GAME_OVER = 3;//游戏结束
public static final int STATUS_GAME_DESTROYED = 4;//游戏销毁
private int status = STATUS_GAME_DESTROYED;//初始为销毁状态
private long frame = 0;//总共绘制的帧数
private long score = 0;//总得分
private float fontSize = 12;//默认的字体大小,用于绘制左上角的文本
private float fontSize2 = 20;//用于在Game Over的时候绘制Dialog中的文本
private float borderSize = 2;//Game Over的Dialog的边框
private Rect continueRect = new Rect();//"继续"、"重新开始"按钮的Rect
//触摸事件相关的变量
private static final int TOUCH_MOVE = 1;//移动
private static final int TOUCH_SINGLE_CLICK = 2;//单击
private static final int TOUCH_DOUBLE_CLICK = 3;//双击
//一次单击事件由DOWN和UP两个事件合成假设从down到up间隔小于200毫秒我们就认为发生了一次单击事件
private static final int singleClickDurationTime = 200;
//一次双击事件由两个点击事件合成两个单击事件之间小于300毫秒我们就认为发生了一次双击事件
private static final int doubleClickDurationTime = 300;
private long lastSingleClickTime = -1;//上次发生单击的时刻
private long touchDownTime = -1;//触点按下的时刻
private long touchUpTime = -1;//触点弹起的时刻
private float touchX = -1;//触点的x坐标
private float touchY = -1;//触点的y坐标
public GameView(Context context) {
super(context);
init(null, 0);
}
public GameView(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs, 0);
}
public GameView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(attrs, defStyle);
}
private void init(AttributeSet attrs, int defStyle) {
final TypedArray a = getContext().obtainStyledAttributes(
attrs, R.styleable.GameView, defStyle, 0);
a.recycle();
//初始化paint
paint = new Paint();
paint.setStyle(Paint.Style.FILL);
//设置textPaint设置为抗锯齿且是粗体
textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG | Paint.FAKE_BOLD_TEXT_FLAG);
textPaint.setColor(0xff000000);
fontSize = textPaint.getTextSize();
fontSize *= density;
fontSize2 *= density;
textPaint.setTextSize(fontSize);
borderSize *= density;
}
public void start(int[] bitmapIds){
destroy();
for(int bitmapId : bitmapIds){
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), bitmapId);
bitmaps.add(bitmap);
}
startWhenBitmapsReady();
}
private void startWhenBitmapsReady(){
combatAircraft = new CombatAircraft(bitmaps.get(0));
//将游戏设置为开始状态
status = STATUS_GAME_STARTED;
postInvalidate();
}
private void restart(){
destroyNotRecyleBitmaps();
startWhenBitmapsReady();
}
public void pause(){
//将游戏设置为暂停状态
status = STATUS_GAME_PAUSED;
}
private void resume(){
//将游戏设置为运行状态
status = STATUS_GAME_STARTED;
postInvalidate();
}
private long getScore(){
//获取游戏得分
return score;
}
/*-------------------------------draw-------------------------------------*/
@Override
protected void onDraw(Canvas canvas) {
//我们在每一帧都检测是否满足延迟触发单击事件的条件
if(isSingleClick()){
onSingleClick(touchX, touchY);
}
super.onDraw(canvas);
if(status == STATUS_GAME_STARTED){
drawGameStarted(canvas);
}else if(status == STATUS_GAME_PAUSED){
drawGamePaused(canvas);
}else if(status == STATUS_GAME_OVER){
drawGameOver(canvas);
}
}
//绘制运行状态的游戏
private void drawGameStarted(Canvas canvas){
drawScoreAndBombs(canvas);
//第一次绘制时将战斗机移到Canvas最下方在水平方向的中心
if(frame == 0){
float centerX = canvas.getWidth() / 2;
float centerY = canvas.getHeight() - combatAircraft.getHeight() / 2;
combatAircraft.centerTo(centerX, centerY);
}
//将spritesNeedAdded添加到sprites中
if(spritesNeedAdded.size() > 0){
sprites.addAll(spritesNeedAdded);
spritesNeedAdded.clear();
}
//检查战斗机跑到子弹前面的情况
destroyBulletsFrontOfCombatAircraft();
//在绘制之前先移除掉已经被destroyed的Sprite
removeDestroyedSprites();
//每隔30帧随机添加Sprite
if(frame % 30 == 0){
createRandomSprites(canvas.getWidth());
}
frame++;
//遍历sprites绘制敌机、子弹、奖励、爆炸效果
Iterator<Sprite> iterator = sprites.iterator();
while (iterator.hasNext()){
Sprite s = iterator.next();
if(!s.isDestroyed()){
//在Sprite的draw方法内有可能会调用destroy方法
s.draw(canvas, paint, this);
}
//我们此处要判断Sprite在执行了draw方法后是否被destroy掉了
if(s.isDestroyed()){
//如果Sprite被销毁了那么从Sprites中将其移除
iterator.remove();
}
}
if(combatAircraft != null){
//最后绘制战斗机
combatAircraft.draw(canvas, paint, this);
if(combatAircraft.isDestroyed()){
//如果战斗机被击中销毁了,那么游戏结束
status = STATUS_GAME_OVER;
}
//通过调用postInvalidate()方法使得View持续渲染实现动态效果
postInvalidate();
}
}
//绘制暂停状态的游戏
private void drawGamePaused(Canvas canvas){
drawScoreAndBombs(canvas);
//调用Sprite的onDraw方法而非draw方法这样就能渲染静态的Sprite而不让Sprite改变位置
for(Sprite s : sprites){
s.onDraw(canvas, paint, this);
}
if(combatAircraft != null){
combatAircraft.onDraw(canvas, paint, this);
}
//绘制Dialog显示得分
drawScoreDialog(canvas, "继续");
if(lastSingleClickTime > 0){
postInvalidate();
}
}
//绘制结束状态的游戏
private void drawGameOver(Canvas canvas){
//Game Over之后只绘制弹出窗显示最终得分
drawScoreDialog(canvas, "重新开始");
if(lastSingleClickTime > 0){
postInvalidate();
}
}
private void drawScoreDialog(Canvas canvas, String operation){
int canvasWidth = canvas.getWidth();
int canvasHeight = canvas.getHeight();
//存储原始值
float originalFontSize = textPaint.getTextSize();
Paint.Align originalFontAlign = textPaint.getTextAlign();
int originalColor = paint.getColor();
Paint.Style originalStyle = paint.getStyle();
/*
W = 360
w1 = 20
w2 = 320
buttonWidth = 140
buttonHeight = 42
H = 558
h1 = 150
h2 = 60
h3 = 124
h4 = 76
*/
int w1 = (int)(20.0 / 360.0 * canvasWidth);
int w2 = canvasWidth - 2 * w1;
int buttonWidth = (int)(140.0 / 360.0 * canvasWidth);
int h1 = (int)(150.0 / 558.0 * canvasHeight);
int h2 = (int)(60.0 / 558.0 * canvasHeight);
int h3 = (int)(124.0 / 558.0 * canvasHeight);
int h4 = (int)(76.0 / 558.0 * canvasHeight);
int buttonHeight = (int)(42.0 / 558.0 * canvasHeight);
canvas.translate(w1, h1);
//绘制背景色
paint.setStyle(Paint.Style.FILL);
paint.setColor(0xFFD7DDDE);
Rect rect1 = new Rect(0, 0, w2, canvasHeight - 2 * h1);
canvas.drawRect(rect1, paint);
//绘制边框
paint.setStyle(Paint.Style.STROKE);
paint.setColor(0xFF515151);
paint.setStrokeWidth(borderSize);
//paint.setStrokeCap(Paint.Cap.ROUND);
paint.setStrokeJoin(Paint.Join.ROUND);
canvas.drawRect(rect1, paint);
//绘制文本"飞机大战分数"
textPaint.setTextSize(fontSize2);
textPaint.setTextAlign(Paint.Align.CENTER);
canvas.drawText("飞机大战分数", w2 / 2, (h2 - fontSize2) / 2 + fontSize2, textPaint);
//绘制"飞机大战分数"下面的横线
canvas.translate(0, h2);
canvas.drawLine(0, 0, w2, 0, paint);
//绘制实际的分数
String allScore = String.valueOf(getScore());
canvas.drawText(allScore, w2 / 2, (h3 - fontSize2) / 2 + fontSize2, textPaint);
//绘制分数下面的横线
canvas.translate(0, h3);
canvas.drawLine(0, 0, w2, 0, paint);
//绘制按钮边框
Rect rect2 = new Rect();
rect2.left = (w2 - buttonWidth) / 2;
rect2.right = w2 - rect2.left;
rect2.top = (h4 - buttonHeight) / 2;
rect2.bottom = h4 - rect2.top;
canvas.drawRect(rect2, paint);
//绘制文本"继续"或"重新开始"
canvas.translate(0, rect2.top);
canvas.drawText(operation, w2 / 2, (buttonHeight - fontSize2) / 2 + fontSize2, textPaint);
continueRect = new Rect(rect2);
continueRect.left = w1 + rect2.left;
continueRect.right = continueRect.left + buttonWidth;
continueRect.top = h1 + h2 + h3 + rect2.top;
continueRect.bottom = continueRect.top + buttonHeight;
//重置
textPaint.setTextSize(originalFontSize);
textPaint.setTextAlign(originalFontAlign);
paint.setColor(originalColor);
paint.setStyle(originalStyle);
}
//绘制左上角的得分和左下角炸弹的数量
private void drawScoreAndBombs(Canvas canvas){
//绘制左上角的暂停按钮
Bitmap pauseBitmap = status == STATUS_GAME_STARTED ? bitmaps.get(9) : bitmaps.get(10);
RectF pauseBitmapDstRecF = getPauseBitmapDstRecF();
float pauseLeft = pauseBitmapDstRecF.left;
float pauseTop = pauseBitmapDstRecF.top;
canvas.drawBitmap(pauseBitmap, pauseLeft, pauseTop, paint);
//绘制左上角的总得分数
float scoreLeft = pauseLeft + pauseBitmap.getWidth() + 20 * density;
float scoreTop = fontSize + pauseTop + pauseBitmap.getHeight() / 2 - fontSize / 2;
canvas.drawText(score + "", scoreLeft, scoreTop, textPaint);
//绘制左下角
if(combatAircraft != null && !combatAircraft.isDestroyed()){
int bombCount = combatAircraft.getBombCount();
if(bombCount > 0){
//绘制左下角的炸弹
Bitmap bombBitmap = bitmaps.get(11);
float bombTop = canvas.getHeight() - bombBitmap.getHeight();
canvas.drawBitmap(bombBitmap, 0, bombTop, paint);
//绘制左下角的炸弹数量
float bombCountLeft = bombBitmap.getWidth() + 10 * density;
float bombCountTop = fontSize + bombTop + bombBitmap.getHeight() / 2 - fontSize / 2;
canvas.drawText("X " + bombCount, bombCountLeft, bombCountTop, textPaint);
}
}
}
//检查战斗机跑到子弹前面的情况
private void destroyBulletsFrontOfCombatAircraft(){
if(combatAircraft != null){
float aircraftY = combatAircraft.getY();
List<Bullet> aliveBullets = getAliveBullets();
for(Bullet bullet : aliveBullets){
//如果战斗机跑到了子弹前面,那么就销毁子弹
if(aircraftY <= bullet.getY()){
bullet.destroy();
}
}
}
}
//移除掉已经destroyed的Sprite
private void removeDestroyedSprites(){
Iterator<Sprite> iterator = sprites.iterator();
while (iterator.hasNext()){
Sprite s = iterator.next();
if(s.isDestroyed()){
iterator.remove();
}
}
}
//生成随机的Sprite
private void createRandomSprites(int canvasWidth){
Sprite sprite = null;
int speed = 2;
//callTime表示createRandomSprites方法被调用的次数
int callTime = Math.round(frame / 30);
if((callTime + 1) % 25 == 0){
//发送道具奖品
if((callTime + 1) % 50 == 0){
//发送炸弹
sprite = new BombAward(bitmaps.get(7));
}
else{
//发送双子弹
sprite = new BulletAward(bitmaps.get(8));
}
}
else{
//发送敌机
int[] nums = {0,0,0,0,0,1,0,0,1,0,0,0,0,1,1,1,1,1,1,2};
int index = (int)Math.floor(nums.length*Math.random());
int type = nums[index];
if(type == 0){
//小敌机
sprite = new SmallEnemyPlane(bitmaps.get(4));
}
else if(type == 1){
//中敌机
sprite = new MiddleEnemyPlane(bitmaps.get(5));
}
else if(type == 2){
//大敌机
sprite = new BigEnemyPlane(bitmaps.get(6));
}
if(type != 2){
if(Math.random() < 0.33){
speed = 4;
}
}
}
if(sprite != null){
float spriteWidth = sprite.getWidth();
float spriteHeight = sprite.getHeight();
float x = (float)((canvasWidth - spriteWidth)*Math.random());
float y = -spriteHeight;
sprite.setX(x);
sprite.setY(y);
if(sprite instanceof AutoSprite){
AutoSprite autoSprite = (AutoSprite)sprite;
autoSprite.setSpeed(speed);
}
addSprite(sprite);
}
}
/*-------------------------------touch------------------------------------*/
@Override
public boolean onTouchEvent(MotionEvent event){
//通过调用resolveTouchType方法得到我们想要的事件类型
//需要注意的是resolveTouchType方法不会返回TOUCH_SINGLE_CLICK类型
//我们会在onDraw方法每次执行的时候都会调用isSingleClick方法检测是否触发了单击事件
int touchType = resolveTouchType(event);
if(status == STATUS_GAME_STARTED){
if(touchType == TOUCH_MOVE){
if(combatAircraft != null){
combatAircraft.centerTo(touchX, touchY);
}
}else if(touchType == TOUCH_DOUBLE_CLICK){
if(status == STATUS_GAME_STARTED){
if(combatAircraft != null){
//双击会使得战斗机使用炸弹
combatAircraft.bomb(this);
}
}
}
}else if(status == STATUS_GAME_PAUSED){
if(lastSingleClickTime > 0){
postInvalidate();
}
}else if(status == STATUS_GAME_OVER){
if(lastSingleClickTime > 0){
postInvalidate();
}
}
return true;
}
//合成我们想要的事件类型
private int resolveTouchType(MotionEvent event){
int touchType = -1;
int action = event.getAction();
touchX = event.getX();
touchY = event.getY();
if(action == MotionEvent.ACTION_MOVE){
long deltaTime = System.currentTimeMillis() - touchDownTime;
if(deltaTime > singleClickDurationTime){
//触点移动
touchType = TOUCH_MOVE;
}
}else if(action == MotionEvent.ACTION_DOWN){
//触点按下
touchDownTime = System.currentTimeMillis();
}else if(action == MotionEvent.ACTION_UP){
//触点弹起
touchUpTime = System.currentTimeMillis();
//计算触点按下到触点弹起之间的时间差
long downUpDurationTime = touchUpTime - touchDownTime;
//如果此次触点按下和抬起之间的时间差小于一次单击事件指定的时间差,
//那么我们就认为发生了一次单击
if(downUpDurationTime <= singleClickDurationTime){
//计算这次单击距离上次单击的时间差
long twoClickDurationTime = touchUpTime - lastSingleClickTime;
if(twoClickDurationTime <= doubleClickDurationTime){
//如果两次单击的时间差小于一次双击事件执行的时间差,
//那么我们就认为发生了一次双击事件
touchType = TOUCH_DOUBLE_CLICK;
//重置变量
lastSingleClickTime = -1;
touchDownTime = -1;
touchUpTime = -1;
}else{
//如果这次形成了单击事件,但是没有形成双击事件,那么我们暂不触发此次形成的单击事件
//我们应该在doubleClickDurationTime毫秒后看一下有没有再次形成第二个单击事件
//如果那时形成了第二个单击事件,那么我们就与此次的单击事件合成一次双击事件
//否则在doubleClickDurationTime毫秒后触发此次的单击事件
lastSingleClickTime = touchUpTime;
}
}
}
return touchType;
}
//在onDraw方法中调用该方法在每一帧都检查是不是发生了单击事件
private boolean isSingleClick(){
boolean singleClick = false;
//我们检查一下是不是上次的单击事件在经过了doubleClickDurationTime毫秒后满足触发单击事件的条件
if(lastSingleClickTime > 0){
//计算当前时刻距离上次发生单击事件的时间差
long deltaTime = System.currentTimeMillis() - lastSingleClickTime;
if(deltaTime >= doubleClickDurationTime){
//如果时间差超过了一次双击事件所需要的时间差,
//那么就在此刻延迟触发之前本该发生的单击事件
singleClick = true;
//重置变量
lastSingleClickTime = -1;
touchDownTime = -1;
touchUpTime = -1;
}
}
return singleClick;
}
private void onSingleClick(float x, float y){
if(status == STATUS_GAME_STARTED){
if(isClickPause(x, y)){
//单击了暂停按钮
pause();
}
}else if(status == STATUS_GAME_PAUSED){
if(isClickContinueButton(x, y)){
//单击了“继续”按钮
resume();
}
}else if(status == STATUS_GAME_OVER){
if(isClickRestartButton(x, y)){
//单击了“重新开始”按钮
restart();
}
}
}
//是否单击了左上角的暂停按钮
private boolean isClickPause(float x, float y){
RectF pauseRecF = getPauseBitmapDstRecF();
return pauseRecF.contains(x, y);
}
//是否单击了暂停状态下的“继续”那妞
private boolean isClickContinueButton(float x, float y){
return continueRect.contains((int)x, (int)y);
}
//是否单击了GAME OVER状态下的“重新开始”按钮
private boolean isClickRestartButton(float x, float y){
return continueRect.contains((int)x, (int)y);
}
private RectF getPauseBitmapDstRecF(){
Bitmap pauseBitmap = status == STATUS_GAME_STARTED ? bitmaps.get(9) : bitmaps.get(10);
RectF recF = new RectF();
recF.left = 15 * density;
recF.top = 15 * density;
recF.right = recF.left + pauseBitmap.getWidth();
recF.bottom = recF.top + pauseBitmap.getHeight();
return recF;
}
/*-------------------------------destroy------------------------------------*/
private void destroyNotRecyleBitmaps(){
//将游戏设置为销毁状态
status = STATUS_GAME_DESTROYED;
//重置frame
frame = 0;
//重置得分
score = 0;
//销毁战斗机
if(combatAircraft != null){
combatAircraft.destroy();
}
combatAircraft = null;
//销毁敌机、子弹、奖励、爆炸
for(Sprite s : sprites){
s.destroy();
}
sprites.clear();
}
public void destroy(){
destroyNotRecyleBitmaps();
//释放Bitmap资源
for(Bitmap bitmap : bitmaps){
bitmap.recycle();
}
bitmaps.clear();
}
/*-------------------------------public methods-----------------------------------*/
//向Sprites中添加Sprite
public void addSprite(Sprite sprite){
spritesNeedAdded.add(sprite);
}
//添加得分
public void addScore(int value){
score += value;
}
public int getStatus(){
return status;
}
public float getDensity(){
return density;
}
public Bitmap getYellowBulletBitmap(){
return bitmaps.get(2);
}
public Bitmap getBlueBulletBitmap(){
return bitmaps.get(3);
}
public Bitmap getExplosionBitmap(){
return bitmaps.get(1);
}
//获取处于活动状态的敌机
public List<EnemyPlane> getAliveEnemyPlanes(){
List<EnemyPlane> enemyPlanes = new ArrayList<EnemyPlane>();
for(Sprite s : sprites){
if(!s.isDestroyed() && s instanceof EnemyPlane){
EnemyPlane sprite = (EnemyPlane)s;
enemyPlanes.add(sprite);
}
}
return enemyPlanes;
}
//获得处于活动状态的炸弹奖励
public List<BombAward> getAliveBombAwards(){
List<BombAward> bombAwards = new ArrayList<BombAward>();
for(Sprite s : sprites){
if(!s.isDestroyed() && s instanceof BombAward){
BombAward bombAward = (BombAward)s;
bombAwards.add(bombAward);
}
}
return bombAwards;
}
//获取处于活动状态的子弹奖励
public List<BulletAward> getAliveBulletAwards(){
List<BulletAward> bulletAwards = new ArrayList<BulletAward>();
for(Sprite s : sprites){
if(!s.isDestroyed() && s instanceof BulletAward){
BulletAward bulletAward = (BulletAward)s;
bulletAwards.add(bulletAward);
}
}
return bulletAwards;
}
//获取处于活动状态的子弹
public List<Bullet> getAliveBullets(){
List<Bullet> bullets = new ArrayList<Bullet>();
for(Sprite s : sprites){
if(!s.isDestroyed() && s instanceof Bullet){
Bullet bullet = (Bullet)s;
bullets.add(bullet);
}
}
return bullets;
}
}

@ -0,0 +1,16 @@
package com.cwj.we.game.aircraftbattle;
import android.graphics.Bitmap;
/**
*
*/
public class MiddleEnemyPlane extends EnemyPlane {
public MiddleEnemyPlane(Bitmap bitmap){
super(bitmap);
setPower(4);//中敌机抗抵抗能力为4即需要4颗子弹才能销毁中敌机
setValue(6000);//销毁一个中敌机可以得6000分
}
}

@ -0,0 +1,16 @@
package com.cwj.we.game.aircraftbattle;
import android.graphics.Bitmap;
/**
*
*/
public class SmallEnemyPlane extends EnemyPlane {
public SmallEnemyPlane(Bitmap bitmap){
super(bitmap);
setPower(1);//小敌机抗抵抗能力为1即一颗子弹就可以销毁小敌机
setValue(1000);//销毁一个小敌机可以得1000分
}
}

@ -0,0 +1,157 @@
package com.cwj.we.game.aircraftbattle;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
/**
*
*/
public class Sprite {
private boolean visible = true;
private float x = 0;
private float y = 0;
private float collideOffset = 0;
private Bitmap bitmap = null;
private boolean destroyed = false;
private int frame = 0;//绘制的次数
public Sprite(Bitmap bitmap){
this.bitmap = bitmap;
}
public Bitmap getBitmap(){
return bitmap;
}
public void setVisibility(boolean visible){
this.visible = visible;
}
public boolean getVisibility(){
return visible;
}
public void setX(float x){
this.x = x;
}
public float getX(){
return x;
}
public void setY(float y){
this.y = y;
}
public float getY(){
return y;
}
public float getWidth(){
if(bitmap != null){
return bitmap.getWidth();
}
return 0;
}
public float getHeight(){
if(bitmap != null){
return bitmap.getHeight();
}
return 0;
}
public void move(float offsetX, float offsetY){
x += offsetX;
y += offsetY;
}
public void moveTo(float x, float y){
this.x = x;
this.y = y;
}
public void centerTo(float centerX, float centerY){
float w = getWidth();
float h = getHeight();
x = centerX - w / 2;
y = centerY - h / 2;
}
public RectF getRectF(){
float left = x;
float top = y;
float right = left + getWidth();
float bottom = top + getHeight();
RectF rectF = new RectF(left, top, right, bottom);
return rectF;
}
public Rect getBitmapSrcRec(){
Rect rect = new Rect();
rect.left = 0;
rect.top = 0;
rect.right = (int)getWidth();
rect.bottom = (int)getHeight();
return rect;
}
public RectF getCollideRectF(){
RectF rectF = getRectF();
rectF.left -= collideOffset;
rectF.right += collideOffset;
rectF.top -= collideOffset;
rectF.bottom += collideOffset;
return rectF;
}
public Point getCollidePointWithOther(Sprite s){
Point p = null;
RectF rectF1 = getCollideRectF();
RectF rectF2 = s.getCollideRectF();
RectF rectF = new RectF();
boolean isIntersect = rectF.setIntersect(rectF1, rectF2);
if(isIntersect){
p = new Point(Math.round(rectF.centerX()), Math.round(rectF.centerY()));
}
return p;
}
public final void draw(Canvas canvas, Paint paint, GameView gameView){
frame++;
beforeDraw(canvas, paint, gameView);
onDraw(canvas, paint, gameView);
afterDraw(canvas, paint, gameView);
}
protected void beforeDraw(Canvas canvas, Paint paint, GameView gameView){}
public void onDraw(Canvas canvas, Paint paint, GameView gameView){
if(!destroyed && this.bitmap != null && getVisibility()){
//将Sprite绘制到Canvas上
Rect srcRef = getBitmapSrcRec();
RectF dstRecF = getRectF();
//canvas.drawBitmap(this.bitmap, x, y, paint);
canvas.drawBitmap(bitmap, srcRef, dstRecF, paint);
}
}
protected void afterDraw(Canvas canvas, Paint paint, GameView gameView){}
public void destroy(){
bitmap = null;
destroyed = true;
}
public boolean isDestroyed(){
return destroyed;
}
public int getFrame(){
return frame;
}
}

@ -0,0 +1,154 @@
package com.cwj.we.game.gobang;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import androidx.fragment.app.FragmentActivity;
import com.cwj.we.R;
import java.util.Locale;
import butterknife.ButterKnife;
/**
* activity
* Created by yangjinxiao on 2016/7/3.
*/
public abstract class BaseActivity extends FragmentActivity implements View.OnClickListener{
private static final String LANGUAGE = "language";
protected Context that;
protected View mDecorView;
protected View mRootLayout;
protected LayoutInflater mInflater;
protected Language mLang;//当前的语言环境
protected ThemeModel mTheme;//当前的主题
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
DialogUtil.init(this);
that = this;
mDecorView = getWindow().getDecorView();
mInflater = LayoutInflater.from(this);
initLang();
initTheme();
mRootLayout = mInflater.inflate(getContentLayout(), null);
ImageView back = (ImageView) mRootLayout.findViewById(R.id.iv_back);
if (back != null) {
back.setOnClickListener(this);
}
setContentView(mRootLayout);
ButterKnife.bind(this);//ButerKnife的初始化操作应放在setContentView之后
getIntentData();
initHeaderView();
initContentView();
initData();
}
protected abstract int getContentLayout();
protected void getIntentData() {
}
protected void initHeaderView() {
}
protected void initContentView() {
}
protected void initData() {
}
private void initTheme() {
String cacheTheme = readThemeCache();
try {
mTheme = (ThemeModel) JsonUtil.decode(cacheTheme, ThemeModel.class);
}catch(Exception e) {
mTheme = new ThemeModel(ThemeModel.ThemeType.DAY);
}
int themeId = ThemeModel.ThemeResId.DAY;//默认是白天主题
switch (mTheme.getType()) {
case DAY:
themeId = ThemeModel.ThemeResId.DAY;
break;
case NIGHT:
themeId = ThemeModel.ThemeResId.NIGHT;
break;
case SEXY:
themeId = ThemeModel.ThemeResId.SEXY;
break;
}
setTheme(themeId);
}
private void initLang() {
//读取缓存中存储的语言信息
String cacheLang = SharedPreferenceUtil.getSharedPreferences(LANGUAGE, Constants.Language.SIMPLED_CHINESE, this);
try {
mLang = (Language) JsonUtil.decode(cacheLang, Language.class);
}catch (Exception e) {
mLang = new Language(Language.Type.SIMPLED_CHINESE, Language.Type4Show.SIMPLED_CHINESE);
}
switchLanguage(mLang);
}
protected void setOnclickListener(View... views) {
for (View v : views) {
if (v != null) {
v.setOnClickListener(this);
}
}
}
@Override
public void onClick(View view) {
int id = view.getId();
switch (id) {
case R.id.iv_back:
finish();
break;
default:
break;
}
}
/**
*
* @param language
*/
protected void switchLanguage(Language language) {
if (language == null) {
return;
}
// 设置应用语言类型
Resources resources = getResources();
Configuration config = resources.getConfiguration();
DisplayMetrics dm = resources.getDisplayMetrics();
Locale local = config.locale;
if (Language.Type.ENGLISH.equals(language.getType())) {
if (local != Locale.ENGLISH) {
config.locale = Locale.ENGLISH;
}
}else if ((Language.Type.SIMPLED_CHINESE).equals(language.getType())){
if (local != Locale.SIMPLIFIED_CHINESE) {
config.locale = Locale.SIMPLIFIED_CHINESE;
}
}
resources.updateConfiguration(config, dm);
// 保存设置语言的类型
SharedPreferenceUtil.setSharedPreferences(LANGUAGE, JsonUtil.encode(language), this);
}
/**
*
* @return
*/
protected String readThemeCache() {
return SharedPreferenceUtil.getSharedPreferences(Constants.SharedPreferenceConstant.PROPERTY_THEME, JsonUtil.encode(new ThemeModel(ThemeModel.ThemeType.DAY)), this);
}
}

@ -0,0 +1,25 @@
package com.cwj.we.game.gobang;
/**
*
* Created by yangjinxiao on 2016/7/3.
*/
public class Constants {
public static final int MAX_LINE = 10;//棋盘的行数
public static final int WIN_PIECES_NUM = 5;//连成几个子算赢
public interface SharedPreferenceConstant {
String PREFERENCE_NAME = "GomokuApp";
String PROPERTY_THEME = "propertiy_theme";
}
public interface Language4Show {
String ENGLISH = "English";
String SIMPLED_CHINESE = "简体中文";
}
public interface Language {
String ENGLISH = "english";
String SIMPLED_CHINESE = "simple_chinese";
}
}

@ -0,0 +1,82 @@
package com.cwj.we.game.gobang;
import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.cwj.we.R;
/**
*
* Created by yangjinxiao on 2016/7/3.
*/
public class DialogUtil {
private static PopupWindow mPopupWindow;
private static Context mContext = null;
public enum DialogType {
ONE_BTN, TWO_BTN
}
private static LayoutInflater mInflater = null;
public static void init(Context context) {
mContext = context;
mInflater = LayoutInflater.from(context);
}
public static void createDialog(View parentView, String msg,
String leftBtnStr, String rightBtnStr,
final Runnable leftClickRunnable, final Runnable righClickRunnable) {
if (mInflater == null) {
return;
}
RelativeLayout layout = (RelativeLayout) mInflater.inflate(R.layout.layout_popupwindow_container, null);
LinearLayout containerLayout = (LinearLayout) layout.findViewById(R.id.ll_container);
containerLayout.setBackgroundResource(R.drawable.bg_popupwindow);
View dialogLayout = mInflater.inflate(R.layout.dialog_main, null);
containerLayout.addView(dialogLayout);
TextView msgText = (TextView) dialogLayout.findViewById(R.id.tv_msg);
TextView leftBtnText = (TextView) dialogLayout.findViewById(R.id.bt_1);
TextView rightBtnText = (TextView) dialogLayout.findViewById(R.id.bt_2);
msgText.setText(msg);
leftBtnText.setText(leftBtnStr);
rightBtnText.setText(rightBtnStr);
leftBtnText.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
leftClickRunnable.run();
mPopupWindow.dismiss();
}
});
rightBtnText.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
righClickRunnable.run();
mPopupWindow.dismiss();
}
});
leftBtnText.setVisibility(StringUtil.isNullOrEmpty(leftBtnStr) ? View.GONE : View.VISIBLE);
rightBtnText.setVisibility(StringUtil.isNullOrEmpty(rightBtnStr) ? View.GONE : View.VISIBLE);
mPopupWindow = new PopupWindow(layout, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, true);
mPopupWindow.setBackgroundDrawable(new ColorDrawable(0x00000000));
mPopupWindow.setOutsideTouchable(true);
mPopupWindow.showAtLocation(parentView, Gravity.CENTER, 0, 0);
}
public static PopupWindow createPopupWindowWithCustomView(View parentView, View contentView) {
mPopupWindow = new PopupWindow(contentView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, true);
mPopupWindow.setBackgroundDrawable(new ColorDrawable(0x00000000));
mPopupWindow.setOutsideTouchable(true);
mPopupWindow.setAnimationStyle(R.style.anim_menu_bottombar);
mPopupWindow.showAtLocation(parentView, Gravity.CENTER, 0, 0);
return mPopupWindow;
}
}

@ -0,0 +1,22 @@
package com.cwj.we.game.gobang;
import com.google.gson.Gson;
/**
* Created by yangjinxiao on 2016/7/4.
*/
public class JsonUtil {
private static final Gson mGson = new Gson();
public static String encode(Object o) {
if (o == null) {
return "";
}
return mGson.toJson(o);
}
public static final Object decode(String jsonStr, Class clazz) {
if (jsonStr instanceof String) {
return mGson.fromJson(jsonStr, clazz);
}
return null;
}
}

@ -0,0 +1,66 @@
package com.cwj.we.game.gobang;
import java.util.ArrayList;
/**
* Created by yangjinxiao on 2016/7/8.
*/
public class Language {
private String type;//"english" "simple_chinese"
private String type4Show;//"English" "简体汉字"
public static ArrayList<Language> ALL_LANGS = new ArrayList<>();
static {
Language en = new Language(Type.ENGLISH, Type4Show.ENGLISH);
Language zh = new Language(Type.SIMPLED_CHINESE, Type4Show.SIMPLED_CHINESE);
ALL_LANGS.add(en);
ALL_LANGS.add(zh);
}
public Language(String type, String type4Show) {
this.type = type;
this.type4Show = type4Show;
}
@Override
public boolean equals(Object o) {
if (o == null) {
return false;
}
if (o instanceof Language) {
Language obj = (Language) o;
String objType = obj.getType();
String objType4Show = obj.getType4Show();
if ((!StringUtil.isNullOrEmpty(objType) && objType.equals(this.getType()))
|| (!StringUtil.isNullOrEmpty(objType4Show) && objType4Show.equals(this.getType4Show()))) {
return true;
}
}
return false;
}
public interface Type {
String ENGLISH = "english";
String SIMPLED_CHINESE = "simple_chinese";
}
public interface Type4Show {
String ENGLISH = "English";
String SIMPLED_CHINESE = "简体中文";
}
public String getType() {
return type;
}
public void setType(String lang) {
this.type = lang;
}
public String getType4Show() {
return type4Show;
}
public void setLang4Show(String lang4Show) {
this.type4Show = lang4Show;
}
}

@ -0,0 +1,435 @@
package com.cwj.we.game.gobang;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import com.cwj.we.R;
import java.util.ArrayList;
import java.util.List;
/**
* Created by yangjinxiao on 2016/6/30.
*/
public class PannelView extends View {
private int mPannaWidth;//棋盘的宽度
private float mLineHeight;//行高(定义成float型防止精度丢失)
private Paint mPaint;
private Paint mPiecePaint;//绘制棋子画笔
private static final float RATIO = 3 * 1.0f / 4;//棋子图片占行高的比例
private int mLineColorId = R.color.Gray;//线的颜色
private Bitmap mWhitePiece;
private Bitmap mBlackPiece;
private ArrayList<Piece> mWhitePieces = new ArrayList<>();//用来存储用户已经下子的点
private ArrayList<Piece> mBlackPieces = new ArrayList<>();
private boolean mIsCurWhiteTurn = true;//当前轮到白子下(这里默认白子先手)
private Piece mCurClickPiece;//当前已下子的点
private boolean mIsGameOver;//标识游戏结束
private boolean mIsWhiteWin;//是否是白子赢了
private OnGameOverListener mGameOverListener;
private OnTurnChangedListener mTurnChangedListener;
private static final int STROKE_LINE_WIDTH = 2;//dp
//数据保存与恢复相关常量
private static final String DEFAULT_INSTANCE = "default_instance";
private static final String WHITE_PIECES = "white_pieces";
private static final String BLACK_PIECES = "black_pieces";
private static final String IS_CUR_WHITE = "is_cur_white";
private static final String CUR_CLICK_POINT = "cur_click_point";
public void registerGameOverListner(OnGameOverListener listener) {
this.mGameOverListener = listener;
}
public void registerTurnChangedListener(OnTurnChangedListener turnChangedListener) {
this.mTurnChangedListener = turnChangedListener;
}
public boolean getIsCurWhiteTurn() {
return mIsCurWhiteTurn;
}
/**
*
*/
public void regretLastStep() {
if (mIsCurWhiteTurn) {//当前轮到白方下子,即黑方要悔棋
if (mBlackPieces != null && !mBlackPieces.isEmpty()) {
mBlackPieces.remove(mBlackPieces.size() - 1);
if (mWhitePieces != null && !mWhitePieces.isEmpty()) {
mCurClickPiece = mWhitePieces.get(mWhitePieces.size() - 1);
}
mIsCurWhiteTurn = !mIsCurWhiteTurn;
notifyObserverTurnChanged();
invalidate();
return;
}
}else {
if (mWhitePieces != null && !mWhitePieces.isEmpty()) {
mWhitePieces.remove(mWhitePieces.size() - 1);
if (mBlackPieces != null && !mBlackPieces.isEmpty()) {
mCurClickPiece = mBlackPieces.get(mBlackPieces.size() - 1);
}
mIsCurWhiteTurn = !mIsCurWhiteTurn;
notifyObserverTurnChanged();
invalidate();
return;
}
}
}
public PannelView(Context context) {
this(context, null);
}
public PannelView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public PannelView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
mPaint = new Paint();
mPaint.setColor(getContext().getResources().getColor(mLineColorId));
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
mPaint.setStrokeWidth(Util.dp2px(STROKE_LINE_WIDTH, getContext()));
mPiecePaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setStyle(Paint.Style.FILL);
mWhitePiece = BitmapFactory.decodeResource(getResources(), R.drawable.stone_w2);
mBlackPiece = BitmapFactory.decodeResource(getResources(), R.drawable.stone_b1);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int heigutMode = MeasureSpec.getMode(heightMeasureSpec);
int squareWidth = Math.min(widthSize, heightSize);//取宽和高的最小值作为正方形棋盘的边长
//针对MeasureMode = UNSPCIFIED的情况做特殊处理(棋盘View的宽高不允许设置为wrap_content)
if (widthMode == MeasureSpec.UNSPECIFIED) {
squareWidth = heightSize;
}else if (heigutMode == MeasureSpec.UNSPECIFIED) {
squareWidth = widthSize;
}
setMeasuredDimension(squareWidth, squareWidth);
}
/**
* View
* @param w
* @param h
* @param oldw
* @param oldh
*/
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mPannaWidth = w;
mLineHeight = (mPannaWidth * 1.0f / Constants.MAX_LINE);
//修改棋子图片的大小,行高的3/4
int pieceWidth = (int) (mLineHeight * RATIO);
mWhitePiece = Bitmap.createScaledBitmap(mWhitePiece, pieceWidth, pieceWidth, false);
mBlackPiece = Bitmap.createScaledBitmap(mBlackPiece, pieceWidth, pieceWidth, false);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
drawBoard(canvas);
drawPiece(canvas);
if (checkGameOver()) {
mIsGameOver = true;
if (mGameOverListener != null) {
mGameOverListener.onGameOver(mIsWhiteWin);
}
}
}
//绘制棋板
private void drawBoard(Canvas canvas) {
int pannalWidth = mPannaWidth;
float lineHeight = mLineHeight;
//绘制横线
for (int i = 0; i < Constants.MAX_LINE; i++) {
float startX = (0.5f * lineHeight);
float endX = (pannalWidth - 0.5f * lineHeight);
float startY = ((0.5f + i) * lineHeight);
float endY = startY;
canvas.drawLine(startX, startY, endX, endY, mPaint);
}
//绘制竖线
for (int i = 0; i < Constants.MAX_LINE; i++) {
float startX = ((0.5f + i) * lineHeight);
float endX = startX;
float startY = (0.5f * lineHeight);
float endY = (pannalWidth - 0.5f * lineHeight);
canvas.drawLine(startX, startY, endX, endY, mPaint);
}
}
/**
*
* @param canvas
*/
private void drawPiece(Canvas canvas) {
for (int i = 0; i < mWhitePieces.size(); i++) {
Piece point = mWhitePieces.get(i);
float left = (point.x + (1 - RATIO) / 2) * mLineHeight;
float top = (point.y + (1 - RATIO) / 2) * mLineHeight;
canvas.drawBitmap(mWhitePiece, left, top, mPiecePaint);
}
for (int i = 0; i < mBlackPieces.size(); i++) {
Piece point = mBlackPieces.get(i);
float left = (point.x + (1 - RATIO) / 2) * mLineHeight;
float top = (point.y + (1 - RATIO) / 2) * mLineHeight;
canvas.drawBitmap(mBlackPiece, left, top, mPiecePaint);
}
}
/**
*
* @return true: game over
*/
private boolean checkGameOver() {
if (mIsCurWhiteTurn) {//当前轮到白子下,即应该检验上一手黑子是否连成
boolean blackWin = checkHorizontalOrVerticalDone(mBlackPieces);
if (!blackWin) {
blackWin = checkLeftOrRightOblique(mBlackPieces);
}
if (blackWin) {
mIsWhiteWin = false;
return true;
}
}else {
boolean whiteWin = checkHorizontalOrVerticalDone(mWhitePieces);
if (!whiteWin) {
whiteWin = checkLeftOrRightOblique(mWhitePieces);
}
if (whiteWin) {
mIsWhiteWin = true;
return true;
}
}
return false;
}
/**
* /
* @param points
* @return
*/
private boolean checkHorizontalOrVerticalDone(List<Piece> points) {
if (points == null || points.isEmpty() || mCurClickPiece == null) {
return false;
}
int horizontalCount = 1;//横向计数
int verticalCount = 1;//纵向计数
for (int i = 1; i < Constants.WIN_PIECES_NUM; i++) {//往左检查
Piece leftPoint = new Piece(mCurClickPiece.x - i, mCurClickPiece.y);
if (points.contains(leftPoint)) {
horizontalCount++;
continue;
} else {
break;
}
}
for (int i = 1; i < Constants.WIN_PIECES_NUM; i++) {//往右检查
Piece rightPoint = new Piece(mCurClickPiece.x + i, mCurClickPiece.y);
if (points.contains(rightPoint)) {
horizontalCount++;
continue;
} else {
break;
}
}
for (int i = 1; i < Constants.WIN_PIECES_NUM; i++) {//往上检查
Piece upPoint = new Piece(mCurClickPiece.x, mCurClickPiece.y - i);
if (points.contains(upPoint)) {
verticalCount++;
continue;
} else {
break;
}
}
for (int i = 1; i < Constants.WIN_PIECES_NUM; i++) {//往下检查
Piece belowPoint = new Piece(mCurClickPiece.x, mCurClickPiece.y + i);
if (points.contains(belowPoint)) {
verticalCount++;
continue;
} else {
break;
}
}
if (horizontalCount == Constants.WIN_PIECES_NUM || verticalCount == Constants.WIN_PIECES_NUM) {
return true;
}
return false;
}
/**
*
* @return
*/
private boolean checkLeftOrRightOblique(List<Piece> points) {
if (points == null || points.isEmpty() || mCurClickPiece == null) {
return false;
}
int leftObliqueCounts = 1;
int rightObliqueCounts = 1;
for (int i = 1; i < Constants.WIN_PIECES_NUM; i++) {//左斜向上检查
Piece leftUpPoint = new Piece(mCurClickPiece.x + i, mCurClickPiece.y - i);
if (points.contains(leftUpPoint)) {
leftObliqueCounts++;
continue;
} else {
break;
}
}
for (int i = 1; i < Constants.WIN_PIECES_NUM; i++) {//左斜向下检查
Piece leftDownPoint = new Piece(mCurClickPiece.x - i, mCurClickPiece.y + i);
if (points.contains(leftDownPoint)) {
leftObliqueCounts++;
continue;
} else {
break;
}
}
if (leftObliqueCounts == Constants.WIN_PIECES_NUM) {
return true;
}
for (int i = 1; i < Constants.WIN_PIECES_NUM; i++) {//右斜向上检查
Piece rightUpPoint = new Piece(mCurClickPiece.x - i, mCurClickPiece.y - i);
if (points.contains(rightUpPoint)) {
rightObliqueCounts++;
continue;
} else {
break;
}
}
for (int i = 1; i < Constants.WIN_PIECES_NUM; i++) {//右斜向下检查
Piece rightDownPoint = new Piece(mCurClickPiece.x + i, mCurClickPiece.y + i);
if (points.contains(rightDownPoint)) {
rightObliqueCounts++;
continue;
} else {
break;
}
}
if (rightObliqueCounts == Constants.WIN_PIECES_NUM) {
return true;
}
return false;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (mIsGameOver) {
return false;//游戏结束,不关心点击事件
}
int action = event.getAction();
if (action == MotionEvent.ACTION_UP) {//用户手指抬起时处理不在ACTION_DOWN时处理防止嵌套在ScrollView中时滚动时落子
int x = (int) event.getX();
int y = (int) event.getY();
mCurClickPiece = getProperPoint(x, y);
if (mWhitePieces.contains(mCurClickPiece) || mBlackPieces.contains(mCurClickPiece)) {//当前点已经下过子了
return false;
}
if (mIsCurWhiteTurn) {
mWhitePieces.add(mCurClickPiece);
}else {
mBlackPieces.add(mCurClickPiece);
}
mIsCurWhiteTurn = !mIsCurWhiteTurn;
notifyObserverTurnChanged();
invalidate();//请求重绘
}
return true;
}
/**
*
*/
private void notifyObserverTurnChanged() {
if (mTurnChangedListener != null) {
mTurnChangedListener.onTurnChangeListener(mIsCurWhiteTurn);
}
}
/**
* (0,1) (0,2)
* 便
* @param x
* @param y
* @return
*/
private Piece getProperPoint(int x, int y) {
return new Piece((int) (x / mLineHeight), (int) (y / mLineHeight));
}
/**
*
*/
public void restart() {
mWhitePieces.clear();
mBlackPieces.clear();
mIsGameOver = false;
mIsWhiteWin = false;
mCurClickPiece = null;
mIsCurWhiteTurn = true;
invalidate();
}
@Override
protected Parcelable onSaveInstanceState() {
Bundle bundle = new Bundle();
bundle.putParcelable(DEFAULT_INSTANCE, super.onSaveInstanceState());
bundle.putParcelableArrayList(WHITE_PIECES, mWhitePieces);
bundle.putParcelableArrayList(BLACK_PIECES, mBlackPieces);
bundle.putBoolean(IS_CUR_WHITE, mIsCurWhiteTurn);
bundle.putParcelable(CUR_CLICK_POINT, mCurClickPiece);
return bundle;
}
@Override
protected void onRestoreInstanceState(Parcelable state) {
if (state instanceof Bundle) {
Bundle bundle = (Bundle) state;
Parcelable defaultState = bundle.getParcelable(DEFAULT_INSTANCE);
super.onRestoreInstanceState(defaultState);//系统默认保存的数据
mWhitePieces = bundle.getParcelableArrayList(WHITE_PIECES);
mBlackPieces = bundle.getParcelableArrayList(BLACK_PIECES);
mIsCurWhiteTurn = bundle.getBoolean(IS_CUR_WHITE);
mCurClickPiece = bundle.getParcelable(CUR_CLICK_POINT);
return;
}
super.onRestoreInstanceState(state);
}
public interface OnGameOverListener {
void onGameOver(boolean isWhiteWin);
}
public interface OnTurnChangedListener {
void onTurnChangeListener(boolean isWhiteTurn);
}
}

@ -0,0 +1,13 @@
package com.cwj.we.game.gobang;
import android.graphics.Point;
/**
* Created by yangjinxiao on 2016/7/5.
*/
public class Piece extends Point {
public static final Creator<Point> CREATOR = null;
public Piece(int x, int y) {
super(x, y);
}
}

@ -0,0 +1,43 @@
package com.cwj.we.game.gobang;
import android.content.Context;
import android.preference.PreferenceActivity;
/**
* Created by yangjinxiao on 2016/7/4.
*/
public class SharedPreferenceUtil {
public static String getSharedPreferences(String propertyName, Context context) {
return context.getSharedPreferences(Constants.SharedPreferenceConstant.PREFERENCE_NAME, PreferenceActivity.MODE_MULTI_PROCESS).getString(propertyName, "");
}
public static String getSharedPreferences(String propertyName, String defaultValue, Context context) {
return context.getSharedPreferences(Constants.SharedPreferenceConstant.PREFERENCE_NAME, PreferenceActivity.MODE_PRIVATE).getString(propertyName, defaultValue);
}
public static int getSharedPreferences(String propertyName, Context context, int defaultValue) {
return context.getSharedPreferences(Constants.SharedPreferenceConstant.PREFERENCE_NAME, PreferenceActivity.MODE_PRIVATE).getInt(propertyName, defaultValue);
}
public static long getSharedPreferences(String propertyName, Context context, long defaultValue) {
return context.getSharedPreferences(Constants.SharedPreferenceConstant.PREFERENCE_NAME, PreferenceActivity.MODE_PRIVATE).getLong(propertyName, defaultValue);
}
public static boolean setSharedPreferences(String propertyName, String propertyValue, Context context) {
return context.getSharedPreferences(Constants.SharedPreferenceConstant.PREFERENCE_NAME, Context.MODE_PRIVATE).edit()
.putString(propertyName, propertyValue).commit();
}
public static boolean setSharedPreferences(String propertyName, int propertyValue, Context context) {
return context.getSharedPreferences(Constants.SharedPreferenceConstant.PREFERENCE_NAME, Context.MODE_PRIVATE).edit()
.putInt(propertyName, propertyValue).commit();
}
public static boolean setSharedPreferences(String preferenceName, String propertyName, long propertyValue, Context context) {
return context.getSharedPreferences(preferenceName, Context.MODE_PRIVATE).edit()
.putLong(propertyName, propertyValue).commit();
}
}

@ -0,0 +1,19 @@
package com.cwj.we.game.gobang;
/**
*
* Created by yangjinxiao on 2016/7/3.
*/
public class StringUtil {
public static boolean isNullOrEmpty(String str) {
return str == null || str.length() == 0;
}
public static boolean isAllNullOrEmpty(String... strs) {
for (String str : strs) {
if (str != null && str.length() > 0) {
return false;
}
}
return true;
}
}

@ -0,0 +1,103 @@
package com.cwj.we.game.gobang;
import com.cwj.we.R;
import java.util.ArrayList;
/**
* Created by yangjinxiao on 2016/7/8.
*/
public class ThemeModel {
private ThemeType type;
private String type4Show;//用于显示
private String type4ShowEn;//用于显示(英文环境下)
public static ArrayList<ThemeModel> ALL_THEMES = new ArrayList<>();
static {
ThemeModel day = new ThemeModel(ThemeType.DAY);
ThemeModel night = new ThemeModel(ThemeType.NIGHT);
ThemeModel sexy = new ThemeModel(ThemeType.SEXY);
ALL_THEMES.add(day);
ALL_THEMES.add(night);
ALL_THEMES.add(sexy);
}
public enum ThemeType {
DAY, NIGHT, SEXY
}
public interface ThemeResId {
int DAY = R.style.DayTheme;
int NIGHT = R.style.NightTheme;
int SEXY = R.style.SexyTheme;
}
public interface Type4Show {
String DAY = "日间模式";
String NIGHT = "夜间模式";
String SEXY = "紫色魅惑";
String DAY_EN = "Day theme";
String NIGHT_EN = "Night theme";
String SEXY_EN = "Plum theme";
}
public ThemeModel(ThemeType type) {
this.type = type;
switch (type) {
case DAY:
this.type4Show = Type4Show.DAY;
this.type4ShowEn = Type4Show.DAY_EN;
break;
case NIGHT:
this.type4Show = Type4Show.NIGHT;
this.type4ShowEn = Type4Show.NIGHT_EN;
break;
case SEXY:
this.type4Show = Type4Show.SEXY;
this.type4ShowEn = Type4Show.SEXY_EN;
break;
}
}
public ThemeType getType() {
return type;
}
public void setType(ThemeType type) {
this.type = type;
}
public String getType4Show() {
return type4Show;
}
public void setType4Show(String themeModel4Show) {
this.type4Show = themeModel4Show;
}
public String getType4ShowEn() {
return type4ShowEn;
}
public void setType4ShowEn(String themeModel4ShowEn) {
this.type4ShowEn = themeModel4ShowEn;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
ThemeModel otherModel = null;
if (obj instanceof ThemeModel) {
otherModel = (ThemeModel) obj;
}
if (otherModel != null) {
return this.getType().equals(otherModel.getType())
&& this.getType4Show().equals(otherModel.getType4Show())
&& this.getType4ShowEn().equals(otherModel.getType4ShowEn());
}
return false;
}
}

@ -0,0 +1,30 @@
package com.cwj.we.game.gobang;
import android.content.Context;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.Display;
import android.view.WindowManager;
/**
* Created by yangjinxiao on 2016/7/3.
*/
public class Util {
public static float dp2px(int dpVal, Context context) {
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpVal, context.getResources().getDisplayMetrics());
}
public static int[] getScrrenPixels(Context context) {
int[] screen = new int[2];
if (context == null) {
return screen;
}
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display ds = wm.getDefaultDisplay();
DisplayMetrics dm = new DisplayMetrics();
ds.getMetrics(dm);
screen[0] = dm.widthPixels;
screen[1] = dm.heightPixels;
return screen;
}
}

@ -0,0 +1,394 @@
package com.cwj.we.game.puzzle;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.Toast;
import com.cwj.we.R;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
* Description: 2048
* Data2016/9/11-19:48
* Blogwww.qiuchengjia.cn
* Author: qiu
*/
public class GamePintuLayout extends RelativeLayout implements View.OnClickListener {
/**
* Itemn*n3
*/
private int mColumn = 3;
/**
*
*/
private int mWidth;
/**
* padding
*/
private int mPadding;
/**
* Item
*/
private ImageView[] mGamePintuItems;
/**
* Item
*/
private int mItemWidth;
/**
* Item
*/
private int mMargin = 3;
/**
*
*/
private Bitmap mBitmap;
/**
* bean
*/
private List<ImagePiece> mItemBitmaps;
/**
*
*/
private boolean once;
public GamePintuLayout(Context context) {
this(context, null);
}
public GamePintuLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
/**
*
*
* @param context the context
* @param attrs the attrs
* @param defStyle the def style
* @author qiu www.qiuchengjia.cn 2016-09-12
*/
public GamePintuLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
//把设置的margin值转换为dp
mMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
mMargin, getResources().getDisplayMetrics());
// 设置Layout的内边距四边一致设置为四内边距中的最小值
mPadding = min(getPaddingLeft(), getPaddingTop(), getPaddingRight(),
getPaddingBottom());
}
/**
* View
*
* @param widthMeasureSpec the width measure spec
* @param heightMeasureSpec the height measure spec
* @author qiu www.qiuchengjia.cn 2016-09-12
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// 获得游戏布局的边长
mWidth = Math.min(getMeasuredHeight(), getMeasuredWidth());
if (!once) {
initBitmap();
initItem();
}
once = true;
setMeasuredDimension(mWidth, mWidth);
}
/**
* bitmap
*
* @author qiu www.qiuchengjia.cn 2016-09-12
*/
private void initBitmap() {
if (mBitmap == null)
mBitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.bb);
mItemBitmaps = ImageSplitter.split(mBitmap, mColumn);
//对图片进行排序
Collections.sort(mItemBitmaps, new Comparator<ImagePiece>() {
@Override
public int compare(ImagePiece lhs, ImagePiece rhs) {
//我们使用random随机比较大小
return Math.random() > 0.5 ? 1 : -1;
}
});
}
/**
* item
*
* @author qiu www.qiuchengjia.cn 2016-09-12
*/
private void initItem() {
// 获得Item的宽度
int childWidth = (mWidth - mPadding * 2 - mMargin * (mColumn - 1))
/ mColumn;
mItemWidth = childWidth;
mGamePintuItems = new ImageView[mColumn * mColumn];
// 放置Item
for (int i = 0; i < mGamePintuItems.length; i++) {
ImageView item = new ImageView(getContext());
item.setOnClickListener(this);
item.setImageBitmap(mItemBitmaps.get(i).bitmap);
mGamePintuItems[i] = item;
item.setId(i + 1);
item.setTag(i + "_" + mItemBitmaps.get(i).index);
LayoutParams lp = new LayoutParams(mItemWidth,
mItemWidth);
// 设置横向边距,不是最后一列
if ((i + 1) % mColumn != 0) {
lp.rightMargin = mMargin;
}
// 如果不是第一列
if (i % mColumn != 0) {
lp.addRule(RelativeLayout.RIGHT_OF,//
mGamePintuItems[i - 1].getId());
}
// 如果不是第一行,//设置纵向边距,非最后一行
if ((i + 1) > mColumn) {
lp.topMargin = mMargin;
lp.addRule(RelativeLayout.BELOW,//
mGamePintuItems[i - mColumn].getId());
}
addView(item, lp);
}
}
/**
*
*
* @param params the params
* @return the int
* @author qiu www.qiuchengjia.cn 2016-09-12
*/
private int min(int... params) {
int minValue = params[0];
for (int param : params) {
if (minValue > param) {
minValue = param;
}
}
return minValue;
}
/**
* ImageView
*/
private ImageView mFirst;
/**
* ImageView
*/
private ImageView mSecond;
/**
*
*
* @param view the view
* @author qiu www.qiuchengjia.cn 2016-09-12
*/
@Override
public void onClick(View view) {
Log.d("TAG", "onClick: " + view.getTag());
// 如果正在执行动画,则屏蔽
if (isAniming)
return;
//如果两次点击的是同一个View
if (mFirst == view) {
mFirst.setColorFilter(null);
mFirst = null;
return;
}
//点击第一个View
if (mFirst == null) {
mFirst = (ImageView) view;
mFirst.setColorFilter(Color.parseColor("#55FF0000"));
} else {//点击第二个View
mSecond = (ImageView) view;
exchangView();
}
}
/**
*
*/
private boolean isAniming;
/**
*
*/
private RelativeLayout mAnimLayout;
/**
* Item
*
* @author qiu www.qiuchengjia.cn 2016-09-12
*/
private void exchangView() {
mFirst.setColorFilter(null);
setUpAnimLayout();
// 添加FirstView
ImageView first = new ImageView(getContext());
first.setImageBitmap(mItemBitmaps
.get(getImageIndexByTag((String) mFirst.getTag())).bitmap);
LayoutParams lp = new LayoutParams(mItemWidth, mItemWidth);
lp.leftMargin = mFirst.getLeft() - mPadding;
lp.topMargin = mFirst.getTop() - mPadding;
first.setLayoutParams(lp);
mAnimLayout.addView(first);
// 添加SecondView
ImageView second = new ImageView(getContext());
second.setImageBitmap(mItemBitmaps
.get(getImageIndexByTag((String) mSecond.getTag())).bitmap);
LayoutParams lp2 = new LayoutParams(mItemWidth, mItemWidth);
lp2.leftMargin = mSecond.getLeft() - mPadding;
lp2.topMargin = mSecond.getTop() - mPadding;
second.setLayoutParams(lp2);
mAnimLayout.addView(second);
// 设置动画
TranslateAnimation anim = new TranslateAnimation(0, mSecond.getLeft()
- mFirst.getLeft(), 0, mSecond.getTop() - mFirst.getTop());
anim.setDuration(300);
anim.setFillAfter(true);
first.startAnimation(anim);
TranslateAnimation animSecond = new TranslateAnimation(0,
mFirst.getLeft() - mSecond.getLeft(), 0, mFirst.getTop()
- mSecond.getTop());
animSecond.setDuration(300);
animSecond.setFillAfter(true);
second.startAnimation(animSecond);
// 添加动画监听
anim.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
isAniming = true;
mFirst.setVisibility(INVISIBLE);
mSecond.setVisibility(INVISIBLE);
}
@Override
public void onAnimationRepeat(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
if (mFirst == null || mSecond == null) {
return;
} else {
String firstTag = (String) mFirst.getTag();
String secondTag = (String) mSecond.getTag();
String[] firstParams = firstTag.split("_");
String[] secondParams = secondTag.split("_");
mFirst.setImageBitmap(mItemBitmaps.get(Integer
.parseInt(secondParams[0])).bitmap);
mSecond.setImageBitmap(mItemBitmaps.get(Integer
.parseInt(firstParams[0])).bitmap);
mFirst.setTag(secondTag);
mSecond.setTag(firstTag);
mFirst.setVisibility(VISIBLE);
mSecond.setVisibility(VISIBLE);
mFirst = mSecond = null;
mAnimLayout.removeAllViews();
//checkSuccess();
isAniming = false;
//进行游戏胜利判断
checkSuccess();
}
}
});
}
/**
*
*
* @author qiu www.qiuchengjia.cn 2016-09-12
*/
private void checkSuccess() {
boolean isSuccess = true;
for (int i = 0; i < mGamePintuItems.length; i++) {
ImageView first = mGamePintuItems[i];
Log.e("TAG", getIndexByTag((String) first.getTag()) + "");
if (getIndexByTag((String) first.getTag()) != i) {
isSuccess = false;
}
}
if (isSuccess) {
Toast.makeText(getContext(), "成功 , 难度升级 !",
Toast.LENGTH_LONG).show();
nextLevel();
}
}
/**
*
*
* @author qiu www.qiuchengjia.cn 2016-09-12
*/
private void nextLevel() {
this.removeAllViews();
mAnimLayout = null;
mColumn++;
initBitmap();
initItem();
}
/**
*
*/
private void setUpAnimLayout() {
if (mAnimLayout == null) {
mAnimLayout = new RelativeLayout(getContext());
addView(mAnimLayout);
}
}
/**
* mItemBitmaps
*
* @param tag the tag
* @return the image index by tag
*/
private int getImageIndexByTag(String tag) {
String[] split = tag.split("_");
return Integer.parseInt(split[0]);
}
/**
*
*
* @param tag the tag
* @return the index by tag
*/
private int getIndexByTag(String tag) {
String[] split = tag.split("_");
return Integer.parseInt(split[1]);
}
}

@ -0,0 +1,14 @@
package com.cwj.we.game.puzzle;
import android.graphics.Bitmap;
/**
* Description:
* Data2016/9/11-19:54
* Blogwww.qiuchengjia.cn
* Author: qiu
*/
public class ImagePiece {
public int index=0;//图片的索引
public Bitmap bitmap=null;//图片
}

@ -0,0 +1,45 @@
package com.cwj.we.game.puzzle;
import android.graphics.Bitmap;
import android.util.Log;
import java.util.ArrayList;
import java.util.List;
/**
* Description:
* Data2016/9/11-19:53
* Blogwww.qiuchengjia.cn
* Author: qiu
*/
public class ImageSplitter {
/**
* piece * piece
* @param bitmap the bitmap
* @param piece the piece
* @return the list
* @author qiu www.qiuchengjia.cn 2016-09-11
*/
public static List<ImagePiece> split(Bitmap bitmap, int piece){
List<ImagePiece> pieces = new ArrayList<ImagePiece>(piece * piece);
int width = bitmap.getWidth();
int height = bitmap.getHeight();
Log.e("TAG", "bitmap Width = " + width + " , height = " + height);
int pieceWidth = Math.min(width, height) / piece;
for (int i = 0; i < piece; i++){
for (int j = 0; j < piece; j++){
ImagePiece imagePiece = new ImagePiece();
imagePiece.index = j + i * piece;
int xValue = j * pieceWidth;
int yValue = i * pieceWidth;
imagePiece.bitmap = Bitmap.createBitmap(bitmap, xValue, yValue,
pieceWidth, pieceWidth);
pieces.add(imagePiece);
}
}
return pieces;
}
}

@ -0,0 +1,17 @@
package com.cwj.we.http;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Path;
import retrofit2.http.Query;
public interface API {
String BASE_URL = "https://v1.alapi.cn/";
String BASE_URL_UPDATA = "http://api.bq04.com/";
//检测版本更新
@GET("apps/latest/{id}")
Call<ResponseBody> latest(@Path("id") String id, @Query("api_token") String api_token);
}

@ -0,0 +1,79 @@
package com.cwj.we.http;
import com.cwj.we.http.gson.BaseConverterFactory;
import java.util.concurrent.TimeUnit;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
/**
* Description : RetrofitService
*
* @author XuCanyou666
* @date 2020/2/8
*/
public class RetrofitService {
private volatile static RetrofitService apiRetrofit;
private API apiServer;
/**
*
*
* @return RetrofitService
*/
public static RetrofitService getInstance() {
if (apiRetrofit == null) {
synchronized (Object.class) {
if (apiRetrofit == null) {
apiRetrofit = new RetrofitService();
}
}
}
return apiRetrofit;
}
/**
* api
*
* @return api
*/
public API getApiService() {
return apiServer;
}
/**
* retrofit
*/
private RetrofitService() {
//配置okHttp并设置时间、日志信息和cookies
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.addInterceptor(httpLoggingInterceptor)
//设置超时时间
.connectTimeout(15, TimeUnit.SECONDS)
//设置Cookie持久化
// .cookieJar(new CookiesManager(YUtils.getApplication()))
.build();
//关联okHttp并加上rxJava和Gson的配置和baseUrl
Retrofit retrofit = new Retrofit.Builder()
.client(okHttpClient)
.addConverterFactory(BaseConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.baseUrl(API.BASE_URL)
.build();
apiServer = retrofit.create(API.class);
}
}

@ -0,0 +1,36 @@
package com.cwj.we.http.cookie;
import android.content.Context;
import java.util.List;
import okhttp3.Cookie;
import okhttp3.CookieJar;
import okhttp3.HttpUrl;
/**
* Created by yechao on 2019/11/19/019.
* Describe :
*/
public class CookiesManager implements CookieJar {
private final PersistentCookieStore cookieStore;
public CookiesManager(Context context) {
cookieStore = new PersistentCookieStore(context);
}
@Override
public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
if (cookies.size() > 0) {
for (Cookie item : cookies) {
cookieStore.add(url, item);
}
}
}
@Override
public List<Cookie> loadForRequest(HttpUrl url) {
return cookieStore.get(url);
}
}

@ -0,0 +1,208 @@
package com.cwj.we.http.cookie;
import android.content.Context;
import android.content.SharedPreferences;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import okhttp3.Cookie;
import okhttp3.HttpUrl;
/**
* Created by yechao on 2019/11/19/019.
* Describe :
*/
public class PersistentCookieStore {
private static final String LOG_TAG = "PersistentCookieStore";
public static final String COOKIE_PREFS = "Cookies_Prefs";
private Map<String, ConcurrentHashMap<String, Cookie>> cookies;
private SharedPreferences cookiePrefs;
public PersistentCookieStore(Context context) {
cookiePrefs = context.getSharedPreferences(COOKIE_PREFS, 0);
cookies = new ArrayMap<>();
//将持久化的cookies缓存到内存中 即map cookies
Map<String, ?> prefsMap = cookiePrefs.getAll();
for (Map.Entry<String, ?> entry : prefsMap.entrySet()) {
String[] cookieNames = TextUtils.split((String) entry.getValue(), ",");
for (String name : cookieNames) {
String encodedCookie = cookiePrefs.getString(name, null);
if (encodedCookie != null) {
Cookie decodedCookie = decodeCookie(encodedCookie);
if (decodedCookie != null) {
if (!cookies.containsKey(entry.getKey())) {
cookies.put(entry.getKey(), new ConcurrentHashMap<String, Cookie>());
}
cookies.get(entry.getKey()).put(name, decodedCookie);
}
}
}
}
}
protected String getCookieToken(Cookie cookie) {
return cookie.name() + "@" + cookie.domain();
}
public void add(HttpUrl url, Cookie cookie) {
String name = getCookieToken(cookie);
//将cookies缓存到内存中 如果缓存过期 就重置此cookie
if (!cookie.persistent()) {
if (!cookies.containsKey(url.host())) {
cookies.put(url.host(), new ConcurrentHashMap<String, Cookie>());
}
cookies.get(url.host()).put(name, cookie);
} else {
if (cookies.containsKey(url.host())) {
if (cookies.get(url.host()) != null) {
cookies.get(url.host()).remove(name);
}
}
}
if (cookies.get(url.host()) != null) {
//讲cookies持久化到本地
SharedPreferences.Editor prefsWriter = cookiePrefs.edit();
prefsWriter.putString(url.host(), TextUtils.join(",", cookies.get(url.host()).keySet()));
prefsWriter.putString(name, encodeCookie(new SerializableOkHttpCookies(cookie)));
prefsWriter.apply();
}
}
public List<Cookie> get(HttpUrl url) {
ArrayList<Cookie> ret = new ArrayList<>();
if (cookies.containsKey(url.host())) {
ret.addAll(cookies.get(url.host()).values());
}
return ret;
}
public boolean removeAll() {
SharedPreferences.Editor prefsWriter = cookiePrefs.edit();
prefsWriter.clear();
prefsWriter.apply();
cookies.clear();
return true;
}
public boolean remove(HttpUrl url, Cookie cookie) {
String name = getCookieToken(cookie);
if (cookies.containsKey(url.host()) && cookies.get(url.host()).containsKey(name)) {
cookies.get(url.host()).remove(name);
SharedPreferences.Editor prefsWriter = cookiePrefs.edit();
if (cookiePrefs.contains(name)) {
prefsWriter.remove(name);
}
prefsWriter.putString(url.host(), TextUtils.join(",", cookies.get(url.host()).keySet()));
prefsWriter.apply();
return true;
} else {
return false;
}
}
public List<Cookie> getCookies() {
ArrayList<Cookie> ret = new ArrayList<>();
for (String key : cookies.keySet()) {
ret.addAll(cookies.get(key).values());
}
return ret;
}
/**
* cookies string
*
* @param cookie cookie
* @return string
*/
protected String encodeCookie(SerializableOkHttpCookies cookie) {
if (cookie == null) {
return null;
}
ByteArrayOutputStream os = new ByteArrayOutputStream();
try {
ObjectOutputStream outputStream = new ObjectOutputStream(os);
outputStream.writeObject(cookie);
} catch (IOException e) {
Log.d(LOG_TAG, "IOException in encodeCookie", e);
return null;
}
return byteArrayToHexString(os.toByteArray());
}
/**
* cookies
*
* @param cookieString cookies string
* @return cookie object
*/
protected Cookie decodeCookie(String cookieString) {
byte[] bytes = hexStringToByteArray(cookieString);
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
Cookie cookie = null;
try {
ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
cookie = ((SerializableOkHttpCookies) objectInputStream.readObject()).getCookies();
} catch (IOException e) {
Log.d(LOG_TAG, "IOException in decodeCookie", e);
} catch (ClassNotFoundException e) {
Log.d(LOG_TAG, "ClassNotFoundException in decodeCookie", e);
}
return cookie;
}
/**
*
*
* @param bytes byte array to be converted
* @return string containing hex values
*/
protected String byteArrayToHexString(byte[] bytes) {
StringBuilder sb = new StringBuilder(bytes.length * 2);
for (byte element : bytes) {
int v = element & 0xff;
if (v < 16) {
sb.append('0');
}
sb.append(Integer.toHexString(v));
}
return sb.toString().toUpperCase(Locale.US);
}
/**
*
*
* @param hexString string of hex-encoded values
* @return decoded byte array
*/
protected byte[] hexStringToByteArray(String hexString) {
int len = hexString.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4) + Character.digit(hexString.charAt(i + 1), 16));
}
return data;
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save