坦克大战1.0:
1.首先建立我的面板Mypanel,继承JPanel ,引用 import javax.swing;
2.主函数要显示面板,使用Demo1类需要extends JFrame
3.绘图 Graphics 需要引用 import java.awt.*;
4.初始化不要忘了初始化 x y
5.整个Myframe 作为坦克的图形,设计好面板最终放入到框架中JFrame
6.Myframe中的画笔画出所有的图形,而JFrame只是设定一个显示框架
7.g.fillRect是为了将背景颜色进行修改
8.编写drawTank函数用g来画出坦克的形状,每调用一个drawTank只能画一个坦克
初步显示静止图形代码:
package demo1; import javax.swing.*; import java.awt.*; /** * 设计坦克形状 * * @author 王志 */ public class Demo1 extends JFrame { Myframe mp = null; public static void main(String[] args) { Demo1 demo = new Demo1(); } public Demo1() { mp = new Myframe(); this.add(mp); this.setSize(400, 300); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setVisible(true); } } // 定义我的面板,最终的显示窗口,整个面板作为坦克的形状 class Myframe extends JPanel { Hero hero; public void paint(Graphics g) {// JPanel的画图功能 g.fillRect(0, 0, 400, 300); this.drawTank(hero.getX(), hero.getY(), g, 0, 1); } public Myframe() { hero = new Hero(200, 100);// 设定位置 } // 画出坦克函数 type表示坦克类型,坦克的形状与type1有关 敌人0与自己1 public void drawTank(int x, int y, Graphics g, int direct, int type) { // 为坦克上色 switch (type) { case 0:// 敌人的坦克 g.setColor(Color.CYAN); case 1:// 我的坦克 g.setColor(Color.YELLOW); } // 判断方向 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, x + 10, y + 15); break; case 1: case 2: case 3: } } }
怎么样让坦克动起来?
事件监听:
import java.awt.event.KeyEvent; import java.awt.event.KeyListener;
1.想要坦克动起来,首先需要设置KeyListener,在Myframe中定义接口,自动生成接口函数
2.在Hero中设置move函数 实现上下左右移动
3.为什么坦克还没有动?主函数加入加入 this.addKeyListener(mp),但是还没有动,还需要在 keyPressed函数中加入this.repeat()函数将面板重画
4.坦克的方向还未改变,switch(direct) 编写完整
可以移动的坦克代码:
package demo1; import javax.swing.*; import java.awt.*; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; /** * 设计坦克形状 * * @author 王志 */ public class Demo1 extends JFrame { Myframe mp = null; public static void main(String[] args) { Demo1 demo = new Demo1(); } public Demo1() { mp = new Myframe(); this.add(mp); this.addKeyListener(mp); this.setSize(400, 300); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setVisible(true); } } // 定义我的面板,最终的显示窗口,整个面板作为坦克的形状 class Myframe extends JPanel implements KeyListener { Hero hero; public void paint(Graphics g) {// JPanel的画图功能 g.fillRect(0, 0, 400, 300); this.drawTank(hero.getX(), hero.getY(), g, hero.direct, 1); } public Myframe() { hero = new Hero(200, 100);// 设定位置 } // 画出坦克函数 type表示坦克类型,坦克的形状与type1有关 敌人0与自己1 public void drawTank(int x, int y, Graphics g, int direct, int type) { // 为坦克上色 switch (type) { case 0:// 敌人的坦克 g.setColor(Color.CYAN); case 1:// 我的坦克 g.setColor(Color.YELLOW); } // 判断方向 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, x + 10, y + 15); 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 + 5, 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 + 5, y + 10, 10, 10); // 画出横线 g.drawLine(x + 10, y + 15, x + 10, 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 + 5, 10, 10); // 画出横线 g.drawLine(x, y + 10, x + 15, y + 10); break; } } @Override public void keyPressed(KeyEvent e) { // TODO Auto-generated method stub if (e.getKeyCode() == KeyEvent.VK_W) { // W 表示上 this.hero.setDirect(0); this.hero.moveup(); } else if (e.getKeyCode() == KeyEvent.VK_D) { // D 表示右 this.hero.setDirect(1); this.hero.moveright(); } else if (e.getKeyCode() == KeyEvent.VK_S) { // S 表示下 this.hero.setDirect(2); this.hero.movedown(); } else if (e.getKeyCode() == KeyEvent.VK_A) { // A 表示左 this.hero.setDirect(3); this.hero.moveleft(); } this.repaint(); } @Override public void keyReleased(KeyEvent e) { // TODO Auto-generated method stub } @Override public void keyTyped(KeyEvent e) { // TODO Auto-generated method stub } }
坦克大战2.0版本:(线程机制,编写敌方动态坦克)
package demo1; //横着x 竖着y import java.awt.*; import javax.swing.*; import java.awt.Event.*; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.util.*; public class Demo2 extends JFrame { Myframe mp; public static void main(String[] args) { Demo2 demo = new Demo2(); } public Demo2() { mp = new Myframe(); // 启动mp线程 Thread t = new Thread(mp); t.start(); this.add(mp); this.setSize(400, 300); this.addKeyListener(mp); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setVisible(true); } } // Myframe定义的面板用于绘图 class Myframe extends JPanel implements KeyListener, Runnable { // 定义我的坦克 Hero hero; // 定义敌人的坦克 Vector<EnemyTank> ets = new Vector<EnemyTank>(); int ensize = 3; public void paint(Graphics g) { super.paint(g); g.fillRect(0, 0, 400, 300); this.drawTank(hero.getX(), hero.getY(), g, this.hero.getDirect(), 1);// 可以实现坦克的类型0 // 画出自己的子弹 if (hero.p != null && hero.p.islive == true) { g.draw3DRect(hero.p.x, hero.p.y, 3, 3, false); } // 画出敌人的坦克 for (int i = 0; i < ets.size(); i++) { this.drawTank(ets.get(i).getX(), ets.get(i).getY(), g, ets.get(i).getDirect(), 0); } } public Myframe() { hero = new Hero(100, 50);// 初始化坦克 // 初始化敌人的坦克 for (int i = 0; i < ensize; i++) { // 生产坦克 EnemyTank et = new EnemyTank((i + 1) * 50, 0); et.setColor(0); et.setDirect(2); ets.add(et); } } // 画出坦克的函数 public void drawTank(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, x + 10, y + 15); 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 + 5, 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 + 5, y + 10, 10, 10); // 画出线 g.drawLine(x + 10, y + 15, x + 10, 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 + 5, 10, 10); g.drawLine(x + 0, y + 10, x + 15, y + 10); break; } } @Override public void keyPressed(KeyEvent e) { // TODO Auto-generated method stub if (e.getKeyCode() == KeyEvent.VK_W) { // 上 this.hero.setDirect(0); this.hero.moveup(); } else if (e.getKeyCode() == KeyEvent.VK_D) { // 右 this.hero.setDirect(1); this.hero.moveright(); } else if (e.getKeyCode() == KeyEvent.VK_S) { // 下 this.hero.setDirect(2); this.hero.movedown(); } else if (e.getKeyCode() == KeyEvent.VK_A) { // 左 this.hero.setDirect(3); this.hero.moveleft(); } if (e.getKeyCode() == KeyEvent.VK_J) { // 判断玩家是否按下 this.hero.shote(); } // 重新绘制panel 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() { // 每100毫秒进行重绘制 while (true) { try { Thread.sleep(100); } catch (Exception e) { // TODO: handle exception } this.repaint(); } } } class Tank { int x; int y; int direct = 0;// 0 表示上 1表示右 2表示下 3表示左 int speed = 5; int color = 0; 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 Tank(int x, int y) { 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; } } class Hero extends Tank { shot p = null; public Hero(int x, int y) { super(x, y); } // 开火 public void shote() { switch (this.direct) { case 0: p = new shot(x + 10, y, 0); break; case 1: p = new shot(x + 30, y + 10, 1); break; case 2: p = new shot(x + 10, y + 30, 2); break; case 3: p = new shot(x, y + 10, 3); break; } Thread s = new Thread(p); s.start(); } public void moveup() { y -= speed; } public void moveright() { x += speed; } public void movedown() { y += speed; } public void moveleft() { x -= speed; } } class shot implements Runnable { int x, y; int direct, speed = 3; boolean islive = true; public shot(int x, int y, int direct) { this.x = x; this.y = y; this.direct = direct; // this.speed=speed; } @Override public void run() { while (true) { try { Thread.sleep(50); } catch (Exception e) { // TODO: handle exception } switch (direct) { case 0: y -= speed; break; case 1: x += speed; break; case 2: y += speed; break; case 3: x -= speed; } // 子弹坐标 System.out.println("子弹坐标x= " + x + "y=" + y); // 判断该子弹是否碰到边缘 if (x < 0 || x > 400 || y < 0 || y > 300) { this.islive = false; break; } } } }
首先增加敌方坦克
1.面板中定义敌方坦克容器
2.构造函数对敌方坦克进行初始化
3.绘图g画出坦克模型,
package demo1; import javax.swing.*; import java.awt.*; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.util.*; /** * 设计坦克形状 * * @author 王志 */ public class Demo1 extends JFrame { Myframe mp = null; public static void main(String[] args) { Demo1 demo = new Demo1(); } public Demo1() { mp = new Myframe(); this.add(mp); this.addKeyListener(mp); this.setSize(400, 300); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setVisible(true); } } // 定义我的面板,最终的显示窗口,整个面板作为坦克的形状 class Myframe extends JPanel implements KeyListener { Hero hero; // 初始化我的敌人 Vector<EnemyTank> ets = new Vector<EnemyTank>(); int ensize = 3; public void paint(Graphics g) {// JPanel的画图功能 g.fillRect(0, 0, 400, 300); this.drawTank(hero.getX(), hero.getY(), g, hero.direct, 1); // 画出子弹 if (hero.s != null) { g.draw3DRect(hero.x, hero.y, 1, 1, false); } // 画出敌人的坦克 for (int i = 0; i < ets.size(); i++) { this.drawTank(ets.get(i).getX(), ets.get(i).getY(), g, ets.get(i).getDirect(), 0); } } public Myframe() { hero = new Hero(200, 100);// 设定位置 // 这里进行设坦克的数目 for (int i = 0; i < ensize; i++) { EnemyTank et = new EnemyTank((i + 1) * 50, 0); et.setColor(0); et.setDirect(2); ets.add(et);// 放入容器 } } // 画出坦克函数 type表示坦克类型,坦克的形状与type1有关 敌人0与自己1 public void drawTank(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, x + 10, y + 15); 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 + 5, 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 + 5, y + 10, 10, 10); // 画出横线 g.drawLine(x + 10, y + 15, x + 10, 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 + 5, 10, 10); // 画出横线 g.drawLine(x, y + 10, x + 15, y + 10); break; } } @Override public void keyPressed(KeyEvent e) { // TODO Auto-generated method stub if (e.getKeyCode() == KeyEvent.VK_W) { // W 表示上 this.hero.setDirect(0); this.hero.moveup(); } else if (e.getKeyCode() == KeyEvent.VK_D) { // D 表示右 this.hero.setDirect(1); this.hero.moveright(); } else if (e.getKeyCode() == KeyEvent.VK_S) { // S 表示下 this.hero.setDirect(2); this.hero.movedown(); } else if (e.getKeyCode() == KeyEvent.VK_A) { // A 表示左 this.hero.setDirect(3); this.hero.moveleft(); } // 判断玩家是否发射了炮弹J if (e.getKeyCode() == KeyEvent.VK_J) { // 开火 this.hero.shot(); } this.repaint(); } @Override public void keyReleased(KeyEvent e) { // TODO Auto-generated method stub } @Override public void keyTyped(KeyEvent e) { // TODO Auto-generated method stub } }
标准代码;
主函数Demo1:
package demo1; import javax.swing.*; import java.awt.*; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; /** * 设计坦克形状 * * @author 王志 */ public class Demo1 extends JFrame { Myframe mp = null; public static void main(String[] args) { Demo1 demo = new Demo1(); } public Demo1() { mp = new Myframe(); Thread t = new Thread(mp); t.start(); this.add(mp); this.addKeyListener(mp); this.setSize(400, 300); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setVisible(true); } } // 定义我的面板,最终的显示窗口,整个面板作为坦克的形状 class Myframe extends JPanel implements KeyListener, Runnable { Hero hero; public void paint(Graphics g) {// JPanel的画图功能 g.fillRect(0, 0, 400, 300); this.drawTank(hero.getX(), hero.getY(), g, hero.direct, 1); // 画出自己的子弹 if (hero.p != null && hero.p.islive == true) { g.draw3DRect(hero.p.x, hero.p.y, 3, 3, false); } } public Myframe() { hero = new Hero(200, 100);// 设定位置 } // 画出坦克函数 type表示坦克类型,坦克的形状与type1有关 敌人0与自己1 public void drawTank(int x, int y, Graphics g, int direct, int type) { // 为坦克上色 switch (type) { case 0:// 敌人的坦克 g.setColor(Color.CYAN); case 1:// 我的坦克 g.setColor(Color.YELLOW); } // 判断方向 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, x + 10, y + 15); 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 + 5, 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 + 5, y + 10, 10, 10); // 画出横线 g.drawLine(x + 10, y + 15, x + 10, 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 + 5, 10, 10); // 画出横线 g.drawLine(x, y + 10, x + 15, y + 10); break; } } @Override public void keyPressed(KeyEvent e) { // TODO Auto-generated method stub if (e.getKeyCode() == KeyEvent.VK_W) { // W 表示上 this.hero.setDirect(0); this.hero.moveup(); } else if (e.getKeyCode() == KeyEvent.VK_D) { // D 表示右 this.hero.setDirect(1); this.hero.moveright(); } else if (e.getKeyCode() == KeyEvent.VK_S) { // S 表示下 this.hero.setDirect(2); this.hero.movedown(); } else if (e.getKeyCode() == KeyEvent.VK_A) { // A 表示左 this.hero.setDirect(3); this.hero.moveleft(); } if (e.getKeyCode() == KeyEvent.VK_J) { // 判断玩家是否按下 this.hero.shote(); } 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() {// 重绘 // TODO Auto-generated method stub // 每100毫秒进行重绘制 while (true) { try { Thread.sleep(100); } catch (Exception e) { // TODO: handle exception } this.repaint(); } } }
Tank:
package demo1; public class Tank { int x; int y; int direct = 0;// 0 表示上 1表示右 2表示下 3表示左 int speed = 5; int color = 0; Shot p=null; //开火 public void shote() { switch (this.direct) { case 0: p = new Shot(x + 10, y, 0); break; case 1: p = new Shot(x + 30, y + 10, 1); break; case 2: p = new Shot(x + 10, y + 30, 2); break; case 3: p = new Shot(x, y + 10, 3); break; } Thread s = new Thread(p); s.start(); } 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 Tank(int x, int y) { 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 void moveup() { y -= speed; } public void moveright() { x += speed; } public void movedown() { y += speed; } public void moveleft() { x -= speed; } } class Hero extends Tank { public Hero(int x, int y) { super(x, y); } }
炮弹Shot
package demo1; class Shot implements Runnable { int x, y; int direct, speed = 3; boolean islive = true; public Shot(int x, int y, int direct) { this.x = x; this.y = y; this.direct = direct; // this.speed=speed; } @Override public void run() { while (true) { try { Thread.sleep(50); } catch (Exception e) { // TODO: handle exception } switch (direct) { case 0: y -= speed; break; case 1: x += speed; break; case 2: y += speed; break; case 3: x -= speed; } // 子弹坐标 System.out.println("子弹坐标x= " + x + "y=" + y); // 判断该子弹是否碰到边缘 if (x < 0 || x > 400 || y < 0 || y > 300) { this.islive = false; break; } } } }
怎么实现连发?
子弹是坦克的属性,设计弹夹,然后绘制
可以连发后最多连发五颗子弹?
连发五颗后就没子弹了,怎么上子弹? 从弹夹中删除弹壳
package demo1; import javax.swing.*; import java.awt.*; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.util.*; /** * 设计坦克形状 * * @author 王志 */ public class Demo1 extends JFrame { Myframe mp = null; public static void main(String[] args) { Demo1 demo = new Demo1(); } public Demo1() { mp = new Myframe(); Thread t = new Thread(mp); t.start(); this.add(mp); this.addKeyListener(mp); this.setSize(400, 300); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setVisible(true); } } // 定义我的面板,最终的显示窗口,整个面板作为坦克的形状 class Myframe extends JPanel implements KeyListener, Runnable { Hero hero; // 加入敌人的坦克(数量不确定用容器) Vector<Enemy> enemy = new Vector<Enemy>(); int ensize = 3; public void paint(Graphics g) {// JPanel的画图功能 g.fillRect(0, 0, 400, 300); this.drawTank(hero.getX(), hero.getY(), g, hero.direct, 1); // 画出敌方的坦克 for (int i = 0; i < ensize; i++) { this.drawTank(enemy.get(i).getX(), enemy.get(i).getY(), g, enemy.get(i).getDirect(), 0); } // 从弹夹中取出每一颗子弹 for (int i = 0; i < this.hero.m.size(); i++) { Shot myshot = hero.m.get(i); // 画出自己的子弹 (一颗) if (myshot != null && myshot.islive == true) { // g.setColor(Color.red); g.draw3DRect(myshot.x, myshot.y, 3, 3, false); } else { // 从m中删除子弹 hero.m.remove(myshot);// 为什么不用i } } } public Myframe() { hero = new Hero(200, 100);// 设定位置 // 初始化敌方坦克 // 初始化敌人的坦克 for (int i = 0; i < ensize; i++) { // 生产坦克 Enemy et = new Enemy((i + 1) * 50, 0); // et.set enemy.add(et); } } // 画出坦克函数 type表示坦克类型,坦克的形状与type1有关 敌人0与自己1 public void drawTank(int x, int y, Graphics g, int direct, int type) { // 为坦克上色 switch (type) { case 0:// 敌人的坦克 g.setColor(Color.cyan); break;// 注意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, x + 10, y + 15); 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 + 5, 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 + 5, y + 10, 10, 10); // 画出横线 g.drawLine(x + 10, y + 15, x + 10, 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 + 5, 10, 10); // 画出横线 g.drawLine(x, y + 10, x + 15, y + 10); break; } } @Override public void keyPressed(KeyEvent e) { // TODO Auto-generated method stub if (e.getKeyCode() == KeyEvent.VK_W) { // W 表示上 this.hero.setDirect(0); this.hero.moveup(); } else if (e.getKeyCode() == KeyEvent.VK_D) { // D 表示右 this.hero.setDirect(1); this.hero.moveright(); } else if (e.getKeyCode() == KeyEvent.VK_S) { // S 表示下 this.hero.setDirect(2); this.hero.movedown(); } else if (e.getKeyCode() == KeyEvent.VK_A) { // A 表示左 this.hero.setDirect(3); this.hero.moveleft(); } if (e.getKeyCode() == KeyEvent.VK_J) { if (this.hero.m.size() <= 5) { // 判断玩家是否按下 this.hero.shote(); } } 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() {// 重绘 // TODO Auto-generated method stub // 每100毫秒进行重绘制 while (true) { try { Thread.sleep(100); } catch (Exception e) { // TODO: handle exception } this.repaint(); } } }
打中坦克后消失,怎么判断打中坦克?
1.选中一个函数判断是否打中,位置在Mypanel中
s.islive=false;
et.islive=false;
在什么地方调用判断函数,随时判断run函数
定义完成后,修改Mypanel的画坦克函数
package demo1; import javax.swing.*; import java.awt.*; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.util.*; /** * 设计坦克形状 * * @author 王志 */ public class Demo1 extends JFrame { Myframe mp = null; public static void main(String[] args) { Demo1 demo = new Demo1(); } public Demo1() { mp = new Myframe(); Thread t = new Thread(mp); t.start(); this.add(mp); this.addKeyListener(mp); this.setSize(400, 300); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setVisible(true); } } // 定义我的面板,最终的显示窗口,整个面板作为坦克的形状 class Myframe extends JPanel implements KeyListener, Runnable { Hero hero; // 加入敌人的坦克(数量不确定用容器) Vector<Enemy> enemy = new Vector<Enemy>(); int ensize = 3; public void paint(Graphics g) {// JPanel的画图功能 g.fillRect(0, 0, 400, 300); this.drawTank(hero.getX(), hero.getY(), g, hero.direct, 1); // 画出敌方的坦克 for (int i = 0; i < ensize; i++) { Enemy et = enemy.get(i); if (et.islive) { // 这里用et代替 this.drawTank(enemy.get(i).getX(), enemy.get(i).getY(), g, enemy.get(i).getDirect(), 0); } } // 从弹夹中取出每一颗子弹 for (int i = 0; i < this.hero.m.size(); i++) { Shot myshot = hero.m.get(i); // 画出自己的子弹 (一颗) if (myshot != null && myshot.islive == true) { // g.setColor(Color.red); g.draw3DRect(myshot.x, myshot.y, 3, 3, false); } else { // 从m中删除子弹 hero.m.remove(myshot);// 为什么不用i } } } public Myframe() { hero = new Hero(200, 100);// 设定位置 // 初始化敌方坦克 // 初始化敌人的坦克 for (int i = 0; i < ensize; i++) { // 生产坦克 Enemy et = new Enemy((i + 1) * 50, 0); // et.set enemy.add(et); } } // 写出一个函数判断是否打中坦克 对象:子弹 敌方坦克 public void hitTank(Shot s, Enemy et) { // 判断坦克的方向 主要是向上 向下 两种位置状态 switch (et.direct) { case 0: case 2: if (s.x > et.x && s.x < et.x + 20 && s.y > et.y && s.y < et.y + 30) { // 击中 子弹死亡 敌人的坦克死亡 s.islive = false; et.islive = false; } break; case 1: case 3: if (s.x > et.x && s.x < et.x + 30 && s.y > et.y && s.y < et.y + 20) { // 击中 子弹死亡 敌人的坦克死亡 s.islive = false; et.islive = false; } break; } } // 画出坦克函数 type表示坦克类型,坦克的形状与type1有关 敌人0与自己1 public void drawTank(int x, int y, Graphics g, int direct, int type) { // 为坦克上色 switch (type) { case 0:// 敌人的坦克 g.setColor(Color.cyan); break;// 注意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, x + 10, y + 15); 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 + 5, 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 + 5, y + 10, 10, 10); // 画出横线 g.drawLine(x + 10, y + 15, x + 10, 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 + 5, 10, 10); // 画出横线 g.drawLine(x, y + 10, x + 15, y + 10); break; } } @Override public void keyPressed(KeyEvent e) { // TODO Auto-generated method stub if (e.getKeyCode() == KeyEvent.VK_W) { // W 表示上 this.hero.setDirect(0); this.hero.moveup(); } else if (e.getKeyCode() == KeyEvent.VK_D) { // D 表示右 this.hero.setDirect(1); this.hero.moveright(); } else if (e.getKeyCode() == KeyEvent.VK_S) { // S 表示下 this.hero.setDirect(2); this.hero.movedown(); } else if (e.getKeyCode() == KeyEvent.VK_A) { // A 表示左 this.hero.setDirect(3); this.hero.moveleft(); } if (e.getKeyCode() == KeyEvent.VK_J) { if (this.hero.m.size() <= 5) { // 判断玩家是否按下 this.hero.shote(); } } 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() {// 重绘 // TODO Auto-generated method stub // 每100毫秒进行重绘制 while (true) { try { Thread.sleep(100); } catch (Exception e) { // TODO: handle exception } // 判断是否击中 for (int i = 0; i < hero.m.size(); i++) { // 取出子弹 Shot myshot = hero.m.get(i); // 判断子弹是否有效 if (myshot.islive) { // 取出每一个坦克与他判断 for (int j = 0; j < enemy.size(); j++) { // 取出坦克 Enemy et = enemy.get(j); if (et.islive) { this.hitTank(myshot, et); } } } } this.repaint(); } } }
怎么产生爆炸效果?
炸弹好多可能都会爆炸,
1.准备三张照片
2.定义bom类
3.在击中敌人坦克时把炸弹放入
4.绘制
package demo1; import javax.swing.*; import java.awt.*; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.util.*; /** * 设计坦克形状 * * @author 王志 */ public class Demo1 extends JFrame { Myframe mp = null; public static void main(String[] args) { Demo1 demo = new Demo1(); } public Demo1() { mp = new Myframe(); Thread t = new Thread(mp); t.start(); this.add(mp); this.addKeyListener(mp); this.setSize(400, 300); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setVisible(true); } } // 定义我的面板,最终的显示窗口,整个面板作为坦克的形状 class Myframe extends JPanel implements KeyListener, Runnable { Hero hero; // 加入敌人的坦克(数量不确定用容器) Vector<Enemy> enemy = new Vector<Enemy>(); // 定义炸弹集合 Vector<Bom> bom = new Vector<Bom>(); int ensize = 3; // 定义三张图片,才能组成一炸弹 Image img1, img2, img3; public void paint(Graphics g) {// JPanel的画图功能 g.fillRect(0, 0, 400, 300); this.drawTank(hero.getX(), hero.getY(), g, hero.direct, 1); // 画出敌方的坦克 for (int i = 0; i < ensize; i++) { Enemy et = enemy.get(i); if (et.islive) { this.drawTank(enemy.get(i).getX(), enemy.get(i).getY(), g, enemy.get(i).getDirect(), 0); } } // 画出炸弹 for (int i = 0; i < bom.size(); i++) { System.out.println("你妈个比比比" + bom.size()); // 取出炸弹 Bom b = bom.get(i); if (b.life > 6) { g.drawImage(img1, b.x, b.y, 30, 30, this); } else if (b.life > 4) { g.drawImage(img2, b.x, b.y, 30, 30, this); } else { g.drawImage(img3, b.x, b.y, 30, 30, this); } b.lifeDown(); if (b.life == 0) { bom.remove(b); } } // 从弹夹中取出每一颗子弹 for (int i = 0; i < this.hero.m.size(); i++) { Shot myshot = hero.m.get(i); // 画出自己的子弹 (一颗) if (myshot != null && myshot.islive == true) { // g.setColor(Color.red); g.draw3DRect(myshot.x, myshot.y, 3, 3, false); } else { // 从m中删除子弹 hero.m.remove(myshot);// 为什么不用i } } } public Myframe() { hero = new Hero(200, 100);// 设定位置 // 初始化敌方坦克 // 初始化敌人的坦克 for (int i = 0; i < ensize; i++) { // 生产坦克 Enemy et = new Enemy((i + 1) * 50, 0); // et.set enemy.add(et); } // 初始化图片 img1 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/qq4.jpg")); img2 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/qq4.jpg")); img3 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/qq4.jpg")); } // 写出一个函数判断是否打中坦克 对象:子弹 敌方坦克 public void hitTank(Shot s, Enemy et) { // 判断坦克的方向 主要是向上 向下 两种位置状态 switch (et.direct) { case 0: case 2: if (s.x > et.x && s.x < et.x + 20 && s.y > et.y && s.y < et.y + 30) { // 击中 子弹死亡 敌人的坦克死亡 s.islive = false; et.islive = false; // 创建一颗炸弹, Bom b = new Bom(et.x, et.y); // 放入到vector bom.add(b); } break; case 1: case 3: if (s.x > et.x && s.x < et.x + 30 && s.y > et.y && s.y < et.y + 20) { // 击中 子弹死亡 敌人的坦克死亡 s.islive = false; et.islive = false; // 创建一颗炸弹 Bom b = new Bom(et.x, et.y); // 放入到vector bom.add(b); } break; } } // 画出坦克函数 type表示坦克类型,坦克的形状与type1有关 敌人0与自己1 public void drawTank(int x, int y, Graphics g, int direct, int type) { // 为坦克上色 switch (type) { case 0:// 敌人的坦克 g.setColor(Color.cyan); break;// 注意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, x + 10, y + 15); 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 + 5, 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 + 5, y + 10, 10, 10); // 画出横线 g.drawLine(x + 10, y + 15, x + 10, 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 + 5, 10, 10); // 画出横线 g.drawLine(x, y + 10, x + 15, y + 10); break; } } @Override public void keyPressed(KeyEvent e) { // TODO Auto-generated method stub if (e.getKeyCode() == KeyEvent.VK_W) { // W 表示上 this.hero.setDirect(0); this.hero.moveup(); } else if (e.getKeyCode() == KeyEvent.VK_D) { // D 表示右 this.hero.setDirect(1); this.hero.moveright(); } else if (e.getKeyCode() == KeyEvent.VK_S) { // S 表示下 this.hero.setDirect(2); this.hero.movedown(); } else if (e.getKeyCode() == KeyEvent.VK_A) { // A 表示左 this.hero.setDirect(3); this.hero.moveleft(); } if (e.getKeyCode() == KeyEvent.VK_J) { if (this.hero.m.size() <= 5) { // 判断玩家是否按下 this.hero.shote(); } } 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() {// 重绘 // TODO Auto-generated method stub // 每100毫秒进行重绘制 while (true) { try { Thread.sleep(1000); } catch (Exception e) { // TODO: handle exception } // 判断是否击中 for (int i = 0; i < hero.m.size(); i++) { // 取出子弹 Shot myshot = hero.m.get(i); // 判断子弹是否有效 if (myshot.islive) { // 取出每一个坦克与他判断 for (int j = 0; j < enemy.size(); j++) { // 取出坦克 Enemy et = enemy.get(j); if (et.islive) { this.hitTank(myshot, et); } } } } this.repaint(); } } }
让敌人的坦克也可以自由的移动:
package demo1; import javax.swing.*; import java.awt.*; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.util.*; /** * 设计坦克形状 * * @author 王志 */ public class Demo1 extends JFrame { Myframe mp = null; public static void main(String[] args) { Demo1 demo = new Demo1(); } public Demo1() { mp = new Myframe(); Thread t = new Thread(mp); t.start(); this.add(mp); this.addKeyListener(mp); this.setSize(400, 300); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setVisible(true); } } // 定义我的面板,最终的显示窗口,整个面板作为坦克的形状 class Myframe extends JPanel implements KeyListener, Runnable { Hero hero; // 加入敌人的坦克(数量不确定用容器) Vector<Enemy> enemy = new Vector<Enemy>(); // 定义炸弹集合 Vector<Bom> bom = new Vector<Bom>(); int ensize = 3; // 定义三张图片,才能组成一炸弹 Image img1, img2, img3; public void paint(Graphics g) {// JPanel的画图功能 g.fillRect(0, 0, 400, 300); this.drawTank(hero.getX(), hero.getY(), g, hero.direct, 1); // 画出敌方的坦克 for (int i = 0; i < ensize; i++) { Enemy et = enemy.get(i); if (et.islive) { this.drawTank(enemy.get(i).getX(), enemy.get(i).getY(), g, enemy.get(i).getDirect(), 0); } } // 画出炸弹 for (int i = 0; i < bom.size(); i++) { System.out.println("你妈个比比比" + bom.size()); // 取出炸弹 Bom b = bom.get(i); if (b.life > 6) { g.drawImage(img1, b.x, b.y, 30, 30, this); } else if (b.life > 4) { g.drawImage(img2, b.x, b.y, 30, 30, this); } else { g.drawImage(img3, b.x, b.y, 30, 30, this); } b.lifeDown(); if (b.life == 0) { bom.remove(b); } } // 从弹夹中取出每一颗子弹 for (int i = 0; i < this.hero.m.size(); i++) { Shot myshot = hero.m.get(i); // 画出自己的子弹 (一颗) if (myshot != null && myshot.islive == true) { // g.setColor(Color.red); g.draw3DRect(myshot.x, myshot.y, 3, 3, false); } else { // 从m中删除子弹 hero.m.remove(myshot);// 为什么不用i } } } public Myframe() { hero = new Hero(200, 100);// 设定位置 // 初始化敌方坦克 // 初始化敌人的坦克 for (int i = 0; i < ensize; i++) { // 生产坦克 Enemy et = new Enemy((i + 1) * 50, 0); // 启动敌人的坦克 Thread t = new Thread(et); t.start(); enemy.add(et); } // 初始化图片 img1 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/qq4.jpg")); img2 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/qq4.jpg")); img3 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/qq4.jpg")); } // 写出一个函数判断是否打中坦克 对象:子弹 敌方坦克 public void hitTank(Shot s, Enemy et) { // 判断坦克的方向 主要是向上 向下 两种位置状态 switch (et.direct) { case 0: case 2: if (s.x > et.x && s.x < et.x + 20 && s.y > et.y && s.y < et.y + 30) { // 击中 子弹死亡 敌人的坦克死亡 s.islive = false; et.islive = false; // 创建一颗炸弹, Bom b = new Bom(et.x, et.y); // 放入到vector bom.add(b); } break; case 1: case 3: if (s.x > et.x && s.x < et.x + 30 && s.y > et.y && s.y < et.y + 20) { // 击中 子弹死亡 敌人的坦克死亡 s.islive = false; et.islive = false; // 创建一颗炸弹 Bom b = new Bom(et.x, et.y); // 放入到vector bom.add(b); } break; } } // 画出坦克函数 type表示坦克类型,坦克的形状与type1有关 敌人0与自己1 public void drawTank(int x, int y, Graphics g, int direct, int type) { // 为坦克上色 switch (type) { case 0:// 敌人的坦克 g.setColor(Color.cyan); break;// 注意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, x + 10, y + 15); 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 + 5, 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 + 5, y + 10, 10, 10); // 画出横线 g.drawLine(x + 10, y + 15, x + 10, 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 + 5, 10, 10); // 画出横线 g.drawLine(x, y + 10, x + 15, y + 10); break; } } @Override public void keyPressed(KeyEvent e) { // TODO Auto-generated method stub if (e.getKeyCode() == KeyEvent.VK_W) { // W 表示上 this.hero.setDirect(0); this.hero.moveup(); } else if (e.getKeyCode() == KeyEvent.VK_D) { // D 表示右 this.hero.setDirect(1); this.hero.moveright(); } else if (e.getKeyCode() == KeyEvent.VK_S) { // S 表示下 this.hero.setDirect(2); this.hero.movedown(); } else if (e.getKeyCode() == KeyEvent.VK_A) { // A 表示左 this.hero.setDirect(3); this.hero.moveleft(); } if (e.getKeyCode() == KeyEvent.VK_J) { if (this.hero.m.size() <= 5) { // 判断玩家是否按下 this.hero.shote(); } } 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() {// 重绘 // TODO Auto-generated method stub // 每100毫秒进行重绘制 while (true) { try { Thread.sleep(100); } catch (Exception e) { // TODO: handle exception } // 判断是否击中 for (int i = 0; i < hero.m.size(); i++) { // 取出子弹 Shot myshot = hero.m.get(i); // 判断子弹是否有效 if (myshot.islive) { // 取出每一个坦克与他判断 for (int j = 0; j < enemy.size(); j++) { // 取出坦克 Enemy et = enemy.get(j); if (et.islive) { this.hitTank(myshot, et); } } } } this.repaint(); } } }
怎么样平缓的移动?坦克在范围内移动
package demo1; import java.util.*; public class Tank { int x; int y; int direct = 0;// 0 表示上 1表示右 2表示下 3表示左 int speed = 5; int color = 0; boolean islive=true; //Shot p=null; 关键点是建立容器 Vector<Shot> m=new Vector<Shot>(); Shot p; //开火 public void shote() { switch (this.direct) { //创建子弹加入弹夹 case 0: p = new Shot(x + 10, y, 0); m.add(p); break; case 1: p = new Shot(x + 30, y + 10, 1); m.add(p); break; case 2: p = new Shot(x + 10, y + 30, 2); m.add(p); break; case 3: p = new Shot(x, y + 10, 3); m.add(p); break; } Thread s = new Thread(p); s.start(); } 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 Tank(int x, int y) { 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 void moveup() { y -= speed; } public void moveright() { x += speed; } public void movedown() { y += speed; } public void moveleft() { x -= speed; } } class Hero extends Tank { public Hero(int x, int y) { super(x, y); } } class Enemy extends Tank implements Runnable{ public Enemy(int x, int y) { super(x, y); // this.ensize=ensize; } @Override public void run() { // TODO Auto-generated method stub while(true){ try { Thread.sleep(50); } catch (Exception e) { // TODO: handle exception } // Math.random(); switch(this.direct){ case 0://向上走 for(int i=0;i<20;i++){ if(y>0){ y-=speed;} try { Thread.sleep(100); } catch (Exception e) { // TODO: handle exception } } break; case 1://向右走 for(int i=0;i<20;i++){ if(x<400){ x+=2*speed;} try { Thread.sleep(100); } catch (Exception e) { // TODO: handle exception } } break; case 2: for(int i=0;i<20;i++){ if(y<200){ y+=speed;} try { Thread.sleep(100); } catch (Exception e) { // TODO: handle exception } } break; case 3: for(int i=0;i<20;i++){ if(x>0){ x-=speed;} try { Thread.sleep(100); } catch (Exception e) { // TODO: handle exception } } break; } //让坦克产生一个随机的方向 this.direct=(int) (Math.random()*4); //判断敌人坦克是否死亡 if(this.islive==false){ //让坦克死亡后退出 break; } } } }
让敌人的坦克也可以发射子弹:
package demo1; import javax.swing.*; import java.awt.*; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.util.*; /** * 设计坦克形状 * * @author 王志 */ public class Demo1 extends JFrame { Myframe mp = null; public static void main(String[] args) { Demo1 demo = new Demo1(); } public Demo1() { mp = new Myframe(); Thread t = new Thread(mp); t.start(); this.add(mp); this.addKeyListener(mp); this.setSize(400, 300); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setVisible(true); } } // 定义我的面板,最终的显示窗口,整个面板作为坦克的形状 class Myframe extends JPanel implements KeyListener, Runnable { Hero hero; // 加入敌人的坦克(数量不确定用容器) Vector<Enemy> enemy = new Vector<Enemy>(); // 定义炸弹集合 Vector<Bom> bom = new Vector<Bom>(); int ensize = 3; // 定义三张图片,才能组成一炸弹 Image img1, img2, img3; public void paint(Graphics g) {// JPanel的画图功能 g.fillRect(0, 0, 400, 300); this.drawTank(hero.getX(), hero.getY(), g, hero.direct, 1); // 画出敌方的坦克 for (int i = 0; i < ensize; i++) { Enemy et = enemy.get(i); if (et.islive) { this.drawTank(enemy.get(i).getX(), enemy.get(i).getY(), g, enemy.get(i).getDirect(), 0); for(int j=0;j<et.m.size();j++){ //取出子弹 Shot xx=et.m.get(j); if(xx.islive){ g.draw3DRect(xx.x, xx.y, 3, 3, false); } } } } // 画出炸弹 for (int i = 0; i < bom.size(); i++) { System.out.println("你妈个比比比" + bom.size()); // 取出炸弹 Bom b = bom.get(i); if (b.life > 6) { g.drawImage(img1, b.x, b.y, 30, 30, this); } else if (b.life > 4) { g.drawImage(img2, b.x, b.y, 30, 30, this); } else { g.drawImage(img3, b.x, b.y, 30, 30, this); } b.lifeDown(); if (b.life == 0) { bom.remove(b); } } // 从弹夹中取出每一颗子弹 for (int i = 0; i < this.hero.m.size(); i++) { Shot myshot = hero.m.get(i); // 画出自己的子弹 (一颗) if (myshot != null && myshot.islive == true) { // g.setColor(Color.red); g.draw3DRect(myshot.x, myshot.y, 3, 3, false); } else { // 从m中删除子弹 hero.m.remove(myshot);// 为什么不用i } } } public Myframe() { hero = new Hero(200, 100);// 设定位置 // 初始化敌方坦克 // 初始化敌人的坦克 for (int i = 0; i < ensize; i++) { // 生产坦克 Enemy et = new Enemy((i + 1) * 50, 0); // 启动敌人的坦克 Thread t = new Thread(et); t.start(); //给敌人的坦克加子弹 Shot s=new Shot(et.x+10,et.y+30,2); et.m.add(s); Thread t2=new Thread(s); t2.start(); enemy.add(et); } // 初始化图片 img1 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/qq4.jpg")); img2 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/qq4.jpg")); img3 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/qq4.jpg")); } // 写出一个函数判断是否打中坦克 对象:子弹 敌方坦克 public void hitTank(Shot s, Enemy et) { // 判断坦克的方向 主要是向上 向下 两种位置状态 switch (et.direct) { case 0: case 2: if (s.x > et.x && s.x < et.x + 20 && s.y > et.y && s.y < et.y + 30) { // 击中 子弹死亡 敌人的坦克死亡 s.islive = false; et.islive = false; // 创建一颗炸弹, Bom b = new Bom(et.x, et.y); // 放入到vector bom.add(b); } break; case 1: case 3: if (s.x > et.x && s.x < et.x + 30 && s.y > et.y && s.y < et.y + 20) { // 击中 子弹死亡 敌人的坦克死亡 s.islive = false; et.islive = false; // 创建一颗炸弹 Bom b = new Bom(et.x, et.y); // 放入到vector bom.add(b); } break; } } // 画出坦克函数 type表示坦克类型,坦克的形状与type1有关 敌人0与自己1 public void drawTank(int x, int y, Graphics g, int direct, int type) { // 为坦克上色 switch (type) { case 0:// 敌人的坦克 g.setColor(Color.cyan); break;// 注意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, x + 10, y + 15); 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 + 5, 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 + 5, y + 10, 10, 10); // 画出横线 g.drawLine(x + 10, y + 15, x + 10, 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 + 5, 10, 10); // 画出横线 g.drawLine(x, y + 10, x + 15, y + 10); break; } } @Override public void keyPressed(KeyEvent e) { // TODO Auto-generated method stub if (e.getKeyCode() == KeyEvent.VK_W) { // W 表示上 this.hero.setDirect(0); this.hero.moveup(); } else if (e.getKeyCode() == KeyEvent.VK_D) { // D 表示右 this.hero.setDirect(1); this.hero.moveright(); } else if (e.getKeyCode() == KeyEvent.VK_S) { // S 表示下 this.hero.setDirect(2); this.hero.movedown(); } else if (e.getKeyCode() == KeyEvent.VK_A) { // A 表示左 this.hero.setDirect(3); this.hero.moveleft(); } if (e.getKeyCode() == KeyEvent.VK_J) { if (this.hero.m.size() <= 5) { // 判断玩家是否按下 this.hero.shote(); } } 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() {// 重绘 // TODO Auto-generated method stub // 每100毫秒进行重绘制 while (true) { try { Thread.sleep(100); } catch (Exception e) { // TODO: handle exception } // 判断是否击中 for (int i = 0; i < hero.m.size(); i++) { // 取出子弹 Shot myshot = hero.m.get(i); // 判断子弹是否有效 if (myshot.islive) { // 取出每一个坦克与他判断 for (int j = 0; j < enemy.size(); j++) { // 取出坦克 Enemy et = enemy.get(j); if (et.islive) { this.hitTank(myshot, et); } } } } this.repaint(); } } }
修改后能敌人随便打子弹: