H5+js实现别踩白块儿


项目地址 -> 已上传github

项目演示地址

  • 先画ui界面
function draw_line() {
    ctx.strokeStyle = 'black'
    for (var i = w; i < canvas.height; i += w) {
        ctx.moveTo(0, i)
        ctx.lineTo(canvas.width, i)
        ctx.stroke()
    }
    for (var i = w; i < canvas.width; i += w) {
        ctx.moveTo(i, 0)
        ctx.lineTo(i, canvas.height)
        ctx.stroke()
    }
    // 将第一个画布作为参数给画下来,画布的起始坐标和宽高和第一个画布大小一致。
    ctx2.drawImage(canvas, 0, 0, canvas.width, canvas.height)
}

首先先确定一件事,我们这个并不是一个canvas完成的,因为我们在黑块儿移动的时候,背景是不能被清除的,而clearRect(x, y, width, height)方法会将指定区域的所有颜色给清除掉,所以我们用了两个canvas,两个canvas是不相干涉的。所以第二个canvascontext对象将第一个canvas画布给画了下来。
* 这是所需要的属性介绍

// 定义变量
var w = 100         // 一个黑块的宽度和高度
var blocks = []     // 存放所有黑块信息对象的数组
var flag = false    // 只有最后一个黑块的flag才允许为true,因为游戏规则是只有最最后一个黑块被点击才可以点击上一个黑块
var speed = 2       // 黑块的移动速度,他会随着你获得的分数而变快
var num = 0         // 分数
var requestId = 0   // requestAnimationFrame()方法的返回值,方便停止动画用的
  • 准备开始游戏
// 准备开始游戏
function ready_game() {
    // 在游戏开始的时候初始化变量
    blocks = []
    flag = false
    speed = 2
    num = 0
    ctx.clearRect(0, 0, canvas.width, canvas.height)
    score.textContent = '得分: ' + num

    ctx.fillStyle = 'black'
    var x = 0
    for (var i = 0; i < canvas.height; i += w) {
        // 随机生产黑块的x轴位置
        x = ~~(Math.random() * 3) * w
        var obj = { x: x, y: i }
        ctx.fillRect(x, i, w, w)
        if (i == 300) {
            ctx.fillStyle = 'white'
            ctx.font = '20px consolas'
            ctx.fillText('开始游戏', x + 10, i + w / 2)
            obj.flag = true
        }
        // 添加鼠标点击事件
        addClick_event(obj)
        // 将当前黑块对象存入数组中
        blocks.push(obj)
    }
}
  • 添加鼠标点击事件的方法
// 在指定位置添加click事件
function addClick_event(obj) {
    canvas2.addEventListener('click', function (e) {
        var cli_x = e.x - 10
        var cli_y = e.y - 10
        /// 如果点击中了有开始游戏文字描述的那个黑块
        if (cli_x > obj.x && cli_x < obj.x + w && cli_y > obj.y && cli_y < obj.y + w && obj.flag && !flag) {
            start_game()    // 开始游戏
        } else destroy_block(e) // 销毁黑块
    })
}
  • 开始游戏
// 开始游戏
function start_game() {
    blocks.pop()
    num++
    score.textContent = '得分: ' + num
    flag = true
    // 开始动画
    animate()
}
  • 黑块移动的方法
// 方块移动
function destroy_block(e) {
    if (!flag) return
    var cli_x = e.x, cli_y = e.y
    blocks.forEach(function (val, index) {
        if (cli_x > val.x && cli_x < val.x + w && cli_y > val.y && cli_y < val.y + w) {
            // 超出高度的黑块将会被销毁,原本是不需要这样做的,因为黑块只要超出高度,就代表游戏结束了。
            // 但是一开始没有考虑到,后来又不想改了,就这样吧~~
            if (index === blocks.length - 1) {
                blocks.pop()
                num++
                score.textContent = '得分: ' + num
            }
        }
    })
}
  • 动画方法
// 动画
function animate() {
    ctx.clearRect(0, 0, canvas.width, canvas.height)
    ctx.fillStyle = 'black'
    // 遍历数组中的黑块,不断的增加它们的y轴值
    blocks.forEach(function (val, index) {
        ctx.fillRect(val.x, val.y += speed, w, w)
        // if (val.y > canvas.height) {
            // blocks.splice(index, 1)
        // }
    })

    // 如果屏幕上显示的黑块用完了,就马上再画一个
    if (blocks.length === 0) {
        ctx.fillStyle = 'black'
        var x = ~~(Math.random() * 3) * w
        var obj = { x: x, y: -100 }
        ctx.fillRect(obj.x, obj.y, w, w)
        blocks.unshift(obj)
        addClick_event(obj)
    }
    // 数组中第一个黑块的y轴值如果超过了0,那么再它的上面再生成一个黑块,这个和上面那个if判断条件可以让屏幕中不断生成新的黑块
    if (blocks[0].y > 0) {
        ctx.fillStyle = 'black'
        var x = ~~(Math.random() * 3) * w
        var obj = { x: x, y: -100 }
        ctx.fillRect(obj.x, obj.y, w, w)
        blocks.unshift(obj)
        addClick_event(obj)
    }
    // 速度会随分数而提高
    speed = num / 10 + 2
    requestId = requestAnimationFrame(animate)

    if (blocks[blocks.length - 1].y >= canvas.height) {
        // 结束动画
        cancelAnimationFrame(requestId)
        // 游戏结束
        game_over()
    }
}
  • 游戏结束
// 游戏结束
function game_over() {
    alert('游戏结束,请重新开始!')
    ready_game()
}

效果图展示

展开阅读全文

没有更多推荐了,返回首页