UDN-企业互联网技术人气社区

板块导航

浏览  : 1449
回复  : 15

[原生js] typescript 写一个 贪吃蛇

[复制链接]
Reborn的头像 楼主
发表于 2018-6-19 18:03:07 | 显示全部楼层 |阅读模式
开始接触到ts ,上手实践了一下 感觉非常爽  第一次写代码有很舒服的感觉。 试着用ts 来写个贪吃蛇小游戏。
1、定义元素坐标 和 元素属性接口
  1. interface pos {
  2.     x: number;
  3.     y: number;
  4. }

  5. interface attr {
  6.     x: number;
  7.     y: number;
  8.     width: number;
  9.     height: number;
  10.     color?: string;
  11.     speedX?: number;
  12.     speedY?: number
  13. }
复制代码

2、创建canvas画
  1. const canv = document.createElement('canvas');
  2. canv.width = 400;
  3. canv.height = 400;
  4. const ctx = canv.getContext('2d');
  5. const app = document.getElementById('app');

  6. app.appendChild(canv);
复制代码

3、游戏元素类
  1. class Square {
  2.     constructor(obj: attr) {
  3.         this.x = obj.x;
  4.         this.y = obj.y;
  5.         this.width = obj.width;
  6.         this.height = obj.height;
  7.         this.color = obj.color || 'white';
  8.         this.speedX = obj.speedX || 0;
  9.         this.speedY = obj.speedY || 0
  10.     }

  11.     x: number;
  12.     y: number;
  13.     width: number;
  14.     height: number;
  15.     color ?: string;
  16.     speedX ?: number;
  17.     speedY ?: number;

  18.     update(game ?: Game) {

  19.     }

  20.     render(game ?: Game) {
  21.         let {x, y, width, height, color} = this;
  22.         ctx.fillStyle = color;
  23.         let pos = game ? game.gs : 0;
  24.         ctx.fillRect(x * pos, y * pos, width, height)
  25.     }

  26.     setPos(x: number, y: number) {
  27.         this.x = x;
  28.         this.y = y
  29.     }

  30.     setSpeed(x ?: number, y ?: number) {
  31.         this.speedX = x;
  32.         this.speedY = y;
  33.     }
  34. }
复制代码


4、游戏背景
  1. class Background extends Square {
  2.     constructor(obj: attr) {
  3.         super(obj)
  4.     }
  5. }
复制代码


5、苹果
  1. class Apple extends Square {
  2.     constructor(obj: attr) {
  3.         super(obj)
  4.     }

  5.     update(game ?: Game) {

  6.         let snake = game.snake;

  7.         if (this.x === snake.x && this.y === snake.y) {
  8.             snake.tail++;
  9.             this.setPos(Math.floor(Math.random() * 20), Math.floor(Math.random() * 20));
  10.             let score = game.score + 1;
  11.             game.setScore(score);
  12.         }
  13.     }
  14. }
复制代码


6、贪吃蛇
  1. class Snake extends Square {
  2.     constructor(obj: attr) {
  3.         super(obj);
  4.         this.tails = [];
  5.         this.tail = 5
  6.     }

  7.     tails: pos[];
  8.     tail: number;

  9.     update(game) {
  10.         let ts = game.tc - 1;
  11.         this.x += this.speedX;
  12.         this.y += this.speedY;

  13.         if (this.x < 0) {
  14.             this.setPos(ts, this.y)
  15.         }
  16.         if (this.x > ts) {
  17.             this.setPos(0, this.y)
  18.         }
  19.         if (this.y < 0) {
  20.             this.setPos(this.x, ts)
  21.         }
  22.         if (this.y > ts) {
  23.             this.setPos(this.x, 0)
  24.         }

  25.         while (this.tails.length > this.tail) {
  26.             this.tails.shift()
  27.         }
  28.     }

  29.     render(game) {
  30.         let {width, height, color} = this;

  31.         ctx.fillStyle = color;

  32.         let pos = game.gs || 0;

  33.         this.tails.forEach(el => {
  34.             ctx.fillRect(el.x * pos, el.y * pos, width, height);
  35.             if (el.x === this.x && el.y === this.y) {
  36.                 this.tail = 5;
  37.                 game.score = 0
  38.             }
  39.         });

  40.         this.tails.push({x: this.x, y: this.y});

  41.     }
  42. }
复制代码


