📜 ⬆️ ⬇️

LÖVE + Android + AdMob = friendship

One day, there was a desire to learn Lua for its modest needs. But just reading the specifications and examples is not interesting, and for a long time there was an idea to write your logical game for Android, the search for a suitable framework for comfortable work began.

After a brief viewing of Google, 2 main candidates stood out: Corona SDK and LÖVE . Corona SDK has, from my point of view, undoubted advantages: support, good documentation, easy integration of various shops / advertisements / social networks (underline the necessary). Despite this, the SDK itself is paid, there is no version for Linux. Starter version has a number of limitations.

After the Corona SDK, I took a close look at LÖVE. The first thing bribed the inscription on the start page:
It's free, open source, and works on Windows, Mac OS X and Linux.

LÖVE is licensed under the liberal zlib / libpng license . It can be used for commercial purposes.


There is quite good documentation even in Russian. The framefork is easy to install. How to write a game using LÖVE user yegorf1 wrote here and continued here . So, slowly studying the possibilities of the framework, I wrote a prototype of my application. And here the fun began.
')
Question number 1

How to run the application under the android, to finally check your "miracle" on your favorite smartphone?
Finding the answer to this question led me to the love-android-sdl2 project , developed by Martin Felis . As the author writes, the project is a port of LÖVE for android. In fact, this is a Lua port on SDL 2.0 for Android .
  1. We pack our application in a zip-archive and rename it to game.love
  2. We copy the archive into the assets folder of the project.
  3. We assemble the .apk file according to the instructions for Linux , Windows , Mac OS X. The process is described in detail by the author, if briefly describe it, then these are a few steps:
    1. Install Android SDK, Android NDK
    2. Installing Android SDK Platoform-tools, Android SDK Built-tools, Android 4.4.2 (API 19) and the Android Support Library via SDK Manager
    3. Run the build in the project directory. First ndk-build, then ant debug.

At the output we have a .apk-file, which can be poured into the phone and finally tested! How to collect the release and sign it, you can read in detail here .
So, the answer to the first question is received. Of course, to make a quick or very economical application is unlikely to work, but for rapid prototyping on Lua or a lightweight game, that's the thing. Almost empty .apk-file immediately weighs about 5 mb, and the main application in assets can plunge Java or C ++ aesthetes into a light shock, although I’m not sure about the latter. You can try to remove unnecessary libraries, but this is a topic for other experiments.

When the application began to acquire more and more complete features, it was time to think about a possible monetization. Of course, there is an option quite for the lazy. Set the application for a fixed price and wait for the light breeze by the sea in the Maldives. But I can’t afford it at the moment, and considering targeting to android, I thought that it was necessary to embed advertising in one way or another. Integration with the AdMob advertising service I have never done. Given the specifics of the resulting "sandwich" from the libraries, I became even more interesting.

Question number 2

How to integrate AdMob into your application?
As the official reference ( en and rus ) suggests using Eclipse in this process, it became obvious that:
  1. You need to build the application in Eclipse. This part is mainly useful for beginners. To do this, download the clean project love-android-sdl2.
    git clone git@bitbucket.org:MartinFelis/love-android-sdl2.git 
  2. Open Eclipse (I use from ADT Bundle). Create a new workspace and add our project File → New → Project ... → Android → Android Project from Existing Code .

    Next, specify the path to the folder with the project. 2 projects should be defined: love-android-sdl2 and SDLActivity. Click Finish .
  3. Go to the properties of the project SDLActivity. Left-click on the project, select Properties . Next, Android and tick Is Library . Click OK .

  4. Go to the properties of the project love-android-sdl2. Java Build Path → Libraries tab → Add JARs ... → find SDLActivity / bin / sdlactivity.jar .

  5. Then we go to the Builders tab and uncheck the box next to [Löve] Generate Internal Scripts .
  6. Push the Run As button ... → Android Application .
  7. We are waiting for the project to be assembled, and Eclipse will ask us to connect the device or run love-android-sdl2.apk on the emulator.


