先放下作者大大的项目地址:https://github.com/yangyunhe369/h5-game-heroVSmonster

然后游戏的效果为

截动图的按键与游戏按键应该冲突,我就截几张图片了。







接下来我们来分析代码

页面入口文件,canvas绘制页面背景以及各个图片

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>英雄大战小怪兽v1.0</title>
<link rel="stylesheet" href="css/common.css">
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<canvas id="canvas" width="1000" height="500"></canvas>
<div>
空格键开始游戏<br>
W、S、A、D键 和 上下左右方向键分别控制英雄、怪兽移动<br>
K 键、小键盘数字 5 键分别控制英雄和怪兽攻击,P 键暂停游戏
</div>
<script src="js/common.js"></script>
<script src="js/scene.js"></script>
<script src="js/game.js"></script>
<script src="js/main.js"></script>
</body>
</html>

common.js中是公共的会用到的图片

//common.js
/* by:弦云孤赫——David Yang
** github - https://github.com/yangyunhe369
*/
// 封装打印日志方法
const log = console.log.bind(console)
// 生成图片对象方法
const imageFromPath = function (src) {
let img = new Image()
img.src = './images/' + src
return img
}
// 图片素材路径
const allImg = {
bg: 'gameBg.jpg',
hero: {
idle: [ // 站立不动
'hero-Idle/hero_Idle_0.png',
'hero-Idle/hero_Idle_1.png',
'hero-Idle/hero_Idle_2.png',
'hero-Idle/hero_Idle_3.png',
'hero-Idle/hero_Idle_4.png',
'hero-Idle/hero_Idle_5.png',
'hero-Idle/hero_Idle_6.png',
'hero-Idle/hero_Idle_7.png',
],
run: [ // 移动
'hero-Run/hero_Run_0.png',
'hero-Run/hero_Run_1.png',
'hero-Run/hero_Run_2.png',
'hero-Run/hero_Run_3.png',
'hero-Run/hero_Run_4.png',
'hero-Run/hero_Run_5.png',
'hero-Run/hero_Run_6.png',
'hero-Run/hero_Run_7.png',
],
attack: [ // 攻击
'hero-Attack/hero_Attack_0.png',
'hero-Attack/hero_Attack_1.png',
'hero-Attack/hero_Attack_2.png',
'hero-Attack/hero_Attack_3.png',
'hero-Attack/hero_Attack_4.png',
'hero-Attack/hero_Attack_5.png',
'hero-Attack/hero_Attack_6.png',
'hero-Attack/hero_Attack_7.png',
],
hurt: [ // 受伤
'hero-Hurt/hero_Hurt_0.png',
'hero-Hurt/hero_Hurt_1.png',
'hero-Hurt/hero_Hurt_2.png',
'hero-Hurt/hero_Hurt_3.png',
'hero-Hurt/hero_Hurt_4.png',
'hero-Hurt/hero_Hurt_5.png',
'hero-Hurt/hero_Hurt_6.png',
'hero-Hurt/hero_Hurt_7.png',
],
die: [ // 死亡
'hero-Die/hero_Die_0.png',
'hero-Die/hero_Die_1.png',
'hero-Die/hero_Die_2.png',
'hero-Die/hero_Die_3.png',
'hero-Die/hero_Die_4.png',
'hero-Die/hero_Die_5.png',
'hero-Die/hero_Die_6.png',
'hero-Die/hero_Die_7.png',
],
},
monster: {
idle: [ // 站立不动
'monster-Idle/monster_Idle_0.png',
'monster-Idle/monster_Idle_1.png',
'monster-Idle/monster_Idle_2.png',
'monster-Idle/monster_Idle_3.png',
'monster-Idle/monster_Idle_4.png',
'monster-Idle/monster_Idle_5.png',
'monster-Idle/monster_Idle_6.png',
'monster-Idle/monster_Idle_7.png',
],
run: [ // 移动
'monster-Run/monster_Run_0.png',
'monster-Run/monster_Run_1.png',
'monster-Run/monster_Run_2.png',
'monster-Run/monster_Run_3.png',
'monster-Run/monster_Run_4.png',
'monster-Run/monster_Run_5.png',
'monster-Run/monster_Run_6.png',
'monster-Run/monster_Run_7.png', ],
attack: [ // 攻击
'monster-Attack/monster_Attack_0.png',
'monster-Attack/monster_Attack_1.png',
'monster-Attack/monster_Attack_2.png',
'monster-Attack/monster_Attack_3.png',
'monster-Attack/monster_Attack_4.png',
'monster-Attack/monster_Attack_5.png',
'monster-Attack/monster_Attack_6.png',
'monster-Attack/monster_Attack_7.png',
],
hurt: [ // 攻击
'monster-Hurt/monster_Hurt_0.png',
'monster-Hurt/monster_Hurt_1.png',
'monster-Hurt/monster_Hurt_2.png',
'monster-Hurt/monster_Hurt_3.png',
'monster-Hurt/monster_Hurt_4.png',
'monster-Hurt/monster_Hurt_5.png',
'monster-Hurt/monster_Hurt_6.png',
'monster-Hurt/monster_Hurt_7.png',
],
die: [ // 死亡
'monster-Die/monster_Die_0.png',
'monster-Die/monster_Die_1.png',
'monster-Die/monster_Die_2.png',
'monster-Die/monster_Die_3.png',
'monster-Die/monster_Die_4.png',
'monster-Die/monster_Die_5.png',
'monster-Die/monster_Die_6.png',
'monster-Die/monster_Die_7.png',
],
}
}

