还记得诺基亚手机上贪吃蛇小游戏吗?

诺基亚手机上的经典游戏

1. 贪吃蛇
贪吃蛇

2. 跳跳球
跳跳球

3. 熊猫爬树
熊猫爬树
还有俄罗斯方块等经典游戏,我就不11介绍了,欢迎大家在评论区中写下自己童年记忆深刻的游戏吧,如果写下了,希望大家可以动手去找到相应的图片或视频保存收藏起来,如果评论还能发图片那就更好了。锻炼一下动手能力和体验一下百度搜资源多、杂,因此珍惜珍贵的资源(记忆)。也希望大家可以相互分享一下乐趣,资源,技巧,经验,让共享更方便。

真正的主题在这☺

JavaScript中Canvas实现贪吃蛇小游戏

两个链接介绍JavaScript和Canvas

JavaScript:https://baike.baidu.com/item/JavaScript/321142

Canvas:https://www.w3school.com.cn/jsref/dom_obj_canvas.asp

先看效果图
snake_gif
点击下载,双击用浏览器打开即可玩耍

主要JavaScript代码实现

//构造方块对象
    function Rect(x,y,w,h,color){
        this.x = x;
        this.y = y;
        this.w = w;
        this.h = h;
        this.color = color;
    }

    //画方块的方法
    Rect.prototype.draw = function(){
        context.beginPath();
        context.fillStyle= this.color;
        context.rect(this.x,this.y,this.w,this.h);
        context.fill();
        context.stroke();
    }

    //构造蛇对象
    function Snake(){

        //定义一个数组存放一整条蛇的方块对象
        var snakeArray = [];
        var start_num = 4;  //方块开始数量
        this.snake_head_color = snake_head_color;   //蛇头颜色
        this.rect_color = rect_color;    //方块颜色

        //生成4个灰色方块
        for(var i=0;i<start_num;i++){
            var rect = new Rect(i*20,0,20,20,this.rect_color);
            snakeArray.splice(0,0,rect);
        }

        var head = snakeArray[0];
        head.color = this.snake_head_color;

        this.head = snakeArray[0];
        this.snakeArray = snakeArray;

        //给定初始位置向右(keyCode右箭头)
        this.direction = 39;
    }

    //画蛇的方法
    Snake.prototype.draw = function (){
        for(var i=0;i<this.snakeArray.length;i++){
            this.snakeArray[i].draw();
        }
    }

    //蛇移动的方法(重点)
    Snake.prototype.move = function(){
        //1、画一个方块位置与蛇头重叠
        //2、将这个方块插入蛇头后面一个的位置
        //3、然后将最后一个方块删除即可
        //4、将蛇头向指定的方向移动一格

        var rect = new Rect(this.head.x,this.head.y,this.head.w,this.head.h,this.rect_color);
        this.snakeArray.splice(1,0,rect);

        //判断是否吃到食物
        if(isEat()){
            score +=score_increment;
            total_score.innerText = score;
            food = new getRandomFood();
        }else{
            this.snakeArray.pop();
        }

        //设置蛇头的运动方向,37、A(65)左,38、W(87)上,39、D(68)右,40、S(83)下
        if(this.direction==37||this.direction==65){ //左
            this.head.x -= this.head.w;
        }else if(this.direction==38||this.direction==87){//上
            this.head.y -= this.head.h;
        }else if(this.direction==39||this.direction==68){//右
            this.head.x += this.head.w;
        }else if(this.direction==40||this.direction==83){//下
            this.head.y += this.head.h;
        }

        //GameOver判定
        //撞墙
        if(this.head.x+1 >mCanvas.width || this.head.x<0 || this.head.y+1>mCanvas.height || this.head.y<0){

            //判定是否无墙模式
            if(hasWall){
                if(this.head.x > mCanvas.width){
                    this.head.x = 0;
                }

                if(this.head.x < 0){
                    this.head.x = mCanvas.width;
                }

                if(this.head.y > mCanvas.height){
                    this.head.y = 0;
                }

                if(this.head.y < 0 ){
                    this.head.y = mCanvas.height;
                }
            }else{
                closeInterval();    //关闭定时器
                setTimeout(function(){
                    //location.reload();
                    game_over();    //游戏结束
                },1500);
            }


        }

        //撞自己
        for(var i=1;i<this.snakeArray.length;i++){
            if(this.snakeArray[i].x == this.head.x && this.snakeArray[i].y == this.head.y){
                closeInterval();
                setTimeout(function(){
                    //location.reload();
                    game_over();
                },1500);
            }
        }
    }

    //画出初始的蛇
    var snake = new Snake();
    snake.draw();
    snake_length.innerText = snake.snakeArray.length;

    //画出初始的食物
    var food = new getRandomFood();

    var timer = null;
     //开启定时器
    function startInterval(){
            if(timer==null){
                timer = setInterval(function (){
                    context.clearRect(0,0,mCanvas.width,mCanvas.height);
                    food.draw();
                    snake.move();
                    snake.draw();
                    snake_length.innerText = snake.snakeArray.length;
                },movement);
            }
    }

JavaScript中Array数组对象的splice()pop()方法

splice()函数用于插入、删除或替换数组的元素。
从当前数组中移除一部分连续的元素。如有必要,还可以在所移除元素的位置上插入一个或多个新的元素。该函数以数组形式返回从当前数组中被移除的元素。

