添加墙元素实现碰撞效果

碰撞效果实现:

  利用CollisionUtils判断两个对象是否发生碰撞

    x1:第一个矩形的x坐标

    y1:第一个矩形的y坐标

    w1:第一个矩形的宽度

    h1:第一个矩形的高度

    x2:第二个矩形的x坐标

    y2:第二个矩形的y坐标

    w2:第二个矩形的宽度

    h2:第二个矩形的高度

  可以理解为tank和wall的碰撞检测,如果发生碰撞则返回true,否则返回false

代码实现:

1、创建一个墙类,继承于Element

 1 package Itheima.bean;
 2
 3 public class Wall extends Element {
 4     public Wall(int x,int y) {
 5         this.x=x;
 6         this.y=y;
 7         this.imagePath="res/img/wall.gif";
 8         getSize();  //获取墙的宽高
 9     }
10 }

Wall

2、在设置类将Wall对象添加入集合,遍历集合

 1 package Itheima;
 2
 3 import java.util.List;
 4 import java.util.concurrent.CopyOnWriteArrayList;
 5
 6 import org.itheima.game.Window;
 7 import org.lwjgl.input.Keyboard;
 8
 9 import Itheima.bean.Bullet;
10 import Itheima.bean.Direction;
11 import Itheima.bean.Element;
12 import Itheima.bean.Tank;
13 import Itheima.bean.Wall;
14
15 public class TankWorld extends Window {
16     Tank tank;
17     Wall wall;
18     List<Element> list;
19
20     public TankWorld(String title, int width, int height, int fps) {
21         super(title, width, height, fps);
22         // TODO 自动生成的构造函数存根
23     }
24
25     @Override
26     protected void onCreate() {
27         list = new CopyOnWriteArrayList<>();
28         tank = new Tank(0, 0);
29         wall = new Wall(64, 64);
30         list.add(tank);
31         list.add(wall);
32     }
33
34     @Override
35     protected void onMouseEvent(int key, int x, int y) {
36         // TODO 自动生成的方法存根
37
38     }
39
40     @Override
41     protected void onKeyEvent(int key) {
42         switch (key) {
43         case Keyboard.KEY_UP:
44             tank.move(Direction.UP);
45             break;
46
47         case Keyboard.KEY_DOWN:
48             tank.move(Direction.DOWN);
49             break;
50         case Keyboard.KEY_LEFT:
51             tank.move(Direction.LEFT);
52             break;
53         case Keyboard.KEY_RIGHT:
54             tank.move(Direction.RIGHT);
55             break;
56         case Keyboard.KEY_SPACE:
57             Bullet bullet = tank.fire();
58             list.add(bullet);
59             break;
60         }
61     }
62
63     @Override
64     protected void onDisplayUpdate() {
65         for (Element e : list) {
66             e.draw();
67         }
68
69         for (Element e1 : list) {
70             if(e1 instanceof Tank){    //遍历到Tank对象
71                 Tank t = (Tank) e1;    //将e1转换成Tank类
72                 for (Element e2 : list) {
73                     if(e2 instanceof Wall){    //遍历到Wall对象
74                         Wall w = (Wall) e2;    //将e2转换成Wall对象
75                         boolean result = t.impact(w);    //判断Tank与Wall是否发生碰撞
76                         if(result){
77                             break;  //如果撞上了就跳出循环 不继续和下一个墙做判断
78                         }
79                     }
80                 }
81             }
82         }
83     }
84
85 }

TankWorld

