Javascript 图形动画笔记(8) 砖块贴图点阵字
时间:2010-10-11 来源:左洸
提示:本文需要 Chorme 浏览器才能看到程序的运行效果。 原来以为象坦克大战、超级玛丽之类的小游戏,开始画面里面的砖块字是静态图片,现在才知道原来都是动态贴图贴出来的,下面用 HTML5 的绘图功能,咱也太做一个坦克大决战的开始画面,顺便研究一下点阵字。
一、点阵字 贴图实际上和点阵字没有多大区别,唯一的区别就是把点用小图片代替了而已,下面是一个点阵字的小程序,你可以输入汉字或者英文字母,然后程序就会分析并生成文字的点阵,然后把它显示出来。至于怎么分析并生成点阵,思路如下: |
1、将文字用 ctx.fillText 方法画到一块内存画布上,前景色为黑,背景色为白
2、读取画布的每一个像素,并用相应的符号代替,组成字符串
这里有一个问题,内存画布应该多大?我的解决办法是,尽可能大,保证无论什么字体都不会出界。
在分析完像素的过程中,同时可以记录下文字的宽度和高度,等分析完成以后,再一次生成一块新的画布,这一次可以和文字大小更好相等。
还有一个问题就是文字太小的时候,字体就有点失真,这应该就是一个分辨率的问题,小字体人的肉眼看不清的,程序一样也分析不清楚。
所以小尺寸的字体需要经过专门的设计,像坦克大战上的字体那样。
程序运行如下:
http://www.cnblogs.com/myqiao/archive/2010/10/11/1847795.html
放在另外一个页面中是因为代码有点小问题,一个页面现在只能对一个 Canvas 进行处理,为了防止出现错误,所以放在另外一个页面中。
二、砖块字
知道了点阵子的原理,实现砖块字就很简单了,这里是一副资源图片,砖块就是从里面截取的:
砖块很小,在图片的中间靠右下方,我们玩的坦克大战游戏里面每一关的地图就是由这么简单一个图片生成的,真是没想到啊。
下面是砖块字的点阵数据,这里只有一部分,刚好组成游戏开机画面里面的:BATTLE CITY 和游戏结束画面里面的 GAME OVER
代码 var keys="abcegilmortvy";var values=["0011100011011011000111100011111111111000111100011",
"1111110110001111000111111110110001111000111111110",
"0011110011001111000001100000110000001100110011110",
"1111110110000011000001111100110000011000001111110",
"0011111011000011000001100111110001101100110011111",
"1111110001100000110000011000001100000110001111110",
"1100000110000011000001100000110000011000001111110",
"1100011111011111111111111111110101111000111100011",
"0111110110001111000111100011110001111000110111110",
"1111110110001111000111100111111110011011101100111",
"1111110001100000110000011000001100000110000011000",
"1100011110001111000111110111011111000111000001000",
"1100110110011011001100111100001100000110000011000"];
下面是程序运行画面,和真实游戏还有一点区别的是,为了能看清楚贴图过程,我是一帧一帧显示出来的,而真正的游戏里面是全部绘制完成了才显示出来。
{{{{{{
你的浏览器不支持 Canvas 标签,请使用 Chrome 浏览器 或者 FireFox 浏览器
}}}}}}
三、代码
因为时间比较紧张,代码写的比较丑,代码里面用到了一个 jsgame.js,这是我自己对 HTML5 2D 功能进行了一个简单的包装,模仿了 pygame 的部分接口样式。
经过封装以后,可以看出来,绘图相关的代码就非常简单了,其他主要都是运算逻辑代码。
点阵字代码 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript" language="javascript" src="jsgame.js"></script>
</head>
<body>
<canvas id="html5_08_1" width="180" height="180" style=" background-color: black">
你的浏览器不支持 Canvas 标签,请使用 Chrome 浏览器 或者 FireFox 浏览器
</canvas>
文本:<input type="text" id="text" value="博客园" />
字号:<input type="text" id="size" value="16" size="2" />
字体:<select id="fontName">
<option>宋体</option>
<option>楷体_GB2312</option>
<option>隶书</option>
<option>Kristen ITC</option>
<option>Harrington</option>
</select>
<input type="checkbox" id="ckBold" />黑体
<input type="checkbox" id="ckitalic" />斜体
<input type="button" id="btnStart" disabled value="处理" onclick="on_click()" />
<br/><textarea wrap="off" rows="20" cols="120" id="txtResult" ></textarea>
<script type="text/javascript">
jsgame.display.attach(document.getElementById("html5_08_1"));
on_click();
function on_click(){
document.getElementById("btnStart").setAttribute("disabled","true");
jsgame.run(function(){
document.getElementById("txtResult").value="";
jsgame.display.clear();
var text=document.getElementById("text").value
var size=document.getElementById("size").value
jsgame.font.bold=document.getElementById("ckBold").checked;
jsgame.font.italic=document.getElementById("ckitalic").checked;
jsgame.font.name=document.getElementById("fontName").value;
var sur=jsgame.font.render(text,size);
jsgame.display.draw(sur,10,10);
var str='';
for(var y=0;y<sur.height;y++){
for(var x=0;x<sur.width;x++){
if((sur.get_pixel(x,y)[0]<255))
str=str+'龍';
else
str=str+' ';
}
str=str+'\n';
}
document.getElementById("txtResult").value=str;
document.getElementById("btnStart").removeAttribute("disabled");
});
}
</script>
</body>
</html>
砖块字代码 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript" language="javascript" src="jsgame.js"></script>
</head>
<body>
<img id="img_sprite" src="src="http://images.cnblogs.com/cnblogs_com/myqiao/sprites.gif" width="96" height="112" /><br/>
<canvas id="html5_08_2" width="480" height="200" style=" background-color: black">
你的浏览器不支持 Canvas 标签,请使用 Chrome 浏览器 或者 FireFox 浏览器
</canvas><br/>
<input type="button" id="btn_draw" value="绘制砖块字" onclick="draw_brick_text()" />
<script type="text/javascript">
var keys="abcegilmortvy";
var values=["0011100011011011000111100011111111111000111100011",
"1111110110001111000111111110110001111000111111110",
"0011110011001111000001100000110000001100110011110",
"1111110110000011000001111100110000011000001111110",
"0011111011000011000001100111110001101100110011111",
"1111110001100000110000011000001100000110001111110",
"1100000110000011000001100000110000011000001111110",
"1100011111011111111111111111110101111000111100011",
"0111110110001111000111100011110001111000110111110",
"1111110110001111000111100111111110011011101100111",
"1111110001100000110000011000001100000110000011000",
"1100011110001111000111110111011111000111000001000",
"1100110110011011001100111100001100000110000011000"];
jsgame.display.attach(document.getElementById("html5_08_2"));
var img=document.getElementById("img_sprite");
jsgame.is_ready(function(){
return img.complete
});
var bricks=[];
jsgame.run(function(){
var temp= jsgame.Surface(img).subsurface(56,64,8,8)
bricks[0]=temp.subsurface(0,0,4,4)
bricks[1]=temp.subsurface(4,0,4,4)
bricks[2]=temp.subsurface(0,4,4,4)
bricks[3]=temp.subsurface(4,4,4,4)
});
function chunk(str,len){
var count=0;
var list=[];
var temp=[];
var times=0;
for(var i=0;i<str.length;i++){
if(count<len){
temp.push(str[i])
count++;
}else{
count=0;
list[times]=temp;
temp=[];
temp.push(str[i])
count++;
times++;
}
}
list[times]=temp;
return list;
}
function draw_brick_text(){
jsgame.stop()
jsgame.display.clear();
var text='BATTLECITY'.toLowerCase();
var alph_bits=[];
for(var i=0;i<text.length;i++)
for(var index=0;index<keys.length;index++)
if(keys[index]==text[i])
alph_bits.push(chunk(values[index],7));
var which=0;
var p_row=0;
var p_col=0;
var surface=jsgame.Surface(28,28)
jsgame.loop(function(){
jsgame.time.pause()
if(alph_bits[which][p_row][p_col]==1){
var temp=null;
if((p_row%2)==0){
if((p_col%2)==0)
temp=bricks[0];
else
temp=bricks[1];
}
else{
if((p_col%2)==0)
temp=bricks[2];
else
temp=bricks[3];
}
surface.draw(temp,p_col*4,p_row*4)
jsgame.display.save()
jsgame.display.scale(2,2)
if(which<6)
jsgame.display.draw(temp,which*32+p_col*4+20,p_row*4+20);
else
jsgame.display.draw(temp,(which-5)*32+p_col*4+20,p_row*4+56);
jsgame.display.restore()
}
p_col++
if((p_col%7)==0){
p_col=0
p_row++
if((p_row%7)==0){
p_row=0;
p_col=0;
which++;
if(which==text.length) jsgame.stop()
}
}
jsgame.time.go()
})
}
</script>
</body>
</html>
//==========================================