티스토리 뷰

 

이번 포스팅에서는

이미 만들어진 특정 방에 유저가 입장하는

기능을 구현해보도록 하겠습니다.


======================================================================


Rhythm Game : Enter Room





1. Rhythm Game : Enter Room


 유저가 특정 방에 들어가는 기능을 구현하기 위해서는 방의 정보에 대해서 알고 각각의 변수에 대해 판단한 후에 입장해야합니다.

예를 들어, 방이 비밀번호 방으로 설정되어 있다면 비밀번호를 입력하여 들어갈 수 있도록 설정해야하고, 1인용이거나 방 인원의 가득찼다면 입장할 수 없어야합니다.


 이러한 변수들을 최대한 줄이고 제어하기 쉽게 하기 위해서 1인용이거나 사람이 가득찬 방이라면 해당 방의 버튼을 누르지 못하게 설정했습니다.

이렇게 설정한다면 비밀번호 방일 때만 다르게 처리해주고 입장 불가능한 나머지 변수에 대해서 오류를 줄일 수 있습니다.






2. Rhythm Game : ClientUI.java

 
  사용자가 특정 방에 입장하기 위해서는 방 목록에 있는 해당 방을 클릭하면 리스너가 호출되도록 설계할 것입니다.
ClientUI에 RoomPanel 객체를 생성해두었기 때문에 ClientUI에서 버튼에 대한 리스너를 호출하겠습니다. 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package client;
 
import java.awt.event.ActionListener;
 
    ...
 
public class ClientUI extends JFrame{
    
    ...
 
    private void addListeners() {
        
        ...
        
        // 총 8개의 방 버튼 
        for(int i=0;i<=7;i++) {
            ActionListener berh = new BtEnterRoomHandler(this);
            pnRoom.btList.get(i).addActionListener(berh);
        }
 
        ...
    
    }
 
    ...
}
 
cs







3. Rhythm Game : BtEnterRoomHandler.java


 이제 리스너에서 동작할 기능을 설계해야합니다.

사용자가 누른 버튼에 대한 정보는 ActionEvent e에 들어있기 때문에 e.getSource()를 통해 누른 버튼에 대한 정보를 얻어옵니다.

또한 btList에 방 버튼이 저장되어 있기 때문에 e.getSource()를 통해 btList에 몇번째 저장되어있는지 찾아내는 것이죠.

이를 통해 어떤 방에 들어가고 싶은지 알아내는 것입니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package handler;
 
import java.awt.Color;
 
    ...
 
public class BtEnterRoomHandler implements ActionListener{
    ClientUI ui;
    public BtEnterRoomHandler(ClientUI c) {
        ui = c;
    }
    @Override
    public void actionPerformed(ActionEvent e) {
        // 해당 방의 위치를 찾아 서버로 전송하기 위한 동작 ====
        int idx = ui.pnRoom.btList.indexOf(e.getSource());
        ui.net.sendEnterRoomRequest(idx);
    }
    
}
 
cs







4. Rhythm Game : ClientNetwork.java


 일단 리스너에서 얻어온 방의 위치를 이용해 서버로 enterroom 키워드와 방의 위치를 나타내는 idx 값을 전송합니다.

뒤에서 보겠지만 클라이언트의 요청에 대한 서버의 결과는 Room의 형태로 올 것입니다.


여기서 방에 입장할 수 없는 경우는 비밀번호 방일 경우만 존재하기 때문에 서버로부터 받은 Room 값이 null이라면 비밀번호 방이라고 판단합니다.

Room 값이 null이라면 비밀번호 방이기 때문에 사용자로부터 다이얼로그 창으로 비밀번호 값을 얻고 서버에게 사용자의 입력값을 전송하게 됩니다.

서버에서는 비밀번호를 통해 해당 방에 설정된 비밀번호와 일치하는지 찾고 일치한다면 해당 Room 객체를, 아니라면 null 값을 전송하게 됩니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package client;
 
import java.io.IOException;
 
     ...
 
public class ClientNetwork extends Thread {
    
    ...
    
    // 방 입장
    public void sendEnterRoomRequest(int idx) {        
        synchronized (oos) {
            try {
                oos.writeObject("enterroom#" + idx);
                Room resp = (Room) ois.readObject();
                if (!(resp == null)) {        
                    // 비밀번호 방이 아니고, 입장 성공시 띄울 화면
 
                } else {        // 비번방일 때
                    String pw = JOptionPane.showInputDialog("비밀번호를 입력하세요.");
                    if (!(pw.equals(""))) {
                        oos.writeObject("secretroom#" + pw);
                        resp = (Room) ois.readObject();
                        if(resp != null) {    
                            // 비밀번호 방인데 비밀번호 일치하여 입장 성공시 띄울 화면        
                                 
                        }else {
                            JOptionPane.showMessageDialog(ui, "비밀번호가 틀렸습니다.");
                        }
                    }
                }
            }catch (ClassNotFoundException | IOException e) {
                    System.out.println(e.toString());
            }
        }
    }    
 
