//坦克大战:-换关卡,IO声音流没做,还有写BUG,没做完 ,本人纯外行自学的,不知道怎么做下一关,请大家指导一下,比一般坦克大战加了小道具
包1如下:
Tank1
import java.awt.;
import javax.swing.;
import java.awt.event.;
import java.util.;
import java.io.*;
public class Tank1 extends JFrame implements ActionListener{
MyPanel mp=null;
StartPanel gkmp=null;
//Record record=null;
JMenuBar cd=null;//??不熟
JMenu cd1=null;//??不熟
JMenu cd2=null;
JMenuItem cd1xl1=null;//菜单栏1系列的1
JMenuItem cd1xl2=null;//菜单栏1系列的2
JMenuItem cd1xl3=null;//菜单栏1系列的1
JMenuItem cd1xl4=null;//菜单栏1系列的2
JMenuItem cd2xl1=null;//菜单栏2系列的1
JLabel imageJLabel=null;
String newGame=“newGame”;//?
//Image tp1=null;
public static void main(String[] args)
{
Tank1 t1=new Tank1();
}
public Tank1(){
gkmp=new StartPanel();
mp=new MyPanel(newGame);//??
Record record=new Record();//创建一个记录对象
Thread t=new Thread(gkmp);
t.start();
cd=new JMenuBar();//菜单栏 不熟
cd1=new JMenu("游戏(G)");//第一个菜单栏的第一个菜单
cd1.setMnemonic('G');//快界键
cd2=new JMenu("设置(Z)");
cd2.setMnemonic('Z');
cd1xl1=new JMenuItem("开始新游戏(N)");//菜单系列 cdxl
cd1xl1.setMnemonic('N');
cd1xl1.addActionListener(this);//加组件监听
cd1xl1.setActionCommand("newGame");//设置键值,和上文同名参数有啥关系没?
cd1.add(cd1xl1);
cd1xl2=new JMenuItem("继续游戏(H)");//菜单系列 cdxl
cd1xl2.setMnemonic('H');
cd1xl2.addActionListener(this);//加组件监听
cd1xl2.setActionCommand("goonGame");//设置键值
cd1.add(cd1xl2);
cd1xl3=new JMenuItem("保存退出(S)");//菜单系列 cdxl
cd1xl3.setMnemonic('S');
cd1xl3.addActionListener(this);//加组件监听
cd1xl3.setActionCommand("saveOut");//设置键值
cd1.add(cd1xl3);
cd1xl4=new JMenuItem("退出(Q)");
cd1xl4.setMnemonic('Q');
cd1xl4.addActionListener(this);//加组件监听
cd1xl4.setActionCommand("exit");//设置键值
cd1.add(cd1xl4);
cd.add(cd1);//给菜单栏 cd 添加菜单 cd1
cd2xl1=new JMenuItem("速度(F)");//菜单系列 cdxl 没做好效果?
cd1xl4.setMnemonic('F');
cd1xl4.addActionListener(this);//加组件监听
cd1xl4.setActionCommand("FSpeed");//设置键值
cd2.add(cd2xl1);
cd.add(cd2);
ImageIcon img = new ImageIcon("E:/Tank1/tankebig.PNG");
JLabel imageJLabel = new JLabel(img);
gkmp.add(imageJLabel);
this.add(gkmp);
this.setJMenuBar(cd);
this.setTitle("坦克大战");
ImageIcon tp1=new ImageIcon("E:/Tank1/tankexiao.PNG");//设置小图标地址要写全路径吗
this.setIconImage(tp1.getImage());
this.setSize(700,620);
this.setLocation(300,80);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);//可见
this.setResizable(false);//可调
// this.setResizable(true);
}
public void actionPerformed(ActionEvent e){
//boolean flag=true;
if(e.getActionCommand().equals("newGame"))
{
this.remove(gkmp);//取消界面 gkmp
if(mp.flag==false)//因为在主类构造函数开始就创建了mp,所以可以引用flag变量
{
this.remove(mp);
mp=new MyPanel("newGame");
}
this.add(mp);
this.addKeyListener(mp);
Thread t=new Thread(mp);//启动我的MyPanel模板对象mp的线程
t.start();//叫醒线程
this.setVisible(true);//因为默认的是不可见,必须写这个!!
Record.bcjl();//????
}else if(e.getActionCommand().equals("saveOut"))
{
Record record0=new Record();
// record0.setDtk(mp.dtk);
record0.cunpan();///???
System.exit(0);//游戏退出
}else if(e.getActionCommand().equals(“exit”))
{
Record.bcjl();
System.exit(0);//游戏退出
}else if(e.getActionCommand().equals(“goonGame”)){
this.remove(gkmp);
if(mp.flag==false)//因为在主类构造函数开始就创建了mp,所以可以引用flag变量
{
this.remove(mp);
mp=new MyPanel(“goonGame”);
}
Thread t=new Thread(mp);
t.start();
this.add(mp);
this.addKeyListener(mp);
this.setVisible(true);
}
}
class StartPanel extends JPanel implements Runnable //开始界面类
{
int time=0;
public void paint(Graphics g){
super.paint(g);
// g.fillRect(0, 0, 600, 500);//设置画布
g.setColor(Color.black);//设置颜色
Color mycolor1=new Color(250,50,0);//自定义红色
g.setFont(new Font(“华文琥珀”,Font.BOLD,80));//设置字体//?
g.drawString(“坦克大战”,190 , 460);//绘字符串
g.setColor(Color.black);//设置颜色
g.setFont(new Font(“黑体”,1,14));//设置字体
g.drawString(“李晋祥”,648 , 552);//绘字符串
if(time%2==0)
{
g.setColor(Color.white);//设置颜色
g.setFont(new Font(“华文行楷”,3,35));//字体:华康楷体, Ravie, OCR A Extended
g.drawString(“准备战斗”,270 , 345);//绘字符串
}
}
StartPanel(){
}
public void run(){
while(true){
try{
Thread.sleep(400);
}catch(Exception e){}
time++;
this.repaint();
}
}
}
class MyPanel extends JPanel implements KeyListener,Runnable
{
//Vector mts=new Vector();//建立一个我的坦克集合类可以出无限个坦克
MyTank mt=null;
MyTank mt0=null;
MyTank mt01=null;
MyTank mt02=null;
Vector dtk=new Vector();//建立一个敌坦克集合类
Props props=null;
Vector bzjh=new Vector();//创建一个爆炸类的集合
Vector wzjh=new Vector();//建立一个位置集合类,为啥建立这集合类
int tksl=3;//坦克数量
int a=122;
int b=455;
int n=10;
int myzdNum=4;//?
int propsSort=5;
int time=0;
boolean flag=true;//标记是不是已经创建过MyPanel类
boolean b1=false;
int x=1;//总关卡数?
int rocket=1;//没用?
int huopao=0;//?
Color mycolor1=new Color(250,50,0);//自定义红色
Color mycolor2=new Color(0,250,50);//自定义绿色
Color mycolor3=new Color(0,50,250);//自定义兰色
Color mycolor11=new Color(130,200,0);//自定义土黄
Color mycolor31=new Color(0,100,200);//自定义兰色
Color mycolor21=new Color(0,250,0);//自定义绿色
JLabel imageJLabel0=null;
JLabel imageJLabel1=null;
ImageIcon img0=null;//?
ImageIcon img1=null;//?
public MyPanel(String ss)
{
ImageIcon img0 = new ImageIcon(“e:/Tank1/background.jpg”);
JLabel imageJLabel0 = new JLabel(img0);
this.add(imageJLabel0);
Record.dqjl();//?
mt=new MyTank(600,280);//new多个可改为多个坦克,循环数组
mt0=new MyTank(550,280);//new多个可改为多个坦克,循环数组
mt01=new MyTank(550,330);//new多个可改为多个坦克,循环数组
mt02=new MyTank(600,330);//new多个可改为多个坦克,循环数组
props=new Props(30,30);//没有实际意义,为了new对象,必须要有个参数?
if(ss.equals(“newGame”)){
// record=new Record();
for(int i=0;i
// dt.dtkxl(dtk);///???是不是敌人坦克血量
dt.setFangxiang(1);//给一个初始值,调drawTank()赋初值要用
Thread t2=new Thread(dt);
t2.start();
Zidan zd=new Zidan(dt.x,dt.y,1);//?这是干啥加子弹元素吗?
Thread t3=new Thread(zd);//?
t3.start();
dtk.add(dt);
}
}else if(ss.equals(“goongame”)){//继续游戏有问题 感觉读取存盘信息有问题
wzjh=Record.dupan();
for(int i=0;i
DiTank dt=new DiTank(wz.x,wz.y);//添加出场敌坦
dt.setFangxiang(wz.fangxiang);
// dt.dtkxl(dtk);//?敌坦克血量,好像暂时用不着
// dt.setFangxiang(1);//给一个初始值,调drawTank()赋初值要用
Thread t2=new Thread(dt);
t2.start();
Zidan zd=new Zidan(dt.x,dt.y,1);//?这是干啥加子弹元素吗?
Thread t3=new Thread(zd);//?
t3.start();
dtk.add(dt);
}
}
flag=false;//MyPanel类的mp创建过一次就标记为假
// this.repaint();
// Record.next();
// if(Record.next()%2!=0){
// Record.reMtNum();//需要吗?
// Record.reDtNum();//需要吗?
// Record.reAddMtNum();
// }
}
public void outNum(Graphics g)//画出统计数据的方法也即使显示数量的函数
{
g.setColor(Color.cyan);
this.drawTank(500,150,g,0,0);//引用drawtank()的不能是g,而是this
this.drawTank(570,150,g,0,1);
this.drawTank(500,70,g,0,1);
g.setColor(Color.black);
g.setFont(new Font("仿宋",2,20));//??换换字体效果
g.drawString(Record.getDtNum()+"",600,170);
if((Record.getMtNum()+Record.getAddMtNum())>=0){
g.drawString((Record.getMtNum()+Record.getAddMtNum())+"",530,170);//
}else{
g.drawString((Record.getAddMtNum())+"",530,170);
}
g.setColor(Color.blue);
g.setFont(new Font("方正小标宋",1,17));
g.drawString("干掉的坦克总数:",510,40);
g.setColor(Color.black);
g.setFont(new Font("仿宋",2,20));
g.drawString(Record.getSumDtNum()+"",530,90);
g.setColor(Color.MAGENTA);//设置颜色
g.setFont(new Font("隶书",0,20));//设置字体
g.drawString("第"+x+"关",500 , 200);//绘字符串
}
public void paint(Graphics g){//这个方法每当窗口激活,最小化,调用repaint()方法都会运行,线程中调用就一直显示
super.paint(g);
// g.fillRect(0,0,400,300);//做个背景画布,默认黑色
this.outNum(g);//调用显示数量的函数
g.setColor(Color.red);//设置颜色
g.fillRect(530, 210, 30, 20);
g.setColor(Color.black);//设置颜色
g.drawLine(530, 210, 530, 320);
g.setColor(mycolor11);//设置颜色
if(mt.livetrue){
this.drawTank(mt.getX(),mt.getY(),g,mt.fangxiang,0);
}
if(mt0.livetrue){
this.drawTank(mt0.getX(),mt0.getY(),g,mt0.fangxiang,2);
}
if(mt01.livetrue){
this.drawTank(mt01.getX(),mt01.getY(),g,mt01.fangxiang,2);
}
if(mt02.livetrue){
this.drawTank(mt02.getX(),mt02.getY(),g,mt02.fangxiang,2);
}
if(mt.getLive()false){
g.setColor(mycolor11);//设置颜色
g.setFont(new Font(“Gill Sans Ultra Bold Condensed”,1,40));//字体:华康楷体, Ravie, OCR A Extended
g.drawString(“game over…”,200 , 220);//绘字符串
this.repaint();
}
if(Record.getDtNum()%60&&(Record.getDtNum()>10)){
// if(time%20)
// {
g.setColor(Color.blue);//设置颜色
g.setFont(new Font(“华文行楷”,1,35));//字体:华康楷体, Ravie, OCR A Extended
g.drawString(“你行不行?”,310 , 265);//绘字符串
// }
}
if(Record.getDtNum()0){
g.setColor(Color.red);//设置颜色
g.setFont(new Font(“华文行楷”,1,35));//字体:华康楷体, Ravie, OCR A Extended
g.drawString(“过关!”,300 , 265);//绘字符串
}
for(int i=0;i
DiTank dt=dtk.get(i);
if(dt.live
this.drawTank(dt.getX(),dt.getY(),g,dt.fangxiang,1);//??!!注意用法用dtk 还是dt调用
}
}
for(int i=0;i
Zidan zd=mt.aa.get(i);
if(mt.zd!=null&&mt.zd.live
{
//g.fill3DRect((mt.zd.x-2),(mt.zd.y-2), 8, 8, false); //???画子弹火力圈
g.setColor(Color.black);//子弹颜色设置为白色
g.fillOval(zd.x+1,zd.y+1, 4,4);
}
if(zd.livefalse)
{
mt.aa.remove(zd);
}
}
//this.repaint();//?
for(int i=0;i
DiTank dt=dtk.get(i);
for(int j=0;j
Zidan zd=dt.dzd.get(j);
if(zd!=null&&dtk.get(i).live
{
g.setColor(Color.red);//子弹颜色设置为红色,次处不进循环是不是更好?
g.fillOval(zd.x+1,zd.y+1, 4,4);
}
if(zd.livefalse)//删除生命为假的敌人子弹???
{
dt.dzd.remove(zd);
}
}
}
for(int i=0;i
Baozha bz=bzjh.get(i);
if(bzjh.get(i).livetime>140){
g.setColor(Color.red);
g.fillOval(bz.x, bz.y+5, 20,20 );//代替上面的句子
//g.fillOval(bz.x, bz.y, 20,5 );//可以用来做合成图形,但是要定好坐标点
}else if((bzjh.get(i).livetime<=100)&&(bzjh.get(i).livetime>50)){
g.setColor(Color.orange);
g.fillOval(bz.x+4, bz.y+9, 12,12 );
}else if((bzjh.get(i).livetime<=50)&&(bzjh.get(i).livetime>20)){
g.setColor(Color.yellow);
g.fillOval(bz.x+7, bz.y+11,5,5 );
}else{
g.setColor(Color.pink);
g.fillOval(bz.x+10, bz.y+13,2,2 );
}
bz.ltjs(); //生存时间减少函数
if(bz.livetime
bzjh.remove(bz);
}
}
//
if(props.live==true){//画道具
this.drawProps(props.getX(),props.getY(),g,props.getleixing());
}
//}
this.repaint();//教学视频少了这句,子弹无法自主运行,主类启动线程后仍然可动
}
public void keyPressed(KeyEvent e)//键盘输入事件
{
if(mt.getLive()==true){
if(e.getKeyCode()==KeyEvent.VK_W){
this.mt.setFangxiang(0);
this.mt.xiangshang();
}else if(e.getKeyCode()==KeyEvent.VK_S){
this.mt.setFangxiang(1);
this.mt.xiangxia();
}else if(e.getKeyCode()==KeyEvent.VK_A){
this.mt.setFangxiang(2);
this.mt.xiangzuo();
}else if(e.getKeyCode()==KeyEvent.VK_D){
this.mt.setFangxiang(3);
this.mt.xiangyou();
}
if(e.getKeyCode()KeyEvent.VK_J)
{
if((mt.aa.size()
{
this.mt.fszd();//调用发射子弹函数
}
}
}
}
public void crash(){
}
public boolean addprops(Props props,MyTank mt)//吃道具触发 方法 (道具功能触发模型为边长20的正方形)
{
boolean b2=false;
switch(props.leixing){
case 0://我的坦克速度提高//mt.fangxiang 0\1\2\3
if((mt.getX()+10>props.getX()&&mt.getX()+10props.getY())||(mt.getX()+10>props.getX()&&mt.getX()+10props.getY()&&mt.getY()+15props.getX()&&mt.getX()+10props.getY()&&mt.getY()+15props.getX()&&mt.getX()+15props.getY()&&mt.getY()+10props.getX()&&mt.getX()+10props.getY())||(mt.getX()+10>props.getX()&&mt.getX()+10props.getY()&&mt.getY()+15props.getX()&&mt.getX()+10props.getY()&&mt.getY()+15props.getX()&&mt.getX()+15props.getY()&&mt.getY()+10props.getX()&&mt.getX()+10props.getY())||(mt.getX()+10>props.getX()&&mt.getX()+10props.getY()&&mt.getY()+15props.getX()&&mt.getX()+10props.getY()&&mt.getY()+15props.getX()&&mt.getX()+15props.getY()&&mt.getY()+10props.getX()&&mt.getX()+10props.getY())||(mt.getX()+10>props.getX()&&mt.getX()+10props.getY()&&mt.getY()+15props.getX()&&mt.getX()+10props.getY()&&mt.getY()+15props.getX()&&mt.getX()+15props.getY()&&mt.getY()+10props.getX()&&mt.getX()+10props.getY())||(mt.getX()+10>props.getX()&&mt.getX()+10props.getY()&&mt.getY()+15props.getX()&&mt.getX()+10props.getY()&&mt.getY()+15props.getX()&&mt.getX()+15props.getY()&&mt.getY()+10
// System.out.println(“吃道具加命程序,正常运行”);
}
break;
}
return b2;
}
// addMyTank++;
//MyTank mt1=new MyTank(mt.getX(),mt.getY());//??创建另一个MyTank对象
// public void setAddMytank(){
// addMyTank++;
// };
// public static int getAddMytank(){
// return addMyTank;
// };
public void run() //我的画板的 线程函数
{
while(true){
try{
Thread.sleep(50);//
}catch(Exception e){}
for(int i=0;i
Zidan myzd=mt.aa.get(i);
if(myzd.live){
for(int j=0;j0)
if(dt.live)//内关联敌人坦克重生的一种情况,有敌人坦克被打中
{
if(this.jzsf(myzd,dt)&&((Record.getDtNum()-tksl)>=0)){//调用jzsf(),打中同时,坦克定点?及时重生
DiTank dt0=new DiTank((int)(Math.random()*50+5)*10,(int)(Math.random()*100+450));
Thread t2=new Thread(dt0);
t2.start();
Zidan zd0=new Zidan(dt0.x,dt0.y,dt0.fangxiang);
Thread t3=new Thread(zd0);
t3.start();
dt0.dzd.add(zd0);
dtk.add(dt0);
}
}
}
}
}
if(Record.getDtNum()>=tksl&&b1==true){ //炸弹爆炸,敌坦克按条件重生,
for(int i=0;i
// for(int i=0;i
Thread t6=new Thread(dt1);
t6.start();
Zidan zd1=new Zidan(dt1.x,dt1.y,dt1.fangxiang);
Thread t7=new Thread(zd1);
t7.start();
dt1.dzd.add(zd1);
dtk.add(dt1);
b1=false;
}
for(int j=0;j
DiTank dt=dtk.get(j);//取出所有敌方坦克
for(int i=0;i
Zidan zd=dt.dzd.get(i);//?
if(zd.live)
{
if(this.jzsf(zd,mt)true){//调用 击中敌坦 函数
}
}
}
}
if((this.time%120)0){//6秒发生1次 道具随机重置//draw mt hit props
props.live=true;
// props.leixing=2;
props.leixing=(int)(Math.random()*propsSort);
props.x=(int)(Math.random()*370);
props.y=(int)(Math.random()*270);
props.livetime=100;//道具生存期
}
if(props.livetime>0){//道具生存期变化
props.livetime–;
}else{
props.live=false;
}
if(mt.livetrue&&props.livetrue){//调用 吃道具 方法
this.addprops(props,mt);
}
time++;
// if(SaveData.getSumDtNum()%200){
// Record.next();
// }
this.repaint();//线程运行中重绘??
}
}
public void jzwf()//敌人子弹集中我方坦克的方法
{
for(int i=0;i
for(int j=0;j
this.jzsf(zd, mt);
}
}
}
public void jzdf() //我的子弹击中坦克的方法
{
for(int i=0;i
if(zd.live
for(int j=0;j
if(dt.live){
this.jzsf(zd,dt);
// levelDtNum–;
}
}
}
this.repaint();
}
}
public boolean jzsf(Zidan zd,Tank tk)//击中双方的方法
{
boolean b2=false;
switch(tk.fangxiang)
{
case 0:
case 1:
if(zd.x>tk.x&&zd.xtk.y&&zd.y
// Record.setAddMtNum();
tk.live=false;
b2=true;
}else{
// System.out.println(“Record.getMtNum()=”+Record.getMtNum());
Record.setMtNum();//Record.getSumMtNum()一直小于0 ?bug
if(Record.getMtNum()+1<=0){
Record.lowAddMtNum();
}
// System.out.println(“Record.getMtNum()=”+Record.getMtNum());
// System.out.println(“Record.AddMtNum()=”+Record.getAddMtNum());
if(Record.getMtNum()+Record.getAddMtNum()>0){//bug 被打一下就游戏结束 已经解决
mt.setX(140);
mt.setY(232);
}
if(Record.getMtNum()+Record.getAddMtNum()<=0){
tk.live=false;
}
}
zd.live=false;
Baozha bz=new Baozha(tk.x,tk.y);
bzjh.add(bz);
}
break;
case 2:
case 3:
if(zd.x>tk.x&&zd.x
Record.setDtNum();//每次敌人坦克数量-1
Record.setSumDtNum();
// Record.setAddMtNum();
tk.live=false;
b2=true;
}else{
// System.out.println(“Record.getMtNum()=”+Record.getMtNum());
Record.setMtNum();//Record.getSumMtNum()一直小于0 ?bug
if(Record.getMtNum()+1<=0){
Record.lowAddMtNum();
}
// System.out.println(“Record.getMtNum()=”+Record.getMtNum());
// System.out.println(“Record.AddMtNum()=”+Record.getAddMtNum());
if(Record.getMtNum()+Record.getAddMtNum()>0){//bug 被打一下就游戏结束 已经解决
mt.setX(550);
mt.setY(270);
}
if(Record.getMtNum()+Record.getAddMtNum()<=0){
tk.live=false;
}
}
zd.live=false;
Baozha bz=new Baozha(tk.x,tk.y);
bzjh.add(bz);
}
break;
}
return b2;
}
public void keyTyped(KeyEvent e){}
public void keyReleased(KeyEvent e){}
public void drawTank(int x,int y,Graphics g,int fangxiang,int leixing)//画坦克函数
{
int m=10;
//double n=1;
switch(leixing)//不同阵营坦克
{
case 0://我的坦克
g.setColor(Color.yellow);// 我的坦克颜色 黄色
// g.fillOval(170huopao, 240huopao, 30huopao, 30huopao);
m=11;
break;
case 1://敌人的坦克
g.setColor(mycolor3);//敌人坦克颜色 蓝色
// m=15;
break;
case 2://玩家2的坦克
g.setColor(mycolor1);//敌人坦克颜色 绿色
break;
}
switch(fangxiang)//不同方向的坦克(0,1,2,3)分别代表上下左右,中心原点不变做坐标变换
{
case 0://上
g.fill3DRect(x,y,5,30,true);
g.fill3DRect(x+15,y,5,30,true);
g.fill3DRect(x+5,y+5,10,20,true);
g.drawLine(x+10,y-5,x+10,(y+10));
g.setColor(Color.black);
g.fillOval(x+5,y+10,10,10);
break;
case 1://下
g.fill3DRect(x,y,5,30,true);
g.fill3DRect(x+15,y,5,30,true);
g.fill3DRect(x+5,y+5,10,20,true);
g.drawLine(x+10,y+10,x+10,(y+35));
g.setColor(Color.black);
g.fillOval(x+5,y+10,10,10);
break;
case 2://左
g.fill3DRect(x-5,y+5,30,5,true);
g.fill3DRect(x-5,y+20,30,5,true);
g.fill3DRect(x,y+10,20,10,true);
g.drawLine((x-10)+n-m,y+15,(x+10),(y+15));
g.setColor(Color.black);
g.fillOval(x+5,y+10,10,10);
break;
case 3://右
g.fill3DRect(x-5,y+5,30,5,true);
g.fill3DRect(x-5,y+20,30,5,true);
g.fill3DRect(x,y+10,20,10,true);
g.drawLine((x+10)-n+m,y+15,(x+30),(y+15));
g.setColor(Color.black);
g.fillOval(x+5,y+10,10,10);
break;
}
}
public void drawProps(int x,int y,Graphics g,int leixing)//画道具
{
if(time%8==0){
switch(leixing)
{
case 0://画车轮对应坦克加速
g.setColor(Color.white);
g.fillOval(x, y, 21, 21);
g.setColor(Color.black);
g.fillOval(x+2,y+2,16,16);
g.setColor(Color.white);
g.drawOval(x+2,y+2,16,16);
g.drawLine(x+2,y+10,x+18,y+10);
g.drawLine(x+10,y+2,x+10,y+18);
g.drawLine(x+16,y+4,x+4,y+16);
g.drawLine(x+4,y+4,x+16,y+16);
break;
case 1://画回出生地道具图标
g.setColor(Color.white);
g.drawRoundRect(x, y, 20, 20, 5, 5);
g.setColor(mycolor3);
g.fillRoundRect(x+5, y+5, 10, 10, 5, 5);
break;
case 2://画增加子弹数目道具//?
g.setColor(mycolor2);
g.fill3DRect(x-15,y+8,30,5,false);
g.fill3DRect(x-15,y+6,10,10,true);
g.fillOval(x+15,y+7,7,7);
break;
case 3://画炸弹
g.setColor(mycolor2);
g.fillRect(x, y, 21, 21);
g.setColor(Color.black);
g.fillRect(x+8,y+6,6,2);
g.fillOval(x+3,y+7,14,14);
g.drawLine(x+11, y+3, x+11, y+6);
g.setColor(Color.white);
g.drawLine(x+11, y+15, x+8, y+14);
break;
case 4://画小坦克道具
g.setColor(Color.yellow);
g.fill3DRect(x,y,20,3,true);
g.fill3DRect(x,y+10,20,3,true);
g.fill3DRect(x+3,y+3,14,7,false);
g.fillOval(x+6,y+3,7,7);
g.drawLine(x-7,y+6,x+7,y+6);
break;
}
}
}
}
}
//this.add(mt1);///
//tp1=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource(“baozha1.jpg”));//添加图片
//tp3=Toolkit.getDefaultToolkit().getImage(baozha3);//添加图片
//if(dt0.live=false){//在敌人坦克重新的run()里只要加上就出问题,这段进程就不走了
//dtk.remove(dt);//只要加上就出问题,这段进程就不走了
//Zidan zd=null;//在MyPanel类内的开头,因为子弹都是随着Tank动,所以在不创建对象,而且创建的子弹超过边界就死了,
//生存期很短,单独操作意义不大
//Baozha bz=null;在MyPanel类内的开头,到底要不要写这?不用,因为爆炸时间较短,但要完成画面效果变化.而且可能同时有很多爆炸,
//所以建立爆炸类集合是必须的
//吃道具图片和功能触发不一致不同步在一个线程的里面就同步了
//不同步的可以分写在不同县城里,同步的程序段必须由一个线程里进行
//for(int i=0;i
// mt.aa.get(i).sudu=30;
//}
包2如下:
Ycl
import java.util.;
import java.io.;
class Tank //坦克类
{
int x=0,y=0; //坐标
int fangxiang=0; //方向
int sudu=5; //速度
boolean live=true;//生命
public Tank(int x,int y){//为什么不定义为3个或者5个变量的构造函数??
this.x=x;
this.y=y;
}
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 getFangxiang() {
return fangxiang;
}
public void setFangxiang(int fangxiang) {
this.fangxiang = fangxiang;
}
public boolean getLive() {
return live;
}
public void setLive() {
this.live=false;
}
}
class MyTank extends Tank//因为子弹的功能大多跟着坦克走,所以在这里加连发功能 //我的坦克
{
Vector aa=new Vector();//建立我的子弹集合类aa
Zidan zd=null;//为什么这里又要写定义为空??
int sudu=7;
public MyTank(int x,int y){
super(x,y); //???
}
public void fszd()//发射子弹函数 发射子弹就子弹的 启动线程!!
{
switch(this.fangxiang){
case 0:
zd=new Zidan(x+9,y-15,0);//建立一个子弹
aa.add(zd);//再添加一个子弹
break;
case 1:
zd=new Zidan(x+9,y+44,1);
aa.add(zd);
break;
case 2:
zd=new Zidan(x-18,y+15,2);
aa.add(zd);
break;
case 3:
zd=new Zidan(x+35,y+15,3);
aa.add(zd);
break;
}
Thread t=new Thread(zd);//???
t.start();//???
}
public void xiangshang(){
if(y>0){
y-=sudu;
}else{
y=0;
}
}
public void xiangxia(){
if(y<530){
y+=sudu;
}else{
y=533;
}
}
public void xiangzuo(){
if(x>0){
x-=sudu;
}else{
x=0;
}
}
public void xiangyou(){
if(x<660){
x+=sudu;
}else{
x=660;
}
}
}
class DiTank extends Tank implements Runnable//敌坦克类
{
int sudu=6;
int time=0;
int pinlv=4;//敌人子弹发射间隔频率
Vector dzd=new Vector();//定义敌人子弹集合类dzd
static Vector dtk=new Vector();//建立一个敌坦克集合类
//Zidan zd=null;//为什么这里不能再指向空?
//Tank dtk;
public DiTank(int x,int y){
super(x,y);
}
public void run()//重写接口的run()
{
while(true)
{
try{
Thread.sleep(40);//线程睡眠
}catch(Exception e){}//System.exit(-1);//??参数放0还是-1?啥区别
switch(this.fangxiang)//敌人坦克运动的线程
{
case 0:
for(int i=0;i<10;i++){
if(y>=260&&this.dtHit()!=true){
y-=sudu;//写到循环里面可以,写到for前面不行吗?
try{
Thread.sleep(50);//线程睡眠
}catch(Exception e){}//System.exit(-1);//??参数放0还是-1?啥区别
}
}
break;
case 1:
for(int i=0;i<10;i++){
if(y<=525&&this.dtHit()!=true){
y+=sudu;
try{
Thread.sleep(50);//线程睡眠
}catch(Exception e){}
}
}
break;
case 2:
for(int i=0;i<10;i++){
if(x>=5&&this.dtHit()!=true){
x-=sudu;
try{
Thread.sleep(50);//线程睡眠
}catch(Exception e){}
}
}
break;
case 3:
for(int i=0;i<10;i++){
if(x<=634&&this.dtHit()!=true){
x+=sudu;
try{
Thread.sleep(50);//线程睡眠
}catch(Exception e){}
}
}
break;
}
this.fangxiang=(int)(Math.random()*4);//使用随机函数 控制fangxiang变量 实现随机变方向
this.efire();//发射子弹 方法
if(this.live==false)//生命假跳出该系列线程的循环
{
break;
}
this.time++;//设置自+1的时间变化
}
}
public void efire() {
if((time%pinlv)==0)//用时间这个量控制敌人坦克子弹发射频率
{
if(live)
{
if(dzd.size()<4)//控制敌坦克子弹数量
{
Zidan zd=null;//为什么这里教学视频写到if判断switch之前?
switch(fangxiang)//为什么这里是教学视频不写this
{
case 0:
zd=new Zidan(x+10,y-5,0);//坐标要算
dzd.add(zd);
//zd.x-=sudu;为啥不用控制坐标?因为还没有子弹对象,而且子弹类中定义了运动坐标
break;
case 1:
zd=new Zidan(x+10,y+35,1);
dzd.add(zd);
break;
case 2:
zd=new Zidan(x-15,y+15,2);
dzd.add(zd);
break;
case 3:
zd=new Zidan(x+35,y+15,3);
dzd.add(zd);
break;
}
Thread t5=new Thread(zd);//怎么在这里启动线程??
t5.start();
}
}
}
}
// public void dtkxl(Vector dtl){
// this.dtk=dtl;
// }
// public void dtkxl(Vector dxl){//?貌似是敌坦克血量 暂时用不着
// this.dtk=dxl;
// }
public boolean dtHit(){
boolean b=false;
switch(this.fangxiang){
case 0:
for(int i=0;i
if(dt!=this&&dt.livetrue){
if(dt.fangxiang 0||dt.fangxiang1){
if((this.x>=dt.x&&this.x<=dt.x+20&&this.y>=dt.y&&this.y<=dt.y+30)){
b=true;
}
if(this.x+20>=x&&this.x+20<=dt.x+20&&this.y>=dt.y&&this.y<=dt.y+30){
b=true;
}
}
if(dt.fangxiang 2||dt.fangxiang3){
if(this.x>=dt.x&&this.x<=dt.x+30&&this.y>=dt.y&&this.y<=dt.y+20){
b=true;
}
if(this.x+20>=dt.x&&this.x+20<=dt.x+30&&this.y>=y&&this.y<=dt.y+20){
b=true;
}
}
}
}
case 1:
for(int i=0;i
if(dt!=this&&dt.live
if(dt.fangxiang0||dt.fangxiang1){
if(this.x>=dt.x&&this.x<=dt.x+20&&this.y+30>=dt.y&&this.y+30<=dt.y+30){
b=true;
}
if(dt.x+20>x&&dt.x+20
}
}
if(dt.fangxiang
if(this.x>=dt.x&&this.x<=dt.x+30&&this.y+30>=dt.y&&this.y+30<=dt.y+20){
b=true;
}
if(this.x+20>=dt.x&&this.x+20<=dt.x+30&&this.y+30>=dt.y&&this.y+30<=dt.y+20){
b=true;
}
}
}
}
case 2:
for(int i=0;i
if(dt!=this&&dt.live
if(dt.fangxiang 0||dt.fangxiang1){
if(this.x>=dt.x&&this.x<=dt.x+20&&this.y>=dt.y&&this.y<=dt.y+30){
b=true;
}
if(this.x>=dt.x&&this.x<=dt.x+20&&this.y+20>=dt.y&&this.y+20<=dt.y+30){
b=true;
}
}
if(dt.fangxiang2||dt.fangxiang3){
if(this.x>=dt.x&&this.x<=dt.x+30&&this.y>=dt.y&&this.y<=dt.y+20){
b=true;
}
if(this.x>=dt.x&&this.x<=dt.x+30&&this.y+20>=dt.y&&this.y+20<=dt.y+20){
b=true;
}
}
}
}
case 3:
for(int i=0;i=dt.x&&this.x+30<=dt.x+20&&this.y>=dt.y&&this.y<=dt.y+30){
b=true;
}
if(this.x+30>=dt.x&&this.x+30<=dt.x+20&&this.y+20>=dt.y&&this.y+20<=dt.y+30){
b=true;
}
}
if(dt.fangxiang ==2||dt.fangxiang==3){
if(this.x+30>=dt.x&&this.x+30<=x+30&&this.y>=dt.y&&this.y<=dt.y+20){
b=true;
}
if(this.x+30>=dt.x&&this.x+30<=dt.x+30&&this.y+20>=dt.y&&this.y+20<=dt.y+20){
b=true;
}
}
}
}
}
return b;
}
}
class Zidan implements Runnable//用实现接口方法把子弹作成线程, 子弹类
{
int x;int y;
int fangxiang;
int sudu=10;
boolean live=true;
public Zidan(int x,int y,int fangxiang){
this.x=x;
this.y=y;
this.fangxiang=fangxiang;
}
public void run()//子弹可以活动的线程
{
while(true)//线程的死循环里都要有睡眠
{
try{
Thread.sleep(50);
}catch(Exception e){}
switch(this.fangxiang){
case 0:
y-=sudu;
break;
case 1:
y+=sudu;
break;
case 2:
x-=sudu;
break;
case 3:
x+=sudu;
break;
}
if(x<0||y<220||x>710||y>710)//边界限制子弹(生命为假的条件)
{
this.live=false;
break;
}
}
}
}
class Baozha //爆炸类
{
int x,y;
int livetime=180;
boolean live=true;
Baozha(int x,int y){
this.x=x;
this.y=y;
}
public void ltjs()//生存时间减少函数
{
if(livetime>0){
livetime–;
}else{
this.live=false;//不写this行不行??
}
}
}
class Props //implements Runnable//道具好象不用建立?直接写入别的程序中=no;不实现Runnable接口
{
int x=0,y=0;
int leixing=0;//0,1
//int perleixing=2;
boolean live=false;
//int perlive=200;//每次live变化的时间系数
int livetime=200;//每次的生存期时间系数
//int lifeFactor=100;
Props(int x,int y){
this.x=x;
this.y=y;
}
public int getX(){
return x;
}
public int getY(){
return y;
}
public int getleixing(){
return leixing;
}
public void setleixing(int leixing){
this.leixing=leixing;
}
public void setLivetime(){
if(live==true&&livetime>0){
livetime–;
}else{
live=false;
}
}
public int getLivetime(){
return livetime;
}
public boolean getLive(){
return live;
}
}
class Record//做成静态的方法静态的变量方便、安全,不然可能出错,由于线程不同时统计
{
private static Vector dtk=new Vector();//建立一个敌坦克集合类
private static Vector wzjh=new Vector();//建立一个位置集合类
private static FileReader fr=null;
private static FileWriter fw=null;
private static BufferedReader br=null;
private static BufferedWriter bw=null;
private static int mtNum=2;//设置为静态,在整个程序里好用
private static int dtNum=20;
private static int addMtNum=0;//获得的hero命
// private static int sumMtNum=0;//我的坦克现有总命
private static int sumDtNum=0;//杀敌坦克总数
public static int next=0;
// private static int sum=3;//总关数
public Record(){
}
// public static int getSum(){
// return sum;
// }
public static void setDtNum()//敌人坦克数量减少方法
{
if(dtNum>0){
dtNum–;
}
}
public static int getDtNum() {
return dtNum;
}
public static void setMtNum()//我的坦克数量统计方法
{
if(mtNum>0){
mtNum–;
}
}
public static int getMtNum() {
return mtNum;
}
public static void reMtNum() {//重置MtNum
mtNum=2;
}
public static void reDtNum() {//重置敌人坦克数量方法MtNum
dtNum=20;
}
public static void reAddMtNum() {//重置敌人坦克数量方法MtNum
addMtNum=0;
}
public static void setAddMtNum0(){//得分奖命 方法
if((sumDtNum==30)||((sumDtNum%40)==0)&&(sumDtNum!=0)){
addMtNum++;
}
}
public static void setAddMtNum(){//吃道具奖命 方法
addMtNum++;
}
public static void lowAddMtNum()//我的坦克数量统计方法
{
if(addMtNum>=0){
addMtNum--;
}
}
public static int getAddMtNum(){//取奖命 方法
return addMtNum;
}
public static int next(){
next++;
return next;
}
public static int reNext(){
next=0;
return next;
}
public static void setSumDtNum()//杀敌坦克统计方法
{
sumDtNum++;
}
public static int getSumDtNum(){
return sumDtNum;
}
public static void bcjl()//保存记录
{
try{
fw=new FileWriter("e:\\tanksavedata.txt");//斜杠方向是捺,非撇?
bw=new BufferedWriter(fw);
bw.write(sumDtNum+"\r\n");
}catch(Exception e){}
finally{
try{
// bw.flush();
// fw.flush();
bw.close();
fw.close();
}catch(Exception e){}
}
}
public static void dqjl()//读取记录
{
try{
fr=new FileReader(“e:\tanksavedata.txt”);
br=new BufferedReader(fr);
String b=br.readLine();
sumDtNum=Integer.parseInt(b);
}catch(Exception e){}
finally{
try{
br.close();
fr.close();
}catch(Exception e){}
}
}
public static void cunpan()//存盘
{
try{
fw=new FileWriter("e:\\tanksavedata.txt");
bw=new BufferedWriter(fw);
bw.write(sumDtNum+"\r\n");
for(int i=0;i
// bw.flush();//?
// fw.flush();//?
bw.close();
fw.close();
}catch(Exception e){}
}
}
public static Vector dupan()//读取cunpan记录
{
try{
fr=new FileReader(“e:\tanksavedata.txt”);
br=new BufferedReader(fr);
String b="";
b=br.readLine();
sumDtNum=Integer.parseInt(b);
while((b=br.readLine())!=null){
String[] st=b.split(" ");//用字符做间隔来确定数组元素
Weizhi wz=new Weizhi(Integer.parseInt(st[0]),Integer.parseInt(st[1]),Integer.parseInt(st[2]));
wzjh.add(wz);
}
}catch(Exception e){}
finally{
try{
br.close();
fr.close();
}catch(Exception e){}
}
return wzjh;
}
public Vector getDtk(){
return dtk;
}
public void setDtk(Vector dtk){
this.dtk=dtk;
}
}
class Weizhi//位置类
{
int x;
int y;
int fangxiang;
Weizhi(int x,int y,int fangxiang){
this.x=x;
this.y=y;
this.fangxiang=fangxiang;
}
}
// public static void setDtk(Vector dtk){
// this.dtk=dtk;
// }
// public static int getSumMtNum()//我的坦克数量统计方法
// {
// return sumMtNum;
// }
// br.read((char)aaaa);
// int a;
// for(int i=0;i
// a=bw.write(i);
//
// }
// br=new BufferedReader(fr); fr=new FileReader(“e:/tanksavedata.txt”);
// public static void setSumMtNum()//我的坦克数量统计方法 这个方法写的有问题!bug
// {
// sumMtNum=mtNum+addMtNum;
// }
//public static void setKillRecord()
//{
// killNum++;
//}
//public static int getKillRecord()
//{
// return killNum;
//}
//class Hit
//{
//
//
// }
// public void run(){
// while(true){
// try{
// Thread.sleep(1000);
// }catch(Exception e){}
//// if(time%4000){
// if(livetime>0){
// livetime–;
// }else{
// live=false;
// }
// if(this.livefalse)//重置生存时间
// {
// break;
// }
// }
// }