码迷,mamicode.com
首页 > 移动开发 > 详细

android 2048游戏项目详解

时间:2015-03-02 06:13:44      阅读:388      评论:0      收藏:0      [点我收藏+]

标签:android开发 2048游戏

壹.自定义卡片单元视图:

public class Cards extends FrameLayout{

private TextView labels;

private int num=0;


public Cards(Context context) {

super(context);

labels=new TextView(getContext());

labels.setTextSize(32);

labels.setGravity(Gravity.CENTER);

labels.setBackgroundColor(0x33ffffff);

LayoutParams lp=new LayoutParams(-1, -1);

lp.setMargins(10,10,0,0);

this.addView(labels,lp);

this.setNum(0);

}


public void setNum(int num){

this.num=num;

if(num<=0){

labels.setText("");

}

else{

labels.setText(num+"");

}

}


public int getNum(){

return this.num;

}

//判断两张卡片的值是否相等

public boolean equals(Cards c){

return this.getNum()==c.getNum();

}


}

贰.创建自定义网格布局:

public class MyGridView  extends GridLayout {


private Cards[][] cardsMap=new Cards[4][4];

private List<Point> emptyPoints = new ArrayList<Point>();

public MyGridView(Context context) {

super(context);

initViews();

}


public MyGridView(Context context, AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle);

initViews();

}


public MyGridView(Context context, AttributeSet attrs) {

super(context, attrs);

initViews();

}

        

        private void initViews(){

setColumnCount(4);

this.setBackgroundColor(0xffbbada0);

        }

        

        @Override

        //绘制布局的过程中添加卡片布局

protected void onSizeChanged(int w, int h, int oldw, int oldh) {

super.onSizeChanged(w, h, oldw, oldh);

int cardWidth=(Math.min(w, h)-10)/4;

addCards(cardWidth,cardWidth);

startGame();

}

/**

* 添加卡片视图

* @param cardWidth

* @param cardHeight

*/

private void addCards(int cardWidth,int cardHeight){

Cards c;

for(int y=0;y<4;y++){

for(int x=0;x<4;x++){

c=new Cards(getContext());

c.setNum(0);

addView(c,cardWidth,cardHeight);

cardsMap[x][y]=c;

}

}

}

叁.在主activity中加入自定义布局:

    <com.zyl2015.mynew2048.MyGridView 

        android:layout_width="fill_parent"

        android:layout_height="0dp"

        android:layout_weight="1"

        android:id="@+id/gameView" >

        

    </com.zyl2015.mynew2048.MyGridView>

四.实现滑动手势监听

    

        private void initGameView(){

setColumnCount(4);

setBackgroundColor(0xffbbada0);

//监听触摸事件处理逻辑

setOnTouchListener(new View.OnTouchListener() {

private float startX,startY,offsetX,offsetY;

@Override

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) {

swipeLeft();

}else if (offsetX>5) {

swipeRight();

}

}else{

if (offsetY<-5) {

swipeUp();

}else if (offsetY>5) {

swipeDown();

}

}

break;

}

return true;

}

});

}

五.实现随机出现2或4的卡片功能:

    

        /**

* 随机添加一个卡片,值为2或4

*/

private void addRandom(){

emptyPoints.clear();

for (int x=0;x<4;x++){

for(int y=0;y<4;y++){

if(cardsMap[x][y].getNum()<=0){

emptyPoints.add(new Point(x,y));

}

}

}

Point p=emptyPoints.remove((int)Math.random()*emptyPoints.size());

cardsMap[p.x][p.y].setNum(Math.random()>0.1?2:4);

Log.i("zyl", cardsMap[p.x][p.y].getNum()+"");

}

六.核心逻辑处理(只演示向左滑动):


private void swipeUp(){

boolean merge=false;

for(int x=0;x<4;x++){

for(int y=0;y<4;y++){

for(int y1=y+1;y1<4;y1++){

if(cardsMap[x][y1].getNum()>0){

if(cardsMap[x][y].getNum()<=0){

cardsMap[x][y].setNum(cardsMap[x][y1].getNum());

cardsMap[x][y1].setNum(0);

y--;

merge=true;

}

else if(cardsMap[x][y].equals(cardsMap[x][y1])){

cardsMap[x][y].setNum(cardsMap[x][y].getNum()*2);

cardsMap[x][y1].setNum(0);

MainActivity.getMainActivity().addScore(cardsMap[x][y].getNum());

merge=true;

}

break;

}

}

}

}

if(merge){

addRandom();

checkComplete();

}

}

七.实现计分功能(调动mainactivity里面的方法)

public void showScore(){

tvTotalScore.setText(tolScore+"");

}

public void addScore(int s){

tolScore+=s;

showScore();

}

public static MainActivity getMainActivity() {

return mainActivity;

}

}

八.判断是否游戏结束:


/**

* 相邻的可以消除并且还有空,游戏就没结束

*/

