helloPe的android项目实战之连连看—实现篇(三)

  前面两篇“实现篇”已经将程序后台框架基本实现了,今天将涉及程序的activity类,在这个类中,为了有一个比较好的视觉效果,将介绍一些android中动画效果,依靠animation来实现,以及简单介绍android中自定义dialog的实现;首先看一下游戏界面运行时的效果图(程序中图片使用了网上的网友的,仅当学习之用):

                         helloPe的android项目实战之连连看—实现篇(三)                           helloPe的android项目实战之连连看—实现篇(三)

                                  游戏运行时界面                                              用于显示游戏结果的自定义dialog显示

先看看用于显示程序的activity类中的代码(这里主要是一些调用等,实现的逻辑在前面两篇文章中已经包含了)

package nate.llk;



//包得导入略去



public class GameActivity extends Activity implements OnToolsChangeListener,OnTimerListener,

						OnStateListener{

	private ImageButton img_startPlay;

	private ImageView img_title;

	private ProgressBar progress;

	

	private MyDialog dialog;

	//visibility at first is "gone"

	private ImageView clock;

	private GameView gameView = null;

	private ImageButton img_tip;

	private ImageButton img_refresh;

	private TextView text_refreshNum;

	private TextView text_tipNum;

	//两个帮助按键的特效

	private Animation anim = null;



	

	private Handler handler = new Handler(){

		@Override

		public void handleMessage(Message msg) {

			switch(msg.what){

			case 0:

				dialog = new MyDialog(GameActivity.this,gameView,"完成!",gameView.getTotalTime() - progress.getProgress() + 1);

				dialog.show();

				break;

			case 1:

				dialog = new MyDialog(GameActivity.this,gameView,"失败!",gameView.getTotalTime() - progress.getProgress() + 1);

				dialog.show();

			}

		}

	};

	

    /** Called when the activity is first created. */

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.game_view);

        anim =  AnimationUtils.loadAnimation(this, R.anim.shake);

        findView();

        startView();

        

        img_startPlay.setOnClickListener(new BtnClickListener());

       

        gameView.setOnTimerListener(this);

        gameView.setOnStateChangeListener(this);

        gameView.setOnToolsChangedListener(this);

        img_refresh.setOnClickListener(new BtnClickListener());

        img_tip.setOnClickListener(new BtnClickListener());

    }//end of the OnCreate method!

    /**

     * 寻找对应资源控件

     */

    public void findView(){

    	clock = (ImageView)this.findViewById(R.id.clock);

    	progress = (ProgressBar)this.findViewById(R.id.timer);

    	img_title = (ImageView)this.findViewById(R.id.title_img);

    	img_startPlay = (ImageButton)this.findViewById(R.id.play_btn);

    	img_tip = (ImageButton)this.findViewById(R.id.tip_btn);

    	img_refresh = (ImageButton)this.findViewById(R.id.refresh_btn);

    	gameView = (GameView)this.findViewById(R.id.game_view);

    	text_refreshNum = (TextView)this.findViewById(R.id.text_refresh_num);

    	text_tipNum = (TextView)this.findViewById(R.id.text_tip_num);

    }

    /**

     * 程序开启界面显示

     */

    public void startView(){

    	Animation scale = AnimationUtils.loadAnimation(this,R.anim.scale_anim);

    	img_title.startAnimation(scale);

    	img_startPlay.startAnimation(scale);

    }

    /**

     * 游戏运行时界面显示,即连连看的布局

     */

    public void playingView(){

    	Animation scaleOut = AnimationUtils.loadAnimation(this, R.anim.scale_anim_out);

    	img_title.startAnimation(scaleOut);

    	img_startPlay.startAnimation(scaleOut);

    	img_title.setVisibility(View.GONE);

    	img_startPlay.setVisibility(View.GONE);

    	

    	clock.setVisibility(View.VISIBLE);

    	progress.setMax(gameView.getTotalTime());

    	progress.setProgress(gameView.getTotalTime());

    	progress.setVisibility(View.VISIBLE);

    	gameView.setVisibility(View.VISIBLE);

    	img_tip.setVisibility(View.VISIBLE);

    	img_refresh.setVisibility(View.VISIBLE);

    	text_tipNum.setVisibility(View.VISIBLE);

    	text_refreshNum.setVisibility(View.VISIBLE);

    	Animation animIn = AnimationUtils.loadAnimation(this, R.anim.trans_in);

    	gameView.startAnimation(animIn);

    	img_tip.startAnimation(animIn);

    	img_refresh.startAnimation(animIn);

    	text_tipNum.startAnimation(animIn);

    	text_refreshNum.startAnimation(animIn);

    	//player.pause();

		gameView.startPlay();

		toast();

    }

    /**

     * 一个处理开始游戏,刷新,帮助三个按钮的listener的类

     * @author HelloPe || NatePan

     *

     */

    class BtnClickListener implements OnClickListener{

		@Override

		public void onClick(View v) {

			switch(v.getId()){

			case R.id.play_btn:

				playingView();

				break;

			case R.id.refresh_btn:

				img_refresh.startAnimation(anim);

				gameView.refreshChange();

				gameView.invalidate();

				break;

			case R.id.tip_btn:

				img_tip.startAnimation(anim);

				gameView.autoHelp();

				break;

			}

		}

    }

	@Override

	public void onRefreshChanged(int count) {

		text_refreshNum.setText(""+gameView.getRefreshNum());

	}

	@Override

	public void onTipChanged(int count) {

		text_tipNum.setText("" + gameView.getTipNum());

	}

	@Override

	public void onTimer(int leftTime) {

		progress.setProgress(leftTime);

		

	}

	

	/**

	 *用来控制音乐的播放 

	 */

	@Override

	public void OnStateChanged(int StateMode) {

		switch(StateMode){

		case GameView.WIN:

			handler.sendEmptyMessage(0);

			break;

		case GameView.LOSE:

			handler.sendEmptyMessage(1);

			break;

		case GameView.PAUSE:

			//player.stop();

	    	//gameView.player.stop();

	    	gameView.stopTimer();

			break;

		case GameView.QUIT:

			//player.release();

	    	//gameView.player.release();

	    	gameView.stopTimer();

	    	break;

		}

	}

	public void quit(){

		this.finish();

	}

	/**

	 * 用于提醒游戏开始,提醒总时间

	 */

	public void toast(){

		Toast.makeText(this, "游戏已经开始!总时间: " + gameView.getTotalTime() + "s", Toast.LENGTH_LONG).show();

	}

	 	@Override

	    protected void onPause() {

	    	super.onPause();

	    	gameView.setMode(GameView.PAUSE);

	    }   

	    @Override

		protected void onDestroy() {

	    	super.onDestroy();

	    	gameView.setMode(GameView.QUIT);

		}

		@Override

		public boolean onCreateOptionsMenu(Menu menu) {

			menu.add(Menu.NONE, 1, Menu.NONE,"Replay").setIcon(R.drawable.buttons_replay);

			menu.add(Menu.NONE, 2, Menu.NONE, "Pause").setIcon(R.drawable.pause);

			menu.add(Menu.NONE, 3, Menu.NONE,"SoundOn").setIcon(R.drawable.volume);

			return super.onCreateOptionsMenu(menu);

		}

		@Override

		public boolean onOptionsItemSelected(MenuItem item) {

			switch(item.getItemId()){

			case 1:

				gameView.setTotalTime(100);

				progress.setMax(100);

				gameView.startPlay();

				break;

			case 2:

				gameView.stopTimer();

				if(item.getTitle().equals("Pause")){

					item.setTitle("Continue");

					item.setIcon(R.drawable.play);

				}else if(item.getTitle().equals("Continue")){

					item.setTitle("Pause");

					item.setIcon(R.drawable.pause);

				}

				AlertDialog.Builder dialog = new AlertDialog.Builder(this);

				dialog.setIcon(R.drawable.icon);

				dialog.setTitle("继续");

				dialog.setMessage("继续游戏?");

				dialog.setPositiveButton("继续", new DialogInterface.OnClickListener() {

					

					@Override

					public void onClick(DialogInterface dialog, int which) {

						gameView.setContinue();

					}

				}).setNeutralButton("重玩", new DialogInterface.OnClickListener() {

					

					@Override

					public void onClick(DialogInterface dialog, int which) {

						gameView.startPlay();

					}

				}).setNegativeButton("退出", new DialogInterface.OnClickListener() {

					

					@Override

					public void onClick(DialogInterface dialog, int which) {

						Intent startMain = new Intent(Intent.ACTION_MAIN);  

	                    startMain.addCategory(Intent.CATEGORY_HOME);   

	                    startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);   

	                    startActivity(startMain);  

	                    System.exit(0); 

					}

				});

				dialog.show();

				break;

			case 3:

				///////////////////////////

				if(item.getTitle().equals("Mute")){

					item.setTitle("SoundOn");

					item.setIcon(R.drawable.volume);

				}else if(item.getTitle().equals("SoundOn")){

					item.setTitle("Mute");

					item.setIcon(R.drawable.mute);

				}

				break;

			}

			return super.onOptionsItemSelected(item);

		}

		/**

		 * 监听后退按钮,以防止误按,按下back按钮后,程序应当处于暂停状态

		 */

		@Override

		public boolean onKeyDown(int keyCode, KeyEvent event) {

			if(keyCode == KeyEvent.KEYCODE_BACK){

				AlertDialog.Builder dialog= new AlertDialog.Builder(GameActivity.this).setTitle("退出游戏")

				.setMessage("确定退出游戏?")

				.setPositiveButton("是",new DialogInterface.OnClickListener(){



					@Override

					public void onClick(DialogInterface dialog, int which) {

						Intent startMain = new Intent(Intent.ACTION_MAIN);  

	                    startMain.addCategory(Intent.CATEGORY_HOME);   

	                    startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);   

	                    startActivity(startMain);  

	                    System.exit(0); 

					}

				}).setNegativeButton("否", new DialogInterface.OnClickListener(){



					@Override

					public void onClick(DialogInterface dialog, int which) {

						Toast.makeText(GameActivity.this, "重新开始了游戏", Toast.LENGTH_LONG).show();

						gameView.startPlay();

					}

					

				});

				dialog.setIcon(R.drawable.icon);

				dialog.show();

			}

			return super.onKeyDown(keyCode, event);

		}

	    

}

