Python – динамический и строго типизированный язык, который поддерживает множество парадигм программирования, таких как процедурное, объектно-ориентированное и функциональное программирование.
Python был реализован несколькими различными способами: стандартный интерпретатор на C (CPython), на самом Python (PyPy), на .Net DLR (C#) (IronPython) и на Java с JVM (Jython). Jython поставляется с Java совместимостью, что позволяет использовать мощные Java библиотеки, такие как libGDX, при этом сохраняя лаконичность и читаемость языка Python.
В этой статье используется последняя бета версия Jython (Jython 2.7b1), этот релиз нацелен на совместимость с CPython 2.7, поэтому в этой статье мы будет программировать с синтаксисом Python 2.7.
Jython и libGDX
На момент написания статьи, использование Jython и libGDX возможно только на персональном компьютере.
Установка
С Jython можно работать в любом тестовом редакторе, в том числе в Vim или Emacs. PyDev вариант для пользователей
Eclipse. Как только настроена среда разработки, создайте новый Jython проект и задайте все libGDX зависимости в PYTHONPATH, для использования LWJGL
backend персонального компьютера. Это включает gdx.jar, gdx-backend-lwjgl.jar, gdx-backend-lwjgl-natives.jar,
gdx-backend-lwjgl.jar, gdx-natives.jar и gdx-sources.jar.
Программирование на Python
Полный урок простой игры может содержаться в одно python файле.
from com.badlogic.gdx.backends.lwjgl import LwjglApplication, LwjglApplicationConfiguration
from com.badlogic.gdx.utils import TimeUtils, Array
from com.badlogic.gdx.math import MathUtils, Rectangle, Vector3
from com.badlogic.gdx import ApplicationListener, Gdx, Input
from com.badlogic.gdx.graphics.g2d import SpriteBatch
from com.badlogic.gdx.graphics import Texture, OrthographicCamera, GL10
class PyGdx(ApplicationListener):
def __init__(self):
self.camera = None
self.batch = None
self.texture = None
self.bucketimg = None
self.dropsound = None
self.rainmusic = None
self.bucket = None
self.raindrops = None
self.lastdrop = 0
self.width = 800
self.height = 480
def spawndrop(self):
raindrop = Rectangle()
raindrop.x = MathUtils.random(0, self.width - 64)
raindrop.y = self.height
raindrop.width = 64
raindrop.height = 64
self.raindrops.add(raindrop)
self.lastdrop = TimeUtils.nanoTime()
def create(self):
self.camera = OrthographicCamera()
self.camera.setToOrtho(False, self.width, self.height)
self.batch = SpriteBatch()
self.dropimg = Texture("assets/droplet.png")
self.bucketimg = Texture("assets/bucket.png")
self.dropsound = Gdx.audio.newSound(Gdx.files.internal("assets/drop.wav"))
self.rainmusic = Gdx.audio.newSound(Gdx.files.internal("assets/rain.mp3"))
self.bucket = Rectangle()
self.bucket.x = (self.width / 2) - (64 / 2)
self.bucket.y = 20
self.bucket.width = 64
self.bucket.height = 64
self.raindrops = Array()
self.spawndrop()
self.rainmusic.setLooping(True, True)
self.rainmusic.play()
def render(self):
Gdx.gl.glClearColor(0,0,0.2,0)
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT)
self.camera.update()
self.batch.setProjectionMatrix(self.camera.combined)
self.batch.begin()
self.batch.draw(self.bucketimg, self.bucket.x, self.bucket.y)
for drop in self.raindrops:
self.batch.draw(self.dropimg, drop.x, drop.y)
self.batch.end()
if Gdx.input.isTouched():
touchpos = Vector3()
touchpos.set(Gdx.input.getX(), Gdx.input.getY(), 0)
self.camera.unproject(touchpos)
self.bucket.x = touchpos.x - (64 / 2)
if Gdx.input.isKeyPressed(Input.Keys.LEFT): self.bucket.x -= 200 * Gdx.graphics.getDeltaTime()
if Gdx.input.isKeyPressed(Input.Keys.RIGHT): self.bucket.x += 200 * Gdx.graphics.getDeltaTime()
if self.bucket.x < 0: self.bucket.x = 0
if self.bucket.x > (self.width - 64): self.bucket.x = self.width - 64
if (TimeUtils.nanoTime() - self.lastdrop) > 1000000000: self.spawndrop()
iterator = self.raindrops.iterator()
while iterator.hasNext():
raindrop = iterator.next()
raindrop.y -= 200 * Gdx.graphics.getDeltaTime();
if (raindrop.y + 64) < 0: iterator.remove()
if raindrop.overlaps(self.bucket):
self.dropsound.play()
iterator.remove()
def resize(self, width, height):
pass
def pause(self):
pass
def resume(self):
pass
def dispose(self):
self.batch.dispose()
self.dropimg.dispose()
self.bucketimg.dispose()
self.dropsound.dispose()
self.rainmusic.dispose()
def main():
cfg = LwjglApplicationConfiguration()
cfg.title = "PyGdx";
cfg.width = 800
cfg.height = 480
LwjglApplication(PyGdx(), cfg)
if __name__ == '__main__':
main()
Отметим, что во время создания asset, нужно указать assets/ директорию. Когда не используется Android, мы должны указывать
структуру директорий, которую мы используем. В то время как на Android считается, что все внутренние asset ресурсы находятся в assets/
директории.