我是Android的新手,并使用蓝牙聊天代码使用示例api我创建了一个tic tac toe游戏,
我可以通过蓝牙连接两个设备,并可以使用蓝牙名称作为对手的名字
例如,如果我的设备名称是“ABC”而对手是“DEF” 然后我的设备中的名字将是你:0 DEF:0
opponets device will have names YOU : 0 ABC : 0
( the score is initially set to 0).
问题出在哪里:
这些设备中的每一个都将其视为玩家1并且可以进行移动。但我想限制它,首先尝试连接设备的玩家获得第一步,然后获得另一个。
我该如何应对这种情况?请帮忙
我的代码:
public class test extends Activity {
// Debugging
private static final String TAG = "TicTacToe";
private static final boolean D = true;
// Message types sent from the BluetoothChatService Handler
public static final int MESSAGE_STATE_CHANGE = 1;
public static final int MESSAGE_READ = 2;
public static final int MESSAGE_WRITE = 3;
public static final int MESSAGE_DEVICE_NAME = 4;
public static final int MESSAGE_TOAST = 5;
// Key names received from the BluetoothChatService Handler
public static final String DEVICE_NAME = "device_name";
public static final String TOAST = "toast";
// Intent request codes
private static final int REQUEST_CONNECT_DEVICE = 1;
private static final int REQUEST_ENABLE_BT = 2;
// Layout Views
private TextView mTitle;
private ListView mConversationView;
private EditText mOutEditText;
private Button mSendButton;
// Name of the connected device
private String mConnectedDeviceName = null;
// Array adapter for the conversation thread
private ArrayAdapter<String> mConversationArrayAdapter;
// String buffer for outgoing messages
private StringBuffer mOutStringBuffer;
// Local Bluetooth adapter
private BluetoothAdapter mBluetoothAdapter = null;
// Member object for the chat services
private BluetoothGameService mGameService = null;
// Member object for the chat services
private BluetoothChatService mChatService = null;
//game variable
// player names initialized with default values.
CharSequence player_name_1 = "Player 1";
CharSequence player_name_2 = "Player 2";
// score initialized to 0.
public static int ben = 0;
int game_mode = 0;
int count = 0; // to count the number of moves made.
int player = 1; // sets the player no. to 1 by default.
int score_player_1 = 0;
int score_player_2 = 0;
int arr[][] = {{0,0,0},{0,0,0},{0,0,0}}; // array which stores the movements made.
// dialog IDs
final int NAME_DIALOG_ID = 1;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(D) Log.e(TAG, "+++ ON CREATE +++");
// Set up the window layout
requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
setContentView(R.layout.tictactoe);
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.custom_title);
// Set up the custom title
mTitle = (TextView) findViewById(R.id.title_left_text);
mTitle.setText(R.string.app_name);
mTitle = (TextView) findViewById(R.id.title_right_text);
// Get local Bluetooth adapter
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
// If the adapter is null, then Bluetooth is not supported
if (mBluetoothAdapter == null) {
Toast.makeText(this, "Bluetooth is not available", Toast.LENGTH_LONG).show();
finish();
return;
}
final Button st = (Button) findViewById(R.id.start);
st.setEnabled(false);
}
// set player names
protected Dialog onCreateDialog(int id){
Dialog mdialog = new Dialog(this);
switch(id) {
case NAME_DIALOG_ID:
mdialog.setContentView(R.layout.name);
mdialog.setTitle("Player Names");
mdialog.setCancelable(true);
final EditText namep1 = (EditText) mdialog.findViewById(R.id.namep1);
final EditText namep2 = (EditText) mdialog.findViewById(R.id.namep2);
Button ok_b = (Button) mdialog.findViewById(R.id.ok);
ok_b.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
player_name_2 = mConnectedDeviceName; //player 2 name
player_name_1 = "You"; //player 1 name
score_player_1 = 0;
score_player_2 = 0;
new_game(namep1.getText()); //calling fn
dismissDialog(1);
}
});
break;
default:
mdialog = null;
}
return mdialog;
}
OnClickListener button_listener = new View.OnClickListener() {
public void onClick(View v) {
ImageButton ibutton = (ImageButton) v;
// Button inactive for further clicks until a result is obtained.
ibutton.setClickable(false);
ibutton.setBackgroundResource(R.drawable.xo);
// Increment Count on clicking the button.
count++;
if ((count % 2 != 0)) {
player = 1;
ibutton.setImageResource(R.drawable.system_cross);
}
else if ((count % 2 == 0)) {
player = 2; // human player.
ibutton.setImageResource(R.drawable.system_dot);
}
// after_move function to check the result and decide.
after_move(ibutton);
}
};
public void new_game(CharSequence player_name) {
setContentView(R.layout.tictactoe);
final ImageButton b3 = (ImageButton) findViewById(R.id.b3);
final ImageButton b2 = (ImageButton) findViewById(R.id.b2);
final ImageButton b1 = (ImageButton) findViewById(R.id.b1);
final ImageButton b6 = (ImageButton) findViewById(R.id.b6);
final ImageButton b5 = (ImageButton) findViewById(R.id.b5);
final ImageButton b4 = (ImageButton) findViewById(R.id.b4);
final ImageButton b9 = (ImageButton) findViewById(R.id.b9);
final ImageButton b8 = (ImageButton) findViewById(R.id.b8);
final ImageButton b7 = (ImageButton) findViewById(R.id.b7);
// set the OnClickListeners.
b1.setOnClickListener(button_listener);
b2.setOnClickListener(button_listener);
b3.setOnClickListener(button_listener);
b4.setOnClickListener(button_listener);
b5.setOnClickListener(button_listener);
b6.setOnClickListener(button_listener);
b7.setOnClickListener(button_listener);
b8.setOnClickListener(button_listener);
b9.setOnClickListener(button_listener);
// Re-enable the Click-able property of buttons.
b1.setClickable(true);
b2.setClickable(true);
b3.setClickable(true);
b4.setClickable(true);
b5.setClickable(true);
b6.setClickable(true);
b7.setClickable(true);
b8.setClickable(true);
b9.setClickable(true);
// dismissDialog(NAME_DIALOG_ID);
// dismissDialog(HELP_DIALOG_ID);
// update the score board with the already existing values.
// this line should come ONLY after the player name is set in the above lines.
set_score(3);
// reset the array arr.
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
arr[i][j] = 0;
/* *********************************************************
* Initiates the computer's chance during start of the game,
* as well as when there is a win / loose and the next
* chance is for the computer.
* *********************************************************
if ((game_mode == 1) && (count % 2 != 0))
CompGame();
*/
}
public void set_score(int player_number) {
TextView tv = (TextView) findViewById(R.id.scoreboard);
if (player_number == 1)
score_player_1 += 1;
else if (player_number == 2)
score_player_2 += 1;
else ; // Don't change score, but set the score board right.
CharSequence score_txt = player_name_1 + " : " + score_player_1 + " " + player_name_2 + " : " + score_player_2;
tv.setText(score_txt);
}
public void after_move (ImageButton ib) {
CharSequence pos_str = ""; // position as a string.
int pos = 0;
boolean result = false;
pos_str = (CharSequence) ib.getTag(); // get the position from the tag.
pos = (int) pos_str.charAt(0) - 48; // char to integer conversion.
// set the values in the array according to the player number.
if (player == 1) {
if (pos < 4)
arr[0][pos - 1] = 1;
else if (pos < 7)
arr[1][(pos - 1) % 3] = 1;
else if (pos < 10)
arr[2][(pos - 1) % 3] = 1;
}
else {
if (pos < 4)
arr[0][pos - 1] = 2;
else if (pos < 7)
arr[1][(pos - 1) % 3] = 2;
else if (pos < 10)
arr[2][(pos - 1) % 3] = 2;
}
// Check for the game result.
result = result_check(player);
// Result check section.
if (result == true) {
// check for the player number.
if (player == 1) {
set_score(1);
if (game_mode == 0) {
show_result("Congrats. " + player_name_1 + " wins !!");
}
}
else {
set_score(2);
if (game_mode == 0) { // human vs human
show_result("Congrats. " + player_name_2 + " wins !!");
}
}
return;
}
else if ((result == false) && arr_isFull()) {
show_result(" Game Draw ! "); // leave the space, or else dialog becomes cramped.
return;
}
else { } // continue game.
}
public boolean result_check(int player_local) {
boolean win = true;
int k = 0;
// check for horizontal condition only.
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (arr[i][j] != player_local) { // check with player number.
win = false;
break;
}
} // column loop.
if (win == true) {
return true;
}
win = true;
} // row loop.
win = true; // resetting win to true.
// checking for vertical condition only.
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (arr[j][i] != player_local) {
win = false;
break;
}
} // column loop.
if (win == true) {
return true;
}
win = true;
} // row loop.
win = true; // reset win to true.
// check for diagonal condition 1.
for (int i = 0; i < 3; i++)
if (arr[i][k++] != player_local) {
win = false;
break;
}
if (win == true) {
return true;
}
k = 2;
win = true; // reset win to true;
// check for diagonal condition 2.
for (int i = 0; i < 3; i++)
if (arr[i][k--] != player_local) {
win = false;
break;
}
if (win == true) {
return true;
}
return false;
}
public boolean show_result(CharSequence message) //function to select the game mode
{
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(message)
.setPositiveButton("Continue", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// reset the game environment.
new_game(player_name_2);
}
});
AlertDialog alert = builder.create();
alert.show();
return true;
}
public boolean arr_isFull () {
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
if (arr[i][j] == 0)
return false;
return true;
}
@Override
public void onStart() {
super.onStart();
if(D) Log.e(TAG, "++ ON START ++");
// If BT is not on, request that it be enabled.
// setupChat() will then be called during onActivityResult
if (!mBluetoothAdapter.isEnabled()) {
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
// Otherwise, setup the chat session
} else {
if (mGameService == null)
setupGame();
}
}
private void setupGame() {
Log.d(TAG, "setupGame()");
// Initialize the BluetoothGameService to perform bluetooth connections
mGameService = new BluetoothGameService(this, mHandler);
// Initialize the buffer for outgoing messages
mOutStringBuffer = new StringBuffer("");
}
@Override
public synchronized void onResume() {
super.onResume();
if(D) Log.e(TAG, "+ ON RESUME +");
// Performing this check in onResume() covers the case in which BT was
// not enabled during onStart(), so we were paused to enable it...
// onResume() will be called when ACTION_REQUEST_ENABLE activity returns.
if (mGameService != null) {
// Only if the state is STATE_NONE, do we know that we haven't started already
if (mGameService.getState() == BluetoothChatService.STATE_NONE) {
// Start the Bluetooth chat services
mGameService.start();
}
}
}
@Override
public synchronized void onPause() {
super.onPause();
if(D) Log.e(TAG, "- ON PAUSE -");
}
@Override
public void onStop() {
super.onStop();
if(D) Log.e(TAG, "-- ON STOP --");
}
@Override
public void onDestroy() {
super.onDestroy();
// Stop the Bluetooth chat services
if (mGameService != null) mGameService.stop();
if(D) Log.e(TAG, "--- ON DESTROY ---");
}
/**
* Sends a message.
* @param message A string of text to send.
*/
private void sendMessage(String message) {
// Check that we're actually connected before trying anything
if (mChatService.getState() != BluetoothChatService.STATE_CONNECTED) {
Toast.makeText(this, R.string.not_connected, Toast.LENGTH_SHORT).show();
return;
}
// Check that there's actually something to send
if (message.length() > 0) {
// Get the message bytes and tell the BluetoothChatService to write
byte[] send = message.getBytes();
mChatService.write(send);
// Reset out string buffer to zero and clear the edit text field
mOutStringBuffer.setLength(0);
mOutEditText.setText(mOutStringBuffer);
}
}
//从BluetoothChatService获取信息的处理程序
private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_STATE_CHANGE:
if(D) Log.i(TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1);
switch (msg.arg1) {
case BluetoothGameService.STATE_CONNECTED:
mTitle.setText(R.string.title_connected_to);
mTitle.append(mConnectedDeviceName);
//mConversationArrayAdapter.clear();
break;
case BluetoothGameService.STATE_CONNECTING:
mTitle.setText(R.string.title_connecting);
break;
case BluetoothGameService.STATE_LISTEN:
case BluetoothGameService.STATE_NONE:
mTitle.setText(R.string.title_not_connected);
break;
}
break;
case MESSAGE_WRITE:
byte[] writeBuf = (byte[]) msg.obj;
// construct a string from the buffer
String writeMessage = new String(writeBuf);
//mConversationArrayAdapter.add("Me: " + writeMessage);
break;
case MESSAGE_READ:
byte[] readBuf = (byte[]) msg.obj;
// construct a string from the valid bytes in the buffer
String readMessage = new String(readBuf, 0, msg.arg1);
//mConversationArrayAdapter.add(mConnectedDeviceName+": " + readMessage);
break;
case MESSAGE_DEVICE_NAME:
// save the connected device's name
mConnectedDeviceName = msg.getData().getString(DEVICE_NAME);
Toast.makeText(getApplicationContext(), "Connected to "
+ mConnectedDeviceName, Toast.LENGTH_SHORT).show();
if(ben>0)
{
final Button st = (Button) findViewById(R.id.start); // enable start button
st.setEnabled(true);
}
else
{
final Button st = (Button) findViewById(R.id.start); // disable start button
st.setEnabled(false);
}
break;
case MESSAGE_TOAST:
Toast.makeText(getApplicationContext(), msg.getData().getString(TOAST),
Toast.LENGTH_SHORT).show();
break;
}
}
};
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if(D) Log.d(TAG, "onActivityResult " + resultCode);
switch (requestCode) {
case REQUEST_CONNECT_DEVICE:
// When DeviceListActivity returns with a device to connect
if (resultCode == Activity.RESULT_OK) {
// Get the device MAC address
String address = data.getExtras()
.getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS);
// Get the BLuetoothDevice object
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
// Attempt to connect to the device
mGameService.connect(device);
}
break;
case REQUEST_ENABLE_BT:
// When the request to enable Bluetooth returns
if (resultCode == Activity.RESULT_OK) {
// Bluetooth is now enabled, so set up a chat session
setupGame();
} else {
// User did not enable Bluetooth or an error occured
Log.d(TAG, "BT not enabled");
Toast.makeText(this, R.string.bt_not_enabled_leaving, Toast.LENGTH_SHORT).show();
finish();
}
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.activity_main, menu);
return true;
}
private void ensureDiscoverable() {
if(D) Log.d(TAG, "ensure discoverable");
if (mBluetoothAdapter.getScanMode() !=
BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivity(discoverableIntent);
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.scan:
ben = ben + 1;
// Launch the DeviceListActivity to see devices and do scan
Intent serverIntent = new Intent(this, DeviceListActivity.class);
startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE);
return true;
case R.id.discoverable:
// Ensure this device is discoverable by others
ensureDiscoverable();
return true;
}
return false;
}
//when start is pressed
public void start(View v){
//showDialog(NAME_DIALOG_ID);
player_name_2 = mConnectedDeviceName; //player 2 name
player_name_1 = "You"; //player 1 name
score_player_1 = 0;
score_player_2 = 0;
new_game(player_name_1); //calling fn
}
//when back | return button is pressed
public void back(View v){
player_name_1 = "Player 1";
player_name_2 = "Player 2";
count = 0;
player = 1;
score_player_1 = 0;
score_player_2 = 0;
Intent open = new Intent("com.example.tictactoechat_abs.STARTINGPOINT");
startActivity(open);
}
}
答案 0 :(得分:1)
我建议在建立连接时,在游戏开始之前,你在客户端传输一条消息,说“游戏正在开始,我要先行”。如果一个人按下“加入”而另一个人按下“主持人”,你可能会告诉谁试图连接。
或者你可以通过让双方都发送一个随机数来随机化它,而最高的那个则是第一个。
答案 1 :(得分:0)
您可以创建一个代表玩家的玩家类。在那里,您可以将实例变量设置为所需的数字,每次增加一个。然后,数量最少的玩家可以先行,然后按照该数字顺序排列其余玩家。然后,您可以拥有一个类来管理所有玩家对象。该班级将负责检查下一个可用号码并将其分配给玩家。