Permalänk

[JAVA] Eh... studsa?

Tjena grappar.

Jag håller på med något. Ja, vad det nu är. Vi får se vad det sedan utvecklas till.

Hursomhelst har jag nu en boll som studsar och en bräda som man styr.
Brädan kan bara åka i X-led och funkar (nästan) felfritt.

Bollen har en hastighet i Y-led (veloy) och en hastighet i X-led (velox).

Det jag vill är att hastigheten i X-led ska få ett positivt värde om man träffar den högra sidan av brädan och ett negativt värde om man träffar den vänstra sidan av brädan. Ja, ni fattar, den ska inte bara studsa upp... och sen ner... och sen upp...

import java.awt.*; import java.applet.*; import java.awt.event.*; public class Studsa extends Applet implements Runnable, KeyListener { private Image dbImage; private Graphics dbg; int radius = 15; int size_x = 500; int size_y = 500; double rect_x = 250; double rect_y = 480; double veloRect_x = 0; double velox = 0; double veloy = 0; double bounce_x = 250; double bounce_y = 30; boolean leftDown = false; boolean rightDown = false; boolean pause = false; boolean bounce = false; boolean gameOver = false; public void start() { Thread ny = new Thread(this); ny.start(); } public void init() { addKeyListener(this); requestFocus(); } public void run() { while(true) { bounce = false; veloy += 0.5; bounce_y = bounce_y + veloy; bounce_x = bounce_x + velox; rect_x = rect_x + veloRect_x; if(bounce_y > 500) // Kollar om bollen är utanför planen { gameOver = true; veloy = 0; } if((rect_x - 3 * radius) < bounce_x && bounce_x < (rect_x + 3 * radius) && gameOver != true) //Kollar om bollen har samma X-värde som rect { bounce = true; } if(bounce_y >= rect_y && bounce == true || bounce_y >= rect_y - 2 * radius && bounce == true && gameOver != true) //Studsar bollen { veloy = - 15; } if(bounce_x > size_x - radius && gameOver != true) { velox = - velox; } if(bounce_x < 0 + radius && gameOver != true) { velox = velox * (-1); } if(rect_x >= size_x - 5 * radius && gameOver != true) { veloRect_x = -0.5; } if(rect_x <= 0 + radius && gameOver != true) { veloRect_x = 0.5; } if(leftDown && gameOver != true) veloRect_x -= 0.5; if(rightDown && gameOver != true) veloRect_x += 0.5; if(pause == true) { velox = 0; veloy = 0; } repaint(); try { Thread.sleep(15); } catch(InterruptedException ie) { } } } public void keyPressed( KeyEvent ke) { if(ke.getKeyCode() == KeyEvent.VK_LEFT) leftDown = true; if(ke.getKeyCode() == KeyEvent.VK_RIGHT) rightDown = true; if(ke.getKeyCode() == KeyEvent.VK_SPACE) pause = true; } public void keyReleased(KeyEvent ke) { if(ke.getKeyCode() == KeyEvent.VK_LEFT) leftDown = false; veloRect_x = 0; if(ke.getKeyCode() == KeyEvent.VK_RIGHT) rightDown = false; veloRect_x = 0; if(ke.getKeyCode() == KeyEvent.VK_SPACE) pause = false; } public void keyTyped(KeyEvent ke) { } public void paint (Graphics g) { g.setColor(Color.red); g.fillOval((int) bounce_x - radius, (int) bounce_y - radius, 2 * radius, 2 * radius); g.setColor(Color.black); g.fillRect((int) rect_x - radius, (int) rect_y - radius, 6 * radius, 1 * radius); g.drawString("Bounce_x: " + bounce_x, 25, 25); g.drawString("Bounce_y: " + bounce_y, 25, 40); g.drawString("Velox: " + velox, 25, 55); g.drawString("Veloy: " + veloy, 25, 70); g.drawString("Rect_x: " + rect_x, 25, 85); g.drawString("Rect_y: " + rect_y, 25, 100); if(gameOver == true) { g.drawString("GAME OVER", 230, 230); } } public void update (Graphics g) { if (dbImage == null) { dbImage = createImage (this.getSize().width, this.getSize().height); dbg = dbImage.getGraphics (); } dbg.setColor (getBackground ()); dbg.fillRect (0, 0, this.getSize().width, this.getSize().height); dbg.setColor (getForeground()); paint (dbg); g.drawImage (dbImage, 0, 0, this); } }

Hoppas att det finns någon som har en idé om hur man kan göra detta för jag kommer då inte på det.
DANKE EN FÜRHANDEN!

Visa signatur

| Sony A580 | Sigma 10-20/4-5.6 | Tamron 17-50/2.8 | Sigma 70/2.8 Macro | Konica Minolta 50/1.7 | Konicha Minolta 75-300/4.5-5.6 |

Permalänk
Medlem

Ett sätt är att jämföra bollens mittpunkts x-värde med brädans mittpunkts x-värde. Mittpunkten på bollen har du i bounce_x om jag inte ser helt fel. Mittpunkten på brädan verkar vara recx_x + radius * 2...

formeln [mitten_av_bollen - mitten_av_brädan] ger ett positivt tal om bollen är till höger om mitten på brädan, och ett negativt tal om bollen är till vänster. Dividera detta tal med halva bredden av brädan, dvs. radius * 3.5 (varför tusan har du gjort så förresten?) så får du ett värde mellan -1.0 och 1.0

Visa signatur

Kom-pa-TI-bilitet

Permalänk
Medlem

Det du gör är att ta fram skillnaden i x-led mellan bollen och plattan, sedan har du en matematisk funktion som ger dig x-hastigheten utifrån x-skillnaden. Denna ekvation kan t.ex. var linjär:

(y = x*0.1)

eller exponentiell:

(x^3 * 0.00002)

Du får justera funktionen för att passa spelet.

x-hastigheten är alltså absolut beroende på var på plattan du träffar.

Visa signatur

citera!

Permalänk
Medlem

Eller använda den matematiska funktionen cos, har för mig att jag gjorde den en gång i tiden när jag gjorde ett breakoutspel till Funplanet. Låt plattan börja med 0 och plattans slut vara PI/2 och x-hastigheten (cos(x)*scale)+|-fluffvärde. Fluffvärdet är för att inte få för mycket horizontell studs utifall bollen studsar ytterst i kanten på baten.
Disclaiment :
Matematiska formeln kan vara uppåt väggarna fel men principen ska stämma, jag skeiver detta efter att ha inmundigat sömntabletter och jag är inte så klartänkt nu

Permalänk
Medlem

cos och sin är mycket lämpade för detta. Sedan behöver man inte använda ett helt halvt varv, utan kanske mellan -60 grader till +60 grader. Blir i princip samma sak som "fluffvärde". Man kan också kombinera olika funktioner, t.ex. additivt eller med intervall.

halvt off topic: En intressant tanke som slog mig vore att brädan också får en horisontell hastighet vid kollisionen. Detta skulle dessutom förebygga "studs loop" där bollen kommer tillbaka till plattan på samma position som innan (om nu inte brädan är låst mot kanten).

Visa signatur

citera!