j2se坦克大战(Demo学习总结)
来源:互联网 发布:达闼科技 知乎 编辑:程序博客网 时间:2024/09/21 09:04
( 纯手绘版坦克大战)
1:制作出显示应用程序窗口
定义好窗口的大小,布局和背景颜色
这里主要覆写了父类的paint()和update()方法,在update方法中加入了双缓冲机制具体代码如下:
Image offScreenImage = null;
public void update(Graphics g) {
if(offScreenImage == null) {
offScreenImage = this.createImage(GAME_WIDTH,GAME_HEIGHT);
}
Graphics gOffScreen = offScreenImage.getGraphics();
Color c = gOffScreen.getColor();
gOffScreen.setColor(Color.GREEN);
gOffScreen.fillRect(0, 0, GAME_WIDTH, GAME_HEIGHT);
gOffScreen.setColor(c);
paint(gOffScreen); //调用paint方法
g.drawImage(offScreenImage, 0, 0, null);
}
其次在重绘和按键监听的时候,定义了两个内部类:
/**重绘内部类*/
private class PaintThread implements Runnable{
@Override
public void run() {
while(true){
repaint();
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
/**事件监听内部类*/
private class KeyMonitor extends KeyAdapter{
public void keyReleased(KeyEvent e){
myTank.keyReleased(e);
}
public void keyPressed(KeyEvent e){
myTank.keyPressed(e);
}
}
this.addKeyListener(new KeyMonitor());
new Thread(new PaintThread()).start();
这里在按键的时候,定义了八个方向。代码如下所示:
private boolean bL=false, bU=false, bR=false, bD =false;
enum Direction {L, LU, U, RU,R, RD, D, LD, STOP};
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
switch(key) {
case KeyEvent.VK_F2 :
if(!this.live) {
this.live = true;
this.life = 100;
}
break;
case KeyEvent.VK_LEFT :
bL = true;
break;
case KeyEvent.VK_UP :
bU = true;
break;
case KeyEvent.VK_RIGHT :
bR = true;
break;
case KeyEvent.VK_DOWN :
bD = true;
break;
}
locateDirection();
}
//在弹起的时候将其对应按键置为false
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
switch(key) {
case KeyEvent.VK_F2 :
if(!this.live) {
this.live = true;
this.life = 100;
}
break;
case KeyEvent.VK_LEFT :
bL = true;
break;
case KeyEvent.VK_UP :
bU = true;
break;
case KeyEvent.VK_RIGHT :
bR = true;
break;
case KeyEvent.VK_DOWN :
bD = true;
break;
}
locateDirection();
}
void locateDirection() {
if(bL && !bU && !bR && !bD) dir = Direction.L;
else if(bL && bU && !bR && !bD) dir = Direction.LU;
else if(!bL && bU && !bR && !bD) dir = Direction.U;
else if(!bL && bU && bR && !bD) dir = Direction.RU;
else if(!bL && !bU && bR && !bD) dir = Direction.R;
else if(!bL && !bU && bR && bD) dir = Direction.RD;
else if(!bL && !bU && !bR && bD) dir = Direction.D;
else if(bL && !bU && !bR && bD) dir = Direction.LD;
else if(!bL && !bU && !bR && !bD) dir = Direction.STOP;
}
在as中看到一段控制多按键的处理方法,感觉不错,拿来借鉴:
private var keys:Object = {};
public function isDown(keyCode:uint):Boolean
{
return keys[keyCode];
}
private function onKeyDown(e:KeyboardEvent):void
{
keys[e.keyCode] = true;
}
private function onKeyUp(e:KeyboardEvent):void
{
delete keys[e.keyCode];
}
private function listener(e:Event):void
{
if(targetPlayer == null) return;
if(isDown(VK_UP) && isDown(VK_LEFT)) //左上
{
targetPlayer.moves(-targetPlayer.speed,-targetPlayer.speed);
}else if(isDown(VK_UP) && isDown(VK_RIGHT)) //右上
{
targetPlayer.moves(targetPlayer.speed,-targetPlayer.speed);
}
}
这段as3代码,主要是将按下的键项放到了一个类似于java中map的Object容器里面。以键值作为key,
以按下boolean值作为value,当按下的时候将对应的key置为true, 弹起的时候置为false,
使用时就可以根据key所对应的value值来判断。
在区分敌方坦克和自己的坦克的时候,通过一个Boolean变量来区分。
创建敌方坦克的时候,默认给他一个方向,然后通过一个random数值来随机敌方坦克的方向, 放弹也是根据一个随机数来获得。 下面是示例代码:
private static Random r = new Random(); //定义成静态的,使内存区中只存在一个该实例对象。
private int step = r.nextInt(12) + 3;
然后在move()方法中,开始监听这个变量
if(!good) { //如果不是好的坦克(说明是敌方)
Direction[] dirs = Direction.values();
if(step == 0) {
step = r.nextInt(12) + 3;
int rn = r.nextInt(dirs.length);
dir = dirs[rn];
}
step --; //根据step数值来改变敌方玩家的方向
if(r.nextInt(40) > 38) this.fire();
}
在和其他物体作碰撞检测的时候,如果碰到某个物体的话,则该坦克不允许再移动,这里解决这个问题的办法是定义另外两个变量oldX, oldY来保存之前的x, y变量。如果碰到物体不可行走则将oldX ,oldY 再付给x,y坐标。
2:在制作爆炸物特效的时候用到了这样一个判断:
int[] diameter = {4, 7, 12, 18, 26, 32, 49, 30, 14, 6}; //爆破物的直径(由小到大,然后再由大到小,爆破物逐渐消失)
private boolean live = true;
public void draw(Graphics g) {
if(!live) {
tc.explodes.remove(this);
return;
}
if(step == diameter.length) {
live = false;
step = 0;
return;
}
Color c = g.getColor();
g.setColor(Color.ORANGE);
g.fillOval(x, y, diameter[step], diameter[step]);
g.setColor(c);
step ++;
}
这样通过一个数组,就可以不通过线程来控制,以后这种方法值得借鉴
而下面的血块也是借用了上面一种写法,知识稍微改动了点地方:
int step = 0;
private boolean live = true;
//指明血块运动的轨迹,由pos中各个点构成.(目的是让血块按指定的路线动起来)
private int[][] pos = {
{350, 300}, {360, 300}, {375, 275}, {400, 200}, {360, 270}, {365, 290}, {340, 280}
};
private void move() {
step ++;
if(step == pos.length){
step = 0;
}
x = pos[step][0];
y = pos[step][1];
}
这个也是给明了运动轨迹,只不过是循环多次,直到为死亡状态时循环才结束.
- j2se坦克大战(Demo学习总结)
- C# 坦克大战学习总结
- JavaSE学习总结-坦克大战
- html5学习-坦克大战总结
- J2se小项目:坦克大战
- html5-学习 坦克大战知识点总结
- 坦克大战项目总结
- 坦克大战项目总结
- 坦克大战 项目总结
- J2SE 坦克大战 马士兵(1)
- J2SE 坦克大战 马士兵(2)
- J2SE 坦克大战 马士兵(3)
- J2SE 坦克大战 马士兵(4)
- J2SE 坦克大战 马士兵(5)
- J2SE 坦克大战 马士兵(5)
- 坦克大战学习笔记
- Java学习总结之坦克大战项目(一)
- Java学习总结之坦克大战项目(二)
- outlook 发送邮件前提醒 宏
- 第五章 JSP的两种开发模型
- EditText输入事件截获与监听
- j2se版五子棋(Demo学习总结)
- [Android实例] android多点触摸demo
- j2se坦克大战(Demo学习总结)
- 使用vc发现的一些问题记录
- java实现随机动态的小球
- Firefox:如何设置Firefox为默认浏览器
- C++高效程序设计
- 中国网速为何总是这么慢?
- oracle:完整剖析PL/SQL DEVELOPER与SQL PLUS字符集设置
- Linux 中批量替换字符串
- linux解压 tar命令