colonleado's

关于游戏也关于技术 im Co
数据加载中……
位操作在实际开发中的应用
位操作就是将10进制数想为“01010000111”这样的2进制形式去运算、操作 常用运算符有|&<<>>^等

在C++的开发里一般是不推荐使用位操作的,因为会降低代码的可读性。而且J2me开发中因为内存、运算速度等诸多原因,所以推荐使用位操作。

实际应用1:按键处理
首先在我们的主Canvas里要调用
 1/**
 2     * 键盘接收
 3     */

 4    protected void keyPressed(int keyCode) {
 5        
 6        CType.setKeyState(keyCode);
 7        
 8    }

 9
10    /**
11     * 键盘放开处理
12     */

13    protected void keyReleased(int keyCode) {
14        
15        CType.clearKeyState(keyCode);
16        
17    }

然后在我的CType里面:
  1public static final int K_UP = 1;
  2    public static final int K_DOWN = 1 << 1;
  3    public static final int K_LEFT = 1 << 2;
  4    public static final int K_RIGHT = 1 << 3;
  5    public static final int K_FIRE = 1 << 4;
  6    public static final int K_COMMAND_LEFT = 1 << 5;
  7    public static final int K_COMMAND_RIGHT = 1 << 6;
  8    public static final int K_NUM1 = 1 << 7;
  9    public static final int K_NUM2 = 1 << 8;
 10    public static final int K_NUM3 = 1 << 9;
 11    public static final int K_NUM4 = 1 << 10;
 12    public static final int K_NUM5 = 1 << 11;
 13    public static final int K_NUM6 = 1 << 12;
 14    public static final int K_NUM7 = 1 << 13;
 15    public static final int K_NUM8 = 1 << 14;
 16    public static final int K_NUM9 = 1 << 15;
 17    public static final int K_NUM0 = 1 << 16;
 18    public static final int K_POUND = 1 << 17;
 19    public static final int K_STAR = 1 << 18;
 20    public static final int K_C = 1 << 19;
 21    
 22    public static final int COMMAND_UP = K_UP | K_NUM2;
 23    public static final int COMMAND_DOWN = K_DOWN | K_NUM8;
 24    public static final int COMMAND_LEFT = K_LEFT | K_NUM4;
 25    public static final int COMMAND_RIGHT = K_RIGHT | K_NUM6;
 26    public static int COMMAND_OK = K_FIRE | K_NUM5;
 27    public static int COMMAND_BACK = isleft ? K_COMMAND_RIGHT : K_COMMAND_LEFT;
 28    public static int COMMAND_LEFT_OK = isleft ? K_COMMAND_LEFT : K_COMMAND_RIGHT;
 29    
 30    public static int key = 0;
 31    /*============================= keycode ==========================*/
 32    // nokia
 33    public static int UP = -1;
 34    public static int DOWN = -2;
 35    public static int LEFT = -3;
 36    public static int RIGHT = -4;
 37    public static int FIRE = -5;
 38    public static int SOFT_LEFT = -6
 39    public static int SOFT_RIGHT = -7
 40    public static int NUM0 = 48;
 41    public static int NUM1 = 49;
 42    public static int NUM2 = 50;
 43    public static int NUM3 = 51;
 44    public static int NUM4 = 52;
 45    public static int NUM5 = 53;
 46    public static int NUM6 = 54;
 47    public static int NUM7 = 55;
 48    public static int NUM8 = 56;
 49    public static int NUM9 = 57;
 50    public static int POUND = 35;// #
 51    public static int ASTERISK = 42;// *
 52    public static int SEND = -10;// 
 53    public static int END = -11;// 
 54    public static int POWER = -12;
 55    public static int SOFT3 = -20;
 56    public static int CLEAR = -8;// 
 57public static void setKeyState(int keyCode){
 58        
 59        if(keyCode == UP)
 60            
 61            key |= K_UP;
 62        
 63        else if(keyCode == DOWN)
 64            
 65            key |= K_DOWN;
 66        
 67        else if(keyCode == LEFT)
 68            
 69            key |= K_LEFT;
 70        
 71        else if(keyCode == RIGHT)
 72            
 73            key |= K_RIGHT;
 74        
 75        else if(keyCode == FIRE)
 76            
 77            key |= K_FIRE;
 78        
 79        else if(keyCode == SOFT_LEFT)
 80            
 81            key |= K_COMMAND_LEFT;
 82        
 83        else if(keyCode == SOFT_RIGHT)
 84            
 85            key |= K_COMMAND_RIGHT;
 86        
 87        else if(keyCode == NUM0)
 88            
 89            key |= K_NUM0;
 90        
 91        else if(keyCode == NUM1)
 92            
 93            key |= K_NUM1;
 94        
 95        else if(keyCode == NUM2)
 96            
 97            key |= K_NUM2;
 98        
 99        else if(keyCode == NUM3)
100            
101            key |= K_NUM3;
102        
103        else if(keyCode == NUM4)
104            
105            key |= K_NUM4;
106        
107        else if(keyCode == NUM5)
108            
109            key |= K_NUM5;
110        
111        else if(keyCode == NUM6)
112            
113            key |= K_NUM6;
114        
115        else if(keyCode == NUM7)
116            
117            key |= K_NUM7;
118        
119        else if(keyCode == NUM8)
120            
121            key |= K_NUM8;
122        
123        else if(keyCode == NUM9)
124            
125            key |= K_NUM9;
126        
127        else if(keyCode == POUND)
128            
129            key |= K_POUND;
130        
131        else if(keyCode == ASTERISK)
132            
133            key |= K_STAR;
134        
135        if(doublePressedTimer < DOUBLE_PRESSED_TIMER 
136                && lastDoublePressedKey == keyCode){
137            
138            doublePressed = true;
139            
140        }
else{
141            
142            doublePressed = false;
143            
144        }

145        
146    }

