Schlagwort-Archive: Android

Android App Pure Ping Pong!


Processing 2.0

Mein erstes fertiges Projekt ist wieder mal Ping Pong, diesmal Pure Ping Pong!. Zum allgemeinen Verständnis siehe: Projekt Ping Pong. Die Version für Android ist eine schon recht deutlich veränderte.

  • Ich habe im Gegensatz zu Ping Pong für die Steuerung des Balls und der Spielerbalken jetzt PVector-Objekte verwendet.
  • Das Spiel nutzt Multitouch und ist ein reines Multiplayer-Game.
    • Durch das Bewegen des Balkens während der Ballberührung kann man den Balls seitlich beschleunigen.
    • Die Geschwindigkeit des Balls hängt von der Größe des Pointers während der Ballberührung ab. Er kann dadurch beschleunigt, oder gebremst werden.
  • Es wurden Vibrations-Effekte für das haptisches Feedback eingebaut.

Hier der Quellcode mit Kommentaren:

<pre>// Imports
import android.content.Context;
import android.app.Notification;
import android.app.NotificationManager;

// Setup vibration globals:
NotificationManager gNotificationManager;
Notification gNotification;
long[] gVibrate = {
0, 100
};

// Globale Variablen
int size;
int s2;
int balls=5;
int balls1=5;
int serve=2;
int frame=0;
PVector ballPos;
PVector ballDir;
int pPosx;
int pPosy;
int ppPosx;
int pPosx1;
int pPosy1;
int ppPosx1;
float ballspeed;
float ballspeed1;
float maxSpeed;
float minSpeed;
int h24;
int h48;
int hh6;
int h6;
int h4;
int w8;
int w6;
int blockdir=0;
color bg = color(0, 150, 255);
color pl = color(255, 170, 0);

PFont font;

void setup()
{
size(displayWidth, displayHeight);

//Damit sich die Ausrichtung des Displays nicht während des Spiels ändert
orientation(PORTRAIT);
maxSpeed=displayHeight/40;
minSpeed=displayHeight/200;
size=(int)height/24;
//hier die am öftesten vorkommenden Berechnungen
s2=(int) size/2;
h24=(int) displayHeight/24;
h48=(int)displayHeight/48;
hh6=(int)displayHeight-displayHeight/6;
h6=(int)displayHeight/6;
h4=(int)displayHeight/4;
w8=(int)displayWidth/8;
w6=(int)displayWidth/6;

// die PVector-Objekte werden erzeugt
pPosx = (int)width/2;
pPosy = hh6;
ppPosx = pPosx;
pPosx1 = (int)width/2;
pPosy1 = h6;

ppPosx1 = pPosx1;
ballPos = new PVector(width/2, height-h4);
ballDir = new PVector (0, -4);
textAlign(CENTER);
rectMode(CENTER);
font = createFont("Arial", 12);
stroke(180);

// Create our Notification Manager:
gNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// Create our Notification that will do the vibration:
gNotification = new Notification();
// Set the vibration:
gNotification.vibrate = gVibrate;
}