private void checkComplete(){

boolean complete =true;

ALL:

for(int y=0;y<4;y++){

for(int x=0;x<4;x++){

if(cardsMap[x][y].getNum()==0||(x>0&&cardsMap[x][y].equals(cardsMap[x-1][y]))||

(x<3&&cardsMap[x][y].equals(cardsMap[x+1][y]))||(y>0&&cardsMap[x][y].equals(cardsMap[x][y-1]))||

(y<3&&cardsMap[x][y].equals(cardsMap[x][y+1]))){

complete=false;

break ALL;

}

}

}

if(complete){

Builder builder= new AlertDialog.Builder(getContext()).setTitle("提示信息").setMessage("      你GameOver了!");

builder.setPositiveButton("重来", new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialog, int which) {

startGame();

}

});

builder.setNegativeButton("哭一场", new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface arg0, int arg1) {

Toast.makeText(getContext(), "哭", Toast.LENGTH_SHORT).show();

}

}); 

builder.show();

}

}

详细实现过程如下:

一.卡片类

public class Cards extends FrameLayout{

private TextView labels;

private int num=0;


public Cards(Context context) {

super(context);

labels=new TextView(getContext());

labels.setTextSize(32);

labels.setGravity(Gravity.CENTER);

labels.setBackgroundColor(0x33ffffff);

LayoutParams lp=new LayoutParams(-1, -1);

lp.setMargins(10,10,0,0);

this.addView(labels,lp);

this.setNum(0);

}


public void setNum(int num){

this.num=num;

if(num<=0){

labels.setText("");

}

else{

labels.setText(num+"");

}

}


public int getNum(){

return this.num;

}


public boolean equals(Cards c){

return this.getNum()==c.getNum();

}


}

二.自定义网格布局、核心逻辑处理类

public class MyGridView  extends GridLayout {


private Cards[][] cardsMap=new Cards[4][4];

private List<Point> emptyPoints = new ArrayList<Point>();

public MyGridView(Context context) {

super(context);

initViews();

}


public MyGridView(Context context, AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle);

initViews();

}


public MyGridView(Context context, AttributeSet attrs) {

super(context, attrs);

initViews();

}

/**

* 初始化卡片布局

*/

private void initViews(){

setColumnCount(4);

this.setBackgroundColor(0xffbbada0);

//监听触摸事件处理逻辑

this.setOnTouchListener(new View.OnTouchListener(){

private float startX,startY,offsetX,offsetY;

@Override

public boolean onTouch(View v, MotionEvent m) {

// 记录方向

switch(m.getAction()){

case MotionEvent.ACTION_DOWN:

startX=m.getX();

startY=m.getY();

break;

case MotionEvent.ACTION_UP:

offsetX=m.getX()-startX;

offsetY=m.getY()-startY;

if(Math.abs(offsetX)>Math.abs(offsetY)){

if(offsetX<-5){

swipeLeft();

Log.i("zyl","left");

}

else if(offsetX>5){

swipeRight();

Log.i("zyl","right");

}

}

else{

if(offsetY<-5){

swipeUp();

Log.i("zyl","up");

}

else if(offsetY>5){

swipeDown();

Log.i("zyl","down");

}

}

break;

}

return true;

}

});

}

@Override

protected void onSizeChanged(int w, int h, int oldw, int oldh) {

super.onSizeChanged(w, h, oldw, oldh);

int cardWidth=(Math.min(w, h)-10)/4;

addCards(cardWidth,cardWidth);

startGame();

}

/**

* 添加卡片视图

* @param cardWidth

* @param cardHeight

*/

private void addCards(int cardWidth,int cardHeight){

Cards c;

for(int y=0;y<4;y++){

for(int x=0;x<4;x++){

c=new Cards(getContext());

c.setNum(0);

addView(c,cardWidth,cardHeight);

cardsMap[x][y]=c;

}

}

}

private void swipeLeft(){

boolean merge=false;

for(int y=0;y<4;y++){

for(int x=0;x<4;x++){

for(int x1=x+1;x1<4;x1++){

if(cardsMap[x1][y].getNum()>0){

if(cardsMap[x][y].getNum()<=0){

cardsMap[x][y].setNum(cardsMap[x1][y].getNum());

cardsMap[x1][y].setNum(0);

x--;

merge=true;

}

else if(cardsMap[x][y].equals(cardsMap[x1][y])){

cardsMap[x][y].setNum(cardsMap[x][y].getNum()*2);

cardsMap[x1][y].setNum(0);

MainActivity.getMainActivity().addScore(cardsMap[x][y].getNum());

merge=true;

}

break;

}

}

}

}

if(merge){

addRandom();

checkComplete();

}

}

