
TypeScript實戰 – 貪吃蛇(1)
目的
使用typescript以及面向物件的方式撰寫簡易版貪吃蛇的專案,實作:蛇自主移動,吃到食物檢測并增加身體長度,食物隨機生成,計分板,撞墻檢測,鍵盤事件檢測等基本功能,
界面


分析
總體來說,整個游戲中所含的類可以分為四個:蛇(Snake),食物(Food),計分板(Scoreboard),游戲控制器(GameController),
- Snake:獲取與設定蛇身體部分的位置,增加長度,處理撞墻,檢測是否吃到自己,禁止掉頭
- Food:獲取與設定食物位置,隨機改變位置
- Scoreboard:獲取積分和等級,增加積分,增加等級
- GameController:控制游戲開始和結束,吃到食物檢測,蛇移動,呼叫其他各物件的方法完成游戲的邏輯,
還需要一個HTML作為界面展示,具體typescript簡單專案搭建,webpack配置可以看我另外一個文章講了如何從0開始搭建簡單的webpack編譯ts的專案
HTML整體結構與樣式不多贅述
注意的地方就是:因為每次吃到食物后,增加一段,增加的是蛇容器里面的子元素,所以我們對于蛇的樣式需要加在蛇的子元素上,而蛇容器不必加樣式和定位
HTML:
<html>
<head>
<title>貪吃蛇</title>
</head>
<body>
<div class="snake_postion">
<div class="snake_body">
<div class="snake_body_screen">
<!-- 設定蛇 -->
<div class="snake">
<div></div>
</div>
<!-- 設定食物 -->
<div class="food"></div>
</div>
<div class="snake_body_score_level">
<div class="snake_body_item">level:
<span class="level">0</span>
</div>
<div class="snake_body_item">grade:
<span class="score">0</span>
</div>
</div>
</div>
</div>
</body>
</html>
CSS(將主要用到的列了出來):
/* 定位總游戲盒子 */
.snake_postion{
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
/* 游戲盒子 */
.snake_body{
width: 324px;
height: 400px;
background: #1e272e;
border-radius: 10px;
box-sizing: border-box;
display: flex;
flex-direction: column;
overflow: hidden;
padding: 10px;
box-shadow: 0 0 15px #1e272e;
}
/* 螢屏 */
.snake_body_screen{
background: #485460;
height: 304px;
box-sizing: border-box;
border-radius: 6px;
border: 2px solid #808e9b;
position: relative;
}
/* 記分板 */
.snake_body_score_level{
border-radius: 6px;
text-align: center;
font-size: 20px;
color: #fff;
line-height: 50px;
display: flex;
}
/* 記分板各項 */
.snake_body_item{
width: 50%;
font-size: 14px;
text-shadow: 0 0 10px #222f3e;
}
/* 蛇身體 */
.snake > div{
width: 10px;
height: 10px;
background: #222f3e;
border: 1px solid #808e9b;
position: absolute;
border-radius: 2px;
}
/* 蛇頭 */
.snake > div:nth-child(1){
width: 10px;
height: 10px;
background: #3c6382;
border: 1px solid #808e9b;
position: absolute;
border-radius: 2px;
left: 20px;
top: 20px;
}
/* 食物 */
.food{
width: 10px;
height: 10px;
background: #222f3e;
border: 1px solid #808e9b;
position: absolute;
left: 120px;
top: 100px;
border-radius: 2px;
}
各類的具體分析與實作
我們最好將各類分成各個模塊,這樣好維護,
因為從分析來看,食物類和計分板類是最簡單的兩個類,所以先將它們實作
Food類
食物類包含了獲取和設定食物位置,隨機改變食物位置
-
實作步驟
- 定義存放食物元素的變數
- 使用
document.querySelector獲取食物元素 - 使用
offsetTop和offsetLeft獲取食物的位置get和set設定食物的位置 - 因為我們螢屏的有效長寬是290px,每次移動10px,所以我們只需要取0-29的亂數,最后再乘以10就行了,使用
Math.random和Math.round實作隨機取數 - 賦值給食物元素的樣式
-
具體代碼
// 定義食物類 class Food{ // 定義存盤元素的變數 private element: HTMLElement; constructor() { // 拿到元素 this.element = document.querySelector(".food")!; } get X() { // 得到left值 return this.element.offsetLeft; } get Y() { // 得到top值 return this.element.offsetTop; } // 吃到一個事物改變位置 change() { // 這里left和top需要分別拿,不然就只能走對角線了 let left = Math.round(Math.random() * 29) * 10; let top = Math.round(Math.random() * 29) * 10; // 賦值給food實作隨機改變位置 this.element.style.left = left + 'px'; this.element.style.top = top + 'px'; } } export default Food;測驗代碼
專案入口檔案
index.ts增加如下測驗代碼import Food from './modules/Food'; const testFood = new Food(); testFood.change();然后重繪多次頁面查看食物隨機改變的效果

Scoreboard類
包含了獲取積分和等級,增加積分,增加等級的功能
-
實作步驟
- 我們需要定義四個變數,存放等級
level和積分score,等級顯示元素和積分顯示元素 - 如果還想自定義升級的規則和最大等級可以定義兩個變數去控制
- 升級和積分增加都是先將現在的
level和score自增后往各自的元素的innerHTML添加即可
- 我們需要定義四個變數,存放等級
-
具體代碼
// 定義記分牌 class LevelScore{ // 等級 private level: number = 1; // 積分 private score: number = 0; // 控制升級規則(每吃多少個升一級) private levelItem: number; // 最大等級 private maxLevel: number; // 顯示等級的元素 private levelElement: HTMLElement; // 顯示積分的元素 private scoreElement: HTMLElement; // 給出初始值定義初始規則:吃10個食物升一級,最高等級10及 constructor(leveItem: number = 10, maxLevel: number = 10) { this.levelItem = leveItem; this.maxLevel = maxLevel; this.levelElement = document.querySelector(".level")!; this.scoreElement = document.querySelector(".score")!; } // 增加積分 addScore() { this.scoreElement.innerHTML = ++this.score + ''; // 如果當前的積分和升級規則規定的個數取余為0,說明達到規定個數升級 if (this.score % this.levelItem === 0) { this.levelUp(); } } levelUp() { if (this.level < this.maxLevel) { this.levelElement.innerHTML = ++this.level + ''; } } getlevel() { return this.level; } getScore() { return this.score; } } export default LevelScore;
測驗代碼
專案入口檔案index.ts增加如下測驗代碼
import LevelScore from './modules/LevelScore'
const testLevelScore = new LevelScore();
setInterval(()=>{
testLevelScore.addScore();
},1000)
查看頁面對于我們增加分數和增加等級規則的測驗

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/278946.html
標籤:其他
