import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myView = (View)findViewById(R.id.myview);
score=(TextView)findViewById(R.id.score);
textView = new TextView[4][4];
int[][] textViewID = new int[][] {
{t11,R.id.t12,R.id.t13,R.id.t14},
{R.id.t21,R.id.t22,R.id.t23,R.id.t24},
{R.id.t31,R.id.t32,R.id.t33,R.id.t34},
{R.id.t41,R.id.t42,R.id.t43,R.id.t44}
};
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
textView[i][j]=(TextView)findViewById(textViewID[i][j]);
}
}
start();
//监听滑动
myView.setOnTouchListener(new View.OnTouchListener() {
private float startX, startY, offsetX, offsetY;
public boolean onTouch(View v, MotionEvent event) {
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
startX =event.getX();
startY =event.getY();
break;
case MotionEvent.ACTION_UP:
offsetX =event.getX()- startX;
offsetY =event.getY()- startY;
if(Math.abs(offsetX)>Math.abs(offsetY)){
if(offsetX <-5){
savePre();
moveLeft();
doMove();
}else if(offsetX >5){
savePre();
moveRight();
doMove();
}
}else{
if(offsetY <-5){
savePre();
moveUp();
doMove();
}else if(offsetX >5){
savePre();
moveDown();
doMove();
}
}
break;
}
return true;
}
});
/*
//监听长按
score.setLongClickable(true);
score.setOnLongClickListener(new View.OnLongClickListener(){
public boolean onLongClick(View v){
if(!checkPre()){
getPre();
doMove();
return true;
}else {
return false;
}
}
}
);
*/
}
static int game[][];
static int gamePre[][];
static TextView textView[][];
static TextView score;
static int moves;
static View myView;
//开始
public static void start(){
game=new int[4][4];
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
game[i][j]=0;
}
}
gamePre =new int[4][4];
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
gamePre[i][j]=0;
}
}
suiJiGe();
suiJiGe();
fill();
savePre();
moves=0;
score.setText("开始了,加油吧");
}
//随机数
public static int suiJiShu(){
return(Math.random()>0.1)?2:4;
}
//随机格子
public static void suiJiGe(){
int x= (int)(Math.random()*4);
int y= (int)(Math.random()*4);
if(game[x][y]!=0){
suiJiGe();
}else {
game[x][y]= suiJiShu();
}
fill();
}
//数组与textview同步
public static void fill(){
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
if(game[i][j]!=0){
textView[i][j].setText(""+game[i][j]);
}else {
textView[i][j].setText("");
}
textView[i][j].setBackgroundColor(setColor(game[i][j]));
}
}
}
//设置颜色
public static int setColor(int x){
int color=0;
switch (x) {
case 0:
color=0x8feee4da;
break;
case 2:
color=0xffeee4da;
break;
case 4:
color=0xffede0c8;
break;
case 8:
color=0xfff2b179;
break;
case 16:
color=0xfff59563;
break;
case 32:
color=0xfff67c5f;
break;
case 64:
color=0xfff65e3b;
break;
case 128:
color=0xffedcf72;
break;
case 256:
color=0xffedcc61;
break;
case 512:
color=0xffedc850;
break;
case 1024:
color=0xffedc53f;
break;
case 2048:
color=0xffedc22e;
break;
default:
}
return color;
}
//判断是否存在2048
public static boolean isWin(){
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
if(game[i][j]==2048){
return true;
}
}
}
return false;
}
//判断是否填满
//可以不需要了
public static boolean isFull(){
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
if(game[i][j]==0){
return false;
}
}
}
return true;
}
//判断是否挂掉
public static boolean isOver(){
boolean over=true;
ALL:
for (int i = 0; i <4; i++) {
for (int j = 0; j <4; j++) {
if((((game[j][i]==0|| j>0&&game[j][i]==game[j-1][i])||
j<3&&game[j][i]==game[j+1][i])||
i>0&&game[j][i]==game[j][i-1])||
i<3&&game[j][i]==game[j][i+1]){
over=false;
break ALL;
}
}
}
return over;
}
//执行结果动作
public static void check(){
if(isOver()){
score.setText("你努力了"+moves+"次,但还是输了!");
}
if(isWin()){
score.setText("恭喜你移动"+moves+"次成功了!");
}
}
//左移动作
public static void moveLeft(){
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
for (int k = j+1; k < 4; k++) {
if (game[i][k]>0) {
if (game[i][j]==0) {
game[i][j]=game[i][k];
game[i][k]=0;
j--;
}else if (game[i][j]==game[i][k]){
game[i][j]=game[i][j]*2;
game[i][k]=0;
}
break;
}
}
}
}
}
//右移动作
public static void moveRight(){
for (int i = 0; i < 4; i++) {
for (int j = 3; j >=0; j--) {
for (int k = j-1; k >=0; k--) {
if (game[i][k]>0) {
if (game[i][j]==0) {
game[i][j]=game[i][k];
game[i][k]=0;
j++;
}else if (game[i][j]==game[i][k]) {
game[i][j]=game[i][j]*2;
game[i][k]=0;
}
break;
}
}
}
}
}
//上移动作
public static void moveUp(){
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
for (int k = j+1; k <4; k++) {
if(game[k][i]>0){
if(game[j][i]==0){
game[j][i]=game[k][i];
game[k][i]=0;
j--;
}else if(game[j][i]==game[k][i]){
game[j][i]=game[j][i]*2;
game[k][i]=0;
}
break;
}
}
}
}
}
//下移动作
public static void moveDown(){
for (int i = 0; i < 4; i++) {
for (int j = 3; j >=0; j--) {
for (int k = j-1; k >=0; k--) {
if(game[k][i]>0){
if(game[j][i]==0){
game[j][i]=game[k][i];
game[k][i]=0;
j++;
}else if(game[j][i]==game[k][i]){
game[j][i]=game[j][i]*2;
game[k][i]=0;
}
break;
}
}
}
}
}
//执行移动动作
public static void doMove(){
if(!checkPre()){
fill();
moves++;
score.setText("你已移动"+moves+"次");
if(!isFull()){
suiJiGe();
}
}else getPre();
check();
}
//本次移动与上次结果比较
public static boolean checkPre(){
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
if(game[i][j]!= gamePre[i][j]){
return false;
}
}
}
return true;
}
//将本次结果存入上次
public static void savePre (){
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
gamePre[i][j]=game[i][j];
}
}
}
//调取上次结果
public static void getPre (){
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
game[i][j]= gamePre[i][j];
}
}
}
}
移动的算法一开始自己写了一大堆可以达到目的,但是太繁琐了,然后网上一搜,握草!太精炼了!于是可耻的抄下来了。
然后颜色的代码也是抄的,其他自己慢慢摸的。
学习使用参考线,用百分比来控制,可以某种程度缓解不同手机的适配问题吧。
这里不知道是软件的bug还是怎么的,竖向的参考线点击会变换参考方式,但是横向的不行,XML里改才行的。
然后有2个问题遗留:
1.向下滑动总是不太灵敏,非手机的问题,2个机子都一样,做其他操作向下没问题,就这个里有问题,查了没结果。
2.本来是加了长按那个分数就退回上一步的,但是退回后不实时刷新textview里的内容,实际是已经改了text值就是没实时显示出来的。