private void swipeRight(){

boolean merge=false;

for(int y=0;y<=3;y++){

for(int x=3;x>=0;x--){

for(int x1=x-1;x1>=0;x1--){

if(cardsMap[x1][y].getNum()>0){

if(cardsMap[x][y].getNum()<=0){

cardsMap[x][y].setNum(cardsMap[x1][y].getNum());

cardsMap[x1][y].setNum(0);

x++;

merge=true;

}

else if(cardsMap[x][y].equals(cardsMap[x1][y])){

cardsMap[x][y].setNum(cardsMap[x][y].getNum()*2);

cardsMap[x1][y].setNum(0);

MainActivity.getMainActivity().addScore(cardsMap[x][y].getNum());

merge=true;

}

break;

}

}

}

}

if(merge){

addRandom();

checkComplete();

}

}

private void swipeUp(){

boolean merge=false;

for(int x=0;x<4;x++){

for(int y=0;y<4;y++){

for(int y1=y+1;y1<4;y1++){

if(cardsMap[x][y1].getNum()>0){

if(cardsMap[x][y].getNum()<=0){

cardsMap[x][y].setNum(cardsMap[x][y1].getNum());

cardsMap[x][y1].setNum(0);

y--;

merge=true;

}

else if(cardsMap[x][y].equals(cardsMap[x][y1])){

cardsMap[x][y].setNum(cardsMap[x][y].getNum()*2);

cardsMap[x][y1].setNum(0);

MainActivity.getMainActivity().addScore(cardsMap[x][y].getNum());

merge=true;

}

break;

}

}

}

}

if(merge){

addRandom();

checkComplete();

}

}

private void swipeDown(){

boolean merge=false;

for(int x=0;x<4;x++){

for(int y=3;y>=0;y--){

for(int y1=y-1;y1>=0;y1--){

if(cardsMap[x][y1].getNum()>0){

if(cardsMap[x][y].getNum()<=0){

cardsMap[x][y].setNum(cardsMap[x][y1].getNum());

cardsMap[x][y1].setNum(0);

y++;

merge=true;

}

else if(cardsMap[x][y].equals(cardsMap[x][y1])){

cardsMap[x][y].setNum(cardsMap[x][y].getNum()*2);

cardsMap[x][y1].setNum(0);

MainActivity.getMainActivity().addScore(cardsMap[x][y].getNum());

merge=true;

}

break;

}

}

}

}

if(merge){

addRandom();

checkComplete();

}

}

/**

* 随机添加一个卡片,值为2或4

*/

private void addRandom(){

emptyPoints.clear();

for (int x=0;x<4;x++){

for(int y=0;y<4;y++){

if(cardsMap[x][y].getNum()<=0){

emptyPoints.add(new Point(x,y));

}

}

}

Point p=emptyPoints.remove((int)Math.random()*emptyPoints.size());

cardsMap[p.x][p.y].setNum(Math.random()>0.1?2:4);

Log.i("zyl", cardsMap[p.x][p.y].getNum()+"");

}

/**

* 开始游戏,清空所有条目

*/

private void startGame(){

MainActivity.getMainActivity().clearScore();

for(int x=0;x<4;x++){

for(int y=0;y<4;y++){

cardsMap[x][y].setNum(0);

}

}

addRandom();

addRandom();

}

/**

* 相邻的可以消除并且还有空,游戏就没结束

*/

private void checkComplete(){

boolean complete =true;

ALL:

for(int y=0;y<4;y++){

for(int x=0;x<4;x++){

if(cardsMap[x][y].getNum()==0||(x>0&&cardsMap[x][y].equals(cardsMap[x-1][y]))||

(x<3&&cardsMap[x][y].equals(cardsMap[x+1][y]))||(y>0&&cardsMap[x][y].equals(cardsMap[x][y-1]))||

(y<3&&cardsMap[x][y].equals(cardsMap[x][y+1]))){

complete=false;

break ALL;

}

}

}

if(complete){

Builder builder= new AlertDialog.Builder(getContext()).setTitle("提示信息").setMessage("      你GameOver了!");

builder.setPositiveButton("重来", new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialog, int which) {

startGame();

}

});

builder.setNegativeButton("哭一场", new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface arg0, int arg1) {

Toast.makeText(getContext(), "哭", Toast.LENGTH_SHORT).show();

}

}); 

builder.show();

}

}


}

三.主活动

public class MainActivity extends Activity {

private int score = 0;

private int tolScore=0;

private TextView tvTotalScore;

private static MainActivity mainActivity = null;

public MainActivity(){

mainActivity=this;

}

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

tvTotalScore=(TextView)this.findViewById(R.id.tvTotalScore);

}

public void clearScore(){

tolScore=0;

showScore();

}

public void showScore(){

tvTotalScore.setText(tolScore+"");

}

public void addScore(int s){

tolScore+=s;

showScore();

}

public static MainActivity getMainActivity() {

return mainActivity;

}

}


android 2048游戏项目详解

标签:android开发 2048游戏

原文地址:http://craftsman001.blog.51cto.com/9187002/1616337

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!