SQLの窓

2018年01月23日


(C#) / VS2010 または VS2012 : TKMP.DLL(3.1.2 または 3.1.8)を使った、『さくらインターネット』用メール送信テンプレート



OneDrive よりダウンロード

テンプレートには、3.1.2 が入っていますが、Windwos10(64) + Visual Studio 2012 C# でテスト(2018-01-23)しました。


さくらインターネット

現在スタンダードを運用していますが、月額 515円 容量 100GB です

メールメールアドレスを無制限で作成できます(当然容量内ですが)。
メールボックスの容量を1MBから2048MBまで任意に指定できます。
※ サーバのディスク容量がひっ迫していると、しきい値内であってもメールは届きません。
ウェブメール ※ 一応あります( そんなに力を入れてるとは思えないです ) ❸ メーリングリストは10個 コスト 月額515円 ( 年間一括支払いの場合、5,142円 ) レンタルサーバーとしては、さくらのブログの内容が Seesaa ブログの劣化版である事をのぞけば、結構いたれりつくせりだと思っています。 基本仕様一覧 Ruby は 1.8.x なんで、ちょっと古いと思っています。 データベース使用量は、こんなふうに昔から記述されています。
基本的に制限は設けておりませんが、共用データベースサーバでは使用量の目安がございます。
目安以上の容量を使用された場合、他のお客様への影響がでたり、障害が発生した場合、データの復旧が正常に行えない 可能性がございます。
SSL は 共有SSL が使えます。気軽にログイン部分等、暗号化可能です。 CRONの設定数は 5 です
MailClass mc = new MailClass()
{
    SmtpServer = "初期ドメイン",
    Port = 587,
    User = "ユーザ名@ドメイン",
    Pass = "パスワード",
    Protocol = AuthenticationProtocols.TLS
};

var result = mc.SendMail(
    "宛て先",
    "ユーザ名@ドメイン",
    this.subject.Text,
    this.body.Text,
    null,   // 必要な場合、宛先を日本語で
    null,   // 必要な場合、差出人を日本語で
    (MailClass.MailClassErrorArg _e) =>
    {
        this.error.Text = _e.Message;
    }
);

MailClass.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TKMP.Writer;
using TKMP.Net;

namespace TKMP_SendMail_Sakura1 {
	class MailClass {
		private MailWriter mw = null;

		public string SmtpServer { get; set; }
		public int Port { get; set; }
		public string User { get; set; }
		public string Pass { get; set; }
		public AuthenticationProtocols Protocol { get; set; }

		private string err_message = "";

		public class MailClassErrorArg {
			public string Message { get; set; }
		}

		public delegate void MailClassError(MailClassErrorArg e);

		public bool SendMail(string To, string From, string Subject, string Body, string To_J, string From_J, MailClassError mce) {
			bool bResult = true;

			mw = new MailWriter();

			try {
				mw.ToAddressList.Add(To);
			}
			catch (Exception ex) {
				bResult = false;
			}
			if (!bResult) {
				if (mce != null) {
					MailClassErrorArg e = new MailClassErrorArg() { Message = "宛先が正しくありません" };
					mce(e);
				}
				return bResult;
			}

			// From が未指定や正しくない文字列の場合
			try {
				mw.FromAddress = From;
			}
			catch (Exception ex) {
				// ユーザが正しければ、以下のように設定しても『ユーザ名 <メールアドレス>』に変換される
				mw.FromAddress = "______@hotmail.co.jp";
			}

			TextPart tp = new TextPart(Body);
			mw.MainPart = tp;

			if (To_J != null) {
				mw.Headers.Add("To", To_J + " <" + To + ">");
			}
			else {
				mw.Headers.Add("To", To);
			}
			if (From_J != null) {
				mw.Headers.Add("From", From_J + " <" + From + ">");
			}
			else {
				// Hotmail では、自動的に 『ユーザ名 <メールアドレス>』に変換される
				mw.Headers.Add("From", From);
			}

			mw.Headers.Add("Subject", Subject);
			mw.Headers.Add("X-Mailer", "TKMP Version 3.1.2");

			var logon = new TKMP.Net.AuthLogin(User, Pass);
			SmtpClient sc = new SmtpClient(SmtpServer, Port, logon);
			sc.AuthenticationProtocol = Protocol;

			try {
				if (!sc.Connect()) {
					err_message = "接続に失敗しました";
					bResult = false;
				}
				else {
					sc.SendMail(mw);
					sc.Close();
				}
			}
			catch (Exception ex) {
				err_message = ex.Message;
				bResult = false;
			}
			if (!bResult) {
				if (mce != null) {
					MailClassErrorArg e = new MailClassErrorArg() { Message = err_message };
					// このメソッドの引数である、ErrorHandler デリゲートを呼び出す
					mce(e);
				}
			}

			return bResult;
		}

		public bool SendMail(string To, string From, string Subject, string Body, string To_J, string From_J) {
			return SendMail(To, From, Subject, Body, To_J, From_J, null);
		}

		public bool SendMail(string To, string From, string Subject, string Body) {
			return SendMail(To, From, Subject, Body, null, null, null);
		}

	}

}

関連する記事

VS2010(C#) : TKMP.DLLを使った、メール送信テンプレート




posted by lightbox at 2018-01-23 21:23 | VS(C#) | このブログの読者になる | 更新情報をチェックする

2017年12月19日


C# : Excel を データベースとして DataGridView に読み込む

※ Microsoft Office の Excel がインストールされている必要はありません

Microsoft.ACE.OLEDB.12.0 を使用して、OleDbConnection と OleDbCommand でデータベースとして処理します。テーブル名としては、シート名が使われますが、範囲指定して名前を定義しない限りは [シート名$] をテーブル
として使用します。( カギかっこは、Oracle で言うところのダブルクォートです )

Microsoft.ACE.OLEDB.12.0 がインストールされていない場合

Microsoft Access データベース エンジン 2010 再頒布可能コンポーネントをダウンロードしてインストールします。


( 32ビット版と64ビット版があるので選択してダウンロードします / ※ システム要件に 『32 ビット版の Access データベース エンジンは、Windows XP Service Pack 3 でしか使用できません』とあります。Windows7 では既にインストールされていると思われます )

▼ ダウンロードページの『インストール方法』より抜粋
OLEDB を使用するアプリケーション開発者: ConnectionString プロパティのプロバイダー引数を "Microsoft.ACE.OLEDB.12.0" に設定します。 

Microsoft Office Excel データに接続する場合は、Excel ファイル形式に基づいて OLEDB 接続文字列の適切な拡張プロパティを追加します 

ファイル形式 (拡張子)                                             拡張プロパティ
---------------------------------------------------------------------------------------------
Excel 97-2003 ブック (.xls)                                  "Excel 8.0"
Excel 2007-2010 ブック (.xlsx)                             "Excel 12.0 Xml"
Excel 2007-2010 マクロ有効ブック (.xlsm)      "Excel 12.0 Macro"
Excel 2007-2010 XML 以外のバイナリ ブック (.xlsb)      "Excel 12.0"
処理コード
	public partial class FormExcelGridView : Form {

		private string path = null;

		public FormExcelGridView() {
			InitializeComponent();
		}

		private void buttonExcel_Click(object sender, EventArgs e) {

			path = Helper.OpenFileDialog();
			if (path == null) {
				return;
			}

			LoadExcel();

		}

		// *********************
		// Excel の読み込み
		// *********************
		private void LoadExcel() {

			using (OleDbConnection myCon = new OleDbConnection())
			using (OleDbCommand myCommand = new OleDbCommand()) {

				// SQL文字列格納用
				string myQuery = "select * from [sheet1$]";

				// 接続文字列の作成
				myCon.ConnectionString = string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"Excel 12.0 Xml;HDR=YES;IMEX=1\"", path);
				Debug.WriteLine(myCon.ConnectionString);

				// *********************
				// 接続
				// *********************
				try {
					// 接続文字列を使用して接続
					myCon.Open();
					// コマンドオブジェクトに接続をセット
					myCommand.Connection = myCon;
					// コマンドを通常 SQL用に変更
					myCommand.CommandType = System.Data.CommandType.Text;
				}
				catch (Exception ex) {
					MessageBox.Show(this, ex.Message);
					return;
				}

				// *********************
				// 実行 SQL
				// *********************
				myCommand.CommandText = myQuery;

				// *********************
				// レコードセット取得
				// *********************
				try {
					using (OleDbDataReader myReader = myCommand.ExecuteReader()) {

						DataTable dataTable = new DataTable();
						dataTable.Load(myReader);
						dataGridView.DataSource = dataTable;

						// リーダを使い終わったので閉じる
						myReader.Close();
					}
				}
				catch (Exception ex) {
					myCon.Close();
					MessageBox.Show(this, ex.Message);
					return;
				}

				// 接続解除
				myCon.Close();

			}	// 最外の using の終わり

			// カラム幅の自動調整
			dataGridView.AutoResizeColumns();

		}
	}



Helpre クラス
	class Helper {

		// https://msdn.microsoft.com/ja-jp/vba/excel-vba/articles/application-object-excel
		public const int xlMaximized = -4137;
		public const int xlMinimized = -4140;
		public const int xlNormal = -4143;

		public static string OpenFileDialog() {

			OpenFileDialog ofd = new OpenFileDialog();

			ofd.Filter = "Excel(*.xls;*.xlsx;*.xlsm)|*.xls;*.xlsx;*.xlsm|すべてのファイル(*.*)|*.*";
			ofd.FilterIndex = 1;
			ofd.Title = "Excel ブックを選択してください";
			ofd.RestoreDirectory = true;

			if (ofd.ShowDialog() != DialogResult.OK) {
				return null;
			}

			return ofd.FileName;
		}
	}


DataGridView のプロパティ
            // 
            // dataGridView
            // 
            this.dataGridView.AllowUserToAddRows = false;
            this.dataGridView.AllowUserToDeleteRows = false;
            this.dataGridView.AllowUserToOrderColumns = true;
            this.dataGridView.AllowUserToResizeRows = false;
            this.dataGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
            this.dataGridView.Location = new System.Drawing.Point(40, 113);
            this.dataGridView.MultiSelect = false;
            this.dataGridView.Name = "dataGridView";
            this.dataGridView.ReadOnly = true;
            this.dataGridView.RowTemplate.Height = 21;
            this.dataGridView.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
            this.dataGridView.Size = new System.Drawing.Size(930, 443);
            this.dataGridView.TabIndex = 0;


関連する記事

C# : dynamic 型 による Excel へのアクセス



posted by lightbox at 2017-12-19 00:12 | VS(C#) | このブログの読者になる | 更新情報をチェックする

2017年12月17日


C# : dynamic 型 による Excel へのアクセス

dynamic 型のオブジェクトは静的な型チェックをバイパスします。 なので、そのオブジェクトに対して熟練している必要がありますが、COM を使用する事を想定している場合、プログラマはそのメソッドに対して良く経験しているはすです。

▼ テンプレートのダウンロード


Excel の初期化部分と終了部分
		// *********************
		// 初期処理
		// *********************
		private void Form1_Load(object sender, EventArgs e) {

			excelApp = Activator.CreateInstance(Type.GetTypeFromProgID("Excel.Application"));
			excelApp.Visible = true;

		}

		// *********************
		// 終了処理
		// *********************
		private void Form1_FormClosed(object sender, FormClosedEventArgs e) {

			if (excelApp != null) {
				if (workBook != null) {
					// 保存した事にする
					workBook.Saved = true;
				}
				excelApp.Quit();
			}
			System.Runtime.InteropServices.Marshal.ReleaseComObject(excelApp);

		}
Excel.Application は、VBScript では CreateObject で使用する ID です。excelApp は、dynamic 型で定義されており、excelApp.Visible = true; は、Excel が表示される事を意味します。



本来は、非表示でなければなりませんが(ユーザが直接操作するとエラーが発生します)、アプリケーション側(C#)が完成せずにテスト段階でエラーを起こしてしまうと、Excel が終了せずにメモリに残ってしまうので(その場合はタスクマネージャより終了させる)、このようにしています。

実装している機能

Excel には気の遠くなるほど、機能がたくさんあります。その中でも基本となる部分を実装しました。
1) セルへの書き込み。

2) Book を開いて、シート名の一覧をコンボボックスに表示

3) 各 シートをアクティブにする

4) Book を閉じる