void draw()
{
background(bg);
fill(180);
// für die Start-Einblendung
if (frameCount<120) {
translate(width/2, height/2);
textSize(w8);
rotate(PI/2);
text("PURE PING PONG!", 0, 0);
rotate(-PI/2);
translate(-width/2, -height/2);
}
else {  // hier läuft das Spiel
line(0, height/2, width, height/2);

//Zeichnet verbleibende Bälle für die Spieler
for (int i=1; i<=balls1; i++) {
ellipse(width/(balls1+1)*i, height/3, h48, h48);
}
for (int i=1; i<=balls; i++) {
ellipse(width/(balls+1)*i, height*2/3, h48, h48);
}

// wenn ein Spieler gewonnen hat
if (balls<=0 || balls1 <=0) {
textSize(w8);
translate(width/2, height/2);
if (balls>balls1) {
text("YOU WON !", 0, h4);
}
else {
rotate(PI);
text("YOU WON !", 0, h4);
rotate(-PI);
}
translate(-width/2, -height/2);
}
else {

// Bewegung des Balles
ballPos.add(ballDir);

//Begrenzung seitlich
if (ballPos.x < 0+s2 || ballPos.x > width-s2) {
ballDir.x *= -1;
}

// Begrenzung Spieler 1 und Fehler

// Ball ist im Bereich des Balkens
if ( int(ballPos.y) >= int(hh6-h48-s2) && serve==2) {

//Ball ist vor dem Balken
if ((ballPos.x > pPosx-w6 && ballPos.x < pPosx+w6) && blockdir>4) {

//Beschleunigung oder Verzögerung des Ball je nach Druckpunkt
ballDir.y *=-lerp(0.6, 3, ballspeed);

//Maximal und Minimalwerte für die Ballgeschwindigkeit
if (ballDir.y>0) {
ballDir.y=min(ballDir.y, maxSpeed);
ballDir.y=max(ballDir.y, minSpeed);
}
else {
ballDir.y=max(ballDir.y, -maxSpeed);
ballDir.y=min(ballDir.y, -minSpeed);
}

// Damit kann man dem Ball "Schnitt" verleihen
ballDir.x -=(ppPosx-pPosx)/3;

//Haptisches Feedback wenn der Ball getroffen wird
gNotificationManager.notify(1, gNotification);

//Damit verhindert wird, dass der Ball mehrmals die Richtung wechselt
blockdir=0;
}

//bei Fehler
else {
frame=0;

balls-=1;
serve=0;
}
}

// Begrenzung Spieler 1 und Fehler

// Ball ist im Bereich des Balkens
if ( int(ballPos.y) <= int(h6+h48+s2) && serve==2) {

//Ball ist vor dem Balken
if ((ballPos.x > pPosx1-w6 && ballPos.x < pPosx1+w6) && blockdir>4) {

//Beschleunigung oder Verzögerung des Ball je nach Druckpunkt
ballDir.y *=-lerp(0.6, 3, ballspeed1);

//Maximal und Minimalwerte für die Ballgeschwindigkeit
if (ballDir.y>0) {
ballDir.y=min(ballDir.y, maxSpeed);
ballDir.y=max(ballDir.y, minSpeed);
}
else {
ballDir.y=max(ballDir.y, -maxSpeed);
ballDir.y=min(ballDir.y, -minSpeed);
}

// Damit kann man dem Ball "Schnitt" verleihen
ballDir.x -=(ppPosx1-pPosx1)/3;

//Haptisches Feedback wenn der Ball getroffen wird
gNotificationManager.notify(1, gNotification);

//Damit verhindert wird, dass der Ball mehrmals die Richtung wechselt
blockdir=0;
}

//bei Fehler
else {
frame=0;

balls1-=1;
serve=1;
}
}

// Zeichnet den Ball
stroke(255);
fill(255);
ellipse(ballPos.x, ballPos.y, size, size);

//Zeichnet die Balken
stroke(pl);
strokeWeight(h24);
line(pPosx-w8, hh6, pPosx+w8, hh6);
line(pPosx1-w8, h6, pPosx1+w8, h6);
strokeWeight(0);
stroke(200);

// Bewegung Player 1 und 2
ppPosx=pPosx;
ppPosx1=pPosx1;
}

// Spielverzögerung bei Fehler
if (serve==0 && frame>30) {
ballDir.x=0;
ballPos.x=pPosx;
ballPos.y=height-h4;
if (serve==0 && frame>90) {
ballDir.y *=-1;

serve =2;
}
}
if (serve==1 && frame>30) {
ballPos.x=pPosx1;
ballPos.y=h4;
ballDir.x=0;
if (serve==1 && frame>90) {
ballDir.y *=-1;

serve =2;
}
}

// Verzögerung bei Fehler
frame++;

// Blockierung der Ballrichtung nach dem Rückprall am Balken
blockdir++;
}
}

//Funktion für Multitouch Events von
// Eric Pavey - www.akeric.com - 2010-10-24  (verändert)
//-----------------------------------------------------------------------------------------
// Override Processing's surfaceTouchEvent, which will intercept all
// screen touch events.  This code only runs when the screen is touched.

public boolean surfaceTouchEvent(MotionEvent me) {
int pointers = me.getPointerCount();

if (pointers>1) {
// Zuordnung der TouchPoints zum jeweiligen Spieler
if (int(me.getY(0))<height/2) {
pPosx=(int)me.getX(1);
pPosx1=(int)me.getX(0);
ballspeed = me.getSize(1);
ballspeed1= me.getSize(0);
}

else {
pPosx=(int)me.getX(0);
pPosx1=(int)me.getX(1);
ballspeed = me.getSize(0);
ballspeed1= me.getSize(1);
}
}
return super.surfaceTouchEvent(me);
}

Viel Spass!

Processing Apps für Android II – Multitouch


Processing 2.0

Ein interessantes Feature der Android- Programmierung ist auf jeden Fall die Möglichkeit Multitouch zu verwenden. Es gibt im Netz schon einige Implementierungen, von denen ich diese von Eric Pavey für mein Projekt Pong für Android genutzt habe. Dieser Beispielcode ist zum Testen hervorragende geeignet.

Das Kernstück verwendet den Processing surfaceTouchEvent und triggert ihn mit dem MotionEvent aus der Android-Library.

//-----------------------------------------------------------------------------------------
// Override Processing's surfaceTouchEvent, which will intercept all
// screen touch events.  This code only runs when the screen is touched.

public boolean surfaceTouchEvent(MotionEvent me) {
 // Number of places on the screen being touched:
 int numPointers = me.getPointerCount();
 if (int(me.getY(0))<height/2) {
  playerPos.x=me.getX(1);
  playerPos1.x=me.getX(0);
  ballspeed = me.getSize(1);
  ballspeed1= me.getSize(0);
 } else {
  playerPos.x=me.getX(0);
  playerPos1.x=me.getX(1);
  ballspeed = me.getSize(0);
  ballspeed1= me.getSize(1);
 }
 return super.surfaceTouchEvent(me);
}

