html5游戏开发-零基础开发RPG游戏-开源讲座(一)
在游戏的世界里,我们可以看到各种地图,各种游戏人物,看到人物在地图上行走,对话等,无论是地图还是人物,其实都是图片的处理与显示,把不同的图片显示到屏幕上,我们就看到不同的游戏界面,要想让这些图片同时显示到界面上,我们就需要处理好层次,让他们来分层显示,我们可以想象,如果游戏人物显示在地图的下层的话,显然会被地图遮挡住。
一款RPG游戏,我简单把它分为地图层,人物层,效果层(一些法术效果等),对话层,控制层(按钮菜单等)。
如下图
我们只要依次将图片画在屏幕上,游戏人物将站在地图上,如果有对话,对话将出现在人物和地图的上面,而按钮等控件会出现在游戏的最外层
下面,我们一步步来实现一个简单的RPG游戏的开发
准备工作
一,库件下载
本游戏开发,需要用到开源库件:LegendForHtml5Programming
请到这里下载最新版的LegendForHtml5Programming,本次开发需要1.2版以上
http://code.google.com/p/legendforhtml5programming/downloads/list
库件的开发过程请看这里
http://bbs.html5cn.org/thread-2712-1-1.html
二,库件配置
首先建立一个文件夹rpg(你也可以起其他的名字)
然后将下载的库件解压,解压后将legend文件夹放到与rpg文件夹同目录
然后,在rpg文件夹里建一个index.html文件和一个js文件夹,在js文件夹里建一个Main.js文件
最后,在index.html里加入下面的代码
-
-
-
-
-
rpg
-
-
-
loading……
-
-
-
当然,你也可以将legend文件夹放到其他地方,但是你需要修改legend文件夹下的legend.js文件中的LEGEND_PATH的值,来配置库件的路径
游戏地图的实现
接下来,我们先来画最底层的地图层,
地图当然就是是由图片来组成的,如何在画面上显示一张图片,我之前已经写过专门的文章,代码如下
- var loader;
- function main(){
- loader = new LLoader();
- loader.addEventListener(LEvent.COMPLETE,loadBitmapdata);
- loader.load("map.jpg","bitmapData");
- }
- function loadBitmapdata(event){
- var bitmapdata = new LBitmapData(loader.content);
- var bitmap = new LBitmap(bitmapdata);
- addChild(bitmap);
- }
如果想更详细了解的话,看下面的帖子
用仿ActionScript的语法来编写html5——第一篇,显示一张图片
http://bbs.html5cn.org/thread-2700-1-1.html
游戏中的地图可以是一张比较大的图片,即整个图片就是游戏的地图,当人物或者地图移动的时候,改变图片显示的区域范围,从而实现地图的滚动和显示等,这样的话,必须为每个场景准备一张地图。
另外,地图也可以是由许多小的地图块儿来组成,比如,我们熟悉的《吞食天地》,《勇者斗恶龙》等经典小型rpg游戏,这样的地图,我们需要准备一张或几张地图块儿,把这些地图块组合成地图来显示,比如下图
在地图显示的时候,首先把图片切割,然后在根据预先设定好的位置显示到地图层上,这样我们就看到了一张完整的地图了
接下来,打开Main.js
在里面加入
- init(50,"mylegend",480,320,main);
在legendForHtml5Progarmming中,用init这个函数来初始化canvas,上面的代码表示,初始化一个速度为50,名字为mylegend,大小为480*320的游戏界面,初始化完成后调用main(),这个速度值是说每个多少毫秒游戏循环一次,所以这个值设定的越小,游戏运行的速度就越快
因为要调用main方法,所以我们要写一个main方法,main方法里做一些简单的准备工作。
虽说读取图片只需要一个
- loader.load("map.jpg","bitmapData");
但是游戏中往往用到很多张图片,你可以用到哪一张再加载哪一张,也可以一次性全部加载完,然后再开始显示游戏
为了一次性把图片加载完,我的做法是,将需要的图片放到一个数组里,然后设定一个索引,每加载一个图片,让这个索引加1,当这个索引小于数组的长度,则继续加载,直到将数组中的图片全部加载完,然后开始进行下一步的工作
具体实现看下面的代码
- //图片path数组
- var imgData = new Array();
- //读取完的图片数组
- var imglist = {};
-
- function main(){
- //准备读取图片
- imgData.push({name:"map",path:"./image/map.jpg"});
- imgData.push({name:"mingren",path:"./image/mingren.png"});
- imgData.push({name:"e1",path:"./image/e1.png"});
- imgData.push({name:"e2",path:"./image/e2.png"});
- //实例化进度条层
- loadingLayer = new LSprite();
- loadingLayer.graphics.drawRect(1,"black",[50, 200, 200, 20],true,"#ffffff");
- addChild(loadingLayer);
- //开始读取图片
- loadImage();
- }
- function loadImage(){
- //图片全部读取完成,开始初始化游戏
- if(loadIndex >= imgData.length){
- removeChild(loadingLayer);
- legendLoadOver();
- gameInit();
- return;
- }
- //开始读取图片
- loader = new LLoader();
- loader.addEventListener(LEvent.COMPLETE,loadComplete);
- loader.load(imgData[loadIndex].path,"bitmapData");
- }
- function loadComplete(event){
- //进度条显示
- loadingLayer.graphics.clear();
- loadingLayer.graphics.drawRect(1,"black",[50, 200, 200, 20],true,"#ffffff");
- loadingLayer.graphics.drawRect(1,"black",[50, 203, 200*(loadIndex/imgData.length), 14],true,"#000000");
- //储存图片数据
- imglist[imgData[loadIndex].name] = loader.content;
- //读取下一张图片
- loadIndex++;
- loadImage();
- }
上面的代码不难明白,当图片没有读取完之前,会不断循环loadImage和loadComplete两个方法,当读取完之后,移除进度条,用legendLoadOver告诉游戏已经读取完成,然后调用gameInit方法,进行游戏的初始化工作。
看gameInit方法
- function gameInit(event){
- //游戏层显示初始化
- layerInit();
- //添加地图
- addMap();
- //添加人物
- addChara();
- }
在gameInit方法中,首先进行游戏层的初始化,然后添加游戏地图,然后添加人物
游戏层显示初始化,按照我们一开始所说,我们一次来初始化地图层,人物层,效果层,对话层,控制层
- //游戏层显示初始化
- function layerInit(){
- //游戏底层添加
- backLayer = new LSprite();
- addChild(backLayer);
- //地图层添加
- mapLayer = new LSprite();
- backLayer.addChild(mapLayer);
- //人物层添加
- charaLayer = new LSprite();
- backLayer.addChild(charaLayer);
- //效果层添加
- effectLayer = new LSprite();
- backLayer.addChild(effectLayer);
- //对话层添加
- talkLayer = new LSprite();
- backLayer.addChild(talkLayer);
- //控制层添加
- ctrlLayer = new LSprite();
- backLayer.addChild(ctrlLayer);
- }
有了游戏层次的划分,我们在添加游戏对象的时候,将地图添加到地图层,人物添加到人物层,他们就会依次显示在游戏的界面
下面开始添加地图
首先我们需要准备好显示地图的数组
- //地图图片数组
- var map = [
- [18,18,18,18,18,18,18,18,18,18,18,18,55,55,18],
- [18,18,18,17,17,17,17,17,17,17,17,17,55,55,18],
- [18,18,17,17,17,17,18,18,17,17,17,17,55,55,18],
- [18,17,17,17,18,18,18,18,18,17,17,55,55,17,18],
- [18,17,17,18,22,23,23,23,24,18,17,55,55,17,18],
- [18,17,17,18,25,28,26,79,27,18,55,55,17,17,18],
- [18,17,17,17,17,10,11,12,18,18,55,55,17,17,18],
- [18,18,17,17,10,16,16,16,11,55,55,17,17,17,18],
- [18,18,17,17,77,16,16,16,16,21,21,17,17,17,18],
- [18,18,18,18,18,18,18,18,18,55,55,18,18,18,18]
- ];
这些数字分别对应着图中如下位置
然后看下面代码
- //添加地图
- function addMap(){
- var i,j,index,indexX,indexY;
- var bitmapdata,bitmap;
- //地图图片数据
- bitmapdata = new LBitmapData(imglist["map"]);
- //将地图图片拆分,得到拆分后的各个小图片的坐标数组
- imageArray = LGlobal.divideCoordinate(bitmapdata.image.width,bitmapdata.image.height,10,10);
-
- //在地图层上,画出15*10的小图片
- for(i=0;i
- for(j=0;j
- //从地图数组中得到相应位置的图片坐标
- index = map[i][j];
- //小图片的竖坐标
- indexY = Math.floor(index /10);
- //小图片的横坐标
- indexX = index - indexY*10;
- //得到小图片
- bitmapdata = new LBitmapData(imglist["map"],indexX*32,indexY*32,32,32);
- bitmap = new LBitmap(bitmapdata);
- //设置小图片的显示位置
- bitmap.x = j*32;
- bitmap.y = i*32;
- //将小图片显示到地图层
- mapLayer.addChild(bitmap);
- }
- }
- }
这样,我们就把预先设置好的图片显示到了游戏界面上,形成了地图
先把addChara方法加上
- //添加人物
- function addChara(){
- }
然后运行游戏
可以得到下面画面
游戏人物的实现
为了更好的实现游戏人物的控制,我们新建一个游戏人物类Character.js
里面代码如下
- function Character(data,row,col,speed){
- base(this,LSprite,[]);
- var self = this;
- //设定人物动作速度
- self.speed = speed==null?3:speed;
- self.speedIndex = 0;
- //设定人物大小
- data.setProperties(0,0,data.image.width/col,data.image.height/row);
- //得到人物图片拆分数组
- var list = LGlobal.divideCoordinate(data.image.width,data.image.height,row,col);
- //设定人物动画
- self.anime = new LAnimation(this,data,list);
- };
- Character.prototype.onframe = function (){
- var self = this;
- if(self.speedIndex++
- self.speedIndex = 0;
- self.anime.onframe();
- };
在legendForHtml5Programming里,有一个LAnimation类,用来实现图片数组顺序播放,形成动画
使用LAnimation类需要三个参数,一个是显示动画的层,一个是图片,一个是图片的坐标数组
然后,调用LAnimation类的onframe方法,就可以实现动画的播放了
在index.html中引入Character类,然后修改addChara方法
- //添加人物
- function addChara(){
- bitmapdata = new LBitmapData(imglist["mingren"]);
- player = new Character(bitmapdata,4,4);
- player.x = 32*5;
- player.y = 32*6;
- charaLayer.addChild(player);
-
- }
在gameInit的末尾添加循环事件
- //添加贞事件,开始游戏循环
- backLayer.addEventListener(LEvent.ENTER_FRAME,onframe);
最后,添加onframe方法
- /**
- * 循环
- * */
- function onframe(){
- player.onframe();
- }
运行代码,看到了吗
一个会动的鸣人出现在游戏的地图上了
游戏演示
http://fsanguo.comoj.com/html5/rpg/index.html
最后,附上这次的游戏源代码
http://legend-demo.googlecode.com/files/rpg.zip

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









uniapp がミニ プログラムと H5 の間で迅速な変換を実現するには、具体的なコード例が必要ですが、近年、モバイル インターネットの発展とスマートフォンの普及に伴い、ミニ プログラムと H5 は不可欠なアプリケーション形式となっています。クロスプラットフォーム開発フレームワークとして、uniapp は一連のコードに基づいて小規模プログラムと H5 間の変換を迅速に実現し、開発効率を大幅に向上させます。この記事では、uniapp がミニ プログラムと H5 の間で迅速な変換を実現する方法と、具体的なコード例を紹介します。 1. uniapp uniaの紹介

win1121h2 と 22h2 の 2 つのバージョンを比較すると、後者の 22h2 の方が安定しており、22h2 の方が機能が多く、前の 21h2 と比べて多くの機能が改善されています。 win1121h2 と 22h2 はどちらの方が安定していますか: 回答: 22h2 の方が安定しています win1121h2 と 22h2 を比較すると、22h2 の方が安定しています。 22h2では多くの機能が追加されており、21h2の問題点も22h2では改善されています。 22h2 アップデート機能: スタート メニューのアプリケーション フォルダー。 [スタート] メニューの調整可能な固定領域。タスクバーにドラッグアンドドロップします。フォーカス アシストは通知センターと統合されています。新しい「スポットライト」壁紙機能。新しい

Windows 101909 は現在、最も安定しており信頼できるバージョンの 1 つと考えられていますが、残念ながら、このバージョンのサービス サポートは最近終了しました。 21H2 は比較的安定したバージョンであり、実際の状況からすると、どちらも非常に良い選択です。 win101909 と 21h2 のどちらが優れていますか? 回答: 1909 の方が安定しており、21h2 の方が安全です。現在の環境では、1909 は依然として最も安定しており信頼できるバージョンの 1 つであると一般に考えられています。ただし、Win101909 バージョンは、2021 年 5 月 11 日に正式にサービスの提供を停止しました。WindowsServer21h2 は、大多数のユーザーに、より専門的な IT 機能のサポートを提供することに取り組んでいます。 1. 多くのユーザーによる実際のテストの後、

該当するシナリオ: 1. プロジェクトの規模が大きくない 2. ユーザー数があまり多くなく、同時実行性の要件がそれほど強くない 3. 専任の運用保守要員が存在しない 4. チームの規模が絶妙である通常のプロジェクト、または企業の責任分担が明確ではない部門。多くの場合、システムは要件から設計、開発、テスト、そして最終的な立ち上げ、運用、保守へと進みます。多くの場合、タスクの 80% は開発チームによって完了されます。したがって、開発者はシステムの機能を実装するだけでなく、顧客の相談に応じ、質問に答え、生産上の問題を解決する必要もあります。想像してみてください。アプリケーションが起動された後は、監視手段が何もありません。ダッシュボードのない車を運転するのと同じように、このような道路では誰も安全を感じません。シンプルさと効率性のバランスをどう取るかは、考える価値のあることです。 1.スプリングブ

Windows 11 システムの 23h2 バージョンと 22h2 バージョンは、それぞれ 2023 年と 2022 年にリリースされる予定です。一般的に、システム アップデートはますます改善されています。編集者も、23h2 バージョンは 22h2 バージョンよりも優れていると考えています。 win1123h2 と 22h2 のどちらが優れていますか? 回答: win1123h2 の方が優れています。報告によると、win1123h2 は 22h2 から次のバージョンへの累積的なバージョン アップデートであり、プラットフォームはすべて同じです。これは、2 つのバージョン間に互換性の問題がないことを意味するため、適時に更新することをお勧めします。 win1123h2 バージョンでは、タスクバー ウィンドウ アプリケーションのマージ禁止モードなど、多くの実用的な機能が提供されます。他にもあります

最近、誰もが Win11 の 23H2 バージョンにアップデートしたいと考えていますが、少数のユーザーがアップデートのプッシュ メッセージをまだ受け取っていません。バックグラウンドでのアップデートの進行中のプロセスが停止している可能性があり、しばらくすると正常になります。 Win11 アップデートが 23H2 を取得できない場合の対処方法. 方法 1: 辛抱強く待つ. ユーザーがコンピューターのアップデート ステータスを確認し、スタックしていることがわかった場合は、しばらく待つことができ、システムはアップデートを続行します。方法 2: 更新されたキャッシュをクリアします。ユーザーが以前にシステムを更新していて、より詳細なキャッシュをクリアしていない場合は、23h2 の通常の更新に影響します。手動でクリアできます。方法 3: イメージ インストールを使用する Microsoft の公式 Web サイトにアクセスして win1123h2 のイメージ ファイルをダウンロードし、ファイルを更新することをお勧めします。

このファイルを変更するには、管理者から提供されたアクセス許可が必要です。解決策: 1. ログイン インターフェイスで管理者アカウントを選択し、パスワードを入力すると、ファイルをスムーズに変更できます。2. ファイルを右クリックして、 「管理者として」の解決策: 3. ファイルのアクセス許可を変更し、ファイルを右クリックして「プロパティ」を選択し、「セキュリティ」タブをクリックして「編集」ボタンをクリックし、ユーザー名を選択して「フル コントロール」にチェックを入れます。オプション ; 4. コマンド プロンプトを使用して問題を解決します; 5. UA 権限を設定します。

Flask-Admin を使用してバックエンド管理インターフェイスを実装する方法 背景の紹介: Web サイトやアプリケーションの開発に伴い、バックエンド管理インターフェイスの重要性がますます高まっています。開発プロセスでは、データ、ユーザー、その他の重要な情報を管理するために、便利で高速なバックエンド管理インターフェイスが必要になることがよくあります。 Flask-Admin は強力で使いやすい Flask 拡張機能で、バックグラウンド管理インターフェイスを迅速に実装するのに役立ちます。 Flask-Admin は、Flask と SQLAlchemy に基づいたオープンソース プロジェクトです。