5) Book を保存して閉じる

6) 最大化・最小化・標準表示
ソースコード
	public partial class Form1 : Form {

		private dynamic excelApp = null;
		private dynamic workBook = null;
		private string path = null;

		public Form1() {
			InitializeComponent();
		}

		// *********************
		// 書き込みテスト
		// *********************
		private void buttonTest_Click(object sender, EventArgs e) {

			if (workBook == null) {
				return;
			}

			// セル用変数
			dynamic cell;
			// 行と列より、セルオブジェクト(アクティブシート)
			cell = workBook.ActiveSheet.Cells(numericRow.Value, numericColumn.Value);
			// セルに値をセット
			cell.Value = textString.Text;

		}

		// *********************
		// アクティブにする
		// *********************
		private void buttonActive_Click(object sender, EventArgs e) {

			if (workBook == null) {
				return;
			}

			string sheetName = listBoxSheet.Text;
			workBook.Sheets(sheetName).Activate();

		}

		// *********************
		// 初期処理
		// *********************
		private void Form1_Load(object sender, EventArgs e) {

			excelApp = Activator.CreateInstance(Type.GetTypeFromProgID("Excel.Application"));
			excelApp.Visible = true;

		}

		// *********************
		// 終了処理
		// *********************
		private void Form1_FormClosed(object sender, FormClosedEventArgs e) {

			if (excelApp != null) {
				if (workBook != null) {
					// 保存した事にする
					workBook.Saved = true;
				}
				excelApp.Quit();
			}
			System.Runtime.InteropServices.Marshal.ReleaseComObject(excelApp);

		}

		// *********************
		// ブックを開く
		// *********************
		private void 開く_Click(object sender, EventArgs e) {

			if (workBook != null) {
				MessageBox.Show(this, "ブックは一つしか開く事ができません");
				return;
			}

			path = Helper.OpenFileDialog();
			if (path != null) {
				workBook = excelApp.Workbooks.Open(path);
				listBoxSheet.Items.Clear();
				// シートの数によりループ
				for (int i = 1; i <= workBook.Sheets.Count; i++) {
					// シート名をコンボボックスにセット
					listBoxSheet.Items.Add(workBook.Sheets(i).Name);
				}
				// コンボボックスを使用可能にして
				listBoxSheet.Enabled = true;
				// 先頭を選択する
				listBoxSheet.SelectedIndex = 0;
			}

		}

		// *********************
		// 閉じる
		// *********************
		private void 閉じる_Click(object sender, EventArgs e) {

			if (workBook != null) {
				// 保存した事にする
				workBook.Saved = true;
			}
			workBook.Close();
			workBook = null;

			// クリア
			listBoxSheet.Items.Clear();
			// リストボックスを使用不可にして
			listBoxSheet.Enabled = false;
			// 選択しない
			listBoxSheet.SelectedIndex = -1;

		}

		// *********************
		// 保存して閉じる
		// *********************
		private void 保存して閉じる_Click(object sender, EventArgs e) {

			if (workBook != null) {
				workBook.Save();
			}
			workBook.Close();
			workBook = null;

			// クリア
			listBoxSheet.Items.Clear();
			// リストボックスを使用不可にして
			listBoxSheet.Enabled = false;
			// 選択しない
			listBoxSheet.SelectedIndex = -1;

		}

		// *********************
		// 最大化
		// *********************
		private void 最大化_Click(object sender, EventArgs e) {

			excelApp.WindowState = Helper.xlMaximized;

		}

		// *********************
		// 最小化
		// *********************
		private void 最小化_Click(object sender, EventArgs e) {

			excelApp.WindowState = Helper.xlMinimized;

		}

		// *********************
		// 標準
		// *********************
		private void 標準_Click(object sender, EventArgs e) {

			excelApp.WindowState = Helper.xlNormal;

		}


	}



