Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java ME (J2ME) > Канва на весь экран. Как такое реализовать?


Автор: javastic 26.4.2005, 10:34
Приветствую вас винградовцы!

Дисплей моего телефона 128x160 точек. Сверху у меня строка состояния (на ней отображается уровень заряда батареи и пр. служебная информация), снизу строка для командных клавишь.
Я запрашиваю getWidth() и getHeight() и мне возвращается резултат: 128x128 точек, т.е.
32 точки сжираются этими строчками. В некоторых приложениях я видел что экран задействован полностью, помогите советом как это сделать?

Автор: AntonSaburov 26.4.2005, 11:46
Очень сильно подозреваю, что это может зависеть от модели телефона.

Автор: javastic 26.4.2005, 11:47
Т.е. лучше не предпринимать нестандартных ситуаций чтобы потом не возиться с совместимостью?

Автор: AntonSaburov 26.4.2005, 11:53
Думаю что так.

Но вполне может быть, что все не так уж и страшно - допускаю, что какие-нибудь System properties содержат внутри себя всякие параметры типа высоты верхней строки или еще чего. В таком случае может быть и можно использовать такую штуку - она не выпадает из общих вызовов, т.е. такие вызовы не влияют на переносимость. Если нет такого параметра - ну на нет и суда нет. А если есть - почему бы не попробовать.

Автор: Andrey Spirin 27.4.2005, 17:29
Status bar нельзя будет зарисовать. Soft key bar можно, используя Canvas (только не сможем тогда CommandListener использовать). Придёся свой листенер писать, то есть слушать кнопки через KeyPressed и делать свои обработки.
Например сделай заливку Canvas каким либо цветом. В цикле перебери с 0 до пусть будет 128, увидишь результат smile)

Автор: javastic 28.4.2005, 09:05
Цитата(Andrey @ 27.4.2005, 17:29)
Status bar нельзя будет зарисовать. Soft key bar можно, используя Canvas (только не сможем тогда CommandListener использовать). Придёся свой листенер писать, то есть слушать кнопки через KeyPressed и делать свои обработки.
Например сделай заливку Canvas каким либо цветом. В цикле перебери с 0 до пусть будет 128, увидишь результат smile)

Я почему спрашивал, потому что видел приложения которые "заливают" весь экран и
статус бар в том числе.
smile

Автор: Andrey Spirin 29.4.2005, 09:10
Java тут уже тогда не причём, не положено J2ME методам весь экран телефона получать, если этого не разрешено нативным кодом в самом телефоне. Так что тут уже точно никак. Если только сами свою JVM напишите и в телефон спортируете smile) (шютка), больно уж дело кропотливое
Кстати, данная функциональнасть с заливкой на весь экран происходила на каких то определённых девайсах? (нельзя ли было списочек хотябы, просто интересно)

Автор: javastic 29.4.2005, 09:34
Это телефон SonyEricsson k500i, я сделал две фотки из двух игр, на первой фотке можно увидеть что канва перекрывает весь экран http://www.vitalich.com/j2me/images/29-04-05_1036.jpg

на второй видны статусная и коммандная строки http://www.vitalich.com/j2me/images/29-04-05_1025.jpg

p.s. фотки делались между прочем на Motorola V600 smile

Автор: Andrey Spirin 29.4.2005, 09:46
скорее всего использовалось специфичное API, специально предназначеное для SonyEricsson, в первой игрушке. Стандартным сановским API это точно не возможно. Попробуй первую игрушку запустить, ну хотя бы на том же самом V600. Больше чем уверен, что даже проинсталироваться она у тебя не сможет в Moto smile

Автор: javastic 29.4.2005, 10:01
Вполне вероятно. Только эта игра не передаётся, т.к. наложены видимо секьюрити на распространение.

Автор: Dancer 29.4.2005, 10:09
На каждую хитрую Ж... как говорится, найдётся свой .... с ВИНТОМ. smile))
Да, я знаю, что эти вещи защищаются и всё такое. Можно в принципе в интернете поискать, должно что-то уже быть что позволяет обратится к файловой системе телефона. Попробуй, может быть чего нить найдёшь. Я с SonyEricsson не работал, так что здесь ничего не могу сказать. Поиск по Gogle рулит! smile)
Если можно будет обратится из какой то тулзины (не из самого телефона, через JSR-75 API) к файловой системе телефона, то скорее всего спокойно можно будет вытащить jad и jar файлики.
Дерзай!
Если чего найду, то сообщу.

