使用方法
var canvas = document.createElement('canvas'),
a = document.getElementById('runner-container'),
ctx = canvas.getContext('2d');
canvas.id = 'c';
canvas.width = 600;
canvas.height = 150;
a.appendChild(canvas);
//坐标
var spriteDefinition = {
CACTUS_LARGE: {
x: 332,
y: 2
}, //大仙人掌
CACTUS_SMALL: {
x: 228,
y: 2
}, //小仙人掌
CLOUD: {
x: 86,
y: 2
}, //云
HORIZON: {
x: 2,
y: 54
}, //地面
MOON: {
x: 484,
y: 2
}, //月亮
PTERODACTYL: {
x: 134,
y: 2
}, //翼龙
RESTART: {
x: 2,
y: 2
}, //重新开始按钮
TEXT_SPRITE: {
x: 655,
y: 2
}, //分数
TREX: {
x: 848,
y: 2
}, //霸王龙
STAR: {
x: 645,
y: 2
} //星星
},
FPS = 60,
DEFAULT_WIDTH = 600,
imgSprite = document.getElementById('sprite');
Runner.config = {
ACCELERATION: 0.001,
BG_CLOUD_SPEED: 0.2,
BOTTOM_PAD: 10,
CLEAR_TIME: 3000,
CLOUD_FREQUENCY: 0.5,
GAMEOVER_CLEAR_TIME: 750,
GAP_COEFFICIENT: 0.6,
GRAVITY: 0.6,
INITIAL_JUMP_VELOCITY: 12,
INVERT_FADE_DURATION: 10000, //夜晚持续时间
INVERT_DISTANCE: 700, //每700距离进行昼夜交替
MAX_CLOUDS: 6, //云最大数量
MAX_OBSTACLE_LENGTH: 3,
MAX_OBSTACLE_DUPLICATION: 2,
MAX_SPEED: 13,
MIN_JUMP_HEIGHT: 35,
MOBILE_SPEED_COEFFICIENT: 1.2,
RESOURCE_TEMPLATE_ID: 'audio-resources',
SPEED: 6,
SPEED_DROP_COEFFICIENT: 3
};
Runner.defaultDimensions = {
HEIGHT: 150,
WIDTH: 600
};
Runner.classes = {
CANVAS: 'runner-canvas',
CONTAINER: 'runner-container',
CRASHED: 'crashed',
ICON: 'icon-offline',
INVERTED: 'inverted',
SNACKBAR: 'snackbar',
SNACKBAR_SHOW: 'snackbar-show',
TOUCH_CONTROLLER: 'controller'
};
Runner.sounds = {
BUTTON_PRESS: 'offline-sound-press',
HIT: 'offline-sound-hit',
SCORE: 'offline-sound-reached'
};
Runner.keycodes = {
JUMP: {
'38': 1,
'32': 1
}, // Up, spacebar
DUCK: {
'40': 1
}, // Down
RESTART: {
'13': 1
} // Enter
};
Runner.events = {
ANIM_END: 'webkitAnimationEnd',
CLICK: 'click',
KEYDOWN: 'keydown',
KEYUP: 'keyup',
MOUSEDOWN: 'mousedown',
MOUSEUP: 'mouseup',
RESIZE: 'resize',
TOUCHEND: 'touchend',
TOUCHSTART: 'touchstart',
VISIBILITY: 'visibilitychange',
BLUR: 'blur',
FOCUS: 'focus',
LOAD: 'load'
};
function Runner(outerContainerId, opt_config) {
if (Runner.instance_) {
return Runner.instance_;
}
Runner.instance_ = this;
//this.outerContainerEl = document.querySelector(outerContainerId);
this.containerEl = null;
this.snackbarEl = null;
//this.detailsButton = this.outerContainerEl.querySelector('#details-button');
this.config = opt_config || Runner.config;
this.dimensions = Runner.defaultDimensions;
this.canvas = null;
this.ctx = null;
this.tRex = null;
this.distanceMeter = null;
this.distanceRan = 0;
this.highestScore = 0;
this.time = 0;
this.runningTime = 0;
this.msPerFrame = 1000 / FPS;
this.currentSpeed = this.config.SPEED;
this.obstacles = []; //障碍物
this.started = false;
this.activated = false;
this.crashed = false;
this.paused = false;
this.inverted = false;
this.invertTimer = 0;
this.resizeTimerId_ = null;
this.playCount = 0;
// Sound FX.
this.audioBuffer = null;
this.soundFx = {};
// Global web audio context for playing sounds.
this.audioContext = null;
// Images.
this.images = {};
this.imagesLoaded = 0;
this.loadImages();
}
Runner.prototype = {
loadImages: function() {
this.spriteDef = spriteDefinition;
this.init();
},
loadSounds: function() {
this.audioContext = new AudioContext();
},
setSpeed: function(opt_speed) {
if (opt_speed) this.currentSpeed = opt_speed;
},
init: function() {
this.setSpeed();
this.canvas = c;
this.ctx = ctx;
this.ctx.fillStyle = '#f7f7f7';
this.ctx.fill();
this.horizon = new Horizon(this.canvas, this.spriteDef, this.dimensions,
this.config.GAP_COEFFICIENT);
this.distanceMeter = new DistanceMeter(this.canvas, this.spriteDef.TEXT_SPRITE, this.dimensions.WIDTH);
this.tRex = new Trex(this.canvas, this.spriteDef.TREX);
this.startListening();
this.update();
},
//开场动画
playIntro: function() {
if (!this.started && !this.crashed) {
this.playingIntro = true;
this.tRex.playingIntro = true;
var keyframes = '@-webkit-keyframes intro { ' +
'from { width:' + Trex.config.WIDTH + 'px }' +
'to { width: ' + this.dimensions.WIDTH + 'px }' +
'}';
document.styleSheets[0].insertRule(keyframes, 0);
this.containerEl = document.getElementById('runner-container');
this.containerEl.addEventListener('webkitAnimationEnd',
this.startGame.bind(this));
this.containerEl.style.webkitAnimation = 'intro .4s ease-out 1 both';
this.containerEl.style.width = this.dimensions.WIDTH + 'px';
this.activated = true;
this.started = true;
} else if (this.crashed) {
this.restart();
}
},
startGame: function() {
this.runningTime = 0;
this.playingIntro = false;
this.tRex.playingIntro = false;
this.containerEl.style.webkitAnimation = '';
this.playCount++;
document.addEventListener('visibilitychange', this.onVisibilityChange.bind(this));
window.addEventListener('blur', this.onVisibilityChange.bind(this));
window.addEventListener('focus', this.onVisibilityChange.bind(this));
},
clearCanvas: function() {
this.ctx.clearRect(0, 0, this.dimensions.WIDTH, this.dimensions.HEIGHT);
},
//todo
update: function() {
this.drawPending = false;
var now = getTimeStamp();
var deltaTime = now - (this.time || now);
this.time = now;
if (this.activated) {
this.clearCanvas();
if (this.tRex.jumping) {
this.tRex.updateJump(deltaTime);
}
this.runningTime += deltaTime;
var hasObstacles = this.runningTime > this.config.CLEAR_TIME;
//如果是第一次跳跃并且没有播放开场动画,则播放开场动画
if (this.tRex.jumpCount == 1 && !this.playingIntro) {
this.playIntro();
}
if (this.playingIntro) {
this.horizon.update(0, this.currentSpeed, hasObstacles);
} else {
deltaTime = !this.started ? 0 : deltaTime;
this.horizon.update(deltaTime, this.currentSpeed, hasObstacles,
this.inverted);
}
var collision = hasObstacles &&
checkForCollision(this.horizon.obstacles[0], this.tRex);
if (!collision) {
this.distanceRan += this.currentSpeed * deltaTime / this.msPerFrame;
if (this.currentSpeed < this.config.MAX_SPEED) {
this.currentSpeed += this.config.ACCELERATION;
}
} else {
this.gameOver();
}
var playAchievementSound = this.distanceMeter.update(deltaTime,
Math.ceil(this.distanceRan));
if (playAchievementSound) {
this.playSound(this.soundFx.SCORE);
}
//若夜晚持续时间大于设定值则变为白天
if (this.invertTimer > this.config.INVERT_FADE_DURATION) {
this.invertTimer = 0;
this.invertTrigger = false;
this.invert();
} else if (this.invertTimer) {
this.invertTimer += deltaTime;
} else {
var actualDistance =
this.distanceMeter.getActualDistance(Math.ceil(this.distanceRan));
if (actualDistance > 0) {
this.invertTrigger = !(actualDistance %
this.config.INVERT_DISTANCE);
if (this.invertTrigger && this.invertTimer === 0) {
this.invertTimer += deltaTime;
this.invert();
}
}
}
}
if (!this.crashed) {
this.tRex.update(deltaTime);
this.raq();
}
},
handleEvent: function(e) {
return (function(evtType, events) {
switch (evtType) {
case events.KEYDOWN:
case events.TOUCHSTART:
case events.MOUSEDOWN:
this.onKeyDown(e);
break;
case events.KEYUP:
case events.TOUCHEND:
case events.MOUSEUP:
this.onKeyUp(e);
break;
}
}.bind(this))(e.type, Runner.events);
},
startListening: function() {
document.addEventListener(Runner.events.KEYDOWN, this);
document.addEventListener(Runner.events.KEYUP, this);
document.addEventListener(Runner.events.MOUSEDOWN, this);
document.addEventListener(Runner.events.MOUSEUP, this);
},
stopListening: function() {
document.removeEventListener(Runner.events.KEYDOWN, this);
document.removeEventListener(Runner.events.KEYUP, this);
document.removeEventListener(Runner.events.MOUSEDOWN, this);
document.removeEventListener(Runner.events.MOUSEUP, this);
},
onKeyDown: functi
站长提示:
1. 苦力吧素材官方QQ群:
950875342
2. 平台上所有素材资源,需注册登录会员方能正常下载。
3. 会员用户积极反馈网站、素材资源BUG或错误问题,每次奖励
2K币。
4. PHP源码类素材,如需协助安装调试,或你有二次开发需求,可联系苦力吧客服。
5. 付费素材资源,需充值后方能下载,如有任何疑问可直接联系苦力吧客服