Ich habe diesen Code für mein Projekt Pure Pong! genutzt. Man kann mit ihm dann die 2 Pointer für das Spiel dem richtigen Spieler zuordnen und in draw() ihre Koordinaten verarbeiten.

Processing Apps für Android I – Erste App erstellen


Processing 2.0

Hier die offizielle Dokumentation für Processing auf Android und die entsprechende Abteilung im Forum.

Auch das ist ein guter Erfahrungsbericht und eine sehr einfache Schritt für Schritt Anleitung.

Unterstützt werden Android-Versionen ab 2.3.3 (API 10).

  1. Zuerst muss die Android SDK heruntergeladen werden. Ich verwende Ubuntu 12.04 und habe das entsprechende Paket laut Anleitung installiert.
    Das ADT-Plugin für Eclipse muss nicht installiert werden. Dafür müssen aber im Schritt 4 der Installationsanleitung die folgenden Pakete installiert werden:

    • unter Available Packages –> Android Repository: SDK Platform Android 2.3.3, API 10

    Man kann auch die neueren Versionen der API oder gleich alles zusätzlich installieren.

  2. In Processing 2.0 Android-Mode aktivieren, Berechtigungen zu setzen usw.
  3. ImageWenn wir unser Processing 2.0 jezt starten und im Menü –> Android Mode aktiviert haben, können wir, mit Shift Play den Sketch starten , wird dieser automatisch im Emulator ausgeführt. Allerdings muss der Sketch vorher gespeichert werden. Es kann mal passieren, dass der Emulator nicht beim ersten Mal startet.
  4. Hier ein kleines Beispielprogramm zum Testen:
  5. void setup() {
    Imagesize(240,400);
    noStroke();
    fill(255);
    
    ellipseMode(CENTER);
    };
    void draw() {
    background(10,80,139);
    ellipse(width/2, height/2, 150, 150);
    };
  6. Damit man das Programm nun auf dem Android-Gerät laufen lassen kann, muss man die Anleitung hier durcharbeiten: http://developer.android.com/guide/developing/device.html
  7. Wenn das Gerät verbunden ist, kann man das Programm von oben in Processing 2.0 mit einem Klick auf Playam Gerät laufen lassen. Mit Shift Play ist es aber nach wie vor möglich, den Emulator aufzurufen!
  8. Einige Tipps zur Programmierung speziell für Android:
    • Will man 3D Sketches im Emulator laufen lassen, muss man die virtuelle Maschine im AVD Manager bearbeiten und unter Hardware die GPU emulation auf yes stellen. Dort können auch andere Hardwareoptionen aktiviert werden.
    • Viele Mobiltelefone unterstützen nicht die volle 24bit Farbtiefe. Dadurch kann es zu Darstellungsproblemen bei Farbübergängen kommen.
    • Die Verwendung von createFont() bringt speziell bei 2D Anwendungen Qualitätsvorteile gegenüber loadFont().
    • Statt size(width, height), ist es besser size(displayWidth, displayHeight) zu verwenden. Dann wird die Anwendung immer auf den vollen Bildschirm skaliert. Als 3D Renderer kann man P2D oder P3D verwenden.
    • Was Maus-Eingabe betrifft, können mouseX und mouseY wie gehabt verwendet werden, zusätzlich gibt es neue Variablen. motionX, motionY, pmotionX, pmotionY und motionPressure.
    • EventHandler für Key– und MouseEvents sind nicht verfügbar.
    • Wenn man die Bildschirm-Orientierung sperren will, kann man das mit orientation(PORTRAIT) oder orientation(LANDSCAPE) machen.
    • weiter info unter: http://wiki.processing.org/w/Android

Processing verwenden


Processing 2.0

Processing kann von der Projektseite heruntergeladen werden. Einfach auspacken und starten.

Image

In Processing 2.0 gibt es rechts oben einen Modus – Wahlschalter. Dieser bietet nach der Installation 3 Möglichkeiten:

  1. JAVA … Es wird ein Java Programm erstellt, das auf unterschiedlichen Plattformen in einem eigenen Programmfenster läuft.
  2. ANDROID … Es wird ein lauffähiges Programm für Android Devices erstellt. Diese können entweder im Emulator oder auf dem Device ausgeführt werden. Damit dieser Modus funktioniert ist allerdings die Installation der Android SDK notwendig! Eine Anleitung findest du hier! Details
  3. JAVASCRIPT … In diesem Modus wird der Java Programmcode in Javascript Code konvertiert. Dieser wird dann direkt mit Browser angezeigt, und kann in jede Webseite integriert werden. Details

In allen 3 Modi wird der Programmcode im Programmfenster geschrieben und kann über die Play-Taste ausgeführt werden.

Das Terminal-Fenster unten kann für Textausgaben benutzt werden.

Die Export-Funktion erzeugt je nach Modus ein ausführbares Programm für Desktops, eine Android App oder eine HTML Datei mit Javascript Elementen.