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!