【问题标题】:how to make an enemy shoot in the players direction如何让敌人朝玩家方向射击
【发布时间】:2015-05-11 21:09:53
【问题描述】:

我正在制作坦克游戏。我已经知道如何让我的敌人朝玩家的方向移动,但我不太确定如何让它朝玩家的方向射击。坦克的射手也必须朝着敌人射击的方向旋转。 (子弹必须从射手身上“出来”)

这个要旋转,我已经写了代码让玩家的射手跟随鼠标的位置

我把射手放在坦克身上

我们使用黑色圆圈作为子弹:(ObjWHObjectWidhtHeight

`public void draw(Graphics2D g)
    {
        g.setColor(Color.BLACK);
        g.fillOval((int) (x_pos - objWH), (int) (y_pos - objWH), (int)  objWH, 
        (int) objWH);
    }`

我想将敌人的子弹存储在 ArrayLists 中,每个敌人都需要自己的 ArrayList。

`package tanks;

import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;
import java.util.ArrayList;

import javax.swing.ImageIcon;
import javax.swing.Timer;

import menu.PlayPanel;
import menu.Tanks;

    public class Enemy extends Game_Object {

        private static final Timer shootTimer = null;
        private PlayPanel panel;

        int launchPosition;

        double distance;
        double deltaX, deltaY;

        private ArrayList<EnemyBullet> enemyBullets;

        public Enemy(PlayPanel panel)
        {
            this.panel = panel;
            speed = 3 + rand.nextInt(5); 
            maxHP = 80 + rand.nextInt(40); 
            HP = maxHP;
            angle = 0; 
            angleCannon = 0;
            objWH = 65;

        }

    public void launch() 
    {
        launchPosition = rand.nextInt(3);

            switch(launchPosition){
            case 0: //up
                x_pos = rand.nextInt(Tanks.getSchermBreedte());
                y_pos =  0;
                break;

            case 1: //left
                x_pos = 0;
                y_pos = rand.nextInt(Tanks.getSchermHoogte());
                break;

            case 2: //downside
                x_pos = rand.nextInt(Tanks.getSchermBreedte());
                y_pos = Tanks.getSchermHoogte();
                break;


            case 3: //right
                x_pos = Tanks.getSchermBreedte();
                y_pos = rand.nextInt(Tanks.getSchermHoogte());
                break;  
            }
        }

        public void move()  
        {
            if (Player.get_x_pos() >= Enemy.get_x_pos())
            {
                deltaX =  Player.get_x_pos() - Enemy.get_x_pos();
            }
            else //if(Player.get_x_pos() <= Enemy.get_x_pos())
            {
                deltaX = Enemy.get_x_pos() - Player.get_x_pos();
            }

            if(Player.get_y_pos() >= Enemy.get_y_pos())
            {
                deltaY = Player.get_y_pos() - Enemy.get_y_pos();
            }
            else //if(Player.get_y_pos() <= Enemy.get_y_pos())
            {
                deltaY =  Enemy.get_y_pos() - Player.get_y_pos();
            }

            distance =  Math.pow(Math.pow(deltaX, deltaX) + Math.pow(deltaY,            
                deltaY), 1/2);

            x_move = speed*(deltaX/distance);
            y_move = speed*(deltaY/distance);

            x_pos += x_move;
            y_pos += y_move;
        }


        private static double get_x_pos()  
        {
            return Enemy.x_pos;
        }           

        private static double get_y_pos()
        {
            return Enemy.y_pos;
        }


        public void shoot()
        {

            enemyBullets = new ArrayList<EnemyBullet>();
        }

        public void touched()
        {
            if(HP>0)
                HP -= (5 + rand.nextInt(10));   

            if(HP <= 0)
                dood = true;
        }

        public void draw(Graphics2D g2d)
        {
            body = new ImageIcon(getClass().getResource("/objects/enemy 
                tank.png")).getImage();
            shooter = new ImageIcon(getClass().getResource("/objects/enemy 
                shooter.png")).getImage();
        }
    }`

【问题讨论】:

  • 我还开设了一个课程EnemyBullet ,因为在我看来,在 1 个(单独的)课程中制作关于子弹的所有内容实际上更符合逻辑,到目前为止我在课程中编写的唯一代码是 public void draw(Graphics2D g)
  • 考虑发布/移动您的问题here
  • 如果我理解的话,你的坦克可以朝玩家的方向移动,但他们的射手不会集中注意力?
  • 我还没有编写敌人射击的代码,这基本上是我的问题,因为我现在真的不知道如何让它a)聚焦和b)射击
  • @Lola 对于重点,arctan 就是你所需要的(正如 Mike Robinson 所说)。对于射击,基本上你必须根据坦克方向定义一个速度向量(vx=k*cos(angle)vy=k*sin(angle),其中k 表示子弹的速度,angle 表示射手的方向),然后更新子弹与它的位置(bullet.x += vxbullet.y += vy)。

标签: java


【解决方案1】:

嗯,它的本质是“基本几何”,特别是函数ATAN2(谷歌搜索...)

想象有一个直角三角形,你的坦克在一个顶点,而敌人在斜边的另一端。 ATAN2 可以告诉您该向量的角度(以及它位于哪个“象限”中)。通常,计算是以弧度为单位的,而不是度数。

为了实现逼真的运动,你的坦克的逻辑必须定期计算这个角度,然后以一定的增量转向。如果现在角度足够小,子弹会击中目标,坦克就会开火。

我不会为您提供“代码编写服务”,但这是它的基本数学原理。

【讨论】:

    【解决方案2】:

    我建议您查看一些有关如何使用 2D 向量进行计算的示例。我不太确定您正在使用哪个框架。通常游戏引擎或框架都有向量类。

    向量看起来像这样 (x,y)。所以你有你需要的两个坐标。如果你从它应该去的位置(v2)中减去你的子弹必须开始的位置(v1),你会得到一个方向向量。 计算如下。

    v3.x = v2.x - v1.x v3.y = v2.y - v1.y

    这个向量可以乘以一个速度因子。然后你只需添加子弹的位置向量。

    在方法之间进行插值的常用方法是 lerp(http://en.wikipedia.org/wiki/Linear_interpolation) 或 slerp。这些是算法。你可以用它来旋转。

    这是有用的还是完全没用的?只要我能,我很高兴为您提供进一步的帮助。

    【讨论】:

      【解决方案3】:

      物体向某个方向旋转的基本逻辑,本质上是让物体看向那个方向,可以表示如下:

      private double calculateAngle(double vecX, double vecY) {
          double angle = Math.toDegrees(Math.atan(vecY / vecX));
          return vecX > 0 ? angle : 180 + angle;
      }
      

      其中vecXvecY 是向量(方向)的xy 值。这可以通过从“射手”的x, y 值中减去敌人的x, y 值来获得。最后,只需将旋转变换与从方法返回的角度应用到您的“射手”对象

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-04-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-29
        • 1970-01-01
        • 2016-05-11
        相关资源
        最近更新 更多