リナザウのソフトウェア開発


○ 第4章 画面にペイントしてみる「RPGみたいなマップを作る」






前回作成したキャンバスに、RPGみたいなマップを配置してみましょう。
また、ここでは「繰り返し(for,while)」「ファイルの読み込み」「CSVファイルの読み込み」についても触れています。




<CPPファイル名 main.cpp>

#include <qpe/qpeapplication.h>   // 使用するクラスを指定する

#include "mainwindow.h"   // 使用するプログラムを指定する

int main(int argc, char *argv[])
{
	QPEApplication a(argc,argv);
	Mainwindow *mw = new Mainwindow();
	a.showMainWidget(mw);
	return a.exec();
}


(解説は、かきかけ)



<ヘッダーファイル名 mainwindow.h>

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <qmainwindow.h>   // 使用するクラスを指定する
#include <qapplication.h>
#include <qcanvas.h>
#include <qtextcodec.h>
#include <qfont.h>
#include <qpixmap.h>
#include <qfile.h>
#include <qtextstream.h>
#include <qstring.h>

class Mainwindow : public QWidget{
	Q_OBJECT

public:
	Mainwindow(QWidget *parent = 0, const char *name = 0);

protected:
    void paintEvent( QPaintEvent * );

private:
	QTextCodec *codec; // テキストコーデック
	QCanvas *qs;  // 簡単にいえば絵を描くところ。絵画のキャンバスといっしょ。
	QCanvasView *qcv;  // QCanvas を表示させるもの。額みたいな。
	
	void readAreaMap( QString MapFile );  // CSV形式のマップファイルを読み込む機能を作成。MapFileで指定したファイルを読み込む
};

#endif //MAINWINDOW_H


(解説は、かきかけ)



<CPPファイル名 mainwindow.cpp>

#include "mainwindow.h"  // mainwindow.cpp のヘッダーファイル mainwindow.h を読み込み

Mainwindow::Mainwindow(QWidget *parent, const char *name)
		: QWidget(parent, name)
{
	// テキストコーデック「codec」を作成
	// 以降、codec->toUnicode("ここに書いたことは日本語で表示できる")
	codec = QTextCodec::codecForName("ShiftJIS");

	// ウィンドウのタイトルを設定
	setCaption(codec->toUnicode("サンプル6「RPGみたいなの」"));

	// 使用するフォントを設定
	QFont f("lcfont",18);
	setFont(f);
	
	qs = new QCanvas(this);  // キャンバスを作成
    qs -> resize(1600,1600);  // キャンバスのサイズを縦1600、横1600に設定
    qcv = new QCanvasView(qs,this);  // キャンバスの額を作成
    qcv -> setGeometry(0, 0, 640, 420);  // キャンバスの額の位置を設定(縦420ドットは、これくらいにしないと水平スクロールバーがツールバーに隠れてしまうため)
    qcv -> setVScrollBarMode( QScrollView::AlwaysOn );  // V=vertical 垂直のスクロールバーを常にON
    qcv -> setHScrollBarMode( QScrollView::AlwaysOn );  // H=horizontal 水平のスクロールバーを常にON
    update();  // キャンバスを更新(書き換え)
}


// QCanvas を使うときにはなくてはいけない?update()実行時にこの中身が実行され画面中に描画される
void Mainwindow::paintEvent( QPaintEvent * )
{
    QPixmap pixmap;  // Pixmap(画像を読み込む場所?)を作成
    if ( pixmap.load("/mnt/card/panel.gif") ){              // /mnt/card/panel.gifを「pixmap」に読み込む
    	qs -> QCanvas::setTiles(pixmap, 50, 50, 32, 32);  // キャンバス「qs」に(RPGのマップになる)タイルを「pixmap」から作成(横50マスX縦50マス、1マスは横32ドットX縦32ドット)
    	
    	readAreaMap( "/mnt/card/torimann.map" );  // /mnt/card/torimann.map をマップファイルとしてreadAreaMapに渡して実行
    }
}


// エリアマップの呼び出し(CSVファイル)
// マップファイルの数値はそのまま配置するタイル番号となっている。50行、50列までという制限はしない。
void Mainwindow::readAreaMap( QString MapFile )
{
	QFile textfile( MapFile );  // MapFile(マップファイル)をファイル名として、textfile に入れる
	if ( textfile.open(IO_ReadOnly) ){  // textfile(=MapFile)を開く(読み込み準備)
		QTextStream t( &textfile );  // textfile を読み込んだ中身が流れる道(t)を作る
		t.setCodec( codec );  // t の文字コードをcodec(=Shift-JIS) に設定する
		QString s;  // 文字列変数s の作成(読み込んだ1行をここに入れる)
		QStringList p;  // 文字列配列p の作成(,(カンマ)で区切って並べたリストを入れる)
		QString pl;  // 文字列変数pl の作成(plで並べたリストから取り出した1つ(=配置するタイル番号)を入れる)
		int px = 0;  // 数値変数px の作成(設定するマップのマスの横列の位置を入れる)
		int py = 0;  // 数値変数py の作成(設定するマップのマスの縦列の位置を入れる)
		int pxy;  // 数値変数pxy の作成(pl を文字列から数値に変換したものを入れる)
		
		while ( !t.eof() ) {  // ファイルの最後の行を読み込み終えるまで繰り返す(1行ずつ読み込んでいく)
			s = t.readLine();  // s に読み込んだ行を入れる
			p = QStringList::split(',', s, TRUE);  // リスト「p」に「s」を「,(カンマ)」で区切って1成分ずつ並べる
			px = 0;  // px の値を0にする(左端にもどる)
			
			for ( QStringList::Iterator it = p.begin(); it != p.end(); ++it ) {  // リスト「p」の最初から「it」に入れていき、最後になるまで繰り返す
				pl = *it;  // pl に取り出した成分を入れる
				pxy = pl.toInt(0,10);  // pl を10進数で数値に変換し、「pxy」に入れる
				qs -> QCanvas::setTile(px,py,pxy);  // キャンバス「qs」の横「px」、縦「py」の位置のタイルを「pxy」に設定する
				
				px++;  // 「px」の値を1増やす(横に1ずれる)
			}
			
			py++;  // 「py」の値を1増やす(下に1ずれる)
		}
		textfile.close();  // ファイル「textfile(=MapFile)」を閉じる
	}
}


(解説は、かきかけ)




というわけで、さっそくコンパイルして実行してみましょう。
ここでは、「~/SLZaurus/」以下に「sample0006」フォルダを作成し、その中にソースがあることを前提にしています。


Cygwinを起動して、次のコマンドを実行してください。



. ~/SLZaurus/bin/dev-arm-qpe.sh
cd ~/SLZaurus/sample0006
progen -o sample0006.pro
tmake -o Makefile sample0006.pro
make



これでエラーが出なければ、「sample0006」というファイルがソースと同一のフォルダに作成されているので、それをリナザウに移してターミナルから実行してみてください。
エラーが出た場合は、もう一度ソースを見直して、問題のある個所を修正しましょう。問題のある個所は、「make」後のエラー情報でも最低限のことは提供されます。




実行する場合は、マップファイル、タイル画像ファイルを「/mnt/card/」においてください。
RPGっぽいのができてきましたね。自分でマップファイルをいじってみてください。




<ソース>

sample0006.tar.gz

First Seed Material, REFMAP 様の画像を利用させていただきました。
http://www.tekepon.net/fsm/




前へ ○○○ 「リナザウのソフトウェア開発」 ○○○ 次へ






inserted by FC2 system