先放下作者大大的项目地址: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. hdu多校第六场1012 (hdu6645) Stay Real 假博弈,真贪心

    题意: 给你一个小根堆,从根开始拿,拿走子节点被拿完后才可以拿走父节点,两个人依次拿,谁拿的节点总和大谁获胜,问你谁有必胜策略. 题解: 小根堆中,每个点的权值总是不小于父亲节点的权值.所以无论怎么取 ...

  2. Hbase启动的时候出现:[RpcServer.handler=28,port=60000] ipc.RpcServer: RpcServer.handler=28,port=60000: exiting,master.HMasterCommandLine: Master exiting

    hadoop 版本:CDH5.02 Hbase 版本:hbase-0.96.1.1-cdh5.0.2 配置文件:hbase-site.xml <configuration> <pro ...

  3. ATC/TC/CF

    10.25 去打 CF,然后被 CF 打了. CF EDU 75 A. Broken Keyboard 精神恍惚,WA 了一发. B. Binary Palindromes 比赛中的憨憨做法,考虑一个 ...

  4. 一个有关group by的错误

    事例:查询有奖金的每个部门的部门名和部门的领导编号和该部门的最低工资 SELECT department_name,MIN(salary),departments.manager_idFROM dep ...

  5. Android开发 ImageView开发记录

    改变图片的着色 默认是这个方法 /** * 为图像设置着色选项. Assumes * {@link PorterDuff.Mode#SRC_ATOP} blending mode. * * @para ...

  6. webstorm安装与破解

    1.下载webstorm和补丁文件 链接:https://pan.baidu.com/s/1aiHxPExAbDCcHxKtB82_vg 提取码:jo07 链接:https://pan.baidu.c ...

  7. leetcode-973-最接近原点的K个点

    题目描述: 可参考:题215 方法一:排序 class Solution: def kClosest(self, points: List[List[int]], K: int) -> List ...

  8. Java 虚拟机 - GC机制

    GC机制的一些总结 https://blog.csdn.net/super_qing_/article/details/85263991 https://blog.csdn.net/yhyr_ycy/ ...

  9. .net下MVC中使用Tuple分页查询数据

    主要是在DAL层写查询分页的代码. 例如DAL层上代码: public Tuple<List<WxBindDto>, int> GetMbersInfo(int start, ...

  10. yii2.0 数据库查询操作

    User::find()->all();    此方法返回所有数据:    User::findOne($id);   此方法返回 主键 id=1  的一条数据(举个例子):    User:: ...