IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> HTML5用canvas制作飞机大战小游戏 -> 正文阅读

[游戏开发]HTML5用canvas制作飞机大战小游戏

css样式:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        canvas {
            display: block;
            margin: 50px auto;
            border: 1px solid black;
        }
    </style>
</head>

<body>
    <canvas width="480" height="600"></canvas>
    <script src="./index.js">
    </script>
</body>

</html>

js部分:

// 获取画布画笔
var canvas = document.getElementsByTagName('canvas')[0]
var ctx = canvas.getContext('2d')
// 初始化游戏数据 画布数据 背景图片数据 阶段数据
var canWidth = canvas.width
var canHeight = canvas.height
// 初始化各个游戏阶段数据
// 开始
var start = 0
// 加载
var ready = 1
// 游戏中
var playing = 2
// 暂停
var pause = 3
// 游戏结束
var over = 4
// 定义一个变量用以记录游戏状态(状态码)
var state = start
// 分数
var score = 0
// 生命值
var lives = 3

// 准备阶段
// 绘制背景图片
var bgimg = new Image()
// 设置图片地址
bgimg.src = 'img/background.png'
// 设置一个背景图片对象,存储图片数据
var bgi = {
    // 图片对象名称
    img: bgimg,
    // 宽高
    width: 480,
    height: 600,
}




// 定义一个构造函数创建背景图片对象
function bg(config) {
    // 图片的基本属性
    this.img = config.img;
    this.width = config.width;
    this.height = config.height;
    // 图片坐标
    this.x = 0;
    this.y = 0;
    // 定义第二张的坐标
    this.x1 = 0;
    this.y1 = -this.height;
    // 绘制方法
    this.paint = function () {
        // 实现无缝衔接绘制两张 一张放在画布上方
        ctx.drawImage(this.img, this.x, this.y);
        ctx.drawImage(this.img, this.x1, this.y1);
    }
    // 运动方法

    // 移动到底后位置回到画布上方
    this.sport = function () {
        // 移动速度
        this.y += 1;
        this.y1 += 1;
        if (this.y > this.height) {
            this.y = -this.height;
        }
        if (this.y1 > this.height) {
            this.y1 = -this.height;
        }
    }
}
// 实例化背景图片对象
var backImg = new bg(bgi)





// 绘制标题图片
var titleImg = new Image()
// 设置标题图片地址
titleImg.src = 'img/start.png'
// 创建对象存储标题图片属性
var timg = {
    img: titleImg,
    width: 480,
    height: 600
}
// 创建一个构造函数 绘制标题
function tit(config) {
    this.img = config.img
    this.width = config.width
    this.height = config.height
    this.x = 40
    this.y = 0
    // 绘制方法
    this.paint = function () {
        ctx.drawImage(this.img, this.x, this.y);
    }
}

// 实例化标题图片对象
var t = new tit(timg)








// 点击开始游戏
canvas.onclick = function () {
    // 如果游戏状态处于开始阶段
    if (state === start) {
        // 切换游戏状态至准备阶段
        state = ready
    }
}

// 加载阶段
var imgs = 'game_loading'
var loading = []
for (var i = 0; i < 4; i++) {
    loading[i] = new Image()
    // 拼接图片地址
    loading[i].src = `img/${imgs}${i + 1}.png`
}
// 创建图片对象
var Loading = {
    img: loading,
    width: 186,
    height: 38,
    length: loading.length
}
// 创建一个构造函数 绘制加载阶段图片
function Load(config) {
    this.img = config.img
    this.width = config.width
    this.height = config.height
    this.x = 0
    this.y = canHeight - this.height
    this.time = 0
    this.Index = 0
    this.length = config.length
    // 绘制加载阶段图片
    this.paint = function () {
        ctx.drawImage(this.img[this.Index], this.x, this.y)
    }
    // 加载图片的运动方法
    this.sport = function () {
        this.time++
        if (this.time % 3 == 0) {
            this.Index++
        }
        if (this.Index == this.length) {
            state = playing
        }
    }
}

// 实例化加载图片对象
var loadfour = new Load(Loading)





// 用数组储存图片地址
var heros = ['img/hero1.png', 'img/hero2.png', 'img/hero_blowup_n1.png', 'img/hero_blowup_n2.png', 'img/hero_blowup_n3.png', 'img/hero_blowup_n4.png']
// 创建数组储存图片对象
var heroObj = []
// 循环创建我方飞机图片对象,对相应图片地址赋值
for (var i = 0; i < heros.length; i++) {
    heroObj[i] = new Image();
    heroObj[i].src = heros[i]
}
// 我方飞机数据
var heroplane = {
    img: heroObj,
    width: 99,
    height: 124,
    length: heroObj.length,
}