Helpre クラス
	class Helper {

		// https://msdn.microsoft.com/ja-jp/vba/excel-vba/articles/application-object-excel
		public const int xlMaximized = -4137;
		public const int xlMinimized = -4140;
		public const int xlNormal = -4143;

		public static string OpenFileDialog() {

			OpenFileDialog ofd = new OpenFileDialog();

			ofd.Filter = "Excel(*.xls;*.xlsx;*.xlsm)|*.xls;*.xlsx;*.xlsm|すべてのファイル(*.*)|*.*";
			ofd.FilterIndex = 1;
			ofd.Title = "Excel ブックを選択してください";
			ofd.RestoreDirectory = true;

			if (ofd.ShowDialog() != DialogResult.OK) {
				return null;
			}

			return ofd.FileName;
		}
	}


関連する記事

C# : Excel を データベースとして DataGridView に読み込む



タグ:C# EXCEL
posted by lightbox at 2017-12-17 20:29 | VS(C#) | このブログの読者になる | 更新情報をチェックする

2017年11月26日


C# でDXライブラリを使って簡単なシューティングをクラス化して標準化 / メインループとプレイヤー (4)



C# でDXライブラリを使って簡単なシューティングをクラス化して標準化 / メインループとプレイヤー (3) で、Game、Player という二つのクラスで、左右の矢印キーでプレイヤーの画像が左右に動く処理を標準化しました。

この Player クラスの機能をそのまま使って、背景を表示する Background クラスを追加します。背景画像はこちらからダウンロードできますが、サイズは 1007x1007 という中途半端なサイズになっています。

この画像はパターン画像で、左端が右端に続き、上端が下端に続く画像で、適当に作ったのでこのようなサイズになっています。ただ、1007 の幅なので、ゲーム画面の幅はこれ以内でないとうまく動作しないので注意して下さい。

Background クラス

背景は、プレイヤーの動きと逆に動くようになっています。また、背景は常に画面いっぱいに表示されるので、DrawRectGraph で描画しています。左端と右端を同時に更新する必要があるのですが、パターン画像なので、二つのエリアに分けて描画します。(矢印キーをずっと押し続けると、プレイヤーは画面の端で止まりますが、背景はずっと横スクロールし続けます)

現在横の動きだけなので二つの DrawRectGraph を使用していますが、縦の動きを入れる場合はさらに二つの DrawRectGraph が必要になる予定です。
		// *******************
		// コンストラクタ
		// *******************
		public Background(Game game, string name, int offset) {

			this.game = game;

			// 画像の読み込み
			image = DX.LoadGraph(name);

			// 画像のサイズを取得
			int w, h;
			DX.GetGraphSize(image, out w, out h);
			graph_w = w;
			graph_h = h;

			// 背景の初期位置
			x = 0;
			y = 0;

			move_offset = offset;

		}

		public int image { get; set; }
		public int graph_w { get; set; }
		public int graph_h { get; set; }
		public int x { get; set; }
		public int y { get; set; }
		public int move_offset { get; set; }
		public Game game { get; set; }

		// *******************
		// 描画
		// *******************
		internal void draw() {

			DX.DrawRectGraph(0, 0, this.graph_w - this.x, this.y, this.x, this.graph_h - this.y, this.image, 0, 0);
			DX.DrawRectGraph(this.x, 0, 0, this.y, this.graph_w, this.graph_h - this.y, this.image, 0, 0);

		}

		// *******************
		// 左移動
		// *******************
		internal void left() {

			this.x -= this.move_offset;

			// 背景は一周する
			if (this.x < 0) {
				// 左へ消えた部分は、右から出て来る
				this.x = this.graph_w;
			}

		}

		// *******************
		// 右移動
		// *******************
		internal void right() {

			this.x += 5;

			// 背景は一周する
			if (this.x >= this.graph_w) {
				// 右へ消えた部分は、左から出て来る
				this.x = 0;
			}

	
		}
	}