scene.js中是定义的角色模型

//scene
/* by:弦云孤赫——David Yang
** github - https://github.com/yangyunhe369
*/
/**
* 动画类
*/
class Animation{
constructor (type, action, fps) {
let a = {
type: type, // 角色类型,hero || monster
action: action, // 根据传入动作生成不同动画对象数组
images: [], // 当前引入角色图片对象数组
img: null, // 当前显示角色图片
imgIdx: 0, // 当前角色图片序列号
count: 0, // 计数器,控制动画运行
fps: fps, // 角色动画运行速度系数,值越小,速度越快
}
Object.assign(this, a)
}
/**
* 为角色不同动作创造动画序列
*/
create () {
let self = this
if (self.type === 'hero') {
for(let item of allImg.hero[self.action]){
self.images.push(imageFromPath(item))
}
} else if (self.type === 'monster') {
for(let item of allImg.monster[self.action]){
self.images.push(imageFromPath(item))
}
}
}
}
/**
* 角色模型类
*/
class Role{
constructor (_main, obj) {
let h = {
_main: _main, // 游戏主函数对象
type: obj.type, // 角色类型,hero || monster
x: obj.x, // x 轴坐标
y: obj.y, // y 轴坐标
w: obj.w, // 角色图片宽度
h: obj.h, // 角色图片高度
speedX: 3, // 角色x轴移动速度
speedY: 3, // 角色y轴移动速度
life: 8, // 角色血量 // animation: {
// idle: null, // 站立动画对象
// run: null, // 奔跑动画对象
// attack: null, // 攻击动画对象
// hurt: null, // 受伤动画对象
// die: null, // 死亡动画对象
// }, idle: null, // 站立动画对象
run: null, // 奔跑动画对象
attack: null, // 攻击动画对象
hurt: null, // 受伤动画对象
die: null, // 死亡动画对象
canMove: true, // 能否移动
isFlipX: false, // 是否翻转画布绘制图片,用于绘制人物朝右动画
isAttacking: false, // 是否处于攻击状态
isDie: false, // 是否死亡,血量降为 0 即死亡
direction: null, // 角色朝向
state: 1, // 保存当前状态值,默认为 0
state_IDLE: 1, // 站立状态
state_RUN: 2, // 奔跑状态
state_ATTACK: 3, // 攻击状态
state_HURT: 4, // 受伤状态
state_DIE: 5, // 死亡状态
}
Object.assign(this, h)
}
/**
* 初始化方法
* 对角色的站位方向、状态、不同姿势动画序列进行初始化
*/
init (info) {
let self = this
// 角色初始站位方向,状态
info.type === 'hero' ? self.direction = 'right' : self.direction = 'left'
// 是否翻转绘制角色,根据角色朝向判断
self.isFlipX = self.direction === 'left' ? false : true
// 角色默认状态值为1,站立状态
self.state = 1
// 角色站立
self.idle = new Animation(self.type, 'idle', 8)
self.idle.create()
// 角色奔跑
self.run = new Animation(self.type, 'run', 4.5),
self.run.create()
// 角色攻击
self.attack = new Animation(self.type, 'attack', 4)
self.attack.create()
// 角色受伤
self.hurt = new Animation(self.type, 'hurt', 4)
self.hurt.create()
// 角色死亡
self.die = new Animation(self.type, 'die', 4)
self.die.create()
}
/**
* 判断角色状态并返回对应动画对象名称方法
*/
switchState (state) {
let self = this
switch (state) {
case self.state_IDLE:
return 'idle'
case self.state_RUN:
return 'run'
case self.state_ATTACK:
return 'attack'
case self.state_HURT:
return 'hurt'
case self.state_DIE:
return 'die'
}
}
/**
* 角色运行动画切换方法
* game: 游戏对象
*/
move (game) {
let self = this,
stateName = self.switchState(self.state)
// 累加动画计数器
self[stateName].count += 1
// 设置角色动画运行速度
self[stateName].imgIdx = Math.floor(self[stateName].count / self[stateName].fps)
// 一整套动画完成后重置动画计数器
self[stateName].imgIdx === 7 ? self[stateName].count = 0 : self[stateName].count = self[stateName].count
// 设置当前帧动画对象
if (game.state !== game.state_STOP) { // 运动时,逐帧显示图片
if (stateName === 'hurt' && self[stateName].imgIdx === 7) { // 受伤时,执行完一套动画切换为站立状态后允许移动
// 角色状态改为站立状态
self.state = self.state_IDLE
self.canMove = true
} else if (stateName === 'die' && self[stateName].imgIdx === 7) {
// 游戏状态改为结束状态
game.state = game.state_GAMEOVER
self[stateName].img = self[stateName].images[7]
} else {
self[stateName].img = self[stateName].images[self[stateName].imgIdx]
}
} else { // 静止时,默认显示第一张图片
self[stateName].img = self[stateName].images[0]
}
}
/**
* 执行动画方法
* game => 游戏引擎对象
* action => 动作类型
* -idle: 站立
* -run: 移动
* -attack: 攻击
* -hurt: 受伤
*/
animation (game, action) {
let self = this,
direction = self.direction, // 获取角色朝向
canvas = self._main.game.canvas // 获取 canvas 对象
if (game.state === game.state_RUNNING) {
switch (action) {
case 'idle':
self.state = self.state_IDLE
break
case 'run':
self.state = self.state_RUN // 上下左右键移动事件,并做边界判断
if (direction === 'up') { // 上
if (self.y > 25) { // 大于上边界 + 血条高度
self.y -= self.speedY
}
} else if (direction === 'down') { // 下
if (self.y < canvas.height - self.h + 15) { // 大于下边界 - 图片高度 + 图片下侧空白部分
self.y += self.speedY
}
} else if (direction === 'left') { // 左
if (self.x > -10) { // 大于左边界 - 图片左侧空白部分
self.x -= self.speedX
}
} else if (direction === 'right') { // 右
if (self.x < canvas.width - self.w) { // 大于右边界 - 图片宽度 - 图片右侧空白部分
self.x += self.speedX
}
}
break
case 'attack':
self.state = self.state_ATTACK
break
case 'hurt':
self.state = self.state_HURT
break
case 'die':
self.state = self.state_DIE
break
}
}
}
}

