30-粗糙滚动的完整代码示例
9.4.8 粗糙滚动的完整代码示例
例9-2展示了粗糙滚动实力的完整代码。粗糙滚动的代码比精确滚动的版本稍简单一些,这是因为不需要使用rowBuffe和colBuffer变量。但是,同样需要通过矩阵变换平移Canvas。用户仅需绘制当前的一组区块,不需要像精确滚动那样绘制任何部分的区块。
例9-2 粗糙滚动
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CH9 EX3 - Scrolling Test 1 coarse scrolling</title>
<script src="modernizr.min.js"></script>
<script type="text/javascript">
window.addEventListener('load', eventWindowLoaded, false);
function eventWindowLoaded() {
canvasApp();
}
</script>
<script language="Javascript">
function canvasSupport () {
return Modernizr.canvas;
}
function canvasApp(){
if (!canvasSupport()) {
return;
}else{
var theCanvas = document.getElementById('canvas');
var context = theCanvas.getContext('2d');
}
document.onkeydown=function(e){
e=e?e:window.event;
keyPressList[e.keyCode]=true;
}
document.onkeyup=function(e){
//document.body.onkeyup=function(e){
e=e?e:window.event;
keyPressList[e.keyCode]=false;
};
//用户按键列表
var keyPressList=[];
//图像
var tileSheet = new Image();
tileSheet.src = "scrolling_tiles.png";
//地图数据
var world={};
//镜头
var camera={}
//用户按键列表
var keyPressList={};
function init() {
world.cols=15;
world.rows=15;
world.tileWidth=32;
world.tileHeight=32;
world.height=world.rows*world.tileHeight;
world.width=world.cols*world.tileWidth;
camera.height=theCanvas.height;
camera.width=theCanvas.width;
camera.rows=camera.height / world.tileHeight;
camera.cols=camera.width / world.tileWidth;
camera.dx=0;
camera.dy=0;
camera.x=0;
camera.y=0;
keyPressList=[];
gameLoop()
}
function runGame() {
camera.dx=0;
camera.dy=0;
//检查用户输入
if (keyPressList[38]){
console.log("up");
camera.dy=-world.tileHeight;
}
if (keyPressList[40]){
console.log("down");
camera.dy=world.tileHeight;
}
if (keyPressList[37]){
console.log("left");
camera.dx=-world.tileWidth;
}
if (keyPressList[39]){
console.log("right");
camera.dx=world.tileWidth;
}
camera.x+=camera.dx;
camera.y+=camera.dy;
if (camera.x<0) {
camera.x=0;
}else if (camera.x > (world.width - camera.width)-world.tileWidth) {
camera.x=world.width - camera.width;
}
if (camera.y<0) {
camera.y=0;
}else if (camera.y > (world.height - camera.height)-world.tileHeight) {
camera.y=world.height - camera.height;
}
context.fillStyle = '#000000';
context.fillRect(0, 0, theCanvas.width, theCanvas.height);
//绘制镜头
//计算起始区块的位置
var tilex=Math.floor(camera.x/world.tileWidth);
var tiley=Math.floor(camera.y/world.tileHeight);
var rowCtr;
var colCtr;
var tileNum;
for (rowCtr=0;rowCtr<camera.rows;rowCtr++) {
for (colCtr=0;colCtr<camera.cols;colCtr++) {
tileNum=(world.map[rowCtr+tiley][colCtr+tilex]);
var tilePoint={};
tilePoint.x=colCtr*world.tileWidth;
tilePoint.y=rowCtr*world.tileHeight;
var source={};
source.x=Math.floor(tileNum % 5) * world.tileWidth;
source.y=Math.floor(tileNum /5) *world.tileHeight;
context.drawImage(tileSheet, source.x, source.y,world.tileWidth,
world.tileHeight,tilePoint.x,tilePoint.y,
world.tileWidth,world.tileHeight);
}
}
}
world.map=[
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
,[0,1,2,1,1,1,1,1,1,1,1,1,1,1,0]
,[0,1,0,1,0,0,1,0,1,0,0,1,0,1,0]
,[0,1,0,1,0,0,1,0,1,0,0,1,0,1,0]
,[0,1,0,1,0,0,1,1,1,0,0,1,0,1,0]
,[0,2,1,1,1,1,0,0,0,1,1,1,1,1,0]
,[0,1,0,0,0,1,0,0,0,1,0,0,0,1,0]
,[0,1,1,1,2,1,0,0,0,1,1,1,1,1,0]
,[0,0,0,0,0,1,1,1,1,1,0,0,0,0,0]
,[0,1,1,1,1,1,0,0,0,1,1,1,1,1,0]
,[0,1,0,1,0,0,1,1,1,0,0,1,0,1,0]
,[0,1,0,1,0,0,2,0,0,0,0,1,0,1,0]
,[0,1,0,1,0,0,1,0,1,0,0,1,0,1,0]
,[0,1,1,1,1,1,1,2,1,1,1,1,1,1,0]
,[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
];
init();
var FRAME_RATE=10;
var intervalTime=1000/FRAME_RATE;
function gameLoop() {
runGame();
window.setTimeout(gameLoop, intervalTime);
}
}
</script>
</head>
<body>
<div style="position: absolute; top: 50px; left: 50px;">
<canvas id="canvas" width="160" height="160">
Your browser does not support the HTML5 Canvas.
</canvas>
</div>
</body>
</html>
在浏览器运行这个示例时,可以使用方向键在游戏世界中滚动160×160的镜头。每一次按钮都会将窗口在该方向上移动32个像素。现在来看一下精确滚动的完整代码。