i_jemin

Archive

← 아카이브로

렌파이(RenPy) 에 광고 (애드몹) 붙이기

렌파이는 기본적으로 파이썬, 데스크탑 플랫폼 기반이라 모바일 네이티브 기능을 활용하기 참 힘들다.

모바일 광고인 애드몹의 경우도 마찬가지라, 결국 렌파이 기반 앱으로 수익을 얻으려면 유료로 팔아야만 한다.

프로그래밍을 잘 모르던 시절에 한 달 동안 여러 조합을 시도하다가, 렌파이에 애드몹 광고를 추가하는 방법을 발견했다.

얀데레 아가씨를 렌파이로 출시했을때 사용했던 방법으로, 나 말고도 궁금해하던 사람들이 많기에 포럼에 공유했다(영어권 개발자 커뮤니티라서, 영어로 썼었다).

https://lemmasoft.renai.us/forums/viewtopic.php?f=51&t=36030


Android only, for now.

Two weeks ago, I added AdMob to my short Android RenPy game and released it for free.
https://play.google.com/store/apps/deta ... om.yandere

I can't share the details, but the revenue was excellent. I found that, in some cases, adding ads to a RenPy game can work better than selling it as a paid app.

Anyway, let's start.

1. Preparations.

Install the latest release of RenPy and Rapt.

Install the latest release of Android Studio and install the following through its SDK Manager:
Android SDK which API is numbered as 19.
Google Play Services.
Google Repository.

Create an AdMob account and a new banner ad for Android.

2. Gathering Source Files from Rapt folder.

Export an APK file from your RenPy project using the RenPy Launcher.
* Don't use expansion APK option!
But we won't use the exported apk file.

We will use the temporary files in the Rapt folder.

After using the Android build function in the RenPy Launcher, you will find new files and folders in the Rapt folder.

These are the converted source files that Rapt uses to export the APK.

Gather the following files and folders from Rapt and move them to a new folder:

Files:
AndroidManifest.xml
build.xml
local.properties
proguard-project.txt
project.properties

Folders:
android-sdk-r23
assets
gen
libs
res
src
templates

3. Make Project for Android Studio

After moving these files to the new folder, open Android Studio and select
"Import Project (Eclipse ADT, Griddle...."

and select your new folder.

Leave the options checked and press Next. Android Studio will create a new project from your folder.

When the new project window opens, wait a few minutes for Gradle sync to finish.
If the console shows errors, make sure you have installed all the required SDKs.

4. Now add ad on main activity.
Android RenPy uses one activity, PythonSDLActivity, which inherits from SDLActivity.
Add the ad object to PythonSDLActivity.

The following steps show the code to add; they do not explain each part in detail.

1. open "build.gradle (Module: yourGameName)" and paste these code inside "dependencies" block.

Image

Code:
compile 'com.google.android.gms:play-services:6.+'

and Press "Sync Now" button.

2. add these code on "AndroidManifest.xml".

Code:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
Code:
<meta-data android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
Code:
<activity android:name="com.google.android.gms.ads.AdActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"
android:theme="@android:style/Theme.Translucent" />

For the placement of these additions, see the complete example below.

Code:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="applemint.com.yandere"
          android:versionCode="104"
          android:versionName="1.04"
          android:installLocation="auto"
          >

  <application android:label="@string/appName"
               android:icon="@drawable/icon"
               android:allowBackup="true"
               android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
               android:hardwareAccelerated="true" >
               >


      <meta-data android:name="com.google.android.gms.version"
          android:value="@integer/google_play_services_version" />


      <meta-data android:name="wakelock" android:value="1" />
    <meta-data android:name="surface.transparent" android:value="0" />
    <meta-data android:name="fullscreen" android:value="1" />

    <activity android:name="org.renpy.android.PythonSDLActivity"
              android:label="@string/iconName"
              android:launchMode="singleTop"
              android:screenOrientation="portrait"
              android:configChanges="keyboardHidden|orientation|screenSize"
              >


      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
        <category android:name="tv.ouya.intent.category.GAME" />
        </intent-filter>


    </activity>




      <activity android:name="com.google.android.gms.ads.AdActivity"
          android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"
          android:theme="@android:style/Theme.Translucent" />



  </application>

  <uses-feature android:glEsVersion="0x00020000" android:required="true" />
  <uses-sdk android:minSdkVersion="10" android:targetSdkVersion="14"/>

  <uses-permission android:name="android.permission.WAKE_LOCK" />
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />





    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>



  
  <uses-permission android:name="android.permission.VIBRATE" />
  
  <uses-permission android:name="android.permission.INTERNET" />
  


</manifest>

3. edit codes on SDLActivity.java and PythonSDLActivity.java

Image

Add these code on top of SDLActivity.java file.

Code:
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.AdSize;
import com.google.android.gms.ads.AdView;

Add this code inside the SDLActivity class.
just copy and paste this code at line after "public class SDLActivity extends Activity {"

Code:
public AdView mAdView;

Image

Copy and paste these code on "OnCreat" function inside of SDLActivity class.
Replace "YOUR AD ID" with your ad's id.

Code:
        AdRequest adRequest = new AdRequest.Builder()
                .build();

        //광고 시작점
        mAdView = new AdView(this);
        mAdView.setAdSize(AdSize.SMART_BANNER);

        mAdView.setAdUnitId("YOUR AD ID");


        mAdView.loadAd(adRequest);

4. add this code on top of PythonSDLActivity.java

