Giới thiệu
Bài viết trước hiện thực StateGamePlay, bài viết này tiếp tục hiện thực StateEndGame.
StateEndgame
StateEndGame.h
#ifndef __STATE_ENDGAME__H__ #define __STATE_ENDGAME__H__ #include "cocos2d.h" USING_NS_CC; class StateEndGame : public cocos2d::Layer { public: // there's no 'id' in cpp, so we recommend returning the class instance pointer static cocos2d::Scene* createScene(); // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone virtual bool init(); // implement the "static create()" method manually CREATE_FUNC(StateEndGame); void update(float dt); void gotoMainMenu(); // thoat ra mainmenu void rateGame(); // danh gia game void shareFaceBook(); // share facebook void playAgain(); // choi lai void UpdateAdsBanner(); void showInterstitial(); void afterCaptured(bool succeed, const std::string& outputFile); // ham chup screeshot void onSharePhoto(cocos2d::Ref* sender); // share screen shot len facebook void onDialogLink(cocos2d::Ref* sender); // share link len facebook private: int countToShowBanner; std::string LinkFileScreenShot; }; #endif // __STATE_ENDGAME__H__
StateEndGame.cpp
State này để thông báo và tính toán điểm vừa chơi có phải là điểm cao nhất không? Nếu cao nhất thì cập nhật.
#include "StateEndGame.h" #include "StateMainMenu.h" #include "StateGamePlay.h" #include "config.h" #include "NativeAndroidHelper.h" #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) #include "PluginFacebook/PluginFacebook.h" #include "PluginChartboost/PluginChartboost.h" using namespace sdkbox; #endif USING_NS_CC; Scene* StateEndGame::createScene() { // 'scene' is an autorelease object auto scene = Scene::create(); // 'layer' is an autorelease object auto layer = StateEndGame::create(); // add layer as a child to scene scene->addChild(layer); // return the scene return scene; } // on "init" you need to initialize your instance bool StateEndGame::init() { ////////////////////////////// // 1. super init first if ( !Layer::init() ) { return false; } #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) // khoi tao quang cao chartboost chi danh cho android sdkbox::PluginChartboost::init(); sdkbox::PluginChartboost::cache(sdkbox::CB_Location_Default); sdkbox::PluginChartboost::cache(sdkbox::CB_Location_LevelComplete); #endif countToShowBanner = 0; auto userdefault = UserDefault::sharedUserDefault(); int highScore = userdefault->getIntegerForKey(HIGH_SCORE); int score = userdefault->getIntegerForKey(POINT_CURRENT); if (score > highScore) // cap nhat gia tri diem cao nhat neu co diem lon hon diem cao nhat { highScore = score; userdefault->setIntegerForKey(HIGH_SCORE, score); userdefault->flush(); } auto spriteBG = Sprite::createWithSpriteFrameName(NameBG_GP); spriteBG->setPosition(posMidleScreen); this->addChild(spriteBG, zBG); auto textEnd = Label::createWithTTF(Pumpkins_font90, "Game Over!"); textEnd->setPosition(posTitleEG); textEnd->setTextColor(yellowColor4B); this->addChild(textEnd, zUi); auto bgHighScore = Sprite::createWithSpriteFrameName(NameBGHighScore); bgHighScore->setPosition(posScoreEndGame); bgHighScore->setOpacity(200); this->addChild(bgHighScore, zUi); auto textScore = Label::createWithTTF(Pumpkins_font60, "SCORE"); textScore->setPosition(bgHighScore->getPosition().x, bgHighScore->getPosition().y + bgHighScore->getContentSize().height / 2 - 50); textScore->setTextColor(pinkColor4B); this->addChild(textScore, zUi); auto str = CCString::createWithFormat("%i", score); // tao text mang gia tri diem de ve ra man hinh auto Currentscore = Label::createWithTTF(Pumpkins_font60, str->getCString()); Currentscore->setPosition(bgHighScore->getPosition().x, textScore->getPosition().y - 60); Currentscore->setTextColor(whiteColor4B); this->addChild(Currentscore, zUi); auto textBScore = Label::createWithTTF(Pumpkins_font60, "BEST SCORE"); textBScore->setPosition(bgHighScore->getPosition().x, Currentscore->getPosition().y - 90); textBScore->setTextColor(pinkColor4B); this->addChild(textBScore, zUi); auto strB = CCString::createWithFormat("%i", highScore); // tao text mang gia tri diem cao nhat ve ra man hinh auto Bscore = Label::createWithTTF(Pumpkins_font60, strB->getCString()); Bscore->setPosition(bgHighScore->getPosition().x, textBScore->getPosition().y - 60); Bscore->setTextColor(whiteColor4B); this->addChild(Bscore, zUi); auto home_btn = Sprite::createWithSpriteFrameName(NamebtBG); home_btn->setPosition(posbtHomeEG); home_btn->setOpacity(150); this->addChild(home_btn, zUi); auto home = MenuItemImage::create(); // tao button home de quay ve mainmenu home->setNormalImage(Sprite::createWithSpriteFrameName(NamebtHome)); home->setSelectedImage(Sprite::createWithSpriteFrameName(NamebtHome)); home->setPosition(posbtHomeEG); home->setCallback(CC_CALLBACK_0(StateEndGame::gotoMainMenu, this)); auto rate_btn = Sprite::createWithSpriteFrameName(NamebtBG); rate_btn->setPosition(posbtRateEG); rate_btn->setOpacity(150); this->addChild(rate_btn, zUi); auto rate = MenuItemImage::create(); // tao button rate de danh gia game rate->setNormalImage(Sprite::createWithSpriteFrameName(NamebtRate)); rate->setSelectedImage(Sprite::createWithSpriteFrameName(NamebtRate)); rate->setPosition(posbtRateEG); rate->setCallback(CC_CALLBACK_0(StateEndGame::rateGame, this)); auto face_btn = Sprite::createWithSpriteFrameName(NamebtBG); face_btn->setPosition(posbtFaceEG); face_btn->setOpacity(150); this->addChild(face_btn, zUi); auto face = MenuItemImage::create(); // tao button face de share diem len face face->setNormalImage(Sprite::createWithSpriteFrameName(NamebtFace)); face->setSelectedImage(Sprite::createWithSpriteFrameName(NamebtFace)); face->setPosition(posbtFaceEG); face->setCallback(CC_CALLBACK_0(StateEndGame::shareFaceBook, this)); auto again_btn = Sprite::createWithSpriteFrameName(NamebtBG); again_btn->setPosition(posbtAgainEG); again_btn->setOpacity(150); this->addChild(again_btn, zUi); auto again = MenuItemImage::create(); // tao button choi lai de choi lai game again->setNormalImage(Sprite::createWithSpriteFrameName(NamebtAgain)); again->setSelectedImage(Sprite::createWithSpriteFrameName(NamebtAgain)); again->setPosition(posbtAgainEG); again->setCallback(CC_CALLBACK_0(StateEndGame::playAgain, this)); auto menu = Menu::create(home, rate, face, again, NULL); menu->setPosition(Point::ZERO); this->addChild(menu, zUi); this->scheduleUpdate(); // goi ham update(dt) auto showInters = CCCallFuncN::create(CC_CALLBACK_0(StateEndGame::showInterstitial, this)); // goi quang cao hinh lon this->runAction(Sequence::create(DelayTime::create(1.0f), showInters, NULL)); return true; } void StateEndGame::update(float dt) { UpdateAdsBanner(); } void StateEndGame::UpdateAdsBanner() // ham hien thi banner 40s sau do se an di 5s { #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) countToShowBanner++; if (NativeAndroidHelper::AdShowing() && countToShowBanner == 1600) { NativeAndroidHelper::hideAd(); countToShowBanner = 0; } else if (!NativeAndroidHelper::AdShowing() && countToShowBanner == 200) { NativeAndroidHelper::showAd(); countToShowBanner = 0; } #endif } void StateEndGame::showInterstitial() // hien quang cao { #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) int rand = random(1, 15); const std::string temp; if (rand == 10) { sdkbox::PluginChartboost::show(sdkbox::CB_Location_LevelComplete); } else if(rand > 10) { sdkbox::PluginChartboost::show(sdkbox::CB_Location_Default); } #endif } void StateEndGame::gotoMainMenu() // quay ve MainMenu khi nhan button Home { Director::getInstance()->replaceScene(StateMainMenu::createScene()); } void StateEndGame::rateGame() // danh gia game khi nhan button rate game { std::string link = std::string("https://play.google.com/store/apps/details?id=com.gamenvl.pumpkins"); Application::getInstance()->openURL(link); } void StateEndGame::playAgain() // choi lai game khi nha button choi lai { Director::getInstance()->replaceScene(StateGamePlay::createScene()); } void StateEndGame::afterCaptured(bool succeed, const std::string& outputFile) // ham nay se tu goi trong ham shareFaceBook() { #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) sdkbox::PluginFacebook::login(); LinkFileScreenShot = outputFile; auto SharePhoto = CCCallFuncN::create(CC_CALLBACK_1(StateEndGame::onSharePhoto, this)); // share screenshot diem game len face auto ShareDialogLink = CCCallFuncN::create(CC_CALLBACK_1(StateEndGame::onDialogLink, this)); // share link down game len face this->runAction(Sequence::create(ShareDialogLink, DelayTime::create(3.0f), SharePhoto, NULL)); #endif } void StateEndGame::shareFaceBook() // share face khi nhan nut face { utils::captureScreen(CC_CALLBACK_2(StateEndGame::afterCaptured, this), "Pumpkins.png"); } void StateEndGame::onSharePhoto(cocos2d::Ref* sender) // share screenshot diem game len face { /* #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) sdkbox::PluginFacebook::requestReadPermissions({ FB_PERM_READ_PUBLIC_PROFILE, FB_PERM_READ_USER_FRIENDS }); sdkbox::PluginFacebook::requestPublishPermissions({ FB_PERM_PUBLISH_POST }); sdkbox::FBShareInfo info; info.type = sdkbox::FB_PHOTO; info.title = "My best score"; info.image = LinkFileScreenShot; sdkbox::PluginFacebook::share(info); #endif */ } void StateEndGame::onDialogLink(cocos2d::Ref* sender) // share link down game len face { auto userdefault = UserDefault::sharedUserDefault(); int highScore = userdefault->getIntegerForKey(HIGH_SCORE); #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) sdkbox::PluginFacebook::requestReadPermissions({ FB_PERM_READ_PUBLIC_PROFILE, FB_PERM_READ_USER_FRIENDS }); sdkbox::PluginFacebook::requestPublishPermissions({ FB_PERM_PUBLISH_POST }); FBShareInfo info; info.type = FB_LINK; info.link = "https://play.google.com/store/apps/details?id=com.gamenvl.pumpkins"; info.title = "Funny Halloween Pumpkins"; auto tempText = CCString::createWithFormat("My best score is %i. Let try it to get best score with me!", highScore); info.text = tempText->getCString(); info.image = "http://i.imgur.com/vBwYKHH.png"; PluginFacebook::dialog(info); #endif }
Tích hợp Ads Admob
Muốn gắn quảng cáo Admob vào game thì trước tiên phải có tài khoản Admob và tạo id cho quảng cáo.
Tìm hiểu thêm tại trang chủ của Admod.
Khi tạo xong id quảng cáo, mở file "Pumpkins\proj.android\AndroidManifest.xml" và thêm vào các quyền như sau:
<!-- Activity required to show admod ad overlays. --> <activity android:name="com.google.android.gms.ads.AdActivity" android:theme="@android:style/Theme.Translucent" android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"/> </application>
<supports-screens android:anyDensity="true" android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:xlargeScreens="true"/> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> </manifest>
Mở file "Pumpkins\proj.android\project.properties" và thêm đường dẫn đến thư viện như sau:
target=android-15 android.library.reference.1=../cocos2d/cocos/platform/android/java android.library.reference.2=../cocos2d/cocos/platform/android/java/libs/facebook_lib/ android.library.reference.3=libs/google-play-services_lib
Thư viện của google play services đã đính kèm trong bài viết trước, copy vào project.
Tiếp tục vào lớp Activity của game để thêm hàm hiển thị ads, lưu ý file này nên lấy giống phần hướng dẫn, chỉ cần đổi id quảng cáo.
Pumpkins\proj.android\src\org\cocos2dx\cpp\AppActivity.java
package org.cocos2dx.cpp; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import org.cocos2dx.lib.Cocos2dxActivity; import android.graphics.Color; import android.graphics.Point; import android.os.Bundle; import android.view.Display; import android.view.View; import android.view.WindowManager; import android.widget.LinearLayout; import com.google.android.gms.ads.*; import android.content.Intent; import android.net.Uri; public class AppActivity extends Cocos2dxActivity { private static AppActivity _appActiviy; private AdView adView; private InterstitialAd interstitial; private static final String AD_UNIT_ID = "ca-app-pub-5088964067816727/5954762096"; // doi id quang cao banner private static final String AD_INTERTITIAL_UNIT_ID = "ca-app-pub-5088964067816727/7431495296"; // doi id quang cao hinh lon private Point getDisplaySize(Display d) { // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { // return getDisplaySizeGE11(d); // } return getDisplaySizeLT11(d); } private Point getDisplaySizeLT11(Display d) { try { Method getWidth = Display.class.getMethod("getWidth", new Class[] {}); Method getHeight = Display.class.getMethod("getHeight", new Class[] {}); return new Point( ((Integer) getWidth.invoke(d, (Object[]) null)).intValue(), ((Integer) getHeight.invoke(d, (Object[]) null)).intValue()); } catch (NoSuchMethodException e2) // None of these exceptions should // ever occur. { return new Point(-1, -1); } catch (IllegalArgumentException e2) { return new Point(-2, -2); } catch (IllegalAccessException e2) { return new Point(-3, -3); } catch (InvocationTargetException e2) { return new Point(-4, -4); } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); int width = getDisplaySize(getWindowManager().getDefaultDisplay()).x; LinearLayout.LayoutParams adParams = new LinearLayout.LayoutParams( width, LinearLayout.LayoutParams.WRAP_CONTENT); adView = new AdView(this); adView.setAdSize(AdSize.BANNER); adView.setAdUnitId(AD_UNIT_ID); AdRequest adRequest = new AdRequest.Builder().build(); // .addTestDevice(AdRequest.DEVICE_ID_EMULATOR) // .addTestDevice("HASH_DEVICE_ID").build(); adView.loadAd(adRequest); adView.setBackgroundColor(Color.BLACK); adView.setBackgroundColor(0); addContentView(adView, adParams); interstitial = new InterstitialAd(this); interstitial.setAdUnitId(AD_INTERTITIAL_UNIT_ID); // Begin loading your interstitial. interstitial.loadAd(adRequest); _appActiviy = this; } public static void hideAd() { _appActiviy.runOnUiThread(new Runnable() { @Override public void run() { if (_appActiviy.adView.isEnabled()) _appActiviy.adView.setEnabled(false); if (_appActiviy.adView.getVisibility() != 4) _appActiviy.adView.setVisibility(View.INVISIBLE); } }); } public static void showAd() { _appActiviy.runOnUiThread(new Runnable() { @Override public void run() { if (!_appActiviy.adView.isEnabled()) _appActiviy.adView.setEnabled(true); if (_appActiviy.adView.getVisibility() == 4) _appActiviy.adView.setVisibility(View.VISIBLE); } }); } public static void showInterstitial() { _appActiviy.runOnUiThread(new Runnable() { @Override public void run() { _appActiviy.interstitial.show(); } }); } public static void loadInterstitalAgain() { _appActiviy.runOnUiThread(new Runnable() { @Override public void run() { AdRequest adRequest = new AdRequest.Builder() .addTestDevice(AdRequest.DEVICE_ID_EMULATOR) .addTestDevice("HASH_DEVICE_ID").build(); _appActiviy.interstitial.loadAd(adRequest); } }); } // Open URL public static void openURL(String url) { Intent i = new Intent(Intent.ACTION_VIEW); i.setData(Uri.parse(url)); _appActiviy.startActivity(i); } @Override protected void onResume() { super.onResume(); if (adView != null) { adView.resume(); } } @Override protected void onPause() { if (adView != null) { adView.pause(); } // uiHelper.onPause(); super.onPause(); } @Override protected void onDestroy() { adView.destroy(); super.onDestroy(); } }
Nếu muốn hiện quảng cáo, tại file .cpp phải gọi các hàm trong lớp Activity trên. Để làm được điều đó thì nhờ đến lớp NativeAndroidHelper
để gọi hàm trong code Java, đã đính kèm trong tài liệu nên có thể sử dụng file này mà không cần phải thêm code. Thêm file NativeAndroidHelper
cũng giống như thêm các file StateMainMenu, StateGamePlay, StateEndGame ở phần trước.
Tiến hành gọi banner và interstital:
void StateEndGame::UpdateAdsBanner() { #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) countToShowBanner++; if (NativeAndroidHelper::AdShowing() && countToShowBanner == 1600) { NativeAndroidHelper::hideAd(); // hàm an banner countToShowBanner = 0; } else if (!NativeAndroidHelper::AdShowing() && countToShowBanner == 200) { NativeAndroidHelper::showAd(); // ham hien thi banner countToShowBanner = 0; } #endif }
void StateEndGame::showInterstitial() { NativeAndroidHelper::hideAd(); // truoc khi goi quang cao lon, nen tat banner NativeAndroidHelper::showInterstitial(); // hien thi quang cao lon }
Đến đây là đã xong phần tích hợp quảng cáo Admob.
2 bài viết đã hướng dẫn toàn bộ các công việc cũng như các bước để làm game "Funny Halloween Pumpkins".