详情教程请看:
https://www.w3cschool.cn/jsref/jsref-splice.html
https://codeplayer.vip/p/j7sh3

pop() 方法用于删除数组的最后一个元素并返回删除的元素。
详情教程请看:https://www.w3cschool.cn/jsref/jsref-pop.html
注意:这种两种方法都会改变原始数组!

大概熟悉

  1. 封装蛇、食物函数
  2. 蛇移动move()判断(重点)
    -[吃到食物,加入蛇数组,再随机产生食物]
    -[判断游戏结束,撞墙,碰撞身体]
  3. 画出初始蛇,方块食物,开启定时器setInterval()
  4. 全局键盘监听document.onkeydown = function(e){...}
    -[W、A、S、D、 ← ↑ ↓ →箭头控制方向键]
    -[蛇方向为右,向左无效,方向上,向下无效类推… ]
    -[enter开始游戏、空格暂停游戏]

源码:https://gitee.com/huiDBK/SnakeGame.git

目前已知Bug,有时候可以蛇身体沿着墙走(进去了),可能因为撞墙判断写的不够严谨,或者方块大小的和canvas大小有冲突,没有形成倍数,还望大神指点迷津
honeybeeshoneybeeshoneybeeshoneybeeshoneybeeshoneybees

  • 9
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
当然可以!以下是一个简单的贪吃蛇游戏的 C 代码,注释详细: ```c #include <stdio.h> #include <stdlib.h> #include <conio.h> #include <windows.h> // 定义常量 #define WIDTH 20 #define HEIGHT 20 #define SNAKE_LENGTH 100 // 定义全局变量 int score = 0; // 得分 int speed = 100; // 速度 int snake_length = 3; // 蛇的长度 int snake_x[SNAKE_LENGTH], snake_y[SNAKE_LENGTH]; // 蛇的坐标 int food_x, food_y; // 食物的坐标 int direction = 1; // 蛇的方向,1:向右,2:向下,3:向左,4:向上 // 初始化游戏 void init_game() { // 初始化蛇的位置 snake_x[0] = 2; snake_y[0] = 2; snake_x[1] = 1; snake_y[1] = 2; snake_x[2] = 0; snake_y[2] = 2; // 随机生成食物的位置 srand((unsigned)time(NULL)); food_x = rand() % WIDTH; food_y = rand() % HEIGHT; } // 显示游戏界面 void show_game() { system("cls"); // 清屏 // 显示边框 for (int i = 0; i < WIDTH + 2; i++) { printf("#"); } printf("\n"); // 显示游戏区域 for (int i = 0; i < HEIGHT; i++) { printf("#"); for (int j = 0; j < WIDTH; j++) { if (i == snake_y[0] && j == snake_x[0]) { // 蛇头 printf("O"); } else if (i == food_y && j == food_x) { // 食物 printf("X"); } else { int is_body = 0; for (int k = 1; k < snake_length; k++) { if (i == snake_y[k] && j == snake_x[k]) { // 蛇身 printf("o"); is_body = 1; break; } } if (!is_body) { printf(" "); } } } printf("#\n"); } // 显示边框 for (int i = 0; i < WIDTH + 2; i++) { printf("#"); } printf("\n"); // 显示得分和速度 printf("Score: %d\n", score); printf("Speed: %d\n", speed); } // 处理键盘输入 void handle_input() { if (_kbhit()) { // 判断是否有键盘输入 char ch = _getch(); // 获取键盘输入 switch (ch) { case 'w': if (direction != 2) { // 防止蛇倒退 direction = 4; } break; case 's': if (direction != 4) { direction = 2; } break; case 'a': if (direction != 1) { direction = 3; } break; case 'd': if (direction != 3) { direction = 1; } break; } } } // 移动蛇 void move_snake() { // 记录蛇尾的位置 int tail_x = snake_x[snake_length - 1]; int tail_y = snake_y[snake_length - 1]; // 移动蛇的身体 for (int i = snake_length - 1; i > 0; i--) { snake_x[i] = snake_x[i - 1]; snake_y[i] = snake_y[i - 1]; } // 移动蛇的头部 switch (direction) { case 1: snake_x[0]++; break; case 2: snake_y[0]++; break; case 3: snake_x[0]--; break; case 4: snake_y[0]--; break; } // 判断是否吃到食物 if (snake_x[0] == food_x && snake_y[0] == food_y) { score += 10; // 得分加10 speed -= 5; // 速度加快 snake_length++; // 蛇的长度加1 food_x = rand() % WIDTH; // 随机生成新的食物位置 food_y = rand() % HEIGHT; } // 判断是否撞墙或撞到自己 if (snake_x[0] < 0 || snake_x[0] >= WIDTH || snake_y[0] < 0 || snake_y[0] >= HEIGHT) { printf("Game Over!\n"); exit(0); } for (int i = 1; i < snake_length; i++) { if (snake_x[0] == snake_x[i] && snake_y[0] == snake_y[i]) { printf("Game Over!\n"); exit(0); } } // 如果没有吃到食物,则删除蛇尾 snake_x[snake_length - 1] = tail_x; snake_y[snake_length - 1] = tail_y; } int main() { init_game(); // 初始化游戏 while (1) { show_game(); // 显示游戏界面 handle_input(); // 处理键盘输入 move_snake(); // 移动蛇 Sleep(speed); // 等待一段时间,控制游戏速度 } return 0; } ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值