Giật hình trên JFrame

xuan11290

New Member
7/3/11
8
0
0
Mình có đang làm 1 game bài tập lớn,mình chạy nó trên 1 Frame. Tuy nhiên mình gặp phải vấn đề là mỗi khi vẽ hình lại(cụ thể là các ảnh, sprite) trên JFrame thì hình thường bị nháy, giật(mình sử dụng 1 thread và vẽ lại sau 1 khoảng thời gian xác định).Mình đã có thử = cách là vẽ tất cả trên 1 Panel rồi add Panel vào Frame nhưng vẫn vậy.
Bạn nào đã từng gặp vấn đề này thì chỉ giáo mình với, làm sao để hình ko bị giật, cảm ơn!!
 

tauit_dnmd

Member
7/11/10
114
1
16
UIT
Ðề: Giật hình trên JFrame

Mình có đang làm 1 game bài tập lớn,mình chạy nó trên 1 Frame. Tuy nhiên mình gặp phải vấn đề là mỗi khi vẽ hình lại(cụ thể là các ảnh, sprite) trên JFrame thì hình thường bị nháy, giật(mình sử dụng 1 thread và vẽ lại sau 1 khoảng thời gian xác định).Mình đã có thử = cách là vẽ tất cả trên 1 Panel rồi add Panel vào Frame nhưng vẫn vậy.
Bạn nào đã từng gặp vấn đề này thì chỉ giáo mình với, làm sao để hình ko bị giật, cảm ơn!!
Hiện tượng giật hình là do chúng ta vẽ đi vẽ lại nhiều lần trực tiếp trên 1 Form.Giả sử chúng ta có nhiều Object cần vẽ trong game,mỗi lần vẽ thì Form đc repaint lại--> nhiều lần như vậy gây ra hiện tượng giật hình.

-Để chống giật hình thì bạn fai sử dụng các kĩ thuật (Double,Triple) Buffring,Page Flipping...:

*Tư tưởng của Double buffering:
+ Sử dụng 1 BufferedImage để làm buffer,chúng ta vẽ lên BufferedImage này,sau đó ,khi vẽ tất cả các thứ cần vẽ lên BufferedImage này xong thì chúng ta mới vẽ BufferedImage này lên Form.
+ Sau đây là ví dụ demo nhỏ .đc trích trong project game của mình.

PHP:
 public void drawMenu() 
{

// Buffer
        BufferedImage buffImg=new BufferedImage(ConstantGame.SCREEN_WIDTH,ConstantGame.SCREEN_HEIGHT,BufferedImage.TRANSLUCENT);
        Graphics2D g2d=(Graphics2D)buffImg.createGraphics();
        g.setClip(0,0,ConstantGame.SCREEN_WIDTH,ConstantGame.SCREEN_HEIGHT);
        for(int i=0;i<this.menuString.length;i++)
        {
            g2d.drawImage(
                    new ImageIcon(getClass().getResource(
                            ConstantGame.RESFOLDER+"Menu/"+menuString[i]+menuArr[i]+".png")).getImage(),
                    440,300+i*30,null);
           
        }
        g.drawImage(
                    new ImageIcon(getClass().getResource(
                            ConstantGame.RESFOLDER+"Menu/title.png")).getImage(),
                            440-50,70,null);
        g.drawImage(
                    new ImageIcon(getClass().getResource(
                            ConstantGame.RESFOLDER+"Menu/note0.png")).getImage(),
                   -10,ConstantGame.SCREEN_HEIGHT-20,250,15,null);
        g.drawImage(
                    new ImageIcon(getClass().getResource(
                            ConstantGame.RESFOLDER+"Menu/uit-mmt03.png")).getImage(),
                   1080-121,ConstantGame.SCREEN_HEIGHT-56,121,56,null);

/// Sau khi vẽ tất cả lên buffer xong thì vẽ buffer lên form.
        Graphics g=this.getGraphics();
        g.drawImage(buffImg,0,0,null);
    }
-Ngoài ra ,ngoài cách trên thì Java API cũng cung cấp cho chúng ta 1 lớp để thực hiện kĩ thuật chống nháy hình trong viết game: đó chính là class BufferStrategy .Bạn coi thêm trên Java API
 

JackV

Administrator
Staff member
Ðề: Giật hình trên JFrame

Chào mừng bạn đến với cộng đồng java việt nam.

Vấn đề của bạn đã từng được trao đổi trên forum.

Nếu bạn muốn trao đổi vấn đề của bạn thì post code lên mọi người kiểm tra và như thế thì ai cũng có kinh nghiệm.

Bạn nên hoạt động theo Quy tắc hỗ trợ khi hoạt động trên cộng đồng java
Thân!
 

xuan11290

New Member
7/3/11
8
0
0
Ðề: Giật hình trên JFrame