7、游戏主体
  1. class Game {
  2.     constructor(fps: number = 15) {
  3.         this.stop = false;
  4.         this.fps = fps;
  5.         this.gs = 20;
  6.         this.tc = 20;
  7.         this.score = 0;
  8.         this.bg = new Background({
  9.             x: 0,
  10.             y: 0,
  11.             width: canv.width,
  12.             height: canv.height,
  13.             color: 'black'
  14.         });
  15.         this.apple = new Apple({
  16.             x: 15,
  17.             y: 15,
  18.             width: this.tc - 2,
  19.             height: this.tc - 2,
  20.             color: 'red'
  21.         });
  22.         this.snake = new Snake({
  23.             x: 10,
  24.             y: 10,
  25.             width: this.tc - 2,
  26.             height: this.tc - 2,
  27.             color: 'lime'
  28.         });

  29.         document.addEventListener('keydown', this.keyPush.bind(this))
  30.     }

  31.     stop: boolean;
  32.     fps: number;
  33.     gs: number;
  34.     tc: number;
  35.     bg: Background;
  36.     apple: Apple;
  37.     snake: Snake;
  38.     score: number;

  39.     run() {
  40.         this.update();
  41.         this.clear();
  42.         this.draw();
  43.         setTimeout(() => {
  44.             this.run()
  45.         }, 1000 / this.fps)
  46.     }

  47.     update() {
  48.         if (this.stop) {
  49.             return
  50.         }
  51.         this.apple.update(this);
  52.         this.snake.update(this)
  53.     }

  54.     clear() {
  55.         ctx.clearRect(0, 0, canv.width, canv.height)
  56.     }

  57.     draw() {
  58.         this.bg.render();
  59.         this.apple.render(this);
  60.         this.snake.render(this);
  61.         this.renderScore()
  62.     }

  63.     setScore(score) {
  64.         this.score = score;
  65.     }

  66.     renderScore() {
  67.         ctx.font = "30px Georgia";
  68.         ctx.fillStyle = 'white';
  69.         ctx.fillText(this.score + '', 20, 30)
  70.     }

  71.     keyPush(e) {
  72.         const snake = this.snake;
  73.         switch (e.keyCode) {
  74.             case 37:
  75.                 if (snake.speedX <= 0) {
  76.                     snake.setSpeed(-1, 0)
  77.                 }
  78.                 break;
  79.             case 38:
  80.                 if (snake.speedY <= 0) {
  81.                     snake.setSpeed(0, -1)
  82.                 }
  83.                 break;
  84.             case 39:
  85.                 if (snake.speedX >= 0) {
  86.                     snake.setSpeed(1, 0)
  87.                 }
  88.                 break;
  89.             case 40:
  90.                 if (snake.speedY >= 0) {
  91.                     snake.setSpeed(0, 1)
  92.                 }
  93.                 break;
  94.             case 32:
  95.                 this.stop = !this.stop;
  96.                 break;
  97.         }
  98.     }
  99. }
复制代码


8、运行
  1. const game = new Game();
  2. game.run();
复制代码



有了类型检查 写起js来就很舒服。 之后继续要深入ts。

Ps: 发帖不支持markdown 有点小难受.

与君共勉~~

Reborn



发表于 2018-6-19 18:03:36 | 显示全部楼层
js框架越来越火了, 不过本人还是喜欢原生的好, 自己写类库, 自己来封装,用着方便。。。。
点评 ( 1 ) 收起 / 展开点评

Reborn 2018年06月19日 18:06 详情 回复

回帖真快

使用道具 举报

回复

发表于 2018-6-19 18:03:37 | 显示全部楼层
LZ是闲人,天天发帖,坚定完毕
点评 ( 1 ) 收起 / 展开点评

Reborn 2018年06月19日 18:04 详情 回复

就发了2个贴 好水啊你

使用道具 举报

回复

Reborn的头像 楼主
发表于 2018-6-19 18:04:52 | 显示全部楼层
孤傲残雪 发表于 2018-6-19 18:03
LZ是闲人,天天发帖,坚定完毕

就发了2个贴        好水啊你
使用道具 举报

回复

Reborn的头像 楼主
发表于 2018-6-19 18:06:09 | 显示全部楼层
卐殺絶1魛メ 发表于 2018-6-19 18:03
js框架越来越火了, 不过本人还是喜欢原生的好, 自己写类库, 自己来封装,用着方便。。。。 ...

回帖真快  
使用道具 举报

回复

发表于 2018-7-13 16:38:23 | 显示全部楼层
感谢楼主分享。。。楼主V5
点评 ( 1 ) 收起 / 展开点评

Reborn 2018年07月25日 10:38 详情 回复

感谢回复 感觉现在都没什么新贴了 凉凉的社区

使用道具 举报

回复

Reborn的头像 楼主
发表于 2018-7-25 10:38:56 | 显示全部楼层
bobby 发表于 2018-7-13 16:38
感谢楼主分享。。。楼主V5

感谢回复  
感觉现在都没什么新贴了   凉凉的社区
使用道具 举报

回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关于我们
联系我们
  • 电话:010-86393388
  • 邮件:udn@yonyou.com
  • 地址:北京市海淀区北清路68号
移动客户端下载
关注我们
  • 微信公众号:yonyouudn
  • 扫描右侧二维码关注我们
  • 专注企业互联网的技术社区
版权所有:用友网络科技股份有限公司82041 京ICP备05007539号-11 京公网网备安1101080209224 Powered by Discuz!
快速回复 返回列表 返回顶部