使用ionic开发自己的第一个游戏APP

前言

这近在跟APP对接接口,在等待对接的空隙中,让我想起了被我遗忘的HybridApp技术 ionic ,于是就有了今天这篇新手级的教程。

当初使用的是ionic 3 ,现在升级到了ionic 6.x。变化比较大,支持Angular、Vue、React或其它任意JS框架,它甚至可以使用简单的脚本独立使用,无需任何前端框架

有关 ionic 的使用本文不详细描述,请查阅官网地址:https://ionicframework.com/docs

安卓调试环境

几年前写过一篇ionic 3 的安卓调试环境配置,但是不适合现在 ionic 6.x

1、安装 Android Studio
2、安装 Android SDK,基本上勾上API Level 16 以上的就行了
使用ionic开发自己的第一个游戏APP_第1张图片
3、配置环境变量

Key Value
ANDROID_SDK_ROOT C:\Users\18228\AppData\Local\Android\Sdk(Android SDK 安装目录)
Path %ANDROID_SDK_ROOT%\tools\bin
Path %ANDROID_SDK_ROOT%\platform-tools
Path %ANDROID_SDK_ROOT%\emulator

4、验证安装
执行adb ,如果不报错,则配置成功
使用ionic开发自己的第一个游戏APP_第2张图片

PS: (此步骤不是必须)一般情况,以前配置可以完成 Android 调试打包,如果有以上配置还是无法调试安卓,安装 JDK 1.8 +,然后配置对应的环境变量
JAVA_HOME = C:\Program Files\Java\jdk1.8.0_171 (JDK 安装目录)
PATH = %JAVA_HOME%\jre\bin

安卓手机环境(不是必须,H5也能调测)

准备一台安卓手机进行真机运行,启动开发者模式,打开USB 调试,打开USB 安装

ionic 环境安装

使用 npm 安装 Ionic CLI,使用 ionic 验证

npm install -g @ionic/cli

使用ionic开发自己的第一个游戏APP_第3张图片

编写ionic 项目

使用初始化一个angular 的 ionic tabs 项目

 ionic start 

使用ionic开发自己的第一个游戏APP_第4张图片
等待完成之后会,会在文件夹创建一个以项目名为文件夹的项目。主体结构如下,此处不就一一介绍了。
使用ionic开发自己的第一个游戏APP_第5张图片
现在切到文件夹根目录,执行下面命令就可以在web中运行

 ionic serve

效果如下图
使用ionic开发自己的第一个游戏APP_第6张图片

引入游戏框架

Phaser 是一个开源的桌面和移动 HTML5 2D 游戏开发框架,支持 JavaScript 和 TypeScript。

使用npm 安装

npm i phaser

修改 tsconfig.json 的编译选项,添加一下两处修改

{
	...
	"compilerOptions":{
		...
		"lib": ["es2018", "dom","scripthost"],
		"allowSyntheticDefaultImports": true, //允许默认从没有默认导出的模块导入。这不会影响代码发出,只会影响类型检查。
		...
	}
	...
}

使用ionic开发自己的第一个游戏APP_第7张图片
接下来正片开始,编写一个简单游戏,修改tab1.page.html 页面如下

<ion-header [translucent]="true">
  <ion-toolbar>
    <ion-title>
      Tab 1
    ion-title>
  ion-toolbar>
ion-header>

<ion-content>
  <div id="game">div>
ion-content>

修改tab1.page.ts , 详细讲解查看注释,主要是利用Phaser 框架新建静态场景和动态角色,添加触碰按钮,控制角色移动。

import { Component, OnInit } from '@angular/core';
import Phaser from 'phaser';

let player;
let platforms;

class GameScene extends Phaser.Scene {
  constructor(config) {
    super(config);
  }

  preload() {
    // 引入本地文件到游戏容器中
    this.load.image('sky', 'assets/sky.png');
    this.load.image('ground', 'assets/platform.png');
    this.load.image('left', 'assets/left.png');
    this.load.image('turn', 'assets/turn.png');
    this.load.image('right', 'assets/right.png');

    this.load.spritesheet('dude', 'assets/dude.png', { frameWidth: 32, frameHeight: 48 });
  }

