1. 程式人生 > >基於easyx的c++貪吃蛇

基於easyx的c++貪吃蛇

本程式碼來自於easyx討論群的分享

先上效果圖,其實也只是畫了簡單的圈圈代表蛇和食物,背景就是黑色的。

#include "stdafx.h"
#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
#include <graphics.h>

#define N 100

using namespace std;

enum moved { UP, DOWN, LEFT, RIGHT };
class Snake {
private:
	struct {      //整條蛇的資訊
		int x;
		int y;
	}snake[100];
	struct {
		int life;   //為1代表還活著,為0代表已經死了
		int length; //代表蛇的長度,初始值為3
		enum moved direction;   //前進方向
	}snake_head;
	struct {       //食物的資訊
		int x;
		int y;
	}food;
public:
	void display();    //顯示介面
	void initSnake(); //隨機生成蛇
	void move();//蛇移動
	void boundary_check();//邊界判斷
	void _food();//生成食物
	int food_eatcheck();//檢查是否吃到食物,吃到則返回1,否則返回0
	int snake_eat();//判斷貪吃蛇是否咬到自己,咬到則返回1,否則返回0
	void run();     //主要執行函式
};
void Snake::display() {
	initgraph(800, 600);
	setbkcolor(WHITE);   //設定背景顏色為白色
	cleardevice();       //將背景顏色重新整理到視窗上
	setfillcolor(BLACK); //設定填充的顏色為黑色,之後話填充的圖形都是這個顏色
	solidrectangle(20, 560, 560, 20);//這個區域每20*20為一個單位,一共有27*27個單位
}
//建構函式
void Snake::initSnake() {
	srand((unsigned)time(NULL));
	//因為一開始蛇是向右走的,所以不能讓蛇初始化在太靠右邊的地方
	int x = rand() % 22 + 3;  //範圍是3-24
	int y = rand() % 22 + 3;  //加三是因為初始的長度是3,必須讓整條蛇都在範圍內
	this->snake[0].x = x * 20 + 10;//加十是因為要確定圓心的位置
	this->snake[0].y = y * 20 + 10;
	//預設蛇一開始是橫著的所以三段的y座標相同
	this->snake[1].y = this->snake[2].y = this->snake[0].y;
	this->snake[1].x = this->snake[0].x - 20;
	this->snake[2].x = this->snake[0].x - 40;
	setfillcolor(GREEN);   //設定填充色為綠色
	solidcircle(this->snake[0].x, this->snake[0].y, 10); //畫圓
	solidcircle(this->snake[1].x, this->snake[1].y, 10);
	solidcircle(this->snake[2].x, this->snake[2].y, 10);
	this->snake_head.length = 3;
	this->snake_head.life = 1;
	this->snake_head.direction = RIGHT;
}
void Snake::move() {
	char ch;
	if (_kbhit()) {   //如果有輸入的話就返回1,沒有輸入的話就返回0
		ch = _getch();//獲取輸入的字元
		switch (ch) {
			case 'w' :if (this->snake_head.direction != DOWN) this->snake_head.direction = UP; break;
			case 'W':if (this->snake_head.direction != DOWN) this->snake_head.direction = UP; break;
			case 's' :if (this->snake_head.direction != UP) this->snake_head.direction = DOWN; break;
			case 'S':if (this->snake_head.direction != UP) this->snake_head.direction = DOWN; break;
			case 'a':if (this->snake_head.direction != RIGHT) this->snake_head.direction = LEFT; break;
			case 'A':if (this->snake_head.direction != RIGHT) this->snake_head.direction = LEFT; break;
			case 'd':if (this->snake_head.direction != LEFT) this->snake_head.direction = RIGHT; break;
			case 'D':if (this->snake_head.direction != LEFT) this->snake_head.direction = RIGHT; break;
			default:break;
		}
	}
	//將蛇尾變成黑色
	int i = this->snake_head.length - 1;
	setfillcolor(BLACK);
	solidcircle(snake[i].x, snake[i].y, 10);
	//接下來遍歷每個身體,每個身體都更新為前一個身體,蛇頭除外
	for (; i > 0; i--) {
		this->snake[i].x = this->snake[i - 1].x;
		this->snake[i].y = this->snake[i - 1].y;
	}
	switch (this->snake_head.direction) {
		case RIGHT:this->snake[0].x += 20; break;
		case LEFT:this->snake[0].x -= 20; break;
		case UP:this->snake[0].y -= 20; break;
		case DOWN:this->snake[0].y += 20; break;
		default:break;
	}
	setfillcolor(GREEN);
	solidcircle(this->snake[0].x, this->snake[0].y, 10);//繪製蛇頭
	Sleep(1000);
}
void Snake::boundary_check() {
	if (this->snake[0].x <= 30 || this->snake[0].x >= 550 || this->snake[0].y <= 30 || this->snake[0].y >= 550) {
		this->snake_head.life = 0; 
	}
}
void Snake::_food() {
	srand((unsigned)time(NULL));
	int x = rand() % 21 + 3;   //範圍是3-23
	int y = rand() % 21 + 3;
	this->food.x = x * 20 + 10;
	this->food.y = y * 20 + 10;
	setfillcolor(YELLOW);
	solidcircle(this->food.x, this->food.y, 10);
}
int Snake::food_eatcheck() {
	if (this->snake[0].x == this->food.x && this->snake[0].y == this->food.y) {
		//如果滿足條件就是吃到食物了
		this->snake_head.length++;//長度加一
		setfillcolor(GREEN);
		solidcircle(food.x, food.y, 10);
		int k = this->snake_head.length;
		//吃到食物之後最後要在尾巴處加一個長度
		switch (this->snake_head.direction) {
			case RIGHT:this->snake[k - 1].x = this->snake[k - 2].x - 20; this->snake[k - 1].y = this->snake[k - 2].y; break;
			case LEFT:this->snake[k - 1].x = this->snake[k - 2].x += 20; this->snake[k - 1].y = this->snake[k - 2].y; break;
			case UP:this->snake[k - 1].x = this->snake[k - 2].x; this->snake[k - 1].y = this->snake[k - 2].y + 20; break;
			case DOWN:this->snake[k - 1].x = this->snake[k - 2].x; this->snake[k - 1].y = this->snake[k - 2].y - 20; break;
			default:break;
		}
		setfillcolor(GREEN);
		solidcircle(this->snake[k - 1].x, this->snake[k - 1].y, 10);
		return 1;
	}
	return 0;
}
int Snake::snake_eat() {
	int i;
	for (i = 1; i < this->snake_head.length; i++) {
		if (this->snake[i].x == this->snake[0].x && this->snake[i].y == this->snake[0].y) {
			return 1;
		}
	}
	return 0;
}
void Snake::run() {
	display();  //顯示遊戲介面
	initSnake();
	_food();    //生成第一個食物
	while (true) {
		move();   //蛇移動
		if (snake_eat() == 1) {
			//自己吃到自己了,遊戲失敗
			cout << "自己吃到自己了,遊戲失敗" << endl;
			break;
		}
		boundary_check();//判斷是否撞牆
		if (this->snake_head.life == 0) {
			//撞牆了
			cout << "撞牆了,遊戲結束" << endl;
			break;
		}
		if (food_eatcheck() == 1) {
			_food();  //吃到食物就重新生成一個食物
		}
	}
}

int main() {
	Snake s;
	s.run();
	return 0;
}