main.js中是定义的游戏的主函数,启动方法

//js\main.js
/* by:弦云孤赫——David Yang
** github - https://github.com/yangyunhe369
*/
/**
* 游戏运行主函数
*/
let _main = {
hero: null, // hero 实例对象
hero_info: { // hero 初始化参数
type: 'hero', // 角色类型
x: 40, // x 轴坐标
y: 350, // y 轴坐标
w: 100, // 图片宽度
h: 109, // 图片高度
},
monster: null, // monster 实例对象
monster_info: { // monster 初始化参数
type: 'monster', // 角色类型
x: 900, // monster x 轴坐标
y: 100, // monster y 轴坐标
w: 100, // 图片宽度
h: 113, // 图片高度
},
game: null, // 游戏引擎对象
fps: 60, // 游戏运行每秒帧数
rollPostion: function () { // 随机角色坐标位置
let self = this,
canvas = document.getElementById('canvas'),
hero = self.hero_info,
monster = self.monster_info
// 随机生成 hero 坐标,在左半区域随机
hero.x = Math.random() * (canvas.width / 2 - hero.w) + 0
hero.y = Math.random() * (canvas.height - hero.h) + 0
// 随机生成 monster 坐标,在右半区域随机
monster.x = Math.random() * (canvas.width / 2 - monster.w) + canvas.width / 2
monster.y = Math.random() * (canvas.height - monster.h) + 0
},
start: function () { // 游戏主程序
let self = this
// 随机生成 hero,monster 坐标
self.rollPostion() // 创建 hero 类
self.hero = new Role(self, self.hero_info)
// 创建 hero 动画序列
self.hero.init(self.hero_info) // 创建 monster 类
self.monster = new Role(self, self.monster_info)
// 创建 monster 动画序列
self.monster.init(self.monster_info) // 创建游戏引擎类
self.game = new Game(self.fps)
self.game.init(self)
}
}
_main.start()

