• Что бы вступить в ряды "Принятый кодер" Вам нужно:
    Написать 10 полезных сообщений или тем и Получить 10 симпатий.
    Для того кто не хочет терять время,может пожертвовать средства для поддержки сервеса, и вступить в ряды VIP на месяц, дополнительная информация в лс.

  • Пользаватели которые будут спамить, уходят в бан без предупреждения. Спам сообщения определяется администрацией и модератором.

  • Гость, Что бы Вы хотели увидеть на нашем Форуме? Изложить свои идеи и пожелания по улучшению форума Вы можете поделиться с нами здесь. ----> Перейдите сюда
  • Все пользователи не прошедшие проверку электронной почты будут заблокированы. Все вопросы с разблокировкой обращайтесь по адресу электронной почте : info@guardianelinks.com . Не пришло сообщение о проверке или о сбросе также сообщите нам.

HarmonyOS NEXT Development Case Study: Jigsaw Puzzle

Lomanu4 Оффлайн

Lomanu4

Команда форума
Администратор
Регистрация
1 Мар 2015
Сообщения
1,481
Баллы
155

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.



This article demonstrates a jigsaw puzzle implementation using HarmonyOS NEXT, featuring image selection, puzzle piece generation, shuffling, and game logic. The solution leverages ArkUI components and HarmonyOS native capabilities.

Project Structure

1. Module Imports


// Core modules
import { fileIo as fs } from '@kit.CoreFileKit'; // File operations module
import { common } from '@kit.AbilityKit'; // Application capability module
import { promptAction } from '@kit.ArkUI'; // UI prompt module
import { image } from '@kit.ImageKit'; // Image processing module
import { photoAccessHelper } from '@kit.MediaLibraryKit'; // Media library access module
2. Data Structure


interface PuzzlePiece {
pixelMap: image.PixelMap; // Pixel map of the puzzle piece
originalIndex: number; // Original position index in the image
}
Core Implementation

3. Page Component Setup


@Entry // Entry component
@Component // Custom component
struct Page30 {
@State selectedImageUrl: string = ''; // Displayed image URI
@State originalImageUrl: string = ''; // Source image URI
@State puzzlePieces: Array<PuzzlePiece> = []; // Puzzle pieces array
@State selectedPiece: number = -1; // Selected piece index
4. Image Selection Logic


async openPicker() {
try {
const PhotoSelectOptions = new photoAccessHelper.PhotoSelectOptions();
PhotoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE;
PhotoSelectOptions.maxSelectNumber = 1;

const photoPicker = new photoAccessHelper.PhotoViewPicker();
const uris = await photoPicker.select(PhotoSelectOptions);

if (!uris?.photoUris.length) return;
const uri = uris.photoUris[0];

// File operations
const file = fs.openSync(uri, fs.OpenMode.READ_ONLY);
const context = getContext(this) as common.UIAbilityContext;
const newUrl = `${context.filesDir}/test${Date.now()}.jpg`;

fs.copyFileSync(file.fd, newUrl);
fs.closeSync(file);

this.selectedImageUrl = newUrl;
this.originalImageUrl = uri;
this.imgChange();
} catch (e) {
console.error('openPicker', JSON.stringify(e));
}
}
5. Image Processing


async imgChange() {
try {
const imageSource = image.createImageSource(this.selectedImageUrl);
const decodingOptions: image.DecodingOptions = {
editable: true,
desiredPixelFormat: 3
};

const mPixelMap = await imageSource.createPixelMap(decodingOptions);
const mImageInfo = await mPixelMap.getImageInfo();

// Calculate grid dimensions
const pieceSize: image.Size = {
width: mImageInfo.size.width / 3,
height: mImageInfo.size.height / 3
};

this.puzzlePieces = [];
let count = 0;

// Generate puzzle pieces
for (let row = 0; row < 3; row++) {
for (let col = 0; col < 3; col++) {
const cutRegion: image.Region = {
x: col * pieceSize.width,
y: row * pieceSize.height,
size: pieceSize
};

const newSource = image.createImageSource(this.selectedImageUrl);
const pieceMap = await newSource.createPixelMap(decodingOptions);
await pieceMap.crop(cutRegion);

this.puzzlePieces.push({
pixelMap: pieceMap,
originalIndex: count++
});
}
}

// Shuffle algorithm
for (let i = this.puzzlePieces.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[this.puzzlePieces, this.puzzlePieces[j]] =
[this.puzzlePieces[j], this.puzzlePieces];
}
} catch (e) {
console.error('imgChange', JSON.stringify(e));
}
}
UI Implementation

6. Game Interface


build() {
Column() {
Button('Select Image →')
.onClick(() => this.openPicker());

if (this.originalImageUrl) {
Text('Original Image ↓');
Image(this.originalImageUrl)
.size({ width: '180lpx', height: '180lpx' })
.objectFit(ImageFit.Contain);
}

if (this.puzzlePieces.length) {
Text('Puzzle Game ↓');
Grid() {
ForEach(this.puzzlePieces, (item, index) => {
GridItem() {
Image(item.pixelMap)
.size({ width: '200lpx', height: '200lpx' })
.margin('5lpx')
.scale(this.selectedPiece === index ? { x: 0.5, y: 0.5 } : { x: 1, y: 1 })
.onClick(() => {
if (this.selectedPiece === -1) {
this.selectedPiece = index;
} else if (this.selectedPiece === index) {
this.selectedPiece = -1;
} else {
// Swap pieces
[this.puzzlePieces[this.selectedPiece], this.puzzlePieces[index]] =
[this.puzzlePieces[index], this.puzzlePieces[this.selectedPiece]];

// Check completion
const isComplete = this.puzzlePieces.every(
(piece, i) => piece.originalIndex === i
);

this.selectedPiece = -1;
if (isComplete) {
promptAction.showDialog({ message: 'Puzzle Completed!' });
}
}
});
}
})
}
.backgroundColor('#fafafa');
}
.width('100%');
}
Key Features


  1. Media Library Integration:
    • Uses photoAccessHelper for secure image selection
    • Implements proper file handling with sandboxed storage

  2. Image Processing:
    • Dynamic grid division based on image dimensions
    • Non-destructive editing using pixel map operations

  3. Game Mechanics:
    • Fisher-Yates shuffle algorithm
    • Visual selection feedback with scaling animation
    • Real-time completion check

  4. Performance:
    • Asynchronous operations for image processing
    • Memory management through proper resource cleanup

This implementation demonstrates HarmonyOS NEXT's capabilities in building interactive media applications with proper resource management and responsive UI design.


Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

 
Вверх Снизу