下面是一个使用DevEco Studio和HarmonyOS 5开发简单射箭小游戏的实现方案:

1. 项目准备

  1. 在DevEco Studio中创建新项目,选择"Empty Ability"模板
  2. 确保SDK版本选择HarmonyOS 5.0或更高

2. 游戏核心代码实现

2.1 主页面布局 (resources/base/layout/ability_main.xml)

<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
    xmlns:ohos="http://schemas.huawei.com/res/ohos"
    ohos:width="match_parent"
    ohos:height="match_parent"
    ohos:orientation="vertical"
    ohos:background_element="#FFD700">
    
    <DirectionalLayout
        ohos:width="match_parent"
        ohos:height="match_parent"
        ohos:weight="1">
        
        <Image
            ohos:id="$+id:bow"
            ohos:width="100vp"
            ohos:height="100vp"
            ohos:image_src="$media:bow"
            ohos:layout_alignment="bottom|left"
            ohos:margin_left="20vp"
            ohos:margin_bottom="20vp"/>
            
        <Image
            ohos:id="$+id:target"
            ohos:width="150vp"
            ohos:height="150vp"
            ohos:image_src="$media:target"
            ohos:layout_alignment="center|right"
            ohos:margin_right="20vp"/>
            
    </DirectionalLayout>
    
    <DirectionalLayout
        ohos:width="match_parent"
        ohos:height="100vp"
        ohos:orientation="horizontal"
        ohos:padding="20vp">
        
        <Text
            ohos:id="$+id:scoreText"
            ohos:width="match_parent"
            ohos:height="match_parent"
            ohos:text="得分: 0"
            ohos:text_size="20fp"
            ohos:text_color="#000000"/>
            
        <Button
            ohos:id="$+id:restartBtn"
            ohos:width="150vp"
            ohos:height="50vp"
            ohos:text="重新开始"
            ohos:background_element="#4CAF50"
            ohos:text_color="#FFFFFF"
            ohos:margin_left="20vp"/>
            
    </DirectionalLayout>
    
</DirectionalLayout>

2.2 主逻辑代码 (MainAbilitySlice.java)

package com.example.archerygame.slice;

import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.components.*;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.utils.Point;
import ohos.multimodalinput.event.TouchEvent;
import java.util.ArrayList;
import java.util.Random;

public class MainAbilitySlice extends AbilitySlice {
    private Image bow;
    private Image target;
    private Text scoreText;
    private Button restartBtn;
    
