Development/Tutorials/Games/Palapeli Slicers

Jump to: navigation, search
Creating a Palapeli pattern
Tutorial Series   Programming with the Palapeli API
Previous   Introduction to KDE4 programming
What's Next   n/a
Further Reading   Palapeli::Pattern, Palapeli::PatternConfiguration
{{{3}}}
 
I'm currently creating this tutorial. You should not edit this page in the mean time. -- Majewsky 18:19, 20 July 2008 (CEST)
Warning to editors


Contents

Abstract

This tutorial shows you how to create a pattern for Palapeli, that is: a plugin for the Palapeli libraries that describes an algorithm to split an image into pieces.

The pattern we will be constructing is quite easy: It splits an image into two equally sized pieces.

Structure

A pattern plugin consists of two classes. The first one (derived from Palapeli::PatternConfiguration) tells Palapeli what features this pattern plugin has and which configuration values it needs. The second one (derived from Palapeli::Pattern) does the actual slicing.

The code: mypattern.h

  1. ifndef MYPATTERN_H
  2. define MYPATTERN_H
  1. include <Palapeli/Pattern>
  2. include <Palapeli/PatternConfiguration>

class MyPattern : public Palapeli::Pattern { public: MyPattern(); virtual ~MyPattern() {}

virtual int estimatePieceCount() const; protected: virtual void doSlice(const QImage& image); };

class MyPatternConfiguration : public Palapeli::PatternConfiguration { public: MyPatternConfiguration(QObject* parent = 0, const QVariantList& args = QVariantList()); virtual ~MyPatternConfiguration() {} virtual Palapeli::Pattern* createPattern() const; };

  1. endif // MYPATTERN_H

As described above, we have declared two classes deriving from the base classes Palapeli::Pattern and Palapeli::PatternConfiguration. For this simple example, we do only reimplement constructors, destructors and some pure virtual functions.

The code: mypattern.cpp

  1. include "mypattern.h"
  1. include <QImage>
  2. include <KPluginFactory>
  3. include <KPluginLoader>

K_PLUGIN_FACTORY(MyPatternFactory, registerPlugin<MyPatternConfiguration>();) K_EXPORT_PLUGIN(MyPatternFactory("mypattern"))

MyPattern::MyPattern() : Palapeli::Pattern() { }

int MyPattern::estimatePieceCount() const {

   return 2;

}

void MyPattern::doSlice(const QImage& image) {

   //construct pixmaps for the pieces
   const int pieceWidth = image.width() / 2, pieceHeight = image.height();
   QImage leftPiece = image.copy(QRect(0, 0, pieceWidth, pieceHeight));
   QImage rightPiece = image.copy(QRect(pieceWidth, 0, pieceWidth, pieceHeight));
   //add pieces; define a neighborship relation between them
   addPiece(leftPiece, QRectF(0, 0, pieceWidth, pieceHeight));
   addPiece(rightPiece, QRectF(pieceWidth, 0, pieceWidth, pieceHeight));
   addRelation(0, 1, QPointF(pieceWidth, 0)); //0 and 1 are the consecutive indices of the pieces

}

MyPatternConfiguration::MyPatternConfiguration(QObject* parent, const QVariantList& args)

   : Palapeli::PatternConfiguration(parent, args)

{

   Q_UNUSED(parent)
   Q_UNUSED(args)
   setSizeDefinitionMode(Palapeli::PatternConfiguration::CustomSizeDefinition);

}

Palapeli::Pattern* MyPatternConfiguration::createPattern() const {

   return new MyPattern;

}

We will start with the MyPatternConfiguration class, because this is the logical entry point. The pattern configuration class is created when Palapeli is started. Its job is to manage the pattern's settings. In this case, there is nothing to configure. If you want to implement a size definition by the number of pieces in horizontal and in vertical direction (as for the standard rectangular piece pattern), you can simply set the size definition mode to Palapeli::PatternConfiguration::CountSizeDefinition. Arbitrary configuration can be achieved by adding widgets through the Palapeli::PatternConfiguration::addWidget method.

When the user has configured its game (and therefore the pattern), the Palapeli game engine will call the createPattern method to create a Palapeli::Pattern object. If you have added configuration values, pass them to the constructor of your pattern object, and save them in private variables. If you have chosen the CountSizeDefinition, you can use the xCount and yCount methods to retrieve the configured values. See the implementation of the standard rectangular pattern for details on how to use this size definition mode.

Now we have a Palapeli::Pattern instance.

Integrate into Palapeli: mypattern.desktop

[Desktop Entry] X-KDE-Library=mypattern X-KDE-PluginInfo-Author=The best KDE hacker X-KDE-PluginInfo-Email=kdehacker@kde-hackers.example.org X-KDE-PluginInfo-Name=mypattern X-KDE-PluginInfo-Version=1.0 X-KDE-PluginInfo-Website=http://kde-hackers.example.org/palapelipatterns X-KDE-PluginInfo-Category= X-KDE-PluginInfo-Depends= X-KDE-PluginInfo-License=GPL X-KDE-PluginInfo-EnabledByDefault=true X-KDE-ParentApp=libpalapelipattern X-KDE-ServiceTypes=Palapeli/PatternPlugin Type=Service Icon=palapeli-pattern-mypattern PatternIdentifier=mypattern Name=My pattern Name[de]=Mein Schnittmuster Comment=The best pattern in the world Comment[de]=Das beste Schnittmuster auf der ganzen Welt

Build everything: CMakeLists.txt

project(mypattern)

find_package(KDE4 REQUIRED) find_package(Palapeli REQUIRED)

add_definitions(${QT_DEFINITIONS} ${KDE4_DEFINITIONS}) include_directories(${KDE4_INCLUDES} ${PALAPELI_INCLUDE_DIR})

set(mypattern_SRCS mypattern.cpp )

kde4_add_plugin(mypattern ${mypattern_SRCS}) target_link_libraries(mypattern ${KDE4_KDEUI_LIBS} palapelipattern)

install(TARGETS mypattern DESTINATION ${PLUGIN_INSTALL_DIR}) install(FILES mypattern.desktop DESTINATION ${SERVICES_INSTALL_DIR})


KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V.Legal