147    
148    public static void clearAllKeyState(){
149        
150        key = 0;
151        
152    }

153    
154    public static void clearKeyState(int keyCode){
155        
156        if(keyCode == UP)
157            
158            key  &= (K_UP ^ 0xffffffff);
159        
160        else if(keyCode == DOWN)
161            
162            key  &= (K_DOWN ^ 0xffffffff);
163        
164        else if(keyCode == LEFT)
165            
166            key  &= (K_LEFT ^ 0xffffffff);
167        
168        else if(keyCode == RIGHT)
169            
170            key  &= (K_RIGHT ^ 0xffffffff);
171        
172        else if(keyCode == FIRE)
173            
174            key  &= (K_FIRE ^ 0xffffffff);
175        
176        else if(keyCode == SOFT_LEFT)
177            
178            key  &= (K_COMMAND_LEFT ^ 0xffffffff);
179        
180        else if(keyCode == SOFT_RIGHT)
181            
182            key  &= (K_COMMAND_RIGHT ^ 0xffffffff);
183        
184        else if(keyCode == NUM0)
185            
186            key  &= (K_NUM0 ^ 0xffffffff);
187        
188        else if(keyCode == NUM1)
189            
190            key  &= (K_NUM1 ^ 0xffffffff);
191        
192        else if(keyCode == NUM2)
193            
194            key  &= (K_NUM2 ^ 0xffffffff);
195        
196        else if(keyCode == NUM3)
197            
198            key  &= (K_NUM3 ^ 0xffffffff);
199        
200        else if(keyCode == NUM4)
201            
202            key  &= (K_NUM4 ^ 0xffffffff);
203        
204        else if(keyCode == NUM5)
205            
206            key  &= (K_NUM5 ^ 0xffffffff);
207        
208        else if(keyCode == NUM6)
209            
210            key  &= (K_NUM6 ^ 0xffffffff);
211        
212        else if(keyCode == NUM7)
213            
214            key  &= (K_NUM7 ^ 0xffffffff);
215        
216        else if(keyCode == NUM8)
217            
218            key  &= (K_NUM8 ^ 0xffffffff);
219        
220        else if(keyCode == NUM9)
221            
222            key  &= (K_NUM9 ^ 0xffffffff);
223        
224        else if(keyCode == POUND)
225            
226            key  &= (K_POUND ^ 0xffffffff);
227        
228        else if(keyCode == ASTERISK)
229            
230            key  &= (K_STAR ^ 0xffffffff);
231        
232        lastDoublePressedKey = keyCode;
233        
234        doublePressedTimer = 0;
235        
236    }

237    
238    public static boolean getKeyState(int command){
239        
240        return (key & command) != 0;
241        
242    }