在此类中,如上次我们所说的,我们实现了之前定义的三个接口,引用了GameView类(在activity的布局文件中使用到),在activity布局文件中如下使用:

  <nate.llk.view.GameView

    	android:layout_width="wrap_content" 

    	android:layout_height="wrap_content" 

    	android:id="@+id/game_view"

    	android:visibility="gone"

    	android:layout_below="@id/timer"

    />

同样对于我们自定义的dialog,跟自定义的GameView(继承自View)是一样的。MyDialog类继承自Dialog类,实现了OnClickListener的OnClick方法,使用一个布局文件,将自定义的dialog布局。布局文件很简单,MyDialog类如下:

package nate.llk;

//导入包略去
public class MyDialog extends Dialog implements OnClickListener{



	private GameView gameview;

	private Context context;

	

	public MyDialog(Context context, GameView gameview, String msg, int time) {

		super(context,R.style.dialog);

		this.gameview = gameview;

		this.context = context;

		this.setContentView(R.layout.dialog_view);

		TextView text_msg = (TextView) findViewById(R.id.text_message);

		TextView text_time = (TextView) findViewById(R.id.text_time);

		ImageButton btn_menu = (ImageButton) findViewById(R.id.menu_imgbtn);

		ImageButton btn_next = (ImageButton) findViewById(R.id.next_imgbtn);

		ImageButton btn_replay = (ImageButton) findViewById(R.id.replay_imgbtn);

		

		text_msg.setText(msg);

		text_time.setText(text_time.getText().toString().replace("$", String.valueOf(time)));

		btn_menu.setOnClickListener(this);

		btn_next.setOnClickListener(this);

		btn_replay.setOnClickListener(this);

		this.setCancelable(false);

	}



