java项目笔记 - 第16章:坦克大战1.0
第16章:坦克大战1.0
- 总体内容
- 项目说明
- java绘图坐标体系
- 坐标体系 - 介绍
- 坐标体系 - 像素
- java绘图技术
- 绘图快速入门案例
- 绘图中的paint()
- 绘图常用方法
- 项目:绘制游戏区域
- 项目:绘制坦克
- java事件处理机制
- 案例:小球移动
- 事件处理机制
- 基本说明
- 概念说明
- 项目:控制坦克上下左右移动(代码改进过程)
- 本章作业
总体内容
- 1.0版本包括:绘制游戏区域,绘制坦克(敌人和我方),实现用键盘按键来操控坦克上下左右移动(且移动过程中,坦克炮筒朝向发生变化)
- 本文中的案例包括:
①用java在面板上画一个圆圈
②小球受键盘按键控制进行移动,- 本文中项目完成包括:
①绘制游戏区域
②绘制我方坦克
③控制坦克上下左右移动
④绘制敌人坦克(注意炮筒方向)
项目说明
坦克大战的演示就省略了,和小时候玩的坦克大战差不多
java绘图坐标体系
坐标体系 - 介绍
坐标体系 - 像素
java绘图技术
绘图快速入门案例
案例要求:在面板上画一个小圆
步骤:
- 写一个面板类MyPanel(继承Panel),重写paint()(绘图)方法,在方法内调用Graphics(画笔)的方法drawOval()来画园
- 写一个窗口类Excise(继承JFrame),在窗口类中定义一个面板对象,在构造器中初始化该对象,并把面板放到窗口中,设置窗口大小和是否可见
- 在主方法中创建窗口类对象。创建对象时会调用构造器,对窗口和面板进行设置,并调用paint()方法绘制圆
import javax.swing.*;
import java.awt.*;//JFrame 相当于一个窗口
// 本例中窗口(Excise继承了JFrame)内有一画板(MyPanel),用画笔(Graphics)来绘图
public class Excise extends JFrame {//JFrame对应一个窗口//定义一个面板private MyPanel mp = null;//主方法public static void main(String[] args) {new Excise();}//构造器public Excise() {//初始化面板mp = new MyPanel();//把面板放到窗口中this.add(mp);//设置窗口大小this.setSize(400, 300);//设置窗口可以显示this.setVisible(true);//设置 当点击窗口的X时,程序完全退出this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);}
}//定义一个MyPanel类(面板类),继承JPanel
// 画图形,就在面板上画
class MyPanel extends JPanel {//说明://1. MyPanel对象 相当于一个画板//2. Graphics g 这里g相当于画笔//3. Graphics中提供了很多绘图的方法@Overridepublic void paint(Graphics g) {//paint()是绘图方法super.paint(g);//调用父类的方法完成初始化(不可省略)//画出一个圆,调用Graphics的drawOval()方法g.drawOval(10, 10, 100, 100);}
}
输出结果:
绘图中的paint()
绘图常用方法
- 画直线:drawLine方法 - 第1,2个参数为起点,第3,4个参数为终点(如果起点和重点的x值不同,则为斜线)
- 画矩形:drawRect方法 - 第1,2个参数为起点,第3,4个参数为长和宽
- 画填充矩形:fillRect方法
①先设置画笔的颜色g.setColor(Color.blue);
②再画填充颜色后的矩形g.fillRect(10,10,100,100);
- 画图片
先把图片copy到out下的项目文件夹下面
画图片的代码(2步):
输出结果:
- 画字符串(也就是写字)–>三步
给画笔设置颜色和字体,然后再写字
项目:绘制游戏区域
游戏中有很多坦克,所以我们将坦克先抽象成一个父类,定义一些方法让子类去继承
Tank.java
package com.wpz.tankgame;/*** @author 王胖子* @version 1.0* 因为该游戏会有很多坦克* 所以先抽象成一个父类*/
public class Tank {private int x;//坦克横坐标private int y;//坦克纵坐标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;}
}
编写我的坦克->继承Tank
MyTank.java
package com.wpz.tankgame;/*** @author 王胖子* @version 1.0* 我的坦克*/
public class MyTank extends Tank {public MyTank(int x, int y) {super(x, y);}
}
编写面板类->继承Jpanel(在面板上绘制游戏区域)
MyPanel.java
package com.wpz.tankgame;import javax.swing.*;
import java.awt.*;/*** @author 王胖子* @version 1.0* 坦克大战的绘图区域*/
public class MyPanel extends JPanel {MyTank myTank = null;//在绘图区域中先定义一个自己的坦克public MyPanel() {myTank = new MyTank(100, 100);//初始化自己的坦克}@Overridepublic void paint(Graphics g) {super.paint(g);g.fillRect(0, 0, 1000, 750);//绘图区域:填充矩形,默认是黑色}
}
编写窗口类->继承JFrame
TankGame.java
package com.wpz.tankgame;import javax.swing.*;/*** @author 王胖子* @version 1.0* 窗口类*/
public class TankGame extends JFrame {private MyPanel mp = null;//定义面板public static void main(String[] args) {new TankGame();}public TankGame() {this.mp = new MyPanel();//初始化面板this.add(mp);//把面板加到窗口中this.setSize(1000, 750);//设置窗口大小this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置关闭方式:点击X则退出程序this.setVisible(true);//设置是否可见}
}
输出效果
项目:绘制坦克
- 根据坦克构造器传入的横纵坐标来确定坦克各个点的坐标,使得坦克变成一个整体
- 将画坦克的代码单独写在一个方法中,增强复用性和可维护性
- 不同类型和不同移动方向的坦克 要学会如何处理
package com.wpz.tankgame;import javax.swing.*;
import java.awt.*;/*** @author 王胖子* @version 1.0* 坦克大战的绘图区域*/
public class MyPanel extends JPanel {MyTank myTank = null;//先定义一个自己的坦克public MyPanel() {myTank = new MyTank(100, 100);//初始化自己的坦克}@Overridepublic void paint(Graphics g) {super.paint(g);g.fillRect(0, 0, 1000, 750);//绘图区域:填充矩形,默认是黑色//画出坦克->封装到画坦克的方法中drawTank(myTank.getX(), myTank.getY(), g, 0, 0);//画出我的坦克}/*** 该项目有两种类型坦克:①我方②敌方 -> 不同类型的坦克,颜色不同* 该项目有四种移动方向:不同移动方向使用画笔绘制的坦克是不同的** @param x 坦克左上角x坐标* @param y 坦克左上角y坐标* @param g 画笔* @param direction 坦克的移动方向(上下左右)* @param type 坦克的类型(敌方/我方)*/public void drawTank(int x, int y, Graphics g, int direction, int type) {//两种类型的坦克①我方②敌方 -> 不同类型的坦克,颜色不同switch (type) {case 0://我方g.setColor(Color.CYAN);break;case 1://敌方g.setColor(Color.YELLOW);break;}//四种移动方向:不同移动方向使用画笔绘制的坦克是不同的switch (direction) {case 0://向上g.fill3DRect(x, y, 10, 60, false);//画坦克左边轱辘(fillRect()画填充的矩形)g.fill3DRect(x + 30, y, 10, 60, false);//画坦克右边轱辘g.fill3DRect(x + 10, y + 10, 20, 40, false);//画坦克的身体g.fillOval(x + 10, y + 20, 20, 20);//画坦克的圆盖g.drawLine(x + 20, y, x + 20, y + 30);//画坦克的炮筒break;default:System.out.println("暂时没有处理");}}
}
输出效果:
java事件处理机制
案例:小球移动
解决:怎样让小球受到键盘的控制,上下左右移动
- 让面板实现KeyListener接口。KeyListener是监听器,可以监听键盘事件,当面板实现了该接口后,就要实现该接口的三个方法(按下,松开,输出),所以实现了该接口,就可以在该类中编写需要监听的事件
class MyPanel extends JPanel implements KeyListener
- 需要监听的事件为:当键盘按下↑↓←→时,小球的坐标发生相应变化。此时就需要把小球左上角的横纵坐标写成变量,方便加减
public void keyPressed(KeyEvent e){//判断按下的键}
- 当小球坐标发生变化时,一定要进行重绘
this.repaint();
- 在窗口类中添加面板的键盘监听器。不写这个的话,窗口是不知道需要监听面板上发生的键盘事件的(//JFrame窗口对象 可以监听键盘事件:即监听面板上发生的键盘事件)
相当于在编码中:面板类中写需要监听的事件,窗口类中为面板添加监听器
this.addKeyListener(mp);
- 事件监听通俗来说就是:一个类实现事件监听接口成为监听器类,然后再实现接口中处理事件的方法,当事件发生时,监听器监听到该事件,就会把该事件(KeyEvent对象)作为参数传给事件处理方法
package com.wpz.event;import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;/*** @author 王胖子* @version 1.0* 让小球收到键盘的控制,上下左右移动 -->来讲解java的事件控制*/
//窗口类
public class BallMove extends JFrame {MyPanel mp = null;public static void main(String[] args) {BallMove ballMove = new BallMove();}public BallMove() {mp = new MyPanel();this.add(mp);this.setSize(250, 200);this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);this.setVisible(true);//JFrame窗口对象 可以监听键盘事件:即监听面板上发生的键盘事件this.addKeyListener(mp);}
}//面板类
//KeyListener 是监听器,可以监听键盘事件
//面板类实现键盘监听器,所以在面板类中可以写需要监听的键盘事件
class MyPanel extends JPanel implements KeyListener {//为了让小球可以移动,把他左上角的坐标(x,y)设置成变量int x = 10;int y = 10;@Overridepublic void paint(Graphics g) {super.paint(g);
// g.fillOval(10,10,20,20);g.fillOval(x, y, 20, 20);//填充的小球,默认填充黑色}//当某个键按下,该方法被触发@Overridepublic void keyPressed(KeyEvent e) {// System.out.println((char) e.getKeyCode()+"键 被按下");//根据用户按下不同键,来处理小球移动//在java中会给每一个键,分配一个值(int)if (e.getKeyCode() == KeyEvent.VK_DOWN) {//KeyEvent.VK_DOWN就是向下箭头对应的codey++;} else if (e.getKeyCode() == KeyEvent.VK_UP) {y--;} else if (e.getKeyCode() == KeyEvent.VK_LEFT) {x--;} else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {x++;}//让面板重绘(当坐标x/y发生变化时,需要主动调用paint()方法进行重绘,这样才能显示小球移动的效果)this.repaint();}//当某个键释放(松开),该方法被触发@Overridepublic void keyReleased(KeyEvent e) {}//有字符输出时,该方法被触发@Overridepublic void keyTyped(KeyEvent e) {}
}
静态效果图,按↑↓←→可以控制小球移动
事件处理机制
基本说明
概念说明
项目:控制坦克上下左右移动(代码改进过程)
步骤及改进代码的过程
- 画出不同方向的坦克。前面已经画过上,现在把右下左的坦克类型也画出来。在drawTank的第二个switch中添加代码。
- 写出事件处理机制的基本代码。
①面板类实现KeyListener接口,并实现接口的三个事件处理方法,本项目中只处理键盘按键的事件(keyPressed)
②判断事件(按键的类型)->WDSA。先把事件处理空下,一会再想,先写完基本流程。
③重绘。在判断结束后(事件处理结束后),用repaint()放啊主动调用paint()进行重绘。
④窗口类的构造器中,为面板类添加键盘监听器。- 写事件处理的逻辑(总体分为2步)
①改变x/y坐标
②改变坦克的方向关于上面事件处理的①,②,写一下我的想法以及改进过程
- 我先不考虑坦克的方向,先写了坐标的变化
① 最开始写的:因为坦克左上角的x和y坐标 在父类中给出了set()和get()方法,所以我直接使用了这两种方法来对坦克的x和y坐标进行修改myTank.setY(myTank.getY()-2);
② 改进1:上面的代码调用了两次方法,效率↓且复用性、维护性差,所以就想着把坐标的改变封装到方法中,因为这是所有坦克移动时都需要的调用的方法,所以干脆把这些方法写到父类中,体会面向对象的好处(封装)
public void moveUp(){//向上移动 y-=2; }
③改进2:将移动的常量换为变量,方便控制移动的速度。 先死后活的思想,开始时坐标是加减固定值,由此想到可以扩展成变化的值,所以引入变量speed(速度)–>提供get和set方法,可以在初始化坦克对象时赋值
public void moveUp(){ y-=speed; }
myTank.setSpeed(5);//修改移动速度
- 考虑如何改变坦克的方向
① 最开始想到的解决方法:将direction设置成面板类的全局变量。
首先我的需求是要在keyPressed()事件处理方法中修改坦克的方向,坦克的方向是由direction表示的,此时direction是传入drawTank()中的一个参数,我在一个方法中是访问不到另一个方法中的参数的,所以我自然想到了把direction设置成面板类中的全局变量,这样我就可以在该类中的任何方法中使用到该变量了–>可行但不好
②改进:direction是所有坦克都具有的属性,它表示坦克的方向,所以我把direction属性写到了tank父类中,并为它提供get和set方法
myTank.moveUp();//改变坦克的坐标(将改变坐标封装到父类的moveUp()方法中) myTank.setDirection(0);//改变坦克的方向(将direction作为所有坦克的属性放到父类中)
面板类MyPanel
package com.wpz.tankgame;import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;/*** @author 王胖子* @version 1.0* 坦克大战的绘图区域*/
public class MyPanel extends JPanel implements KeyListener {MyTank myTank = null;//先定义一个自己的坦克public MyPanel() {myTank = new MyTank(100, 100);//初始化自己的坦克myTank.setSpeed(5);//设置坦克移动的速度}@Overridepublic void paint(Graphics g) {super.paint(g);g.fillRect(0, 0, 1000, 750);//绘图区域:填充矩形,默认是黑色//画出坦克->封装到画坦克的方法中//对direction做了修改,把它放到了tank父类中(使用get()方法访问)drawTank(myTank.getX(), myTank.getY(), g, myTank.getDirection(), 0);//画出我的坦克}/*** 该项目有两种类型坦克:①我方②敌方 -> 不同类型的坦克,颜色不同* 该项目有四种移动方向:不同移动方向使用画笔绘制的坦克是不同的** @param x 坦克左上角x坐标* @param y 坦克左上角y坐标* @param g 画笔* @param direction 坦克的移动方向(上下左右)* @param type 坦克的类型(敌方/我方)*/public void drawTank(int x, int y, Graphics g, int direction, int type) {//两种类型的坦克①我方②敌方 -> 不同类型的坦克,颜色不同switch (type) {case 0://我方g.setColor(Color.CYAN);break;case 1://敌方g.setColor(Color.YELLOW);break;}//四种移动方向:不同移动方向使用画笔绘制的坦克是不同的//direction:0:向上,1:向右,2:向下,3:向左switch (direction) {case 0://向上g.fill3DRect(x, y, 10, 60, false);//画坦克左边轱辘g.fill3DRect(x + 30, y, 10, 60, false);//画坦克右边轱辘g.fill3DRect(x + 10, y + 10, 20, 40, false);//画坦克的身体g.fillOval(x + 10, y + 20, 20, 20);//画坦克的圆盖g.drawLine(x + 20, y, x + 20, y + 30);//画坦克的炮筒break;case 1://向右g.fill3DRect(x, y, 60, 10, false);//画坦克上边轱辘g.fill3DRect(x, y + 30, 60, 10, false);//画坦克下边轱辘g.fill3DRect(x + 10, y + 10, 40, 20, false);//画坦克的身体g.fillOval(x + 20, y + 10, 20, 20);//画坦克的圆盖g.drawLine(x + 30, y + 20, x + 60, y + 20);//画坦克的炮筒break;case 2://向下g.fill3DRect(x, y, 10, 60, false);//画坦克左边轱辘g.fill3DRect(x + 30, y, 10, 60, false);//画坦克右边轱辘g.fill3DRect(x + 10, y + 10, 20, 40, false);//画坦克的身体g.fillOval(x + 10, y + 20, 20, 20);//画坦克的圆盖g.drawLine(x + 20, y + 30, x + 20, y + 60);//画坦克的炮筒break;case 3://向左g.fill3DRect(x, y, 60, 10, false);//画坦克左边轱辘g.fill3DRect(x, y + 30, 60, 10, false);//画坦克右边轱辘g.fill3DRect(x + 10, y + 10, 40, 20, false);//画坦克的身体g.fillOval(x + 20, y + 10, 20, 20);//画坦克的圆盖g.drawLine(x + 30, y + 20, x, y + 20);//画坦克的炮筒break;}}//事件处理方法(对按键进行监听)@Overridepublic void keyPressed(KeyEvent e) {//判断事件(当按下WDSA键时进行处理)if (e.getKeyCode() == KeyEvent.VK_W) {//上myTank.moveUp();//改变坦克的坐标(将改变坐标封装到父类的moveUp()方法中)myTank.setDirection(0);//改变坦克的方向(将direction作为所有坦克的属性放到父类中)} else if (e.getKeyCode() == KeyEvent.VK_D) {//右myTank.moveRight();myTank.setDirection(1);} else if (e.getKeyCode() == KeyEvent.VK_S) {//下myTank.moveDown();myTank.setDirection(2);} else if (e.getKeyCode() == KeyEvent.VK_A) {//左myTank.moveLeft();myTank.setDirection(3);}//重绘this.repaint();}@Overridepublic void keyReleased(KeyEvent e) {}@Overridepublic void keyTyped(KeyEvent e) {}
}
实体类Tank
package com.wpz.tankgame;/*** @author 王胖子* @version 1.0* 因为该游戏会有很多坦克* 所以先抽象成一个父类*/
public class Tank {private int x;//坦克横坐标private int y;//坦克纵坐标//将坦克的方向写到父类中 这样任意坦克在不同方法中 都可以设置移动方向private int direction;//坦克的方向(0:上,1:右,2:下,3:左)private int speed = 2;//移动速度public Tank(int x, int y) {this.x = x;this.y = y;}public int getDirection() {return direction;}public void setDirection(int direction) {this.direction = direction;}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 getSpeed() {return speed;}public void setSpeed(int speed) {this.speed = speed;}//将坦克移动时的坐标改变封装到 父类的方法中//直接改变坐标的x/y值(取代myTank.setY(myTank.getY()-2);)//先死后活:开始时坐标是加减固定值-->可以扩展成变化的--引入变量-->speed(可以在初始化坦克对象时赋值)public void moveUp() {y -= speed;}public void moveRight() {x += speed;}public void moveDown() {y += speed;}public void moveLeft() {x -= speed;}
}
窗口类
package com.wpz.tankgame;import javax.swing.*;/*** @author 王胖子* @version 1.0* 窗口类*/
public class TankGame extends JFrame {private MyPanel mp = null;//定义面板public static void main(String[] args) {new TankGame();}public TankGame() {this.mp = new MyPanel();this.add(mp);this.setSize(1000, 750);this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);this.setVisible(true);this.addKeyListener(mp);//为面板添加键盘监听器}
}
本章作业
分析:
修改的部分:
- 新建敌人坦克类
- 面板类中:定义敌人坦克集合及坦克数量,在构造器中初始化敌人坦克(同时修改坦克方向),在paint中绘制敌人坦克
敌人坦克类
package com.wpz.tankgame;/*** @author 王胖子* @version 1.0* 敌人的坦克*/
public class EnemyTank extends Tank {public EnemyTank(int x, int y) {super(x, y);}
}
面板类
package com.wpz.tankgame;import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Vector;/*** @author 王胖子* @version 1.0* 坦克大战的绘图区域*/
public class MyPanel extends JPanel implements KeyListener {MyTank myTank = null;//定义一个自己的坦克Vector<EnemyTank> enemyTanks = new Vector<>();//定义敌人的坦克,放到Vector中int enemyTankSize = 3;//敌人坦克的数量public MyPanel() {myTank = new MyTank(100, 100);//初始化自己的坦克myTank.setSpeed(5);//设置坦克移动的速度//初始化敌人的坦克(注意:使用循环来添加。因为敌人坦克数量多,不要一个一个add)for (int i = 0; i < enemyTankSize; i++) {//创建一个敌人的坦克EnemyTank enemyTank = new EnemyTank(100 * (i + 1), 0);//设置方向enemyTank.setDirection(2);//加入敌人坦克集合enemyTanks.add(enemyTank);}}@Overridepublic void paint(Graphics g) {super.paint(g);g.fillRect(0, 0, 1000, 750);//绘图区域:填充矩形,默认是黑色//画出自己的坦克->封装到画坦克的方法中//对direction做了修改,把它放到了tank父类中(使用get()方法访问)drawTank(myTank.getX(), myTank.getY(), g, myTank.getDirection(), 0);//画出我的坦克//画敌人的坦克->遍历集合for (int i = 0; i < enemyTanks.size(); i++) {//取出坦克EnemyTank enemyTank = enemyTanks.get(i);drawTank(enemyTank.getX(), enemyTank.getY(), g, enemyTank.getDirection(), 1);}}/*** 该项目有两种类型坦克:①我方②敌方 -> 不同类型的坦克,颜色不同* 该项目有四种移动方向:不同移动方向使用画笔绘制的坦克是不同的** @param x 坦克左上角x坐标* @param y 坦克左上角y坐标* @param g 画笔* @param direction 坦克的移动方向(上下左右)* @param type 坦克的类型(敌方/我方)*/public void drawTank(int x, int y, Graphics g, int direction, int type) {//两种类型的坦克①我方②敌方 -> 不同类型的坦克,颜色不同switch (type) {case 0://我方g.setColor(Color.CYAN);break;case 1://敌方g.setColor(Color.YELLOW);break;}//四种移动方向:不同移动方向使用画笔绘制的坦克是不同的//direction:0:向上,1:向右,2:向下,3:向左switch (direction) {case 0://向上g.fill3DRect(x, y, 10, 60, false);//画坦克左边轱辘g.fill3DRect(x + 30, y, 10, 60, false);//画坦克右边轱辘g.fill3DRect(x + 10, y + 10, 20, 40, false);//画坦克的身体g.fillOval(x + 10, y + 20, 20, 20);//画坦克的圆盖g.drawLine(x + 20, y, x + 20, y + 30);//画坦克的炮筒break;case 1://向右g.fill3DRect(x, y, 60, 10, false);//画坦克上边轱辘g.fill3DRect(x, y + 30, 60, 10, false);//画坦克下边轱辘g.fill3DRect(x + 10, y + 10, 40, 20, false);//画坦克的身体g.fillOval(x + 20, y + 10, 20, 20);//画坦克的圆盖g.drawLine(x + 30, y + 20, x + 60, y + 20);//画坦克的炮筒break;case 2://向下g.fill3DRect(x, y, 10, 60, false);//画坦克左边轱辘g.fill3DRect(x + 30, y, 10, 60, false);//画坦克右边轱辘g.fill3DRect(x + 10, y + 10, 20, 40, false);//画坦克的身体g.fillOval(x + 10, y + 20, 20, 20);//画坦克的圆盖g.drawLine(x + 20, y + 30, x + 20, y + 60);//画坦克的炮筒break;case 3://向左g.fill3DRect(x, y, 60, 10, false);//画坦克左边轱辘g.fill3DRect(x, y + 30, 60, 10, false);//画坦克右边轱辘g.fill3DRect(x + 10, y + 10, 40, 20, false);//画坦克的身体g.fillOval(x + 20, y + 10, 20, 20);//画坦克的圆盖g.drawLine(x + 30, y + 20, x, y + 20);//画坦克的炮筒break;}}//事件处理方法(对按键进行监听)@Overridepublic void keyPressed(KeyEvent e) {//判断事件(当按下WDSA键时进行处理)if (e.getKeyCode() == KeyEvent.VK_W) {//上myTank.moveUp();//改变坦克的坐标(将改变坐标封装到父类的moveUp()方法中)myTank.setDirection(0);//改变坦克的方向(将direction作为所有坦克的属性放到父类中)} else if (e.getKeyCode() == KeyEvent.VK_D) {//右myTank.moveRight();myTank.setDirection(1);} else if (e.getKeyCode() == KeyEvent.VK_S) {//下myTank.moveDown();myTank.setDirection(2);} else if (e.getKeyCode() == KeyEvent.VK_A) {//左myTank.moveLeft();myTank.setDirection(3);}//重绘this.repaint();}@Overridepublic void keyReleased(KeyEvent e) {}@Overridepublic void keyTyped(KeyEvent e) {}
}
输出效果
java项目笔记 - 第16章:坦克大战1.0相关推荐
- Java 学习笔记:第一章 Java入门
Java 学习笔记:第一章 Java入门 1.1 计算机语言发展史以及未来方向 1.2 常见编程语言介绍 C语言 C++ 语言 Java语言 PHP 语言 Object-C和Swift 语言 Java ...
- JavaStudy7(18章-坦克大战2)—B站韩顺平
JavaStudy7(18章-坦克大战2)-B站韩顺平 1.坦克大战 1.1线程-应用到坦克大战 1.1.1 坦克大战 0.3 代码演示: //为了监听 键盘事件, 实现 KeyListener pu ...
- 《Java小游戏实现》:坦克大战(续四)
<Java小游戏实现>:坦克大战(续四) 相关博文: <Java小游戏实现>:坦克大战http://blog.csdn.net/u010412719/article/detai ...
- 《Java小游戏实现》:坦克大战
<Java小游戏实现>:坦克大战 前面写了一个简单的聊天小程序,今天开始就写一个坦克大战的游戏,算是对Java相关小知识点的一个应用. 这个游戏的完成,我们也是分步完成,逐步累加,一个一个 ...
- [ java ] 坦克大战 5.0 ~ 最终完整版
坦克大战5.0 新增功能内容:(加入IO流内容) 防止敌坦克间重叠 击杀数显示 保存上局游戏进度–>两种开局方式 加入开局音乐 修复记录文件丢失后的异常 5.0版本为最终版 提示:爆炸图片需自行 ...
- 用JAVA 做一个简易版的坦克大战(只实现基本功能)
不太会写文章,只是为了记录自己做过的东西 文章目录 前言 一.大概思路 二.主要代码 1.Tank.java 2.Shot.java 3. Mypanel.java 4.Hero.java 5.Ene ...
- java游戏牛仔炮筒,《Java小游戏实现》:坦克大战(续2)
<Java小游戏实现>:坦克大战(续2) 相关博文: 博文<Java小游戏实现>:坦克大战(续1)中已经实现到了坦克可以发射一颗子弹了.这篇博文在此基础上继续实现更多的功能. ...
- 坦克大战2.0,3.0,4.0版本
1.坦克大战 0.3 在坦克大战游戏(0.2版)基础上添加如下功能:当玩家按一下j键,就发射一颗子弹. 编写Shot类 package com.yt.tankgame03;/*** 射击子弹*/ pu ...
- 韩老师坦克大战2.0版本
本博文源于对b站视频韩老师(韩顺平)的java学习,本章学习坦克大战2.0版本,用多线程实现,本章内容还是比较多的,先看内容效果 内容效果 开局 被打死(黄色是hero) 打死别人 源码 Bomb.j ...
- eclipse 导入项目_JAVA编程实战:坦克大战系列2-坦克如何在eclipse中编写
游戏中寻找学习JAVA的乐趣之 坦克大战系列2-坦克如何在Eclipse中编写 前言 本篇主要对Robocode在eclipse中如何配置并编写. Eclipse中的配置 通过本身自带的编辑器去写代码 ...
最新文章
- Struts2中action接收参数的三种方法及ModelDriven跟Preparable接口结合JAVA反射机制的灵活用法...
- Linux系统下文件与目录权限管理
- 《机器人学经典教程》——2.3 人工智能
- 【赠书】迁移学习如何入门,看看这本简明手册即可
- VTK:可视化之QuadricLODActor
- java中比较字符串的大小用String的compareTo()
- git统计每个人的代码行数_项目出了bug如何甩锅?使用这个Git工具帮你找到元凶...
- Knative 多容器支持介绍
- shell编程之条件语句(文件测试,test命令,字符串和逻辑测试,if单支语句,if双支语句,if多支语句,case命令,用if写跑步小实验)
- OPC通信原理在数采中的应用
- 齐博V7仿爱丽图库模板(含齐博图库V1.0模板)
- 多对多关联映射(双向)
- Linux和Windows下查看、设置环境变量的比较
- Android平台RTMP/RTSP播放器开发系列之解码和绘制
- keil4怎么移植其他人的程序_简单和你聊聊造血干细胞移植!
- Sql Server 2005 PIVOT的行列转换应用实例
- 时空、维度,以及其他(二)
- property自己实现
- ubuntu实用工具
- MS Navision专业BBS