3、Tank类碰撞方法

  1 package Itheima.bean;
  2
  3 import java.util.Collections;
  4
  5 import org.itheima.game.utils.CollisionUtils;
  6
  7 import Itheima.Constants;
  8
  9 public class Tank extends Element {
 10     private int speed = 32; // 移动速度
 11     Direction dir = Direction.UP; // 方向默认向上
 12     Direction badDirection = null; //记录tank不能走的方向
 13
 14     public Tank(int x, int y) { // 构造方法
 15         this.x = x;
 16         this.y = y;
 17         this.imagePath = "res/img/tank_u.gif";
 18         getSize(); // 获取tank宽高
 19     }
 20
 21     public void move(Direction dir) {
 22         if(badDirection!=null && dir == badDirection){  //判断当前方向是否等于不能走的方向
 23             return ; //如果是则不执行下面的代码
 24         }
 25         if (dir != this.dir) { // 传入的方向不等于当前方向
 26             this.dir = dir; // 当前方向等于传入的方向
 27             switch (dir) { // 只更换方向不做移动
 28             case UP:
 29                 this.imagePath = "res/img/tank_u.gif";
 30                 break;
 31
 32             case DOWN:
 33                 this.imagePath = "res/img/tank_d.gif";
 34                 break;
 35             case LEFT:
 36                 this.imagePath = "res/img/tank_l.gif";
 37                 break;
 38             case RIGHT:
 39                 this.imagePath = "res/img/tank_r.gif";
 40                 break;
 41             }
 42         }
 43         switch (dir) { // 如果当前方向等于传入的方向
 44         case UP:
 45             y -= speed;
 46             break;
 47
 48         case DOWN:
 49             y += speed;
 50             break;
 51         case LEFT:
 52             x -= speed;
 53             break;
 54         case RIGHT:
 55             x += speed;
 56             break;
 57         }
 58         // 越界处理
 59         if (x < 0) {
 60             x = 0;
 61         }
 62         if (x > Constants.WIDTH - this.width) {
 63             x = Constants.WIDTH - this.width;
 64         }
 65         if (y < 0) {
 66             y = 0;
 67         }
 68         if (y > Constants.HEIGHT - this.height) {
 69             y = Constants.HEIGHT - this.height;
 70         }
 71     }
 72
 73     public Bullet fire() {
 74         Bullet b = new Bullet(this); // 根据tank坐标生成子弹
 75         return b;
 76     }
 77
 78     public boolean impact(Wall w) { // 判断是否发生碰撞
 79         int x1 = this.x; // 坦克的参数
 80         int y1 = this.y;
 81         int w1 = this.width;
 82         int h1 = this.height;
 83
 84         int x2 = w.x; // 墙的参数
 85         int y2 = w.y;
 86         int w2 = w.width;
 87         int h2 = w.height;
 88
 89         // 根据tank的方向计算下一步的坐标
 90         switch (this.dir) {
 91         case UP:
 92             y1 -= speed;
 93             break;
 94
 95         case DOWN:
 96             y1 += speed;
 97             break;
 98         case LEFT:
 99             x1 -= speed;
100             break;
101         case RIGHT:
102             x1 += speed;
103             break;
104         }
105
106         //碰撞检测函数
107         boolean result = CollisionUtils.isCollisionWithRect(x1, y1, w1, h1, x2, y2, w2, h2);
108
109         if (result) {
110             badDirection = this.dir;
111             switch (this.dir) {
112             case UP:
113                 this.y = y2 + h2;
114                 break;
115
116             case DOWN:
117                 this.y = y2 - h1;
118                 break;
119             case LEFT:
120                 this.x = x2 + w2;
121                 break;
122             case RIGHT:
123                 this.x = x2 - w1;
124                 break;
125             }
126         }else{
127             badDirection = null;
128         }
129         return result;
130     }
131 }

Tank

随笔说:  

      必须将tank的下一步坐标放入检测函数内计算,不然还是会多走一步再退回来。

时间: 2024-10-14 06:18:26

添加墙元素实现碰撞效果的相关文章

UIDynamic仿物理引擎-浮动碰撞效果-b

最近产品提了个需求(电商的APP-两鲜),需要在APP背景加上几个水果图案在那里无规则缓慢游荡...模仿 天天果园 APP的.好吧,那我就在网上找了很多文章,总结一下写个demo.效果如下: Mou icon 这里用到的是UIDynamic这个类. UIDynamic简介 一.简介 注意:UIKit动力学的引入,并不是为了替代CA或者UIView动画,在绝大多数情况下CA或者UIView动画仍然是最有方案,只有在需要引入逼真的交互设计的时候,才需要使用UIKit动力学它是作为现有交互设计和实现的

