使用TypeScript实现简单的HTML5贪吃蛇游戏

时间:2024-01-09 18:06:50

  TypeScript是一种由微软开发的*开源的编程语言。它是JavaScript的一个超集,而且本质上向这个语言添加了可选的静态类型和基于类的面向对象编程安德斯·海尔斯伯格C#的首席架构师,已工作于TypeScript的开发。2012年十月份,微软发布了首个公开版本的TypeScript,2013年6月19日,在经历了一个预览版之后微软正式发布了正式版TypeScript
0.9,向未来的TypeScript 1.0版迈进了很大一步。——摘自百度百科

  我个人感觉这个最大的优势就是建模比较方便了,因为它通过对JS的扩充实现了类、接口、枚举等(都是编译器在干活),感觉它把一些C#的语法加进去了,从而简化了大型JS应用程序的开发。

  对于使用VS2012/2013的开发者来说,需要下载一个插件才行,地址如下:http://www.microsoft.com/en-us/download/details.aspx?id=34790

  代码比较简单,直接上代码了,希望对typescript有兴趣的大牛给点建议吧。

下面是typescript源码,typescript源文件默认后缀为.ts,在HTML页面引用这个文件的时候需要使用后缀为.js,在请求该脚本文件时,编译器会把typescript代码编译为其等价的JavaScript代码,并保证其兼容性(官方说法,没有验证)。

 //方向类,方向数值和键盘方向键一致