// 绘制我方飞机
function Hero(config) {
    this.img = config.img
    this.width = config.width
    this.height = config.height
    this.length = config.length
    this.x = (canWidth - this.width) / 2
    this.y = canHeight - this.height - 100
    this.Index = 0
    this.boom = false
    this.time = 0
    this.paint = function () {
        ctx.drawImage(this.img[this.Index], this.x, this.y)
    }
    // 我方飞机运动方法
    this.sport = function () {
        if (this.boom) {
            this.Index++
            if (this.Index == this.length) {
                lives--
                this.boom = false
                this.Index = 0
                if (lives == 0) {
                    state = over
                    this.Index = this.length - 1
                }
            }
        } else {
            if (this.Index == 0) {
                this.Index = 1
            } else {
                this.Index = 0
            }
        }
    }
    // 子弹的射击方案
    this.shoot = function () {
        // 用变量控制子弹输出频率  每刷新三次发射一次子弹
        if (this.time % 3 == 0) {
            // 将创建的子弹对象存入弹夹数组
            bulletbox.push(new Bullet(bulletObj))
        }
        this.time++
    }
}

// 实例化我方飞机对象
var hero = new Hero(heroplane)





// 子弹部分


// 创建子弹图片对象
var bullet = new Image()
bullet.src = 'img/bullet1.png'
var bulletObj = {
    img: bullet,
    width: 9,
    height: 21
}
// 绘制子弹函数
function Bullet(config) {
    this.img = config.img
    this.width = config.width
    this.height = config.height
    this.x = hero.x + hero.width / 2 - this.width / 2
    this.y = hero.y - this.height
    this.bang = false
    this.paint = function () {
        ctx.drawImage(this.img, this.x, this.y)
    }
    this.sport = function () {
        this.y -= this.height
    }
}

var bullets = new Bullet(bulletObj)
// 创建数组存储所以绘制的子弹图片对象
var bulletbox = []
// 子弹绘制方法
function bulletPaint() {
    for (var i = 0; i < bulletbox.length; i++) {
        bulletbox[i].paint()
    }
}
// 子弹运动方法
function bulletSport() {
    for (var i = 0; i < bulletbox.length; i++) {
        bulletbox[i].sport()
    }
}
// 删除子弹
function bulletDelete() {
    for (var i = 0; i < bulletbox.length; i++) {
        // 当子弹超出屏幕范围或者命中后删除子弹
        if (bulletbox[i].y <= -bulletbox[i].height || bulletbox[i].bang) {
            bulletbox.splice(i, 1)
        }
    }
}


// 绘制敌机

// 小敌机
var enemy1Arr = ['img/enemy1.png', 'img/enemy1_down1.png', 'img/enemy1_down2.png', 'img/enemy1_down3.png', 'img/enemy1_down4.png',]
var enemy1 = []
for (var i = 0; i < enemy1Arr.length; i++) {
    enemy1[i] = new Image()
    enemy1[i].src = enemy1Arr[i]
}
// 小敌机对应数据
var enemy1Obj = {
    img: enemy1,
    height: 51,
    width: 57,
    length: enemy1Arr.length,
    life: 2,
    type: 1, //设置类型状态码用以判断敌机类型
    score: 1
}
// 中敌机
var enemy2Arr = ['img/enemy2.png', 'img/enemy2_down1.png', 'img/enemy2_down2.png', 'img/enemy2_down3.png', 'img/enemy2_down4.png']
var enemy2 = []
for (var i = 0; i < enemy2Arr.length; i++) {
    enemy2[i] = new Image()
    enemy2[i].src = enemy2Arr[i]
}
//中敌机的对应数据
var enemy2Obj = {
    img: enemy2,
    height: 95,
    width: 69,
    length: enemy2Arr.length,
    life: 10,
    type: 1, //设置类型状态码用以判断敌机类型
    score: 5
}
// 大敌机
var enemy3Arr = ['img/enemy3_n1.png', 'img/enemy3_n2.png', 'img/enemy3_hit.png', 'img/enemy3_down1.png', 'img/enemy3_down2.png', 'img/enemy3_down3.png', 'img/enemy3_down4.png']
var enemy3 = []
for (var i = 0; i < enemy3Arr.length; i++) {
    enemy3[i] = new Image()
    enemy3[i].src = enemy3Arr[i]
}
//大敌机的对应数据
var enemy3Obj = {
    img: enemy3,
    height: 258,
    width: 169,
    length: enemy3Arr.length,
    life: 20,
    type: 2, //设置类型状态码用以判断敌机类型
    score: 10
}



// 构造函数 绘制敌机
function Enemy(config) {
    this.img = config.img
    this.width = config.width
    this.height = config.height
    this.length = config.length
    this.life = config.life
    this.type = config.type
    this.x = Math.random() * (canWidth - this.width)
    this.y = -this.height
    this.Index = 0
    this.down = false
    this.boom = false
    this.time = 0
    this.score = config.score
    this.paint = function () {
        ctx.drawImage(this.img[this.Index], this.x, this.y)
    }
    // 敌机运动方法
    this.sport = function () {
        // 受击状态
        if (this.down) {
            this.life--
            if (this.life < 0) {
                this.Index++
                if (this.Index == this.length - 1) {
                    this.Index = this.length - 1
                    this.boom = true
                    score += this.score
                }
            }
        }
        // 正常状态
        if (!this.down) {
            if (this.type == 2) {
                this.Index = this.Index == 0 ? 1 : 0
            }
        }
        this.y += 2
    }
    // 判断自身是否被碰撞
    this.chenckhit = function (my) {
        return my.x > this.x && my.x < this.x + this.width && my.y <= this.y + this.height && my.y > 0
    }
}


