看了韩顺平老师JAVA循序渐进视频,自己也做了tank大战,遇到了一些问题,作为java初学者的小弟在此希望请问代码中的问题所在。
for(int i=0;i<v.size();i++)//画敌人
{
if(v.get(i).islive)
drawtank(v.get(i),g);
for(int j=0;j<v.get(i).zhav.size();j++)//画敌人子弹
{
if(v.get(i).zhav.get(j).islive)
drawzha(v.get(i).zhav.get(j),g);
else
{
v.get(i).zhav.remove(j);
}
}
}
for(int i=0;i<=hero.zhav.size();i++)//画我方子弹
{
if(hero.zhav.get(i).islive)
{
System.out.println("画子弹");
drawzha(hero.zhav.get(i),g);
}
else
{
hero.zhav.remove(i);
}
}
###############;i<=hero.zhav.size();i+多了个等号---------知道了吧。
----------------------biu~biu~biu~~~在下问答机器人小D,这是我依靠自己的聪明才智给出的答案,如果不正确,你来咬我啊!
public void paint(Graphics g)
{
super.paint(g);
for(int i=0;i<wallnum;i++)//画墙
{
drawwall(walls.get(i).x,walls.get(i).y,g);
}
for(int i=0;i<v.size();i++)//画敌人
{
if(v.get(i).islive)
drawtank(v.get(i),g);
for(int j=0;j<v.get(i).zhav.size();j++)//画敌人子弹
{
if(v.get(i).zhav.get(j).islive)
drawzha(v.get(i).zhav.get(j),g);
else
{
v.get(i).zhav.remove(j);
}
}
}
for(int i=0;i<=hero.zhav.size();i++)//画我方子弹
{
if(hero.zhav.get(i).islive)
{
System.out.println("画子弹");
drawzha(hero.zhav.get(i),g);
}
else
{
hero.zhav.remove(i);
}
}
drawtank(hero,g);//画我
drawbase(base.x,base.y,g);//画基地
}
运行后出错的提示是Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: Array index out of range: 0
at java.util.Vector.get(Unknown Source)
at 练习.MyPanel.paint(Ta.java:85)
这是说数组指针越界了? 85行的话是话我方子弹的那个循环,但是为什么同样是画子弹,画敌人子弹的时候数组指针就不会越界,小弟诚心请教问题所在。
前面好像说不太清除,我还是把我所有的代码贴出来吧
package 练习;
import java.util.Vector;
class Zha implements Runnable//子弹对象一经创建就是线程,能自动变化坐标
{
int speed=10;
int x,y;
int direction;
boolean islive;
public Zha(int x,int y,int direction)
{
this.x=x;
this.y=y;
this.direction=direction;
this.islive=true;
System.out.println(this.islive);
}
public void run()
{
while(x>0&&y>0&&x<800&&y<800)
{
try {
Thread.sleep(50);
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
switch (direction)
{
case 0:
y-=speed;
break;
case 1:
y+=speed;
break;
case 2:
x+=speed;
break;
case 3:
x-=speed;
break;
default:
break;
}
}
islive=false;
}
}
class Tank
{
int x,y;//坐标
int type;//坦克种类,分敌方和我方
int speed=3;//速度
int direction;
boolean islive;//记录是否活着
int zhanum;//最大弹药数
Vector zhav=new Vector();//记录子弹集合
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;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public int getSpeed() {
return speed;
}
public void setSpeed(int speed) {
this.speed = speed;
}
public int getDirection() {
return direction;
}
public void setDirection(int direction) {
this.direction = direction;
}
public Tank(int x,int y,int direction)
{
this.x=x;
this.y=y;
this.direction=direction;
this.islive=true;
}
public void shoot()//射击函数生成子弹对象
{
if(zhav.size()<zhanum)
{
System.out.println("子弹发射");
Zha zha=new Zha(x+20, y+15, direction);
zhav.add(zha);
System.out.println(zhav.size());
System.out.println("目前子弹数量"+zhav.size());
Thread thread=new Thread(zha);
thread.start();
}
}
public void moveup()
{
if((y-speed)>100&&(y-speed)<700)
y-=speed;
}
public void movedown()
{
if((y+speed)>100&&(y+speed)<700)
y+=speed;
}
public void moveleft()
{
if((x-speed)>100&&(x-speed)<700)
x-=speed;
}
public void moveright()
{
if((x+speed)>100&&(x+speed)<700)
x+=speed;
}
}
class Hero extends Tank
{
public Hero(int x,int y,int direction)
{
super(x,y,direction);
type=1;//1表示我方
zhanum=5;//规定我方弹药上限5
}
}
class Anemy extends Tank implements Runnable//敌方坦克对象一经生成,就是作为独立的线程变化坐标
{
public Anemy(int x,int y,int direction)
{
super(x,y,direction);
type=0;//0表示敌方
zhanum=2;//规定敌方弹药上限2
}
@Override
public void run() {
// TODO 自动生成的方法存根
int x=0;
int num=0;
while(true)
{
try {
Thread.sleep(50);
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
if(num%8==0)
x=(int)(Math.random()*5);
if(x==0)
{
this.direction=0;
this.moveup();
num++;
}
else if(x==1)
{
this.direction=1;
this.movedown();
num++;
}
else if (x==2)
{
this.direction=2;
this.moveright();
num++;
}
else if (x==3)
{
this.direction=3;
this.moveleft();
num++;
}
else if (x==4)
{
this.shoot();
}
}
}
}
class Wall
{
int x,y;
public Wall(int x,int y)
{
this.x=x;
this.y=y;
}
}
class Base
{
int x,y;
public Base(int x,int y)
{
this.x=x;
this.y=y;
}
}
package 练习;
import java.awt.*;
import java.awt.event.*;
import java.util.Vector;
import javax.swing.*;
public class Ta extends JFrame{
public static void main(String[] args) {
// TODO 自动生成的方法存根
Ta ta=new Ta();
}
public Ta()
{
MyPanel mp=new MyPanel();
Thread thread=new Thread(mp);
thread.start();
this.addKeyListener(mp);
this.add(mp);
this.setVisible(true);
this.setSize(800,800);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
class MyPanel extends JPanel implements KeyListener,Runnable
{
int anemynum=2;
int wallnum=20;
Base base=null;
Hero hero=null;
JTextField jTextField=null;
Vector v=new Vector();
Vector walls=new Vector();
public MyPanel()
{
base=new Base(350,680);//初始化基地
for(int i=0;i<wallnum;i++)//初始化围墙
{
Wall wall=new Wall((i+3)*30, 350);
walls.add(wall);
}
for(int i=0;i<anemynum;i++)//初始化敌人
{
Anemy a=new Anemy((i+3)*100, 150, 1);
Thread th1=new Thread(a);
th1.start();
System.out.println(" "+a.direction);
v.add(a);
}
hero =new Hero(300, 690, 0);//初始化我
}
public void paint(Graphics g)
{
super.paint(g);
for(int i=0;i<wallnum;i++)//画墙
{
drawwall(walls.get(i).x,walls.get(i).y,g);
}
for(int i=0;i<v.size();i++)//画敌人
{
if(v.get(i).islive)
drawtank(v.get(i),g);
for(int j=0;j<v.get(i).zhav.size();j++)//画敌人子弹
{
if(v.get(i).zhav.get(j).islive)
drawzha(v.get(i).zhav.get(j),g);
else
{
v.get(i).zhav.remove(j);
}
}
}
for(int i=0;i<=hero.zhav.size();i++)//画我方子弹
{
if(hero.zhav.get(i).islive)
{
System.out.println("画子弹");
drawzha(hero.zhav.get(i),g);
}
else
{
hero.zhav.remove(i);
}
}
drawtank(hero,g);//画我
drawbase(base.x,base.y,g);//画基地
}
public boolean disdray(Zha z,Tank t)
{
int zhax,zhay,tankx,tanky;
zhax=z.x;
zhay=z.y;
tankx=t.getX();
tanky=t.getY();
if((zhax<tankx+40)&&(zhax>tankx)&&(zhay<tanky+40)&&(zhay>tanky)&&z.islive)
{
z.islive=false;
t.islive=false;
System.out.println("击毁敌机");
anemynum--;
return true;
}
else
{
return false;
}
}
public void drawbase(int x,int y,Graphics g)//画基地
{
g.fill3DRect(x, y, 100, 50, false);
g.setColor(Color.black);
g.drawLine(x, y, x+100, y+50);
g.drawLine(x+100, y, x, y+50);
}
public void drawwall(int x,int y,Graphics g)//画墙
{
g.fill3DRect(x, y, 30, 30, false);
}
public void drawzha(Zha z,Graphics g)//画子弹
{
if(z.islive)
{
g.setColor(Color.black);
g.fill3DRect(z.x, z.y, 5, 5, false);
}
}
public void drawtank(Tank t,Graphics g)//画坦克
{
switch (t.type)
{
case 0:
g.setColor(Color.yellow);
break;
case 1:
g.setColor(Color.red);
break;
default:
break;
}
switch (t.direction) {
case 0://朝上
g.fill3DRect(t.getX(), t.getY(), 10,30, false);
g.fill3DRect(t.getX()+30, t.getY(), 10, 30, false);
g.fill3DRect(t.getX()+10, t.getY()+5, 20, 20, false);
g.drawLine(t.getX()+20, t.getY()+15,t.getX()+20, t.getY()-25);
break;
case 1://朝下
g.fill3DRect(t.getX(), t.getY(), 10,30, false);
g.fill3DRect(t.getX()+30, t.getY(), 10,30, false);
g.fill3DRect(t.getX()+10, t.getY()+5, 20, 20, false);
g.drawLine(t.getX()+20, t.getY()+15,t.getX()+20, t.getY()+45);
break;
case 2://朝右
g.fill3DRect(t.getX(), t.getY(), 30,10, false);
g.fill3DRect(t.getX(), t.getY()+30, 30,10, false);
g.fill3DRect(t.getX()+5, t.getY()+10, 20, 20, false);
g.drawLine(t.getX()+15, t.getY()+20,t.getX()+45, t.getY()+20);
break;
case 3://朝左
g.fill3DRect(t.getX(), t.getY(), 30,10, false);
g.fill3DRect(t.getX(), t.getY()+30, 30,10, false);
g.fill3DRect(t.getX()+5, t.getY()+10, 20, 20, false);
g.drawLine(t.getX()+15, t.getY()+20,t.getX()-15, t.getY()+20);
break;
default:
break;
}
}
@Override//键盘监听事件处理
public void keyPressed(KeyEvent e) {
// TODO 自动生成的方法存根
if(e.getKeyCode()==KeyEvent.VK_DOWN)
{
System.out.println("下");
hero.movedown();
hero.direction=1;
repaint();
}
else if(e.getKeyCode()==KeyEvent.VK_UP)
{
System.out.println("上");
hero.moveup();
hero.direction=0;
repaint();
}
else if(e.getKeyCode()==KeyEvent.VK_LEFT)
{
System.out.println("左");
hero.moveleft();
hero.direction=3;
repaint();
}
else if(e.getKeyCode()==KeyEvent.VK_RIGHT)
{
System.out.println("右");
hero.moveright();
hero.direction=2;
repaint();
}
if(e.getKeyCode()==KeyEvent.VK_X)
{
//System.out.println("shoot");
hero.shoot();
}
}
@Override
public void keyReleased(KeyEvent e) {
// TODO 自动生成的方法存根
}
@Override
public void keyTyped(KeyEvent e) {
// TODO 自动生成的方法存根
}
@Override//做线程。每50msrepaint一次
public void run() {
// TODO 自动生成的方法存根
while(true)
{
try {
Thread.sleep(50);
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
if(anemynum!=0)
repaint();
else
{
jTextField=new JTextField("恭喜");
this.add(jTextField);
repaint();
}
}
}
}