4. Oktober 2012
Von den Physik-Libraries etwas enttäuscht, habe ich mich entschlossen, die "Physik", bzw. die Kollisionsabfragen für mein Spiel selber zu programmieren. Da ich viel Zeit verloren habe, musste ich mich etwas beeilen. Spielidee/Konzept Ich wollte das Spiel Pong verändern und die Spielfläche auf einen Kreis projezieren. Zwei Spieler müssen dafür sorgen, dass der Ball nie den Rand erreicht. In der Mitte wirkt eine Gravitationskraft dafür, dass der Ball abgelenkt wird und der Einschlagort schwer vorauszusehen ist. Die Gravitation wechselt zwischen anziehend und abstossend.![Game_Example](../../../../files/2012/10/Game_Example-300x300.jpg)
![Game_Steuerung_Kinect](http://blogs.iad.zhdk.ch/codingspace/files/2012/10/Game_Steuerung_Kinect-150x150.jpg)
![game1](http://blogs.iad.zhdk.ch/codingspace/files/2012/10/game1-150x150.jpg)
![game2](http://blogs.iad.zhdk.ch/codingspace/files/2012/10/game2-150x150.jpg)
![Bildschirmfoto 2012-10-04 um 16.15.16](http://blogs.iad.zhdk.ch/codingspace/files/2012/10/Bildschirmfoto-2012-10-04-um-16.15.16-150x150.png)
![Bildschirmfoto 2012-10-04 um 16.15.30](http://blogs.iad.zhdk.ch/codingspace/files/2012/10/Bildschirmfoto-2012-10-04-um-16.15.30-150x150.png)
![Bildschirmfoto 2012-10-04 um 16.15.36](http://blogs.iad.zhdk.ch/codingspace/files/2012/10/Bildschirmfoto-2012-10-04-um-16.15.36-292x300.png)
private void initGame() { ball = new Ball(0,0, 25); ball.set(new PVector(width/2, height/2+200), new PVector(random(-3,3),-1)); paddleLeft = new Paddle(20, 0, 360, 270, 30); gravityDirection = 0; if(gravityController != null) { gravityController.quit(); } gravityController = new TimeController(2000,6000,THREAD_MODE_GRAVITY_CONTROL); gravityController.start(); gameStartTime = millis(); }Auszug aus der Kollisionsabfrage
private void checkMovementAndGravity() { PVector vDistFromCenter = PVector.sub(pos, centerPos); float r = vDistFromCenter.mag(); float K = 2500.0; if(gravityDirection < 0) { K = 1800; } float a = K / sq(r); PVector gravityVector = PVector.sub(centerPos,pos); gravityVector.setMag(a); gravityVector.mult(gravityDirection); if(r > minGravityRadius && r < maxGravityRadius) { dir.add(gravityVector); } if(r > 150 && dir.mag() > 20) { dir.setMag(8); } pos.add(dir); } private void checkEdgeCollision() { PVector vDistFromCenter = PVector.sub(pos, centerPos); if(vDistFromCenter.mag() > gameCircleRadius-radius) { if(checkCollision) { speed = START_SPEED; checkCollision = false; checkPaddleCollisionBlocker = true; paddleCollisionBlockTime = millis(); bounceOff(vDistFromCenter, gameCircleRadius); stopGame(); } } else { checkCollision = true; } } private void checkPaddleCollision() { PVector vDistFromCenter = PVector.sub(pos, centerPos); float ballAngleFromCenter = calculateBallAngleFromCenter(vDistFromCenter); if(millis() - paddleCollisionBlockTime > 200) { checkPaddleCollisionBlocker = false; } float paddleStart = paddleLeft.angle; if(ballAngleFromCenter < radians(30)) { paddleStart = paddleStart - radians(360); } float paddleEnd = paddleLeft.angle + radians(paddleLeft.lengthAngle); if(vDistFromCenter.mag() > paddleRadius-radius) { println("start " + degrees(paddleStart)); println("end " + degrees(paddleEnd)); println("degree " + degrees(ballAngleFromCenter) + "\n"); if(ballAngleFromCenter > paddleStart && ballAngleFromCenter < paddleEnd) { if(checkPaddleCollision && !checkPaddleCollisionBlocker) { bounceOff(vDistFromCenter, paddleRadius); checkPaddleCollision = false; speed += 0.2; } } } else { checkPaddleCollision = true; } } private void bounceOff(PVector vDistFromCenter, float borderRadius) { float entryAngle = PVector.angleBetween(dir,vDistFromCenter); float bounceAngle = entryAngle * 2; if(bounceAngle < radians(10)) { bounceAngle = radians(15); } else if(bounceAngle > radians(60)) { bounceAngle = radians(50); } float Rgoal = borderRadius - radius; float Rnow = vDistFromCenter.mag(); float part2 = (sq(Rnow) * sq(cos(entryAngle))) - sq(Rnow) + sq(Rgoal); float offset = (Rnow * cos(entryAngle)) - sqrt(part2); PVector correctionMove = dir.get(); correctionMove.setMag(offset); correctionMove.mult(-1); pos.add(correctionMove); float orientierung = dir.x * vDistFromCenter.y - dir.y * vDistFromCenter.x; rotate2D(dir,bounceAngle * (orientierung > 0 ? 1 : -1)); dir.x *=-1; dir.y *=-1; dir.setMag(speed); } private void rotate2D(PVector v, float theta) { float m = v.mag(); float a = v.heading2D(); a += theta; v.x = m * cos(a); v.y = m * sin(a); } private float calculateBallAngleFromCenter(PVector vDistFromCenter) { float ballAngleFromCenter = 0; float ballAngle = PVector.angleBetween(vDistFromCenter,new PVector(1,0)); if(pos.y < height/2) { ballAngleFromCenter = radians(360) - ballAngle; } else { ballAngleFromCenter = ballAngle; } return ballAngleFromCenter; } void draw() { calcPos(); PVector vDistFromCenter = PVector.sub(pos, centerPos); float drawAngle = PVector.angleBetween(dir,new PVector(0,-1)); pushMatrix(); translate(pos.x,pos.y); fill(255); image(backgroundImage,-50,-50); popMatrix(); //drawDebugLines(); }