Sto lavorando a un gioco di trading spaziale 3D con alcune persone, e una delle cose che mi è stato assegnato è creare un tunnel di guida che il la nave viaggia attraverso, con il tunnel fatto di quadrati che l'utente vola verso la loro destinazione, aumentando di numero man mano che l'utente si avvicina alla destinazione.Targeting per computer di orientamento simulatore spaziale con quadrante concentrico
È solo necessario rendere i quadrati per i punti davanti alla nave, poiché è tutto ciò che è visibile all'utente. Sulla loro strada verso una destinazione, il computer della nave dovrebbe piazzare quadrati sull'HUD che rappresentano punti fissi nello spazio tra te e la destinazione, che sono piccoli in lontananza e diventano più grandi man mano che i punti si avvicinano all'aereo.
che ho avuto un andare a implementare questo e non riesco a capirlo, utilizzando prevalentemente logaritmi (Math.log10(x)
e tali). Ho cercato di ottenere la posizione della nave in "spazio logaritmico" per scoprire da quale indice iniziare quando disegno i quadrati, ma poi il fatto che ho solo una distanza dalla destinazione per lavorare confonde la questione, specialmente quando considera che il numero di quadrati deve variare dinamicamente per assicurarsi che rimangano fissi nelle posizioni giuste nello spazio (cioè i quadrati sono posizionati a intervalli di circa 200 prima di essere trasformati logaritmicamente).
Riguardo a ciò, ho avuto un'implementazione funzionante con la nave tra un inizio di 0.0d e la fine di 1.0d, sebbene l'implementazione non fosse così bella. Ad ogni modo, il problema si riduce essenzialmente alla natura 1d. Qualsiasi consiglio sarebbe apprezzato con questo problema, compresi possibili soluzioni alternative per ottenere lo stesso effetto o soluzioni.
(Inoltre, c'è un video di Youtube che mostra questo effetto: http://www.youtube.com/watch?v=79F9Nj7GgfM&t=3m5s)
Cheers,
Chris
Edit: riformulato l'intera questione.
Edit: nuovo codice banco di prova:
package st;
import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferStrategy;
import java.text.DecimalFormat;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class StUI2 extends JFrame {
public static final double DEG_TO_RAD = Math.PI/180.0d;
public static final DecimalFormat decimalFormat = new DecimalFormat("0.0000");
public static final Font MONO = new Font("Monospaced", Font.PLAIN, 10);
public class StPanel extends Canvas {
protected final Object imgLock = new Object();
protected int lastWidth = 1, lastHeight = 1;
protected boolean first = true;
protected Color bgColour = Color.DARK_GRAY, gridColour = Color.GRAY;
double shipWrap = 700;
double shipFrame = 100;
double shipPos = 0;
long lastUpdateTimeMS = -1;
long currUpdateTimeMS = -1;
public StPanel() {
setFocusable(true);
setMinimumSize(new Dimension(1, 1));
setAlwaysOnTop(true);
}
public void internalPaint(Graphics2D g) {
synchronized (imgLock) {
if (lastUpdateTimeMS < 0) {
lastUpdateTimeMS = System.currentTimeMillis();
}
currUpdateTimeMS = System.currentTimeMillis();
long diffMS = currUpdateTimeMS - lastUpdateTimeMS;
g.setFont(MONO);
shipPos += (60d * ((double)diffMS/1000));
if (shipPos > shipWrap) {
shipPos = 0d;
}
double shipPosPerc = shipPos/shipWrap;
double distToDest = shipWrap - shipPos;
double compression = 1000d/distToDest;
g.setColor(bgColour);
Dimension d = getSize();
g.fillRect(0, 0, (int)d.getWidth(), (int)d.getHeight());
//int amnt2 = (int)unlog10((1000d/distToDest));
g.setColor(Color.WHITE);
g.drawString("shipPos: " + decimalFormat.format(shipPos), 10, 10);
g.drawString("distToDest: " + decimalFormat.format(distToDest), 10, 20);
g.drawString("shipWrap: " + decimalFormat.format(shipWrap), 150, 10);
int offset = 40;
g.setFont(MONO);
double scalingFactor = 10d;
double dist = 0;
int curri = 0;
int i = 0;
do {
curri = i;
g.setColor(Color.GREEN);
dist = distToDest - getSquareDistance(distToDest, scalingFactor, i);
double sqh = getSquareHeight(dist, 100d * DEG_TO_RAD);
g.drawLine(30 + (int)dist, (offset + 50) - (int)(sqh/2d), 30 + (int)dist, (offset + 50) + (int)(sqh/2d));
g.setColor(Color.LIGHT_GRAY);
g.drawString("i: " + i + ", dist: " + decimalFormat.format(dist), 10, 120 + (i * 10));
i++;
} while (dist < distToDest);
g.drawLine(10, 122, 200, 122);
g.drawString("last/i: " + curri + ", dist: " + decimalFormat.format(dist), 10, 122 + (i * 10));
g.setColor(Color.MAGENTA);
g.fillOval(30 + (int)shipPos, offset + 50, 4, 4);
lastUpdateTimeMS = currUpdateTimeMS;
}
}
public double getSquareDistance(double initialDist, double scalingFactor, int num) {
return Math.pow(scalingFactor, num) * num * initialDist;
}
public double getSquareHeight(double distance, double angle) {
return distance/Math.tan(angle);
}
/* (non-Javadoc)
* @see java.awt.Canvas#paint(java.awt.Graphics)
*/
@Override
public void paint(Graphics g) {
internalPaint((Graphics2D)g);
}
public void redraw() {
synchronized (imgLock) {
Dimension d = getSize();
if (d.width == 0) d.width = 1;
if (d.height == 0) d.height = 1;
if (first || d.getWidth() != lastWidth || d.getHeight() != lastHeight) {
first = false;
// remake buf
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
//create an object that represents the device that outputs to screen (video card).
GraphicsDevice gd = ge.getDefaultScreenDevice();
gd.getDefaultConfiguration();
createBufferStrategy(2);
lastWidth = (int)d.getWidth();
lastHeight = (int)d.getHeight();
}
BufferStrategy strategy = getBufferStrategy();
Graphics2D g = (Graphics2D)strategy.getDrawGraphics();
internalPaint(g);
g.dispose();
if (!strategy.contentsLost()) strategy.show();
}
}
}
protected final StPanel canvas;
protected Timer viewTimer = new Timer(1000/60, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
canvas.redraw();
}
});
{
viewTimer.setRepeats(true);
viewTimer.setCoalesce(true);
}
/**
* Create the applet.
*/
public StUI2() {
JPanel panel = new JPanel(new BorderLayout());
setContentPane(panel);
panel.add(canvas = new StPanel(), BorderLayout.CENTER);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(800, 300);
setTitle("Targetting indicator test #2");
viewTimer.start();
}
public static double unlog10(double x) {
return Math.pow(10d, x);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
StUI2 ui = new StUI2();
}
});
}
}
1) Non mescolare Swing ('JApplet') e AWT (componenti' Canvas'). 2) Un'applet è leggermente più difficile da testare per gli altri. Si prega di considerare lo sviluppo utilizzando un'applicazione/applet ibrida. 3) Hai una domanda? Che cos'è? –
OK. Ora ho eseguito il codice. Oltre alla domanda, non sono ancora chiaro su cosa dovrebbe accadere. I punti rosso e giallo dovrebbero essere allineati? Anche il mestiere magenta si muove da sinistra a destra. Il modello giallo è presumibilmente ciò che il pilota vede dalla finestra frontale (sarebbe proiettato sulla parete destra dalla nostra prospettiva)? –
Sì, sarebbe l'ideale se i punti rosso e giallo fossero allineati. Devo produrre una piccola sottosezione dei punti rossi, che * dovrebbe * essere i punti gialli. Dovrebbero rimanere in punti fissi nello spazio sul percorso target relativo alla distanza dal bersaglio. –