Code:
import android.widget.RelativeLayout;

change this code

Code:
/**
    * A layout that contains mLayout. This is a 3x3 grid, with the layout
    * in the center. The idea is that if someone wants to show an ad, they
    * can stick it in one of the other cells..
    */
   public LinearLayout mVbox;

to this.

Code:
   /**
    * A layout that contains mLayout. This is a 3x3 grid, with the layout
    * in the center. The idea is that if someone wants to show an ad, they
    * can stick it in one of the other cells..
    */
   public RelativeLayout mVbox;

change these code

Code:
   // GUI code. /////////////////////////////////////////////////////////////


   public void addView(View view, int index) {
      mVbox.addView(view, index, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT, (float) 0.0));
   }

   public void removeView(View view) {
      mVbox.removeView(view);
   }

   @Override
   public void setContentView(View view) {
      mFrameLayout = new FrameLayout(this);
      mFrameLayout.addView(view);

      mVbox = new LinearLayout(this);
      mVbox.setOrientation(LinearLayout.VERTICAL);
      mVbox.addView(mFrameLayout, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0, (float) 1.0));

      super.setContentView(mVbox);
   }

to these.

Code:
   public void addView(View view, int index) {
      mVbox.addView(view, index);
   }

   public void removeView(View view) {
      mVbox.removeView(view);
   }

   @Override
   public void setContentView(View view) {
      mFrameLayout = new FrameLayout(this);
      mFrameLayout.addView(view);

      mVbox = new RelativeLayout(this);
      mVbox.addView(mFrameLayout);

      super.setContentView(mVbox);
   }

Image

last, add these codes on "OnCreate" function of PythonSDLActivity class.

Code:
        ///


        RelativeLayout.LayoutParams lay = new RelativeLayout.LayoutParams(
                RelativeLayout.LayoutParams.WRAP_CONTENT,
                RelativeLayout.LayoutParams.WRAP_CONTENT);

        lay.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);



        mVbox.addView(mAdView, lay);

        mAdView.bringToFront();


Done.

Now you can use the Android Studio build menu to create a new APK file.
Hope you like this tutorial. Good luck.

/// 1.20.2016 updated

# IF YOU WANT TO USE EXPANSION APK.

Mostly same as when you do not use expansion apk.
1. Select "Yes" when RenPy ask you would you like to create an expansion APK.
(Make sure you set Playstore Public Key in your rpy file)
2. Build it, and prepare Android Studio Project from rapt folder same as above tutorial.
3. Follow above tutorial and build new APK file.
4. Upload APK file you just build with Android Studio with OBB file which RenPy builded.

When using "Expansion APK", pay particular attention to the "Constants.java" file in the project.

Code:
package org.renpy.android;

public class Constants {
   // Used by the google play store.
    public static String PLAY_BASE64_PUBLIC_KEY = "SOME_KEY_FROM_GOOGLE_PLAY";
    public static byte[] PLAY_SALT = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };

    // Used by the expansion downloader.
    public static int fileVersion = 1260;
    public static int fileSize = 240049003;

    // Used by the in-app purchasing code.
    public static String store = "play";
}

You do not need a new Android Studio project for every game version.
If you already have the project for a previous version, build new APK and OBB files from RenPy. We will not use the new APK from RenPy.

1. Change Version information on AndroidManifest.xml same as you set on RenPy Android build setting.
2. Change fileVersion and fileSize value on Constants.java. (You may can check or replace with Updated Constants.java file from Rapt folder).
3. Upload APK file from Android Studio with OBB fie from RenPy.

# You can control Size and Position of ads by change this value.

1. Change AdSize.SMART_BANNER gonna change ad size. There are preset values(constant values) like "SMART_BANNER" under AdSize classes.

Code:
mAdView.setAdSize(AdSize.SMART_BANNER);

2. Change input of addRule function gonna change ad Position. You can use preset values under "RelativeLayout".

Code:
lay.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);

# You can turn off Ads when Player pay for inapp purchase. It's super easy.

1. Collect codes for ad from oncreate Function, bound them as one function under PythonSDLActivity class.
In my case:

Code:
    public void adToLife()
    {
            AdRequest adRequest = new AdRequest.Builder()
                    .build();

            //광고 시작점
            mAdView = new AdView(this);
            mAdView.setAdSize(AdSize.SMART_BANNER);

            mAdView.setAdUnitId("ADS_CODE");


            mAdView.loadAd(adRequest);

            ///


            RelativeLayout.LayoutParams lay = new RelativeLayout.LayoutParams(
                    RelativeLayout.LayoutParams.WRAP_CONTENT,
                    RelativeLayout.LayoutParams.WRAP_CONTENT);

            lay.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);


            mVbox.addView(mAdView, lay);
            mAdView.bringToFront();
    }

2. Go to "Store.java" file, Add these codes to Store class.

Code:
    static public PythonSDLActivity pAct;

    static public void getAct(PythonSDLActivity aa)
    {
        pAct = aa;
    }

3. Go to "Playstore.java" file, Add these code to last line of restorePurchases Function.

Code:
        if (purchased.contains("PACKAGE NAME OF YOU INAPP PRODUCT") == false) {
            activity.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    pAct.adToLife();

                }
            });

4. Add this code to oncreate function of PythonSDLActivity class.
Write this code under "Store.create(this);"

Code:
Store.getAct(this);

The oncreate function in PythonSDLActivity should then look like this.

Code:
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);


        Store.create(this);

        Store.getAct(this);



    }