enum Direction {
Up= 38,
Down= 40,
Right= 39,
Left= 37
} //贪吃蛇类
class Snake {
//当前运动方向
direction: Direction;
//蛇位置数组
body: number[] = [];
//在移动蛇
move() {
var i = 0;
for (; i < this.body.length - 1; i++) {
this.body[i] = this.body[i + 1];
}
//根据方向计算蛇头位置
var cubeNumber = new Game().cubeNumber;
var y = parseInt(this.body[i] / cubeNumber + "");
var x = this.body[i] - y * cubeNumber;
switch (this.direction) {
case Direction.Up:
this.body[i] = (y - 1) * cubeNumber + x;
break;
case Direction.Down:
this.body[i] = (y + 1) * cubeNumber + x;
break;
case Direction.Right:
this.body[i] = y * cubeNumber + x + 1;
break;
case Direction.Left:
this.body[i] = y * cubeNumber + x - 1;
break;
}
}
} class Game {
canvas: HTMLCanvasElement;
Width: number = 602;
Height: number = 602;
cubeWidth: number = 30;
cubeNumber: number = 20;
wallNum: number = -1;
comNum: number = 0;
snakeNum: number = 1;
frogNum:number = 2;
boardArray: number[] = [];
snake: Snake;
wallColor: string = "#cccccc";
snakeColor: string = "#000000";
comColor: string = "#ffffff";
frogColor: string = "#00cc33"; snakeMoveInterval: number;
frogInterval: number;
moveInterval:number = 1000; //初始化贪吃蛇界面(本贪吃蛇比较简单,只有一个canvas)
initialUI() {
//创建canvas并设置格式
this.canvas = document.createElement("canvas");
this.canvas.height = this.Height;
this.canvas.width = this.Width;
this.canvas.style.margin = "30px auto auto auto";
//this.canvas.style.border = "1px solid red";
document.body.style.margin = "0px";
document.body.style.textAlign = "center";
document.body.appendChild(this.canvas);
}
//在(x,y)坐标处绘制一块墙
drawWall(x: number, y: number) {
var ctx = this.canvas.getContext("2d");
ctx.fillStyle = this.wallColor;
//alert("(x,y)=>(" + (this.cubeWidth * x) + "," + (this.cubeWidth * y) + ")");
//(x,y)各加0.5用来修正位置
ctx.fillRect(x * this.cubeWidth + 0.5, y * this.cubeWidth + 0.5, this.cubeWidth - 1, this.cubeWidth - 1);
} //初始化一条蛇(此处简化处理了)
initialSnake() {
this.snake = new Snake();
this.snake.direction = Direction.Right;
for (var i = 0; i < 4; i++) {
//从第二行开始位置设置一条向右运动的蛇
this.snake.body.push(this.cubeNumber + 1 + i);
}
} //绘制蛇
drawSnake() {
//遍历蛇身
var ctx = this.canvas.getContext("2d");
ctx.fillStyle = this.snakeColor;
for (var i = 0; i < this.snake.body.length; i++) {
//计算坐标
var y = parseInt(this.snake.body[i] / this.cubeNumber + "");
var x = this.snake.body[i] - y * this.cubeNumber;
ctx.fillRect(x * this.cubeWidth + 0.5, y * this.cubeWidth + 0.5, this.cubeWidth - 1, this.cubeWidth - 1);
}
} //清除蛇
eraseSnake() {
var ctx = this.canvas.getContext("2d");
ctx.fillStyle = this.comColor;
for (var i = 0; i < this.snake.body.length; i++) {
var y = parseInt(this.snake.body[i] / this.cubeNumber + "");
var x = this.snake.body[i] - y * this.cubeNumber;
ctx.fillRect(x * this.cubeWidth + 0.5, y * this.cubeWidth + 0.5, this.cubeWidth - 1, this.cubeWidth - 1);
}
} //检查蛇的位置状态
checkSnake() { var head = this.snake.body[this.snake.body.length - 1];
//如果蛇头在墙上,则弹出蛇已经死亡的消息
if (this.boardArray[head] == this.wallNum) {
//停止蛇的移动
clearInterval(this.snakeMoveInterval);
alert("Your snake has gone !");
}
//如果蛇头位置在蛇身上
for (var i = 0; i < this.snake.body.length - 2; i++) {
if (this.snake.body[i] == head) {
//停止蛇的移动
clearInterval(this.snakeMoveInterval);
alert("Your snake has gone !");
}
} //如果设的下一个位置是青蛙,则吃掉青蛙
//计算当前位置
var y = parseInt("" + head / this.cubeNumber);
var x = head - y * this.cubeNumber;
var next = 0;
//计算下一个位置
switch (this.snake.direction) {
case Direction.Up:
next = head - this.cubeNumber;
break;
case Direction.Down:
next = head + this.cubeNumber;
break;
case Direction.Right:
next = head +1;
break;
case Direction.Left:
next = head - 1;
break;
}
//如果是青蛙,吃掉青蛙
if (this.boardArray[next] == this.frogNum) {
this.boardArray[next] = this.comNum;
this.snake.body.push(next);
this.setFrog();
}
}
//绘制面板
drawBoard() {
var ctx = this.canvas.getContext("2d");
//画横线
ctx.beginPath();
ctx.translate(0.5, 0.5);
for (var y = 0; y <= this.cubeNumber; y++) {
ctx.moveTo(0, y * this.cubeWidth);
ctx.lineTo(this.cubeNumber * this.cubeWidth, y * this.cubeWidth);
}
//画竖线
for (var x = 0; x <= this.cubeNumber; x++) {
ctx.moveTo(x * this.cubeWidth, 0);
ctx.lineTo(x * this.cubeWidth, this.cubeNumber * this.cubeWidth);
}
ctx.stroke(); //数学化面板,以行序存储
for (var y = 0; y < this.cubeNumber; y++) {
for (var x = 0; x < this.cubeNumber; x++) {
//如果是四周,则设置值为墙的值
if (x == 0 || y == 0 || x == this.cubeNumber - 1 || y == this.cubeNumber - 1) {
this.boardArray.push(this.wallNum);
} else {
this.boardArray.push(this.comNum);
}
}
} //遍历boardArray绘制其中表示墙的区域
for (var i = 0; i < this.boardArray.length; i++) {
if (this.boardArray[i] == this.wallNum) {
var y = parseInt(i / this.cubeNumber + "");
var x = i - y * this.cubeNumber;
this.drawWall(x, y);
}
} }
//随机设置一个位置为青蛙(保证青蛙不在墙上或蛇身上)
getRandomFrog() {
var position = parseInt(""+ Math.random() * this.boardArray.length);
if (this.boardArray[position] == this.wallNum) {
//递归
return this.getRandomFrog();
}
//检查是否在蛇身上
if (this.snake.body.indexOf(position) > -1) {
return this.getRandomFrog();
}
return position;
} //绘制青蛙
drawFrog(position) {
//计算x,y
var y = parseInt(position / this.cubeNumber + "");
var x = position - y * this.cubeNumber;
var ctx = this.canvas.getContext("2d");
ctx.fillStyle = this.frogColor;
ctx.fillRect(x * this.cubeWidth+0.5, y * this.cubeWidth+0.5, this.cubeWidth - 1, this.cubeWidth - 1);
} //声称青蛙
setFrog() {
var position = this.getRandomFrog();
//设置该区域为青蛙
this.boardArray[position] = this.frogNum;
//绘制青蛙
this.drawFrog(position);
}
//绑定键盘事件
bindKeyBoard() {
window.onkeydown = (e) => {
//如果和当前方向相反,无操作
if (e.keyCode+2!=this.snake.direction&&e.keyCode-2!=this.snake.direction) {
//如果和当前方向相同
if (e.keyCode == this.snake.direction) {
if (this.moveInterval - 200 >= 200) {
this.moveInterval -= 200;
clearInterval(this.snakeMoveInterval);
this.setSnakeMoveInterval();
}
} else {
if (this.moveInterval + 200 <= 1000) {
this.moveInterval += 200;
clearInterval(this.snakeMoveInterval);
this.setSnakeMoveInterval();
}
}
this.snake.direction = e.keyCode;
//检查蛇状态,吃掉青蛙
this.checkSnake();
this.drawSnake();
}
};
} //移动蛇
moveSnake() {
this.eraseSnake();
this.moveSnake();
this.checkSnake();
this.drawSnake();
} //设置贪吃蛇循环运动
setSnakeMoveInterval() {
clearInterval(this.snakeMoveInterval);
this.snakeMoveInterval = setInterval(() => {
this.eraseSnake();
this.snake.move();
this.checkSnake();
this.drawSnake();
},this.moveInterval);
} //开始游戏
start() {
this.initialUI();
this.drawBoard();
this.initialSnake();
this.drawSnake();
this.bindKeyBoard();
this.setSnakeMoveInterval();
this.setFrog();
}
} //window加载时启动游戏
window.onload = () => {
var game = new Game();
game.start();
}

  下面是其编译后的JavaScript代码。

 //方向类,方向数值和键盘方向键一致
