使用TypeScript实现简单的HTML5贪吃蛇游戏
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贪吃蛇游戏的更多相关文章
- [置顶] 63行代码完美实现html5 贪吃蛇游戏
以前也很少关注html5,感觉选择html已经慢慢成为趋势,想了解下.就找了个游戏学习了,写完这个游戏感觉html5和js结合很紧密,如果js不是特别好.估计需要先补习下js,这个只是个人的建议,不一 ...
- 「JavaScript」手起刀落-一起来写经典的贪吃蛇游戏
回味 小时候玩的经典贪吃蛇游戏我们印象仍然深刻,谋划了几天,小时候喜欢玩的游戏,长大了终于有能力把他做出来(从来都没有通关过,不知道自己写的程序,是不是能通关了...),好了,闲话不多谈,先来看一下效 ...
- 一个简单的c# 贪吃蛇程序
一个简单的c#贪吃蛇程序 程序分为界面设计和程序设计:界面设计和程序设计均参考了一些游戏实例,但是所有代码内容是本人编写. 由于看到别人写的程序并没有署名,这里的署名全部都是csdn官网. 游戏界面设 ...
- WebGL实现HTML5贪吃蛇3D游戏
js1k.com收集了小于1k的javascript小例子,里面有很多很炫很酷的游戏和特效,今年规则又增加了新花样,传统的classic类型基础上又增加了WebGL类型,以及允许增加到2K的++类型, ...
- WebGL实现HTML5的3D贪吃蛇游戏
js1k.com收集了小于1k的javascript小例子,里面有很多很炫很酷的游戏和特效,今年规则又增加了新花样,传统的classic类型基础上又增加了WebGL类型,以及允许增加到2K的++类型, ...
- 100行JS实现HTML5的3D贪吃蛇游戏
js1k.com收集了小于1k的javascript小例子,里面有很多很炫很酷的游戏和特效,今年规则又增加了新花样,传统的classic类型基础上又增加了WebGL类型,以及允许增加到2K的++类型, ...
- 用OpenGL简单编写的一个最简单贪吃蛇游戏
刚学OpenGL的时候,写的一个最简单的贪吃蛇游戏代码 如下: //贪吃蛇游戏 #include<stdio.h> #include<stdlib.h> #include< ...
- H5实现的可自定义贪吃蛇游戏
原创游戏,使用lufylegend.js开发 用canvas实现的贪吃蛇游戏,与一般的贪吃蛇游戏不同,图片经过美工设计,代码设计支持扩展和自定义. 游戏元素丰富,包括障碍物(仙人掌),金币(奖励),苹 ...
- 关于用Java写的贪吃蛇游戏的一些感想
学习Java有那么一个月了,兴趣还是挺高的.然而最近老师布置的一个迷宫问题,着实让我头疼了一两个礼拜,以至于身心疲惫,困扰不安.无奈,暂且先放下这个迷宫问题,写个简单点的贪吃蛇程序,以此来提高低落的情 ...
随机推荐
- php平台移植windows和linux
2015/1/14 今天项目中遇到一个问题,在本地运行没有问题,挂到服务器上,就运行错误.过程中比较粗心,知道导致这样的原因,居然小时漏掉了一些细节. 比如,在php中通过声明__autoload() ...
- MySQL导出数据文件
SELECT * INTO OUTFILE '/root/a.txt' FIELDS TERMINATED BY '\t' LINES TERMINATED BY '\n' FROM t_log_in ...
- DJANGO的HTTPRESPONSE流式输出
在项目当中遇到的问题,网上有样例代码,但都不行,后来,发现在了1.5版本之后,新的STREAMHTTPRESPONSE对象, 搞定. from django.http import HttpRespo ...
- Codeforces 509F Progress Monitoring
http://codeforces.com/problemset/problem/509/F 题目大意:给出一个遍历树的程序的输出的遍历顺序b序列,问可能的树的形态有多少种. 思路:记忆化搜索 其中我 ...
- Keil C51编译及连接技术
主要介绍Keil C51的预处理方法如宏定义.常用的预处理指令及文件包含指令,C51编译库的选择及代码优化原理,C51与汇编混合编程的方法与实现以及超过64KB空间的地址分页方法的C51实现. 教学目 ...
- SQL Server 性能优化之——重复索引
原文 http://www.cnblogs.com/BoyceYang/archive/2013/06/16/3139006.html 阅读导航 1. 概述 2. 什么是重复索引 3. 查找重复索引 ...
- grep详解
一.简介 Global Regular Expression Print,是一种强大的文本搜索工具,能使用正则表达式. 二.语法 grep [OPTIONS] PATTERN [FILE...]gre ...
- mysql用户和权限管理
用户和权限管理 Information about account privileges is stored in the user, db, host, tables_priv, columns_p ...
- 【转】[总结]FFMPEG视音频编解码零基础学习方法
在CSDN上的这一段日子,接触到了很多同行业的人,尤其是使用FFMPEG进行视音频编解码的人,有的已经是有多年经验的“大神”,有的是刚开始学习的初学者.在和大家探讨的过程中,我忽然发现了一个问题:在“ ...
- Linux 块设备驱动 (二)
linux下Ramdisk驱动 1 什么是Ramdisk Ramdisk是一种模拟磁盘,其数据实际上是存储在RAM中,它使用一部分内存空间来模拟出一个磁盘设备,并以块设备的方式来组织和访问这片内存.对 ...