	@Override

	public void onClick(View v) {

		this.dismiss();

		switch(v.getId()){

		case R.id.menu_imgbtn:

			Dialog dialog = new AlertDialog.Builder(context)

            .setIcon(R.drawable.buttons_bg20)

            .setTitle(R.string.quit)

            .setMessage(R.string.sure_quit)

            .setPositiveButton(R.string.alert_dialog_ok, new DialogInterface.OnClickListener() {

                public void onClick(DialogInterface dialog, int whichButton) {

                	((GameActivity)context).quit();

                }

            })

            .setNegativeButton(R.string.alert_dialog_cancel, new DialogInterface.OnClickListener() {

                public void onClick(DialogInterface dialog, int whichButton) {

                	gameview.startPlay();

                }

            })

            .create();

			dialog.show();

			break;

		case R.id.replay_imgbtn:

			gameview.startPlay();

			break;

		case R.id.next_imgbtn:

			gameview.startNextPlay();

			break;

		}

	}



	@Override

	public boolean onKeyDown(int keyCode, KeyEvent event) {

		if(keyCode == KeyEvent.KEYCODE_BACK){

			this.dismiss();

		}

		return super.onKeyDown(keyCode, event);

	}

	

}

上面代码简单,不过还是实现了较好的效果。

在android中使用animation的动画包含四种,Tween animation的使用也能够使程序看起来效果好点:

