Pygame on Android

How do I compile pygame on android tablet?

Pygame is a SDL wrapper. I doubted that it is available for the android system, since I never heard of SDL for android.

After a quick search I have found the website of the pygame subset for android which looks like something you are looking for.

The tutorial seems to be complete, so I would suggest looking into this.

Python: how do I can use android.show_keyboard for my android app?

As specified in the Python for Android documentation, android is a Cython module "used for Android API interaction with Kivy’s old interface, but is now mostly replaced by Pyjnius."

Therefore, the solution I have found is based on Pyjnius, and essentially consists in replicating the Java code used to hide and show keyboard on Android (I used this answer as a base, but there might be something better out there), by exploiting the Pyjnius autoclass-based syntax:

from jnius import autoclass

def show_android_keyboard():
InputMethodManager = autoclass("android.view.inputmethod.InputMethodManager")
PythonActivity = autoclass("org.kivy.android.PythonActivity")
Context = autoclass("android.content.Context")
activity = PythonActivity.mActivity
service = activity.getSystemService(Context.INPUT_METHOD_SERVICE)
service.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0)

def hide_android_keyboard():
PythonActivity = autoclass("org.kivy.android.PythonActivity")
Context = autoclass("android.content.Context")
activity = PythonActivity.mActivity
service = activity.getSystemService(Context.INPUT_METHOD_SERVICE)
service.hideSoftInputFromWindow(activity.getContentView().getWindowToken(), 0)

If you want to learn more about how Pyjinius's autoclass works, take a look at the section related to Automatic Recursive Inspection, within the Python for Android documentation.

Pygame/Kivy on Android?

It is possible to programm android apps / games in qpython (not in qpython3) with kivy.

The only problem is that you can't export them as an apk file on your smartphone.

For that you need a linux PC / laptop.

How you can programm and run your app/game:

  1. download qpython here

  2. in the app go to qpypi and download kivy

  3. write your first kivy programm in the qpython editor (kivy doc)(Kivy crash course)

Then you have to add these lines of code above your actual code (in your main.py file) :

#-*-coding:utf8;-*-
#qpy:2
#qpy:kivy

Then you can run your code.

I hope I could help.

Could not open resource file, pygame error: FileNotFoundError: No such file or directory.

The resource (image, font, sound, etc.) file path has to be relative to the current working directory. The working directory is possibly different from the directory of the python file.

It is not enough to put the files in the same directory or sub directory. You also need to set the working directory. Alternatively, you can create an absolute file path.


The name and path of the file can be get by __file__. The current working directory can be get by os.getcwd() and can be changed by os.chdir(path):

import os

os.chdir(os.path.dirname(os.path.abspath(__file__)))

An alternative solution is to find the absolute path.
If the file is in an subfolder of the python file (or even in the same folder), then you can get the directory of the file and join (os.path.join()) the relative filepath. e.g.:

import pygame
import os

# get the directory of this file
sourceFileDir = os.path.dirname(os.path.abspath(__file__))

# [...]

# join the filepath and the filename
filePath = os.path.join(sourceFileDir, 'test_bg.jpg')
# filePath = os.path.join(sourceFileDir, '_pycache_/test_bg.jpg')

surface = pygame.image.load(filePath)

The same can be achieved with the pathlib module.
Change the working directory

import os, pathlib

os.chdir(pathlib.Path(__file__).resolve().parent)

or create an absolute filepath:

import pathlib

# [...]

filePath = pathlib.Path(__file__).resolve().parent / 'test_bg.jpg'
surface = pygame.image.load(filePath)

Android to apk via Buildozer: Play Sound with pygame - Kivy

I wrote simple test app. In short, you should ask the user for permission to read files, for this you need to specify them in the buildozer.spec file and do it using a command in python code.

main.py

from kivy.app import App

from kivy.lang import Builder
from kivy import platform
from kivy.clock import Clock
from kivy.event import EventDispatcher

import pygame.mixer as mixer
import os
import pathlib

if platform == 'android':
from android.permissions import request_permissions, Permission

KV = """
GridLayout:
cols: 1
ProgressBar:
id: pb
max: 100
min: 0

Button:
text: 'Load'
on_release: app.load_track()

Button:
text: 'Play'
on_release: app.player.play()

Button:
text: 'Stop'
on_release: app.player.stop()

Button:
text: 'Pause'
on_release: app.player.pause()

Button:
text: 'Resume'
on_release: app.player.resume()

Button:
text: 'Loop'
on_release: app.player.loop()
"""

class Player(EventDispatcher):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.register_event_type('on_stop')
self.register_event_type('on_start')

self.sound = None
self.sound_inst = None
self.song = ''
self.is_loop = False
mixer.init()

def load(self, filename: str):
if os.path.exists(filename):
self.song = filename
mixer.music.load(self.song)
self.sound_inst = mixer.Sound(self.song)
else:
raise FileNotFoundError

def loop(self):
if self.is_loop:
self.is_loop = False
else:
self.is_loop = True

def play(self):
self.dispatch('on_start')
mixer.music.play(self.is_loop)

def stop(self):
self.dispatch('on_stop')
mixer.music.stop()

def pause(self):
mixer.music.pause()

def resume(self):
mixer.music.unpause()

def get_pos(self):
return mixer.music.get_pos()

def get_length(self):
return self.sound_inst.get_length() # sec

def on_stop(self):
pass

def on_start(self):
pass

class TestApp(App):
def __init__(self, **kwargs):
super().__init__(**kwargs)

self.song = 'test.ogg' # wav/ogg supported
self.player = Player()
self.value_update_clock = None
self.player.bind(on_stop=lambda inst: (self.cancel_clock(),
Clock.schedule_once(lambda dt: self.set_pb_value(0))
)
)
self.player.bind(on_start=lambda inst: self.set_clock())

def on_start(self):
if platform == 'android':
request_permissions([Permission.WRITE_EXTERNAL_STORAGE])

def load_track(self):
filepath = os.path.join(pathlib.Path(__file__).resolve().parent, self.song)
self.player.load(filepath)
print(filepath, 'loaded')

def build(self):
return Builder.load_string(KV)

def set_clock(self):
self.value_update_clock = Clock.schedule_interval(lambda dt: self.set_pb_value(), 1.0)

def cancel_clock(self):
if self.value_update_clock:
self.value_update_clock.cancel()

def set_pb_value(self, value: int = None):
if not value:
pos = self.player.get_pos() / 1000
length = self.player.get_length()

value = round(pos / length * 100, 2)

self.root.ids.pb.value = value

TestApp().run()

buildozer.spec

source.include_exts = py,png,jpg,kv,atlas,mp3,ogg,wav
requirements = kivy, pygame
android.permissions = WRITE_EXTERNAL_STORAGE, READ_EXTERNAL_STORAGE
android.api = 32
android.minapi = 21
android.ndk = 19c
p4a.branch = master
p4a.bootstrap = sdl2

Cannot open image in pygame on android

The image filepath has to be relative to the current working directory. The working directory is possibly different to the directory of the python file.

The name and path of the file can be get by __file__. The current working directory can be get by os.getcwd().

If the image is in the same folder as the python file, then you cab get the directory of the file and concatenate the image filename. e.g.:

import sys
import pygame
from pygame.locals import *
import os

# get the directory of this file
sourceFileDir = os.path.dirname(os.path.abspath(__file__))

# [...]

image = pygame.image.load( os.path.join(sourceFileDir, "Audi.png") ).convert()


Related Topics



Leave a reply



Submit