var Direction;
(function (Direction) {
Direction[Direction["Up"] = 38] = "Up";
Direction[Direction["Down"] = 40] = "Down";
Direction[Direction["Right"] = 39] = "Right";
Direction[Direction["Left"] = 37] = "Left";
})(Direction || (Direction = {})); //贪吃蛇类
var Snake = (function () {
function Snake() {
//蛇位置数组
this.body = [];
}
//在移动蛇
Snake.prototype.move = function () {
var i = 0;
for (; i < this.body.length - 1; i++) {
this.body[i] = this.body[i + 1];
} //根据方向计算蛇头位置
var cubeNumber = new Game().cubeNumber;
var y = parseInt(this.body[i] / cubeNumber + "");
var x = this.body[i] - y * cubeNumber;
switch (this.direction) {
case 38 /* Up */:
this.body[i] = (y - 1) * cubeNumber + x;
break;
case 40 /* Down */:
this.body[i] = (y + 1) * cubeNumber + x;
break;
case 39 /* Right */:
this.body[i] = y * cubeNumber + x + 1;
break;
case 37 /* Left */:
this.body[i] = y * cubeNumber + x - 1;
break;
}
};
return Snake;
})(); var Game = (function () {
function Game() {
this.Width = 602;
this.Height = 602;
this.cubeWidth = 30;
this.cubeNumber = 20;
this.wallNum = -1;
this.comNum = 0;
this.snakeNum = 1;
this.frogNum = 2;
this.boardArray = [];
this.wallColor = "#cccccc";
this.snakeColor = "#000000";
this.comColor = "#ffffff";
this.frogColor = "#00cc33";
this.moveInterval = 1000;
}
//初始化贪吃蛇界面(本贪吃蛇比较简单,只有一个canvas)
Game.prototype.initialUI = function () {
//创建canvas并设置格式
this.canvas = document.createElement("canvas");
this.canvas.height = this.Height;
this.canvas.width = this.Width;
this.canvas.style.margin = "30px auto auto auto"; //this.canvas.style.border = "1px solid red";
document.body.style.margin = "0px";
document.body.style.textAlign = "center";
document.body.appendChild(this.canvas);
}; //在(x,y)坐标处绘制一块墙
Game.prototype.drawWall = function (x, y) {
var ctx = this.canvas.getContext("2d");
ctx.fillStyle = this.wallColor; //alert("(x,y)=>(" + (this.cubeWidth * x) + "," + (this.cubeWidth * y) + ")");
//(x,y)各加0.5用来修正位置
ctx.fillRect(x * this.cubeWidth + 0.5, y * this.cubeWidth + 0.5, this.cubeWidth - 1, this.cubeWidth - 1);
}; //初始化一条蛇(此处简化处理了)
Game.prototype.initialSnake = function () {
this.snake = new Snake();
this.snake.direction = 39 /* Right */;
for (var i = 0; i < 4; i++) {
//从第二行开始位置设置一条向右运动的蛇
this.snake.body.push(this.cubeNumber + 1 + i);
}
}; //绘制蛇
Game.prototype.drawSnake = function () {
//遍历蛇身
var ctx = this.canvas.getContext("2d");
ctx.fillStyle = this.snakeColor;
for (var i = 0; i < this.snake.body.length; i++) {
//计算坐标
var y = parseInt(this.snake.body[i] / this.cubeNumber + "");
var x = this.snake.body[i] - y * this.cubeNumber;
ctx.fillRect(x * this.cubeWidth + 0.5, y * this.cubeWidth + 0.5, this.cubeWidth - 1, this.cubeWidth - 1);
}
}; //清除蛇
Game.prototype.eraseSnake = function () {
var ctx = this.canvas.getContext("2d");
ctx.fillStyle = this.comColor;
for (var i = 0; i < this.snake.body.length; i++) {
var y = parseInt(this.snake.body[i] / this.cubeNumber + "");
var x = this.snake.body[i] - y * this.cubeNumber;
ctx.fillRect(x * this.cubeWidth + 0.5, y * this.cubeWidth + 0.5, this.cubeWidth - 1, this.cubeWidth - 1);
}
}; //检查蛇的位置状态
Game.prototype.checkSnake = function () {
var head = this.snake.body[this.snake.body.length - 1]; //如果蛇头在墙上,则弹出蛇已经死亡的消息
if (this.boardArray[head] == this.wallNum) {
//停止蛇的移动
clearInterval(this.snakeMoveInterval);
alert("Your snake has gone !");
} for (var i = 0; i < this.snake.body.length - 2; i++) {
if (this.snake.body[i] == head) {
//停止蛇的移动
clearInterval(this.snakeMoveInterval);
alert("Your snake has gone !");
}
} //如果设的下一个位置是青蛙,则吃掉青蛙
//计算当前位置
var y = parseInt("" + head / this.cubeNumber);
var x = head - y * this.cubeNumber;
var next = 0; switch (this.snake.direction) {
case 38 /* Up */:
next = head - this.cubeNumber;
break;
case 40 /* Down */:
next = head + this.cubeNumber;
break;
case 39 /* Right */:
next = head + 1;
break;
case 37 /* Left */:
next = head - 1;
break;
} //如果是青蛙,吃掉青蛙
if (this.boardArray[next] == this.frogNum) {
this.boardArray[next] = this.comNum;
this.snake.body.push(next);
this.setFrog();
}
}; //绘制面板
Game.prototype.drawBoard = function () {
var ctx = this.canvas.getContext("2d"); //画横线
ctx.beginPath();
ctx.translate(0.5, 0.5);
for (var y = 0; y <= this.cubeNumber; y++) {
ctx.moveTo(0, y * this.cubeWidth);
ctx.lineTo(this.cubeNumber * this.cubeWidth, y * this.cubeWidth);
} for (var x = 0; x <= this.cubeNumber; x++) {
ctx.moveTo(x * this.cubeWidth, 0);
ctx.lineTo(x * this.cubeWidth, this.cubeNumber * this.cubeWidth);
}
ctx.stroke(); for (var y = 0; y < this.cubeNumber; y++) {
for (var x = 0; x < this.cubeNumber; x++) {
//如果是四周,则设置值为墙的值
if (x == 0 || y == 0 || x == this.cubeNumber - 1 || y == this.cubeNumber - 1) {
this.boardArray.push(this.wallNum);
} else {
this.boardArray.push(this.comNum);
}
}
} for (var i = 0; i < this.boardArray.length; i++) {
if (this.boardArray[i] == this.wallNum) {
var y = parseInt(i / this.cubeNumber + "");
var x = i - y * this.cubeNumber;
this.drawWall(x, y);
}
}
}; //随机设置一个位置为青蛙(保证青蛙不在墙上或蛇身上)
Game.prototype.getRandomFrog = function () {
var position = parseInt("" + Math.random() * this.boardArray.length);
if (this.boardArray[position] == this.wallNum) {
//递归
return this.getRandomFrog();
} //检查是否在蛇身上
if (this.snake.body.indexOf(position) > -1) {
return this.getRandomFrog();
}
return position;
}; //绘制青蛙
Game.prototype.drawFrog = function (position) {
//计算x,y
var y = parseInt(position / this.cubeNumber + "");
var x = position - y * this.cubeNumber;
var ctx = this.canvas.getContext("2d");
ctx.fillStyle = this.frogColor;
ctx.fillRect(x * this.cubeWidth + 0.5, y * this.cubeWidth + 0.5, this.cubeWidth - 1, this.cubeWidth - 1);
}; //声称青蛙
Game.prototype.setFrog = function () {
var position = this.getRandomFrog(); //设置该区域为青蛙
this.boardArray[position] = this.frogNum; //绘制青蛙
this.drawFrog(position);
}; //绑定键盘事件
Game.prototype.bindKeyBoard = function () {
var _this = this;
window.onkeydown = function (e) {
//如果和当前方向相反,无操作
if (e.keyCode + 2 != _this.snake.direction && e.keyCode - 2 != _this.snake.direction) {
//如果和当前方向相同
if (e.keyCode == _this.snake.direction) {
if (_this.moveInterval - 200 >= 200) {
_this.moveInterval -= 200;
clearInterval(_this.snakeMoveInterval);
_this.setSnakeMoveInterval();
}
} else {
if (_this.moveInterval + 200 <= 1000) {
_this.moveInterval += 200;
clearInterval(_this.snakeMoveInterval);
_this.setSnakeMoveInterval();
}
}
_this.snake.direction = e.keyCode; //检查蛇状态,吃掉青蛙
_this.checkSnake();
_this.drawSnake();
}
};
}; //移动蛇
Game.prototype.moveSnake = function () {
this.eraseSnake();
this.moveSnake();
this.checkSnake();
this.drawSnake();
}; //设置贪吃蛇循环运动
Game.prototype.setSnakeMoveInterval = function () {
var _this = this;
clearInterval(this.snakeMoveInterval);
this.snakeMoveInterval = setInterval(function () {
_this.eraseSnake();
_this.snake.move();
_this.checkSnake();
_this.drawSnake();
}, this.moveInterval);
}; //开始游戏
Game.prototype.start = function () {
this.initialUI();
this.drawBoard();
this.initialSnake();
this.drawSnake();
this.bindKeyBoard();
this.setSnakeMoveInterval();
this.setFrog();
};
return Game;
})(); //window加载时启动游戏
window.onload = function () {
var game = new Game();
game.start();
};

  

  效果图:

使用TypeScript实现简单的HTML5贪吃蛇游戏