// 定义敌方飞机对象数组
var enemyFleet = []
// 往数组中添加不同型号的敌机
function createEnemy() {
    var random = Math.random()
    // 设置不同型号敌机出现概率
    if (random < 0.08) {
        enemyFleet.push(new Enemy(enemy1Obj))
    } else if (random < 0.1) {
        enemyFleet.push(new Enemy(enemy2Obj))
    } else if (random < 0.12) {
        enemyFleet.push(new Enemy(enemy3Obj))
    }
}
// 敌机绘制方法
function enemyPaint() {
    for (var i = 0; i < enemyFleet.length; i++) {
        enemyFleet[i].paint();
    }
}
// 敌机运动方法
function enemySport() {
    for (var i = 0; i < enemyFleet.length; i++) {
        enemyFleet[i].sport()
    }
}
// 删除敌机
function enemyDelete() {
    for (var i = 0; i < enemyFleet.length; i++) {
        if (enemyFleet[i].boom || (enemyFleet[i].y >= canHeight)) {
            enemyFleet.splice(i, 1)
        }
    }
}


// 封装一个函数判断是否发生碰撞
function hit() {
    for (var i = 0; i < enemyFleet.length; i++) {
        if (enemyFleet[i].chenckhit(hero)) {
            // 发生碰撞则将我方飞机碰撞状态改为true
            hero.boom = true
        }
        for (var j = 0; j < bulletbox.length; j++) {
            if (enemyFleet[i].chenckhit(bulletbox[j])) {
                // 将子弹命中状态,与敌机受击状态改为true
                bulletbox[j].bang = true
                enemyFleet[i].down = true
                enemyFleet[i].y += 0
            }
        }
    }
}

// 鼠标移出事件 移出暂停
canvas.onmouseout = function () {
    if (state == playing) {
        state = pause
    }
}

// 鼠标移入事件 移入游戏继续
canvas.onmouseover = function () {
    if (state == pause) {
        state = playing
    }
}

// 移动事件,让飞机跟随鼠标移动
canvas.onmousemove = function (e) {
    var x = e.offsetX
    var y = e.offsetY
    if (state === playing) {
        hero.x = x - hero.width / 2
        hero.y = y - hero.height / 2
    }
}

// 暂停阶段
var pauseImg = new Image()
pauseImg.src = 'img/game_pause_nor.png'

var paused = {
    img: pauseImg,
    width: 60,
    height: 45
}
// 绘制暂停图片
function Pause(config) {
    this.img = config.img
    this.width = config.width
    this.height = config.height
    this.x = canWidth / 2 - this.width / 2
    this.y = canHeight / 2 - this.height / 2
    this.paint = function () {
        ctx.drawImage(this.img, this.x, this.y)
    }
}

// 实例化暂停图片对象
var pause = new Pause(paused)





// 游戏结束阶段
function paintOver() {
    ctx.font = "bold 50px 微软雅黑";
    ctx.fillText("游戏结束!", 130, 300);
}

// 飞机的生命值与得分
function paintText() {
    ctx.font = "bold 30px 微软雅黑";
    ctx.fillText("SCORE:" + score, 10, 30);
    ctx.fillText("LIFE:" + lives, 380, 30)
}








setInterval(function () {
    // 绘制背景
    backImg.paint();
    backImg.sport();
    if (state === start) {
        // 准备阶段绘制LOGO
        t.paint()
    } else if (state === ready) {
        // 加载阶段绘制加载图片
        loadfour.paint()
        loadfour.sport()
    } else if (state === playing) {
        // 游戏进行中
        // 绘制我方灰机
        hero.paint()
        hero.sport()
        hero.shoot()
        // 绘制子弹
        bulletPaint()
        bulletSport()
        bulletDelete()
        // 绘制敌机
        enemyPaint()
        createEnemy()
        enemySport()
        enemyDelete()
        hit()
        // 当前生命值与分数
        paintText()
    } else if (state === pause) {
        // 暂停阶段 停止运动
        hero.paint()
        bulletPaint()
        enemyPaint()
        pause.paint()
        paintText()
    } else if (state === over) {
        // 结束阶段 停止运动  绘制游戏结束文本
        paintOver()
        hero.paint()
        bulletPaint()
        enemyPaint()
        paintText()
    }
}, 20)

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2021-07-05 20:29:10  更:2021-07-05 20:29:15 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/4 9:23:57-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码