赞
踩
@bg-color:#b7d4a8;
margin: 0;
padding: 0;
box-sizing: border-box;
}
#main {
display: flex;
flex-flow: column;
align-items: center;
justify-content: space-around;
margin: 0 auto;
width: 360px;
height: 420px;
border: 10px solid #000;
background-color: @bg-color;
border-radius: 30px;
#stage{
position: relative;
width: 304px;
height: 304px;
border: 2px solid #000;
#snake{
&>div{
position: absolute;
width: 10px;
height: 10px;
background-color: #000;
border: 1px solid @bg-color;
}
}
&>#food{
display: flex;
flex-flow: row wrap;
justify-content: space-between;
align-content: space-between;
position: absolute;
top: 10px;
left: 10px;
width: 10px;
height: 10px;
&>div{
width: 4px;
height: 4px;
background: #000;
transform: rotate(45deg);
}
}
}
#score-panel{
width: 300px;
display: flex;
align-items: center;
justify-content: space-between;
}
}
body {
font:bold 20px “Courier”;
}
src/modules/Food.ts
class Food{
element:HTMLElement;
constructor(){
//this.element=document.getElementById(‘food’) as HTMLElement
this.element=document.getElementById(‘food’)!;
}
get X() {
return this.element.offsetLeft
}
get Y() {
return this.element.offsetTop
}
change() {
this.element.style.left=Math.ceil(Math.random()*29)*10+‘px’;
this.element.style.top=Math.ceil(Math.random()*29)*10+‘px’;
}
}
export default Food;
src/modules/ScorePanel.ts
class ScorePanel{
score:number=0;
level:number=1;
scoreEle:HTMLElement;
levelEle:HTMLElement;
maxLevel:number;
upScore:number;
constructor(maxLevel:number=10,upScore:number=10){
this.scoreEle= document.getElementById(‘score’)!;
this.levelEle= document.getElementById(‘level’)!;
this.maxLevel=maxLevel;
this.upScore = upScore;
}
addScore(){
this.score++;
this.scoreEle.innerHTML = this.score + ‘’;
if(this.score % this.upScore === 0){
this.levelUp();
}
}
levelUp(){
if(this.level<this.maxLevel){
this.levelEle.innerHTML = ++this.level + ‘’;
}
}
}
export default ScorePanel;
src/modules/Snake.ts
class Snake{
head:HTMLElement;
bodies:HTMLCollection;
element:HTMLElement;
constructor(){
this.element = document.getElementById(‘snake’)!;
this.head = document.querySelector(‘#snake>div’)!;
this.bodies=this.element.getElementsByTagName(‘div’)!;
}
public get X(){
return this.head.offsetLeft;
}
public get Y(){
return this.head.offsetTop;
}
set X(value:number){
if(this.X === value){
return;
}
if(value<0 || value>290){
throw new Error(‘蛇撞墙了!!’)
}
//是否掉头
if(this.bodies[1]&&(this.bodies[1] as HTMLElement).offsetLeft === value){
if(value>this.X){
//左走向右调头
value -= 20
}else{
value += 20
}
}
//移动身体
this.moveBody();
//移动蛇头
this.head.style.left = value + ‘px’;
this.checkHeadBody();
}
set Y(value:number){
if(this.Y === value){
return
}
if(value<0 || value>290){
throw new Error(‘蛇撞墙了!!’)
}
//是否掉头
if(this.bodies[1]&&(this.bodies[1] as HTMLElement).offsetTop === value){
if(value>this.Y){
//左走向右调头
value -= 20
}else{
value += 20
}
}
this.moveBody();
this.head.style.top = value + ‘px’;
this.checkHeadBody();
}
addBody(){
this.element.insertAdjacentElement(‘beforeend’,document.createElement(‘div’))
}
moveBody(){
//将后面身体的位置改为前面身体的位置,先改后面的位置,
//后面的位置依附前面的位置
for(let i = this.bodies.length-1;i>0;i–){
let X = (this.bodies[i-1] as HTMLElement).offsetLeft;
let Y = (this.bodies[i-1] as HTMLElement).offsetTop;
// 将值设置到当前身体上
(this.bodies[i] as HTMLElement).style.left = X + ‘px’;
(this.bodies[i] as HTMLElement).style.top = Y + ‘px’;
}
}
// 移动后检查
checkHeadBody(){
//获取所有身体坐标
for (let i = 1; i < this.bodies.length; i++) {
if(this.X === (this.bodies[i] as HTMLElement).offsetLeft &&this.Y === (this.bodies[i] as HTMLElement).offsetTop){
throw new Error(‘撞到自己了!’)
}
}
}
}
export default Snake
src/modules/GameControl.ts
import Food from “./Food”;
import ScorePanel from “./ScorePanel”;
import Snake from “./Snake”;
class GameControl{
snake:Snake;
food:Food;
scorePanel:ScorePanel;
//蛇的运动方向
direction:string=’ ';
//游戏是否结束
isLive = true;
constructor(){
this.snake = new Snake();
this.food = new Food();
this.scorePanel = new ScorePanel();
this.init();
this.run();
}
init(){
//绑定键盘事件
document.addEventListener(‘keydown’,this.keydownHandler.bind(this))
}
//键盘响应函数
//key:ArrowUp ArrowDown ArrowLeft ArrowRight
// IE: Up Down Left Right
keydownHandler(event:KeyboardEvent){
const keyhefa = [‘ArrowUp’,‘ArrowDown’,‘ArrowLeft’,‘ArrowRight’,‘Up’,‘Down’,‘Left’,‘Right’,’ ']
if (keyhefa.indexOf(event.key)>-1) {
this.direction = event.key;
}
}
//蛇移动的方法
run(){
//获取蛇现在的坐标
let X = this.snake.X;
let Y = this.snake.Y;
//修改位置变量
switch(this.direction){
case ‘ArrowUp’:
case ‘UP’:
Y -= 10;
break;
case ‘ArrowDown’:
case ‘Down’:
Y +=10;
break;
case ‘ArrowRight’:
case ‘Right’:
X += 10;
break;
case ‘ArrowLeft’:
case ‘Left’:
X -= 10;
break;
case ’ ':
break;
default:
break;
}
//检查移动后会不会吃到食物
this.eatHandler(X,Y)
//移动蛇头和身体
try{
this.snake.X = X;
this.snake.Y = Y;
}catch (e:any){
alert(e.message)
this.isLive = false;
}
this.isLive && setTimeout(this.run.bind(this), 300-(this.scorePanel.level-1)*30)
}
//检查蛇是否吃到食物
eatHandler(X:number,Y:number){
if(X === this.food.X && Y ===this.food.Y){
this.food.change();
this.scorePanel.addScore();
this.snake.addBody();
}
}
}
export default GameControl
src/index.ts
import ‘./style/index.less’
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。