    ...
 
}
cs







5. Rhythm Game : PersonalServer.java


 방에 입장하는 순서를 간단하게 정리하자며 다음과 같습ㄴ다.

 

 1) setJoinRoomIndex() 메소드로 유저의 정보를 담은 Account 객체에 해당 유저가 입장하고자 하는 방의 번호를 저장합니다.

     -> 해당 사용자가 방에 입장해있다면 해당 방의 idx를, 방에 입장해 있지않다면 idx는 -1로 설정합니다.


 2-1) 입장하고자하는 방이 비밀번호 방이라면 null를 전송합니다.

2-1-1) 클라이언트로부터 받은 비밀번호를 방에 설정된 비밀번호와 비교하여 일치한다면,

   해당 Room 객체를 전송하고 다른 유저에게 방의 정보가 바뀌었다는 사실을 UDP로 보냅니다.

2-2-2) 클라이언트로부터 받은 비밀번호를 방에 설정된 비밀번호와 비교하여 일치하지 않는다면,

   사용자의 idx값을 -1로 변경하고 null 값을 전송합니다.


 2-2) 입장하고자하는 방이 비밀번호 방이 아니라면 해당 Room 객체를 전송하고 다른 유저에게 방의 정보가 바뀌었다는 사실을 UDP로 보냅니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package server;
 
import java.io.IOException;
 
    ...
 
public class PersonalServer extends Thread {
    
    ...
 
    @Override
    public void run() {
        String[] command = null;
        while(socket.isConnected()) {
            
            ...
 
            switch(command[0]) {
                
                ...
 
                case "enterroom":        // 방 입장
                    user.setJoinRoomIndex(Integer.valueOf(command[1]));
                    int roomIndex = user.getJoinRoomIndex();
                    if(rooms.get(roomIndex).getJoiner().size() != 2 && rooms.get(roomIndex).getPass().equals("")) {
                        rooms.get(roomIndex).enterAccount(user);
                        resp = rooms.get(roomIndex);
                        sendToClient(resp);
                        sendAlramToAll("changerooms");
                    } else {
                        resp = null;
                        sendToClient(resp);
                    }
                    break;
                case "secretroom":    // 비번방 입장시
                    if(command[1].equals((rooms.get(user.getJoinRoomIndex()).getPass()))) {
                        rooms.get(user.getJoinRoomIndex()).enterAccount(user);
                        resp = rooms.get(user.getJoinRoomIndex());
                        sendAlramToAll("changerooms");
                    } else {
                        user.setJoinRoomIndex(-1);
                        resp = null;
                    }
                    sendToClient(resp);
                    break;
            }
        }
    }
 
    ...
 
}
 
cs




## 방 입장 기능에 대한 클래스 동작 흐름.


(Client) 해당 방 버튼 클릭시 리스너(BtEnterRoomHandler) 호출 -> ClientNetwork를 통해 서버로 'enterroom' 키워드와 방 위치를 담은 idx 전송 ->

(Server) 해당 방이 비밀번호 방인지 체크하여 비밀번호 방이라면 null, 아니라면 해당 Room 객체 전송 ->

-> (Client) 받은 데이터의 Room이 null 이라면 사용자에게 비밀번호 입력받음

-> 입력받은 비밀번호를 서버로 'secretroom' 키워드와 함께 전송

-> (Server) 받은 비밀번호와 해당 방의 비밀번호가 일치하면 해당 Room 객체 전송

-> (Client) 입장 성공으로 게임 대기방 화면 출력

-> (Server) 받은 비밀번호와 일치하지 않는다면 null 전송

-> (Client) 입장 실패로 비밀번호 실패 다이얼로그 출력


-> (Client) 받은 데이터의 Room이 null이 아니라면 입장 성공으로 게임 대기방 화면 출력





'Project > Java를 이용한 게임 프로그램 구현' 카테고리의 다른 글

10. Rhythm Game : Quick Enter Room  (4) 2018.12.05
8. Rhythm Game : Create Room  (0) 2018.12.03
7. Rhythm Game : LoginUserList  (0) 2018.12.03
6. Rhythm Game : Login  (0) 2018.11.30
5. Rhythm Game : Signup  (0) 2018.11.29
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함