Thêm âm thanh vào game[e3droid]
08/08/2012
FacebookTwitterDeliciousStumbleuponDiggMyspaceLinkedInZingmegovnlinkhay


 
Để đơn giản không code nhiều mình dùng lại project 6. Trong project 6 ta có xét va chạm giữa 2 sprite, khi 2 sprite này chạm vào nhau thì có vụ nổ. Vậy khi vụ nổ được bật thì cũng là lúc ta phát âm thanh vụ nổ. Ngoài ra khi mới bắt đầu game thì mình có chạy 1 đoạn nhạc nền nữa. Các bạn xem code sau.
code
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
package Bai_13_e3droid.gioi;
import java.util.ArrayList;
import android.view.MotionEvent;
import com.e3roid.E3Activity;
import com.e3roid.E3Engine;
import com.e3roid.E3Scene;
import com.e3roid.drawable.sprite.AnimatedSprite;
import com.e3roid.drawable.texture.TiledTexture;
import com.e3roid.event.SceneUpdateListener;
//Để tạo được vòng lặp trong game ta cần implements SceneUpdateListener
public class Bai_13_e3droidActivity extends E3Activity implements SceneUpdateListener {
    private final static int WIDTH  = 320;
    private final static int HEIGHT = 480;
    
    //Khai báo 2 biến đê quản lý nhạc nền và âm thanh nổ
    private Sound nhac_nen;
    private Sound no;
    
    private TiledTexture sunmonster;//Biến này để load ảnh nhé
    private TiledTexture explosion;
    private AnimatedSprite[] sprite;// Cái này là cái mới nè.Mình khai báo 1 mảng AnimatedSprite.
    //Cái này sẽ dùng để vẽ 1 cái mặt kiểu Yahoo ý, và 1 vụ nổ.
    
    
    //Cài này dùng để cắt cái ảnh của mình ra để lấy từng Frame 1
    private ArrayList<AnimatedSprite.Frame> Frames_sunmonster  = new ArrayList<AnimatedSprite.Frame>();
    private ArrayList<AnimatedSprite.Frame> Frames_explosion  = new ArrayList<AnimatedSprite.Frame>();
    
    //---------------------------------------------------------------------------------------
    @Override
    public E3Engine onLoadEngine() {
        E3Engine engine = new E3Engine(this, WIDTH, HEIGHT);
        engine.requestFullScreen();
        engine.requestPortrait();
        return engine;
    }
    //---------------------------------------------------------------------------------------
    @Override
    public E3Scene onLoadScene() {
        
        //Khởi tạo 2 biến quản lý âm thanh
        nhac_nen = new Sound(this, R.raw.nhacnen);
        no = new Sound(this, R.raw.no);
        
        E3Scene scene = new E3Scene();
        scene.addEventListener(this);
        
        //Cứ 30ms là làm tươi màn hình 1 lần
        scene.registerUpdateListener(30, this);
        //Giờ ta sẽ khởi tạo các AnimatedSprite
        sprite =  new AnimatedSprite[3];//Khai bảo mảng này có 3 phần tử
        
        //Đặt các ảnh và các sprite và khởi tạo vị trí của sprite này
        //Đặt cả 2 đối tượng này ở giữa theo trục x nhé.
        int centerX = (getWidth()  - sunmonster.getTileWidth())  / 2;       
        sprite[0] = new AnimatedSprite(sunmonster, centerX, 50);//Cái này đặt vị trí y=50
        
        centerX = (getWidth()  - explosion.getTileWidth())  / 2;   
        sprite[1] = new AnimatedSprite(sunmonster, centerX, getHeight()-50);//Cái này đặt ở cuối màn hình - 50 để bạn thấy nó luôn
        
        
        //Ở trên ta đã khởi tạo và đặt vị trí cho 2 sprite
        //Giờ ta add frame vào cho sprite
        sprite[0]. animate(100, Frames_sunmonster);//Cứ 100ms là vẽ 1 cái ảnh
        sprite[1].animate(100, Frames_sunmonster);
        
        //Add xong frame rồi. giờ ta cho nó hiện thị thôi.
        scene.getTopLayer().add(sprite[0]);
        scene.getTopLayer().add(sprite[1]);
        
        //Phần trên ta mới tạo ra 2 cái mặt cưới thồi. Giờ ta thêm 1 cái để làm vụ nổ nhé.
        sprite[2] = new AnimatedSprite(explosion, (getWidth()  - explosion.getTileWidth())  / 2, (getHeight() - explosion.getTileWidth())  / 2);//Đặt nó vào vị trí trung tâm
        //Add frame
        sprite[2].animate(100, Frames_explosion);
        
        //Hiện thị
        scene.getTopLayer().add(sprite[2]);
        //Tạm thời ta cho ẩn sprite[2]ẩn đi.
        sprite[2].hide();
        
        //Bắt đầu game thì ta bật nhạc nền.
        nhac_nen.play();
        return scene;
    }
    //---------------------------------------------------------------------------------------
    @Override
    public void onLoadResources() {
        /*TiledTexture(java.lang.String name,
                *int width,
                *int height,
                *int xindex,
                *int yindex,
                *int border,
                *Context context)
        */
        //Tại sao lại là 192/6: chiều rộng thực tế của ảnh là 192 và trong đó có 6 cái ảnh nhỏ, mỗi ảnh nhỏ là 1 sprite
        //nên ta mang chia cho 6 để lấy chiều rộng của 1 sprite
        sunmonster = new TiledTexture("sunmonster.png", 192/6, 32, 0, 0, 0, this);//Load ảnh mặt cười nè.
        
        
        explosion = new TiledTexture("explosion.png", 162/5, 32, 0, 0, 0, this);//Cái này là ảnh tạo ra vụ nổ.
        
        
        //Ở đây ta thực hiện cắt lấy từng frame của 2 bức ảnh trên
        Frames_sunmonster = new ArrayList<AnimatedSprite.Frame>();
        //Ta dùng phương thức add để lấy từng phần của bức ảnh nhé
        //.add(new AnimatedSprite.Frame(chỉ số cột, chỉ số hàng)); Chỉ số bắt đầu là 0 nhé.
        Frames_sunmonster.add(new AnimatedSprite.Frame(0, 0));//Cột 0, hàng 0
        Frames_sunmonster.add(new AnimatedSprite.Frame(1, 0));//Cột 1, hàng 0
        Frames_sunmonster.add(new AnimatedSprite.Frame(2, 0));//Cột 2, hàng 0
        Frames_sunmonster.add(new AnimatedSprite.Frame(3, 0));//Cột 3, hàng 0
        Frames_sunmonster.add(new AnimatedSprite.Frame(4, 0));//Cột 4, hàng 0
        Frames_sunmonster.add(new AnimatedSprite.Frame(5, 0));//Cột 5, hàng 0
        
        
        // cái này tương tự cái trên nhé.
        Frames_explosion = new ArrayList< AnimatedSprite.Frame>();
        Frames_explosion.add(new AnimatedSprite.Frame(0, 0));
        Frames_explosion.add(new AnimatedSprite.Frame(1, 0));
        Frames_explosion.add(new AnimatedSprite.Frame(2, 0));
        Frames_explosion.add(new AnimatedSprite.Frame(3, 0));
        Frames_explosion.add(new AnimatedSprite.Frame(4, 0));
        
    }
    //---------------------------------------------------------------------------------------
    public boolean onSceneTouchEvent(E3Scene scene, MotionEvent motionEvent) {
        //Khi chạm vào màn hình thì tắt nhạc nền
        nhac_nen.stop();
        return false;
    }
    //---------------------------------------------------------------------------------------
    
