HarmonyOS鸿蒙Next“井”字小游戏

HarmonyOS鸿蒙Next“井”字小游戏 运行效果如下:

Video_20211021_124634_222.gif

这个小游戏是我小时候经常和同桌无聊的时候一起玩的。那个时候的快乐很简单,两个人,两支笔,一张草稿纸就能大战三百回合!

小游戏实现的功能很简单,就是两台设备通过分布式来同步笔记。

(听说最新的版本里面,就算A设备里面没有下载B设备中的某个APP,也可以通过分布式从B设备中流转到A设备里面运行?期待ing!!!这才是真正的突破了硬件的限制!!!)


1、设备连接

还是之前那个思想,能找到封装好的代码,就不重复造轮子

对于设备连接,SelectDeviceDialog和DevicesListAda封装的已经很好了,直接拿来用就行了,有需要的可以稍微修改下UI界面啥的。


package com.huawei.codelab.devices;

import com.huawei.codelab.ResourceTable;
import ohos.agp.components.Component;
import ohos.agp.components.LayoutScatter;
import ohos.agp.components.ListContainer;
import ohos.agp.utils.LayoutAlignment;
import ohos.agp.window.dialog.CommonDialog;
import ohos.app.Context;
import ohos.distributedschedule.interwork.DeviceInfo;
import java.util.List;

/**
 * Select Device Dialog
 * 
 * @since 2021-01-11
 */
public class SelectDeviceDialog {
    private static final int DIALOG_WIDTH = 840;
    private static final int DIALOG_HEIGHT = 900;
    private CommonDialog commonDialog;

    /**
     * SelectDeviceDialog
     * 
     * @param context Context
     * @param devices List
     * @param listener SelectResultListener
     * @since 2021-03-12
     */
    public SelectDeviceDialog(Context context, List<DeviceInfo> devices, SelectResultListener listener) {
        initView(context, devices, listener);
    }

    private void initView(Context context, List<DeviceInfo> devices, SelectResultListener listener) {
        commonDialog = new CommonDialog(context);
        commonDialog.setAlignment(LayoutAlignment.CENTER);
        commonDialog.setSize(DIALOG_WIDTH, DIALOG_HEIGHT);
        commonDialog.setAutoClosable(true);
        Component dialogLayout = LayoutScatter.getInstance(context).parse(ResourceTable.Layout_dialog_select_device, null, false);
        commonDialog.setContentCustomComponent(dialogLayout);
        if (dialogLayout.findComponentById(ResourceTable.Id_list_devices) instanceof ListContainer) {
            ListContainer devicesListContainer = (ListContainer) dialogLayout.findComponentById(ResourceTable.Id_list_devices);
            DevicesListAdapter devicesListAdapter = new DevicesListAdapter(devices, context);
            devicesListContainer.setItemProvider(devicesListAdapter);
            devicesListContainer.setItemClickedListener((listContainer, component, position, id) -> {
                listener.callBack(devices.get(position));
                commonDialog.hide();
            });
        }
        dialogLayout.findComponentById(ResourceTable.Id_cancel).setClickedListener(component -> {
            commonDialog.hide();
        });
    }

    /**
     * Show Dialog
     */
    public void show() {
        commonDialog.show();
    }

    /**
     * select device result call back interface
     * 
     * @since 2021-01-12
     */
    public interface SelectResultListener {
        /**
         * callBack
         * 
         * @param deviceInfo DeviceInfo
         */
        void callBack(DeviceInfo deviceInfo);
    }
}

package com.huawei.codelab.devices;

import com.huawei.codelab.ResourceTable;
import ohos.agp.components.BaseItemProvider;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;
import ohos.agp.components.LayoutScatter;
import ohos.agp.components.Text;
import ohos.app.Context;
import ohos.distributedschedule.interwork.DeviceInfo;
import java.util.List;
import java.util.Optional;

/**
 * DevicesListAdapter
 * 
 * @since 2021-01-11
 */
public class DevicesListAdapter extends BaseItemProvider {
    private static final int SUBSTRING_START = 0;
    private static final int SUBSTRING_END = 4;
    private List<DeviceInfo> deviceInfoList;
    private Context context;

    /**
     * DevicesListAdapter
     * 
     * @param deviceInfoList deviceInfoList
     * @param context Context
     * @since 2021-03-12
     */
    public DevicesListAdapter(List<DeviceInfo> deviceInfoList, Context context) {
        this.deviceInfoList = deviceInfoList;
        this.context = context;
    }

    @Override
    public int getCount() {
        return deviceInfoList == null ? 0 : deviceInfoList.size();
    }