game.js中定义的是游戏说明以及得分点

//js\game.js

/* by:弦云孤赫——David Yang
** github - https://github.com/yangyunhe369
*/
/**
* 游戏引擎函数
*/
class Game {
constructor (fps = 60) {
let g = {
actions: {}, // 按键事件方法集,并在按键事件触发时调用对应方法
keydowns: {}, // 按键事件生成对象集
state: 1, // 游戏状态值,初始默认为 1
state_START: 1, // 游戏初始化
state_RUNNING: 2, // 游戏开始
state_STOP: 3, // 游戏暂停
state_GAMEOVER: 4, // 游戏结束
canvas: document.getElementById("canvas"), // canvas 元素
context: document.getElementById("canvas").getContext("2d"), // canvas 画布
timer: null, // 轮询定时器
fps: fps, // 动画帧数,默认 60
}
Object.assign(this, g)
}
// 绘制所有游戏素材
drawAll (hero, monster) {
let g = this
// 清除画布
g.context.clearRect(0, 0, g.canvas.width, g.canvas.height)
// 绘制背景
g.drawBg()
// 绘制角色及角色血条
g.drawImage(hero)
g.drawBlood(hero.x, hero.y, hero.life, hero.type)
g.drawImage(monster)
g.drawBlood(monster.x, monster.y, monster.life, monster.type)
}
// 绘制游戏背景
drawBg () {
let img = imageFromPath(allImg.bg)
this.context.drawImage(img, 0, 0)
}
/**
* 绘制角色血条
* x: x轴坐标
* y: y轴坐标
* life: 血量
* type: 角色类型 => hero || monster
* height: 血条高度
* fillColor: 填充颜色
* borderWidth: 边框宽度
* borderColor: 边框颜色
*/
drawBlood (x, y, life, type, fillColor, borderColor, borderWidth = 1, height = 15) {
let cxt = this.context,
width = 6 * life // 血量单位宽度 * 总血量 // 根据角色类型不同,绘制不同颜色血条
if (type === 'hero') {
fillColor = 'red'
borderColor = 'red'
} else {
fillColor = '#cc3f30'
borderColor = '#cc3f30'
}
// 开始绘制血条
cxt.beginPath()
cxt.rect(x + 26, y - 20, width, height) cxt.lineWidth = borderWidth
cxt.strokeStyle = borderColor
cxt.fillStyle = fillColor cxt.fill()
cxt.stroke()
}
/**
* 绘制图片
* obj: 绘制对象
*/
drawImage (obj) {
let state = obj.state, // 当前角色状态值
stateName = obj.switchState(obj.state) // 判断并获取当前动画对象名称
if (obj.isFlipX) { // 是否水平翻转图像并绘制,true 翻转且角色朝右,false 不翻转且角色朝左
let x = obj.x + obj.w / 2
// 把当前状态的一份拷贝压入到一个保存图像状态的栈中
this.context.save()
this.context.translate(x, 0)
this.context.scale(-1, 1)
this.context.translate(-x, 0)
this.context.drawImage(obj[stateName].img, obj.x, obj.y)
// 从栈中弹出存储的图形状态并恢复 CanvasRenderingContext2D 对象的属性、剪切路径和变换矩阵的值
this.context.restore()
} else {
this.context.drawImage(obj[stateName].img, obj.x, obj.y)
}
}
// 游戏结束执行方法
drawGameOver (hero, monster) {
let info = '' // 游戏结束提示信息
if (hero.isDie) {
info = '恭喜怪兽获得胜利'
}
if (monster.isDie) {
info = '恭喜英雄获得胜利'
}
// 清除定时器
clearInterval(this.timer)
// 清除画布
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height)
// 绘制背景
this.drawBg()
this.context.fillStyle = 'red'
this.context.font = '48px Microsoft YaHei'
this.context.fillText(info, 308, 226)
}
// 注册事件
registerAction (key, callback) {
this.actions[key] = callback
}
// 设置逐帧动画
setTimer (hero, monster) {
let g = this
// 事件集合
let actions = Object.keys(g.actions)
for (let i = 0; i < actions.length; i++) {
let key = actions[i]
if(g.keydowns[key]) {
// 如果按键被按下,调用注册的action
g.actions[key]()
}
}
// 判断游戏状态并执行相应事件
if (g.state === g.state_START){ // 游戏开始
// 角色移动动画
hero.move(g)
monster.move(g)
// 绘制所有游戏素材
g.drawAll(hero, monster) // 绘制准备开始游戏标题
g.context.fillStyle = 'red'
g.context.font = '48px Microsoft YaHei'
g.context.fillText('请按空格键开始游戏', 284, 226)
} else if (g.state === g.state_RUNNING) { // 游戏运行
// 角色移动动画
hero.move(g)
monster.move(g)
// 绘制所有游戏素材
g.drawAll(hero, monster)
} else if (g.state === g.state_STOP) { // 游戏暂停
// 绘制所有游戏素材
g.drawAll(hero, monster) // 绘制准备开始游戏标题
g.context.fillStyle = 'red'
g.context.font = '48px Microsoft YaHei'
g.context.fillText('请按空格键开始游戏', 284, 226)
} else if (g.state === g.state_GAMEOVER) { // 游戏结束
// 绘制所有游戏素材
g.drawAll(hero, monster)
setTimeout(function () {
// 绘制游戏结束标题
g.drawGameOver(hero, monster)
},500)
}
}
/**
* 注册按键移动事件
* role: 注册角色对象
* keyCode: 按键keyCode值
* direction: 角色移动方向
* [
* {role: hero, keyCode: '87', direction: 'up'},
* ...
* ]
*/
registerRoleMove (roleList) {
let game = this
for (let item of roleList) {
game.registerAction(item.keyCode, function () {
if (game.state === game.state_RUNNING && item.role.canMove) {
// 设置当前角色朝向
item.role.direction = item.direction
// 判断是否需要翻转角色动画
if (item.direction === 'left') {
// 禁止翻转动画,同时角色朝左移动
item.role.isFlipX = false
} else if (item.direction === 'right') {
// 翻转动画,同时角色朝右移动
item.role.isFlipX = true
}
if (game.keydowns[item.keyCode] === 'down') {
// 角色不处于受伤状态时才能移动
if (item.role.state !== item.role.state_HURT) {
// 执行奔跑动画
item.role.animation(game, 'run')
}
} else if (game.keydowns[item.keyCode] === 'up') {
// 取消奔跑动画
game.keydowns[item.keyCode] = null
item.role.animation(game, 'idle')
}
}
})
}
}
/**
* 注册按键攻击事件
* roList: [
* {
* role: 注册角色对象
* keyCode: 按键keyCode值
* }
* ...
* ]
*/
registerRoleAttack (roleList) {
let game = this, // 当前游戏引擎类
hero = roleList[0].role, // hero 对象
monster = roleList[1].role // monster 对象
for (let item of roleList) {
let role = item.role.type // 当前角色类型,hero || monster
game.registerAction(item.keyCode, function () {
if (game.state === game.state_RUNNING) {
if (game.keydowns[item.keyCode] === 'down') {
// 角色不处于受伤状态时才能攻击
if (item.role.state !== item.role.state_HURT && item.role.state !== item.role.state_DIE) {
// 执行攻击动画
item.role.animation(game, 'attack')
}
// 禁止左右移动
item.role.canMove = false
} else if (game.keydowns[item.keyCode] === 'up') {
// 取消攻击动画
if (item.role.attack.imgIdx === 7) { // 执行一次完整动画后停止
// 将按键事件置为空
game.keydowns[item.keyCode] = null
item.role.animation(game, 'idle')
// 检测 hero、monster 是否攻击成功
if (role === 'hero') {
game.checkAttack(role, hero, monster)
} else {
game.checkAttack(role, monster, hero)
}
// 允许左右移动
item.role.canMove = true
}
}
}
})
}
}
/**
* 检测是否处于攻击范围
* role1:当前执行攻击动作角色
* role2:当前被攻击角色
*/
collideAttack (role1, role2) {
let r1 = role1,
r2 = role2
// 两个角色图片之间的中心点距离小与两站图片宽度之和的一半,即为可攻击
if (Math.abs((role1.x + role1.w/2) - (role2.x + role2.w/2)) < (role1.w + role2.w - 80)/2 &&
Math.abs((role1.y + role1.h/2) - (role2.y + role2.h/2)) < (role1.h + role2.h - 150)/2) {
if (r1.isFlipX && r1.x < r2.x ||
!r1.isFlipX && r1.x > r2.x) { // r1面向右侧,且r2在r1右侧时;r1面向左侧,且r2在r1左侧时
return true
}
}
return false
}
/**
* 检测是否攻击成功
* roleName:角色名称
* role1:当前执行攻击动作角色
* role2:当前被攻击角色
*/
checkAttack (roleName, role1, role2) {
let game = this
// 处于角色攻击范围时,即可攻击
if (game.collideAttack(role1, role2)) {
if (role2.life === 1) { // 生命值为1时
// 执行受伤动画
role2.animation(game, 'die')
// 禁止移动
role2.canMove = false
role2.life -= 1
// 改变角色死亡状态
role2.isDie = true
setTimeout(function () {
// 生命值为0时,游戏结束
game.state = game.state_GAMEOVER
}, 500)
} else {
// 执行受伤动画
role2.animation(game, 'hurt')
// 禁止移动
role2.canMove = false
role2.life -= 1
}
}
}
/**
* 初始化函数
* _main: 游戏入口函数对象
*/
init (_main) {
let g = this,
hero = _main.hero,
monster = _main.monster
// 设置键盘按下及松开相关注册函数
window.addEventListener('keydown', function (event) {
g.keydowns[event.keyCode] = 'down'
})
window.addEventListener('keyup', function (event) {
g.keydowns[event.keyCode] = 'up'
})
g.registerAction = function (key, callback) {
g.actions[key] = callback
}
/**
* 为 hero 和 monster 注册按键移动事件
* hero 按键事件,对应 W、S、A、D
* monster 按键事件,对应 up、down、left、right方向键
*/
g.registerRoleMove([
{role: hero, keyCode: '87', direction: 'up'},
{role: hero, keyCode: '83', direction: 'down'},
{role: hero, keyCode: '65', direction: 'left'},
{role: hero, keyCode: '68', direction: 'right'},
{role: monster, keyCode: '38', direction: 'up'},
{role: monster, keyCode: '40', direction: 'down'},
{role: monster, keyCode: '37', direction: 'left'},
{role: monster, keyCode: '39', direction: 'right'},
]) /**
* 为 hero 和 monster 注册按键攻击事件
*/
g.registerRoleAttack([
{role: hero, keyCode: '75'}, // 注册 hero K 键攻击事件
{role: monster, keyCode: '101'} // 注册 monster 小键盘 5 键攻击事件
]) // 设置轮询定时器
g.timer = setInterval(function () {
g.setTimer(hero, monster)
}, 1000/g.fps) // 注册游戏全局按键控制事件
window.addEventListener('keydown', function (event) {
switch (event.keyCode) {
// 注册空格键开始游戏事件
case 32 :
// 开始游戏
g.state = g.state_RUNNING
break
// P 键暂停游戏事件
case 80 :
g.state = g.state_STOP
break
}
})
}
}

