Đăng ký
Cộng đồng phát triển game Việt - kết nối đam mê !

Cuộc Chiến Không Gian là game được làm để clone game 1945.

 

Mình đã viết tutorial trên các bài viết và đây là nơi để chúng ta cùng trao đổi thắc mắc về những khó khăn khi làm game này và đồng thời cũng là nơi để các bạn trình diễn các sản phẩm mà mình đã làm.

 

Data:

 

 

Cùng chia sẻ nhé! 

Lần cập nhật cuối tháng 4 20, 1:36 pm bởi Nguyễn Tài Hải.
Skype: hai.nguyentai<br />Gmail: hainguyentai@gmail.com

Em út tài hèn sức mọn, mày mò clone game "Cuộc Chiến Không Gian" của a.Hải được vài bữa cũng có chút thành quả


giờ post lên cho mọi người cùng chém


 


Game có tất cả 4 lvl, 4 lvl cho nâng cấp đạn, enemy giống nhau ở 3 lvl đầu, trừ con boss cuối


 


Bác nào k thấy con máy bay của mình thì xem trang  bằng google chrome nhé


 


Thông báo với Admin là em đã fix bugs không refresh BG rồi nhé cám ơn sự giúp đỡ của anh TaiHai !


 


em đưa luôn link public cho những ai k thích chơi thử trên forum


http://db.tt/NIrVfvEE


 


enjoy nhé


 


Lần cập nhật cuối tháng 6 14, 11:20 am bởi Nguyễn Tài Hải.
Dinh Hoang Thuan Nhan GLter - ACM

Cool!

 

Có một cái bug hổng biết có phải là em cố ý gài hông, màn hình không xóa làm cho hình trước chồng lên hình sau (anh đang dùng chrome Smile)

Cool!

 

Có một cái bug hổng biết có phải là em cố ý gài hông, màn hình không xóa làm cho hình trước chồng lên hình sau (anh đang dùng chrome Smile)

 

hehe, tại em k có phân state loading, nên lúc k có BG nó k có vẽ lại được lúc đó chắc nó đang load data đó anh, hehe, sáng mai sẽ sữa lại ngay

Dinh Hoang Thuan Nhan GLter - ACM

Lỗi này là do load image background quá lâu. Tức là đang thiếu phần xử lý loading trước khi paint game ấy mà. Đoạn xử lý loading images đơn giản như sau:

 

Chú ý: window.onload là hàm đầu tiên để gọi vào javascript. Nên chúng ta không cần phải click vào màn hình để chạy như trong bài hướng dẫn.

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
function loadImages(sources, callback)
{
    var loadedImages = 0;
    var numImages = 0;
    for (var src in sources)
    {
        numImages++;
    }
    for (var src in sources) {
        images[src] = new Image();
        images[src].onload = function(){
            if (++loadedImages >= numImages) {
                callback(); //Load xong hết image data gọi hàm callback()
            }
        };
        images[src].src = sources[src];
    }
}
 
//Có nhiều cách quản lý load resource.
window.onload =  function()
{
    var sources = [
        "imgs/MC_01.png",
        "imgs/MC_02.png",
        "imgs/MC_03.png",
        "imgs/1945Data.png",
        "imgs/beach.jpg",
        "imgs/Enemy.png",
        "imgs/Bullet.png",
        "imgs/Fire_01.png",
        "imgs/Fire_02.png",
        "imgs/Fire_03.png",
        "imgs/Fire_04.png",
        "imgs/Fire_05.png"
    ];
    loadImages(sources, initGame);
}
 
function initGame()
{
//Init game here
 
//End initGame call gameLoop()
  gameLoop();
}
Lần cập nhật cuối tháng 4 26, 12:28 am bởi Nguyễn Tài Hải.
Skype: hai.nguyentai<br />Gmail: hainguyentai@gmail.com

Đã load được hình nền, phiên bản đầu chạy khá tốt, khá thú vị!

 

