游戏开发笔记1-phaser

Phaser是一款流行的h5游戏引擎。API文档:https://photonstorm.github.io/phaser3-docs/index.html

Phaser引擎框架基本结构为html+js,在header部分引入phaser。主体游戏逻辑在js代码中,

<!doctype html> 
<html lang="en"> 
<head> 
    <meta charset="UTF-8" />
    <title>Making your first Phaser 3 Game - Part 1</title>
    <script src="//cdn.jsdelivr.net/npm/phaser@3.11.0/dist/phaser.js"></script>
    <style type="text/css">
        body {
            margin: 0;
        }
    </style>
</head>
<body>

<script type="text/javascript">

    var config = {
        type: Phaser.AUTO,
        width: 800,
        height: 600,
        scene: {
            preload: preload,
            create: create,
            update: update
        }
    };

    var game = new Phaser.Game(config);

    function preload ()
    {
    }

    function create ()
    {
    }

    function update ()
    {
    }

</script>

</body>
</html>

首先创造一个Phaser.Game实例,var game = new Phaser.Game(config);,原型为new Game( [GameConfig])。在config中提供三个回调函数,其中preload用于加载资源,create用于首次渲染页面,而update用于定时更新页面。这三个函数属于Phaser.Scene类成员

// this.load为LoaderPlugin类型
// 加载图片:LoaderPlugin.image(key [, url] [, xhrSettings])
this.load.path = "images/sprites/"; // 指定load资源的根目录
this.load.image('sky', 'assets/sky.png');
this.load.image('ground', 'assets/platform.png');
this.load.image('star', 'assets/star.png');
this.load.image('bomb', 'assets/bomb.png');
// 加载动画:LoaderPlugin.animation(key [, url] [, dataKey] [, xhrSettings])
this.load.animation('baddieAnims', 'files/BaddieAnims.json');
this.load.animation({
    key: 'baddieAnims',
    url: 'files/BaddieAnims.json'
});
// 从缓存中获取动画
var data = this.cache.json.get('baddieAnims');
// 加载图集:LoaderPlugin.atlas(key [, textureURL] [, atlasURL] [, textureXhrSettings] [, atlasXhrSettings])
this.load.atlas('mainmenu', 'images/MainMenu.png', 'images/MainMenu.json');
this.load.atlas({
    key: 'mainmenu',
    textureURL: 'images/MainMenu.png',
    atlasURL: 'images/MainMenu.json'
});
this.load.atlas('mainmenu', 'images/MainMenu.png', 'images/MainMenu.json');
// and later in your game ...
this.add.image(x, y, 'mainmenu', 'background');
// 加载声音:LoaderPlugin.audio(key [, urls] [, config] [, xhrSettings])
this.load.audio('title', [ 'music/Title.ogg', 'music/Title.mp3', 'music/Title.m4a' ]);
this.load.audio({
    key: 'title',
    url: [ 'music/Title.ogg', 'music/Title.mp3', 'music/Title.m4a' ]
});
// 加载html:LoaderPlugin.html(key [, url] [, xhrSettings])
this.load.html('story', 'files/LoginForm.html');
this.load.html({
    key: 'login',
    url: 'files/LoginForm.html'
});
this.load.html('login', 'files/LoginForm.html');
// and later in your game ...
var data = this.cache.html.get('login');
// 加载精灵表单:spritesheet(key [, url] [, frameConfig] [, xhrSettings])
this.load.spritesheet('dude', 'assets/dude.png', { frameWidth: 32, frameHeight: 48 });
this.load.spritesheet({
    key: 'bot',
    url: 'images/robot.png',
    frameConfig: {
        frameWidth: 32,
        frameHeight: 38,
        startFrame: 0,
        endFrame: 8
    }
});
this.load.spritesheet('bot', 'images/robot.png', { frameWidth: 32, frameHeight: 38 });
// and later in your game ...

// this.add为GameObjectFactory类型
// 先加载的图片在底部,后加载的在上面
this.add.image(x, y, 'bot', 0);

完整代码示例

var config = {
  type: Phaser.AUTO,
  width: 800,
  height: 600,
  physics: {
    default: "arcade",
    arcade: {
      gravity: { y: 300 },
      debug: false
    }
  },
  scene: {
    preload: preload,
    create: create,
    update: update
  }
};

var player;
var platforms;
var stars;
var score = 0;
var scoreText;
var gameOver = false;
var bombs;
var game = new Phaser.Game(config);

