Hello World

Cocos学习笔记——碰撞回调(1)

接上篇小球落地,如果想让小球落地后反弹,要怎么做哪?
cocos的物理引擎提供了碰撞回调,需要如下步骤开启:
1. 参照前一篇,配置碰撞双方的RigidBody,开启重力引擎
2. 菜单选择“项目”-“项目设置”-“分组管理”,添加分组:ground、balls(这里,物理引擎的碰撞并不需要勾选balls与ground的碰撞关系)
3. “层级管理器”里,分别选择ground、ball节点,配置ground、balls分组
4. 脚本的onLoad内开启重力引擎,小球的脚本内添加碰撞回调:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
....
  onLoad(){
    cc.director.getPhysicsManager().enabled = true;
  }
....
  //碰撞开始时的回调,self为碰撞“主动方”, other为碰撞“被动方”
  onBeginContact(contact, self, other){
    let v = self.body.linearVelocity;
    v.y = 1200;//设置一个向上的速度
    self.body.linearVelocity = v;
    //注意,下面这种写法是无效的:
    //self.body.linearVelocity.y = 1200;
  }
  //碰撞处理结束时的回调
  onEndContact(contact, self, other){
 
  }
....

注意:
a. onBeginContact、onEndContact是系统指定的碰撞引擎的回调方法,不需要绑定,也不能改名
b. 除了“物理组件”引起的碰撞,cocos还有正常运动时产生的碰撞,此时的回调方法是onCollisionEnter,详细使用方法将放到下一篇笔记里

演示:http://dev.jiangkunlun.com/ex/dlx2
转载请注明出处:http://www.jiangkunlun.com/2020/05/cocos_碰撞

Hello World 日志

Cocos学习笔记——开启重力引擎

使用cocos自带的重力引擎起作用,这里以小球下落到地面为例,需要下面几步:
1. 添加“地面”节点,并添加RigidBody组件,type选Static;为了更好地演示“地面”的桌面,还需要配置碰撞组件PhysicsBoxCollider,也可以选择、调整为其他形状
2. 添加“小球”节点,并添加RigidBody组件,type选Dynamic,配置小球所受重力加速度GraviteScale;配置碰撞组件PhysicsCircleCollider,因为是球,所以这里选的是“原型”
3. 脚本的onLoad内开启重力引擎:

1
2
3
4
5
6
....
  onLoad(){
    cc.director.getPhysicsManager().enabled = true;
    cc.director.getPhysicsManager().gravity = cc.v2(0, -320);
  }
....

上面1、2两步,都可以在CocosCreator的可视化界面内完成配置,只要第3步需要写js

演示:http://dev.jiangkunlun.com/ex/dlx
转载请注明出处:http://www.jiangkunlun.com/2020/05/cocos_gravity

Hello World 他山石

defineProperty

学习VUE“双向绑定”的实现,DOM变化时,同步给js变量,这一层比较容易理解,使用DOM的事件绑定就好了;但是当js变量发送变化时,是如何监控到、然后更新到DOM的,这点就比较有意思的。
看VUE代码,里面使用了ES5新加入的“Object.defineProperty()”,属性拦截器

看名字就比较好理解,使用defineProperty定义的属性,可以针对getter,和setter操作做监控、拦截,比如下面:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
let o = {};
Object.defineProperty(o, 'b', {
  configurable: true,
  enumerable: true,
  get: function(){
    console.log('get run');     //log1
  },
  set: function(v){
    console.log('set run', v);  //log2
  }
});
 
setInterval(function(){
  o.b = new Date().toLocaleString();
  console.log('o.b, ', o.b);     //log3  undefined
}, 3000);

这样,每隔3秒,log2,o.b赋值时,log2,就会被打印出来
但是,下面的反应比较奇怪,getter也被拦截了,log3位置,打印出来的是“undefined”。。。
这是因为getter里没有返回值
但是如果你胆敢在getter“return this.b”,运行时就会死循环,因为如果this.b又会去调getger
(是的,这就是js。。。增加一个看似“美丽强大”的新特性的同时,还给你附加几个坑,等你往里跳。。。。。)
那么,还能不能让人好好使用这个拦截器哪?
当然可以,这里,我们可以加一个“中间变量”过渡,setter时,给中间变量赋值;getter时,return这个中间变量,就不会死循环了

当然,还可以借助经典的“function-Class”定义,对整个过程做封装,比如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function O1(){
  let v1;     //中间变量
 
  Object.defineProperty(this, 'v1', {
    get: function(){
      console.log('get run', v1);
      return v1;
    },
    set: function(v){
      v1 = v;
      console.log('set run', v);
    }
  });
}
 
var o1 = new O1();
 
setInterval(function(){
  o1.v1 = new Date().toLocaleString();
  console.log('o1.v1, ', o1.v1);
}, 3000);

