MichaelStott / KivMob

AdMob support for Kivy
MIT License
143 stars 38 forks source link

pygame and kivmob #95

Open SonofPoseidon1982 opened 3 years ago

SonofPoseidon1982 commented 3 years ago

Can you use kivmob with pygame? You see I've managed to get Unity ads working with pyjnius - it works with my Kivy app but crashes with a black screen death on pygame.

MichaelStott commented 3 years ago

It might be possible with some fiddling. I don't know how to go about building a pygame project for Android, but it doesn't look like it uses buildozer. As a result, you willl need to manually add the AdMob library/dependencies to the Android project and make sure the app permissions are set accordingly. kivmob.py also references the Kivy logging module, which may cause some issues when building a pygame project, but that could easily be replaced or abstracted away.

This would need more investigation, but I like the idea of having this library include pygame support/build instructions. Marking as a possible enhancement for now.

SonofPoseidon1982 commented 3 years ago

It's ok :) Pygame now has a buildozer recipe and works fine. It was introduced this year. There are no problems with kivy logging module as I've used it in my pygame project.

I imported unity ads with pyjnius, it worked absolutely flawlessly in Kivy. But in pygame, there were problems with displaying the ads.. they would load, but then the black screen death occurred.

Sahil-pixel commented 3 years ago

hey..can you tell me ..how you have converted pygame game into apk..? can you share your buildozer.spec file ?

Maxython commented 3 years ago

@Sahil-pixel, buildozer is a compiler for Kivy. Though I've never done PyGame, try this https://github.com/renpytom/rapt-pygame-example.

Sahil-pixel commented 3 years ago

it is only for python 2

Maxython commented 3 years ago

Yes, it needs python 2. At the moment there is no compiler for PyGame in python 3. There are only two solutions: 1) Switch to kivy.
2) Compile PyGame on python 2 (you can use linux for this).

Sahil-pixel commented 3 years ago

I know Kivy see my game written in Kivy .

Maxython commented 3 years ago

Self-advertisement, classic) The game is cool, but did I answer your question?

Sahil-pixel commented 3 years ago

yes .I want to use pygame ..I don't have any idea with pygame to convert into an APK ....and there is no good tutorial ...

SonofPoseidon1982 commented 3 years ago

Sahil-pixel, you can use pygame in buildozer. I have used it myself. There is a recipe. See for yourself; https://github.com/kivy/python-for-android/tree/master/pythonforandroid/recipes

Just include it in your list of recipes (It works with python3). This was added this year.

SonofPoseidon1982 commented 3 years ago

p4a recipes are not limited to Kivy, even though that is an important interface. I previously used Kivy (for simple apps). but I find pygame more conducive for games (I'm having problems getting ads in which worked on Kivy though)

Maxython commented 3 years ago

As I understand it, it was just necessary to add PyGame to the requirement, and this is actually logical.

SonofPoseidon1982 commented 3 years ago

Yup, it works very well

SonofPoseidon1982 commented 3 years ago

I wish I could get help with my problem.. I managed to get unity ads into my Kivy App with pyjnius, but it doesn't show (with a black screen death) in pygame. This could be due to graphical differences. Kivy has an opengl wrapper. This is all relevant if kivmob is also to work in pygame.

SonofPoseidon1982 commented 3 years ago

Right, I'm deleting the buildozer.spec comment as its taking too much space (I think you've got what you need)

Sahil-pixel commented 3 years ago

i have tried see this .but i have failed.. https://github.com/kivy/python-for-android/issues/2333

Rajesh-JP commented 3 years ago

hey..can you tell me ..how you have converted pygame game into apk..? can you share your buildozer.spec file ?

It's easy to convert a pygame program into an android app. I have made a file sharing app with pygame and socket programming that worked well. At the beginning, I also had some issues like app crashing after showing presplash screen. But after thinking too many things, I came to know that the issue is in loading images and pygame display. You want to correct something in your code.

  1. Set pygame display in FULLSCREEN mode. Eg: surface = pygame.display.set_mode((w,h), FULLSCREEN)
  2. If your app uses any images, then follow this step. Add this string before the relative path to your image. "/data/data/(package.name)/files/app/". Here (package.name) means the value that you given to the "package.name" in buildozer.spec file. This step is because the additional files of you app like images, audios will moved to this path while installing the app. Eg: If your app package name is "org.test.mypgapp", then - img = pygame.image.load("/data/data/org.test.mypgapp/files/app/myimg.png")
SonofPoseidon1982 commented 3 years ago

Also for smooth running you will need to convert the surface to the same pixel format as the android display, so use the function convert_alpha(). For example,

img = pygame.image.load("/data/data/org.test.mypgapp/files/app/myimg.png").convert_alpha()

I have to say however, we seem to have gone off topic as this thread was really supposed to be about pygame and kivmob :D

Rajesh-JP commented 3 years ago

Yes. We gone off the topic. If any one knows the answer please comment here. I also want to know the how to display ads in my pygame android app , that I referenced before (File sharing app).

SonofPoseidon1982 commented 3 years ago

I've been working on it (but can't find a way around my black screen death every time the interstitial ad tries to show). Here is a link to what I've managed so far with UnityADS: https://stackoverflow.com/questions/64522188/why-is-my-unity-ads-integration-working-on-kivy-but-not-pygame-any-ideas