后记:我没有完全看懂代码啊~

【默默努力】h5-game-heroVSmonster的更多相关文章

  1. 2018.5.2(7:20到的办公室开始早课 阮一峰的JS) 所有的默默努力都是为了让自己看起来毫不费力

    continue语句用于立即终止本轮循环,返回循环结构的头部,开始下一轮循环. break语句用于跳出代码块或循环. 标签(label) JavaScript 语言允许,语句的前面有标签(label) ...

  2. 【默默努力】PixelFire

    先放下我玩游戏的效果图: 关于游戏最后的结束部分其实我还没有截图,看着挺好看的,后面的效果 再放作者大大的项目地址:https://github.com/panruiplay/PixelFire 接下 ...

  3. 【默默努力】fishingGame

    这个捕鱼游戏挺有意思的,通过发射子弹,打鱼.打鱼的子弹会消耗金币,但是打鱼如果打到了鱼,就会奖励金币的数量. 我如果写这个的话,应该会画一个 背景海底,然后生成很多鱼的图片,还要有一个大炮,金币.大炮 ...

  4. 【默默努力】h5-game-blockBreaker

    先放下游戏的效果,我不太会玩游戏 然后放下无私开源的作者大大的地址:https://github.com/yangyunhe369/h5-game-blockBreaker 这个游戏的话,我觉得应该是 ...

  5. 【默默努力】ig-wxz-and-hotdog

    这个是一个非常跟热点的小游戏,思聪吃热狗.这个游戏的话,我感觉思路还挺简单的,天上会掉热狗和障碍物, 思聪在下面张开嘴巴,进行左右移动,接热狗.如果吃到的是热狗就得一分,如果思聪吃到的不是热狗,是障碍 ...

  6. 【默默努力】react-drag-grid

    先放项目地址:https://github.com/Bilif/react-drag-grid 项目运行效果 感谢无私开源的程序员 先看项目入口文件 //index.js import React f ...

  7. 【默默努力】vue-pc-app

    最近在github上面看到了一个团队的项目,真的非常赞.他们进行vue-cli的二次开发,将项目用自己的方式打包. 今天的这个开源项目地址为:https://github.com/tffe-team/ ...

  8. Shader的学习方法总结

    最近网友candycat1992的新书<Unity Shader入门精要>出版了,估计万千的中国unity开发者又要掀起一波学Shader热潮了.我也想把自己这几年学习Shader的一些历 ...

  9. VIM移动

    VIM移动   断断续续的使用VIM也一年了,会的始终都是那么几个命令,效率极低 前几个星期把Windows换成了Linux Mint,基本上也稳定了下来 就今晚,我已经下定决心开始新的VIM之旅,顺 ...