VS2013点击右键菜单命令添加xml元素插件开发

一.选择Visual Studio Package模板建立插件项目 由于此功能需要在右键菜单上添加命令,所以选择Visual Studio Package模板,根据模板向导步骤插件项目,在Select VSPackage Options步骤的时候选择Menu Command选项,如图-1所示: 图-1 接下来是设置命令的名称,如图-2所示 图-2 修改Command name的值,将其设置为我们要添加到右键菜单时的名称.Command ID可选择是否修改,值是一个十六进制数,由于标识我们的添加的

如何给before和after伪元素设置js效果

目录 [1]动态嵌入CSS[2]添加类名 [3]setAttribute [4]添加样式表 [5]修改样式表 前面的话 无法直接给before和after伪元素设置js效果 例子说明 现在需要为(id为box,内容为"我是测试内容"的div)添加(:before内容为"前缀",颜色为红色的伪类) <!DOCTYPE html> <html lang="en"> <head> <meta charset=&

jquery动态添加的元素绑定的事件不生效的问题

我们可以通过 $(document).on('click', '#xxx', callback) 这种形式解决. 原因,一般情况下,我们是通过 $('#xxx').click(callback) 这种形式去绑定,这种绑定之所以生效是因为,我们程序加载 $(function(){}) 的时候绑定了回调,而动态添加上去的,我们并没有去绑定. 所以动态添加的元素,点击的时候并不会触发我们想要的效果.但是实际上,在我们点击的时候,还是产生了点击事件,只是这个事件没有被我们的预期回调处理,因为我们的回调没

IOS 自定义UIBUTTON 直接拖个xib 就能在button上显示多行文本 并且添加了点击的效果

拖个button继承一下  几行代码 就搞定 自用效果还行 IOS 自定义UIBUTTON 直接拖个xib 就能在button上显示多行文本 并且添加了点击的效果,布布扣,bubuko.com

在for、foreach循环体中添加数组元素

在开发工作中遇到这样一种情形,需要在循环体中动态向遍历中的数组添加元素并在当前循环遍历中使用数组的全部元素. 首先使用foreach循环来遍历数组,将代码简化抽象如下: $arr = array(1, 2, 3, 4, 5, 6, 7, 8); foreach($arr as $v) { if($v % 2 == 0) $arr[] = 11; echo $v . ' '; } 结果只打印出数组原来已有元素,在循环体中动态添加的元素并没有打印出来. 后来改用for循环,coding如下: $ar

点击enter回车键实现表单元素切换焦点效果

点击enter回车键实现表单元素切换焦点效果:现在网站都比较追求人性化,比如填写表单的时候,能够实现点击回车就可以切换表单元素的焦点,这样比使用鼠标进行切换更能让人接受,下面就通过代码实例介绍一下如何实现此功能.代码如下: <!DOCTYPE html> <html> <head> <meta charset=" utf-8"> <meta name="author" content="http://w

jQuery对 动态添加 的元素 绑定事件(on()的用法)

从jQuery 版本 1.7 起,on() 方法是向被选元素添加事件处理程序的(官方推荐)首选方法. 当浏览器下载完一个页面的时候就开始渲染(翻译)HTML标签,然后执行css.js代码,在执行js代码的时候就注册了相应绑定的事件,我们平常用jQuery给HTML标签绑定(单击)事件是一般这样写 $("#btnId").click(function () { //触发事件后 逻辑 });  但是对用js动态添加的元素 是无效的,即没有绑定单击事件,所以对于动态添加的标签需要用on()来

jQuery给动态添加的元素绑定事件的方法

jquery中绑定事件一般使用bind,或者click,但是这只能是对已经加载好的元素定义事件,那些后来添加插入的元素则需要另行绑定.在1.7版本以前使用live.但是在1.8版本以后推荐使用on.这里介绍jQuery中如何给动态添加的元素绑定事件在实际开发中会遇到要给动态生成的html元素绑定触发事件的情况 例如 1 <div id="testdiv"> 2 <ul></ul> 3 </div> 需要给<ul>里面动态添加的