cảm ơn bạn, đoạn code draw của mình sau khi sửa đã ko bị giật nữa
public void drawStaticMap(Graphics g,String[] map,ImageObserver o){
boolean isStart=false;
int DX=16,DY=8,dx=400,dy=-200;
//draw nen

BufferedImage buffImage=new BufferedImage(jpanel.getWidth(), jpanel.getHeight(), BufferedImage.TRANSLUCENT);
Graphics2D g2d=(Graphics2D)buffImage.createGraphics();
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, jpanel.getWidth(), jpanel.getHeight());
//draw grass on buffer
for(int i=0;i<map.length;i++){
for(int j=0;j<map.length();j++){
if(map.charAt(j)=='0'){
if(!isStart){
isStart=true;
}else{
isStart=false;
}
}
if(isStart)
drawGrass(g2d,map.charAt(j),j*DX+dx,j*DY+dy,o);
}
isStart=false;
dx=dx-DX;
dy=dy+DY;
}
//draw cac o tren buffer
dx=400;dy=-200;
for(int i=0;i<map.length;i++){
for(int j=0;j<map.length();j++){
if(map.charAt(j)=='0'){
if(!isStart){
isStart=true;
}else{
isStart=false;
}
}
if(isStart)drawTile(g2d,map.charAt(j),j*DX+dx,j*DY+dy,o);
}
isStart=false;
dx=dx-DX;
dy=dy+DY;
}
// draw node tren buff
dx=400;dy=-200;
for(int i=0;i<map.length;i++){
for(int j=0;j<map.length();j++){
if(map.charAt(j)=='0'){
if(!isStart){
isStart=true;
}else{
isStart=false;
}
}
if(isStart)
drawTileNode(g2d,map.charAt(j),j*DX+dx,j*DY+dy,o);
}
isStart=false;
dx=dx-DX;
dy=dy+DY;
}
//Draw Arrow tren buff
nodeRotate[0].drawImage(g2d, o);
nodeRotate[1].drawImage(g2d, o);
nodeRotate[2].drawImage(g2d, o);

//Draw box move tren buff
g2d.drawImage(box.getImage(), box.getX(), box.getY(), o);
box.moveBox();
//Lay buffer ra
g.drawImage(buffImage, 0,0, null);
}
 

xuan11290

New Member
7/3/11
8
0
0
Ðề: Giật hình trên JFrame

Cho mình hỏi 1 điều nữa, nếu bạn biết thì giúp mình với:D
Mình có xử lí sự kiện khi mouse click như sau:
private void jPanel1MouseClicked(java.awt.event.MouseEvent evt) {
// TODO add your handling code here:
if(evt.getX()>488&&evt.getX()<515&&evt.getY()>218&&evt.getY()<235){
draw.nodeRotate[0].updateImage(1);
}else if(evt.getX()>392&&evt.getX()<419&&evt.getY()>314&&evt.getY()<331){
draw.nodeRotate[1].updateImage(2);
}else if(evt.getX()>456&&evt.getX()<483&&evt.getY()>346&&evt.getY()<363){
draw.nodeRotate[2].updateImage(3);
}

}

private void jPanel1MouseMoved(java.awt.event.MouseEvent evt) {
// TODO add your handling code here:
if(evt.getX()>488&&evt.getX()<515&&evt.getY()>218&&evt.getY()<235){
jPanel1.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
}else if(evt.getX()>392&&evt.getX()<419&&evt.getY()>314&&evt.getY()<331){
jPanel1.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
}else if(evt.getX()>456&&evt.getX()<483&&evt.getY()>346&&evt.getY()<363){
jPanel1.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
}else{
jPanel1.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
}
Đây là các sự kiện mình xử lí trên Frame, tác dụng của nó là mỗi khi mình click chuột vào các tọa độ đó thì ảnh tại vị trí đó được thay bằng 1 ảnh khác.
Vấn đề xảy ra là:
Tại lần click đầu tiên thì Frame bị giật 1 lần, từ sau đó click thì ko giật nữa,nếu bạn biết thì share mình với nhé:D:D
 

kenzso

New Member
23/5/10
267
5
0
Ðề: Giật hình trên JFrame

Cho mình hỏi 1 điều nữa, nếu bạn biết thì giúp mình với:D
Mình có xử lí sự kiện khi mouse click như sau:

Đây là các sự kiện mình xử lí trên Frame, tác dụng của nó là mỗi khi mình click chuột vào các tọa độ đó thì ảnh tại vị trí đó được thay bằng 1 ảnh khác.
Vấn đề xảy ra là:
Tại lần click đầu tiên thì Frame bị giật 1 lần, từ sau đó click thì ko giật nữa,nếu bạn biết thì share mình với nhé:D:D
Một thủ thuật trong trường hợp này là bạn tự cho chuột click 1 lần trước đi. :D so fun
 

xuan11290

New Member
7/3/11
8
0
0
Ðề: Giật hình trên JFrame

Mình nói rõ hơn, vấn đề là như thế này.Trong file mình đính kèm là hình game mình đang làm, có 3 nút mũi tên màu trắng là các vị trí cần xử lí sự kiện click, hiện tượng giật hình 1 lần chỉ xảy ra đối với 1 nút trong 3 nút đó, mà lại chỉ xảy ra tại lần click đầu tiên. Mình đã thử hoán đổi các hàm xử lí 3 nút(3 nút này xử lí tương tự nhau) thì luôn có 1 nút xảy ra vấn đề giật hình như vậy, còn 2 nút còn lại thì lại ko gây ra giật hình:D