本科做的小项目,现在整理一下:
package T1;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.io.*;
import java.util.Vector;
//1
public class Tank1 extends JFrame implements ActionListener{//1
MyPanel mp=null;
GuankaPanel gkmp=null;
JMenuBar cdl=null;
JMenu cd1=null;
JMenuItem cdxl=null;
public static void main(String[] args) {
Tank1 t1=new Tank1();
}
public Tank1(){
// mp=new MyPanel();
//
// this.add(mp);
// //9,事件响应写完后,必须添加一个监听,否则坦克是动不起来的
// this.addKeyListener(mp);
// Thread t=new Thread(mp);//子弹可以自己运动,而不是随着坦克运动
// t.start();
cdl=new JMenuBar();
cd1=new JMenu("游戏(G)");
cd1.setMnemonic('G');
cdxl=new JMenuItem("新游戏(N)");
cdxl.addActionListener(this);
cdxl.setActionCommand("xyx");
cd1.add(cdxl);
cdl.add(cd1);
gkmp=new GuankaPanel();
Thread t=new Thread(gkmp);
t.start();
this.setJMenuBar(cdl);
this.add(gkmp);
this.setTitle("坦克大战");
this.setSize(600, 500);
this.setLocation(300, 280);
this.setResizable(false);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if(e.getActionCommand().equals("xyx")) {
mp=new MyPanel();
this.remove(gkmp);//删除旧面板
this.add(mp);
//9,事件响应写完后,必须添加一个监听,否则坦克是动不起来的
this.addKeyListener(mp);
Thread t=new Thread(mp);//子弹可以自己运动,而不是随着坦克运动
t.start();
this.setVisible(true);
}
}
}
class GuankaPanel extends JPanel implements Runnable{
int times=0;
public void paint(Graphics g) {
super.paint(g);
g.fillRect(0, 0, 400, 300);
if(times%2==0) {
g.setColor(Color.YELLOW);
Font myFont=new Font("华文行楷",Font.BOLD,38);
g.setFont(myFont);
g.drawString("第一关", 140, 140);
}
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true) {
try {
Thread.sleep(600);
}catch(Exception e) {}
times++;
this.repaint();
}
}
}
class MyPanel extends JPanel implements KeyListener,Runnable{//4
MyTank mt=null;
Vector dtk=new Vector();
//下一行子弹击中爆炸的diamagnetic
//Vector bzjh=new Vector();
//这个集合类只能放敌方坦克,所以用了泛型,避免强转
//敌方坦克是要编成坦克组的,所以需要集合类,Vector和ArrayList类似,但是ArrayList是单线程的
//全部由用户可控制用单线程ArrayList,随机性用多线程Vector
int tksl=3;
//下三行子弹击中爆炸的代码
// Image tp1=null;
// Image tp2=null;
// Image tp3=null;
//MyTank mt1=null;可以画第二个坦克,3,4,5,6,
public MyPanel() {
mt=new MyTank(140,232);
for(int i=0;i6)
// {
// g.drawImage(tp1, bz.x, bz.y, 30, 30, this);
//
// }else if(bz.shengcunqi>3)
// {
// g.drawImage(tp2, bz.x, bz.y, 30,30, this);
//
// }else {
// g.drawImage(tp3, bz.x, bz.y, 30, 30, this);
// }
// bz.suqsd();
// if(bz.shengcunqi==0) {
// bzjh.remove(bz);
//
// }
//
// }
}
public void jzwf() {
for(int i=0;idt.x && zd.xdt.y && zd.ydt.x && zd.xdt.y && zd.y
package T1;
import java.util.Vector;
class Tank{//2
//6充实坦克类
int x=0,y=0;//x为横坐标,y为纵坐标
//选中,右键-source-Generate Getters and Setters,生成下面的这些封装方法
//为坦克添加方向和速度,并且将方向和速度也封装起来
int fangxiang=0;
int sudu=5;
int Color;
boolean shengming=true;
public int getColor() {
return Color;
}
public void setColor(int color) {
Color = color;
}
public int getFangxiang() {
return fangxiang;
}
public void setFangxiang(int fangxiang) {
this.fangxiang = fangxiang;
}
public int getSudu() {
return sudu;
}
public void setSudu(int sudu) {
this.sudu = sudu;
}
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 Tank(int x,int y) {
//初始化横纵坐标
this.x=x;
this.y=y;
}
}
class DiTank extends Tank implements Runnable{
int sudu=7;//为了让敌人的坦克比自己的坦克快
int time=0;
Vector dzd=new Vector();
Vector dtk=new Vector();
public DiTank(int x, int y) {
super(x, y);
// TODO Auto-generated constructor stub
}
public void dtkxl(Vector dxl) {//避免敌方坦克的重叠
this.dtk=dxl;
}
public boolean huxiangpengzhuang() {
boolean b=false;
switch(this.fangxiang) {
case 0:
for(int i=0;i=dt.x && this.x<=dt.x+20 && this.y>=dt.y && this.y<=dt.y+30) {
return true;
}
if(this.x+20>=dt.x && this.x+20=dt.y && this.y<=dt.y+30) {
return true;
}
}
if(dt.fangxiang==1||dt.fangxiang==3) {
if(this.x>=dt.x && this.x<=dt.x+20 && this.y>=dt.y && this.y<=dt.y+30) {
return true;
}
if(this.x+20>=dt.x && this.x+20=dt.y && this.y<=dt.y+20) {
return true;
}
}
}
}
break;
case 1:
for(int i=0;i=dt.x && this.x<=dt.x+20 && this.y>=dt.y && this.y<=dt.y+30) {
return true;
}
if(this.x+20>=dt.x && this.x+20=dt.y && this.y<=dt.y+30) {
return true;
}
}
if(dt.fangxiang==1||dt.fangxiang==3) {
if(this.x>=dt.x && this.x<=dt.x+20 && this.y>=dt.y && this.y<=dt.y+30) {
return true;
}
if(this.x+20>=dt.x && this.x+20=dt.y && this.y<=dt.y+20) {
return true;
}
}
}
}
break;
case 2:
for(int i=0;i=dt.x && this.x<=dt.x+20 && this.y>=dt.y && this.y<=dt.y+30) {
return true;
}
if(this.x+20>=dt.x && this.x+20=dt.y && this.y<=dt.y+30) {
return true;
}
}
if(dt.fangxiang==1||dt.fangxiang==3) {
if(this.x>=dt.x && this.x<=dt.x+20 && this.y>=dt.y && this.y<=dt.y+30) {
return true;
}
if(this.x+20>=dt.x && this.x+20=dt.y && this.y<=dt.y+20) {
return true;
}
}
}
}
break;
case 3:
for(int i=0;i=dt.x && this.x<=dt.x+20 && this.y>=dt.y && this.y<=dt.y+30) {
return true;
}
if(this.x+20>=dt.x && this.x+20=dt.y && this.y<=dt.y+30) {
return true;
}
}
if(dt.fangxiang==1||dt.fangxiang==3) {
if(this.x>=dt.x && this.x<=dt.x+20 && this.y>=dt.y && this.y<=dt.y+30) {
return true;
}
if(this.x+20>=dt.x && this.x+20=dt.y && this.y<=dt.y+20) {
return true;
}
}
}
}
break;
}
return b;//因为上面所有的return 都在循环里面,所以编译器会认为不一定会有return被执行
}
@Override
public void run() {
// TODO Auto-generated method stub
// while(true) {
// try {
// Thread.sleep(50);
// }catch(Exception e) {}
// switch(this.fangxiang) {
// case 0:
// y-=sudu;
// break;
// case 1:
// x-=sudu;
// break;
// case 2:
// y+=sudu;
// break;
// case 3:
// x+=sudu;
// break;
//
//
// }
// this.fangxiang=(int)(Math.random()*4);//随机出现0-3之间的数字
// if(this.shengming==false) {//只有生命为假时,才能没有,不能坦克自己飞着就没了
// break;
//
// }
//
// }
//修改后让敌人的坦克可以运动一段时间再换方向,而不是随意的改变方向
while(true) {
switch(this.fangxiang) {
case 0:
for(int i=0;i<30;i++) {
if(y>0&& !huxiangpengzhuang()) {
y-=sudu;}
try {
Thread.sleep(50);
}catch(Exception e) {}
}
break;
case 1:
for(int i=0;i<30;i++) {//30这个数越大,它向着一个方向走的时间就越长
if(x>0 && !huxiangpengzhuang()) {//限制边界
x-=sudu;}
try {
Thread.sleep(50);
}catch(Exception e) {}
}
break;
case 2:
for(int i=0;i<30;i++) {
if(y<250 && !huxiangpengzhuang()) {//限制边界
y+=sudu;}
try {
Thread.sleep(50);
}catch(Exception e) {}
}
break;
case 3:
for(int i=0;i<30;i++) {
if(x<360 && !huxiangpengzhuang()) {
x+=sudu;}
try {
Thread.sleep(50);
}catch(Exception e) {}
}
break;
}
this.fangxiang=(int)(Math.random()*4);//随机出现0-3之间的数字
if(this.shengming==false) {//只有生命为假时,才能没有,不能坦克自己飞着就没了
break;
}
this.time++;
if(time%2==0) {//减慢子弹的发射速度,这样就是偶数发子弹,奇数就不发子弹了
if(shengming) {//先判断生命是否为假
if(dzd.size()<5) {//应许发五个子弹
Zidan zd=null;
switch(fangxiang) {//坦克方向,
case 0:
zd=new Zidan(x+10,y,0);//输入的坐标 new一个,添加进去
dzd.add(zd);
break;
case 1:
zd=new Zidan(x,y+10,1);
dzd.add(zd);
break;
case 2:
zd=new Zidan(x+10,y+30,2);
dzd.add(zd);
break;
case 3:
zd=new Zidan(x+30,y+10,3);
dzd.add(zd);
break;
}
Thread t5=new Thread(zd);
t5.start();
}
}
}
}
}
}
//公共属性放在Tank类中,然后再建立一个MyTank和敌人的Tank,并且对Tank类进行继承,使用公共属性
class MyTank extends Tank{//子弹发射必须写进MyTank类里,因为子弹发射是需要随着我的坦克走的,子弹的功能大多和坦克有关
Vectoraa=new Vector();//集合类要存就存,要取就取
//创建集合类是为了解决一次只能发送一颗子弹的问题
Zidan zd=null;
//3
//增加一个构造方法
public MyTank(int x, int y) {
super(x, y);
}
//7增加上下左右功能
public void xiangshang() {
y-=sudu;
}
public void xiangxia() {
y+=sudu;
}
public void xiangzuo() {
x-=sudu;
}
public void xiangyou() {
x+=sudu;
}
public void fszd() {
// TODO Auto-generated method stub
switch(this.fangxiang) {
//下面的左标就是画子弹的位置,不是子弹射出来,实质上是在相应的位置连续画出子弹,达到射击的效果
case 0://上
zd= new Zidan(x+10,y, 0);
aa.add(zd);//子弹只有一颗,为保证其连续性
break;
case 1://左
zd=new Zidan(x,y+10, 1);
aa.add(zd);
break;
case 2://下
zd=new Zidan(x+10,y+30, 2);
aa.add(zd);
break;
case 3://右
zd=new Zidan(x+30,y+10, 3);
aa.add(zd);
break;
}
//线程启动必须在Tank类中,因为子弹是随着坦克移动和发出的
Thread t=new Thread(zd);
t.start();
}
}
class Zidan implements Runnable{
int x;
int y;
int fangxiang;
int sudu=5;
boolean shengming=true;//这个参数就是为了防止子弹穿墙而过的
public Zidan(int x,int y,int fangxiang) {
this.x=x;
this.y=y;
this.fangxiang=fangxiang;
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true) {//死循环下面一般都需要异常处理
try{
Thread.sleep(50);
}catch(Exception e) {}
switch(fangxiang) {
case 0://上
y-=sudu;
break;
case 1://左
x-=sudu;
break;
case 2://下
y+=sudu;
break;
case 3://右
x+=sudu;
break;
}
if(x<0||x>400||y<0||y>300) {//画布边界
this.shengming=false;
break;//如果超出边界,就停止绘制子弹
}
}
}
}
//爆炸类,爆炸的代码
//class Baozha{
// int x,y;
// int shengcunqi=9;
// boolean shengming=true;
// public Baozha(int x,int y) {
// this.x=x;
// this.y=y;
//
// }
// public void suqsd() {
// if(shengcunqi>0) {
// shengcunqi--;
//
// }
// else {
// this.shengming=false;
// }
//
// }
//}
class Jilu{
private static int dtsl=10;
private static int mtsl=2;
public static int getDtsl() {
return dtsl;
}
public static void setDtsl(int dtsl) {
Jilu.dtsl = dtsl;
}
public static int getMtsl() {
return mtsl;
}
public static void setMtsl(int mtsl) {
Jilu.mtsl = mtsl;
}
public static void dtjs() {//敌人坦克减少
dtsl--;
}
}
运行结果:(键盘中的ADSW分别为左下右上,J是发射子弹)