STDIO
Tìm kiếm gần đây
    Nội dung
    0
    0
    Chia sẻ
    Nội dung
    0
    0
    Chia sẻ

    Phát Triển Game Funny Halloween Pumpkins với Cocos2d-x - Phần 2

    Bài viết hướng dẫn các bạn mới muốn học làm game bằng Cocos2d-x. Thông qua bài viết này, các bạn có thể biết đuợc một số kiến thức về xử lý cũng như cách bố trí cấu trúc của game để có thể tự làm game cho mình.
    29/11/2015 21/09/2020 8 phút đọc
    Phát Triển Game Funny Halloween Pumpkins với Cocos2d-x - Phần 2

    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

    End game scene

    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".

    Bài chung series

    0 Bình luận
    Lập Trình Game

    Lập Trình Game

    Kiến thức, kỹ thuật, kinh nghiệm lập trình game.

    Khi bạn nhấn vào sản phẩm do chúng tôi đề xuất và mua hàng, chúng tôi sẽ nhận được hoa hồng. Điều này hỗ trợ chúng tôi có thêm kinh phí tạo nhiều nội dung hữu ích. Tìm hiểu thêm.
    STDIO

    Trang chính

    Công ty TNHH STDIO

    • 30, Trịnh Đình Thảo, Hòa Thạnh, Tân Phú, Hồ Chí Minh
      +84 28.36205514 - +84 942.111912
      developer@stdio.vn
    • 383/1 Quang Trung, Phường 10, Quận Gò Vấp, Hồ Chí Minh
      Số giấy phép ĐKKD: 0311563559 do sở Kế hoạch và Đầu Tư TPHCM cấp ngày 23/02/2012
    ©STDIO, 2013 - 2021