免费获取|
论文天下网
  • 论文天下网 |
  • 原创毕业论文 |
  • 论文范文 |
  • 论文下载 |
  • 计算机论文 |
  • 论文降重 |
  • 毕业论文 |
  • 外文翻译 |
  • 免费论文 |
  • 开题报告 |
  • 心得体会 |

当前位置:论文天下网 -> 免费论文 -> 计算机论文

基于HTML5的跨平台游戏设计与实现(三)

JS同样提供便利的触摸(touchstart(e),touchend(e),touchmove(e)),鼠标(mouseup(e),mousedown(e),mousemove(e))事件等交互操作函数。let rect = canvas.getBoundingClientRect();获取到canvas的大小及其相对于窗口的位置。画面自适应章节我们已将canvas的大小设置为设备屏幕大小,因此该rect 值为就是{W,H,0,0};现在要获取鼠标点击位置相对与玩家的位置,以设置玩家的方块移动的方向。这里可以取巧为鼠标位置就是玩家方块要去的位置,因此直接设置 const mousePosX = e.offsetX - rect.left;player.position.x = mousePosX;这里e是JS提供的鼠标/触摸点击位置坐标对象,里面包含点击位置坐标以及距离窗口的坐标。
为了游戏的简单性,设置游戏子弹的发射为自动,每隔10帧就发射一次子弹,每次生成子弹的起始坐标等于玩家的position。
游戏开始菜单页,监听mousedown和touchstart事件,等待玩家有点击或者触摸时,则设置游戏为开始状态。
五、游戏测试
在PC端OSX系统用Chrome浏览器打开index.html文件,按下F12,开启浏览器的手机模式。我们看到一个画面如图所示,游戏文字显示正常,文字动画正常闪缩。
 
图5-1 游戏开始界面
根据提示,点击游戏窗口屏幕,画面正常跳转到游戏场景页。开始如图5-2所示,分数,难度,最高分等游戏交互文本显示正常。子弹攻击到敌人后,敌人正常炸裂,并且分数增加。
  
图5-2 游戏HUD界面
在游戏窗口点击鼠标左键不放,并拖动鼠标,屏幕最下放玩家方块跟随鼠标移动正常如图5-3和图5-4所示。
  
图5-3 玩家方块
  