Tiếp đi em ủng hộ em 2 tay, khi nào xong, cần phát triển lên Win 8 hoặc playbook thì liên hệ anh, hehe...

Lần cập nhật cuối tháng 4 26, 12:54 am bởi Nguyễn Quang Vinh.

Đã load được hình nền, phiên bản đầu chạy khá tốt, khá thú vị!

 

Tiếp đi em ủng hộ em 2 tay, khi nào xong, cần phát triển lên Win 8 hoặc playbook thì liên hệ anh, hehe...

 

Hehe, em làm chơi cho quen tay thôi anh Smile

làm xong, đẹp đẹp chút em làm thêm game khác hehe!

Mà lúc nào cần, em nhờ anh phụ, hehe!

Dinh Hoang Thuan Nhan GLter - ACM

Trả lời câu hỏi của Nhân về: requestAnimFrame 


1. Định nghĩa hàm requestAnimFrame toàn cục

 

1
2
3
4
5
6
7
8
9
10
11
12
window.requestAnimFrame = (function(callback)
{
    return window.requestAnimationFrame ||
    window.webkitRequestAnimationFrame ||
    window.mozRequestAnimationFrame ||
    window.oRequestAnimationFrame ||
    window.msRequestAnimationFrame ||
    function(callback)
    {
        window.setTimeout(callback, 1000 / gameFPS);
    };
})();

 

note: gameFPS: Giá trị này cần phải đưa  vào: ex: gameFPS = 60;

 

2. Cuối gameLoop() gọi callback đến gameLoop().

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function gameLoop()
{
    // update
    gameUpdate();
  
    // draw
    gamePaint();
     
    // request new frame
    requestAnimFrame(function()
    {
        gameLoop();
    });
}

 

Note: Chúng ta làm theo cách này để sau này có những tương tác khác có thể ngắt gameLoop() để pause game ngay.

Skype: hai.nguyentai<br />Gmail: hainguyentai@gmail.com

Phải chăng đây cũng là Cuộc Chiến Không Gian? Game Designer đâu hết rồi. Hận. 

 

 

Nguồn: http://www.phoboslab.org/ztype/

Lần cập nhật cuối tháng 5 3, 3:36 pm bởi Nguyễn Tài Hải.
Skype: hai.nguyentai<br />Gmail: hainguyentai@gmail.com

Phải chăng đây cũng là Cuộc Chiến Không Gian? Game Designer đâu hết rồi. Hận. 

hay =D>

Trò này khá giống "The typing of the dead" ngày xưa.

Hóa ra forum này có signature
Giúp em giải quyết vấn đề về va chạm giữa đạn và máy bay địch với !!!


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
var PlanetImg=null;
var PlanetEnImg=null;
var dan=null;
var dan2=null;
var PEx = [];
var PEy = [];
var danX=[];
var danY=[];
var pX;
var pY;
var BulletX;
var BulletY;
var count =0;
var check=0;
 
 
window.onload = function()  {
    var gameCv=document.getElementById("gameCv");
    PlanetImg = new Image();
    PlanetEnImg = new Image();
    dan = new Image();
     
    PlanetImg.src = "img/planet.png"; //set duong dan image
    PlanetEnImg.src = "img/planetEn.png";
    dan.src= "img/Dan.PNG";
     
     
    //loadBG(setUpGame);
    gameCv.getContext("2d").clearRect(0,0,gameCv.width,gameCv.height); //xoa het image trong canvas
    gameCv.getContext("2d").drawImage(PlanetImg,Math.random()*100,Math.random()*100); //sinh random image
    gameCv.getContext("2d").drawImage(PlanetEnImg, 150,200);
    gameCv.getContext("2d").drawImage(dan,Math.random()*100,Math.random()*100);
    gameCv.addEventListener("mousemove", handleMouseEvent);
    setInterval(handleTick,25);
 
}
 