    private int score = 0;
    private ArrayList<Image> arrows = new ArrayList<>();
    
    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_main);
        
        // 初始化组件
        bow = (Image) findComponentById(ResourceTable.Id_bow);
        target = (Image) findComponentById(ResourceTable.Id_target);
        scoreText = (Text) findComponentById(ResourceTable.Id_scoreText);
        restartBtn = (Button) findComponentById(ResourceTable.Id_restartBtn);
        
        // 设置弓的触摸事件
        bow.setTouchEventListener(new Component.TouchEventListener() {
            private float startX, startY;
            
            @Override
            public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
                switch (touchEvent.getAction()) {
                    case TouchEvent.PRIMARY_POINT_DOWN:
                        startX = touchEvent.getPointerPosition(0).getX();
                        startY = touchEvent.getPointerPosition(0).getY();
                        return true;
                        
                    case TouchEvent.PRIMARY_POINT_UP:
                        float endX = touchEvent.getPointerPosition(0).getX();
                        float endY = touchEvent.getPointerPosition(0).getY();
                        
                        // 计算滑动距离和方向
                        float dx = endX - startX;
                        float dy = endY - startY;
                        
                        // 发射箭
                        shootArrow(dx, dy);
                        return true;
                }
                return false;
            }
        });
        
        // 重新开始按钮
        restartBtn.setClickedListener(component -> {
            score = 0;
            scoreText.setText("得分: 0");
            clearArrows();
            moveTargetToRandomPosition();
        });
        
        // 初始目标位置
        moveTargetToRandomPosition();
    }
    
    private void shootArrow(float dx, float dy) {
        // 创建箭
        Image arrow = new Image(getContext());
        arrow.setWidth(50);
        arrow.setHeight(10);
        arrow.setImageAndDecodeBounds(ResourceTable.Media_arrow);
        
        // 设置初始位置(弓的位置)
        int[] bowLocation = new int[2];
        bow.getLocationOnScreen(bowLocation);
        arrow.setPixelPosition(bowLocation[0] + bow.getWidth(), bowLocation[1] + bow.getHeight() / 2);
        
        // 添加到布局
        DirectionalLayout layout = (DirectionalLayout) findComponentById(ResourceTable.Id_main_layout);
        layout.addComponent(arrow);
        arrows.add(arrow);
        
        // 动画移动箭
        AnimatorProperty animator = arrow.createAnimatorProperty();
        animator.moveFromX(arrow.getContentPositionX())
                .moveFromY(arrow.getContentPositionY())
                .moveToX(arrow.getContentPositionX() + dx * 2)
                .moveToY(arrow.getContentPositionY() + dy * 2)
                .setDuration(1000)
                .setCurveType(Animator.CurveType.LINEAR);
        
        animator.setStateChangedListener(new Animator.StateChangedListener() {
            @Override
            public void onStart(Animator animator) {}
            
            @Override
            public void onStop(Animator animator) {}
            
            @Override
            public void onCancel(Animator animator) {}
            
            @Override
            public void onEnd(Animator animator) {
                // 检查是否命中目标
                checkHit(arrow);
            }
            
            @Override
            public void onPause(Animator animator) {}
            
            @Override
            public void onResume(Animator animator) {}
        });
        
        animator.start();
    }
    
    private void checkHit(Image arrow) {
        int[] arrowPos = new int[2];
        arrow.getLocationOnScreen(arrowPos);
        
        int[] targetPos = new int[2];
        target.getLocationOnScreen(targetPos);
        
        // 简单碰撞检测
        if (arrowPos[0] >= targetPos[0] && 
            arrowPos[0] <= targetPos[0] + target.getWidth() &&
            arrowPos[1] >= targetPos[1] && 
            arrowPos[1] <= targetPos[1] + target.getHeight()) {
            
            // 命中目标
            score += 10;
            scoreText.setText("得分: " + score);
            
            // 移动目标到新位置
            moveTargetToRandomPosition();
        }
    }
    
    private void moveTargetToRandomPosition() {
        Random random = new Random();
        DirectionalLayout layout = (DirectionalLayout) findComponentById(ResourceTable.Id_main_layout);
        
        int maxX = layout.getWidth() - target.getWidth();
        int maxY = layout.getHeight() - target.getHeight();
        
        int newX = random.nextInt(maxX);
        int newY = random.nextInt(maxY / 2) + (layout.getHeight() / 3); // 保持在屏幕上半部分
        
        target.setPixelPosition(newX, newY);
    }
    
    private void clearArrows() {
        DirectionalLayout layout = (DirectionalLayout) findComponentById(ResourceTable.Id_main_layout);
        for (Image arrow : arrows) {
            layout.removeComponent(arrow);
        }
        arrows.clear();
    }
}

2.3 资源文件

  1. 在resources/base/media目录下添加以下图片资源:

    • bow.png (弓的图像)
    • target.png (靶子的图像)
    • arrow.png (箭的图像)
  2. 在resources/base/element目录下创建colors.json:

{
    "colors": [
        {
            "name": "primary_color",
            "value": "#4CAF50"
        },
        {
            "name": "background_color",
            "value": "#FFD700"
        }
    ]
}

3. 游戏功能说明

  1. ​游戏玩法​​:

    • 玩家在弓上滑动手指来发射箭
    • 滑动方向和距离决定箭的飞行轨迹
    • 命中靶子得10分,靶子会随机移动到新位置
  2. ​功能特点​​:

    • 触摸控制发射箭
    • 简单的碰撞检测
    • 得分系统
    • 重新开始功能
  3. ​扩展建议​​:

    • 添加难度级别(靶子移动速度、大小变化)
    • 添加音效
    • 实现更精确的物理模拟
    • 添加关卡系统

4. 运行效果

游戏运行后,玩家可以通过在弓上滑动来发射箭。箭会沿着滑动方向飞行,如果命中靶子,玩家得分增加,靶子会随机移动到新位置。点击"重新开始"按钮可以重置游戏。

这个实现使用了HarmonyOS的基本组件和动画功能,适合作为入门级游戏开发示例。您可以根据需要进一步扩展和完善功能。

Logo

社区规范:仅讨论OpenHarmony相关问题。

更多推荐