Background クラスを追加したメイン処理( Program クラス内 ) は以下のようになります

Program 内の処理

処理としては逆向きのメソッドをそれぞれ配置しただけのものになっています
			// メインゲームインスタンス作成
			Game game = new Game(800, 600);

			// 初期化
			game.init();

			// 背景インスタンス作成
			Background background = new Background(game, "field.png", 5);

			// プレイヤーインスタンス作成
			Player player = new Player(game, "player.png", 5);

			game.start(
				// *******************
				// 主処理
				// *******************
				(int counter) => {

					// 右矢印キー
					if (DX.CheckHitKey(DX.KEY_INPUT_RIGHT) == 1) {

						player.right();
						// player と 逆向き
						background.left();

					}

					// 左矢印キー
					if (DX.CheckHitKey(DX.KEY_INPUT_LEFT) == 1) {

						player.left();
						// player と 逆向き
						background.right();

					}

				},
				// *******************
				// 描画処理
				// *******************
				() => {

					background.draw();
					player.draw();

				}

			);



posted by lightbox at 2017-11-26 20:17 | VS(C#) | このブログの読者になる | 更新情報をチェックする

C# でDXライブラリを使って簡単なシューティングをクラス化して標準化 / メインループとプレイヤー (3)



C# でDXライブラリを使って簡単なシューティングをクラス化して標準化 / メインループとプレイヤー (2) では、Player クラスを作成し、Player に依存する情報を Player クラス内にプロパティとして保存しました。

以下では、そのプロパティを使って、Player クラス内でデータを処理する為の right、left、draw メソッドを作成しています。

Player クラス
	class Player {

		// *******************
		// コンストラクタ
		// *******************
		public Player(Game game, string name, int offset) {

			this.game = game;

			// 画像の読み込み
			image = DX.LoadGraph(name);

			// 画像のサイズを取得
			int w, h;
			DX.GetGraphSize(image, out w, out h);
			graph_w = w;
			graph_h = h;

			// プレーヤーの初期位置
			x = game.screen_w / 2 - h / 2;
			y = game.screen_h - 70;

			move_offset = offset;

		}

		public int image { get; set; }
		public int graph_w { get; set; }
		public int graph_h { get; set; }
		public int x { get; set; }
		public int y { get; set; }
		public int move_offset { get; set; }
		public Game game { get; set; }

		// *******************
		// 描画
		// *******************
		internal void draw() {

			DX.DrawGraph(this.x, this.y, this.image, DX.TRUE);

		}

		// *******************
		// 右移動
		// *******************
		internal void right() {

			this.x += this.move_offset;
			if (this.x + this.graph_w > game.screen_w) {
				this.x = game.screen_w - this.graph_w;
			}

		}

		// *******************
		// 左移動
		// *******************
		internal void left() {

			this.x -= this.move_offset;
			if (this.x < 0) {
				this.x = 0;
			}

		}
	}


そして、以下ではこの Player クラスのメソッドを使用して、Program クラス内の記述を簡略化しています。
			// メインゲームインスタンス作成
			Game game = new Game(800, 600);

			// 初期化
			game.init();

			// プレイヤーインスタンス作成
			Player player = new Player(game, "player.png", 5);

			game.start(
				// *******************
				// 主処理
				// *******************
				(int counter) => {

					// 右矢印キー
					if (DX.CheckHitKey(DX.KEY_INPUT_RIGHT) == 1) {

						player.right();

					}

					// 左矢印キー
					if (DX.CheckHitKey(DX.KEY_INPUT_LEFT) == 1) {

						player.left();

					}

				},
				// *******************
				// 描画処理
				// *******************
				() => {

					player.draw();

				}

			);

関連する記事

C# でDXライブラリを使って簡単なシューティングをクラス化して標準化 / メインループとプレイヤー (4)




posted by lightbox at 2017-11-26 17:51 | VS(C#) | このブログの読者になる | 更新情報をチェックする

C# でDXライブラリを使って簡単なシューティングをクラス化して標準化 / メインループとプレイヤー (2)



C# でDXライブラリを使って簡単なシューティングをクラス化して標準化 / メインループとプレイヤー (1) では、メインループと初期化部分を Game クラスとしてクラス化しました。(Game クラスの start メソッド内で、キーアクションの処理部分と描画部分を分けて、start の引数の無名ブロックを呼び出すようにしました。)

今回は、それに引き続いてプレイヤーを左右矢印キーで左右に動くようにしている部分をクラス化し、Player クラスを作成します。

プレイヤーの初期処理は、使用する画像の決定と一回のキー押下でどのくらい移動するかの距離を設定する事にしました。また、初期位置を画面下部中央に設置する為に、スクリーンサイズが必要になるので、Game クラスのインスタンスも同時に引き渡しています。

Player クラス
ここでは情報をプロパティとして定義しています。

1) image : 画像ハンドル
2) graph_w : 画像幅
3) graph_h : 画像高さ
4) x : 描画座標
5) y : 描画座標
6) move_offset : キー押下による移動距離
7) game : Game クラスのインスタンス
	class Player {

		// *******************
		// コンストラクタ
		// *******************
		public Player(Game game, string name, int offset) {

			this.game = game;

			// 画像の読み込み
			image = DX.LoadGraph(name);

			// 画像のサイズを取得
			int w, h;
			DX.GetGraphSize(image, out w, out h);
			graph_w = w;
			graph_h = h;

			// プレーヤーの初期位置
			x = game.screen_w / 2 - h / 2;
			y = game.screen_h - 70;

			// キー押下による移動距離
			move_offset = offset;

		}

		public int image { get; set; }
		public int graph_w { get; set; }
		public int graph_h { get; set; }
		public int x { get; set; }
		public int y { get; set; }
		public int move_offset { get; set; }
		public Game game { get; set; }
	}


