カテゴリー: プログラミング

うにのトゲは刺さると痛い(´・ω・`)-3

Web上にあるUnityのサンプルコードを眺めているとC#固有というか特有な機能等があったりして、C#をよく解っていない俺氏はコードが理解出来ず(´・ω・`)

その都度ぐぐるわけだが、それも段々面倒くさくなり、C#の本でも買うかと考えた。
で、たまたまkindleでセールをやっていて、金城俊哉という人の「Visual C# 2017パーフェクトマスター」という書籍が¥1,244だったので買ってみた。amazonのレビューでも悪くなさそうだったのだが…

 

 

失敗だった…_| ̄|○

日本語表現がちょっとおかしかったり、同じ表現を繰り返してまだるっこしかったり、踏み込んだ内容が少なくて冗長、誤字等が多いという感じで読んでいて苦痛だったわ(ヽ'ω`)
レイアウトや時々入ってるHintやMemoとかもなんか酷かったな。あれは空白を埋める為に適当に入れるものなんだろうか。

4章までは頑張って読んだけどそこで本を閉じた…_| ̄|○
後のアプリケーション作成の方は必要になったら読めばいいし。マルチスレッドプログラミングも今のところ必要ないし。

この人は同じような本を何冊か書いてるみたいなんだけど、皆こんなレベルなんだろうか。
もしかしたら下請けライターみたいなのが居て、それを取りまとめているのかなぁ?
一部分だけ詳述されているがそれ以外の部分は知っていることをただ羅列しましたみたいな感じで内容にムラがあったので、そんな風に思ってしまった。

取り敢えず中級者が読むには内容が薄く、初級者が読むには誤字が多くて表現が冗長で解りにくいという印象。もっと言うと知識を文字(及び図)を使って他者へと伝達するという意志が見られない書籍であった(ノ∀`)

これを買うならWebでぐぐって自分に合った学習サイトで勉強した方がいいかもねぇ(´・ω・`)
この人の本と秀和システムの本にはもう手を出さないにしようw
内容は著者が担う問題だけど誤字が酷いのは編集プロダクションか出版社の問題だからなぁw


画面スクロール

結局スクロールに関しては「UnityでiOS/Android/Editorの共通タッチ処理を実装する」にdeltaを取れるように追加してみたをベースにし、2本指でスワイプした時にカメラを並行移動させる処理を実装するの内容を混ぜてみた。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ScreenScroll : MonoBehaviour {

<pre><code>public float moveSpeed = 0.1f;
private Camera mainCamera;
private float horizontalPosition;
private float varticalPosition;
private Vector2 beforePoint;
private Vector2 nowPoint;

// Use this for initialization
void Start()
{
    mainCamera = Camera.main;
}

// Update is called once per frame
void Update()
{
    TouchInfo info = AppUtil.GetTouch();
    switch (info)
    {
        case TouchInfo.Began:
            beforePoint = AppUtil.GetTouchPosition();
            break;

        case TouchInfo.Moved:
            nowPoint = AppUtil.GetTouchPosition();

            if (nowPoint.x - beforePoint.x != 0)
            {
                horizontalPosition = (nowPoint.x - beforePoint.x) * (-1);
                horizontalPosition *= moveSpeed * Time.deltaTime;

                mainCamera.transform.position =
                    new Vector3(Mathf.Clamp(mainCamera.transform.position.x + horizontalPosition, 0f, 7f),
                mainCamera.transform.position.y, 0f);

            }

            if (nowPoint.y - beforePoint.y != 0)
            {
                varticalPosition = (nowPoint.y - beforePoint.y) * (-1);
                varticalPosition *= moveSpeed * Time.deltaTime;

                mainCamera.transform.position =
                    new Vector3(mainCamera.transform.position.x,
                Mathf.Clamp(mainCamera.transform.position.y + varticalPosition, -10f, 0f), 0f);
            }

            beforePoint = nowPoint;
            break;
        case TouchInfo.Ended:
            break;
    }
}
</code></pre>

}

この内容が正しいかどうかは解らない(ノ∀`)
2D用スクロールなのでQuaternionの辺りは削除してみた。
一応動いてくれてるので、後は移動限界値を可変にするだけでいいかな。


imageと普通のオブジェクトの違い(ヽ'ω`)
面倒くさくなって来たので端折って書くが、Unityの寺子屋 定番スマホゲーム開発入門で学んだことから拡張しておこうとした俺氏は、

  1. UI上にimageを並べてしまったが為に画面スクロールがまともに動作しないという事態に陥る。(カメラ設定を変えると動くけど意図しない大きさになったんだったかな?)
  2. imageからGameObjectに変え、canvasではなく新たに作ったGameObjectの子としてインスタンスを生成したら、スクロールはするようになったが、意図した配置にならなくなった。
  3. インポートしたimageの「Pixels Per Unit」を正しい値にしたら、まぁまぁ意図した配置になった。(厳密には未解決(ノ∀`))
  4. GameObjectをタップしても反応しなかったので、Physics 2D RaycasterやらBox Collider 2Dを追加したり。

参考:
【Unity2D】Pixels per Uint について
Unity(3D・2D) EventSystemでクリックイベントの制御

画面出力
実機の画面上に簡単に出力する方法が見当たらなかったので、
UnityのGUIでテキスト(文字)を表示させる方法【初心者向け】
テキストのサイズを変更する
を参考に、

    void Start()
    {
        style = new GUIStyle();
        style.fontSize = 50;
    }

<pre><code>void OnGUI()
{
    GUI.TextField(new Rect(100, 100, 200, 200), Screen.width + &amp;quot;:&amp;quot; + Screen.height,style);
}
</code></pre>

みたいな感じにした。まあこれは解像度を出力してるだけ。
「Screen.width + ":" + Screen.height」の部分を変数にしといて、update()の方でその値を更新すれば画面ログ出力が出来る感じか(´・ω・`)

xmlファイルを使わずにFragmentを生成する方法(´・ω・`)?

xmlを使わずにFragmentを生成する方法をぐぐっていて、ヒットした
android - How to programmatically create the layout for a Fragment?
android - How do I add a Fragment to an Activity with a programmatically created content view
を参考にコードをでっち上げたが、果たしてこれで正しいのかどうかよくわからないw

そもそもなんでそんなことをしようしたのかというと、前のエントリを確認している時に
LongClickを拾えなくなった時に「前に試したコードはListFragmentだったから、それと
一緒にしないと再現できないのか…( ;・´ω・`)ゴクリッ?」という勘違いをして、かつ、
「サンプルコードはワンストップならぬワンコピペで完結すべき(`・ω・´)」という
謎の思想から、xmlファイルによるレイアウト指定を無しにしたいと思ったから(ノ∀`)

一応これで出来てるみたいだけれども、実際にプログラムの一部として使うには
もっと何かをしないといけないのかもしれないが、その辺はよくわからないw

取り敢えずワンコピペで試せるFragmentを使用するサンプルを作るのには
利用出来るので、これはこれでいいかな。

なぜかLongClickでToastが表示出来ないのは謎(´・ω・`)
Log.dには出力されているのに。まあタッチイベント関連はこのサンプルの
本質とは全く関係ないのだけれどw

import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.Toast;

public class MainActivity extends Activity {

	private GestureDetector mGestureDetector;
	private View.OnTouchListener mGestureListener;
	private static final int CONTENT_VIEW_ID = 10101010;
	private static final String[] CONFECTIONERY = {
		"Apple Pie", "Banana Bread", "Cupcake", "Donut", "Eclair", "Froyo",
		"Gingerbread", "Honeycomb", "Ice Cream Sandwich", "Jelly Bean",
		"KitKat", "Lollipop"
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		LinearLayout layout=new LinearLayout(this);
		layout.setBackgroundColor(Color.WHITE);
		layout.setOrientation(LinearLayout.VERTICAL);
		layout.setId(CONTENT_VIEW_ID);

		setContentView(layout, new LayoutParams(
				LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));

		Bundle bundle = new Bundle();
		bundle.putStringArray("confectionery", CONFECTIONERY);

		if (savedInstanceState == null) {
			Fragment newFragment = new MyFragment();
			FragmentTransaction ft = getFragmentManager().beginTransaction();
			ft.add(CONTENT_VIEW_ID, newFragment).commit();
		}
	}

	private void myOnItemClick(int position) {
		Log.d("myOnItemClick", "itemClick: " + position);
		Toast.makeText(MainActivity.this, "myOnItemClick itemClick" + position, Toast.LENGTH_LONG).show();
	}

	public class MyFragment extends Fragment {

		public MyFragment() {}

		View rootView;
		ListView listView;
		@Override
		public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
			LinearLayout layout=new LinearLayout(getActivity());
			Log.d("MyFragment", "onCreateView");
			layout.setOrientation(LinearLayout.VERTICAL);

			listView = new ListView(getActivity());

			listView.setLayoutParams(new LinearLayout.LayoutParams(
					LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
			listView.setAdapter(new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1,
					CONFECTIONERY));

			layout.addView(listView);

			rootView = layout;
			rootView.setBackgroundColor(Color.WHITE);
			return rootView;
		}

		@Override
		public void onActivityCreated(Bundle savedInstanceState) {
			super.onActivityCreated(savedInstanceState);

			mGestureDetector = new GestureDetector(getActivity(),new MyGestureDetector());
			mGestureListener = new View.OnTouchListener() {
				@Override
				public boolean onTouch(View v, MotionEvent event) {
					return mGestureDetector.onTouchEvent(event);
				}
			};

			listView.setOnTouchListener(mGestureListener);
			listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
				@Override
				public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
					Log.d("onItemLongClick", "LongClick");
					Toast.makeText(MainActivity.this, "onItemLongClick LongClick", Toast.LENGTH_LONG).show();
					return true;
				}
			});
		}

		class MyGestureDetector extends SimpleOnGestureListener {
			private static final int SWIPE_MIN_DISTANCE = 120;
			private static final int SWIPE_MAX_OFF_PATH = 250;
			private static final int SWIPE_THRESHOLD_VELOCITY = 200;

			@Override
			public boolean onSingleTapUp(MotionEvent e) {
				int pos = listView.pointToPosition((int)e.getX(), (int)e.getY());
				myOnItemClick(pos);
				return false;
			}

			@Override
			public boolean onFling(MotionEvent e1, MotionEvent e2,
					float velocityX, float velocityY) {
				if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH) {
					return false;
				}

				boolean isDoCancel = false;

				if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
					Log.d("onFling", "FlingLeft");
					Toast.makeText(MainActivity.this, "onFling FlingLeft", Toast.LENGTH_LONG).show();

					isDoCancel = true;

				} else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
					Log.d("onFling", "FlingRight");
					Toast.makeText(MainActivity.this, "onFling FlingRight", Toast.LENGTH_LONG).show();

					isDoCancel = true;
				}

				if(isDoCancel){
					MotionEvent cancelEvent = MotionEvent.obtain(e2);
					cancelEvent.setAction(MotionEvent.ACTION_UP);
					listView.onTouchEvent(cancelEvent);
					return true;
				}else{
					return false;
				}

			}
		}
	}
}

フッターの書き換え(・∀・)

ずっと前に仕事でxlsやdocのfooterの内容を変えることがあった時に書いたVBAコード。
仕事としてではなく試しに家で書いたものなので公開しても問題ない…はず(・∀・)

まあ内容的に古いので今更有効活用出来る内容ではないけれども、
いつかまた何かの役に立つかもしれないのでエントリとして保存しておこう。

多分、こちらのエントリを参考にして再帰部分は書いた…ような。
VBA(2007もOK)で,ファイルの再帰検索をしよう

その他の部分は色々なVBA関連のサイトやヘルプ(リファレンス?)を
参考にしたような気がするけど、詳しくは覚えていない。

MsgBoxとかの部分はお試しで入れているだけなので本当は要らない。
対象となるパスはxls_test()の中で直書きして、そこにxlsファイル群を
ぶちこんでこれを実行すると「All Rights Reserved, Copyright © ~」
みたいなのが右下のfooterに追加されるはず。
rightfooterを他のfooterやheaderに代えれば任意の部分の値を変更出来る…はず。

このままで動くかもしれないけれども、このコード自体は実地で
試したものではないので修正が必要かも(ノ∀`)

doc_test()はWord用。確かこれで動いたような気がする…けど自信はないw
最新のOfficeのVBAはどうなってるんだろうか。


Option Explicit

Function FileSearch2007(dir_path, target_extension)
	Dim found_files As Collection

	Set found_files = New Collection
	Call FileSearch2007_Repeat(dir_path, found_files, target_extension)
	Set FileSearch2007 = found_files
End Function

Private Sub FileSearch2007_Repeat(dir_path, found_files, target_extension)
	Dim fso As FileSystemObject
	Dim target_folder As Folder
	Dim sub_folder As Folder
	Dim objFile As File

	Set fso = New FileSystemObject
	Set target_folder = fso.GetFolder(dir_path)

	For Each sub_folder In target_folder.SubFolders
		Call FileSearch2007_Repeat(sub_folder.Path,found_files,target_extension)
	Next sub_folder

	For Each objFile In target_folder.Files
		With objFile
			If ((UCase)fso.GetExtensionName(.Path)) = target_extension) Then
				found_files.Add Item:=.Path
			End If
		End With
	Next objFile

	Set fso = Nothing
End Sub

Sub xls_test()
	Dim dir_path As String
	Dim target_extension As String
	Dim found_files As Collection
	Dim found_num As Integer

	//ここに対象のファイル群があるパスを指定
	dir_path = "<ディレクトリパス>" 'ThisWorkbook.Path & "\test"
	target_extension = UCase("xls")

	Set found_files = FileSearch2007(dir_path, target_extension)

	found_num = found_files.Count
	If found_num = 0 Then
		MsgBox "not found"
	Else
		MsgBox found_num & " found"

		Dim i As Integer
		Dim bookpath As String
		Dim TargetBook As Workbook
		Dim eachsheet As Worksheet

		For i= 1 To found_num
			bookpath=found_files(i)
			If Len(bookpath) > 0 Then
				'MsgBox bookpath
				Set TargetBook = Workbooks.Open(bookpath)

				'Office2010の互換性チェックを無効にする。
				Dim ret As Variant
				ret = Application.Version
				If Val(ret)=14 Then
					ActiveWorkbook.CheckCompatibility = False
				Else
				End If

				For Each eachsheet In TargetBook.Worksheets
					With eachsheet.PageSetup
					//ここでFooterやHeaderの値を修正
						RightFooter = "All Rights Reserved, Copyright " & Chr(169) & ""
					End With
				Next eachsheet

				TargetBook.Save
				TargetBook.Close
			End If
		Next i

		MsgBox "xls modified"
	End If
End Sub

Sub doc_test()
	Dim dir_path As String
	Dim target_extension As String
	Dim found_files As Collection
	Dim found_num As Integer

	dir_path = "<ディレクトリパス>" 'ThisWorkbook.Path & "\test"
	target_extension = UCase("doc")

	Set found_files = FileSearch2007(dir_path, target_extension)
	found_num = found_files.Count
	If found_num = 0 Then
		MsgBox "not found"
	Else
		MsgBox found_num & " found"

		Dim i As Integer
		Dim docpath As String
		Dim eachsheet As Worksheet
		Dim objWord As Object

		Set objWord = CreateObject("Word.Application")
		For i = 1 To found_num
			docpath = found_files(i)
			If Len(docpath) > 0 Then
				'MsgBox docpath
				With objWord
					.Documents. Open docpath

					.ActiveDocument.Section(1).Footers(1).Range.Text=
					"All Rights Reserved, Copyright " & Chr(169) & ""

					.ActiveDocument.Save
					.ActiveDocument.Close
				End with
			End if
		Next i
		MsgBox "doc modified"
	End If
End Sub

プチコンmkII

買っておいてずっと放置していたプチコンmkIIを触ってみた(・∀・)

日経ソフトウェアの2012年1月号があったので、
それに載っていたサンプルコードをポチポチ打ち込んだ。

想像してたものよりもなんか凄かったw
入力支援があったり、3DSでもサクサク動いてた。
やろうと思えばそれなりのゲームが作れるような気がする。
テキストからPTCへ変換するツールもある、つまりはPCで
作成して3DSのプチコンへと流しこむことも出来るみたい。

スマイルブームのページにチュートリアルもあるので
子供やちょっと試しにプログラミングしてみたい人に良さそう。

中々面白い(・∀・)