Heim  >  Artikel  >  Java  >  „Java Mini Game Implementation“: Panzerschlacht (Fortsetzung 2)

„Java Mini Game Implementation“: Panzerschlacht (Fortsetzung 2)

黄舟
黄舟Original
2016-12-27 11:59:491399Durchsuche

"Java Mini Game Implementation": Panzerschlacht

"Java Mini Game Implementation": Panzerschlacht (Fortsetzung 1)

Blogbeitrag "Java Mini Game Implementation": Panzerschlacht (Fortsetzung 1) ) wurde implementiert, damit der Panzer eine Kugel abfeuern kann. In diesem Blogbeitrag werden auf dieser Basis weitere Funktionen implementiert.

Vollständige Funktion: Panzer feuert mehrere Kugeln ab

Mit der Grundlage eines Panzers, der eine Kugel abfeuert, ist das Abfeuern mehrerer Kugeln ganz einfach. Sie müssen nur einen Container zur TankClien-Klasse hinzufügen, um ihn zu speichern . Nur mehrere Kugeln. Da auch das Fassungsvermögen des Behälters begrenzt ist, können wir ihn nicht ständig füllen. Daher haben wir in der Bullet-Klasse ein Live-Attribut für das Bullet-Objekt eingeführt, um festzustellen, ob das Bullet noch am Leben ist. Die Feststellung, ob die Kugel noch am Leben ist, basiert darauf, ob die Position der Kugel außerhalb der Grenzen liegt.

Nur ​​der relevante Code zum Abschließen dieser Funktion wird unten veröffentlicht

TankClient.java