随机推荐

  1. Oracle sql判断一个字段是否全数字 或含有中文

    update (select length(t.name), t.* -- name,length(name) from g_enterprise_info t where nvl2(translat ...

  2. 制作windows puppet openstack镜像

    由于电信需要远程部署软件,拟使用puppet进行远程服务管理 前提 windows系统已经安装 windows已经安装virtio driver 远程桌面开启,最好关闭防火墙 设置MTU 在没有安装c ...

  3. docker实用参数

    docker images:查看docker镜像docker ls:查看运行中的docker 镜像docker run -d -p 80:80 -v /home/xxxxx/nginx-conf/ht ...

  4. docker service 集群创建

    docker service create /新建docker集群--name webwork /集群的名称--replicas 3/ 启动3个节点--network my-network/ netw ...

  5. linux centos 装g++安装不了

    今天需要编译一个项目的时候在装g++都装不上, [root@master hadoop]# yum install g++ Loaded plugins: fastestmirror, refresh ...

  6. Vue项目中同级组件传值的例子

    大家好,今天给大家带来Vue项目中同级组件之间传值的例子,父子组件之间的通信比较简单,这里不做讨论. 假设该项目中的需求如下: 图中左上角有一个按钮,我们的需求是点击它时,侧边导航栏收缩且主界面放大, ...

  7. cms系统视频分享

    cms_001-CMS系统功能需求简介-1.avicms_002-如何采用用例分析方法来理解需求-1.avicms_003-后台管理系统用例-1.avicms_004-实现验证码的初步思路-1.avi ...

  8. 2019-8-31-C#-如何写出一个不能被其他程序集继承的抽象类

    title author date CreateTime categories C# 如何写出一个不能被其他程序集继承的抽象类 lindexi 2019-08-31 16:55:58 +0800 20 ...

  9. Impala简介

  10. springboot EL @Value

    一,springboot中 看一下代码: @Controller public class HelloController { //读取枚举值 @Value("#{T(com.example ...