function preload() {
  //加载资源文件
  this.load.image("sky", "assets/sky.png");
  this.load.image("ground", "assets/platform.png");
  this.load.image("star", "assets/star.png");
  this.load.image("bomb", "assets/bomb.png");
  this.load.spritesheet("dude", "assets/dude.png", {
    frameWidth: 32,
    frameHeight: 48
  });
}
function create() {
  // 一个简单的图片作为背景 A simple background for our game
  this.add.image(400, 300, "sky");
  // 添加一个静态组  The platforms group contains the ground and the 2 ledges we can jump on
  platforms = this.physics.add.staticGroup();
  // 添加地面  Here we create the ground.
  // 将地面放大成合适尺寸 Scale it to fit the width of the game (the original sprite is 400x32 in size)
  // create( [x] [, y] [, key] [, frame] [, visible] [, active])
  platforms.create(400, 568, "ground").setScale(2).refreshBody();
  // 在不同位置添加三条横条 Now let's create some ledges
  platforms.create(600, 400, "ground");
  platforms.create(50, 250, "ground");
  platforms.create(750, 220, "ground");
  // 创建玩家(角色) The player and its settings
  player = this.physics.add.sprite(100, 450, "dude");
  // 设置玩家反弹系数 Player physics properties. Give the little guy a slight bounce.
  player.setBounce(0);
  player.setCollideWorldBounds(true); // 禁止玩家走出世界
  // 将玩家的转身,走路以及停止设置动画 Our player animations, turning, walking left and walking right.
  // 向左走
  this.anims.create({
    key: "left",
    frames: this.anims.generateFrameNumbers("dude", { start: 0, end: 3 }),
    frameRate: 10,
    repeat: -1
  });
  //静止
  this.anims.create({
    key: "turn",
    frames: [{ key: "dude", frame: 4 }],
    frameRate: 20
  });
  //向右走
  this.anims.create({
    key: "right",
    frames: this.anims.generateFrameNumbers("dude", { start: 5, end: 8 }),
    frameRate: 10,
    repeat: -1
  });
  // 由键盘控制方向 Input Events
  cursors = this.input.keyboard.createCursorKeys();
  // 产生12个星星每个之间空70像素 Some stars to collect, 12 in total, evenly spaced 70 pixels apart along the x axis
  stars = this.physics.add.group({
    key: "star",
    repeat: 11,
    setXY: { x: 12, y: 0, stepX: 70 }
  });
  stars.children.iterate(function(child) {
    // 对于每个星星产生不同的反弹系数 Give each star a slightly different bounce
    child.setBounceY(Phaser.Math.FloatBetween(0.4, 0.8));
  });
  bombs = this.physics.add.group();
  var x = player.x < 400 ? Phaser.Math.Between(400, 800) : Phaser.Math.Between(0, 400);
    //产生炸弹
    var bomb = bombs.create(x, 16, "bomb");
    bomb.setBounce(1);
    bomb.setCollideWorldBounds(true);
    bomb.setVelocity(Phaser.Math.Between(-200, 200), 20);
    bomb.allowGravity = false;
  // 添加分数 The score
  scoreText = this.add.text(16, 16, "score: 0", {
    fontSize: "32px",
    fill: "#000"
  });
  // 两两(玩家与星星,玩家与炸弹)之间的碰撞 Collide the player and the stars with the platforms
  this.physics.add.collider(player, platforms);
  this.physics.add.collider(stars, platforms);
  this.physics.add.collider(bombs, platforms);
  // 收集星星 Checks to see if the player overlaps with any of the stars, if he does call the collectStar function
  this.physics.add.overlap(player, stars, collectStar, null, this);
  // 碰到炸弹
  this.physics.add.collider(player, bombs, hitBomb, null, this);
}

function update() {
  if (gameOver) {
    return;
  }
  if (cursors.left.isDown) {
    player.setVelocityX(-160);
    player.anims.play("left", true);
  } else if (cursors.right.isDown) {
    player.setVelocityX(160);
    player.anims.play("right", true);
  } else {
    player.setVelocityX(0);
    player.anims.play("turn");
  }

  if (cursors.up.isDown && player.body.touching.down) {
    player.setVelocityY(-400);
  }
}
function collectStar(player, star) {
  star.disableBody(true, true);
  // 更新分数 Add and update the score
  score += 10;
  scoreText.setText("Score: " + score);
  if (stars.countActive(true) === 0) {
    // 重新生成一批星星 A new batch of stars to collect
    stars.children.iterate(function(child) {
      child.enableBody(true, child.x, 0, true, true);
    });
    var x =
      player.x < 400 ? Phaser.Math.Between(400, 800) : Phaser.Math.Between(0, 400);
    //产生炸弹
    var bomb = bombs.create(x, 16, "bomb");
    bomb.setBounce(1);
    bomb.setCollideWorldBounds(true);
    bomb.setVelocity(Phaser.Math.Between(-200, 200), 20);
    bomb.allowGravity = false;
  }
}

function hitBomb(player, bomb) {
  // 碰到炸弹
  this.physics.pause();
  player.setTint(0xff0000); // 设置颜色
  player.anims.play("turn");
  gameOver = true;
}
GIF.gif
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容

  • 1、通过CocoaPods安装项目名称项目信息 AFNetworking网络请求组件 FMDB本地数据库组件 SD...
    阳明先生_x阅读 15,967评论 3 119
  • 1 Webpack 1.1 概念简介 1.1.1 WebPack是什么 1、一个打包工具 2、一个模块加载工具 3...
    Kevin_Junbaozi阅读 6,636评论 0 16
  • 舍寒三友 进大学的第一天,随处可见各种新生社团的报名公会,每个公会旁都有一群老生们帮着搬行李、登记姓名、发注册指南...
    投文字DI阅读 356评论 0 0
  • 两天的山东出差行程很快地结束了,时间总在瞬间流逝,当你还没怎么认识这个城市时,又匆匆启程回去。 知道现在的航班肯定...
    尚未明阅读 270评论 0 3
  • [俄]莱蒙托夫 兄弟,我想与你单独待一会儿 据说我在世界上已活不长了 你快些回家 看...,又如何呢 事实上 没有...
    wlola阅读 1,125评论 0 0