———
转载请注明出处: http://www.jiangkunlun.com/2019/06/js_defineproperty

Hello World

python读取csv/json/xml

python(3.x)读取csv:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import csv
 
filename = 'xxx.csv'
fi = [] 
ls = []
 
with open(filename, 'r', encoding='gbk') as csvfile:
    reader = csv.reader(csvfile)
    fi = next(reader)
    for lr in reader:
        ls.append(lr)
 
for lr in ls[:5]:
    print(lr)

当然,使用专业类库,会更简单:

1
2
3
4
5
6
7
import pandas as pd
 
filename = 'xxx.csv'
 
data = pd.read_csv(filename, encoding='gbk')
 
print(data.head(5))

读取json:

1
2
3
4
5
6
7
8
import json
 
filename = 'xxx.json'
 
with open(filename) as f:
    jsondata = json.load(f)
 
print(jsondata)

当然,pandas里也有更高效的读取json的read_json(),不过用它读取多维不定格式的json时,会报错“ValueError: arrays must all be same length”,这里就不再演示了

读取xml,并转变为json:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import json
import xml.etree.ElementTree as ET
import xmltodict
 
filename = 'xxx/s1.xml'
 
tree = ET.parse(filename)
xmldata = tree.getroot()
 
xmlstr = ET.tostring(xmldata, encoding='utf8', method='xml')
xmldict = xmltodict.parse(xmlstr, encoding='utf8')
 
datadict = dict(xmldict)
 
print(datadict)
 
filename2 = 'xxxx/s1.json'
with open(filename2, 'w+') as jsonfile:
    json.dump(datadict, jsonfile, indent=4, sort_keys=True)

注:
1. xmltodict可能需要安装:pip install xmltodict
2. xmltodict.parse对xml格式要求较严格,如果某节点字符串开头第一个字符是数值,createElement时可能会报错

爱好收藏

老白老白

上个月开始看美剧,绝命毒师,五季看完,真的很棒
沿用网友们的习惯,我们把男主沃尔特,叫“老白”

几个角度:
1. 第一、二季的时候,感受最深的是(口可口可,估计是人到中年有共鸣),一个男人,为了家庭,真的不容易。
一个将死之人,为了自己老婆孩子,去做这种“不要命”的搞毒品的事,游走在各色风险之间,去和各种“不要命”的人打交道。
2. 业务模式的发展,从房车/地下室“小作坊”,一路走到和大毒枭联合,再到自成一派
做什么,都要有个学习、提高、循序渐进的过程:
第一季,他们找屠库出货;
第二季屠库死了,他们只能自建渠道去卖;
再到后来给大毒枭打工,只做直接最擅长的制毒工作,将销售交给其他大佬
最后一季,对整个行业上下游有了足够了解后,开始单干
3. 钱,money,多少才到头
从开始,算的清清楚楚,只想挣76.x万美元,却一次一次被中断制毒、堵死销路,用了两季也没打到目标
到后来坐上大毒枭的顺风车,已经远远超过了目标,却还不满意,还受不住手
第三季的时候,面对各种风险,加之身体暂时没问题了,其实男主已经放弃了制毒,可惜又被毒枭拉下了水
到第五季,有一个大好的机会,没有什么风险一下赚到500万,可自信心爆棚的男主,却已经收不住手了,一口气赚到了九千万!
这时再收手,却已经晚了。。。

4. 故事&剧情
很佩服美剧的编剧们,第二季,汉克和乌龟那段,和主剧情基本无关,但是作为一个独立的故事,也是非常精彩
另外,第三季吧,那只苍蝇。。。哈哈,一只苍蝇居然真的拍了一集,而且并不让你觉得无聊,反而能感受到人物内心的煎熬
5. 汉克
说实话,整整五季,最痛心疾首的就是汉克的死。虽然很讨厌他对男主一直穷追不舍。可是这么敬业、这么有正义感的一个警察,突然就死了,真的不应该啊
6. 谎言
为了可以有时间去安心制毒,从第一季开始,男主对老婆编造了一个又一个。。。“善意的谎言”。可看似“天衣无缝”的谎言,到后来却一一被识破,直到最后,老婆完全不在信任男主。这种情况,太矛盾了:你能接受“为你好、对你有利”的谎言吗?
———
不像很多美剧为了拍续集、不停故能玄虚绕圈子的套路,绝命毒师是一个完整的故事,到第五季结尾,尘归尘土归土,男主给家人留下了足够的钱,然后清理掉仇人,自己也挂了
话虽如此,倒数第二集,男主独自一人,守着一千万,躲在穷乡僻壤的小屋里。。。这时,真的希望故事就这么结束
可惜男主杀了个回马枪
故事结局,还算圆满吧,无论最初的目的是什么,男主也算罪大恶极,死的也算罪有应得
而他拼了老命挣下来的钱,总算有了一个合法的渠道,可以给到他的家人了~~,堪称死得其所