243    
244    public static boolean getKeyStateOnce(int command){
245        
246        boolean tmp = (key & command) != 0;
247        
248        if(tmp) clearAllKeyState();
249        
250            return tmp;
251    }

252    
253    public static boolean haveKeyPressedEvent(){
254        
255        return key != 0;
256        
257    }

258    
259    /**
260     * 双击方向键上
261     * @return
262     */

263    public static boolean doubleCommandUp(){
264        
265        return getKeyState(COMMAND_UP) && doublePressed;
266        
267    }

268    
269    /**
270     * 双击方向键下
271     * @return
272     */

273    public static boolean doubleCommandDown(){
274        
275        return getKeyState(COMMAND_DOWN) && doublePressed;
276        
277    }

278    
279    /**
280     * 双击方向键左
281     * @return
282     */

283    public static boolean doubleCommandLeft(){
284        
285        return getKeyState(COMMAND_LEFT) && doublePressed;
286        
287    }

288    
289    /**
290     * 双击方向键右
291     * @return
292     */

293    public static boolean doubleCommandRight(){
294        
295        return getKeyState(COMMAND_RIGHT) && doublePressed;
296        
297    }

298    
299    /**
300     * 双击方向键确定
301     * @return
302     */

303    public static boolean doubleCommandOK(){
304        
305        return getKeyState(COMMAND_OK) && doublePressed;
306        
307    }

308    
309    /**
310     * 按下方向键上
311     * @return
312     */

313    public static boolean commandUp(){
314        
315        return getKeyState(COMMAND_UP);
316        
317    }

318    
319    /**
320     * 按下方向键下
321     * @return
322     */

323    public static boolean commandDown(){
324        
325        return getKeyState(COMMAND_DOWN);
326        
327    }

328    
329    /**
330     * 按下方向键左
331     * @return
332     */

333    public static boolean commandLeft(){
334        
335        return getKeyState(COMMAND_LEFT);
336        
337    }

338    
339    /**
340     * 按下方向键右
341     * @return
342     */

343    public static boolean commandRight(){
344        
345        return getKeyState(COMMAND_RIGHT);
346        
347    }

348    
349    /**
350     * 按下方向键确定
351     * @return
352     */

353    public static boolean commandOK(){
354        
355        return getKeyState(COMMAND_OK);
356        
357    }

358    
359    /**
360     * 按下确定软键
361     * @return
362     */

363    public static boolean commandLeftOk(){
364        
365        return getKeyState(COMMAND_LEFT_OK);
366        
367    }

368    
369    /**
370     * 按下取消软键
371     * @return
372     */

373    public static boolean commandBack(){
374        
375        return getKeyState(COMMAND_BACK);
376        
377    }

378    
379    /**
380     * 单击方向键上一次
381     * @return
382     */

383    public static boolean commandUpOnce(){
384        
385        boolean r = commandUp();
386        
387        if(r)
388            
389            clearAllKeyState();
390        
391        return r;
392        
393    }

394    
395    /**
396     * 单击方向键下一次
397     * @return
398     */

399    public static boolean commandDownOnce(){
400        
401        boolean r = commandDown();
402        
403        if(r)
404            
405            clearAllKeyState();
406        
407        return r;
408        
409    }

410    
411    /**
412     * 单击方向键左一次
413     * @return
414     */

415    public static boolean commandLeftOnce(){
416        
417        boolean r = commandLeft();
418        
419        if(r)
420            
421            clearAllKeyState();
422        
423        return r;
424        
425    }

426    
427    /**
428     * 单击方向键右一次
429     * @return
430     */

431    public static boolean commandRightOnce(){
432        
433        boolean r = commandRight();
434        
435        if(r)
436            
437            clearAllKeyState();
438        
439        return r;
440        
441    }

442    
443    /**
444     * 单击确定键一次
445     * @return
446     */

447    public static boolean commandOkOnce(){
448        
449        boolean r = commandOK();
450        
451        if(r)
452            
453            clearAllKeyState();
454        
455        return r;
456        
457    }

458    
459    /**
460     * 单击确定软键一次
461     * @return
462     */

463    public static boolean commandLeftOkOnce(){
464        
465        boolean r = commandLeftOk();
466        
467        if(r)
468            
469            clearAllKeyState();
470        
471        return r;
472        
473    }

