html5实现贪吃蛇源代码
- 格式:docx
- 大小:14.16 KB
- 文档页数:7
贪吃蛇游戏源代码#include <stdio.h>#include <stdlib.h>#include <conio.h>#include <graphics.h>#include <bios.h>#include <dos.h>#include<string.h>#define LEFT_MARGIN 140#define FRAME_UNIT_WIDTH 25#define FRAME_UNIT_HEIGHT 15#define BOX_SIZE 15#define WINDOW_WIDTH 640#define WINDOW_HEIGHT 480#define SNAK_DEFAULT_POS_X 10#define SNAK_DEFAULT_POS_Y 5#define SMD_UP 1#define SMD_DOWN 2#define SMD_RIGHT 3#define SMD_LEFT 4#define UP_MOVE 72#define DOWN_MOVE 80#define LEFT_MOVE 75#define RIGHT_MOVE 77#define STEP_MOVE 7#define GAME_STOP 57#define ESC_OUT 1#define GENERAT_EGG 8#define NO_EVENT 0#define Boolean int#define TRUTH 1#define FALS 0#define Type_GAMESTATUS int#define ON_PAL YING 2#define WINNER 1#define GAMEOVER 0#define TIMEINTERV AL 6typedef struct{int p_X;int p_Y;}POS_in_Fram;typedef struct SNode{POS_in_Fram cur_pos;int color;struct SNode *next;}SNode, *LSNode;typedef struct{int direction;int len;POS_in_Fram Head_pre_pos; POS_in_Fram Head_cur_pos;int Head_color;LSNode next;Boolean Dead;}SNAK;typedef struct{POS_in_Fram egg_pos;int egg_color;}EggType;SNAK obj_snake;EggType obj_egg;int Message_Event;int ScoreTotal;int SpeedLevel;Type_GAMESTATUS GameStat;void set_Message_Event(int T){Message_Event = T;}int get_Message_Event(){return(Message_Event);}void clear_ScoreTotal(){ScoreTotal = 0;}int get_ScoreTotal(){return(ScoreTotal);}void draw_ScoreTotal(){char text_buffer[20];int ul_X, ul_Y;ul_X = LEFT_MARGIN;ul_Y = WINDOW_HEIGHT - BOX_SIZE * (FRAME_UNIT_HEIGHT - 4); setcolor(BLUE);sprintf(text_buffer, "Score Total: %d", get_ScoreTotal());moveto(ul_X, ul_Y);outtext(text_buffer);setcolor(YELLOW);ScoreTotal++;sprintf(text_buffer, "Score Total: %d", get_ScoreTotal());moveto(ul_X, ul_Y);outtext(text_buffer);}void init_SpeedLevel(){SpeedLevel = 1;}int get_SpeedLevel(){return(SpeedLevel);}void draw_SpeedLevel(int old_l, int new_l){char text_buffer[20];int ul_X, ul_Y;ul_X = LEFT_MARGIN;ul_Y = WINDOW_HEIGHT - BOX_SIZE * (FRAME_UNIT_HEIGHT - 4); setcolor(BLUE);sprintf(text_buffer, "Speed Level: %d", old_l);moveto(ul_X, ul_Y + textheight("H") * 2);outtext(text_buffer);setcolor(YELLOW);sprintf(text_buffer, "Speed Level: %d", new_l);moveto(ul_X, ul_Y + textheight("H") * 2);outtext(text_buffer);}void setSpeedLevel(int score){if(score >= 0 && score < 20){draw_SpeedLevel(get_SpeedLevel(), 1);SpeedLevel = 1;}else if(score >= 20 && score < 50){draw_SpeedLevel(get_SpeedLevel(), 2);SpeedLevel = 2;}else if(score >= 50 && score < 100){draw_SpeedLevel(get_SpeedLevel(), 3);SpeedLevel = 3;}else{draw_SpeedLevel(get_SpeedLevel(), 4);SpeedLevel = 4;}}void set_GameStat(Type_GAMESTATUS state){GameStat = state;}Type_GAMESTATUS get_GameStat() {return(GameStat);}void set_SnakeDead(Boolean T){obj_snake.Dead = T;}Boolean Is_SnakeDead(){return(obj_snake.Dead);}int get_SHOD(int T){switch(T){case SMD_UP:return(SMD_DOWN);case SMD_DOWN:return(SMD_UP);case SMD_RIGHT:return(SMD_LEFT);case SMD_LEFT:return(SMD_RIGHT);}}int get_SHD(){return(obj_snake.direction);}Boolean findPointInSnake(int pX, int pY) {LSNode p;if((obj_snake.Head_cur_pos.p_X == pX) && (obj_snake.Head_cur_pos.p_Y == pY))return(TRUTH);for(p = obj_snake.next;p != NULL;p = p->next){if((p->cur_pos.p_X == pX) && (p->cur_pos.p_Y == pY))return(TRUTH);}return(FALS);}Boolean Is_SnakEating(){if((obj_snake.Head_pre_pos.p_X == obj_egg.egg_pos.p_X) && (obj_snake.Head_pre_pos.p_Y == obj_egg.egg_pos.p_Y))return(TRUTH);elsereturn(FALS);}void Init_obj_snake(){obj_snake.direction = SMD_RIGHT;obj_snake.len = 1;obj_snake.Head_cur_pos.p_X = SNAK_DEFAULT_POS_X;obj_snake.Head_cur_pos.p_Y = SNAK_DEFAULT_POS_Y;obj_snake.Head_pre_pos = obj_snake.Head_cur_pos;obj_snake.Head_color = RED;obj_snake.next = NULL;obj_snake.Dead = FALS;}void Init_obj_egg(){obj_egg.egg_pos.p_X = 0;obj_egg.egg_pos.p_Y = 0;obj_egg.egg_color = BLACK;}void RegistryGraphicMode(){int Driver, Mode;detectgraph(&Driver, &Mode);initgraph(&Driver, &Mode,"");}void Draw_FrameInWindow(int f_ul_X, int f_ul_Y, int f_dr_X, int f_dr_Y, int W, int H) {int i, x, y;rectangle(f_ul_X - 1, f_ul_Y - 1, f_dr_X + 1, f_dr_Y + 1);setfillstyle(SOLID_FILL, BLACK);bar(f_ul_X, f_ul_Y, f_dr_X, f_dr_Y);setcolor(DARKGRAY);for(i = 1;i < W;i++){x = f_ul_X + i * BOX_SIZE;line(x, f_ul_Y, x, f_dr_Y);}for(i = 1;i < H;i++){y = f_ul_Y + i * BOX_SIZE;line(f_ul_X, y, f_dr_X, y);}}void Draw_mainGraphWindow(){int ul_X, ul_Y, dr_X, dr_Y;setfillstyle(SOLID_FILL, BLUE);bar(0, 0, WINDOW_WIDTH - 1, WINDOW_HEIGHT - 1);ul_X = LEFT_MARGIN;ul_Y = WINDOW_HEIGHT - BOX_SIZE * (FRAME_UNIT_HEIGHT * 2 - 3);dr_X = LEFT_MARGIN + BOX_SIZE * FRAME_UNIT_WIDTH;dr_Y = WINDOW_HEIGHT - BOX_SIZE * (FRAME_UNIT_HEIGHT - 3);Draw_FrameInWindow(ul_X, ul_Y, dr_X, dr_Y, FRAME_UNIT_WIDTH, FRAME_UNIT_HEIGHT);ul_X = LEFT_MARGIN;ul_Y = WINDOW_HEIGHT - BOX_SIZE * (FRAME_UNIT_HEIGHT - 4);settextjustify(LEFT_TEXT, TOP_TEXT);settextstyle(DEFAULT_FONT, HORIZ_DIR, 1);setcolor(YELLOW);sprintf(text_buffer, "Score Total: %d", get_ScoreTotal());moveto(ul_X, ul_Y);outtext(text_buffer);sprintf(text_buffer, "Speed Level: %d", get_SpeedLevel());moveto(ul_X, gety() + textheight("H") * 2);outtext(text_buffer);strcpy(text_buffer, "EXIT: ESC Button");moveto(ul_X, gety() + textheight("H") * 2);outtext(text_buffer);strcpy(text_buffer, "Created By: qiuyongfei");moveto(ul_X, gety() + textheight("H") * 2);outtext(text_buffer);strcpy(text_buffer, "Class: 04hulianwang29hao");moveto(ul_X, gety() + textheight("H") * 2);outtext(text_buffer);strcpy(text_buffer, "UP: Up Arrow");moveto(ul_X + textwidth("H") * 30, ul_Y);strcpy(text_buffer, "DOWN: Down Arrow");moveto(ul_X + textwidth("H") * 30, gety() + textheight("H") * 2);outtext(text_buffer);strcpy(text_buffer, "LEFT: Left Arrow");moveto(ul_X + textwidth("H") * 30, gety() + textheight("H") * 2);outtext(text_buffer);strcpy(text_buffer, "RIGHT: Right Arrow");moveto(ul_X + textwidth("H") * 30, gety() + textheight("H") * 2);outtext(text_buffer);strcpy(text_buffer, "STOP: Space Button");moveto(ul_X + textwidth("H") * 30, gety() + textheight("H") * 2);outtext(text_buffer);}void draw_egg(Boolean T){int ul_X, ul_Y;int color;ul_X = LEFT_MARGIN;ul_Y = WINDOW_HEIGHT - BOX_SIZE * (FRAME_UNIT_HEIGHT * 2 - 3);if(T == FALS)color = BLACK;elsecolor = obj_egg.egg_color;setfillstyle(SOLID_FILL, color);bar(ul_X + BOX_SIZE * obj_egg.egg_pos.p_Y + 1, ul_Y + BOX_SIZE * obj_egg.egg_pos.p_X + 1, ul_X + BOX_SIZE * (obj_egg.egg_pos.p_Y + 1) - 1, ul_Y + BOX_SIZE * (obj_egg.egg_pos.p_X + 1) - 1);}void Mapped_Draw(Boolean T){int ul_X, ul_Y;int Ax, Ay, Bx, By;int color;LSNode p;ul_X = LEFT_MARGIN;ul_Y = WINDOW_HEIGHT - BOX_SIZE * (FRAME_UNIT_HEIGHT * 2 - 3);if(T == FALS)color = BLACK;elsecolor = obj_snake.Head_color;setfillstyle(SOLID_FILL, color);Ax = ul_X + BOX_SIZE * obj_snake.Head_cur_pos.p_Y + 1;Ay = ul_Y + BOX_SIZE * obj_snake.Head_cur_pos.p_X + 1;Bx = ul_X + BOX_SIZE * (obj_snake.Head_cur_pos.p_Y + 1) - 1;By = ul_Y + BOX_SIZE * (obj_snake.Head_cur_pos.p_X + 1) - 1;bar(Ax, Ay, Bx, By);if(T == TRUTH){setfillstyle(SOLID_FILL, YELLOW);bar(Ax + 4, Ay + 4, Ax + 4 + 5, Ay + 4 + 5);}for(p = obj_snake.next;p != NULL;p = p->next){if(T == FALS)color = BLACK;elsecolor = p->color;setfillstyle(SOLID_FILL, color);Ax = ul_X + BOX_SIZE * p->cur_pos.p_Y + 1;Ay = ul_Y + BOX_SIZE * p->cur_pos.p_X + 1;Bx = ul_X + BOX_SIZE * (p->cur_pos.p_Y + 1) - 1;By = ul_Y + BOX_SIZE * (p->cur_pos.p_X + 1) - 1;bar(Ax, Ay, Bx, By);}}void draw_GS_GO_Surface(Type_GAMESTA TUS T){char text_buffer[40];settextjustify(LEFT_TEXT, TOP_TEXT);switch(T){case ON_PAL YING:settextstyle(SANS_SERIF_FONT, HORIZ_DIR, 4);setcolor(LIGHTCY AN);strcpy(text_buffer, "ITEM - 2: Game.Greed Snake");moveto(100, 100);outtext(text_buffer);settextstyle(SANS_SERIF_FONT, HORIZ_DIR, 1);setcolor(YELLOW);strcpy(text_buffer, "Please press any key to continue ...");moveto(150, 300);outtext(text_buffer);break;case GAMEOVER:settextstyle(GOTHIC_FONT, HORIZ_DIR, 8);setcolor(RED);strcpy(text_buffer, "GAME OVER");moveto(70, 80);outtext(text_buffer);settextstyle(SANS_SERIF_FONT, HORIZ_DIR, 2);setcolor(YELLOW);strcpy(text_buffer, "Sorry!");moveto(160, 320);outtext(text_buffer);sprintf(text_buffer, "Total Score: %d", get_ScoreTotal());moveto(240, 320);outtext(text_buffer);sprintf(text_buffer, "Speed Level: %d", get_SpeedLevel());moveto(240, 350);outtext(text_buffer);break;case WINNER:settextstyle(GOTHIC_FONT, HORIZ_DIR, 8);setcolor(RED);strcpy(text_buffer, "YOU WIN !");moveto(80, 80);outtext(text_buffer);settextstyle(SANS_SERIF_FONT, HORIZ_DIR, 2);setcolor(YELLOW);strcpy(text_buffer, "Congratulation!");moveto(120, 320);outtext(text_buffer);sprintf(text_buffer, "Total Score: %d", get_ScoreTotal());moveto(280, 320);outtext(text_buffer);sprintf(text_buffer, "Speed Level: %d", get_SpeedLevel());moveto(280, 350);outtext(text_buffer);break;default:break;}}void set_SH_Pre_Pos(int T){int H_pX, H_pY;H_pX = obj_snake.Head_cur_pos.p_X;H_pY = obj_snake.Head_cur_pos.p_Y;switch(T){case SMD_UP:if((H_pX - 1) < 0 || findPointInSnake(H_pX - 1, H_pY) == TRUTH){set_SnakeDead(TRUTH);return;}obj_snake.Head_pre_pos.p_X = H_pX - 1;obj_snake.Head_pre_pos.p_Y = H_pY;break;case SMD_DOWN:if((H_pX + 1) >= FRAME_UNIT_HEIGHT || findPointInSnake(H_pX + 1, H_pY) == TRUTH){set_SnakeDead(TRUTH);return;}obj_snake.Head_pre_pos.p_X = H_pX + 1;obj_snake.Head_pre_pos.p_Y = H_pY;break;case SMD_RIGHT:if((H_pY + 1) >= FRAME_UNIT_WIDTH || findPointInSnake(H_pX, H_pY + 1) == TRUTH){set_SnakeDead(TRUTH);return;}obj_snake.Head_pre_pos.p_X = H_pX;obj_snake.Head_pre_pos.p_Y = H_pY + 1;break;case SMD_LEFT:if((H_pY - 1) < 0 || findPointInSnake(H_pX, H_pY - 1) == TRUTH){set_SnakeDead(TRUTH);return;}obj_snake.Head_pre_pos.p_X = H_pX;obj_snake.Head_pre_pos.p_Y = H_pY - 1;break;}}Boolean set_SHD(int T){if(get_SHD() == T || get_SHOD(get_SHD()) == T) return(FALS);obj_snake.direction = T;return(TRUTH);}void process_SnakeNode(Boolean eated){int i;POS_in_Fram temp1_cur_pos, temp2_cur_pos; LSNode p, q;temp1_cur_pos = obj_snake.Head_cur_pos;obj_snake.Head_cur_pos = obj_snake.Head_pre_pos;p = obj_snake.next;for(i = 1;i < obj_snake.len;i++){temp2_cur_pos = p->cur_pos;p->cur_pos = temp1_cur_pos;temp1_cur_pos = temp2_cur_pos;p = p->next;}if(eated == TRUTH){q = (LSNode)malloc(sizeof(SNode));q->color = obj_egg.egg_color;q->cur_pos = temp1_cur_pos;if(obj_snake.len == 1){q->next = obj_snake.next;obj_snake.next = q;obj_snake.len++;return;}for(p = obj_snake.next;p->next != NULL;p = p->next);q->next = p->next;p->next = q;obj_snake.len++;}}void generate_Egg(){int temp_pX, temp_pY, temp_color;draw_egg(FALS);temp_pX = random(FRAME_UNIT_HEIGHT);temp_pY = random(FRAME_UNIT_WIDTH);while(findPointInSnake(temp_pX, temp_pY) == TRUTH){temp_pX = random(FRAME_UNIT_HEIGHT);temp_pY = random(FRAME_UNIT_WIDTH);}obj_egg.egg_pos.p_X = temp_pX;obj_egg.egg_pos.p_Y = temp_pY;for(temp_color = random(16);temp_color == BLACK;temp_color = random(16)); obj_egg.egg_color = temp_color;draw_egg(TRUTH);set_Message_Event(NO_EVENT);}void move_To(int T, Boolean step) {if(step == FALS){if(set_SHD(T) == FALS)goto Skip_1;}set_SH_Pre_Pos(T);if(Is_SnakeDead() == TRUTH) goto Skip_2;if(Is_SnakEating() == TRUTH) {Mapped_Draw(FALS);process_SnakeNode(TRUTH);Mapped_Draw(TRUTH);draw_ScoreTotal();setSpeedLevel(get_ScoreTotal());goto Skip_3;}else{Mapped_Draw(FALS);process_SnakeNode(FALS);Mapped_Draw(TRUTH);goto Skip_1;}Skip_1:set_Message_Event(NO_EVENT); return;Skip_2:set_Message_Event(ESC_OUT); return;Skip_3:set_Message_Event(GENERAT_EGG); return;}void pause_game(){while((bioskey(0) >> 8) != GAME_STOP);set_Message_Event(NO_EVENT);}void process_GameStat(Type_GAMESTATUS T) {LSNode p, q;switch(T){case ON_PAL YING:draw_GS_GO_Surface(ON_PAL YING);break;case WINNER:cleardevice();draw_GS_GO_Surface(WINNER);getch();break;case GAMEOVER:cleardevice();draw_GS_GO_Surface(GAMEOVER);getch();break;default:break;}p = obj_snake.next;while(p != NULL){q = p->next;free(p);}}Boolean IsWinner(){if(get_SpeedLevel() == 4)return(TRUTH);elsereturn(FALS);}Boolean IsGameOver(){if(get_Message_Event() == ESC_OUT)return(TRUTH);elsereturn(FALS);}Boolean IsTimeOut(){static long temp, sourc;temp = biostime(0, sourc);if((temp - sourc) < (TIMEINTERVAL - SpeedLevel))return FALS;else{sourc = temp;return TRUTH;}}void getMessageEvent(){if(get_Message_Event() == GENERAT_EGG || get_Message_Event() == ESC_OUT || get_Message_Event() == GAME_STOP)return;if(IsTimeOut() == TRUTH){set_Message_Event(STEP_MOVE);}if(bioskey(1)){set_Message_Event(bioskey(0) >> 8); return;}}void dispatchMessage_Event(){switch(get_Message_Event()){case UP_MOVE:move_To(SMD_UP, FALS);break;case DOWN_MOVE:move_To(SMD_DOWN, FALS);break;case LEFT_MOVE:move_To(SMD_LEFT, FALS);break;case RIGHT_MOVE:move_To(SMD_RIGHT, FALS);break;case STEP_MOVE:move_To(get_SHD(), TRUTH);break;case GENERA T_EGG:generate_Egg();break;case GAME_STOP:pause_game();break;case ESC_OUT:break;default:set_Message_Event(NO_EVENT); }}void main(){RegistryGraphicMode();set_GameStat(ON_PAL YING);process_GameStat(get_GameStat());clear_ScoreTotal();Init_obj_snake();Init_obj_egg();init_SpeedLevel();randomize();set_Message_Event(GENERAT_EGG);getch();cleardevice();Draw_mainGraphWindow();do{getMessageEvent(); dispatchMessage_Event();if(IsWinner() == TRUTH){set_GameStat(WINNER);break;}if(IsGameOver() == TRUTH){set_GameStat(GAMEOVER); break;}}while(1);process_GameStat(get_GameStat());closegraph(); }。
贪吃蛇(HTML小游戏使用JavaScript开发)贪吃蛇:HTML小游戏使用JavaScript开发在游戏界,贪吃蛇是非常经典和受欢迎的一款小游戏。
它的简单和上瘾性使得无数玩家沉迷其中。
今天,我们将学习如何使用HTML和JavaScript来开发一个贪吃蛇的小游戏。
一、游戏的基本思路贪吃蛇的游戏规则非常简单明了。
玩家控制蛇的移动,通过吃食物来不断增长蛇的长度。
当蛇碰到墙壁或者自己的身体时,游戏结束。
游戏的目标是使蛇长得尽可能长,挑战自己的最高得分。
二、HTML布局首先,我们需要在HTML文件中创建游戏画布。
这个画布将用于显示游戏的界面。
我们可以通过HTML的"canvas"元素来实现。
```html<!DOCTYPE html><html><head><title>贪吃蛇</title><style>#gameCanvas {border: 1px solid black;}</style></head><body><canvas id="gameCanvas" width="400" height="400"></canvas><script>// 在这里编写JavaScript代码</script></body></html>```上面的代码中,我们创建了一个宽高为400像素的画布,并给它设置了一个边框。
三、JavaScript逻辑接下来,我们需要使用JavaScript来实现游戏的逻辑。
我们将使用一个JavaScript类来表示贪吃蛇,并在其中实现移动、吃食物等功能。
```javascript<script>class SnakeGame {constructor(canvasId) {this.canvas = document.getElementById(canvasId);this.context = this.canvas.getContext("2d");this.snake = new Snake();this.food = new Food();// 在这里添加事件监听器,监听用户的方向键输入this.gameLoop();}// 游戏主循环gameLoop() {// 清空画布this.context.clearRect(0, 0, this.canvas.width, this.canvas.height); // 更新蛇的位置this.snake.update();// 绘制蛇和食物this.snake.draw(this.context);this.food.draw(this.context);// 在下一帧时再次调用游戏主循环requestAnimationFrame(() => this.gameLoop()); }}class Snake {constructor() {// 在这里初始化蛇的位置和长度等信息}update() {// 在这里更新蛇的位置和长度等信息}draw(context) {// 在这里使用context绘制蛇的形状}}class Food {constructor() {// 在这里初始化食物的位置等信息}draw(context) {// 在这里使用context绘制食物的形状}}// 创建一个名为"game"的SnakeGame实例const game = new SnakeGame("gameCanvas");</script>```在上面的代码中,我们创建了一个`SnakeGame`类来表示游戏,`Snake`类来表示蛇,和`Food`类来表示食物。
<!DOCTYPE html><html><head><meta charset="UTF-8"><title>Insert title here</title><style type="text/css">#myCanvas{border:1px solid #f00;}</style></head><body><input type="button" value="开始游戏" onclick="beginGame();" /> <canvas id="myCanvas" width="450" height="450"></canvas></body><script type="text/javascript">var canvas = document.getElementById("myCanvas");var ctx = canvas.getContext("2d");var w = 15;//格子宽、高var snaLen = 6; //初始长度var snake = []; //身体长度for(var i = 0; i < snaLen; i++){snake[i] = new cell(i , 0 , 39);}var head = snake[snaLen - 1]; //头部//初始食物var foodx = Math.ceil(Math.random() * 28 + 1);var foody = Math.ceil(Math.random() * 28 + 1);var food = new Food(foodx , foody);//食物function Food(x , y){this.x = x;this.y = y;return this;}//身体function cell(x , y , d){this.x = x;this.y = y;this.d = d;return this;}//动作function draw(){ctx.clearRect(0,0,450,450);//画布局// for(var i = 0; i < 30; i++){// ctx.strokeStyle = "#ccc";//线条颜色// ctx.beginPath();// ctx.moveTo(0,i*w);// ctx.lineTo(450,i*w);// ctx.moveTo(i*w,0);// ctx.lineTo(i*w,450);// ctx.closePath();// ctx.stroke();// }//画蛇身for(var j = 0; j < snake.length; j++){ctx.fillStyle = "black";if(j == snake.length - 1){ctx.fillStyle = "red";}ctx.beginPath();ctx.rect(snake[j].x*w , snake[j].y*w , w , w);ctx.closePath();ctx.fill();ctx.stroke();}//出现食物drawFood();//吃到食物if(head.x == food.x && head.y == food.y){initFood();food = new Food(foodx , foody);//重新出现食物drawFood();//增加蛇的长度有些小瑕疵,蛇身增长时应该是身体增长,而不是在蛇头上增长var newCell = new cell(head.x , head.y , head.d);switch(head.d){case 40 : newCell.y++ ; break;//下case 39 : newCell.x++ ; break;//右case 38 : newCell.y-- ; break;//上case 37 : newCell.x-- ; break;//左}snake[snake.length] = newCell;head = newCell;//head =}}//随机初始化食物function initFood(){foodx = Math.ceil(Math.random() * 28 + 1);foody = Math.ceil(Math.random() * 28 + 1);for(var i = 0; i < snake.length; i++){if(snake[i].x == foodx && snake[i].y == foody){initFood();}}}//画食物function drawFood(){//绘制食物ctx.fillStyle = "blue";ctx.beginPath();ctx.rect(food.x * w , food.y * w , w , w);ctx.closePath();ctx.fill();}draw();//监听键盘事件document.onkeydown = function(e){//下40 ,右边39,左边37,上38 键盘事件var keyCode = e.keyCode;if(head.d - keyCode != 2 && head.d - keyCode != -2 && keyCode >=37 && keyCode <=40){moveSnake(keyCode);}}//控制蛇移动方向function moveSnake(keyCode){var newSnake = [];var newCell = new cell(head.x , head.y , head.d);//头//身体for(var i = 1; i < snake.length ; i++){newSnake[i - 1] = snake[i];}newSnake[snake.length - 1] = newCell;newCell.d = keyCode;switch(keyCode){case 40 : newCell.y++ ; break;//下case 39 : newCell.x++ ; break;//右case 38 : newCell.y-- ; break;//上case 37 : newCell.x-- ; break;//左}snake = newSnake;head = snake[snake.length - 1];checkDeath();draw();}//游戏规则function checkDeath(){//超出边框if(head.x >= 30 || head.y>= 30 || head.x < 0 || head.y < 0){alert("Game over!");window.location.reload();}//咬到自己for(var i = 0 ; i < snake.length - 1 ; i++){if(head.x == snake[i].x && head.y == snake[i].y){alert("Game over!");window.location.reload();}}}//蛇自动走function moveClock(){moveSnake(head.d);}function beginGame(){setInterval(moveClock,600);}</script></html>。
html+js贪吃蛇游戏区域限制在⼀个ul⾥,蛇的每⼀节是有⼀个个li组成,每个li都⽤position定位。
⾷物是创建的⼀个div,每次蛇头碰触⾷物时,创建⼀个新的li,li会⾃动加载蛇的尾部,然后通过随机数改变⾷物的位置。
通过响应键盘的wasd控制蛇头的⽅向(⽤的是onkeypress事件和keyCode),⽤定时器控制蛇头⾃动⾛,⽤数组储存蛇头每次所⾛的top和left值,⽤循环把这些top和left值赋值给蛇头后⾯的li上,这样蛇⾝⼦就会随着蛇头动起来了。
效果图:标注:红⾊的圆是⾷物,蛇头是⿊⾊的。
代码如下:<!DOCTYPE html><html><head><meta charset="utf-8"><title>蛇头移动</title><style media="screen">*{padding: 0px;margin: 0px;}ul{height: 800px;width: 800px;background-color: darkgreen;position: relative;list-style: none;margin: 15px auto;text-align: right;color: white;font-size: 2em;padding: 10px 10px;}ul li{height: 100px;width: 100px;border-radius: 50%;background-color: darkred;position: absolute;}ul li:nth-child(1){top: 20px;left: 0;background-color: black;height: 111px;width: 111px;}ul li:nth-child(2){top: 10px;left: 0;background-color: white;}ul li:nth-child(3){top: 0px;left: 0;}div{height: 100px;width: 100px;border-radius: 50%;background-color: darkred;position: absolute;}section{width: 800px;padding: 10px 0px;border-radius: 30px;background-color: rgba(200,17, 2,0.9);margin: 1px auto;text-align: center;font-size: 33px;border: 3px solid black;box-shadow: 0 0 10px gray;cursor: pointer;color: white;}</style><script type="text/javascript">window.onload=function(){var ul=document.querySelector('ul');var lis=document.getElementsByTagName('li');var btn=document.getElementsByTagName('section')[0];var timer;//蛇头的top与left值var top=lis[0].offsetTop;var left=lis[0].offsetLeft;var flag=true;//存储蛇头的每⼀节的位置var snakePosi=[{x:lis[1].offsetLeft,y:lis[1].offsetTop},{x:lis[0].offsetLeft,y:lis[0].offsetTop}];//声明速度var speedX=10;var speedY=10;var contrStarPau=false;function keyContrMove(flag){clearInterval(timer);timer=setInterval(function(){if (!contrStarPau) {return;}if (flag) {top+=speedY;lis[0].style.top=top+'px';}else {left+=speedX;lis[0].style.left=left+'px';}//将蛇头的位置存⼊数组,⽬的是把它的位置赋给它的下⼀节snakePosi.push({x:left,y:top});if (snakePosi.length>lis.length) {snakePosi.shift();}for (var i =1; i<snakePosi.length; i++) {lis[i].style.top=snakePosi[snakePosi.length-1-i].y+'px';lis[i].style.left=snakePosi[snakePosi.length-1-i].x+'px';}if ((Math.abs(lis[0].offsetTop-div.offsetTop)<lis[0].offsetHeight && lis[0].offsetLeft==div.offsetLeft) || (Math.abs(lis[0].offsetLeft-div.offsetLeft)<lis[0].offsetWidth && lis[0].offsetTop==div.offsetTop)) { div.style.top=randomNum()+'px';div.style.left=randomNum()+'px';createLi();}if (lis[2].offsetTop<0 || lis[2].offsetTop>(ul.offsetHeight-lis[2].offsetHeight) || lis[2].offsetLeft<0 || lis[2].offsetLeft>(ul.offsetWidth-lis[2].offsetWidth)) {clearInterval(timer)}},33)}keyContrMove(true);document.onkeypress=function(event){event=event||window.event;if (event.keyCode==119 && flag==false) {if (speedY>0) {speedY=-speedY;}flag=true;keyContrMove(true);}if (event.keyCode==115 && flag==false) {if (speedY<0) {speedY=-speedY;}flag=true;keyContrMove(true);}if (event.keyCode==97 && flag==true) {if (speedX>0) {speedX=-speedX;}flag=false;keyContrMove(false);}if (event.keyCode==100 && flag==true) {if (speedX<0) {speedX=-speedX;}flag=false;keyContrMove(false);}}function randomNum(){var a=parseInt(Math.random()*(700-10)+10)return a=a-a%10;}function createLi(){var li=document.createElement('li');ul.appendChild(li);}function createDiv(){var div=document.createElement('div');div.style.top=randomNum()+'px';div.style.left=randomNum()+'px';ul.appendChild(div);}createDiv();var div=document.getElementsByTagName('div')[0];btn.onclick=function(){contrStarPau=!contrStarPau;console.log(contrStarPau);}}</script></head><body><ul>By Paul.SJ<li></li><li></li><li></li></ul>//按钮<section>start / pause</section></body></html>。
//主函数# include <windows.h># include <time.h># include "resource.h"#include "snake.h"#include "table.h"#define GAME_STATE_W AIT 0//游戏等待状态#define GAME_STATE_RUN 1//游戏运行状态#define GAME_STATE_END 2//游戏结束状态//界面相关物件尺寸的定义#define WALL_WIDTH 80//外墙左部到游戏区的宽度#define WALL_HEIGHT 80//外墙顶部到游戏区的高度#define BMP_W ALL_WIDTH 16//墙位图的宽度#define BMP_W ALL_HEIGHT 16//墙位图的高度LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam);void DrawGame(void);void ShellDraw( HDC hdc );void GameAreaDraw(HDC hdc);void OnTimer(UINT uTIMER_ID);void StartGame( void );void EndGame( void );//创建一个桌子CTable table;int tableBlockWidth = 0; //桌子的格子的宽度int tableBlockHeight = 0; //桌子的格子的高度int iScores = 0; //游戏的得分UINT uGameState = GAME_STATE_W AIT; //当前游戏状态HDC windowDC = NULL; //windows屏幕设备HDC bufferDC = NULL; //缓冲设备环境HDC picDC = NULL; //snake图像内存设备HDC endDC = NULL; //游戏终结图像内存设备HDC scoreDC = NULL; //分数板内存设备HWND hAppWnd = NULL; //本application窗口句柄HBITMAP picBMP = NULL; //snake图像位图句柄HBITMAP bufferBMP = NULL; //缓冲位图句柄HBITMAP endBMP = NULL; //游戏终结hAppWnd图像内存句柄HBITMAP hbmpWall = NULL; //墙位图句柄HBITMAP hbmpScore = NULL; //分数板位图句柄HBRUSH hbrushWall = NULL; //墙画刷//定时器标识UINT uSnakeMoveTimer; //蛇的移动UINT uFoodAddTimer; //水果的产生//框架的位置数据定义//GDI RECT 而不是MFC CRectRECT g_ClientRect;int g_iClientWidth;int g_iClientHeight;int WINAPI WinMain(HINSTANCE hInstance, // handle to current instanceHINSTANCE hPrevInstance, // handle to previous instanceLPSTR lpCmdLine, // command lineint nCmdShow // show state){WNDCLASS wndClass;UINT width,height;//定义窗口wndClass.cbClsExtra = 0;wndClass.cbWndExtra = 0;wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);wndClass.hIcon = LoadIcon(NULL,MAKEINTRESOURCE(IDI_MAIN));wndClass.hCursor = LoadCursor(NULL,IDC_ARROW);wndClass.hInstance = hInstance;wndClass.lpfnWndProc = WndProc;wndClass.lpszClassName = "Snake";wndClass.lpszMenuName = NULL;wndClass.style = CS_HREDRAW | CS_VREDRAW;//注册窗口RegisterClass(&wndClass);width = GetSystemMetrics(SM_CXSCREEN);height = GetSystemMetrics(SM_CYSCREEN);HWND hWnd;hWnd = CreateWindow("Snake","贪吃蛇游戏",WS_POPUP,0,0,width,height,NULL,NULL,hInstance,NULL);hAppWnd = hWnd;//显示窗口ShowWindow(hWnd,SW_SHOWNORMAL);UpdateWindow(hWnd);GetClientRect(hWnd,&g_ClientRect);g_iClientWidth = g_ClientRect.right - g_ClientRect.left;g_iClientHeight = g_ClientRect.bottom - g_ClientRect.top;//将游戏区域分成横纵均匀的20小块tableBlockWidth = (g_ClientRect.right - 2 * WALL_WIDTH) / 20;tableBlockHeight = (g_ClientRect.bottom - 2 * WALL_HEIGHT) / 20;//获取当前主设备与windowDC相连windowDC = GetDC(NULL);//创建与windowDC兼容的内存设备环境bufferDC = CreateCompatibleDC(windowDC);picDC = CreateCompatibleDC(windowDC);endDC = CreateCompatibleDC(windowDC);scoreDC =CreateCompatibleDC(windowDC);//位图的初始化与载入位图bufferBMP = CreateCompatibleBitmap(windowDC,g_iClientWidth,g_iClientHeight);picBMP = (HBITMAP)LoadImage(NULL,"snake.bmp",IMAGE_BITMAP,160,80,LR_LOADFROMFILE);hbmpWall = (HBITMAP)LoadImage(NULL,"brick.bmp",IMAGE_BITMAP,16,16,LR_LOADFROMFILE);endBMP = (HBITMAP)LoadImage(NULL,"end.bmp",IMAGE_BITMAP,369,300,LR_LOADFROMFILE);hbmpScore = (HBITMAP)LoadImage(NULL,"scoreboard.bmp",IMAGE_BITMAP,265,55,LR_LOADFROMFILE);//生声明位图与设备环境的关联SelectObject(bufferDC,bufferBMP);SelectObject(picDC,picBMP);SelectObject(endDC,endBMP);SelectObject(scoreDC,hbmpScore);hbrushWall = CreatePatternBrush(hbmpWall);StartGame();MSG Msg;while (GetMessage(&Msg,NULL,0,0)){TranslateMessage(&Msg);DispatchMessage(&Msg);}return Msg.wParam;}LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam){switch (message){case WM_TIMER:OnTimer((UINT)wParam);break;case WM_KEYDOWN:switch (wParam){case VK_ESCAPE:KillTimer(hAppWnd,uSnakeMoveTimer);KillTimer(hAppWnd,uFoodAddTimer);uGameState = GAME_STATE_W AIT;if (IDYES == MessageBox(hWnd,"真的要退出吗?","贪吃蛇",MB_YESNO | MB_ICONQUESTION)){exit(0);}uSnakeMoveTimer = SetTimer(hAppWnd,500,100,NULL);uFoodAddTimer = SetTimer(hAppWnd,600,7000,NULL);uGameState = GAME_STATE_RUN;break;case VK_UP:table.ChangeSnakeDirect(S_UP);break;case VK_DOWN:table.ChangeSnakeDirect(S_DOWN);break;case VK_LEFT:table.ChangeSnakeDirect(S_LEFT);break;case VK_RIGHT:table.ChangeSnakeDirect(S_RIGHT);break;case VK_SPACE:if (GAME_STATE_END == uGameState){StartGame();}else if (GAME_STATE_RUN == uGameState){KillTimer(hAppWnd,uSnakeMoveTimer);KillTimer(hAppWnd,uFoodAddTimer);uGameState = GAME_STATE_W AIT;}else{uSnakeMoveTimer = SetTimer(hAppWnd,500,100,NULL);uFoodAddTimer = SetTimer(hAppWnd,600,7000,NULL);uGameState = GAME_STATE_RUN;}break;}break;case WM_SETCURSOR:SetCursor(NULL);break;case WM_DESTROY:ReleaseDC(hWnd,picDC);ReleaseDC(hWnd,bufferDC);ReleaseDC(hWnd,windowDC);PostQuitMessage(0);break;}return DefWindowProc(hWnd,message,wParam,lParam);}void DrawGame(){ShellDraw(bufferDC);GameAreaDraw(bufferDC);BitBlt(windowDC,0,0,g_iClientWidth,g_iClientHeight,bufferDC,0,0,SRCCOPY);}void OnTimer(UINT uTIMER_ID){if (uTIMER_ID == uSnakeMoveTimer){//移动蛇table.SnakeMove();//检测蛇是否碰到自己的身体if (table.GetSnake() ->IsHeadTouchBody(table.GetSnake() ->GetPos()[0].x,table.GetSnake() ->GetPos()[0].y)){EndGame();}//根据蛇头所在区域做相应的处理switch (table.GetData(table.GetSnake() ->GetPos()[0].x,table.GetSnake() ->GetPos()[0].y)){case TB_STATE_FOOD:table.ClearFood(table.GetSnake() ->GetPos()[0].x,table.GetSnake() ->GetPos()[0].y);table.AddBlock((rand())%tableBlockWidth,rand()%tableBlockHeight);table.GetSnake() ->AddBody();iScores++;break;case TB_STATE_BLOCK:case TB_STATE_SBLOCK:EndGame();break;}//xianshiDrawGame();}else if (uTIMER_ID == uFoodAddTimer){//定时加食物table.AddFood((rand())%tableBlockWidth,rand()%tableBlockHeight);}}//开始游戏void StartGame(){iScores = 0;int iFoodNumber;//桌面初始化table.InitialTable(tableBlockWidth,tableBlockHeight);table.GetSnake() ->ChangeDirect(S_RIGHT);table.GetSnake() ->SetHeadPos(tableBlockWidth / 2,tableBlockHeight / 2);//预先随机产生一些食物srand( (unsigned)time(NULL));for (iFoodNumber = 0; iFoodNumber < 400; iFoodNumber++){table.AddFood((rand())%tableBlockWidth,(rand())%tableBlockHeight);}//打开定时器DrawGame();uSnakeMoveTimer = SetTimer(hAppWnd,500,100,NULL);uFoodAddTimer = SetTimer(hAppWnd,600,7000,NULL);uGameState = GAME_STATE_RUN;}void EndGame(){//关计时器KillTimer(hAppWnd,uSnakeMoveTimer);KillTimer(hAppWnd,uFoodAddTimer);uGameState = GAME_STATE_END;}void ShellDraw(HDC hdc){char szText[30] = "Score: ";char szNum[20];int iNowScores = iScores * 100;itoa(iNowScores,szNum,10);strcat(szText,szNum);RECT rt,rect;GetClientRect(hAppWnd,&rt);//墙的绘制SelectObject(hdc,hbrushWall);PatBlt(hdc,rt.left,rt.top,rt.right,rt.bottom,PATCOPY);//内部游戏区为白色底平面rect.left = rt.left + WALL_WIDTH;rect.top = rt.top + WALL_HEIGHT;rect.right = rt.right - WALL_WIDTH;rect.bottom = rt.bottom - WALL_HEIGHT;FillRect(hdc,&rect,(HBRUSH)(COLOR_WINDOW + 1));BitBlt(hdc,GetSystemMetrics(SM_CXSCREEN) / 3 ,10,256,55,scoreDC,0,0,SRCCOPY);SetBkMode(hdc,TRANSPARENT);TextOut(hdc,GetSystemMetrics(SM_CXSCREEN) / 3 + 50,30,szText,strlen(szText));}void GameAreaDraw(HDC hdc){int i,j;int x, y, x_pos, y_pos;BitmapState state;//绘制水果与毒果for (i = 0; i < tableBlockHeight; i++){for (j = 0; j < tableBlockWidth; j++){x_pos = j * 20 + WALL_WIDTH;y_pos = i * 20 + WALL_HEIGHT;switch (table.GetData(j,i)){case TB_STATE_FOOD:BitBlt(hdc,x_pos,y_pos,20,20,picDC,100,0,SRCPAINT);BitBlt(hdc,x_pos,y_pos,20,20,picDC,20,0,SRCAND);break;case TB_STATE_BLOCK:BitBlt(hdc,x_pos,y_pos,20,20,picDC,80,0,SRCPAINT);BitBlt(hdc,x_pos,y_pos,20,20,picDC,0,0,SRCAND);break;}}}//根据当前的形状绘制蛇头x = table.GetSnake()->GetPos()[0].x;y = table.GetSnake()->GetPos()[0].y;x_pos = x * 20 + WALL_WIDTH;y_pos = y * 20 + WALL_HEIGHT;state = table.GetSnake()->GetStateArray()[0];switch (state){case M_UP_UP:BitBlt(hdc,x_pos,y_pos,20,20,picDC,80,20,SRCPAINT);BitBlt(hdc,x_pos,y_pos,20,20,picDC,0,20,SRCAND);break;case M_DOWN_DOWN:BitBlt(hdc,x_pos,y_pos,20,20,picDC,140,20,SRCPAINT);BitBlt(hdc,x_pos,y_pos,20,20,picDC,60,20,SRCAND);break;case M_LEFT_LEFT:BitBlt(hdc,x_pos,y_pos,20,20,picDC,100,20,SRCPAINT);BitBlt(hdc,x_pos,y_pos,20,20,picDC,20,20,SRCAND);break;case M_RIGHT_RIGHT:BitBlt(hdc,x_pos,y_pos,20,20,picDC,120,20,SRCPAINT);BitBlt(hdc,x_pos,y_pos,20,20,picDC,40,20,SRCAND);break;}//根据蛇身各节点的状态绘制蛇身for (i = 1; i < table.GetSnake()->GetLength() - 1; i++){x = table.GetSnake()->GetPos()[i].x;y = table.GetSnake()->GetPos()[i].y;x_pos = x * 20 + WALL_WIDTH;y_pos = y * 20 + WALL_HEIGHT;state = table.GetSnake()->GetStateArray()[i];switch (state){case M_UP_UP:case M_DOWN_DOWN:BitBlt(hdc,x_pos,y_pos,20,20,picDC,80,40,SRCPAINT);BitBlt(hdc,x_pos,y_pos,20,20,picDC,0,40,SRCAND);break;case M_LEFT_LEFT:case M_RIGHT_RIGHT:BitBlt(hdc,x_pos,y_pos,20,20,picDC,100,40,SRCPAINT);BitBlt(hdc,x_pos,y_pos,20,20,picDC,20,40,SRCAND);break;case M_RIGHT_DOWN:case M_UP_LEFT:BitBlt(hdc,x_pos,y_pos,20,20,picDC,100,60,SRCPAINT);BitBlt(hdc,x_pos,y_pos,20,20,picDC,20,60,SRCAND);break;case M_RIGHT_UP:case M_DOWN_LEFT:BitBlt(hdc,x_pos,y_pos,20,20,picDC,140,40,SRCPAINT);BitBlt(hdc,x_pos,y_pos,20,20,picDC,60,40,SRCAND);break;case M_LEFT_DOWN:case M_UP_RIGHT:BitBlt(hdc,x_pos,y_pos,20,20,picDC,80,60,SRCPAINT);BitBlt(hdc,x_pos,y_pos,20,20,picDC,0,60,SRCAND);break;case M_LEFT_UP:case M_DOWN_RIGHT:BitBlt(hdc,x_pos,y_pos,20,20,picDC,120,40,SRCPAINT);BitBlt(hdc,x_pos,y_pos,20,20,picDC,40,40,SRCAND);break;}}//绘制蛇尾巴x = table.GetSnake()->GetPos()[table.GetSnake()->GetLength()-1].x;y = table.GetSnake()->GetPos()[table.GetSnake()->GetLength()-1].y;x_pos = x * 20 + WALL_WIDTH;y_pos = y * 20 + WALL_HEIGHT;state = table.GetSnake()->GetStateArray()[table.GetSnake()->GetLength()-1];switch (state){case M_UP_UP:BitBlt(hdc,x_pos,y_pos,20,20,picDC,120,60,SRCPAINT);BitBlt(hdc,x_pos,y_pos,20,20,picDC,40,60,SRCAND);break;case M_DOWN_DOWN:BitBlt(hdc,x_pos,y_pos,20,20,picDC,120,0,SRCPAINT);BitBlt(hdc,x_pos,y_pos,20,20,picDC,40,0,SRCAND);break;case M_LEFT_LEFT:BitBlt(hdc,x_pos,y_pos,20,20,picDC,140,60,SRCPAINT);BitBlt(hdc,x_pos,y_pos,20,20,picDC,60,60,SRCAND);break;case M_RIGHT_RIGHT:BitBlt(hdc,x_pos,y_pos,20,20,picDC,140,0,SRCPAINT);BitBlt(hdc,x_pos,y_pos,20,20,picDC,60,0,SRCAND);break;}//绘制游戏结束图案if (uGameState == GAME_STA TE_END){x_pos = g_iClientWidth / 3;y_pos = g_iClientHeight / 4;BitBlt(hdc,x_pos,y_pos,369,300,endDC,0,0,SRCCOPY);}}# include "snake.h"CSnake::CSnake(int x_pos,int y_pos,int len){if (len < 1){len = 1;}int i;m_length = len;//蛇的身体体长//初始化蛇的坐标位置m_pPos = new SPoint[m_length+2];m_pPos[0].x = x_pos;m_pPos[0].y = y_pos;for (i = 1; i < m_length +2; i++){m_pPos[i].x = 0;m_pPos[i].y = 0;}//初始化蛇的运动状态m_newSnake.head = S_NONE;m_oldSnake.head = S_NONE;m_newSnake.body = new MoveState[m_length];m_oldSnake.body = new MoveState[m_length];for(i = 0; i < m_length; i++){m_oldSnake.body[i] = S_NONE;m_newSnake.body[i] = S_NONE;}m_newSnake.tail = S_NONE;m_oldSnake.tail = S_NONE;//初始化蛇的位图显示状态;m_pStateArray = new BitmapState[m_length+2];for (i = 0; i < m_length + 2; i++){m_pStateArray[i] = M_NONE;}}CSnake::~CSnake(){SAFE_DELETE_ARRAY(m_pPos);SAFE_DELETE_ARRAY(m_pStateArray);}//根据新旧两蛇的运动状态,确定当前显示的运动状态BitmapState CSnake::GetRightState(MoveState oldDirect,MoveState newDirect) {BitmapState re;switch(oldDirect){case S_NONE:switch(newDirect){case S_NONE:re = M_NONE;break;case S_UP:re = M_UP_UP;break;case S_DOWN:re = M_DOWN_DOWN;break;case S_LEFT:re = M_LEFT_LEFT;break;case S_RIGHT:re = M_RIGHT_RIGHT;break;}break;case S_UP:switch(newDirect){case S_UP:re = M_UP_UP;break;case S_LEFT:re = M_UP_LEFT;break;case S_RIGHT:re = M_UP_RIGHT;break;}break;case S_DOWN:switch(newDirect){case S_DOWN:re = M_DOWN_DOWN;break;case S_LEFT:re = M_DOWN_LEFT;break;case S_RIGHT:re = M_DOWN_RIGHT;break;}break;case S_LEFT:switch(newDirect){case S_UP:re = M_LEFT_UP;break;case S_LEFT:re = M_LEFT_LEFT;break;case S_DOWN:re = M_LEFT_DOWN;break;}break;case S_RIGHT:switch(newDirect){case S_UP:re = M_RIGHT_UP;break;case S_DOWN:re = M_RIGHT_DOWN;break;case S_RIGHT:re = M_RIGHT_RIGHT;break;}break;}return re;}//改变方向void CSnake::ChangeDirect(MoveState d) {//方向不能为其对立方switch(d){case S_NONE:m_newSnake.head = S_NONE;break;case S_UP:if(m_newSnake.head != S_DOWN)m_newSnake.head = S_UP;break;case S_DOWN:if(m_newSnake.head != S_UP)m_newSnake.head = S_DOWN;break;case S_LEFT:if(m_newSnake.head != S_RIGHT)m_newSnake.head = S_LEFT;break;case S_RIGHT:if(m_newSnake.head != S_LEFT)m_newSnake.head = S_RIGHT;break;}}//蛇移动void CSnake::Move(){int i;//1.计算各节点的新状态//保存蛇身体各部位的形状for (i = 0; i < m_length; i++){m_oldSnake.body[i] = m_newSnake.body[i];}m_newSnake.tail = m_newSnake.body[m_length-1];for(i = m_length - 1; i > 0; i--){m_newSnake.body[i] = m_newSnake.body[i-1];}m_newSnake.body[0] = m_newSnake.head;//根据新旧状态获取新的状态m_pStateArray[0] = GetRightState(m_oldSnake.head,m_newSnake.head);for(i = 0; i < m_length; i++){m_pStateArray[i+1] = GetRightState(m_oldSnake.body[i],m_newSnake.body[i]);}m_pStateArray[m_length+1] = GetRightState(m_oldSnake.tail,m_newSnake.tail);//2、整个蛇坐标移动,除蛇头外其他为原状态的前一位置for(i = m_length + 1; i > 0; i--){m_pPos[i] = m_pPos[i-1];}//蛇头根据新位置进行偏移switch(m_newSnake.head){case S_UP:m_pPos[0].y -= SNAKE_MOVE;break;case S_DOWN:m_pPos[0].y += SNAKE_MOVE;break;case S_LEFT:m_pPos[0].x -= SNAKE_MOVE;break;case S_RIGHT:m_pPos[0].x += SNAKE_MOVE;break;}}//蛇身体的增长void CSnake::AddBody(int n){//分配变量作为保存各种数据状态int i;Snake_Struct saveOldSnake,saveNewSnake;BitmapState *saveStateArray;SPoint *savePos;//保存蛇的位置信息savePos = new SPoint[m_length+2];for(i = 0; i < m_length + 2; i++){savePos[i] = m_pPos[i];}//保存蛇的状态信息saveOldSnake.head = m_oldSnake.head;saveOldSnake.body = new MoveState[m_length];for(i = 0; i < m_length; i++){saveOldSnake.body[i] = m_oldSnake.body[i];}saveOldSnake.tail = m_oldSnake.tail;saveNewSnake.head = m_newSnake.head;saveNewSnake.body = new MoveState[m_length];for(i = 0; i < m_length; i++){saveNewSnake.body[i] = m_newSnake.body[i];}saveNewSnake.tail = m_newSnake.tail;saveStateArray = new BitmapState[m_length+2];for (i = 0; i < m_length + 2; i++){saveStateArray[i] = m_pStateArray[i];}//将长度增长m_length += n;//释放所有存储蛇状态数据的存储空间SAFE_DELETE_ARRAY(m_newSnake.body); SAFE_DELETE_ARRAY(m_oldSnake.body); SAFE_DELETE_ARRAY(m_pPos);SAFE_DELETE_ARRAY(m_pStateArray);//创建并初始化蛇增长后的存储空间m_pPos = new SPoint[m_length+2];for (i = 0; i < m_length +2; i++){m_pPos[i].x = 0;m_pPos[i].y = 0;}//初始化蛇的运动状态m_newSnake.head = S_NONE;m_oldSnake.head = S_NONE;m_newSnake.body = new MoveState[m_length]; m_oldSnake.body = new MoveState[m_length];for(i = 0; i < m_length; i++){m_oldSnake.body[i] = S_NONE;m_newSnake.body[i] = S_NONE;}m_newSnake.tail = S_NONE;m_oldSnake.tail = S_NONE;//初始化蛇的位图显示状态;m_pStateArray = new BitmapState[m_length+2]; for (i = 0; i < m_length + 2; i++){m_pStateArray[i] = M_NONE;}//恢复原来的长度数据m_newSnake.head = saveNewSnake.head;m_oldSnake.head = saveOldSnake.head;for(i = 0; i < m_length - n; i++){m_newSnake.body[i] = saveNewSnake.body[i];m_oldSnake.body[i] = saveOldSnake.body[i];}m_newSnake.tail = saveNewSnake.tail;m_oldSnake.tail = saveOldSnake.tail;m_pStateArray = new BitmapState[m_length+2];for (i = 0; i < m_length + 2 - n; i++)m_pStateArray[i] = saveStateArray[i];m_pPos = new SPoint[m_length+2];for(i = 0; i < m_length + 2 - n; i++)m_pPos[i] = savePos[i];}//设置蛇头坐标void CSnake::SetHeadPos(int x, int y){m_pPos[0].x = x;m_pPos[0].y = y;}//取蛇状态的标志数组BitmapState* CSnake::GetStateArray(){return m_pStateArray;}//取蛇的位置信息SPoint* CSnake::GetPos(){return m_pPos;}//取蛇长度int CSnake::GetLength()return m_length + 2;}//检测蛇头是否碰到身体bool CSnake::IsHeadTouchBody(int x, int y){int i;for(i = 1; i < m_length + 2; i++){if (m_pPos[i].x == x && m_pPos[i].y == y)return true;}return false;}//初始化,用作游戏结束后重新开始void CSnake::Initial(){//释放以前的存储空间SAFE_DELETE_ARRAY(m_pPos);SAFE_DELETE_ARRAY(m_pStateArray);SAFE_DELETE_ARRAY(m_newSnake.body);SAFE_DELETE_ARRAY(m_oldSnake.body);int i;int x_pos = 0;int y_pos = 0;m_length = 1;//蛇的身体体长//初始化蛇的坐标位置m_pPos = new SPoint[m_length+2];m_pPos[0].x = x_pos;m_pPos[0].y = y_pos;for (i = 1; i < m_length +2; i++){m_pPos[i].x = 0;m_pPos[i].y = 0;}//初始化蛇的运动状态m_newSnake.head = S_NONE;m_oldSnake.head = S_NONE;m_newSnake.body = new MoveState[m_length];m_oldSnake.body = new MoveState[m_length];for(i = 0; i < m_length; i++){m_oldSnake.body[i] = S_NONE;m_newSnake.body[i] = S_NONE;}m_newSnake.tail = S_NONE;m_oldSnake.tail = S_NONE;//初始化蛇的位图显示状态;m_pStateArray = new BitmapState[m_length+2];for (i = 0; i < m_length + 2; i++){m_pStateArray[i] = M_NONE;}}#ifndef __SNAKE_H_H#define __SNAKE_H_H#define SNAKE_MOVE 1#define SAFE_DELETE_ARRAY(p) {delete [](p);(p)=NULL;}#include <stdio.h>//节点图像显示位图状态enumBitmapState{M_NONE,M_UP_UP,M_DOWN_DOWN,M_LEFT_LEFT,M_RIGHT_RIGHT, M_UP_LEFT,M_UP_RIGHT,M_DOWN_LEFT,M_DOWN_RIGHT,M_LEFT_UP,M_LEFT_DOWN,M_RIGHT_UP,M_RIGHT_DOWN};//节点运动状态enum MoveState{S_NONE,S_UP,S_DOWN,S_LEFT,S_RIGHT};//节点位置坐标struct SPointint x;int y;};//定义蛇体状态struct Snake_Struct{MoveState head;//头部MoveState *body;//身体MoveState tail;//尾部};class CSnake{private:int m_length; //蛇的长度Snake_Struct m_newSnake; //蛇的新态的所有节点的运动状态Snake_Struct m_oldSnake; //蛇的原态的所有节点的坐标的运动状态BitmapState *m_pStateArray; //蛇的所有节点显示位图的状态SPoint *m_pPos; //蛇体坐标BitmapState GetRightState(MoveState oldDirect,MoveState newDirect);public:void Move(void);void ChangeDirect(MoveState d);void AddBody(int n=1);void SetHeadPos(int x, int y);BitmapState * GetStateArray(void);SPoint * GetPos(void);bool IsHeadTouchBody(int x, int y);int GetLength(void);void Initial(void);CSnake(int x_pos = 0, int y_pos = 0, int len = 1);~CSnake();};#endif#include "table.h"CTable::CTable()m_width = 0;m_height = 0;m_foodNumber = 0;m_blockNumber = 0;m_board = NULL;}CTable::~CTable(){if (m_board != NULL){SAFE_DELETE_ARRAY(m_board);}}//初始化面板void CTable::InitialTable(int w,int h){int i, j;m_width = w;m_height = h;m_snake.Initial();if (m_board != NULL){SAFE_DELETE_ARRAY(m_board);}//根据高度和宽度设置新的桌子m_board = new int * [m_height];for (i = 0; i < m_height; i++){m_board[i] = new int[m_width];for (j = 0; j < m_width; j++){m_board[i][j] = 0;}}//将桌子四周设置为墙for (i = 0; i < m_height; i++){m_board[i][0] = TB_STATE_SBLOCK;m_board[i][m_width-1] = TB_STA TE_SBLOCK;}for (i = 0; i < m_width; i++){m_board[0][i] = TB_STATE_SBLOCK;m_board[m_height-1][i] = TB_STA TE_SBLOCK;}}//食物的操作bool CTable::AddBlock(int x, int y){if( (x > 0) && (x < m_width) && (y > 0) && (y < m_height) && (m_board[y][x] == TB_STATE_OK)){m_board[y][x] = TB_STA TE_BLOCK;m_blockNumber++;return true;}return false;}bool CTable::AddFood(int x, int y){if( (x > 0) && (x < m_width) && (y > 0) && (y < m_height) && (m_board[y][x] == TB_STATE_OK)){m_board[y][x] = TB_STA TE_FOOD;m_foodNumber++;return true;}return false;}bool CTable::ClearFood(int x, int y){m_board[y][x] = TB_STA TE_OK;return true;}//取蛇对象CSnake * CTable::GetSnake(void){return &m_snake;}//取桌子对象int ** CTable::GetBoard(void){return m_board;}//获取数据信息int CTable::GetData(int x, int y){return m_board[y][x];}//蛇的操作void CTable::SnakeMove(void){m_snake.Move();}bool CTable::ChangeSnakeDirect(MoveState d){m_snake.ChangeDirect(d);return true;}#ifndef __TABLE_H_H#define __TABLE_H_H#define TB_STATE_OK 0 //正常#define TB_STATE_FOOD 1 //食物#define TB_STATE_BLOCK 2 //障碍-毒果#define TB_STATE_SBLOCK 3 //障碍-墙#include "snake.h"class CTable{private:int m_width;//桌子的宽度int m_height;//桌子的宽度int m_foodNumber;//桌子上食物的数量int m_blockNumber;//毒果的数量CSnake m_snake;//桌上的蛇int ** m_board;//桌的面板public:CTable();~CTable();//初始化面板void InitialTable(int w,int h);//食物的操作bool AddBlock(int x, int y);bool AddFood(int x, int y);bool ClearFood(int x, int y);//物件获取CSnake * GetSnake(void);int ** GetBoard(void);int GetData(int x, int y);//蛇的操作void SnakeMove(void);bool ChangeSnakeDirect(MoveState d); };#endif。
贪吃蛇游戏实现思路及源代码HTML5 贪吃蛇游戏实现思路及源代码点评:游戏难点是怎么模拟贪吃蛇的移动。
如果只是一个方块的话显然很简单。
但是当蛇的长度变长之后要怎么样控制,下面为大家简要介绍下具体的实现,感兴趣的朋友可以参考下,希望对大家有所帮助游戏操作说明通过方向键控制贪吃蛇上下左右移动。
贪吃蛇吃到食物之后会变长一个长度。
游戏具体实现游戏难点是怎么模拟贪吃蛇的移动。
如果只是一个方块的话显然很简单。
但是当蛇的长度变长之后要怎么样控制每个方块的移动呢?如果观察蛇的移动,可以发现,从蛇的头部到尾部,每个方块在下一时刻的位置就是它的前一个方块在当前时刻的位置。
因此我们需要做的只是控制贪吃蛇的头部的运动。
其他部分的位置都可以依次类推。
另外一个值得注意的问题是贪吃蛇吃下食物之后,新增加的方块应该放在哪个位置。
答案就是在下一时刻,新增加的方块应该出现在当前时刻的尾部位置。
因此,在吃下食物之后应该在更新蛇的每个位置之前,增加一个方块,并且将其位置设定在当前时刻的尾部位置。
然后在当前时刻更新出了新增方块之外的所有方块的位置index.htmlsnake.js复制代码代码如下:var canvas;var ctx;var timer;//measuresvar x_cnt = 15;var y_cnt = 15;var unit = 48;var box_x = 0;var box_y = 0;var box_width = 15 * unit;var box_height = 15 * unit;var bound_left = box_x;var bound_right = box_x + box_width;var bound_up = box_y;var bound_down = box_y + box_height;//imagesvar image_sprite;//objectsvar snake;var food;var food_x;var food_y;//functionsfunction Role(sx, sy, sw, sh, direction, status, speed, image, flag) {this.x = sx;this.y = sy;this.w = sw;this.h = sh;this.direction = direction;this.status = status;this.speed = speed;this.image = image;this.flag = flag;}function transfer(keyCode){switch (keyCode){case 37:return 1;case 38:return 3;case 39:return 2;case 40:return 0;}}function addFood(){//food_x=box_x+Math.floor(Math.random()*(box_width-unit));//food_y=box_y+Math.floor(Math.random()*(box_height-unit));food_x = unit * Math.floor(Math.random() * x_cnt);food_y = unit * Math.floor(Math.random() * y_cnt);food = new Role(food_x, food_y, unit, unit, 0, 0, 0, image_sprite, true);}function play(event){var keyCode;if (event == null){keyCode = window.event.keyCode;window.event.preventDefault();}else{keyCode = event.keyCode;event.preventDefault();}var cur_direction = transfer(keyCode);snake[0].direction = cur_direction;}function update(){//add a new part to the snake before move the snakeif (snake[0].x == food.x && snake[0].y == food.y){var length = snake.length;var tail_x = snake[length - 1].x;var tail_y = snake[length - 1].y;var tail = new Role(tail_x, tail_y, unit, unit, snake[length - 1].direction, 0, 0, image_sprite, true); snake.push(tail);addFood();}//modify attributes//move the headswitch (snake[0].direction){case 0: //downsnake[0].y += unit;if (snake[0].y > bound_down - unit) snake[0].y = bound_down - unit; break;case 1: //leftsnake[0].x -= unit;if (snake[0].x < bound_left)snake[0].x = bound_left;break;case 2: //rightsnake[0].x += unit;if (snake[0].x > bound_right - unit) snake[0].x = bound_right - unit; break;case 3: //upsnake[0].y -= unit;if (snake[0].y < bound_up)snake[0].y = bound_up;break;}//move other part of the snakefor (var i = snake.length - 1; i >= 0; i--) {if (i > 0)//snake[i].direction=snake[i-1].direction; {snake[i].x = snake[i - 1].x;snake[i].y = snake[i - 1].y;}}}function drawScene(){ctx.clearRect(box_x, box_y, box_width, box_height); ctx.strokeStyle = "rgb(0,0,0";ctx.strokeRect(box_x, box_y, box_width, box_height); //detection collisions//draw imagesfor (var i = 0; i < snake.length; i++){ctx.drawImage(image_sprite, snake[i].x, snake[i].y); }ctx.drawImage(image_sprite, food.x, food.y);}function init(){canvas = document.getElementById("scene");ctx = canvas.getContext('2d');//imagesimage_sprite = new Image();image_sprite.src = "images/sprite.png";image_sprite.onLoad = function (){}//ojectssnake = new Array();var head = new Role(0 * unit, 0 * unit, unit, unit, 5, 0, 1, image_sprite, true); snake.push(head);window.addEventListener('keydown', play, false);addFood();setInterval(update, 300); //notesetInterval(drawScene, 30); }。
学习H5开发怎能不会Canvas ! Canvas顾名思义是定义在浏览器上画布,但Canvas不仅仅是一个元素,它更是一套编程的接口,它的出现已然超过了Web 基于文档的设计初衷。
利用它你可以开发出很多梦寐以求的内容,让编程工作者彻底释放自己的创造力!
公开课QQ群:149135489
这款html5“贪食蛇”游戏适合刚入手游戏开发的同学,或是想学习html5 API 的同学。
本课程将带领你玩转Canvas,通过一个清新美好的小游戏,帮助你熟悉游戏开发流程。
听起来有点儿小激动呢!!!
本课程主要内容包括游戏逻辑分析、JS面向对象编程实战运用、游戏代码实现及优化,每个步骤都带领大家进行代码断点演示。
<head><title>使用表格</title></head><script language="JavaScript">var fangxiang;fangxiang=4;var sk=new Array(18);sk[0]="5,5";sk[1]="5,4";sk[2]="5,3";var long=3;var zhanshichunweiba;var shiwu="15,15";var shudu=250;var movedong=true;var shifouchongzhi=true;function keydown(){if(event.keyCode==38){if(fangxiang!=2)fangxiang=1;if(fangxiang==2)fangxiang=2;}if(event.keyCode==40){if(fangxiang!=1)fangxiang=2;if(fangxiang==1)fangxiang=1;}if(event.keyCode==37){if(fangxiang!=4)fangxiang=3;if(fangxiang==4)fangxiang=4;}if(event.keyCode==39){if(fangxiang!=3)fangxiang=4;if(fangxiang==3)fangxiang=3;}}function kaishi(){if(shifouchongzhi){shifouchongzhi=false;document.getElementById(sk[0]).style.backgroundColor = "red";document.getElementById(sk[1]).style.backgroundColor = "red";document.getElementById(sk[2]).style.backgroundColor = "red";document.getElementById(shiwu).style.backgroundColor = "blue";move();}alert("你要先重置");}function chongzhi(){shifouchongzhi=true;shiwu="15,15";shudu=250;fangxiang=4;sk[0]="5,5";sk[1]="5,4";sk[2]="5,3";long=3;var m=document.getElementsByTagName("td");for(var n=0;n<400;n++){m[n].style.backgroundColor = "yellow";}movedong=true;}function dong(){zhanshichunweiba=sk[long-1];for(var m=long-1;m>0;m--){sk[m]=sk[m-1]}var i=sk[0].split(',');if(fangxiang==1){i[0]--;sk[0]=i[0]+','+i[1]}if(fangxiang==2){i[0]++;sk[0]=i[0]+','+i[1]}if(fangxiang==3){i[1]--;sk[0]=i[0]+','+i[1]}if(fangxiang==4){i[1]++;sk[0]=i[0]+','+i[1]}}function zhenchanshengshiwu(){var x;var y;x=Math.round(Math.random()*19);y=Math.round(Math.random()*19);shiwu=x+','+y;chanshengshiwu();}function chanshengshiwu(){for(var m=0;m<long;m++)if(shiwu==sk[m]){zhenchanshengshiwu();}document.getElementById(shiwu).style.backgroundColor = "blue"; }function chishiwu(){if(shiwu==sk[0]){long++;sk[long-1]=zhanshichunweiba;document.getElementById(sk[long-1]).style.backgroundColor = "red";chanshengshiwu();}}function jieshujiashu(){var i=sk[0].split(',');if(i[0]<0||i[0]>19||i[1]<0||i[1]>19){alert("你死求");movedong=false;}if(long>=6){shudu=200;}if(long>=9){shudu=150;}if(long>=12){shudu=100;}if(long>=15){shudu=80;}if(long>=18){shudu=50;}if(long>=25){alert("你真NB 你赢了");chongzhi();movedong=false;}}function move(){dong();jieshujiashu();for(var m=0;m<long;m++){document.getElementById(sk[m]).style.backgroundColor = "red";}document.getElementById(zhanshichunweiba).style.backgroundColor = "yellow";chishiwu();if(movedong)setTimeout("move()",shudu);}</script><body onkeydown="keydown()"><input type="button" width="80" value="开始" onclick="kaishi();"> <input type="button" width="80" value="重置" onclick="chongzhi()"> <table border ="0" cellspacing="0" id="quanbu"><tr><td id="0,0" bgcolor="yellow" width="20" height="20"> </td><td id="0,1" bgcolor="yellow" width="20" height="20"> </td><td id="0,2" bgcolor="yellow" width="20" height="20"> </td><td id="0,3" bgcolor="yellow" width="20" height="20"> </td><td id="0,4" bgcolor="yellow" width="20" height="20"> </td><td id="0,5" bgcolor="yellow" width="20" height="20"> </td><td id="0,6" bgcolor="yellow" width="20" height="20"> </td><td id="0,7" bgcolor="yellow" width="20" height="20"> </td><td id="0,8" bgcolor="yellow" width="20" height="20"> </td><td id="0,9" bgcolor="yellow" width="20" height="20"> </td><td id="0,10" bgcolor="yellow" width="20" height="20"> </td><td id="0,11" bgcolor="yellow" width="20" height="20"> </td><td id="0,12" bgcolor="yellow" width="20" height="20"> </td><td id="0,13" bgcolor="yellow" width="20" height="20"> </td><td id="0,14" bgcolor="yellow" width="20" height="20"> </td><td id="0,15" bgcolor="yellow" width="20" height="20"> </td><td id="0,16" bgcolor="yellow" width="20" height="20"> </td><td id="0,17" bgcolor="yellow" width="20" height="20"> </td><td id="0,18" bgcolor="yellow" width="20" height="20"> </td><td id="0,19" bgcolor="yellow" width="20" height="20"> </td></tr><tr><td id="1,0" bgcolor="yellow" width="20" height="20"> </td><td id="1,1" bgcolor="yellow" width="20" height="20"> </td><td id="1,2" bgcolor="yellow" width="20" height="20"> </td><td id="1,3" bgcolor="yellow" width="20" height="20"> </td><td id="1,4" bgcolor="yellow" width="20" height="20"> </td><td id="1,5" bgcolor="yellow" width="20" height="20"> </td><td id="1,6" bgcolor="yellow" width="20" height="20"> </td><td id="1,7" bgcolor="yellow" width="20" height="20"> </td><td id="1,8" bgcolor="yellow" width="20" height="20"> </td><td id="1,9" bgcolor="yellow" width="20" height="20"> </td><td id="1,10" bgcolor="yellow" width="20" height="20"> </td><td id="1,12" bgcolor="yellow" width="20" height="20"> </td> <td id="1,13" bgcolor="yellow" width="20" height="20"> </td> <td id="1,14" bgcolor="yellow" width="20" height="20"> </td> <td id="1,15" bgcolor="yellow" width="20" height="20"> </td> <td id="1,16" bgcolor="yellow" width="20" height="20"> </td> <td id="1,17" bgcolor="yellow" width="20" height="20"> </td> <td id="1,18" bgcolor="yellow" width="20" height="20"> </td> <td id="1,19" bgcolor="yellow" width="20" height="20"> </td> </tr><tr><td id="2,0" bgcolor="yellow" width="20" height="20"> </td> <td id="2,1" bgcolor="yellow" width="20" height="20"> </td> <td id="2,2" bgcolor="yellow" width="20" height="20"> </td> <td id="2,3" bgcolor="yellow" width="20" height="20"> </td> <td id="2,4" bgcolor="yellow" width="20" height="20"> </td> <td id="2,5" bgcolor="yellow" width="20" height="20"> </td> <td id="2,6" bgcolor="yellow" width="20" height="20"> </td> <td id="2,7" bgcolor="yellow" width="20" height="20"> </td> <td id="2,8" bgcolor="yellow" width="20" height="20"> </td> <td id="2,9" bgcolor="yellow" width="20" height="20"> </td> <td id="2,10" bgcolor="yellow" width="20" height="20"> </td> <td id="2,11" bgcolor="yellow" width="20" height="20"> </td> <td id="2,12" bgcolor="yellow" width="20" height="20"> </td> <td id="2,13" bgcolor="yellow" width="20" height="20"> </td> <td id="2,14" bgcolor="yellow" width="20" height="20"> </td> <td id="2,15" bgcolor="yellow" width="20" height="20"> </td> <td id="2,16" bgcolor="yellow" width="20" height="20"> </td> <td id="2,17" bgcolor="yellow" width="20" height="20"> </td> <td id="2,18" bgcolor="yellow" width="20" height="20"> </td> <td id="2,19" bgcolor="yellow" width="20" height="20"> </td> </tr><tr><td id="3,0" bgcolor="yellow" width="20" height="20"> </td> <td id="3,1" bgcolor="yellow" width="20" height="20"> </td> <td id="3,2" bgcolor="yellow" width="20" height="20"> </td> <td id="3,3" bgcolor="yellow" width="20" height="20"> </td> <td id="3,4" bgcolor="yellow" width="20" height="20"> </td> <td id="3,5" bgcolor="yellow" width="20" height="20"> </td> <td id="3,6" bgcolor="yellow" width="20" height="20"> </td> <td id="3,7" bgcolor="yellow" width="20" height="20"> </td> <td id="3,8" bgcolor="yellow" width="20" height="20"> </td> <td id="3,9" bgcolor="yellow" width="20" height="20"> </td> <td id="3,10" bgcolor="yellow" width="20" height="20"> </td><td id="3,12" bgcolor="yellow" width="20" height="20"> </td> <td id="3,13" bgcolor="yellow" width="20" height="20"> </td> <td id="3,14" bgcolor="yellow" width="20" height="20"> </td> <td id="3,15" bgcolor="yellow" width="20" height="20"> </td> <td id="3,16" bgcolor="yellow" width="20" height="20"> </td> <td id="3,17" bgcolor="yellow" width="20" height="20"> </td> <td id="3,18" bgcolor="yellow" width="20" height="20"> </td> <td id="3,19" bgcolor="yellow" width="20" height="20"> </td> </tr><tr><td id="4,0" bgcolor="yellow" width="20" height="20"> </td> <td id="4,1" bgcolor="yellow" width="20" height="20"> </td> <td id="4,2" bgcolor="yellow" width="20" height="20"> </td> <td id="4,3" bgcolor="yellow" width="20" height="20"> </td> <td id="4,4" bgcolor="yellow" width="20" height="20"> </td> <td id="4,5" bgcolor="yellow" width="20" height="20"> </td> <td id="4,6" bgcolor="yellow" width="20" height="20"> </td> <td id="4,7" bgcolor="yellow" width="20" height="20"> </td> <td id="4,8" bgcolor="yellow" width="20" height="20"> </td> <td id="4,9" bgcolor="yellow" width="20" height="20"> </td> <td id="4,10" bgcolor="yellow" width="20" height="20"> </td> <td id="4,11" bgcolor="yellow" width="20" height="20"> </td> <td id="4,12" bgcolor="yellow" width="20" height="20"> </td> <td id="4,13" bgcolor="yellow" width="20" height="20"> </td> <td id="4,14" bgcolor="yellow" width="20" height="20"> </td> <td id="4,15" bgcolor="yellow" width="20" height="20"> </td> <td id="4,16" bgcolor="yellow" width="20" height="20"> </td> <td id="4,17" bgcolor="yellow" width="20" height="20"> </td> <td id="4,18" bgcolor="yellow" width="20" height="20"> </td> <td id="4,19" bgcolor="yellow" width="20" height="20"> </td> </tr><tr><td id="5,0" bgcolor="yellow" width="20" height="20"> </td> <td id="5,1" bgcolor="yellow" width="20" height="20"> </td> <td id="5,2" bgcolor="yellow" width="20" height="20"> </td> <td id="5,3" bgcolor="yellow" width="20" height="20"> </td> <td id="5,4" bgcolor="yellow" width="20" height="20"> </td> <td id="5,5" bgcolor="yellow" width="20" height="20"> </td> <td id="5,6" bgcolor="yellow" width="20" height="20"> </td> <td id="5,7" bgcolor="yellow" width="20" height="20"> </td> <td id="5,8" bgcolor="yellow" width="20" height="20"> </td> <td id="5,9" bgcolor="yellow" width="20" height="20"> </td> <td id="5,10" bgcolor="yellow" width="20" height="20"> </td><td id="5,12" bgcolor="yellow" width="20" height="20"> </td> <td id="5,13" bgcolor="yellow" width="20" height="20"> </td> <td id="5,14" bgcolor="yellow" width="20" height="20"> </td> <td id="5,15" bgcolor="yellow" width="20" height="20"> </td> <td id="5,16" bgcolor="yellow" width="20" height="20"> </td> <td id="5,17" bgcolor="yellow" width="20" height="20"> </td> <td id="5,18" bgcolor="yellow" width="20" height="20"> </td> <td id="5,19" bgcolor="yellow" width="20" height="20"> </td> </tr><tr><td id="6,0" bgcolor="yellow" width="20" height="20"> </td> <td id="6,1" bgcolor="yellow" width="20" height="20"> </td> <td id="6,2" bgcolor="yellow" width="20" height="20"> </td> <td id="6,3" bgcolor="yellow" width="20" height="20"> </td> <td id="6,4" bgcolor="yellow" width="20" height="20"> </td> <td id="6,5" bgcolor="yellow" width="20" height="20"> </td> <td id="6,6" bgcolor="yellow" width="20" height="20"> </td> <td id="6,7" bgcolor="yellow" width="20" height="20"> </td> <td id="6,8" bgcolor="yellow" width="20" height="20"> </td> <td id="6,9" bgcolor="yellow" width="20" height="20"> </td> <td id="6,10" bgcolor="yellow" width="20" height="20"> </td> <td id="6,11" bgcolor="yellow" width="20" height="20"> </td> <td id="6,12" bgcolor="yellow" width="20" height="20"> </td> <td id="6,13" bgcolor="yellow" width="20" height="20"> </td> <td id="6,14" bgcolor="yellow" width="20" height="20"> </td> <td id="6,15" bgcolor="yellow" width="20" height="20"> </td> <td id="6,16" bgcolor="yellow" width="20" height="20"> </td> <td id="6,17" bgcolor="yellow" width="20" height="20"> </td> <td id="6,18" bgcolor="yellow" width="20" height="20"> </td> <td id="6,19" bgcolor="yellow" width="20" height="20"> </td> </tr><tr><td id="7,0" bgcolor="yellow" width="20" height="20"> </td> <td id="7,1" bgcolor="yellow" width="20" height="20"> </td> <td id="7,2" bgcolor="yellow" width="20" height="20"> </td> <td id="7,3" bgcolor="yellow" width="20" height="20"> </td> <td id="7,4" bgcolor="yellow" width="20" height="20"> </td> <td id="7,5" bgcolor="yellow" width="20" height="20"> </td> <td id="7,6" bgcolor="yellow" width="20" height="20"> </td> <td id="7,7" bgcolor="yellow" width="20" height="20"> </td> <td id="7,8" bgcolor="yellow" width="20" height="20"> </td> <td id="7,9" bgcolor="yellow" width="20" height="20"> </td> <td id="7,10" bgcolor="yellow" width="20" height="20"> </td><td id="7,12" bgcolor="yellow" width="20" height="20"> </td> <td id="7,13" bgcolor="yellow" width="20" height="20"> </td> <td id="7,14" bgcolor="yellow" width="20" height="20"> </td> <td id="7,15" bgcolor="yellow" width="20" height="20"> </td> <td id="7,16" bgcolor="yellow" width="20" height="20"> </td> <td id="7,17" bgcolor="yellow" width="20" height="20"> </td> <td id="7,18" bgcolor="yellow" width="20" height="20"> </td> <td id="7,19" bgcolor="yellow" width="20" height="20"> </td> </tr><tr><td id="8,0" bgcolor="yellow" width="20" height="20"> </td> <td id="8,1" bgcolor="yellow" width="20" height="20"> </td> <td id="8,2" bgcolor="yellow" width="20" height="20"> </td> <td id="8,3" bgcolor="yellow" width="20" height="20"> </td> <td id="8,4" bgcolor="yellow" width="20" height="20"> </td> <td id="8,5" bgcolor="yellow" width="20" height="20"> </td> <td id="8,6" bgcolor="yellow" width="20" height="20"> </td> <td id="8,7" bgcolor="yellow" width="20" height="20"> </td> <td id="8,8" bgcolor="yellow" width="20" height="20"> </td> <td id="8,9" bgcolor="yellow" width="20" height="20"> </td> <td id="8,10" bgcolor="yellow" width="20" height="20"> </td> <td id="8,11" bgcolor="yellow" width="20" height="20"> </td> <td id="8,12" bgcolor="yellow" width="20" height="20"> </td> <td id="8,13" bgcolor="yellow" width="20" height="20"> </td> <td id="8,14" bgcolor="yellow" width="20" height="20"> </td> <td id="8,15" bgcolor="yellow" width="20" height="20"> </td> <td id="8,16" bgcolor="yellow" width="20" height="20"> </td> <td id="8,17" bgcolor="yellow" width="20" height="20"> </td> <td id="8,18" bgcolor="yellow" width="20" height="20"> </td> <td id="8,19" bgcolor="yellow" width="20" height="20"> </td> </tr><tr><td id="9,0" bgcolor="yellow" width="20" height="20"> </td> <td id="9,1" bgcolor="yellow" width="20" height="20"> </td> <td id="9,2" bgcolor="yellow" width="20" height="20"> </td> <td id="9,3" bgcolor="yellow" width="20" height="20"> </td> <td id="9,4" bgcolor="yellow" width="20" height="20"> </td> <td id="9,5" bgcolor="yellow" width="20" height="20"> </td> <td id="9,6" bgcolor="yellow" width="20" height="20"> </td> <td id="9,7" bgcolor="yellow" width="20" height="20"> </td> <td id="9,8" bgcolor="yellow" width="20" height="20"> </td> <td id="9,9" bgcolor="yellow" width="20" height="20"> </td> <td id="9,10" bgcolor="yellow" width="20" height="20"> </td><td id="9,12" bgcolor="yellow" width="20" height="20"> </td> <td id="9,13" bgcolor="yellow" width="20" height="20"> </td> <td id="9,14" bgcolor="yellow" width="20" height="20"> </td> <td id="9,15" bgcolor="yellow" width="20" height="20"> </td> <td id="9,16" bgcolor="yellow" width="20" height="20"> </td> <td id="9,17" bgcolor="yellow" width="20" height="20"> </td> <td id="9,18" bgcolor="yellow" width="20" height="20"> </td> <td id="9,19" bgcolor="yellow" width="20" height="20"> </td> </tr><tr><td id="10,0" bgcolor="yellow" width="20" height="20"> </td> <td id="10,1" bgcolor="yellow" width="20" height="20"> </td> <td id="10,2" bgcolor="yellow" width="20" height="20"> </td> <td id="10,3" bgcolor="yellow" width="20" height="20"> </td> <td id="10,4" bgcolor="yellow" width="20" height="20"> </td> <td id="10,5" bgcolor="yellow" width="20" height="20"> </td> <td id="10,6" bgcolor="yellow" width="20" height="20"> </td> <td id="10,7" bgcolor="yellow" width="20" height="20"> </td> <td id="10,8" bgcolor="yellow" width="20" height="20"> </td> <td id="10,9" bgcolor="yellow" width="20" height="20"> </td> <td id="10,10" bgcolor="yellow" width="20" height="20"> </td> <td id="10,11" bgcolor="yellow" width="20" height="20"> </td> <td id="10,12" bgcolor="yellow" width="20" height="20"> </td> <td id="10,13" bgcolor="yellow" width="20" height="20"> </td> <td id="10,14" bgcolor="yellow" width="20" height="20"> </td> <td id="10,15" bgcolor="yellow" width="20" height="20"> </td> <td id="10,16" bgcolor="yellow" width="20" height="20"> </td> <td id="10,17" bgcolor="yellow" width="20" height="20"> </td> <td id="10,18" bgcolor="yellow" width="20" height="20"> </td> <td id="10,19" bgcolor="yellow" width="20" height="20"> </td> </tr><tr><td id="11,0" bgcolor="yellow" width="20" height="20"> </td> <td id="11,1" bgcolor="yellow" width="20" height="20"> </td> <td id="11,2" bgcolor="yellow" width="20" height="20"> </td> <td id="11,3" bgcolor="yellow" width="20" height="20"> </td> <td id="11,4" bgcolor="yellow" width="20" height="20"> </td> <td id="11,5" bgcolor="yellow" width="20" height="20"> </td> <td id="11,6" bgcolor="yellow" width="20" height="20"> </td> <td id="11,7" bgcolor="yellow" width="20" height="20"> </td> <td id="11,8" bgcolor="yellow" width="20" height="20"> </td> <td id="11,9" bgcolor="yellow" width="20" height="20"> </td> <td id="11,10" bgcolor="yellow" width="20" height="20"> </td>。
html+css+JavaScript贪吃蛇写⽂记录⼀下最近新完成的贪吃蛇游戏案例,⽤到了html、css和JavaScript,难度不⾼,适合刚⼊坑的同学练习,欢迎⼤家交流。
下⾯贴源码:1<!DOCTYPE html>2<html>3<head>4<meta charset="UTF-8">5<title>贪吃蛇游戏界⾯</title>6<style>8 font-family: "微软雅⿊";9 }1011 #map{12 width: 600px;13 height: 600px;14 background: cadetblue;15 position: absolute;16 left: 10px;17 top: 60px;18 overflow: hidden;19 }2021 input{22 padding: 10px;23 background: black;24 color: #ffffff;25 }26</style>27</head>28<!--捕获键盘按键-->29<body onkeydown="control(event);">30<div class="top">31<input type="button" value="开始游戏" id="start_btn" onclick="start();test(this)"/> 3233<span>得分:</span><span id="score"></span>34</div>35<div id="map"></div>363738<script type="text/javascript">39var snake_left = Math.floor(Math.random() * 26) * 20; //游戏开始时,蛇的位置40var snake_top = Math.floor(Math.random() * 30) * 20;41var map = document.getElementById("map");42var snakes = [];//蛇的关节43var stepX = 20;44var stepY = 0;45var snake_direction="right";46var timer;4748//开始按钮点击⼀次后失效49function test(obj){5051 obj.disabled=true;52 obj.value="游戏开始中"53 }5455//点击“开始按钮” 开始游戏56//document.getElementById("start_btn").onclick = function (){57function start(){58//游戏开始,蛇头放到数组的第⼀项59for(var i = 2; i>=0;i--){60 drawSnake(i);61 }6263//蛇的移动64 snakeMove();6566//碰到墙壁死掉67 overDiv();6869//产⽣⾷物70 food();7172//吃掉⾷物73 eat();74 }7576//让蛇移动77function snakeMove(){7879//蛇尾的位置等于上⼀个80for(var i=snakes.length-1;i>0;i--){81 snakes[i].style.left = snakes[i-1].style.left;82 snakes[i].style.top = snakes[i-1].style.top;83 }8485//snakes数组的第零项是蛇头86 snakes[0].style.left = parseInt(snakes[0].style.left) + stepX +"px";87 snakes[0].style.top = parseInt(snakes[0].style.top) + stepY +"px";8889 timer = setTimeout("snakeMove()",400);90 }93function drawSnake(num){94var snakeNode = document.createElement("div");95 snakeNode.style.position = "absolute";96 snakeNode.style.top = "0px";97 snakeNode.style.left = num * 20+"px";98 snakeNode.style.background = "coral";99100//如果设置div边框 20*20 18*18 1101//snakeNode.style.border = "1px solid #333";102 snakeNode.style.width = "20px";103 snakeNode.style.height = "20px";104105 snakes.push(snakeNode);106107 map.appendChild(snakeNode);108109110 }111112function re_move(){113 clearTimeout(timer);114 snakeMove()115116 }117118//控制⽅向119function control(event){120var n = event.keyCode;121switch(n){122case 37:// 左蛇在向右跑的过程中按左是不起作⽤的123if(snake_direction=="right"){124break;125 }else{126 stepX = -20;127 stepY = 0;128 snake_direction="left";129 }130 re_move();131break;132133case 40://下蛇在向下跑的过程中按上是不起作⽤的134if(snake_direction=="up"){135break;136 }else{137 stepX = 0;138 stepY = 20;139 snake_direction="down";140 }141 re_move();142break;143144case 38:// 上蛇在向下跑的过程中按左是不起作⽤的145if(snake_direction=="down"){146break;147 }else{148 stepX = 0;149 stepY = -20;150 snake_direction="up";151 }152 re_move();153break;154155case 39://下蛇在向下跑的过程中按上是不起作⽤的156if(snake_direction=="left"){157break;158 }else{159 stepX = 20;160 stepY = 0;161 snake_direction="right";162 }163 re_move();164break;165166167168169 }170171 }172173//判断是否碰到墙壁174function overDiv(){177var score = document.getElementById("score");178 score.innerHTML = (snakes.length-3)*10;179180var x = parseInt(snakes[0].style.left); //snakes[0]代表蛇头181var y = parseInt(snakes[0].style.top);182183//判断是否碰到墙壁184if(x<0||x>580||y<0||y>580){185 alert("Game Over");186 window.location.reload();187 }188189//判断是否吃到⾃⼰190if(snakes.length > 4){191for(var i=3;i<snakes.length-1;i++){192var x1 = parseInt(snakes[i].style.left);193var y1 = parseInt(snakes[i].style.top);194195if(x==x1 && y==y1){196 alert("Game Over");197 window.location.reload();198 }199 }200 }201202 setTimeout("overDiv()",30);203 }204205//产⽣⾷物206function food(){207208var food_x = Math.floor(Math.random()*29+1)*20 + "px"; 209var food_y = Math.floor(Math.random()*29+1)*20 + "px"; 210//画出⾷物211var food_div = document.createElement("div");212213 food_div.style.position = "absolute";214 food_div.style.top = food_y;215 food_div.style.left = food_x;216217 food_div.style.backgroundColor = "orange";218//food_div.style.border = "1px solid #333";219 food_div.style.width = "20px";220 food_div.style.height = "20px";221222//给⾷物加id223 food_div.id = "i_food";224 map.appendChild(food_div);225226 }227228//吃掉⾷物229function eat(){230//得到蛇头坐标231var x1 = parseInt(snakes[0].style.left);232var y1 = parseInt(snakes[0].style.top);233234//得到⾷物坐标235var i_food = document.getElementById("i_food");236237var x2 = parseInt(i_food.style.left);238var y2 = parseInt(i_food.style.top);239240if(Math.abs(x1-x2)<20 && Math.abs(y1-y2)<20){241242 snakes.push(i_food);243 i_food.id = "";244245//⽣成⾷物246 food();247 }248249 setTimeout("eat()",30);250 }251</script>252</body>253</html>。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style type="text/css">
#myCanvas{
border:1px solid #f00;
}
</style>
</head>
<body>
<input type="button" value="开始游戏" onclick="beginGame();" /> <canvas id="myCanvas" width="450" height="450">
</canvas>
</body>
<script type="text/javascript">
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var w = 15;//格子宽、高
var snaLen = 6; //初始长度
var snake = []; //身体长度
for(var i = 0; i < snaLen; i++){
snake[i] = new cell(i , 0 , 39);
}
var head = snake[snaLen - 1]; //头部
//初始食物
var foodx = Math.ceil(Math.random() * 28 + 1);
var foody = Math.ceil(Math.random() * 28 + 1);
var food = new Food(foodx , foody);
//食物
function Food(x , y){
this.x = x;
this.y = y;
return this;
}
//身体
function cell(x , y , d){
this.x = x;
this.y = y;
this.d = d;
return this;
}
//动作
function draw(){
ctx.clearRect(0,0,450,450);
//画布局
// for(var i = 0; i < 30; i++){
// ctx.strokeStyle = "#ccc";//线条颜色// ctx.beginPath();
// ctx.moveTo(0,i*w);
// ctx.lineTo(450,i*w);
// ctx.moveTo(i*w,0);
// ctx.lineTo(i*w,450);
// ctx.closePath();
// ctx.stroke();
// }
//画蛇身
for(var j = 0; j < snake.length; j++){
ctx.fillStyle = "black";
if(j == snake.length - 1){
ctx.fillStyle = "red";
}
ctx.beginPath();
ctx.rect(snake[j].x*w , snake[j].y*w , w , w);
ctx.closePath();
ctx.fill();
ctx.stroke();
}
//出现食物
drawFood();
//吃到食物
if(head.x == food.x && head.y == food.y){
initFood();
food = new Food(foodx , foody);
//重新出现食物
drawFood();
//增加蛇的长度有些小瑕疵,蛇身增长时应该是身体增长,而不是在蛇头上增长
var newCell = new cell(head.x , head.y , head.d);
switch(head.d){
case 40 : newCell.y++ ; break;//下
case 39 : newCell.x++ ; break;//右
case 38 : newCell.y-- ; break;//上
case 37 : newCell.x-- ; break;//左
}
snake[snake.length] = newCell;
head = newCell;
//head =
}
}
//随机初始化食物
function initFood(){
foodx = Math.ceil(Math.random() * 28 + 1);
foody = Math.ceil(Math.random() * 28 + 1);
for(var i = 0; i < snake.length; i++){
if(snake[i].x == foodx && snake[i].y == foody){
initFood();
}
}
}
//画食物
function drawFood(){
//绘制食物
ctx.fillStyle = "blue";
ctx.beginPath();
ctx.rect(food.x * w , food.y * w , w , w);
ctx.closePath();
ctx.fill();
}
draw();
//监听键盘事件
document.onkeydown = function(e){
//下40 ,右边39,左边37,上38 键盘事件
var keyCode = e.keyCode;
if(head.d - keyCode != 2 && head.d - keyCode != -2 && keyCode >=37 && keyCode <=40){
moveSnake(keyCode);
}
}
//控制蛇移动方向
function moveSnake(keyCode){
var newSnake = [];
var newCell = new cell(head.x , head.y , head.d);//头
//身体
for(var i = 1; i < snake.length ; i++){
newSnake[i - 1] = snake[i];
}
newSnake[snake.length - 1] = newCell;
newCell.d = keyCode;
switch(keyCode){
case 40 : newCell.y++ ; break;//下
case 39 : newCell.x++ ; break;//右
case 38 : newCell.y-- ; break;//上
case 37 : newCell.x-- ; break;//左
}
snake = newSnake;
head = snake[snake.length - 1];
checkDeath();
draw();
}
//游戏规则
function checkDeath(){
//超出边框
if(head.x >= 30 || head.y>= 30 || head.x < 0 || head.y < 0){
alert("Game over!");
window.location.reload();
}
//咬到自己
for(var i = 0 ; i < snake.length - 1 ; i++){
if(head.x == snake[i].x && head.y == snake[i].y){
alert("Game over!");
window.location.reload();
}
}
}
//蛇自动走
function moveClock(){
moveSnake(head.d);
}
function beginGame(){
setInterval(moveClock,600);
}
</script>
</html>。