先给大家看一个demo
http://www.koooi.com/html5/
代码很简单
页面上面加一个<canvas style="border:1px solid" id="canvas" width="1000" height="800">
<p>
Your browser does not support the canvas element.
</p>
</canvas>
然后javascript中写上
var canvas = null;
var ctx = null;
var score = 0;
var num = 51;
function getRandomInt(a, b){
return Math.floor(Math.random() * (b - a + 1)) + a;
}
window.onload = init;
function init(){
canvas = document.getElementById('canvas');
scoreID = document.getElementById('score');
ctx = canvas.getContext('2d');
// setInterval(draw, 1000 / FPS);
controller = new ERIC.CanvasController(ctx, canvas.width, canvas.height);
controller.animateStopBySignal();
canvas.onclick = function(e){
var mousex = e.clientX;
var mousey = e.clientY;
var relativex = mousex - canvas.offsetLeft;
var relativey = mousey - canvas.offsetTop;
var len = controller.canvasObjectList.length;
var infig = false;
for (i = len - 1; i >= 0; i--) {
if (controller.canvasObjectList[i].isInFigure(relativex, relativey)) {
score = score + 10;
infig = true;
controller.canvasObjectList[i].removeFromControl();
}
}
if (!infig) {
score = score - 10;
}
scoreID.innerHTML = score;
}
ERIC.run(function test(){
var t = getRandomInt(0, 0);
if (t == 0) {
num--;
if(num==0){
ERIC.stop();
return;
}
var cir1 = new ERIC.Circle(getRandomInt(70, 930), getRandomInt(70, 730), 5);
cir1.setTriggerDelete(function(){
return this.radius >= 40;
});
cir1.setAction(function(){
this.radius = this.radius + 1;
});
controller.add(cir1);
}
}, 400);
}
很简单的代码,利用了我写的基础类ERIC.Circle Eric.
CanvasController 以及ERIC.Run
使用简介:
1.先实例化ERIC.CanvasController,假设实例名字controller
2.实例化一个ERIC.BasicFigure类的子类的对象,现在EricUtils.js只提供了一个扩展类Circle,假设实例名字为cir
3.设置cir实例的动作和删除的条件。动作意思是每一个动画要执行什么操作,比如圆的半径加1, 或者圆心移动。删除的条件比如半径大于50就从画布当中删除掉,不再显示这个圆。
cir1.setTriggerDelete(function(){
return this.radius >= 40;
});
cir1.setAction(function(){
this.radius = this.radius + 1;
});
4.把cir添加到controller中。controller.add(cir)
5.调用controller.animate(); 此方法会以每秒30帧来画出cir对象,每帧结束执行cir在第三步设置的动作。到达删除条件会删除掉该object,直到没有object在controller当中。
6.也可以调用controller.animateStopBySignal()方法,动作和5相同,但是会一直进行渲染,这样适合于临时添加object到controller当中,添加进去以后马上就可以被渲染,直到满足被删除的条件。渲染结束需要调用controller.signalStop()
基础类下载地址http://www.koooi.com/html5/js/EricUtils.js
当然,这只是一个框架,以后要添加更多的功能,如果您对于html5有兴趣,打算和我一起来开发,欢迎联系我
希望可以起到抛砖引玉的作用。
QQ627四23四四三
摘要: 从小就有一个梦想,将来开发机器人,说白了,就是人工智能。现在看来,可喜的是,做的是软件这行,还有点可行性,可惜的是,做的工作与人工智能不搭嘎,工作又太累,天天加班不说,大老远跑回家,就没那么多时间去思考,学习人工智能了。徘徊犹豫了几个月,一直没有决心去写代码,这不,终于决定继续小时候的梦想,开始了用java实现人工智能的第一步了,那就是用java来分析语义,让我们从头开始。
我的第一个Miles... 阅读全文
最大字串问题描述大概就是给定2个字符串,找出他们两个共有的最长字符串。比如一个是"tabcfg"另外一个"abckj"那么最大子串就是"abc".
动态规划算法最重要的就是分解问题,找出递归。说一下我的思考思路,首先拿到2个字符串,如何找到最长子串呢?
1.假设他们(字符串a,b)的头字母不相同的话,那么分别去掉首字母比较,也就是说用a.subString(1)和b比较,用b.subString(1)和a比较,最长子字符串没变吧?答案是肯定的。ok递归出现了,结束条件就是有一个字符串变空,返回值就是a和b的最长子串。
b.假设他们头字母相同,那么一直比较下去,知道两者的第n个字母不相同,然后把前n-1个字母存为子字符串c,把a.subString(1)和b返回结果记为d,b.subString(1)和a返回结果记为e,那么返回c,d和e最长的一个(感谢lexy的评论,之前确实遗漏一种情况。不应该直接把前面的相同的去掉直接比较的,现在代码已经更新了)。
也许有人说应该从后面往前面比较,找到相同的然后一个个再往前比,其实道理都是一样的,关键要找到分解问题的方法。这里只是抛砖引玉,下面是具体的java实现。
import java.util.HashMap;
import java.util.Map;
/**
* @author HEACK
*
*/
public class CompareStr {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String str1 = "abcde1234567abcdefghijk";
String str2 = "abcdefgh12345";
//String str2 = "abc happyies dutcbirthday peter";
CompareStr cj = new CompareStr();
System.out.println(cj.getLongestString(str1,str2));
}
private boolean isEmpty(String str) {
return str == null || str.trim().length() == 0;
}
private Map map = new HashMap();
private String getLongestString(String str1, String str2) {
if (isEmpty(str1) || isEmpty(str2)) {
return "";
}
StringBuffer key = new StringBuffer();
key.append(str1).append("&&").append(str2);
if (map.containsKey(key.toString())) {
return (String)map.get(key.toString());
}
StringBuffer longestStr = new StringBuffer();
char[] str1List = str1.toCharArray();
char[] str2List = str2.toCharArray();
int i = 0;
for (i = 0; i < str1List.length && i < str2List.length; i++) {
if (str1List[i] == str2List[i]) {
longestStr.append(str1List[i]);
} else {
break;
}
}
String subStr1 = str1.substring(i);
String subStr2 = str2.substring(i);
if (i == 0) {
String retStr1 = getLongestString(subStr1.substring(1), subStr2);
String retStr2 = getLongestString(subStr1, subStr2.substring(1));
String returnStr = retStr1.length() >= retStr2.length() ? retStr1 : retStr2;
map.put(key.toString(), returnStr);
return returnStr;
} else {
String retStr1 = getLongestString(str1.substring(1), str2);
String retStr2 = getLongestString(str1, str2.substring(1));
String retStr = retStr1.length() > retStr2.length() ? retStr1
: retStr2;
String returnStr = retStr.length() >= longestStr.toString().length() ? retStr
: longestStr.toString();
map.put(key.toString(), returnStr);
return returnStr;
}
}
}
HashMap用来存储已经计算过的字符串,用空间换时间。代码当然还可以优化,您也可以一试身手哦。
倘若,有这么一个需求,对于一个数字,如果是负的,那么需要变成正的相反数,如果是2的倍数,那么就除以2,如果是3的倍数,那么就除以3,可能以后还有其他的需求,比如是5的倍数,就再除以5,或者是6的倍数,那么就加上6,也就是结果与顺序息息相关,那么应该如何来实现呢?
如果写一个类的方法,按照这个需求来写if语句,可以,但是,如果有两套定制的呢?一套需要其中的几种变化,另外需要另外几种,那么就需要2个方法,而且其中有很多的重复代码,这样行不通的.
其实设计模式说到底,其根本思想就是找到变化并封装之.这里变化的是处理的方法,那么我们就把它封装起来.实现的类如下:
package decorater;
public class Integor {
private Integer x;
public Integer getX() {
return x;
}
public void setX(Integer x) {
this.x = x;
}
Integor(Integer x){
this.x = x;
}
}
由于Integer不能修改传递的值,所以写一个类来封装一个integer
/**
*
*/
package decorater;
public abstract class Decorater {
private Decorater next;
public Decorater setNext(Decorater dcrtr) {
this.next = dcrtr;
return this.next;
}
public void process(Integor x) {
this.executeBefore(x);
if (this.next != null) {
this.next.process(x);
}
this.executeAfter(x);
}
protected abstract void executeBefore(Object x);
protected abstract void executeAfter(Object x);
}
每个实现的类只需要来实现executeBefore和executeAfter方法即可.
注意实现的顺序是
decorater1.executeBefore->decorater2.executeBefore->decorater3.executeBefore->decorater3.executeAfter->decorater2.executeAfter->decorater1.executerAfter
package decorater;
public class PositiveDecorater extends Decorater {
@Override
protected void executeAfter(Object x) {
System.out.println("PositiveDecorater end!");
}
@Override
protected void executeBefore(Object x) {
// TODO Auto-generated method stub
System.out.println("starting PositiveDecorater!");
Integor in = (Integor) x;
if (in.getX() < 0)
in.setX(-in.getX());
}
}
package decorater;
public class Devide2Decorater extends Decorater {
@Override
protected void executeAfter(Object x) {
System.out.println("Devide2Decorater end!");
}
@Override
protected void executeBefore(Object x) {
System.out.println("Starting Devide2Decorater!");
Integor in = (Integor) x;
if (in.getX() % 2 == 0) {
in.setX(in.getX() / 2);
}
}
}
package decorater;
public class Devide3Decorater extends Decorater {
@Override
protected void executeAfter(Object x) {
System.out.println("Devide3Decorater end!");
}
@Override
protected void executeBefore(Object x) {
System.out.println("Starting Devide3Decorater!");
Integor in = (Integor) x;
if (in.getX() % 3 == 0) {
in.setX(in.getX() / 3);
}
}
}
/**
*
*/
package decorater;
/**
* @author KONGHE
*
*/
public class Main {
/**
* @param args
*/
public static void main(String[] args) {
Decorater a = new PositiveDecorater();
a.setNext(new Devide2Decorater()).setNext(new Devide3Decorater());
Integor x = new Integor(-18);
a.process(x);
System.out.println(x.getX());
}
}
输出结果是:
starting PositiveDecorater!
Starting Devide2Decorater!
Starting Devide3Decorater!
Devide3Decorater end!
Devide2Decorater end!
PositiveDecorater end!
3
其实每种设计模式的核心思想都是一致的,但是没有必要照本宣科,只要注意其模式的精髓,就可以了,剩下的就是自己去按照实现来设计其中的细节了.比如我设计这个模式,就是先写了main函数,把其中的方法写好,然后去按照这个实现来想去如何实现,这样才更符合解决实际的问题.其实decorater模式有很多种实现方式.比如下面的这种解法,也可:
/**
*
*/
package decorator;
/**
* @author KONGHE
*
*/
public class Main {
/**
* @param args
*/
public static void main(String[] args) {
DecoraterChain a = new DecoraterChain();
a.setNext(new PositiveDecorater()).setNext(new Devide2Decorater()).setNext(new Devide3Decorater());
Integer x = -32;
x = a.process(x);
System.out.println(x);
}
}
/**
*
*/
package decorator;
import java.util.ArrayList;
import java.util.List;
/**
* @author KONGHE
*
*/
public class DecoraterChain {
private List<Decorater> decorater = new ArrayList<Decorater>();
public DecoraterChain setNext(Decorater decrter) {
decorater.add(decrter);
return this;
}
public Integer process(Integer x) {
for (int i = 0; i < this.decorater.size(); i++) {
x = this.decorater.get(i).process(x);
}
return x;
}
}
/**
*
*/
package decorator;
/**
* @author KONGHE
*
*/
public abstract class Decorater {
public abstract Integer process(Integer x);
}
总而言之,模式是为了具体的实际情况而服务的,不要为了一定要去用某种设计模式而委屈自己的需求.
在设计的时候多想想,可能某天你再读设计模式的书,你会发现,原来我之前写的代码,包含了这么多的设计模式啊!