Maxython commented 3 years ago

In short, I dug around on the Internet and found an interesting fact. The PyGame module uses the SDL cross-platform multimedia library (it can also use version 2), and kivy uses SDL2 as the logic of the game, it already uses OpenGL to display the game on the screen. In short, the black eran of death may occur due to different ways of displaying the game on the screen (but this is not accurate, maybe I misunderstood something).

SonofPoseidon1982 commented 3 years ago

I think you're probably on right lines with what you're saying. I just find it all very unclear. My games descent into blackness remains unresolved unfortunately :D

Maxython commented 3 years ago

@MichaelStott can you explain the logic and action of kivmod?

MichaelStott commented 3 years ago

@SonofPoseidon1982 Can you provide an example project demonstrating the issue?

@Maxython On a high level, kivmob instantiates a new AdMob ad view and adds it to the activity that runs the Python application through pyjnius for banner ads specifically. For interstitial and rewarded video ads, I believe AdMob handles the switching of views in that case. KivMob basically creates and manages the interactions between the interstitial object associated with PythonActivity.

SonofPoseidon1982 commented 3 years ago

@MichaelStott I have quickly made this project to demonstrate the problem. https://github.com/SonofPoseidon1982/Py_1982

If you have any questions, I will try my best to answer (or anything I need to add or clarify)

Rajesh-JP commented 3 years ago

Please explain how the KIVMOB works in low level.

Rajesh-JP commented 3 years ago

Explain what it do actually

SonofPoseidon1982 commented 3 years ago

Does anyone have any theory that might explain why I'm getting a black screen death in my pygame (taking into account that it is working smoothly with kivy)? At the moment if feels like I'm groping around in the dark.

Maxython commented 3 years ago

I think I need to go to kivmod, I need to make another class that works not with kivy but with pygame.

Maxython commented 3 years ago

it seems to me in kivmod, you need to make another class that does not work with kivy but with pygame.

Maxython commented 3 years ago

sorry, working with a translator.

SonofPoseidon1982 commented 3 years ago

Guys, I think I may have found the answer. It is to do with the FPS (Frames per second). While the interstitial ad is called during the ostensible pause (where it is not blitting graphics to the screen i.e when g_sleep==True), the frames are still refreshing at 30 FPS, and this does not stop when the ads are called. To test this theory, I added the following line straight after 'unity_ads.show_ad(inter_id)':


                unity_ads.show_ad(inter_id) 
                pygame.time.delay(40000)

The ad showed, but I need to find a proper solution so it can be properly integrated.

SonofPoseidon1982 commented 3 years ago

Something like this works but its clumsy so far:

         unity_ads.show_ad(inter_id)
         pygame.time.delay(<duration of ad>)
         self.g_pause=False  # allow blitting every fps
         py_display =pygame.display.set_mode((display_width, display_height),pygame.FULLSCREEN)

This is admittedly a bit clumsy (I'm still working on it), but what it means is that ultimately kivmob should also work with pygame without any real need for revision. The methods used in kivmob are pretty much the same as mine. All you need to do is find a way to pause the updating FPS until the ad has finished showing. As for banner ads, I have no idea, that's a myriad of difficulty due to the way graphics are displayed in pygame in terms of FPS.

SonofPoseidon1982 commented 3 years ago

OK, so I have found an improved solution (although it is still a little suspicious and clumsy).

In UnityAdsListener interface (in kivunity.py) I added 'ad_shown=True' for when the ad is shown:

@java_method('(Ljava/lang/String;Lcom/unity3d/ads/UnityAds$FinishState;)V')
  def onUnityAdsFinish(self,inter_id,finish_state):
    #pass
    global ad_shown
    logging.warning("\n\n ADS are FINISHED! "+str(finish_state) + " \n\n")
    #appl_id = u_h.app_id2                                                     
    ad_shown = True 

I added the following function to the Unity_handler class which registers when the ad has finished (making sure to set ad_shown=False before the ad show is called in kivunity.py):

        def check_ad_status(self):
            return ad_shown

In main.py, I added the following:

       tmp_sleep=False
       unity_ads.show_ad(inter_id)
       while tmp_sleep==False:
           tmp_sleep = unity_ads.check_ad_status()
           time.sleep(1)
       self.g_sleep=False #for resuming the inner game loop
       py_display =pygame.display.set_mode((display_width, display_height),pygame.FULLSCREEN)     
       print("\n\n Pygame window back into focus \n\n ")   # Bizarrely this is sufficient to bring the pygame window back into focus

Well, my game has managed to load interstitial ads 10+ times repeatedly without any problems (no crashes). Although it works, my solution is not exactly elegant.

MichaelStott commented 3 years ago

Hey, as long as it works :)

This currently isn't exposed through KivMob for interstitials, but you might be able to add this logic to an onShow and onClose callback for the interstitial object. That would at least remove the need to have the whole "sleep then check" loop. Callbacks for rewarded video ads are currently supported, I just never got around to implementing them for interstitials

SonofPoseidon1982 commented 3 years ago

Well this might suffice for now, while I try to find a less whacky solution :D