  create() {

    // 使用图片,这里使用sky 作为背景
    this.add.image(400, 100, 'sky');

    // 构建静态物理游戏场景组
    platforms = this.physics.add.staticGroup();

    // 创建一个新的游戏对象并将其添加到该组中,缩放以适应游戏的宽度
    platforms.create(window.innerWidth - 20, 400, 'ground').setScale(2).refreshBody();

    // 新建玩家
    player = this.physics.add.sprite(100, 250, 'dude');

    player.setBounce(0.2); //设置这个身体的反弹值。弹跳是身体与另一个物体碰撞时的恢复量或弹性。值为 1 意味着它将在回弹后保持其全速。值为 0 表示它根本不会反弹
    player.setCollideWorldBounds(true); //设置这个身体是否与边界碰撞。

    // 创建左转动画效果
    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
    });

    this.physics.add.collider(player, platforms);//Arcade Physics Collider 将在每一步自动检查两个对象之间的碰撞或重叠。如果发生碰撞或重叠,它将调用给定的回调

    // cursors = this.input.keyboard.createCursorKeys(); 创建键盘键

    // 用为作为App,没有键盘,需要定义上、左、右三个按钮来操控人物行动,同事监听事件触发上面定义的相对应动画及行走距离
    const button = this.add.sprite(200, 500, 'turn')
      .setInteractive()
      .on('pointerdown', () => {
        player.setVelocityX(0);
        player.anims.play('turn');
        player.setVelocityY(-330);
      });
    const rightButton = this.add.sprite(300, 500, 'right')
      .setInteractive()
      .on('pointerdown', () => {
        player.setVelocityX(160);
        player.anims.play('right', true);
      })
      .on('pointerup', () => {
        player.setVelocityX(0);
      });
    const leftButton = this.add.sprite(100, 500, 'left')
      .setInteractive()
      .on('pointerdown', () => {
        player.setVelocityX(-160);
        player.anims.play('left', true);
      })
      .on('pointerup', () => {
        player.setVelocityX(0);
      });
  }

  update() {

  }
}

@Component({
  selector: 'app-tab1',
  templateUrl: 'tab1.page.html',
  styleUrls: ['tab1.page.scss']
})



export class Tab1Page implements OnInit {

  phaserGame: Phaser.Game;
  config: Phaser.Types.Core.GameConfig;

  winH = window.innerHeight;
  winW = window.innerWidth;

  constructor() {
    this.config = {
      type: Phaser.AUTO,
      width: this.winW,
      height: this.winH,
      physics: {
        default: 'arcade',
        arcade: {
          gravity: { y: 300 },
          debug: false
        }
      },
      parent: 'game',
      scene: GameScene
    };
  }

  ngOnInit(): void {
    this.phaserGame = new Phaser.Game(this.config);
  }
}

web 页面运行如下
使用ionic开发自己的第一个游戏APP_第8张图片

真机调试(仅Android)

前面说到安卓手机环境配置,现在我们打开配置,连接USB,输入一下命令,查看是否读到设备

adb devices

如下图所示,已读到设备。
在这里插入图片描述
设备调整后,代码需要添加编译成Android 源码操作,执行一下命令,第一次执行需要一些时间。

ionic capacitor add android

执行成功后,根目录多了一个android 文件夹,这就是编译后的android 源码,可以直接在Android Studio 中运行
使用ionic开发自己的第一个游戏APP_第9张图片
ionic 6 版本真机调试,需要在 android\app\src\main\AndroidManifest.xmlapplication 节点下添加 android:usesCleartextTraffic=“true” 属性。不然真机会找不到网页
使用ionic开发自己的第一个游戏APP_第10张图片
查看capacitor.config.json 文件,可以修改appId 、appName 等属性;同时,可以看到真机运行依赖www web文件夹,所以我们需要先build 出www文件夹
使用ionic开发自己的第一个游戏APP_第11张图片
运行以下命令

npm run build

执行自动生成了www 发布文件
使用ionic开发自己的第一个游戏APP_第12张图片
接下来就是执行命令,真机调试了,执行这个命令需要等待几分钟,同时注意手机是否有弹框提示确认安装。

ionic capacitor run android -l --external

本次只是简单讲解怎么使用ionic开发游戏,至于游戏的画面的兼容性,这些都是没有考虑在内的,更多的资料可以查阅 ionic 、Phaser ,
最后,看一下真机的运行效果(Redmi note 9 5G):

ionic app

该项目源码地址:https://github.com/CacoCode/ionic-phaser

你可能感兴趣的:(Ionic,游戏,android,ionic,phaser)