    @Override
    public Object getItem(int position) {
        return Optional.of(deviceInfoList.get(position));
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public Component getComponent(int position, Component component, ComponentContainer componentContainer) {
        ViewHolder viewHolder = null;
        Component mComponent = component;
        if (mComponent == null) {
            mComponent = LayoutScatter.getInstance(context).parse(ResourceTable.Layout_item_device_list, null, false);
            viewHolder = new ViewHolder();
            if (mComponent.findComponentById(ResourceTable.Id_device_name) instanceof Text) {
                viewHolder.devicesName = (Text) mComponent.findComponentById(ResourceTable.Id_device_name);
            }
            if (mComponent.findComponentById(ResourceTable.Id_device_id) instanceof Text) {
                viewHolder.devicesId = (Text) mComponent.findComponentById(ResourceTable.Id_device_id);
            }
            mComponent.setTag(viewHolder);
        } else {
            if (mComponent.getTag() instanceof ViewHolder) {
                viewHolder = (ViewHolder) mComponent.getTag();
            }
        }
        if (viewHolder != null) {
            viewHolder.devicesName.setText(deviceInfoList.get(position).getDeviceName());
            String deviceId = deviceInfoList.get(position).getDeviceId();
            deviceId = deviceId.substring(SUBSTRING_START, SUBSTRING_END) + "******"
                + deviceId.substring(deviceId.length() - SUBSTRING_END);
            viewHolder.devicesId.setText(deviceId);
        }
        return mComponent;
    }

    /**
     * ViewHolder
     * 
     * @since 2021-03-12
     */
    private static class ViewHolder {
        private Text devicesName;
        private Text devicesId;
    }
}

这两个类使用起来也非常方便,可以直接从官方给的CodeLab示例代码中找到

直接调用下图的getDevices就行了

private List<DeviceInfo> devices = new ArrayList<>();
private void getDevices() {
    if (devices.size() > 0) {
        devices.clear();
    }
    List<DeviceInfo> deviceInfos = DeviceManager.getDeviceList(ohos.distributedschedule.interwork.DeviceInfo.FLAG_GET_ONLINE_DEVICE);
    LogUtil.info(TAG, "MathGameAbilitySlice deviceInfos size is :" + deviceInfos.size());
    devices.addAll(deviceInfos);
    showDevicesDialog();
}

private void showDevicesDialog() {
    new SelectDeviceDialog(this, devices, deviceInfo -> {
        startLocalFa(deviceInfo.getDeviceId());
        startRemoteFa(deviceInfo.getDeviceId());
    }).show();
}

private void startLocalFa(String deviceId) {
    LogUtil.info(TAG, "startLocalFa......");
    Intent intent = new Intent();
    intent.setParam(CommonData.KEY_REMOTE_DEVICEID, deviceId);
    intent.setParam(CommonData.KEY_IS_LOCAL, true);
    Operation operation = new Intent.OperationBuilder().withBundleName(getBundleName())
            .withAbilityName(CommonData.ABILITY_MAIN)
            .withAction(CommonData.DRAW_PAGE)
            .build();
    intent.setOperation(operation);
    startAbility(intent);
}

private void startRemoteFa(String deviceId) {
    LogUtil.info(TAG, "startRemoteFa......");
    String localDeviceId = KvManagerFactory.getInstance().createKvManager(new KvManagerConfig(this)).getLocalDeviceInfo().getId();
    Intent intent = new Intent();
    intent.setParam(CommonData.KEY_REMOTE_DEVICEID, localDeviceId);
    intent.setParam(CommonData.KEY_IS_LOCAL, false);
    Operation operation = new Intent.OperationBuilder().withDeviceId(deviceId)
            .withBundleName(getBundleName())
            .withAbilityName(CommonData.ABILITY_MAIN)
            .withAction(CommonData.DRAW_PAGE)
            .withFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE)
            .build();
    intent.setOperation(operation);
    startAbility(intent);
}

2、前端界面的绘制

ability_main

<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
    xmlns:ohos="http://schemas.huawei.com/res/ohos"
    ohos:height="match_parent"
    ohos:width="match_parent"
    ohos:orientation="vertical">
    <Text
        ohos:height="match_content"
        ohos:width="match_content"
        ohos:layout_alignment="horizontal_center"
        ohos:padding="10vp"
        ohos:text="基于HarmonyOS分布式技术的"
        ohos:text_size="20vp"
        ohos:top_padding="20vp"/>
    <Text
        ohos:height="match_content"
        ohos:width="match_content"
        ohos:layout_alignment="horizontal_center"
        ohos:text="‘井’字小游戏"
        ohos:text_size="20vp"/>
    <Image
        ohos:height="350vp"
        ohos:width="match_parent"
        ohos:left_margin="10vp"
        ohos:right_margin="10vp"
        ohos:image_src="$media:picture_10"/>
    <Button
        ohos:id="$+id:math_game"
        ohos:height="100vp"
        ohos:width="300vp"
        ohos:background_element="$graphic:background_button"
        ohos:layout_alignment="horizontal_center"
        ohos:left_padding="15vp"
        ohos:right_padding="15vp"
        ohos:text="‘井’字小游戏"
        ohos:text_size="30vp"
        ohos:top_margin="20vp"/>