Автор: Dancer 29.4.2005, 10:20
попрбуй здесь посмотреть http://www.google.ru/search?hl=ru&q=SonyEricsson+K500+filesystem+tool&lr=
поиграйся со словами в запросе. Более некогда в форуме быть smile, вечером зайду. Расскажи если что-то найдёшь

Автор: javastic 3.5.2005, 09:27
Привет. Например есть такая тулза http://sourceforge.net/projects/fma/, я ей когда-то пользовался, но она у меня глючит ужасно, а так функцонал хороший.

Вот более крутая штука http://edesktop.sourceforge.net/, в которая даже есть Net Monitor gsm сети.


Автор: Dancer 3.5.2005, 12:34
Хорошо, используя эти тулзы ты можешь до файловой системы добраться. Ты эти закрытые файлики можешь выковырять этими тулзами? Пробовал нати JAD/JAR файлы? Хоть какие нибудь смог вытащить из телефона?

Автор: javastic 3.5.2005, 12:37
Dancer, ещё не пробовал, но думаю что смогу без проблем. Чуть-чуть освобожусь и вытяну их из недр =)

Автор: Dancer 17.5.2005, 12:01
я так думаю это будет решение всех проблем. setFullScreenMode(boolean mode) это стандартный метод для Canvas. Кнопки софтварные самому придётся писать и обрабатывать. Этим методом нельзя закрасить статус бар. Так что извиняйте smile
Думаю, простенький код этому сможет помочь.
в классе наследуемом от Canvas делаю вызов this.setFullScreenMode(true) что означает, что моя канва всегда будет на весь экран, не включая статус бар.

Код

import javax.microedition.lcdui.*;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;

public class Gradient extends MIDlet {
    Display disp = Display.getDisplay(this);
    GradientCanvas grad = new GradientCanvas(0xff00ff,0xff0000,300,500);

    protected void startApp() throws MIDletStateChangeException {
        disp.setCurrent(grad);
    }

    protected void pauseApp() {
    }

    protected void destroyApp(boolean b) throws MIDletStateChangeException {
    }
}

class GradientCanvas extends Canvas {
    int[] interp;
    int color1;
    int color2;
    int width;
    int height;

    GradientCanvas(int color1, int color2, int width, int height){
        this.color1 = color1;
        this.color2 = color2;
        this.width = width;
        this.height = height;
        this.setFullScreenMode(true);
        
        int a1 = (color1 >> 24) & 0xff;
        int r1 = (color1 >> 16) & 0xff;
        int g1 = (color1 >>  8) & 0xff;
        int b1 = (color1) & 0xff;
        int da = ((color2 >> 24) & 0xff) - a1;
        int dr = ((color2 >> 16) & 0xff) - r1;
        int dg = ((color2 >>  8) & 0xff) - g1;
        int db = ((color2) & 0xff) - b1;
        interp = new int[257];
        for (int i = 0; i <= 256; i++) {
            int rgb =
            (((int) (a1 + da * i / 256)) << 24) |
            (((int) (r1 + dr * i / 256)) << 16) |
            (((int) (g1 + dg * i / 256)) <<  8) |
            (((int) (b1 + db * i / 256))      );
            interp[i] = rgb;
        }

    }
    public void paint(Graphics g){
        int x=100;
        int y=100;
        int r1 = 50;//y
        int r2 = 100;//x

        for(int i=0;i<height;i++) {
            g.setColor(interp[interp.length*i/height]);
            g.drawLine(0,i,width,i);
        }
    }

    int[] getInterpArray() {
        return interp;
    }
    void printInterpArray() {
        for(int i=0;i<interp.length;i++) {
            System.out.println("interp["+i+"]= "+interp[i]);
        }
    }
}



Спасибо за внимание, Андрюха

Автор: Nemesis 4.6.2005, 19:00
Цитата

Status bar нельзя будет зарисовать. Soft key bar можно, используя Canvas (только не сможем тогда CommandListener использовать). Придёся свой листенер писать, то есть слушать кнопки через KeyPressed и делать свои обработки.
Например сделай заливку Canvas каким либо цветом. В цикле перебери с 0 до пусть будет 128, увидишь результат )