    /*
     * Trong vòng lặp này ta sẽ cho 2 mặt cười di chuyển. một mặt di chuyển từ trên xuống, một mặt di chuyển từ dưới
     * lên. Khi 2 mặt này chạm vào nhau thì có 1 vụ nổ. Khi sảy ra vụ nổ này thì 2 cái mặt cười sẽ biến mất*/
    @Override
    public void onUpdateScene(E3Scene arg0, long arg1) {
        runOnUiThread(new Runnable() {           
            public void run() {
                sprite[0].moveRelativeY(2);
                sprite[1].moveRelativeY(-2);//Mỗi lần ta di chuyển 2px
                
                
                if(sprite[0].collidesWith(sprite[1])){//Kiểm tra va chạm
                    //Khi 2 mặt cười này chạm vào nhau ta ẩn 2 mặt cười này đi
                    sprite[0].hide();
                    sprite[1].hide();
                    
                    //Ta cho hiện thị cái vụ nổ lên
                    sprite[2].show();
                    //Khi hiện thị bom thì ta cho phát tiếng nổ.(Cho phép lặp lại)
                    no.loop();
                }
            }
        });
        
    }
}
Ở code này ta khai báo thêm 2 biến để quán lý nhạc nền và nhạc vụ nổ.
Đây là lớp Sound phụ vụ cho việc play, pause, replay..
code
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package Bai_13_e3droid.gioi;
import android.content.Context;
import android.media.MediaPlayer;
public class Sound {
    private MediaPlayer mPlayer;
    private boolean mPlaying = false;
    private boolean mLoop = false;
    public Sound(Context ctx, int resID) {
        mPlayer = MediaPlayer.create(ctx, resID);
        
        mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            public void onCompletion(MediaPlayer mp) {
                mPlaying = false;
                if (mLoop) {
                    mp.start();
                }
            }
        });
    }
    public synchronized void play() {
        if (mPlaying)
            return;
        if (mPlayer != null) {
            mPlaying = true;
            mPlayer.start();
        }
    }
    
    public synchronized void replay() {
        if (mPlaying)
            return;
        if (mPlayer != null) {
            mPlaying = true;
            mPlayer.seekTo(0);
            mPlayer.start();
        }
    }
    public synchronized void stop() {
        try {
            mLoop = false;
            if (mPlaying) {
                mPlaying = false;
                mPlayer.pause();
            }
        } catch (Exception e) {
        }
    }
    public synchronized void loop() {
        mLoop = true;
        mPlaying = true;
        mPlayer.start();
    }
    public void release() {
        if (mPlayer != null) {
            mPlayer.release();
            mPlayer = null;
        }
    }
}
Các bạn chú ý là các đoạn nhạc được lưu trong thư mục res/raw/ tenfile. <