次に、この Player クラスを使用して、Program クラスの記述を変更すると以下のようになります。

ただ、この時点ではまだ Player の処理が Program クラス での記述に依存してしまっているので、キーの処理と描画の処理を Player クラスのメソッドとして変更する必要があります
			// メインゲームインスタンス作成
			Game game = new Game(800, 600);

			// 初期化
			game.init();

			// プレイヤーインスタンス作成
			Player player = new Player(game, "player.png", 5);

			game.start(
				// *******************
				// 主処理
				// *******************
				(int counter) => {

					// 右矢印キー
					if (DX.CheckHitKey(DX.KEY_INPUT_RIGHT) == 1) {
						player.x += player.move_offset;
						if (player.x + player.graph_w > game.screen_w) {
							player.x = game.screen_w - player.graph_w;
						}
					}

					// 左矢印キー
					if (DX.CheckHitKey(DX.KEY_INPUT_LEFT) == 1) {
						player.x -= player.move_offset;
						if (player.x < 0) {
							player.x = 0;
						}
					}

				},
				// *******************
				// 描画処理
				// *******************
				() => {

					DX.DrawGraph(player.x, player.y, player.image, DX.TRUE);

				}

			);

関連する記事

C# でDXライブラリを使って簡単なシューティングをクラス化して標準化 / メインループとプレイヤー (3)



posted by lightbox at 2017-11-26 17:06 | VS(C#) | このブログの読者になる | 更新情報をチェックする
Seesaa の各ページの表示について
Seesaa の 記事がたまに全く表示されない場合があります。その場合は、設定> 詳細設定> ブログ設定 で 最新の情報に更新の『実行ボタン』で記事やアーカイブが最新にビルドされます。

Seesaa のページで、アーカイブとタグページは要注意です。タグページはコンテンツが全く無い状態になりますし、アーカイブページも歯抜けページはコンテンツが存在しないのにページが表示されてしまいます。

また、カテゴリページもそういう意味では完全ではありません。『カテゴリID-番号』というフォーマットで表示されるページですが、実際存在するより大きな番号でも表示されてしまいます。

※ インデックスページのみ、実際の記事数を超えたページを指定しても最後のページが表示されるようです

対処としては、このようなヘルプ的な情報を固定でページの最後に表示するようにするといいでしょう。具体的には、メインの記事コンテンツの下に『自由形式』を追加し、アーカイブとカテゴリページでのみ表示するように設定し、コンテンツを用意するといいと思います。


※ エキスパートモードで表示しています

アーカイブとカテゴリページはこのように簡単に設定できますが、タグページは HTML 設定を直接変更して、以下の『タグページでのみ表示される内容』の記述方法で設定する必要があります

<% if:page_name eq 'archive' -%>
アーカイブページでのみ表示される内容
<% /if %>

<% if:page_name eq 'category' -%>
カテゴリページでのみ表示される内容
<% /if %>

<% if:page_name eq 'tag' -%>
タグページでのみ表示される内容
<% /if %>
この記述は、以下の場所で使用します
container 終わり

フリーフォントで簡単ロゴ作成
フリーフォントでボタン素材作成
フリーフォントで吹き出し画像作成
フリーフォントではんこ画像作成
ほぼ自由に利用できるフリーフォント
フリーフォントの書体見本とサンプル
画像を大きく見る為のウインドウを開くボタンの作成

CSS ドロップシャドウの参考デモ
BUTTONS (CSS でボタン)
イラストAC
ぱくたそ
写真素材 足成
フリーフォント一覧
utf8 文字ツール
右サイド 終わり
base 終わり