我照着视频的讲解写了一个坦克大战的小代码,现在的问题是:按下发射键(J)之后,子弹不会自己飞行,
请各位高手给看看。
一共分了两部分
第一部分:
package game.tank;class Tank
{
// 1、确定tank的坐标,也就是起始位置;
int x = 0;
int y = 0;
// 方向
int direct ;
// 速度 
int speed = 2;
// 颜色
int color; public int getColor()
{
return color;
} public void setColor(int color)
{
this.color = color;
} public int getSpeed()
{
return speed;
} public void setSpeed(int speed)
{
this.speed = speed;
} public int getDirect()
{
return direct;
} public void setDirect(int direct)
{
this.direct = direct;
} public int getX()
{
return x;
} public void setX(int x)
{
this.x = x;
} public int getY()
{
return y;
} public void setY(int y)
{
this.y = y;
} // 2、要想使坦克可以动起来,需要一个构造函
public Tank(int x, int y)
{
this.x = x;
this.y = y;
}
}// 定义子弹
class Bullet implements Runnable
{
int x;
int y;
int direct;
int speed = 1;
public Bullet(int x,int y,int direct)
{
this.x = x;
this.y = y;
this.direct = direct;
}
@Override
public void run()
{
try
{
Thread.sleep(500);
}
catch (Exception e)
{
}
while(true)
{
switch(direct)
{
case 0:
y-=speed;
break;
case 1:
x+=speed;
break;
case 2:
y+=speed;
break;
case 3:
x-=speed;
break;
}
}
}
}// 定义我自己的坦克
class Mytank extends Tank
{
Bullet b = null;
public Mytank(int x, int y)
{
super(x, y);
}
// 开火
public void fire()
{
switch(this.direct)
{
case 0:
b = new Bullet(x+10, y, 0);
break;
case 1:
b = new Bullet(x+30, y+10, 1);
break;
case 2:
b = new Bullet(x+10, y+30, 2);
break;
case 3:
b = new Bullet(x, y+10, 3);
break;
}
Thread t = new Thread(b);
t.start();
}

public void moveup()
{
y -= speed;
} public void movedown()
{
y += speed;
} public void moveright()
{
x += speed;
} public void moveleft()
{
x -= speed;
}
}class Enemytank extends Tank
{ public Enemytank(int x, int y)
{
super(x, y);
}

}第二部分package game.tank;import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Vector;public class DrawTank extends JFrame
{
Mypanel mypanel ; public DrawTank()
{
mypanel = new Mypanel();
mypanel.setBackground(Color.black);

Thread t = new Thread(mypanel);
t.start();

this.add(mypanel);
this.addKeyListener(mypanel);
this.setSize(500, 400);
this.setLocation(500, 350);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
} public static void main(String[] args)
{
new DrawTank();
}
}// 定义我的面板
class Mypanel extends JPanel implements KeyListener, Runnable
{
Mytank mytank;
// 定义敌人的tank数组
Vector<Enemytank> enemytank = new Vector<Enemytank>();
// 定义敌人tank出现的数量
int etSize = 3; public Mypanel()
{
mytank = new Mytank(200, 340);
mytank.setColor(0);
for (int i = 0; i < etSize; i++)
{
Enemytank et = new Enemytank((i + 1) * 110, 0);
et.setColor(1);
et.setDirect(2);
enemytank.add(et);
}
} public void paint(Graphics g)
{
super.paint(g);
g.setColor(Color.cyan);
this.draw(mytank.getX(), mytank.getY(), g, this.mytank.direct, 0);
// 画出子弹
if (mytank.b != null)
{
g.draw3DRect(mytank.b.x, mytank.b.y, 1, 1, false);
} // 画出敌人的坦克
for (int i = 0; i < enemytank.size(); i++)
{ this.draw(enemytank.get(i).getX(), enemytank.get(i).getY(), g,
enemytank.get(i).getDirect(), 1);
} } public void draw(int x, int y, Graphics g, int direct, int type)
{
switch (type)
{
case 0:
g.setColor(Color.cyan);
break;
case 1:
g.setColor(Color.yellow);
break;
}
switch (direct)
{
// 向上
case 0:
g.fill3DRect(x, y, 5, 30, false);
g.fill3DRect(x + 15, y, 5, 30, false);
g.fill3DRect(x + 5, y + 5, 10, 20, false);
g.fillOval(x + 5, y + 10, 10, 10);
g.drawLine(x + 10, y + 15, x + 10, y);
break;
// 向右
case 1:
g.fill3DRect(x, y, 30, 5, false);
g.fill3DRect(x, y + 15, 30, 5, false);
g.fill3DRect(x + 5, y + 5, 20, 10, false);
g.fillOval(x + 10, y + 4, 10, 10);
g.drawLine(x + 15, y + 10, x + 30, y + 10);
break;
// 向下
case 2:
g.fill3DRect(x, y, 5, 30, false);
g.fill3DRect(x + 15, y, 5, 30, false);
g.fill3DRect(x + 5, y + 5, 10, 20, false);
g.fillOval(x + 4, y + 10, 10, 10);
g.drawLine(x + 9, y + 15, x + 9, y + 30);
break;
// 向左
case 3:
g.fill3DRect(x, y, 30, 5, false);
g.fill3DRect(x, y + 15, 30, 5, false);
g.fill3DRect(x + 5, y + 5, 20, 10, false);
g.fillOval(x + 10, y + 4, 10, 10);
g.drawLine(x + 15, y + 10, x, y + 10);
break; }
} @Override
public void keyPressed(KeyEvent e)
{
if (e.getKeyCode() == KeyEvent.VK_UP)
{
this.mytank.setDirect(0);
this.mytank.moveup();
}
else if (e.getKeyCode() == KeyEvent.VK_RIGHT)
{
this.mytank.setDirect(1);
this.mytank.moveright();
}
else if (e.getKeyCode() == KeyEvent.VK_DOWN)
{
this.mytank.setDirect(2);
this.mytank.movedown();
}
else if (e.getKeyCode() == KeyEvent.VK_LEFT)
{
this.mytank.setDirect(3);
this.mytank.moveleft();
}
if (e.getKeyCode() == KeyEvent.VK_J)
{
this.mytank.fire();
}
this.repaint();
} @Override
public void keyReleased(KeyEvent e)
{
// TODO Auto-generated method stub } @Override
public void keyTyped(KeyEvent e)
{
// TODO Auto-generated method stub } @Override
public void run()
{
while (true)
{
try
{
Thread.sleep(100);
}
catch (Exception e)
{
e.printStackTrace();
}
this.repaint();
} }
}

解决方案 »

  1.   

    没把子弹画出来吧,而且,你的子弹速度比坦克速度还慢……
    每一个坦克都只有一个子弹吧……你的paint似乎只画这一个
      

  2.   

    因为你的Bullet类的run()方法完全写错了,应该把sleep()放到while()循环内部去,如下:
    class Bullet implements Runnable
    {
        int x;
        int y;
        int direct;
        int speed = 5;
        public Bullet(int x,int y,int direct)
        {
            this.x = x;
            this.y = y;
            this.direct = direct;
        }
        @Override
        public void run()
        {
            while(true)
            {
                try
                {
                    Thread.sleep(500);
                }
                catch (Exception e)
                {
                }
                switch(direct)
                {
                case 0:
                    y-=speed;
                    break;
                case 1:
                    x+=speed;
                    break;
                case 2:
                    y+=speed;
                    break;
                case 3:
                    x-=speed;
                    break;
                }
            }
        }
    }
    另外提点建议啊,子弹飞得太慢了,建议增速。
      

  3.   

    // 画出子弹
            if (mytank.b != null)
            {
                g.draw3DRect(mytank.b.x, mytank.b.y, 1, 1, false);
            }
    子弹画出来了,我现在还没考虑那么多,我现在就是想先实现子弹自己会飞行,
    希望你继续帮助我,看看我的程序到底哪里出了问题
      

  4.   

    子弹类 没必要实现Runnable接口吧 只要一个类来实现他   在main方法中起一线程就可了
      

  5.   


    这个我还真不知道,我也是刚刚学习Java,我试试吧!!
      

  6.   


    好像不行吧!要是不实现Runnable接口,如何覆写Run方法
      

  7.   

    main中起一线程也可以,把子弹统一管理,不过控制稍微复杂一点。
    子弹单独起线程也可以,因为我看你同时存在的子弹也不会很多。但有一点很重要,子弹飞出界外或者击中敌人后都要终止该线程。你现在没做这个处理,子弹线程永远存在,将来线程会越来越多,直到内存溢出。
      

  8.   

    结贴给分了,alexandertech的答案最直接,也最有效,本来要给40分的,但是wlf2131 又给提了一个醒(建议)我觉得对我也有帮助,所以给wlf2131了5分,剩下的35分都给alexandertech了,感谢你们的帮助