Зачем говорить, что приложения в полный экран встречаются редко? Их уйма на самом деле. Любая нормальная игра показывается во весь экран и заливает всю область. И дело не в модели телефона. А реально нужен АПИ, вот где его можно найти... Это уже друой вопрос. А насчет этого:

Цитата

Я запрашиваю getWidth() и getHeight() и мне возвращается резултат: 128x128 точек, т.е.
32 точки сжираются этими строчками.


довольно странно, поскольку функции,т.е. методы класса Display возвращают истинные размеры экрана без всяких "урезок". Быть может ты все-таки использовал getClipHeight() и getClipWidth() ?

Автор: javastic 6.6.2005, 09:45
Nemesis нет именно getWidth() и getHeight(), вот поэтому для меня это и стало удивительно smile

Автор: Nemesis 6.6.2005, 19:08
Да, действительно, для полного экрана достаточно вызвать метод setFullScreenMode(true) и экран переводится в полноэкранку. CommandListener новый писать не нужно, клавиши итак обрабатываются, просто нажимая какую-либо функциональную клавишу выпадает список меню с нужными действиями. По поводу getWidth() и getHeight() даже не знаю smile У меня вообще в приложении непонятный баг, может кто-нибудь сталкивался?

На эмуляторе программа работает прекрасно, все хорошо и без глюка, но вот стоит перенести на реальный телефон приложение и появляется след:

Приложение работает в графическом режиме, скажем бегает там мячик, нажимаю клавишу с информацией о телефоне и
- на эмуляторе все в порядке, т.е. экран перерисовывается и выводится инфа в Form в виде StringItem.
- на телефоне задний(графика) экран не перерисоваля и инфа выводится поверх этого дела, но ! стоит нажать клавишу вверх smile и экран перерисовывается и информация нормально рисуется в новом чистом Form`е.
В чем здесь может быть ошибка? Кому интересно, могу код показать. Но хотелось бы разрешить эту проблему. Может быть дело в телефоне? Ведь эмулятор нормально работает, причем тестил на достаточном кол-ве эмуляторов( где-то на 6-ти).

Автор: javastic 7.6.2005, 09:54
Давай, запости код, я думаю кому-то будет интересно.

Автор: Nemesis 7.6.2005, 12:14
Вот код.Только там все без коммента, но я думаю итак все понятно.
Опущен класс отвечающий за спрайт, да он тут и не особо-то и нужен.

Код

package Graph;

/*
 * Main.java
 *
 * Created on 29 Май 2005 г., 19:23
 */

import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
/**
 *
 * @author  Nemesis
 * @version
 */
public class Main extends MIDlet implements CommandListener
{
    private Command exitMidlet = new Command("Выход", Command.EXIT,0);
    private Command backButton = new Command("Назад", Command.BACK,1);
    private Command showInfo   = new Command("Инфо",  Command.SCREEN,0);
    private Form info;
    private Draw dr;
    
    private Display curdispl;
   
    public Main()
    {
        curdispl = Display.getDisplay(this);         
    }
    
    public void startApp()     
    {
        try
        {
            dr = new Draw();
            dr.start();
            dr.addCommand(exitMidlet);
            dr.addCommand(showInfo);
            dr.setCommandListener(this);
            
            curdispl.setCurrent(dr);
        }
        catch(java.io.IOException zxz)
        {
            destroyApp(false);
            notifyDestroyed();
        }
    }
    
    public void pauseApp(){}
    
    public void destroyApp(boolean unconditional)
    {
        if( dr!=null) dr.stop();
    }
    
    public void commandAction(Command c, Displayable d)
    {
        if(c==exitMidlet)
        {
            destroyApp(false);
            notifyDestroyed();
        }
        
        if(c==showInfo)
        {
            
            Integer numcol= new Integer(Display.getDisplay(this).numColors());
            
            String textstr=
            "Ширина = "+dr.x.toString()
            +"\nВысота = "+dr.y.toString()            
            +"\nЦветов = "+numcol.toString();
            
            info = new Form("Информация");
            StringItem text = new StringItem("Инфо:\n",textstr);
            info.append(text);
            info.addCommand(backButton);
            info.setCommandListener(this);
            curdispl.setCurrent(info);
        }
        
        if(c==backButton)
        {
            curdispl.setCurrent(dr);
        }
    }
}

//----------------------------------------------------------------------------------------------------------------

package Graph;

/*
 * Draw.java
 *
 * Created on 29 Май 2005 г., 19:59
 */

import java.io.*;
import javax.microedition.lcdui.*;
import javax.microedition.lcdui.game.*;

/**
 *
 * @author  Nemesis
 * @version
 */

public class Draw  extends GameCanvas implements Runnable
{
    private TiledLayer fonPole; // Фон экрана
    private LayerManager lm;
    private SpriteObject ball;   // можно опустить
    boolean z;        
    
    public Integer x,y;
    
    public Draw() throws IOException
    {
        super(true); 
        
        fonPole = Fon();
        lm = new LayerManager();                
        lm.append(fonPole);
        
        Image im = Image.createImage("/Graph/Src/bol.png");
        ball = new SpriteObject(im, 23, 23);        
        ball.setPosition(getWidth()/2, getHeight()/2);
        ball.defineReferencePixel(ball.getWidth()/2, ball.getHeight()/2);
        
        lm.append(ball);        
        
        x = new Integer(0);
        y = new Integer(0);
        
        this.setFullScreenMode(true);
    }
    
    public void start()
    {
        z = true;
        Thread t = new Thread(this);
        t.start();
    }
    
    public TiledLayer Fon() throws IOException
    {
        Image im = Image.createImage("/Graph/Src/fon.png");
        TiledLayer tmp = new TiledLayer(21,13,im,16,16);
      
        int[] pole = 
        {            
        2, 2, 2, 7, 1, 1, 1, 2, 2, 2, 7, 1, 1, 1, 2, 2, 2, 7, 1, 1, 1,
    2, 2, 2, 1, 2, 2, 7, 2, 2, 2, 1, 2, 2, 7, 2, 2, 2, 1, 2, 2, 7,
    2, 7, 1, 6, 2, 2, 1, 2, 7, 1, 6, 2, 2, 1, 2, 7, 1, 6, 2, 2, 1,
    2, 1, 2, 2, 2, 2, 1, 2, 1, 2, 2, 2, 2, 1, 2, 1, 2, 2, 2, 2, 1,
    2, 1,12, 1, 1, 8, 5, 2, 1,12, 1, 1, 8, 5, 2, 1,12, 1, 1, 8, 5,
    2, 1, 7, 6, 2, 1, 2, 2, 1, 2, 2, 1, 7, 6, 2, 1, 2, 2, 1, 2, 2,
    2, 1, 6, 7, 1, 6, 7, 1, 6, 2, 2, 1, 6, 7, 1, 6, 7, 1, 6, 2, 2,
    2, 10,2, 1, 2, 2, 1, 2, 2, 2, 2, 10,2, 1, 2, 2, 1, 2, 2, 2, 2,
    2, 2, 2, 5, 1, 8, 5, 1, 1, 8, 2, 2, 2, 5, 1, 8, 5, 1, 1, 8, 2,
    2, 2, 2, 2, 2, 1, 1, 1, 1, 6, 2, 2, 2, 2, 2, 1, 1, 1, 1, 6, 2,
        2, 1,12, 1, 1, 8, 5, 2, 1,12, 1, 1, 8, 5, 2, 1,12, 1, 1, 8, 5,
        2, 10,2, 1, 2, 2, 1, 2, 2, 2, 2, 10,2, 1, 2, 2, 1, 2, 2, 2, 2,
        2, 2, 2, 1, 2, 2, 7, 2, 2, 2, 1, 2, 2, 7, 2, 2, 2, 1, 2, 2, 7
        };
        
        for(int i=0; i<13; i++)
            for(int j=0; j<21; j++)
                tmp.setCell(j, i, pole[21*i+j]);
            
        return tmp;
    }
    
    public void stop(){z = false;}
    
    public void run() 
    {
        Graphics g = getGraphics();
        while(z)
        {            
            inputKey();
            
            init(g);
            
            try{ Thread.sleep(20);}
            catch(java.lang.InterruptedException zxz){}
        }
    }
    

/* Здесь особо можно не вникать, просто происходит управление и остановка по мере приближения к концу экрана. А также передвижение самого мяча, если фон полностью прокручен(для того,чтобы можно было попасть в угол экрана, так мяч всегда в центре и движется только задник)*/
    private void inputKey()
    {
        int keyState = getKeyStates();
        
        if((keyState & LEFT_PRESSED) != 0 ) 
        {
            if(fonPole.getX()<0 && ball.getX()<getWidth()/2)
                fonPole.move(5,0);
            else
            {
                if(ball.getX()>0)
                    ball.move_left();
            }          
        }
        if((keyState & RIGHT_PRESSED) != 0 ) 
        {
            if((fonPole.getX()>-fonPole.getWidth()+getWidth()) && ball.getX()>getWidth()/2)
                fonPole.move(-5,0);
            else
            {
                if(ball.getX()<getWidth()-ball.getWidth())
                    ball.move_right();
            }
        }
        if((keyState & UP_PRESSED) != 0 ) 
        {
            if(fonPole.getY()<0 && ball.getY()<getHeight()/2)
                fonPole.move(0,5);
            else
            {
                if(ball.getY()>0)
                    ball.move_up();
            }
        }
        if((keyState & DOWN_PRESSED) != 0 )
        {
            if((fonPole.getY()>-fonPole.getHeight()+getHeight()) && ball.getY()>getHeight()/2)
                fonPole.move(0,-5);
            else
            {
                if(ball.getY()<getHeight()-ball.getHeight())
                ball.move_down();
            }
        }
    }
    
    private void init(Graphics g)
    {
        x = new Integer(g.getClipWidth());
        y = new Integer(g.getClipHeight());
        g.setColor(0xffffff);
        g.fillRect(0,0,getWidth(),getHeight());
        lm.paint(g,0,0);
        flushGraphics();
    }
    
    private void collide()
    {
        if(ball.collidesWith(fonPole, true))
        {
            
        }
    }
    
}



Надеюсь код понятен,если что, распишу все.

Автор: Zandr 29.6.2005, 13:00
Мдя, ребята, setFullScreenMode() это конечно хорошо, только в спецификации MIDP1.0 его еще нет... Так что делайте две канвы (под MIDP1 и MIDP2) с конструкторами по умолчанию. Выносите методы, которые вызываются извне, в интерфейс, добавляйте, что эти Canvas implements ваш интерфейс, а в мидлете (или где вы создаете вашу канву) создавайте ее ч-з:
Код

Class canvasClass;
if (midpVer >= 2) {
  canvasClass = Class.forName( "mygame.myFullscreenCanvas");
} else {
  canvasClass = Class.forName( "mygame.myStandartCanvas");
}
MyCanvas canvas = (MyCanvas) canvasClass.newInstance();

Можно даже без интерфейса обойтись. Просто пишется MyCanvas и MyFullScreenCanvas (которая наследует от MyCanvas и делает вызовы к setFullScreen.....). А в приложении определяется MIDP и по результату загружается нужный класс канвы, с помощью которого создается инстанс, который потом кастится в MyCanvas. Извне естественно fullScreenMode менять нельзя, только из MyFullScreenCanvas.

Автор: NickTo 3.8.2005, 11:21
чтоб в игре перекрыть статусбар.. попробуй в констукторе прописать следующий метод
Код

       //XXX Fullscreen for MIDP 2.0
        this.setFullScreenMode(true);
 

Автор: javastic 8.8.2005, 15:58
Nikolka52 мы не поддерживаем и не приветствуем взлом чужих программ, Мы пытаемся делать их сами.

М
 
Просьба болше не писать о взломе в этом форуме.

Автор: Steeller 14.9.2005, 16:10
Канва на весь экран реализуется сугубо под каждую платформу отдельно. Например, в Нокии вместо Canvas используется FullCanvas
public class Game
extends FullCanvas
implements Runnable {...
И т.д.
Добавлено @ 16:11
При этом нужно обязательно подключить специфичную библиотеку. Для Нокии, опять же:
import com.nokia.mid.ui.*;

Автор: W0LF 9.2.2006, 19:27
блин, а что такое не работает в MIDP2 (ну для к500i точно работатет):
Код

setFullScreenMode(boolean mode) 

???


упс. вторую страницу не дочитал smile
с первым MIDP повозиться надо

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)