0

我需要一些家庭作业的帮助。明天我们有一个“线程秀”在课堂上,我的差不多完成了。我让企业号航空母舰在一艘克林贡飞船后面飞行,在柯克船长大喊命令的同时发射光子。它工作得很好,但我不喜欢的一件事是我不能很好地控制光子的轨迹。由于我模拟运动的方式是 += x 和 y,因此无论克林贡船位于何处,它似乎都朝着相同的方向前进。(我确实设法让它向左、向右、向上或向下射击,只是不完全朝向飞船。理想情况下,我希望它射击到我创建 PhotonThread 时飞船最后所在的位置。(它不应该总是如此击中它。只是一个线性轨迹..))

这是我的代码的一部分,我非常感谢有关如何解决该问题的任何帮助或指示。

 /**
 * 
 */
package actualProgram;

import java.applet.Applet;
import java.applet.AudioClip;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URI;

/**
 * @author Stryk3r
 *
 */
public class MainApp extends Thread {

    static boolean deflector, lockEnemy, phasersFire, photonEffect, redAlert, redAlertEffect = false;
    static int EnterpriseX;
    static int EnterpriseY;
    static int EnterpriseSpeed;
    static AudioClip sound;
    static int KlingonX;
    static int KlingonY;
    static int KlingonSpeed;
    static int KlingonDirectionX;
    static int KlingonDirectionY;
    static String KlingonImage = "images/FirstEditKlingon.png";

    static String soundPath;


    public static void main(String[] args) {


        new EnterpriseThread(0,0, "images/FirstEditNCC.png").start();

        try {
            sleep(800);
        } catch (InterruptedException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }


        new KlingonThread(400,400, "images/FirstEditKlingon.png").start();

        try {
            sleep(300);
        } catch (InterruptedException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }

        new SoundThread().start();


        while (true) {
            try {
                sleep(10);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }


            if (distanceToKlingon(EnterpriseX, EnterpriseY, MainApp.KlingonX, MainApp.KlingonY)  <200.) {


                try {
                    sleep(300);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                new PhotonThread(EnterpriseX+75, EnterpriseY+30,"images/Photon.png").start();
                new PhotonSound().start();



            }
            try {
                sleep(300);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }


    }


    private static double distanceToKlingon(int x1, int y1, int x2, int y2) {
        return Math.sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1));
    }

}

这是 PhotonThread 代码的一部分:

    public void run() {
        super.run();

        int direccionX = 1, direccionY =1;
//      Random random = new Random();

        while(true) {



            try {
                sleep(1);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            int klingonX = MainApp.KlingonX;
            int klingonY = MainApp.KlingonY;

            if (this.x < klingonX)
                direccionX = 1;
            else if (this.x > klingonX)
                direccionX = -1;

            if (this.y < klingonY)
                direccionY = 1;
            else if (this.y > klingonY)
                direccionY = -1;

//          this.x = this.pendienteX;
//          this.y = this.pendienteY;


            while (true) {

                this.x += 10 * direccionX;//la constante es la velocidad
                this.y += 10 * direccionY;//la constante es la velocidad

                try {
                    sleep(10);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

                if (this.x > Toolkit.getDefaultToolkit().getScreenSize().width
                        || this.y > Toolkit.getDefaultToolkit().getScreenSize().height || this.x < 0 || this.y <0) {
                    //bolitaJframe.hide();
                    bolitaJframe.dispose();
//                  this.stop();

                }

                if (distanceToKlingon(this.x, this.y, klingonX, klingonY)< 60.0) {
                    //MainApp.KlingonImage = "images/roja.png";
                    bolitaJframe.setVisible(false);

                    try {
                        sleep(300);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    System.out.println("ship destroyed");
                    bolitaJframe.dispose();


                }

                bolitaJframe.setLocation(this.x, this.y);
            }


        }
    }
4

1 回答 1

0

当您根据另一艘船的位置设置directionXdirectionY变量时,您在每个方向上移动的“数量”没有变化。你应该研究一些三角函数来为你解决这个问题。

我不想为你做作业,但这应该会让你走上正确的道路。考虑一下如何将两点之间的直线分解为与 x 轴和 y 轴相对应的分量。

编辑

两点之间的直线部分由其斜率定义,因此这肯定很重要。考虑到您的发射船是您坐标系的原点,而被发射的船是您与原点的线相交的点。如果该船位于 (3, 4)(例如),则该线的斜率为 4/3。如果您想直接移动到船上,您将拥有directionX = 3并且directionY = 4

然而,这并不完全是您想要的,因为您宁愿以恒定的速度移动而不是四处跳动。如果您希望整体速度为 1,则需要C*(directionX**2 + directionY**2) == 1C 为常数。C*(9 + 16) == 1 -> C == 1/25. 因此,您希望将方向按 1/25 缩放。这看起来像directionX *= C; directionY *= C请记住,您C每次移动时都会重新计算。

这不是最稳健或最技术性的方法,但它避免使用除勾股定理之外的三角函数或恒等式。我肯定会建议您在有时间的时候更多地研究这方面的事情。

于 2013-10-09T15:56:45.053 回答