图5-4 玩家方块向左移动
六、结论
通过基于H5的跨平台小游戏开发,基本上体现了H5游戏的开发过程,最后也已经实现了一个跨平台游戏所需要的基本功能要素。H5的游戏开发过程较为简单,只要写好游戏规则和游戏部件绘制,开发游戏是很方便的,而所花时间也和开发游戏的规模,规则,内容复杂度相关。H5作为最新的web语言标准,此次开发中过程中,采用了JS最新版本ES6语法让代码耦合大大降低,面向对象的class新特性也上不同功能的代码分离更干净,相同功能代码更成体系。既方便阅读,又方便逻辑组装。对于后期修改整理有着极大方便。尽管所有功能并不是每个版本的浏览器都能兼容,但是对于canvas标签来说,随着时间的推移,支持H5的浏览器会越来越多,越来越完善与规范。2019年连微软的都放弃了IE转而用支持H5特性的更好的浏览器开源项目Chromium来重构自己的Edge浏览器。如今来说,基本适用无论是PC端还是智能手机端,都对H5有很好的支持。
附录 游戏源码
1. html文件源码
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=0.5, maximum-scale=1.0, minimum-scale=0.5">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>方块进攻</title>
<style type="text/css">
* {margin: 0;border: 0;padding: 0;overflow: hidden;}
body{background-color:rgba(0,0,0,0.8);}
</style>
</head>
<body>
<canvas id="game" onresize="View.resize"></canvas>
</body>
<script src="press_key.js"></script>
<script src="game.js"></script>
</html>
2. Press_key.js文件源码
let mouseDown=(e)=>{
    keys[82] = true;
}
let mouseUp=(e)=>{
    keys[82] = false;
}
let mouseMove=(e) =>{
    let rect = canvas.getBoundingClientRect();
    const mousePosX = e.offsetX - rect.left;
    if (player && !gameOver) player.position.x = mousePosX;
}
let touchStart = (e)=>{
    keys[82] = true;
}
let touchEnd = (e)=>{
    keys[82] = false;
}
let touchMove=(e) =>{
    const rect = canvas.getBoundingClientRect();
    const mousePosX = e.touches[0].pageX - rect.left;
    if (player && !gameOver) player.position.x = mousePosX;
}
3. Game.js文件源码
// 全局变量
//-----------------
let frames,W,H,W2,H2,player,
canvas,
ctx,
gameMode='menu';
let bgColor = "rgba(0,0,0,0.8)"
let ready;
let enemyScore;
let spawntime;
let difficulty;
let score=0;
let highScore=localStorage.getItem('highScore');
if (!highScore) highScore = 0
let gameOver=false;
let keys = [],entities = [], units = [], effects = [];
let OS_PC = "pc",
OS_IPHONE = "iPhone",
OS_IPAD = "iPad",
OS_ANDROID = "Android";
let Lib = {
os: OS_PC,
canTouch: false,
ios: false,
rand:(n=1)=>{
return Math.floor(Math.random() * n);
},
rangeRand:(min,max)=>{
return Math.floor(Math.random() * (max - min + 1)) + min;
},
rgba:(r, g, b, a=1)=>{
return `rgba(${r},${g},${b},${a})`;
},
randomColor:(min=0,max=255)=>{
let r = Lib.rangeRand(min,max);
let g = Lib.rangeRand(min,max);
let b = Lib.rangeRand(min,max);
return Lib.rgba(r,g,b);
},
overlaps:(entityA,entityB)=>{
let aSize = entityA.size;
let x1a = entityA.position.x;
let x2a = x1a + aSize;
let y1a = entityA.position.y;
let y2a = y1a + aSize;
let bSize = entityB.size;
let x1b = entityB.position.x;
let x2b = x1b + bSize;
let y1b = entityB.position.y;
let y2b = y1b + bSize;
return (x1a < x2b && x2a > x1b && y1a < y2b && y2a > y1b);
}
};
((userAgent)=>{
if (userAgent.indexOf(OS_IPHONE) > -1) {
Lib.os = OS_IPHONE;
Lib.canTouch = true;
Lib.ios = true;
} else if (userAgent.indexOf(OS_IPAD) > -1) {
Lib.os = OS_IPAD;
Lib.ios = true;
Lib.canTouch = true;
} else if (userAgent.indexOf(OS_ANDROID) > -1) {
Lib.os = OS_ANDROID;
Lib.canTouch = true;
Lib.android = true;
}
})(navigator.userAgent);
window.onload = ()=>{
Game.init();
}
//全局 函数
//----------------
let Game = {
init:()=>{
canvas = document.getElementById('game');
View.resize();
Game.reset();
Game.event();
gameMode = "menu";
Game.loop();
},
start:()=>{
gameMode = "game";
keys[121] = true;
ctx.textAlign = "left";
//Spawn player
player = new Player();
player.position.set(W2,H-player.size);
units.push(player);
},
loop() {
switch (gameMode) {
case "menu":
View.menu();
break;
case "game":
Game.update();
View.game();
break;
case "over":
View.gameOver();
break;
}
frames ++;
window.requestAnimationFrame(Game.loop);
},
update:()=>{
if(frames % 1800 === 0){
Game.increaseDifficulty();
}
if(frames%spawntime === 0){
Game.spawnEnemy();
}
units.forEach((e,index)=>{
if(e.alive){
e.update();
} else {
units.splice(index,1);
}
})
effects.forEach((e,index)=>{
if(e.alive){
e.update();
} else {
effects.splice(index,1);
}
})
Game.checkCollide();
},
checkCollide:()=>{
let len = units.length;
let l = 0;
let r = len - 1;
while (l != r){
let a = units[l];
let b = units[r];
if (Lib.overlaps(a,b)){
if(a.name === "Enemy"){
a.alive = false;
b.alive = false;
View.boomEffect(a);
score ++;
}
if(b.name === "Enemy"){
a.alive = false;
b.alive = false;
View.boomEffect(a);
score ++;
}
}
l++;
if(l != r){
r--;
}
}
},
event:()=>{
canvas.oncontextmenu =()=>{return false;}
if(Lib.canTouch){
canvas.addEventListener('touchstart', touchStart, false);
canvas.addEventListener('touchend', touchEnd, false);
canvas.addEventListener("touchmove", touchMove, false);
}else {
canvas.addEventListener('mouseup', mouseUp, false);
canvas.addEventListener('mousedown', mouseDown, false);
canvas.addEventListener('mousemove', mouseMove, false);
}
},
reset:()=>{
if (score > highScore){
highScore = score;
localStorage.setItem('highScore',highScore)
} 
ready = true;
frames = 0;
enemyScore = 0;
difficulty = 1;
score = 0;
spawntime = 120;
gameOver = false;
entities = [];
player = null;
},
increaseDifficulty(){
difficulty += 1;
if (spawntime > 20) spawntime -= 10;
},
spawnEnemy(){
let e = new Enemy();
let px = Lib.rand(W);
let py = -e.size;
e.position.set(px,py);
let r = Lib.rand();
if (r > .7){
AI.line(e);
} else if (r > .4){
AI.avg(e);
} else {
AI.triangular(e);
}
units.push(e);
}
};
let View = {
resize: ()=>{
W = window.innerWidth;
H = window.innerHeight;
W2 = window.innerWidth>>1;
H2 = window.innerHeight>>1;
canvas.width = W;
canvas.height = H;
ctx = canvas.getContext("2d");
ctx.font = "32px Arial";
ctx.textAlign = "center";
ctx.strokeStyle = "rgba(255,255,255,1)";
ctx.fillStyle = "rgba(220,220,255,1)";
},
menu:()=>{
View.clear();
ctx.fillStyle = "rgba(220,220,255,1)";
ctx.fillText("方块进攻", W2, H2>>1);
ctx.fillText("", W2, (H2>>1)+100);
ctx.fillStyle = Lib.rgba(125 - (frames % 60) * 3, 255 - (frames % 60) * 3, 125 - (frames % 60) * 3,1);
ctx.fillText("点击屏幕开始", W2, H2);
if (keys[82]) {
Game.start();
}
},
clear:()=>{
ctx.fillStyle = bgColor;
ctx.fillRect(0,0,W, H);
},
game:()=>{
View.clear();
if (gameOver){
gameMode = "menu";
Game.reset();
return;
}
View.drawEntities();
View.drawScore();
},
drawEntities:()=>{
units.forEach((e)=>{
e.render();
})
effects.forEach((e)=>{
e.render();
})
},
gameOver:()=>{
View.clear();
View.drawStatic();
View.drawScore();
ctx.fillStyle = Lib.rgba(125 - (frames % 60) * 3, 255 - (frames % 60) * 3, 125 - (frames % 60) * 3,1);;
ctx.fillText("游戏结束",W2 - 220,H2);
if (keys[82]) {
gameMode = "menu";
}
},
drawStatic:()=>{
let s = 30 ;
for (let x = 0; x < W; x+=s){
for (let y = 0; y < W; y+=s){
let n = Lib.rangeRand(0,60);
ctx.fillStyle = Lib.rgba(n,n,n,Math.random() * frames%60);
ctx.fillRect(x,y,s,s);
}
}
},
boomEffect:(entity)=>{
let particleCount = Math.floor((Math.random() * 6) + 3);
for (let i = 0; i < particleCount; i++){
let p = new Particle();
p.color = entity.color;
p.size = Math.floor((Math.random() * entity.size/2) + 5);
p.position.set(entity.position.x+entity.size/2,entity.position.y+entity.size/2);
effects.push(p);
}
},
drawScore:()=>{
ctx.fillStyle = "#CCFF99";
ctx.fillText("分数: " + score,20,40);
ctx.fillText("最高分: " + highScore,20,80);
let enemyScoreString = "";
for (let i = 0; i < enemyScore; i++){
enemyScoreString += "X";
}
ctx.fillStyle = "#FF6666";
ctx.fillText(enemyScoreString,20,120);
ctx.fillText("难度: " + difficulty,W2,30);
}
}
let AI = {
line:(entity)=>{
entity.velocity.x = W2;
entity.update = function(){
if(frames%20 === 0){
if(this.position.x == 0){
this.velocity.x = W2;
}else if(this.position.x == W){
this.velocity.x = -W2;
}
}else{
this.velocity.x = 0;
}
this.velocity.y = 1;
Entity.prototype.update.call(this);
}
},
avg:(entity)=>{
entity.update = function(){
this.velocity.x = this.size;
this.velocity.y = 1+difficulty;
Entity.prototype.update.call(this);
}
},
triangular:(entity)=>{
entity.update = function(){
this.velocity.x = this.size;
this.velocity.y = this.size/2;
Entity.prototype.update.call(this);
}
}
}
// class ================
class Vector2{
constructor(x,y){
this.x = x;
this.y = y;
}
set(a,b){
this.x = a;
this.y = b;
}
}
class Entity{
constructor(){
this.name = "Entity";
this.size = 25*2;
this.position = new Vector2(0,0);
this.velocity = new Vector2(0,0);
this.color = "#FFF";
this.alive = true;
}
sayName(){
console.log(this.name);
}
update(){
if (this.position.x == 0 || this.position.x == W) {
this.velocity.x = (-this.velocity.x)
}
this.position.x += this.velocity.x;
this.position.y += this.velocity.y;
if (this.position.x + this.size > W) {
this.position.x = W - this.size;
}
if (this.position.x - this.size < 0) {
this.position.x = 0
}
}
render(){
ctx.fillStyle = this.color;
ctx.fillRect(this.position.x,this.position.y,this.size,this.size);
}
}
class Enemy extends Entity{
constructor(){
super();
this.name = "Enemy";
this.size = Lib.rangeRand(40,100);
this.color = Lib.randomColor();
}
}
class Player extends Entity{
constructor(){
super();
this.name = "Player";
this.color = Lib.randomColor();
this.cd = 10;
this.bulletSpeed = -30; 
}
update() {
super.update();
if(frames%this.cd===0){
let bullet = new Bullet();
let offset = (player.size>>1) - (bullet.size>>1) ;
bullet.position.set(player.position.x + offset, player.position.y - offset);
bullet.velocity.y = this.bulletSpeed;
units.push(bullet);
}
}
}
class Particle extends Entity{
constructor(){
super();
this.name = "Particle";
this.size = 10*2;
this.time = 0;
this.maxTime = Lib.rangeRand(10,20);
this.velocity.x = Lib.rangeRand(10,-20);
this.velocity.y = Lib.rangeRand(10,30);
}
update(){
super.update();
this.time += 1;
if (this.time >= this.maxTime){
this.alive = false;
}
}
}
class Bullet extends Entity{
constructor(){
super();
this.name = "Bullet";
this.size = 10*2;
this.color = Lib.randomColor();
this.particlesDelay = 5;
}
update(){
if (this.position.y < 0) {
this.alive = false;
return;
}
super.update();
if (frames%this.particlesDelay === 0){
let p = new Particle();
let b_size = (this.size>>1);
p.size = Lib.rangeRand(5,b_size);
p.color = Lib.randomColor();
p.position.x = this.position.x + (p.size>>1);
p.position.y = this.position.y - (p.size>>1);
effects.push(p);
}
}
}

首页 上一页 1 2 3 下一页 尾页 3/3/3

相关论文
上一篇:计算机网络安全浅析 下一篇:防火墙技术浅析
推荐论文 本专业最新论文
Tags:基于 HTML5 跨平台 游戏 设计 实现 【返回顶部】

相关栏目

自动化相关
计算机论文
工程管理论文
法律论文
医学论文
人力资源
电子专业
电气工程
英语论文
行政管理
电子商务
社科文学
教育论文
物流专业
金融专业
财务管理
会计专业
化学化工材料科学
电子通信
环境科学
经济类
机械模具类
报告,总结,申请书
其他专业论文


关于我们 | 联系方式 | 论文说明 | 网站地图 | 免费获取 | 钻石会员 | 原创毕业论文

 

论文天下网提供论文检测,论文降重,论文范文,论文排版,网站永久域名WWW.GEPUW.NET

本站部分文章来自网友投稿上传,如发现侵犯了您的版权,请联系指出,本站及时确认并删除  E-mail: 893628136@qq.com

Copyright@ 2009-2022 GEPUW.NET 论文天下网 版权所有