編輯:關於Android編程
8月9日,晴。“江城如畫裡,山曉望晴空。雨水夾明鏡,雙橋落彩虹。 人煙寒橘柚,秋色老梧桐。”
上篇已經讓飛機加載子彈和音效及背景音樂,本篇主要添加敵機。
本篇要用到的幾個函數講解:
1、voidsetTag (int nTag) 設置動作的標記。
2、CCRANDOM_0_1()函數生成的是 [0, 1] 之間的隨機數;要生成 [0-100] 之間的數CCRANDOM_0_1 * 100;生成 [1,5] 之間的float 數,就是 CCRANDOM_0_1 * 4 + 1。
3、sprite.getContentSize 得到精靈的矩形區域寬、高。獲得節點原始的大小,只是邏輯尺寸,不是像素。
float initX = (winSize.width - sprite.getContentSize().width) * ccMacros.CCRANDOM_0_1() + sprite.getContentSize().width/2;
表示敵機在X軸上的任意位置,sprite.getContentSize().width/2是為了防止出現半個敵機。
MainActivity.java
一、
package edu.eurasia.cocos2d_game04; import org.cocos2d.layers.CCScene; import org.cocos2d.nodes.CCDirector; import org.cocos2d.opengl.CCGLSurfaceView; import org.cocos2d.sound.SoundEngine; import android.os.Bundle; import android.app.Activity; import android.view.Window; import android.view.WindowManager; public class MainActivity extends Activity { // 創建一個view對象,cocos2d引擎會把圖形繪制在該view對象上面 private CCGLSurfaceView view = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 不顯示標題欄 requestWindowFeature(Window.FEATURE_NO_TITLE); // 設置當前程序全屏顯示 getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); // 設置不允許屏幕自動休眠 getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); view = new CCGLSurfaceView(this); setContentView(view); // 獲取導演對象 CCDirector director = CCDirector.sharedDirector(); // 設置游戲引擎畫面的輸出目標View director.attachInView(view); // 設置游戲是否顯示FPS值 // director.setDisplayFPS(true); // 設置游戲的刷新率 FPS = frame per second director.setAnimationInterval(1 / 60.0f); // 生成場景對象 CCScene scene = CCScene.node(); // 生成圖層對象 PlaneLayer layer = new PlaneLayer(this); // 將圖層添加至場景當中 scene.addChild(layer, 1); // 通知導演,運行場景 director.runWithScene(scene); } @Override protected void onDestroy() { super.onDestroy(); //清理所有的音效 SoundEngine.sharedEngine().realesAllSounds(); SoundEngine.sharedEngine().realesAllEffects(); // 完全關閉音響系統 SoundEngine.purgeSharedEngine(); } }二、PlaneLayer.java
package edu.eurasia.cocos2d_game04; import java.util.ArrayList; import java.util.List; import org.cocos2d.actions.instant.CCCallFuncN; import org.cocos2d.actions.interval.CCMoveTo; import org.cocos2d.actions.interval.CCSequence; import org.cocos2d.config.ccMacros; import org.cocos2d.layers.CCLayer; import org.cocos2d.nodes.CCDirector; import org.cocos2d.nodes.CCSprite; import org.cocos2d.sound.SoundEngine; import org.cocos2d.types.CGPoint; import org.cocos2d.types.CGRect; import org.cocos2d.types.CGSize; import android.content.Context; import android.view.MotionEvent; public class PlaneLayer extends CCLayer { // 聲明一個精靈對象 private CCSprite plane; private CCDirector director; private CGSize winSize; private CGPoint offset; private boolean flag = false; // 定義子彈的速度為每秒500像素 private float bulletSpeed = 500; private Context context; private Listbullets = new ArrayList (); private List enemies = new ArrayList (); private static final int E1_TAG = 1; private static final int E2_TAG = 2; public PlaneLayer(Context context) { super(); this.context = context; // 設置當前圖層是否接受觸摸事件 this.setIsTouchEnabled(true); director = CCDirector.sharedDirector(); winSize = director.winSize(); // 初始化精靈對象 plane = CCSprite.sprite("p.png"); // 設置精靈對象的位置 plane.setPosition(CGPoint.ccp(winSize.width / 2, 200)); this.addChild(plane); // 定時器schedule,添加子彈,每隔0.5秒調用一次 schedule("addBullet", 0.5f); //添加敵人,每隔一秒調用一次 schedule("addEnemy",1f); // 背景音樂 SoundEngine.sharedEngine().playSound(context, R.raw.game_music, true); } // 當用戶開始觸摸屏幕,執行該方法 @Override public boolean ccTouchesBegan(MotionEvent event) { CGPoint point = director.convertToGL(CGPoint.ccp(event.getX(), event.getY())); CGRect rect = plane.getBoundingBox(); flag = CGRect.containsPoint(rect, point); if (flag) { offset = CGPoint.ccpSub(plane.getPosition(), point); } return super.ccTouchesBegan(event); } // 當用戶手指離開屏幕時,執行該方法 @Override public boolean ccTouchesEnded(MotionEvent event) { flag = false; return super.ccTouchesEnded(event); } // 當用戶手指在屏幕移動時,執行該方法 @Override public boolean ccTouchesMoved(MotionEvent event) { if (flag) { CGPoint point = director.convertToGL(CGPoint.ccp(event.getX(), event.getY())); point = CGPoint.ccpAdd(point, offset); plane.setPosition(point); } return super.ccTouchesMoved(event); } public void addBullet(float delta) { // 生成一個子彈精靈對象 CCSprite bullet = CCSprite.sprite("bullet.png"); // 將子彈對象添加至圖層當中 this.addChild(bullet); // 將新添加的子彈對象放置在bullets集合當中 bullets.add(bullet); // 獲得精靈的大小,getContentSize函數來獲得節點原始的大小 CGSize planeSize = plane.getContentSize(); CGSize bulletSize = bullet.getContentSize(); CGPoint initPos = plane.getPosition(); // 子彈的y軸的初始位置 initPos.y = initPos.y + planeSize.height / 2 + bulletSize.height / 2; bullet.setPosition(initPos); // 創建一個代表坐標的對象 CGPoint targetPos = CGPoint.ccp(initPos.x, winSize.height); // 計算兩個坐標點之間的距離,計算子彈運行的距離 float distance = CGPoint.ccpDistance(initPos, targetPos); // 計算子彈運行的時間 float t = distance / bulletSpeed; // 生成一個動畫對象,讓子彈移動到屏幕的上端 CCMoveTo moveTo = CCMoveTo.action(t, targetPos); // 生成一個動作對象,該動作執行時,將會調用當前對象的onBulletMoveToFinished方法 // CCCallFuncN: // 它可以讓你為某個執行此action的對象指定一個回調函數。我們指定的回調函數是:onBulletMoveToFinished CCCallFuncN func = CCCallFuncN.action(this, "onBulletMoveToFinished"); // CCSequence: // 它允許我們把一系列的action組成一個action序列,並且這些action可以按順序執行。一次執行完所有的action。 CCSequence seq = CCSequence.actions(moveTo, func); // 通知精靈執行動作 bullet.runAction(seq); // 子彈聲效 SoundEngine.sharedEngine().playEffect(context, R.raw.bullet); } public void onBulletMoveToFinished(Object sender) { if (sender instanceof CCSprite) { CCSprite sprite = (CCSprite) sender; // 將子彈對象從集合中移除 bullets.remove(sprite); // 將子彈對象從屏幕中移除 this.removeChild(sprite, true); } } public void addEnemy(float delta){ String imgName = "e1a0.png"; int tag = E1_TAG; //生成的是 [0, 1] 之間的隨機數 float ran = ccMacros.CCRANDOM_0_1(); if(ran > 0.8){ imgName = "e2a0.png"; tag = E2_TAG; } //生成代表敵機的精靈對象 CCSprite sprite = CCSprite.sprite(imgName); // 設置動作的標記 sprite.setTag(tag); //將敵機添加到當前圖層中 this.addChild(sprite); // 將新添加的敵機對象放置在benemies集合當中 enemies.add(sprite); //計算敵機的初始化位置 float initY = winSize.height + sprite.getContentSize().height/2; float initX = (winSize.width - sprite.getContentSize().width) * ccMacros.CCRANDOM_0_1() + sprite.getContentSize().width/2; //創建一個代表坐標的對象 CGPoint initPos = CGPoint.ccp(initX, initY); //設置敵機的位置 sprite.setPosition(initPos); //計算敵機運行的終點位置 float targetX = initX; float targetY = -sprite.getContentSize().height/2; //創建一個代表坐標的對象 CGPoint targetPos = CGPoint.ccp(targetX, targetY); //計算敵機運行的時間 float t = 3 * ccMacros.CCRANDOM_0_1() + 2; //生成用於移動敵機的MoveTo對象 CCMoveTo moveTo = CCMoveTo.action(t, targetPos); CCCallFuncN func = CCCallFuncN.action(this, "onEnemyMoveToFinished"); CCSequence seq = CCSequence.actions(moveTo, func); // 通知精靈執行動作 sprite.runAction(seq); } public void onEnemyMoveToFinished(Object sender){ if(sender instanceof CCSprite){ CCSprite sprite = (CCSprite)sender; //將飛出屏幕的敵機從集合中移除 enemies.remove(sprite); // 將敵機對象從屏幕中移除 this.removeChild(sprite, true); } } }
三、
運行結果
源代碼下載地址:http://download.csdn.net/detail/zwszws/7734537
先看下效果圖: 上面是MTextView,下面是默認的TextView。 一、原因 用最簡單的全英文句子為例,如果有一個很長的單詞,這一行剩余的空間顯示不下了,
在開發中往往有要獲取聯系人列表的功能,但是這次卻不是獲取聯系人列表,而是在聯系人列表點擊單個聯系人,獲取單個聯系人的姓名和電話,並設置在指定的輸入框內,方便用戶的使用;以
如果說使用dex2jar和JD-GUI獲得了一個APP反編譯後的JAVA代碼,再結合smali代碼調試器來進行調試還不夠爽,不夠暢快的話,下面將介紹一個幫助分析代碼執行流
第二十章、適配器模式 適配器模式是結構型設計模式之一,它在我們的開發中使用率極高,比如ListView、GridView以及RecyclerView都需要使用Adapte