在anim文件下:

实现当点击程序中两个工具按钮时,工具按钮出现抖动的效果:

<?xml version="1.0" encoding="utf-8"?>

<translate xmlns:android="http://schemas.android.com/apk/res/android" 

			android:fromXDelta="0" 

			android:toXDelta="10" 

			android:duration="1000" 

			android:interpolator="@anim/cycle" />

<?xml version="1.0" encoding="utf-8"?>

<cycleInterpolator xmlns:android="http://schemas.android.com/apk/res/android" 

				   android:cycles="7"

				   /><!--用于控制上面颤动的次数-->

用于控制欢迎界面的图标逐渐变大的出场效果:

<?xml version="1.0" encoding="utf-8"?>

<set xmlns:android="http://schemas.android.com/apk/res/android">

	<scale

          android:interpolator="@android:anim/accelerate_decelerate_interpolator"

          android:fromXScale="0.0"

          android:toXScale="1.0"

          android:fromYScale="0.0"

          android:toYScale="1.0"

          android:pivotX="50%"

          android:pivotY="50%"

          android:fillAfter="true"

          android:duration="1600" />

</set>

当然放大效果只是改一下android:fromXScale="1.0"     与    android:toXScale="0.0"即可;

至于透明效果,用于将GameView中的内容从透明慢慢展示出来:

<?xml version="1.0" encoding="utf-8"?>

<set xmlns:android="http://schemas.android.com/apk/res/android">

	<alpha android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="1000" />

</set>

而在activity中对于以上资源的使用上面activity类中已经给出,先载入,然后调用imageView或者其他View的startAnimation方法即可;

对于游戏中音效的播放方法比较简单,主要是在不同的状态播放不同的声音比较繁琐,android中有两种播放音效的方法:一种是SoundPool,一种是MediaPlayer。SoundPool适合短促音乐,但是反应速度要求比较高的情况;MediaPlayer则是是相反。使用步骤如:

// 初始化soundPool 对象,第一个参数是允许有多少个声音流同时播放,第2个参数是声音类型,第三个参数是声音的品质

		soundPool = new SoundPool(25, AudioManager.STREAM_MUSIC, 100);//SoudPool的引用

soundPool.load(context, raw, 1);//调用load函数载入音乐资源

//之后调用play函数即可播放参数中相应的音乐资源

本程序算是完成了,向网友们学习了不少,毕竟是很多人都做过的小项目。记录下来,希望高手路过别喷~

                                                                                                                                                                                               while(success != try());

你可能感兴趣的:(android)