</DirectionalLayout>

game

<?xml version="1.0" encoding="utf-8"?>
<DependentLayout
    xmlns:ohos="http://schemas.huawei.com/res/ohos"
    ohos:background_element="#eeeeee"
    ohos:height="match_parent"
    ohos:orientation="vertical"
    ohos:width="match_parent">
    <DependentLayout
        ohos:height="match_parent"
        ohos:id="$+id:bac_area"
        ohos:width="match_parent">
        <DirectionalLayout
            ohos:height="match_parent"
            ohos:orientation="vertical"
            ohos:width="match_parent">
            <DependentLayout
                ohos:height="50vp"
                ohos:id="$+id:header"
                ohos:width="match_parent">
                <Text
                    ohos:id="$+id:text_title"
                    ohos:align_parent_left="true"
                    ohos:height="match_content"
                    ohos:left_margin="12vp"
                    ohos:text="远程画图页面"
                    ohos:text_size="38fp"
                    ohos:vertical_center="true"
                    ohos:width="match_content"/>
                <Button
                    ohos:height="match_parent"
                    ohos:width="100vp"
                    ohos:id="$+id:clear_points"
                    ohos:text="清除"
                    ohos:auto_font_size="true"
                    ohos:background_element="$graphic:background_button"
                    ohos:align_parent_right="true"/>
            </DependentLayout>
            <DirectionalLayout
                ohos:height="match_content"
                ohos:id="$+id:product_list"
                ohos:orientation="vertical"
                ohos:width="match_parent"/>
        </DirectionalLayout>
    </DependentLayout>
    <Component
        ohos:height="6px"
        ohos:width="match_parent"
        ohos:top_margin="250vp"
        ohos:left_margin="10vp"
        ohos:right_margin="10vp"
        ohos:background_element="#000000"/>
    <Component
        ohos:height="6px"
        ohos:width="match_parent"
        ohos:left_margin="10vp"
        ohos:right_margin="10vp"
        ohos:top_margin="450vp"
        ohos:background_element="#000000"/>
    <Component
        ohos:height="match_parent"
        ohos:width="6px"
        ohos:top_margin="150vp"
        ohos:bottom_margin="50vp"
        ohos:left_margin="100vp"
        ohos:background_element="#000000"/>
    <Component
        ohos:height="match_parent"
        ohos:width="6px"
        ohos:left_margin="250vp"
        ohos:top_margin="150vp"
        ohos:bottom_margin="50vp"
        ohos:background_element="#000000"/>
</DependentLayout>

因为我也是刚开始学习分布式,再加上最近事儿比较多,所以本贴主要就是展示“井”字小游戏啦!

同时,也期待能够在HDC开发者大会上见到HarmonyOS 3.0!!!提前祝各位1024节快乐呀!!!愿鸿蒙越做越好,争取早日走向世界!!!


更多关于HarmonyOS鸿蒙Next“井”字小游戏的实战教程也可以访问 https://www.itying.com/category-93-b0.html

6 回复

老哥有源码吗,最近在学分布式相关内容,能不能发我一份参考下,非常感谢!

更多关于HarmonyOS鸿蒙Next“井”字小游戏的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


参考官方codelab:https://developer.huawei.com/consumer/cn/codelabsPortal/carddetails/Distribute-Database-Draw

  • 作者: harp
  • 创建时间: 2024年2月29日
  • 最后修改时间: 2024年2月29日

666,人的创造力果然是无限的

要是能加上判输赢就好了,

确实…哪天有空整整,嘿嘿(≧∇≦*)

HarmonyOS鸿蒙Next的“井”字小游戏是一款基于鸿蒙系统开发的经典双人策略游戏。玩家通过点击3x3的网格,轮流放置“X”或“O”,目标是在水平、垂直或对角线上先连成一条线。该游戏充分利用了鸿蒙系统的分布式能力,支持多设备协同操作,用户可以在手机、平板或智慧屏等设备上无缝切换游戏体验。同时,游戏界面简洁流畅,操作响应迅速,展现了鸿蒙系统的高效性能与用户体验优化。

回到顶部