The first series of experiments using the official AdMob integration reference did not lead to success. I turned for help to the project developer, but he replied that he had not yet tried adding AdMob to his project, and that he would also be interested in how to do this.
  1. Follow the instructions in the standard help starting from section 1. Embedding the Google Play services library into the project . The only reservation is that the google-play-services_lib project must first be added from sdk / extras / google / google_play_services / libproject / google-play-services_lib.
  2. Then you can do Project → Clean ... → Clean all project → OK and restart the assembly.
  3. Open the file love-android-sdl2 / src / org.love2d.android / GameActivity.java
  4. We add the necessary code.
    Listing GameActivity.java
     package org.love2d.android; import com.google.android.gms.ads.*; //     import org.libsdl.app.SDLActivity; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; import android.app.DownloadManager; import android.app.ProgressDialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.net.Uri; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.os.PowerManager; import android.os.ResultReceiver; import android.util.Log; import android.util.DisplayMetrics; import android.widget.RelativeLayout; import android.widget.Toast; public class GameActivity extends SDLActivity { private static DisplayMetrics metrics = new DisplayMetrics(); private static String gamePath = ""; private static Context context; private AdView adView; @Override protected void onCreate(Bundle savedInstanceState) { Log.d("GameActivity", "started"); context = this.getApplicationContext(); Uri game = this.getIntent().getData(); if (game != null) { if (game.getScheme().equals ("file")) { gamePath = game.getPath(); } else { copyGameToCache (game); } Log.d("GameActivity", "Selected the file: " + getGamePath()); } super.onCreate(savedInstanceState); getWindowManager().getDefaultDisplay().getMetrics(metrics); //   AdView adView = new AdView(mSingleton); adView.setAdSize(AdSize.BANNER); //   adView.setAdUnitId("ca-app-pub-1209995634500922/8885931497"); //  id  //    RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams( RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); params.addRule(RelativeLayout.ALIGN_PARENT_TOP); params.addRule(RelativeLayout.CENTER_HORIZONTAL); AdRequest adRequest = new AdRequest.Builder().build(); adView.loadAd(adRequest); mLayout.addView(adView, params); } public static String getGamePath() { Log.d ("GameActivity", "called getGamePath(), game path = " + gamePath); return gamePath; } public static DisplayMetrics getMetrics() { return metrics; } public static void openURL (String url) { Log.d ("GameActivity", "opening url = " + url); Intent i = new Intent(Intent.ACTION_VIEW); i.setData(Uri.parse(url)); i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(i); } void copyGameToCache (Uri sourceuri) { String destinationFilename = this.getCacheDir().getPath()+"/downloaded.love"; gamePath = destinationFilename; BufferedOutputStream bos = null; try { bos = new BufferedOutputStream(new FileOutputStream(destinationFilename, false)); } catch (IOException e) { Log.d ("GameActivity", "Could not open destination file:" + e.getMessage()); } int chunk_read = 0; int bytes_written = 0; BufferedInputStream bis = null; if (sourceuri.getScheme().equals("content")) { try { bis = new BufferedInputStream(getContentResolver().openInputStream(sourceuri)); } catch (IOException e) { Log.d ("GameActivity", "Could not open game file:" + e.getMessage()); } } else { Log.d ("GameActivity", "Unsupported scheme: " + sourceuri.getScheme()); } if (bis != null) { // actual copying try { byte[] buf = new byte[1024]; chunk_read = bis.read(buf); do { bos.write(buf, 0, chunk_read); bytes_written += chunk_read; chunk_read = bis.read(buf); } while(chunk_read != -1); } catch (IOException e) { Log.d ("GameActivity", "Copying failed:" + e.getMessage()); } } // close streams try { if (bis != null) bis.close(); if (bos != null) bos.close(); } catch (IOException e) { Log.d ("GameActivity", "Copying failed: " + e.getMessage()); } Log.d("GameActivity", "Copied " + bytes_written + " bytes"); } } 


  5. We reassemble our application, launch it, wait a bit and see the ads above!



The answer to the second and most troubling question for me was found. In this way I managed to “make friends” with LÖVE, Android and AdMob. My game is almost over, I hope for a quick release. Happy end.

Source: https://habr.com/ru/post/219255/


All Articles