react實現貪喫蛇小遊戲

之前看別人寫小遊戲覺得很厲害,正好最近閒來無聊,就寫了個入門級的小遊戲,貪喫蛇。

當你開始實現的時候,會發現其實並沒有你想的那麼難。下面進入正題。

項目源碼見:https://github.com/Eveveen/react-snake

1. 首先畫出背景

2. 然後初始化初始蛇的位置,蛇爲黑色,食物爲紅色

renderBackground() {  // 其中 size = {row: 20, col: 20}
    let trs = [];
    for (let i = 0; i < size.row; i++) {
        let tds = [];
        for (let j = 0; j < size.col; j++) {
            let value = this.getSnack(i, j);
            if (value === 0) {  // 空白
                // 這裏的key只是爲了使這個td唯一
                tds.push(<td key={i * 200 + j}></td>); 
            } else if (value === 1) { // 有蛇,黑色
                tds.push(<td key={i * 100 + j}>{black}</td>)
            } else if (value === 2) { // 食物,紅色
                tds.push(<td key={i * 5 + j}>{red}</td>)
            }
        }
        trs.push(<tr key={i}>{tds}</tr>)
    }
    return <tbody>{trs}</tbody>;
}

// 獲取在方塊中蛇以及食物的顯示
getSnack = (c, r) => {
	const { snake, food } = this.state;
	for (let s in snake) {
		// 如果這個點是蛇,則返回1
		if (snake[s].x === c && snake[s].y === r) {
			return 1;
		}
		// 如果這個點是食物,則返回2
		if (food.x === c && food.y === r) {
			return 2;
		}
	}
	// 如果這個點什麼都不是返回0
	return 0;
}

 

3. 蛇可以定時移動

// 定時自己移動
timer = () => {
	let interval = setInterval(function () {
		this.move(this.state.dir);
	}.bind(this), 600);
	this.setState({ interval, status: 'start' })
}

4. 通過鍵盤控制蛇的移動

componentDidMount() {
    // 鍵盤點擊事件
	document.onkeydown = function (event) {
		var e = event || window.event;
		var keyCode = e.keyCode;
		if (keyCode === 37 || keyCode === 65) { // left a
			this.move(direction.left);
			this.setState({ dir: direction.left })
		} else if (keyCode === 38 || keyCode === 87) { // up w
			this.move(direction.up);
			this.setState({ dir: direction.up })
		} else if (keyCode === 39 || keyCode === 68) { //right d
			this.move(direction.right);
			this.setState({ dir: direction.right })
		} else if (keyCode === 40 || keyCode === 83) { // down s
			this.move(direction.down);
			this.setState({ dir: direction.down })
		}
	}.bind(this);
        // 初次渲染的時候開啓定時
	this.timer();
}

5. 蛇喫完食物變長,繼續行走,蛇頭撞到自己失敗,重新開始

6. 蛇的每個部分統一行走,轉換方向時,後一個按照前一個的軌跡進行行走

7. 超過邊界時,重新開始

move = (dir) => {
	const { snake, food } = this.state;
	let first = { x: snake[0].x, y: snake[0].y }
	let last = {};
	// move
	if (dir === direction.up) {
		first.x -= 1;
	} else if (dir === direction.down) {
		first.x += 1;
	} else if (dir === direction.left) {
		first.y -= 1;
	} else if (dir === direction.right) {
		first.y += 1;
	}

	// 撞到自己
	let _snake = snake.filter(item => item.x === first.x && item.y === first.y)
	if (first.y > size.col - 1 || first.y < 0 || first.x < 0 || first.x > size.row - 1 || _snake.length > 0) {
		this.handleRestart();
		return;
	}

	let eat = false;
	// 喫到食物
	if (first.x === food.x && first.y === food.y) {
		eat = true;
		last = { x: snake[snake.length - 1].x, y: snake[snake.length - 1].y }
		this.showFood();
	}

	// 蛇整體動起來
	for (let s in snake) {
		var next_first = { x: snake[s].x, y: snake[s].y };
		snake[s].x = first.x;
		snake[s].y = first.y;
		first = next_first;
	}
	// 喫到食物之後蛇變長
	if (eat) {
		snake[snake.length] = last
	}

	this.setState({ snake })
}

8. 暫停,遊戲暫停,蛇不動

// 暫停
pause = () => {
	let i = this.state.interval;
	window.clearInterval(i); //清除定時器
	this.setState({ status: 'pause' })
}

9. 開始,蛇繼續行走

// 開始
handleStart = () => {
	const { status } = this.state;
	if (status === 'pause') {
		this.timer();  // 重新開啓定時器
	}
}

10. 計分,每喫一個食物,則加一分

// 顯示新的食物
showFood = () => {
	let x = parseInt(Math.random() * size.row);
	let y = parseInt(Math.random() * size.col);
	if (this.getSnack() !== 0) {
		x = parseInt(Math.random() * size.row);
		y = parseInt(Math.random() * size.col);
	}
	//每次顯示新的食物意味着吃了上一個食物,加1分
	let score = this.state.score + 1; 
	this.setState({ food: { x: x, y: y }, score })
}

11. 重新開始,回到初始化狀態

// 重新開始
handleRestart = () => {
	let i = this.state.interval;
	window.clearInterval(i);
	this.setState({
		snake: [{ x: 1, y: 1 }],
		food: { x: 1, y: 4 },
		dir: direction.right,
		interval: 2,
		status: 'start',
		score: 0
	})
	this.timer()
}

12. 優化界面,對頁面佈局進行優化

 

好了,以上就是我的思路,源碼可以見我的git項目,地址在文章開頭

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章