//ham xu ly ve image theo toa do di mouse
 
 
function handleMouseEvent(mouseEvent) {
    pX = mouseEvent.offsetX - PlanetImg.width/2;
    pY = mouseEvent.offsetY - PlanetImg.height/2;  
}
function handleTick() {    
    var gameCv=document.getElementById("gameCv");
     
    var Pw=PlanetImg.width/2;
    var Ph=PlanetImg.height/2;
    var Pew=PlanetEnImg.width;
    var Peh=PlanetEnImg.height;
    var checkpush;
    BulletX = pX+2;
    BulletY = pY - 5;
     
     
    var numPE=0;
    var numD=0;
 
    count = count + 1; 
     
    gameCv.getContext("2d").clearRect(0,0,gameCv.width,gameCv.height); 
    gameCv.getContext("2d").drawImage(PlanetImg, pX, pY);
 
         
    //push mot toa do vao mang may bay dich
    if (Math.random() < 1/20 ) {
        checkpush=Math.random()*800
            if ((checkpush > (check + 184 )) || ( checkpush < (check - 184 ))) {
                PEx.push(checkpush);
                PEy.push(0);
                check=checkpush;
            }
    }
     
    //push mot toa do vao mang dan
    if (count > 5) {
    danX.push(BulletX);
    danY.push(BulletY);
    count = 0;
    }
 
     
     
     
    // ve quan dich
     
    while( numPE < PEx.length) {
        PEy[numPE]=PEy[numPE] + 3;     
        gameCv.getContext("2d").drawImage(PlanetEnImg,PEx[numPE],PEy[numPE]);      
        numPE=numPE+1;
    while (numD < danX.length) {
    danY[numD]=danY[numD] - 20;
    gameCv.getContext("2d").drawImage(dan,danX[numD],danY[numD]);
    gameCv.getContext("2d").drawImage(dan,danX[numD] + 62,danY[numD]-10);
            while ((((danX[numD]         (((danY[numD]  )
    {
    alert("Chet diiiii !!!");
    }
    numD=numD+1;   
    }      
    }
    numPE=0;
    numD=0;
    // tinh toan va cham
     
    while (numPE < PEx.length) {           
    if ((((pX       (((pY   )
    {
    alert("Chet diiiii !!!");
    }
    numPE= numPE +1;
    }
     
}


 
Lần cập nhật cuối tháng 6 14, 9:13 pm bởi Nguyễn Tài Hải.

Phát triển 1:


Đặt biến context để quản lý context 2d để đỡ phải get nhiều lần.



1
2
3
4
5
var context = gameCanvas.getContext("2d");
  
context.clearRect(0,0,gameCanvas .width,gameCanvas .height);
  
...


Phát triển 2:


Tách vẽ và xử lý đừng làm chung một chỗ:



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// ve quan dich
  
while( numPE < PEx.length)
{
    PEy[numPE]=PEy[numPE] + 3;     
    gameCv.getContext("2d").drawImage(PlanetEnImg,PEx[numPE],PEy[numPE]);      
     
    numPE=numPE+1;
}
 
while (numD < danX.length)
{
    danY[numD]=danY[numD] - 20;
    gameCv.getContext("2d").drawImage(dan,danX[numD],danY[numD]);
    gameCv.getContext("2d").drawImage(dan,danX[numD] + 62,danY[numD]-10);
         
    numD=numD+1;   
}


Xử lý va chạm giữa máy bay và đạn:


Mã giả:



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
// ve quan dich
    numPELength = PEx.length;
    numDanLength  = danX.length;
     
    while( numPE < numPELength)
    {
        while (numD < numDanLength)
        {
            if ( Kiểm tra va chạm )
            {
                // Va chạm ở đây
                 
                // Remove đạn có ID =  numD ra khỏi mảng
                danX.splice(numD, 1);
                danY.splice(numD, 1);
                 
                // Remove máy bay địch có ID =  numPE ra khỏi mảng
                PEx.splice(numPE, 1);
                PEy.splice(numPE, 1);
                 
                // Giản chiều dài mảng
                numPELength -= 1;
                numDanLength -= 1;
                 
                // Kiểm tra viên đạn tại vị trí mảng cũ.
                numD -=1;
                numPE -= 1;
            }
            numD=numD+1;  
        }
        numPE=numPE+1;
    }


 


Bạn thử áp dụng xem thế nào nhé!


 

Skype: hai.nguyentai<br />Gmail: hainguyentai@gmail.com
   thích điều này.

Chào mọi người !


em mới tham gia website, và đang tập làm quen.


Em làm theo hướng dẫn nhưng tới phần hiển thị item sau khi enemyPlane nổ (tức là enemyPLan nổ chỗ nào thì item hiển thị chỗ đóWink


Nhưng mà, em làm thì sau khi item hiển thị nó lại mất luôn.


Làm sao khi enemyPlan nổ thì item hiển thị luôn ở vị trí đó mà ko mất vậy 


day là đoạn code check va chạm giữa đạn và enemyPlan của em


 


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
if
                (
                (danxPosition[count] >= enemyXPosition[currentNumber] && (danxPosition[count]
                    ((danxPosition[count] + dan.width) > enemyXPosition[currentNumber] && (danxPosition[count] < (enemyXPosition[currentNumber] + enemyplaneImage.width)))
                )
            {
                if(danyPOsition[count] enemyYPosition[currentNumber]))
                {
                    
                    _context.drawImage(item[0],enemyXPosition[currentNumber],enemyYPosition[currentNumber]);
                   
                    danxPosition.splice(count,1);
                    danyPOsition.splice(count,1);
                    enemyXPosition.splice(currentNumber,1);
                    enemyYPosition.splice(currentNumber,1)
 
                    var change_to_recover = Math.random()*100;
                    score = score+100;
                    var d = new Image();
                    d.src="img/c.png";
                    _context.drawImage(d,enemyXPosition[currentNumber],enemyYPosition[currentNumber]);
                    destroy.play();
 
 
                }
 
            }
Lần cập nhật cuối tháng 7 18, 3:11 pm bởi Tom.

Tom said...


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
if
                (
                (danxPosition[count] >= enemyXPosition[currentNumber] && (danxPosition[count]
                    ((danxPosition[count] + dan.width) > enemyXPosition[currentNumber] && (danxPosition[count] < (enemyXPosition[currentNumber] + enemyplaneImage.width)))
                )
            {
                if(danyPOsition[count] enemyYPosition[currentNumber]))
                {
                    
                    _context.drawImage(item[0],enemyXPosition[currentNumber],enemyYPosition[currentNumber]);
                   
                    danxPosition.splice(count,1);
                    danyPOsition.splice(count,1);
                    enemyXPosition.splice(currentNumber,1);
                    enemyYPosition.splice(currentNumber,1)
 
                    var change_to_recover = Math.random()*100;
                    score = score+100;
                    var d = new Image();
                    d.src="img/c.png";
                    _context.drawImage(d,enemyXPosition[currentNumber],enemyYPosition[currentNumber]);
                    destroy.play();
 
 
                }
 
            }


Chố tô màu là nguyên nhân sai.


Để khắc phục chuyện này bạn làm tương tự với cách làm của máy bay địch. Vùng màu vàng sẽ trở thành nơi thêm iteam vào mảng.


Ví dụ:


1
2
3
4
5
6
7
8
9
10
11
//Biến toàn cục
var arrItemsPos = [];
 
//Chỗ tô màu sẽ là:
arrItems.push({x:enemyXPosition[currentNumber], y: enemyYPosition[currentNumber]});
 
//Trong hàm vẽ sẽ là:
for (var i=0; i<arrItems.length; i++)
{
   //Vẽ items ra ở đây.
}

Bạn có thể cài đặt dựa trên mã giả ở trên chứ?

Skype: hai.nguyentai<br />Gmail: hainguyentai@gmail.com
   thích điều này.
Múi giờ GMT +9. Bây giờ là 7:04 pm.