【微信小游戏开发】小游戏屏幕虚拟网格 - 像素游戏
我们知道,在平面世界,任何图形,几乎都可以看成是一个有起始点 (x,y)
和宽高 (width,height)
的矩形,不同的只是这个图形在矩形内部是如何绘制的
一般情况下,我们都把屏幕看成是一个起始点为 (0,0)
,宽高为屏幕像素宽高 (screenWidth,screenHeight)
的矩形
如果我们以 1px
横竖划分屏幕,那么每个小方块就是一个 1x1
的小正方形
这也是我们屏幕的网格系统,这种网格系统可以使用一个总长度为 width x height
的数组来表示
像素游戏
随着屏幕的分辨率越来越高,人眼已经看不清 1 x 1
像素的小正方形了,这时候我们就要把屏幕按照更高的像素单位来划分网格,当然,这是虚拟的,实际上我们没法改变屏幕本身的像素单位
例如以 w
个 1px
来划分屏幕,那么屏幕的虚拟高宽就是 (width/w,height/w)
此时我们可以使用一个长度为 (width/w) x (height/w)
的数组来表示这个屏幕
当然了,可能屏幕就会像图中那样,右边和下边不完整,那么数组的长度就是
(width/w+1)x(height/w+1)
整体的计算方法就是
// 以 `10px` 像素大小划分屏幕varunit=10;
varw=Math.ceil(c.width/unit);
varh=Math.ceil(c.height/unit);
// 数组长度
varsize[w*h];
这就是像素游戏划分屏幕的方法
虚拟网格
我们写一个范例,把上图中的虚拟网格给表现出来
game.js
varc=wx.createCanvas();varctx=c.getContext('2d');
varunit=10;
varw=Math.ceil(c.width/unit);
varh=Math.ceil(c.height/unit);
// 数组长度
varpixls=newArray(w*h);
varcur=0;
varpos=0;
// 每一个数组的值,创建一个黑白相间的数组
for(vari=0;i<h;i++){
cur=i%2==0?0:1;
for(varj=0;j<w;j++){
// 数组位置位置
pos=(i*w)+j;
pixls[pos]=cur;
cur=cur==1?0:1;
}
}
functionrenderVirtualGrid(){
ctx.save();
ctx.fillStyle='green';
ctx.fillRect(0,0,c.width,c.height);
ctx.fillStyle="#fff";
pos=0;
for(vari=0;i<h;i++){
for(varj=0;j<w;j++){
pos=(i*w)+j;
ctx.fillStyle=pixls[pos]==0?"#000":"#fff";
ctx.fillRect(j*unit,i*unit,unit,unit)
}
}
ctx.textAlign="center"// 居中对齐
ctx.textBaseline="middle"//垂直居中绘制
ctx.fillStyle="#aaa";
ctx.font="13px Arial"// 字体大小 44 像素
ctx.fillText("简单教程,简单编程",c.width/2,(c.height-25))
ctx.fillText(" © 2015-2018 www.twle.cn",c.width/2,(c.height-10));
ctx.restore();
}
renderVirtualGrid();
在微信中运行效果如下
范例: 贪吃蛇
虚拟网格有什么用呢?
比如做贪吃蛇游戏,小蛇每次只能前进一格子
我们写一个范例来模拟小蛇的移动吧
game.js
varc=wx.createCanvas();varctx=c.getContext('2d');
varunit=10;
varw=Math.ceil(c.width/unit);
varh=Math.ceil(c.height/unit);
// 数组长度
varpixls=newArray(w*h);
varcur=0;
varpos=0;
// 每一个数组的值,创建一个黑白相间的数组
for(vari=0;i<h;i++){
cur=i%2==0?0:1;
for(varj=0;j<w;j++){
// 数组位置位置
pos=(i*w)+j;
pixls[pos]=cur;
cur=cur==1?0:1;
}
}
vartt=null;// 用于保存定时器
// 用来判断是否在游戏中
// 0 表示未开始
// 1 表示游戏进行中
// 2 表示游戏已经结束
varingame=0;
// 用来保存开始触摸点
varlasted={x:null,y:null};
// 降帧,每秒 2 帧
varfps=(60/2);
varfps_s=0;
vargame={
v:1,
direction:1,// 0 1 2 3 分别表示上右下左
boxes:[],
draw_boxes:function(ctx){
for(vari=0;i<this.boxes.length;i++){
this.boxes[i].draw(ctx);
}
},
hit:function(){
varb=this.boxes[0];
varx=(b.x+1)*unit;
vary=(b.y+1)*unit;
// +1 是因为原点在左上角
returnx<0||y<0||(x+unit)>c.width||(y+unit)>c.height;
},
move:function(){
// 把数组里底部弹出来,然后在从数组头部插入一个元素
varbox=this.boxes[0];
varx=box.x;
vary=box.y;
switch(game.direction){
case0://向上
y--;
break;
case1://向右
x++;
break;
case2://向下
y++;
break;
case3:// 向左
x--;
}
varb=newBox();
b.x=x;
b.y=y;
this.boxes.unshift(b);
this.boxes.pop();
returnthis;
},
add:function(){
varbox=newBox();
varb2=this.boxes[0];
varx=b2.x;
vary=b2.y;
switch(game.direction){
case0://向上
y--;
break;
case1://向右
x++;
break;
case2://向下
y++;
break;
case3:// 向左
x--;
}
box.x=x;
box.y=y;
this.boxes.unshift(box);
returnthis;
}
}
// 蛇
functionBox(){
this.x=5;
this.y=5;
this.color='black';
this.draw=function(ctx){
ctx.save();
ctx.fillStyle="#000";
ctx.fillRect(this.x*unit,this.y*unit,unit,unit);
}
};
functionreset_game(){
game.v=1;
game.direction=1;
game.boxes=[];
varbox=newBox();
box.x=5;
box.y=5;
game.boxes.unshift(box);
}
functionreset(){
ctx.save();
ctx.fillStyle='#fff';
ctx.fillRect(0,0,c.width,c.height);
ctx.textAlign="center"// 居中对齐
ctx.textBaseline="middle"//垂直居中绘制
ctx.fillStyle="#aaa";
ctx.font="13px Arial"// 字体大小 44 像素
ctx.fillText("简单教程,简单编程",c.width/2,(c.height-25))
ctx.fillText(" © 2015-2018 www.twle.cn",c.width/2,(c.height-10));
ctx.restore();
if(ingame==0){
drawTip("请点击屏幕开始任意位置开始");
}
}
functiondrawTip(text){
ctx.save();
ctx.font="22px Arial"// 字体大小 44 像素
ctx.fillStyle='#333333';
ctx.textAlign="center"// 居中对齐
ctx.textBaseline="middle"//垂直居中绘制
ctx.fillText(text,c.width/2,c.height/2);
ctx.restore();
}
functionanimate_it(){
fps_s++;
// 降帧
if(fps_s%fps!=0){
requestAnimationFrame(animate_it);
return;
}
reset();
if(fps_s%(fps*10)==0){
game.add();
}else{
game.move();
}
game.draw_boxes(ctx);
if(game.hit()){
ingame=2;
drawTip("你失败了....,请点击画面重新开始");
cancelAnimationFrame(tt);
return;
}
requestAnimationFrame(animate_it);
}
// 绘制文本
functiondrawText(ctx,text){
ctx.save();
ctx.font="14px Arial"// 字体大小 44 像素
ctx.fillText(text,10,25);
ctx.restore();
}
// 触摸开始事件
wx.onTouchStart(function(e){
if(ingame==0||ingame==2){
return;
}
lasted.x=e.touches[0].clientX
lasted.y=e.touches[0].clientY
})
// 手指离开屏幕
wx.onTouchEnd(function(e){
console.log("wx.ontouchend:");
if(ingame==0||ingame==2){
ingame=1;
reset_game();
tt=requestAnimationFrame(animate_it);
return;
}
varx=e.touches[0].clientX
vary=e.touches[0].clientY
varx0=x-lasted.x;
vary0=y-lasted.y;
// 左右滑动
if(Math.abs(x0)>Math.abs(y0)){
game.direction=x0>0?1:3;
}else{// 上下滑动
game.direction=y0>0?2:0;
}
lasted.x=null;
lasted.y=null;
})
reset();
其它
大家还可以对这个小游戏做一些改动,比如
绘制边界,就是不使用屏幕边界,而是使用自己绘制的边界
加入另一个点,编程贪吃蛇游戏
加入如果是反方向可以掉头或者失败,因为自己撞了自己
改变每次重新画的局面,而是重绘变化的部分,提高帧率
以上是 【微信小游戏开发】小游戏屏幕虚拟网格 - 像素游戏 的全部内容, 来源链接: utcz.com/a/129894.html