474    
475    /**
476     * 单击取消软键一次
477     * @return
478     */

479    public static boolean commandBackOnce(){
480        
481        boolean r = commandBack();
482        
483        if(r)
484            
485            clearAllKeyState();
486        
487        return r;
488        
489    }

其实就是你想想象一串的01010101010010000每个位都代表一个按键 当他是1的时候就是按下了 0就表示没被按下


实际应用2:效果Buffer
 1// 比如这里我们定义一些技能效果
 2static final int 
 3SKILL_BUFFER_燃烧 = 1
 4SKILL_BUFFER_眩晕 = 1 << 1,
 5SKILL_BUFFER_攻击力X2 = 1 << 2
 6SKILL_BUFFER_必闪 = 1 << 3;
 7
 8// 为什么不写成
 9// SKILL_BUFFER_燃烧 = 1, 
10// SKILL_BUFFER_眩晕 = 2,
11// SKILL_BUFFER_攻击力X2 = 3, 
12// SKILL_BUFFER_必闪 = 4; 呢?
13// 因为有可能我身上的效果是很多叠在一起的
14// 我可能身上又着火又眩晕 
15// 用位操作就可以实现多状态buffer的共存
16
17public void setBuffer_燃烧(){
18    buffer |= SKILL_BUFFER_燃烧;
19}

20
21public void clearBuffer_燃烧(){
22
23}

24
25public boolean isBuffer_燃烧(){
26    return (buffer & SKILL_BUFFER_燃烧) != 0;
27}



实际应用3:整型保存数据
在实际开发的时候,有时候我们想把多个数字保存在一个int里面,那么可以这样
 1/**
 2     * 将一个数保存在整数里
 3     * @param src 原始数据
 4     * @param num 要保存的数据
 5     * @param begin  从第几位开始写
 6     * @return
 7     */

 8    public static int setBit(int src, int num, int begin){
 9        return src | (num << begin);
10    }

11    
12    /**
13     * 得到一个整数的某几位
14     * @param src 原数据
15     * @param begin 从第几位开始获取
16     * @param len 获取长度多少位
17     * @return
18     */

19    public static int getBit(int src, int begin, int len){
20        return (src & getDec(begin, len)) >> begin;
21    }

22    
23    private static int getDec(int begin, int len){
24        int k = 0;
25        for(int i = 0; i < len; ++i){
26            k |= (1 << i);
27        }

28        return k << begin;
29    }

这个在实际开发中是常用的,比如我的地图数据,其图块编号也就0~100多那么我可以把多层的同一个格子的数据写到一个int里面
注意不要存负数就可以了,因为负数前面可有一位符号位哦
想起来曾经刚使用位的时候总是出错 给我的惊喜就像刚写C++时控制台上满满的烫烫烫一样~


夏天的确很烫


posted on 2010-07-04 12:52 colonleado 阅读(1711) 评论(3)  编辑  收藏 所属分类: J2me

评论

# re: 位操作在实际开发中的应用 2010-07-04 15:55 nmb

你得解释一下为什么要这么做吧.
比如1 << 1 ,1 << 2
COMMAND_UP = K_UP | K_NUM2;
可以达到想要的效果
也就是说他的规律是什么?
  回复  更多评论    

# re: 位操作在实际开发中的应用 2010-07-05 10:30 colonleado

@nmb
比如我们第一位的状态(0或1)表示方向键上是否被按下
第八位的状态表示数字键2是否被按下
COMMAND_UP就是方向键上和数字键2的组合按键
所有COMMAND开头的都是组合按键
COMMAND_UP就是通过检测它不论你按下了方向键上还是数字键2都会返回你按了上
  回复  更多评论    

# re: 位操作在实际开发中的应用 2010-07-05 18:39 Jie

感觉讲解的不清楚,比如:
为什么不写成
SKILL_BUFFER_燃烧 = 1,
SKILL_BUFFER_眩晕 = 2,
SKILL_BUFFER_攻击力X2 = 3,
SKILL_BUFFER_必闪 = 4; 呢?
因为有可能我身上的效果是很多叠在一起的
我可能身上又着火又眩晕
用位操作就可以实现多状态buffer的共存

共存?咋样共存?我看完文章后的感觉是位操作就是为了提高代码的可阅读性
  回复  更多评论    

只有注册用户登录后才能发表评论。


网站导航: