2012年4月26日木曜日

フリーソフトの公開 その2


はいどうも。かねてから作成していた暗記カードもどきソフトが完成したので公開します。今のところ説明書とかサンプルとかがかなりアレですが...(超やっつけです。はい。)

まぁそんなに難しいことやってないんで直感的に使えると思います。よかったら使ってみてください。

不具合があった場合はブログ内の障害の報告から連絡してください。可能な限り修正します。
ああ、それと報告の際の名前入力とか適当でいいです。一貫性とかルールありませんから。url, mailは仕様上はずせないので表示していますが、空欄で構いません。
本当はコメント欄開放すればいいんですがコメントってチェックするのもメンドイし、いちいち返信するのもメンドイし、面倒だし、面倒だからねぇ。顔の見えない相手と世間話もアレだしねぇ。でも何より縦にコメントがバァーっとね並ぶあの記事より目立っちゃってる感がレイアウト的に嫌なんですよね。コメント欄同士で議論なんか始まったあかつきにはもう記事なんておいてけぼりですよ。ええ。

とまぁそういうわけでコメント開放の予定はありません。「こんのフライドチキン野郎!けしからん!どうにかして灸を据えてやらにゃいかん!」という方は障害報告で適当な名前で憂さ晴らししてください。

とりあえず以上です。

2012年4月25日水曜日

( Game ( C++ ) )状態遷移について

新しくゲームに関するページを作成しました。対象読者は「ゲームプログラマ!?はっ...無理無理。興味もねぇし。でもまぁ技術には興味ある。」というかたを想定しています。わたしもゲームプログラマにはまったく興味がありません。実力的にも無理でしょうしね。公式をプログラムに変換とか、どの公式を利用して画面にでっちあげるかとか、私にはそんな発想力ありません。あの世界では数学、物理にある程度強くないと最前線ではやっていけない感じがします。

まぁでも中で何をやっているのかってすごく興味があるんですよね。このフワッとしたキャラ移動どうやったとか。
また、ゲームの画像移動になれておくと、通常のアプリケーションで臆することなく動的な画面効果をフフンとだせるようにもなるんじゃないかと思うんですよね。んでwindows8とか巣魔ー戸電話とかこういうの多用してるっぽいじゃないですか?あのヌルヌル現在の画面が移動していくみたいなアレね。私自身は「あんなもんただの○ソだろ。意味あんのか?とりあえず○indows8はアンチエ○リアス先かけろ」なんて思っていますが、時代には逆らえません。

...とまぁ長々と書きましたが、とにもかくにもゲーム関連の記事やっていこうと思います。


本日はシューティングゲームを作った際、最もコードが複雑化した部分「状態遷移」について書いていこうと思います。
「状態遷移!?そんなとこで詰まってんの?人生大丈夫?」そう思った方、実際作ってみてください。普段からかなり勉強されているかたは難なくクリアできるでしょう。しかし、そうではない方はかなり苦戦するはずです。

状態遷移の例題を提示します。
・用意する状態はタイトル、ゲームオーバー、エンディング、1Pプレイ、2Pプレイ、ポーズ画面の5つとします。
・タイトルから1Pプレイか2Pプレイに飛べます。
・1Pプレイ、2Pプレイからポーズ、ゲームオーバー 、エンディング、タイトルへ飛べるようにする。
・ゲームオーバー、エンディング後はタイトルに飛びます。
・ポーズ画面からは現在プレイ中の画面(1Por2P)にしか戻れません。 
・必ず画面には現在の状態を表す画像か文字列を表示してください。
※当たり前ですがゲームを意識して作成してください。

図示すると以下のようになります。
状態遷移の数もかなり減らし、ゲームの骨格も丸まる無視しましたので難易度的には通常のゲームよりは簡単であろうかと思いますが...まぁやってみてください。言語はなんでもかまいません。C++でもC#でもQtでもお好きなものを。

とりあえず今日はこのへんで。


2012年4月18日水曜日

雑記


どうも皆さんご無沙汰です。
最近は投稿が滞っています。病気?仕事?付き合い?それもありますが、一番大きいのは飽きてしまったということです。

アウトプットによる復習効果を期待して始めたブログですが、なんていうか、ブログにまとめるという作業がやってみるとかなり面倒なんですね。30分から1時間とられてしまいます。で、なんていうかその時間がもったいないなぁという感覚になってきたわけです。
また、大方Qtの記事も基本系はそろってきたので、小ネタにシフトしなければならず、それを考えるのも面倒な感じになってきたわけです。 ええ、とどのつまりブログそのものが面倒系で面倒な感じで面倒なんです。

でこれからブログどうするかということなんですが、まぁ閉鎖はしません。まったり投稿にシフトしていこうと思います。そしてQt特化をやめます。いろんな言語のものをダラダラと書いていこうと思います。
というわけで、以上です。


2012年4月3日火曜日

( Qt C++ )ツールバーに項目をセットする


最近、風邪をこじらせてしまって体が関節痛でキッツイです。いつもはすぐ直るのですが今回は油断しました。やはり初期の段階で薬を飲んでおくべきでした。まぁ今更なげいてもしかたがありませんが...


はい、それでは表題の件やっていきます。
ちなみにツールバーって何かというと

の赤枠線内の部分です。よく使いますよね。

サンプルは独自のものを使用します。
また、いつものようにQtCreaterの使用を前提とします。(QtCreaterなどの使い方は ”Qtをはじめよう" を見てください。)

ではさっそくやっていきます。

まず新規プロジェクトを作成してください。(Qt ウィジットプロジェクトのQt GUI アプリケーションを選択し、適当な名前をつけてください。)
そうするとツールバーも既に配置されたMainWindowが表示されると思います。これで下準備は終了です。

では次にデザイナ下の方にあるアクションエディタを使用します。新規作成を押し、"Open", "Close", "Cut"のアクションを作成してください。ちなみにCutアクションは文字ではなくアイコンをセットします。

作成後、これらのアクションを順にツールバーにドラッグ&ドロップして配置していきます。
(ちなみにセパレータも配置できます。ツールバー上で右クリックし、適宜配置してください。)

 これで配置完了です。それではここからコード書きに入ります。

(mainwindow.h)

#include <QMainWindow>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT
    
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    
private slots:
    void on_actionOpen_triggered();
    void CloseClicked();
    void CutClicked();

private:
    Ui::MainWindow *ui;
};

(mainwindow.cpp)

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    connect(ui->actionClose, SIGNAL(triggered()), this, SLOT(CloseClicked()));
    connect(ui->actionCut, SIGNAL(triggered()), this, SLOT(CutClicked()));
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_actionOpen_triggered()
{
    ui->label->setText("Open Click");
}

void MainWindow::CloseClicked()
{
    ui->label->setText("Close Click");
}

void MainWindow::CutClicked()
{
    ui->label->setText("Cut Click");
}


はい簡単ですね。
Openはon_actionOpen_triggeredでどこにもconnectせずにシグナルを補足しています。この辺りは”Qtをはじめよう"に書いてあったはずなのでそちらを参照してください。CloseとCutについてはコンストラクタで両方ともconnectしています。

これらを実行すると以下のようになります。
(起動時画面)

(ツールバーのOpenを押したとき)

以上です。


※補足
デザイナやアクションエディタを使用せず自分で手書きする場合は以下のコードを参考にしてください。(Qt Createrが吐いたコードです。)
#include <QtCore/QVariant>
#include <QtGui/QAction>
#include <QtGui/QApplication>
#include <QtGui/QButtonGroup>
#include <QtGui/QHeaderView>
#include <QtGui/QLabel>
#include <QtGui/QMainWindow>
#include <QtGui/QMenuBar>
#include <QtGui/QStatusBar>
#include <QtGui/QToolBar>
#include <QtGui/QWidget>

QT_BEGIN_NAMESPACE

class Ui_MainWindow
{
public:
    QAction *actionOpen;
    QAction *actionClose;
    QAction *actionCut;
    QWidget *centralWidget;
    QLabel *label;
    QMenuBar *menuBar;
    QToolBar *mainToolBar;
    QStatusBar *statusBar;

    void setupUi(QMainWindow *MainWindow)
    {
        if (MainWindow->objectName().isEmpty())
            MainWindow->setObjectName(QString::fromUtf8("MainWindow"));
        MainWindow->resize(400, 300);
        actionOpen = new QAction(MainWindow);
        actionOpen->setObjectName(QString::fromUtf8("actionOpen"));
        actionClose = new QAction(MainWindow);
        actionClose->setObjectName(QString::fromUtf8("actionClose"));
        actionCut = new QAction(MainWindow);
        actionCut->setObjectName(QString::fromUtf8("actionCut"));
        QIcon icon;
        icon.addFile(QString::fromUtf8("../toolbar-build-desktop-Qt_4_7_4_for_Desktop_-_MSVC2008__Qt_SDK__Debug/trimming_img.gif"), QSize(), QIcon::Normal, QIcon::Off);
        icon.addFile(QString::fromUtf8("../GameProgram/SettingFiles/CharacterImage/life.png"), QSize(), QIcon::Selected, QIcon::On);
        actionCut->setIcon(icon);
        centralWidget = new QWidget(MainWindow);
        centralWidget->setObjectName(QString::fromUtf8("centralWidget"));
        label = new QLabel(centralWidget);
        label->setObjectName(QString::fromUtf8("label"));
        label->setGeometry(QRect(79, 100, 221, 20));
        MainWindow->setCentralWidget(centralWidget);
        menuBar = new QMenuBar(MainWindow);
        menuBar->setObjectName(QString::fromUtf8("menuBar"));
        menuBar->setGeometry(QRect(0, 0, 400, 24));
        MainWindow->setMenuBar(menuBar);
        mainToolBar = new QToolBar(MainWindow);
        mainToolBar->setObjectName(QString::fromUtf8("mainToolBar"));
        MainWindow->addToolBar(Qt::TopToolBarArea, mainToolBar);
        statusBar = new QStatusBar(MainWindow);
        statusBar->setObjectName(QString::fromUtf8("statusBar"));
        MainWindow->setStatusBar(statusBar);

        mainToolBar->addAction(actionOpen);
        mainToolBar->addSeparator();
        mainToolBar->addAction(actionClose);
        mainToolBar->addSeparator();
        mainToolBar->addAction(actionCut);
        mainToolBar->addSeparator();

        retranslateUi(MainWindow);

        QMetaObject::connectSlotsByName(MainWindow);
    } // setupUi

    void retranslateUi(QMainWindow *MainWindow)
    {
        MainWindow->setWindowTitle(QApplication::translate("MainWindow", "MainWindow", 0, QApplication::UnicodeUTF8));
        actionOpen->setText(QApplication::translate("MainWindow", "Open", 0, QApplication::UnicodeUTF8));
        actionClose->setText(QApplication::translate("MainWindow", "Close", 0, QApplication::UnicodeUTF8));
        actionCut->setText(QApplication::translate("MainWindow", "Cut", 0, QApplication::UnicodeUTF8));
        label->setText(QApplication::translate("MainWindow", "\343\201\223\343\201\223\343\201\253\350\241\250\347\244\272\343\201\225\343\202\214\343\201\276\343\201\231\343\200\202", 0, QApplication::UnicodeUTF8));
    } // retranslateUi

};

namespace Ui {
    class MainWindow: public Ui_MainWindow {};
} // namespace Ui