<code class="hljs cs">    private List<missile> missiles = new ArrayList<missile> ();
 
    public List<missile> getMissiles() {
        return missiles;
    }
    @Override
    public void paint(Graphics g) {
        //直接调用坦克类的draw方法
        tk.draw(g); 
        //画子弹
        for(int i=0;i<missiles.size();i++){ code="" missile="" ms="missiles.get(i);"></missiles.size();i++){></missile></missile></missile></code>

Missile.java-Klasse

In der Move-Methode Anhand der Position der Kugel kann festgestellt werden, ob die Kugel noch am Leben ist.

<code class="hljs cs"><code class="hljs cs">    public class Missile {
 
        private void move() {
            if(dir==Direction.L){//L,LU,U,RU,R,RD,D,LD,STOP
                x -= XSPEED;
            }
            else if(dir==Direction.LU){
                x -= XSPEED;
                y -= YSPEED;
            }
            else if(dir==Direction.U){
                y -= YSPEED;
            }
            else if(dir==Direction.RU){
                x += XSPEED;
                y -= YSPEED;
            }
            else if(dir==Direction.R){
                x += XSPEED;
            }
            else if(dir==Direction.RD){
                x += XSPEED;
                y += YSPEED;
            }
            else if(dir==Direction.D){
                y += YSPEED;
            }
            else if(dir==Direction.LD){
                x -= XSPEED;
                y += YSPEED;
            }
 
            //根据子弹所在的位置x,y来判断子弹是否还存活在
            if(x<0||x>TankClient.GAME_WIDTH||y<0||y>TankClient.GAME_HEIGHT){
                live = false;
            }
        }
        public boolean isLive() {   
            return live;
        }
    }
</code></code>

Der Inhalt der Tank.java-Datei lautet wie folgt:

In der Tank-Klasse wird in der keyPressed-Methode jedes Mal, wenn die Strg-Taste gedrückt wird, eine Kugel abgefeuert.

<code class="hljs cs"><code class="hljs cs">    public class Tank {
 
        //记录键盘的按键情况
        public void keyPressed(KeyEvent e){
            int key=e.getKeyCode();
            //System.out.println(key);
            switch(key){
            case 17:
                tc.getMissiles().add(fire());
                break;
            case KeyEvent.VK_LEFT:
                b_L=true;
                break;
            case KeyEvent.VK_UP:
                b_U=true;
                break;
            case KeyEvent.VK_RIGHT:
                b_R=true;
                break;
            case KeyEvent.VK_DOWN:
                b_D=true;
                break;
            }
            //根据上面的按键情况,确定坦克即将要运行的方向
            moveDirection();
        }
 
    }
</code></code>

Link zum vollständigen Code-Download: http://download.csdn.net/detail/u010412719/9555292

Vollständige Funktion: Lösen Sie das Problem des Panzerübertritts

Panzer überquert die Grenze Das Problem ist relativ einfach. Sie müssen nur feststellen, ob der Standort des Tanks die Grenze überschreitet. Wenn dies der Fall ist, stellen Sie seine Position auf die Grenzposition ein.

Der Implementierungscode lautet wie folgt:

<code class="hljs cs"><code class="hljs cs">        /*
         * 函数功能:处理坦克越界问题
         * */
        private void dealTankBorder() {
            if(x<0){
                x = 0;
            } 
            else if(x > TankClient.GAME_WIDTH-this.WIDTH){
                x = TankClient.GAME_WIDTH-this.WIDTH ;
            } 
            if(y<0){
                 y = 0;
            }
            else if(y>TankClient.GAME_WIDTH - this.HEIGHT){
                 y = TankClient.GAME_WIDTH - this.HEIGHT;
            }
        }</code></code>

Die obige Funktion kann am Ende der move()-Methode aufgerufen werden.

Vollständige Funktion: feindliche Panzer hinzufügen

Die zuvor implementierten Funktionen bestehen darin, einen Panzer auf der Benutzeroberfläche zu bewegen, Kugeln abzufeuern usw.

Jetzt sind wir damit fertig, der Benutzeroberfläche einen feindlichen Panzer hinzuzufügen.

Es gibt zwei Möglichkeiten, feindliche Panzer zu implementieren

1. Die erste besteht darin, eine neue EnemyTank-Klasse zu erstellen,

2 Eigenschaft der Klasse A, die den Typ dieses Tanks angibt.

Da wir der Einfachheit halber bereits eine Tankklasse haben, ist hier die zweite Methode: Fügen Sie der ursprünglichen Tankklasse ein Attribut hinzu, um den Tanktyp anzugeben.

Der neu hinzugefügte Inhalt in Tank.java umfasst hauptsächlich

<code class="hljs cs"><code class="hljs java">    //添加一个属性,表示此坦克是好还是坏
        private boolean good;
 
    //更改下构造方法
 
        public Tank(int x, int y,boolean good) {
            this.x = x;
            this.y = y;
            this.good = good;
        }
 
        public Tank(int x, int y,boolean good, TankClient tc) {
            this(x,y,good);
            this.tc = tc;
        }
    //根据坦克的类型给出不同的颜色
        public void draw(Graphics g){
 
            Color c = g.getColor();
            if(good){
                g.setColor(Color.RED);
            }
            else{
                g.setColor(Color.BLUE);
            }
 
            g.fillOval(x, y, WIDTH, HEIGHT);
            g.setColor(c);
            //画一个炮筒
            drawGunBarrel(g);
 
            move();//根据键盘按键的结果改变坦克所在的位置
        }

Es gibt keine Änderung in der Missile-Klasse.

Die Inhalte, die dem General Manager TankClient.java hinzugefügt werden müssen, sind:

1. Erstellen Sie zwei neue Tankobjekte

<code class="hljs cs"><code class="hljs cs">private Tank tk=new Tank(50,50,true,this);
 
private Tank enemy = new Tank(100,100,false,this);</code></code>

Zeichnen Sie zwei Tankobjekte im Farbmethodentank

<code class="hljs cs"><code class="hljs cs">    @Override
    public void paint(Graphics g) {
        //直接调用坦克类的draw方法
        tk.draw(g); 
 
        enemy.draw(g);
        //画子弹
        for(int i=0;i<missiles.size();i++){ code="" missile="" ms="missiles.get(i);"></missiles.size();i++){></code></code>

„Java Mini Game Implementation“: Panzerschlacht (Fortsetzung 2)

Das Obige hat die Funktion zum Hinzufügen feindlicher Panzer implementiert, ihnen jedoch noch keine zufällige Bewegung hinzugefügt.

Abgeschlossene Funktion: Kugeln töten feindliche Panzer

Nach der obigen Implementierung haben wir einen albernen feindlichen Panzer, der sich nicht bewegt und keine Kugeln abfeuern kann, aber wir können ihn auch nicht bekämpfen. Töte ihn Töte als nächstes den Panzer. Haha, ist es nicht etwas interessanter?

Analyse:

1. Da das Geschoss den feindlichen Panzer tötete, wurde gemäß der objektorientierten Idee eine hitTank-Methode zur Geschossklasse hinzugefügt

<code class="hljs cs"><code class="hljs cs"><code>public boolean hitTank(Tank t){
 
}
</code></code></code>

2. Wie soll die hitTank-Methode also feststellen, ob die Kugel den Panzer getroffen hat? ? Dabei handelt es sich um ein Kollisionsproblem. Da unsere Kugeln und Panzer beide Rechtecke sind, wird das Kollisionsproblem stark vereinfacht. Wir müssen nur feststellen, ob sich die beiden Rechtecke überlappen. Wenn ja, wird davon ausgegangen, dass eine Kollision stattgefunden hat und die Kugel den Panzer getroffen hat.

Fügen Sie daher in der Missile-Klasse und der Tank-Klasse eine getRect()-Methode hinzu, um das rechteckige Flächenobjekt zurückzugeben, in dem sich die Kugel und der Panzer befinden.

<code class="hljs cs"><code class="hljs cs"><code>public Rectangle getRect(){
        return new Rectangle(x, y, WIDTH, HEIGHT);
}
</code></code></code>

3. Wenn die Kugel den Panzer trifft, sollten sowohl die Kugel als auch der Panzer verschwinden. Daher muss eine boolesche Variable in den Tank eingeführt werden, um zu bestimmen, ob der Tank lebt

<code class="hljs cs"><code class="hljs cs"><code class="hljs java">    public boolean hitTank(Tank t){
        //首先判断此坦克是否是存活的,如果是死的,就不打了
        if(!t.isLive()){
            return false;
        }
        if(this.getRect().intersects(t.getRect())){//判断是否有碰撞
            //碰撞之后,子弹和该坦克就应该都死了
            this.live = false;//子弹死了
            t.setLive(false);//坦克死了
            return true;
        }
        else{
            return false;
        }
    }</code></code></code>

Ob die Kugel verschwindet, wurde in der vorherigen Version behandelt, aber der Tank verschwindet in dieser Version Die aktuelle Verarbeitungsmethode ist Ohne es zu zeichnen, das heißt, in der Zeichenmethode wird zunächst überprüft, ob das Objekt lebt. Wenn es lebendig ist, zeichnen Sie es.

Der Code lautet wie folgt:

<code class="hljs cs"><code class="hljs cs"><code class="hljs cs">        public void draw(Graphics g){
            if(!live){      //判断坦克是否存活,如果死了,则不绘画出来,直接返回     
                return ;
            }
            Color c = g.getColor();
            if(good){
                g.setColor(Color.RED);
            }
            else{
                g.setColor(Color.BLUE);
            }
 
            g.fillOval(x, y, WIDTH, HEIGHT);
            g.setColor(c);
            //画一个炮筒
            drawGunBarrel(g);
 
            move();//根据键盘按键的结果改变坦克所在的位置
        }
</code></code></code>

Veröffentlichen Sie abschließend den vollständigen Code der Panzerklasse, der Raketenklasse und der TankClient-Klasse:

Panzerklasse

<code class="hljs cs"><code class="hljs cs"><code class="hljs java">    public class Tank {
        //坦克所在的位置坐标
        private int x;
        private int y;
 
        //坦克的高度和宽度
        private static final int WIDTH = 30;
        private static final int HEIGHT = 30;
 
        //定义两个常量,表示运动的速度
        private static final int XSPEED = 5;
        private static final int YSPEED = 5;
 
        //定义四个布尔类型变量来记录按键的情况,默认状态下为false,表示没有键按下
        private boolean b_L,b_U,b_R,b_D;
 
        //添加一个属性,表示此坦克是好还是坏
        private boolean good;
 
        public boolean isGood() {
            return good;
        }
 
        //用来标识此坦克对象是否存活
        private boolean live =true;
 
        public boolean isLive() {
            return live;
        }
 
        public void setLive(boolean live) {
            this.live = live;
        }
        //定义一个枚举类型来表示运行的方向  
        public enum Direction{
            L,LU,U,RU,R,RD,D,LD,STOP
        }
        //定义一个变量来表示坦克要运行的方向,初始状态为STOP
        private Direction dir = Direction.STOP;
 
        //炮筒方向
        private Direction ptDir = Direction.D;
 
        private TankClient tc;
 
        public Tank(int x, int y,boolean good) {
            this.x = x;
            this.y = y;
            this.good = good;
        }
 
        public Tank(int x, int y,boolean good, TankClient tc) {
            this(x,y,good);
            this.tc = tc;
        }
 
        public void draw(Graphics g){
            if(!live){      //判断坦克是否存活,如果死了,则不绘画出来,直接返回     
                return ;
            }
            Color c = g.getColor();
            if(good){
                g.setColor(Color.RED);
            }
            else{
                g.setColor(Color.BLUE);
            }
 
            g.fillOval(x, y, WIDTH, HEIGHT);
            g.setColor(c);
            //画一个炮筒
            drawGunBarrel(g);
 
            move();//根据键盘按键的结果改变坦克所在的位置
        }
 
        private void drawGunBarrel(Graphics g) {
            int centerX = this.x + this.WIDTH/2;
            int centerY = this.y + this.HEIGHT/2;
 
            if(ptDir==Direction.L){//L,LU,U,RU,R,RD,D,LD,STOP
                g.drawLine(centerX, centerY, x, y + HEIGHT/2);
            }
            else if(ptDir==Direction.LU){
                g.drawLine(centerX, centerY, x, y );
            }
            else if(ptDir==Direction.U){
                g.drawLine(centerX, centerY, x+ WIDTH/2, y );
            }
            else if(ptDir==Direction.RU){
                g.drawLine(centerX, centerY, x + WIDTH, y );
            }
            else if(ptDir==Direction.R){
                g.drawLine(centerX, centerY, x+ WIDTH, y + HEIGHT/2);
            }
            else if(ptDir==Direction.RD){
                g.drawLine(centerX, centerY, x+ WIDTH, y + HEIGHT);
            }
            else if(ptDir==Direction.D){
                g.drawLine(centerX, centerY, x+ WIDTH/2, y + HEIGHT);
            }
            else if(ptDir==Direction.LD){
                g.drawLine(centerX, centerY, x, y + HEIGHT);
            }
 
        }
 
        //记录键盘的按键情况
        public void keyPressed(KeyEvent e){
            int key=e.getKeyCode();
            //System.out.println(key);
            switch(key){
//          case 17://避免因Ctrl一直按下,一直发射子弹,因此将这一功能放入keyReleased方法中了
//              tc.getMissiles().add(fire());
//              break;
            case KeyEvent.VK_LEFT:
                b_L=true;
                break;
            case KeyEvent.VK_UP:
                b_U=true;
                break;
            case KeyEvent.VK_RIGHT:
                b_R=true;
                break;
            case KeyEvent.VK_DOWN:
                b_D=true;
                break;
            }
            //根据上面的按键情况,确定坦克即将要运行的方向
            moveDirection();
        }
 
        //键盘按键松下时,也要进行记录
        public void keyReleased(KeyEvent e) {
            int key=e.getKeyCode();
            switch(key){
            case 17:
                tc.getMissiles().add(fire());
                break;
            case KeyEvent.VK_LEFT:
                b_L=false;
                break;
            case KeyEvent.VK_UP:
                b_U=false;
                break;
            case KeyEvent.VK_RIGHT:
                b_R=false;
                break;
            case KeyEvent.VK_DOWN:
                b_D=false;
                break;
            }
        }
 
        //根据键盘的按键情况来确定坦克的运行方向
        private void moveDirection() {//L,LU,U,RU,R,RD,D,LD,STOP
            if(b_L&&!b_U&&!b_R&&!b_D){
                dir = Direction.L;
            }
            else if(b_L&&b_U&&!b_R&&!b_D){
                dir = Direction.LU;
            }
            else if(!b_L&&b_U&&!b_R&&!b_D){
                dir = Direction.U;
            }
            else if(!b_L&&b_U&&b_R&&!b_D){
                dir = Direction.RU;
            }
            else if(!b_L&&!b_U&&b_R&&!b_D){
                dir = Direction.R;
            }
            else if(!b_L&&!b_U&&b_R&&b_D){
                dir = Direction.RD;
            }
            else if(!b_L&&!b_U&&!b_R&&b_D){
                dir = Direction.D;
            }
            else if(b_L&&!b_U&&!b_R&&b_D){
                dir = Direction.LD;
            }
            else{//其它所有情况,都是不动
                dir = Direction.STOP;
            }
            //将坦克方向赋值给炮筒方向
            if(dir!=Direction.STOP){
                ptDir = dir;
            }
 
        }
 
        //上面有运行方向,但是还缺少具体的运行细节,例如:假设是按下了右键,则应该横坐标x+=XSPEED;
        private void move(){
            if(dir==Direction.L){//L,LU,U,RU,R,RD,D,LD,STOP
                x -= XSPEED;
            }
            else if(dir==Direction.LU){
                x -= XSPEED;
                y -= YSPEED;
            }
            else if(dir==Direction.U){
                y -= YSPEED;
            }
            else if(dir==Direction.RU){
                x += XSPEED;
                y -= YSPEED;
            }
            else if(dir==Direction.R){
                x += XSPEED;
            }
            else if(dir==Direction.RD){
                x += XSPEED;
                y += YSPEED;
            }
            else if(dir==Direction.D){
                y += YSPEED;
            }
            else if(dir==Direction.LD){
                x -= XSPEED;
                y += YSPEED;
            }
            else if(dir==Direction.STOP){
                //... nothing
            }
 
            //处理坦克越界问题
            dealTankBorder();       
        }
        /*
         * 函数功能:处理坦克越界问题
         * */
        private void dealTankBorder() {
            if(x<0){
                x = 0;
            } 
            else if(x > TankClient.GAME_WIDTH-this.WIDTH){
                x = TankClient.GAME_WIDTH-this.WIDTH ;
            } 
            if(y<0){
                 y = 0;
            }
            else if(y>TankClient.GAME_WIDTH - this.HEIGHT){
                 y = TankClient.GAME_WIDTH - this.HEIGHT;
            }
        }
 
        public Missile fire(){
            //计算子弹的位置,并利用炮筒的方向来new一个子弹对象
            int x = this.x +(this.WIDTH)/2 - (Missile.WIDTH)/2;
            int y = this.y + (this.HEIGHT)/2 -(Missile.HEIGHT)/2;
            Missile ms = new Missile(x,y,this.ptDir);
            return ms;
        }
        /*
         * 函数功能:得到坦克所在位置的矩形框
         * */
        public Rectangle getRect(){
            return new Rectangle(x, y, WIDTH, HEIGHT);
        }
 
    }</code></code></code>

Raketenklasse

Der Code lautet wie folgt

<code class="hljs cs"><code class="hljs cs"><code class="hljs java">    public class Missile {
 
        //定义两个常量,表示运动的速度
        private static final int XSPEED = 10;
        private static final int YSPEED = 10;
 
        //子弹所在的位置
        private int x;
        private int y;
 
        //坦克的高度和宽度
        public static final int WIDTH = 10;
        public static final int HEIGHT = 10;
 
        //子弹的运行方向
        private Direction dir;
 
        private boolean live = true;
 
        public Missile(int x, int y, Direction dir) {
            this.x = x;
            this.y = y;
            this.dir = dir;
        }
        public void draw(Graphics g){
            //如果该子弹不是存活的,则不进行绘图
            if(!live){
                return ;
            }
            Color c = g.getColor();
            g.setColor(Color.YELLOW);
            g.fillOval(x, y, WIDTH, HEIGHT);
            g.setColor(c);
            move();
        }
 
        private void move() {
            if(dir==Direction.L){//L,LU,U,RU,R,RD,D,LD,STOP
                x -= XSPEED;
            }
            else if(dir==Direction.LU){
                x -= XSPEED;
                y -= YSPEED;
            }
            else if(dir==Direction.U){
                y -= YSPEED;
            }
            else if(dir==Direction.RU){
                x += XSPEED;
                y -= YSPEED;
            }
            else if(dir==Direction.R){
                x += XSPEED;
            }
            else if(dir==Direction.RD){
                x += XSPEED;
                y += YSPEED;
            }
            else if(dir==Direction.D){
                y += YSPEED;
            }
            else if(dir==Direction.LD){
                x -= XSPEED;
                y += YSPEED;
            }
 
            //根据子弹所在的位置x,y来判断子弹是否还存活在
            if(x<0||x>TankClient.GAME_WIDTH||y<0||y>TankClient.GAME_HEIGHT){
                live = false;
            }
        }
        public boolean isLive() {   
            return live;
        }
 
        public Rectangle getRect(){
            return new Rectangle(x, y, WIDTH, HEIGHT);
        }
 
        public boolean hitTank(Tank t){
            //首先判断此坦克是否是存活的,如果是死的,就不打了
            if(!t.isLive()){
                return false;
            }
            if(this.getRect().intersects(t.getRect())){//判断是否有碰撞
                //碰撞之后,子弹和该坦克就应该都死了
                this.live = false;//子弹死了
                t.setLive(false);//坦克死了
                return true;
            }
            else{
                return false;
            }
        }
</code></code></code>

Der TankClient-Klassencode lautet wie folgt:

<code class="hljs cs"><code class="hljs cs"><code class="hljs java">    /*
     * 此版本添加了子弹打死敌对坦克
     * */
    public class TankClient extends Frame{
 
        public final static int GAME_WIDTH=600;
        public final static int GAME_HEIGHT=600;
 
 
        private Tank tk=new Tank(50,50,true,this);
 
        private Tank enemy = new Tank(100,100,false,this);
 
        private List<missile> missiles = new ArrayList<missile> ();
 
        public List<missile> getMissiles() {
            return missiles;
        }
 
        private Image offScreenImage = null;
 
        public static void main(String[] args) {
            new TankClient().launchFrame();
        }
 
        @Override
        public void update(Graphics g) {
            if (offScreenImage == null) {
                offScreenImage = this.createImage(GAME_WIDTH, GAME_HEIGHT);
            }
            Graphics goffScreen = offScreenImage.getGraphics();// 重新定义一个画虚拟桌布的画笔//
            Color c = goffScreen.getColor();
            goffScreen.setColor(Color.darkGray);
            goffScreen.fillRect(0, 0, GAME_WIDTH, GAME_HEIGHT);
            goffScreen.setColor(c);
            paint(goffScreen);
            g.drawImage(offScreenImage, 0, 0, null);
        }
 
        @Override
        public void paint(Graphics g) {
            //直接调用坦克类的draw方法
            tk.draw(g);         
            enemy.draw(g);
            //画子弹
            for(int i=0;i<missiles.size();i++){ 
            catch="" code="" extends="" implements="" interruptedexception="" keyevent="" keymonitor="" missile="" ms="missiles.get(i);" myrepaint="" new="" 
            override="" private="" public="" try="" void="" windowevent=""></missiles.size();i++){></missile></missile></missile></code></code></code>

Das Obige vervollständigt die Funktion des Panzers Sie feuern Kugeln ab, um feindliche Panzer zu treffen.

Noch nicht fertig, siehe nächster Blog-Beitrag für die verbleibenden Funktionen

Das Obige ist der Inhalt von „Java Mini Game Implementation“: Tank Battle (Fortsetzung 2). Bitte beachten Sie die chinesische PHP-Website (www.php.cn)!


Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn