SSブログ

Android SDK で,ゲームを作る (1) [プログラム三昧]このエントリーを含むはてなブックマーク#

WS000944.png

Android SDK を使って,ゲームを作ってみました.その昔,アプレットで作成した「数字探しゲーム」の焼き直しです.ボタンの並べ方がわからないので, GridView に TextView を並べてみました.不完全ながらも,ゲームとして機能しそうなことがわかってきたので,ここに足跡を残します.

main.xml の記述

このアプリケーションは,4個の部品を縦に配置して作られています.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="center"
    >
    <TextView  
        android:id="@+id/title"
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:text="@string/app_name"
        android:gravity="center"
        android:layout_margin="10dp"
    />
    <GridView 
        android:id="@+id/content"
        android:layout_width="fill_parent" 
        android:layout_height="fill_parent"
        android:layout_weight="1"
        android:columnWidth="60dp"
        android:numColumns="auto_fit"
        android:verticalSpacing="10dp"
        android:horizontalSpacing="10dp"
        android:stretchMode="columnWidth"
        android:gravity="center"
        android:background="#333333"
    />
    <TextView  
        android:id="@+id/status"
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:text=""
        android:gravity="center"
        android:layout_margin="10dp"
    />
    <Button
        android:id="@+id/start"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:layout_margin="10dp"
        android:text="START"
    />
</LinearLayout>

タイトル行は,ただの TextView です. content と名付けられた GridView には,制御コードでボタンを配置します. status は,現在の状態を示す TextView です.最後の start ボタンをクリックするとゲームが開始されます.

strings.xml の記述

アプリケーションで使用するリソースを strings.xml というファイルに入れて置きます.まだ,有効活用されていないもので.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">Seek Number Game</string>
</resources>

これだけです.

SeekNumberActivity.java の記述

ゲームのすべてをひとつのクラスにまとめてみました.コメントも無いし,モデルとビューがゴチャゴチャになったプログラムですが,ご了承ください.

package org.noritan.seeknumber;

import java.util.ArrayList;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.GridView;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;

public class SeekNumberActivity extends Activity {
    private int columnCount = 4;
    private int rowCount = 4;
    private GridView content;
    private TextView statusBar;
    private Button startButton;
    private ButtonAdapter buttonAdapter;
    
	/** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // Create a model object.
        buttonAdapter = new ButtonAdapter(this, columnCount, rowCount);
        
        content = (GridView) findViewById(R.id.content);
        content.setOnItemClickListener(buttonAdapter);
        content.setNumColumns(columnCount);
        content.setAdapter(buttonAdapter);
        
        statusBar = (TextView) findViewById(R.id.status);
        
        startButton = (Button) findViewById(R.id.start);
        startButton.setOnClickListener(new OnClickListener(){
            @Override
            public void onClick(View v) {
                buttonAdapter.reorder();
            }
        });
    }
    

    private class ButtonAdapter extends BaseAdapter implements OnItemClickListener {
        private int buttonCount;
        private ArrayList<TextView> buttonList;
        private ArrayList<TextView> buttonOrdered;
        private int expected = Integer.MAX_VALUE;

        public ButtonAdapter(
                Context context,
                int columnCount,
                int rowCount
            ) {
            // Save button count for future use.
            this.buttonCount = columnCount * rowCount;
            
            buttonList = new ArrayList<TextView>();
            // create and put buttons.
            for (int i = 0; i < buttonCount; i++) {
                TextView button = new TextView(context);
                button.setText(String.valueOf(i+1));
                button.setGravity(Gravity.CENTER);
                button.setPadding(5, 5, 5, 5);
                buttonList.add(button);
            }
            // Initialize ordered button list.
            buttonOrdered = new ArrayList<TextView>(buttonList);
            notifyDataSetInvalidated();
        }
        public void reorder() {
            ArrayList<TextView> buttonLeft = new ArrayList<TextView>(buttonList);
            buttonOrdered.clear();
            for (int i = buttonList.size(); i > 0; i--) {
                int k = (int)(Math.random() * i);
                TextView button = buttonLeft.get(k);
                button.setVisibility(TextView.VISIBLE);
                buttonOrdered.add(button);
                buttonLeft.remove(k);
            }
            notifyDataSetInvalidated();
            expected = 0;
            statusBar.setText("GO!!");
        }
        
        @Override
        public int getCount() {
            return buttonCount;
        }
        @Override
        public Object getItem(int position) {
            return null;
        }
        @Override
        public long getItemId(int position) {
            return 0;
        }
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            return buttonOrdered.get(position);
        }
        @Override
        public void onItemClick (
                AdapterView<?> parent,
                View view,
                int position,
                long id
            ) {
            if (expected >= buttonCount) {
                // Nothing is expected.
                return;
            }
            // Select a button expected as next choice.
            TextView buttonExpected = buttonList.get(expected);
            if (view == buttonExpected) {
                // Right selection.
                // Make the right button invisible.
                buttonExpected.setVisibility(View.INVISIBLE);
                notifyDataSetInvalidated();
                // point next button to be expected.
                expected++;
                if (expected >= buttonCount) {
                    // All buttons are clicked.
                    statusBar.setText("Finished !!");
                }
            }            
        }
    }
}

START ボタンをクリックすると, TextView がランダムに配置されます.ユーザが 1 から順に TextView を押して消していって,最後まで消せたら,完了です.完了までの時間を競わせたいのだけど,タイマ機能は,まだはいっていません.

GridView に並べた部品をクリックすると「選択」してしまうので,このゲームの用途に使用するべきではないことがわかってきました.次は,他の Layout を試してみます.

参考サイト

Hello, Android
Android 版, "Hello World" は,各種 Layout オブジェクトの使い方実例まで付いています.こいつらを,片っ端から試してみりゃいいわけだ.

nice!(0)  コメント(2)  トラックバック(0)  このエントリーを含むはてなブックマーク#

nice! 0

コメント 2

moni

R.id.content
R.id.status
R.id.start

以上三つに
id cannot be resolved or is not a field
というエラーが出ます。

どうか御教授ください・・・。
by moni (2010-10-29 15:28) 

noritan

moniさん,いらっしゃいませ.
クラス R は, Android の開発環境が main.xml の記述をもとに自動的に作成してくれます.作成された Java のコードは,通常のソースファイルが入っている src フォルダではなく, gen[Generated Java Files] フォルダに配置されます.
ファイルの作成は, aapt によって自動的に作成されると R.java ファイルに書いてあり,コンパイルの前提条件として aapt が実行されているものと思われます.プロジェクトを作成する時に "New → Android → Android Project" を選ぶと,このあたりの設定も自動的に提供されます.どこで, aapt の実行を制御しているのかは,今日は探し出せませんでした.
by noritan (2010-10-30 02:07) 

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

トラックバックの受付は締め切りました

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。