服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 新手入门 > 基础入门 > 查看文档

使用gamecanvas制作星空效果

    midp2.0中提供了游戏开发专用的api,比如gamecanvas等类。他们位于javax.microedition.lcdui.game包内。本文介绍gamecanvas的基本使用方法并实现一种滚动星空的效果。您可以参考game canvas basic获得更详细的信息。

    gamecanvas是canvas的子类,因此他同样继承了canvas类的一些特性,比如shownotify()方法会在canvas被显示在屏幕的时候调用,而hidenotify()会在canvas离开屏幕的时候被调用。我们可以把他们当作监听器来使用,用于初始化和销毁资源。比如
    // when the canvas is shown, start a thread to
    // run the game loop.

    protected void shownotify()
    {
        random = new random();
        thread = new thread(this);
        thread.start();
    }
    // when the game canvas is hidden, stop the thread.

    protected void hidenotify()
    {
        thread = null;
    }

在游戏开发中最重要的就是接受用户触发的事件然后重新绘制屏幕,通常我们使用getkeystates()方法判断哪个键被按下了,然后绘制屏幕,调用flushgraphics()。在gamecanvas中,系统事实上已经为我们实现了双缓冲技术,因此每次我们绘制的时候就是在off-screen上绘制的。结束后通过flushgraphics把它复制到屏幕上去。下面是典型的接受事件、处理逻辑、绘制屏幕的代码。
 // get the graphics object for the off-screen buffer
graphics g = getgraphics();

while (true) {
      // check user input and update positions if necessary
      int keystate = getkeystates();
      if ((keystate & left_pressed) != 0) {
          sprite.move(-1, 0);
      }
      else if ((keystate & right_pressed) != 0) {
          sprite.move(1, 0);
      }

// clear the background to white
g.setcolor(0xffffff);
g.fillrect(0,0,getwidth(), getheight());

      // draw the sprite
      sprite.paint(g);

      // flush the off-screen buffer
      flushgraphics();
}

    下面开始实现我们滚动星空的效果,其实设计的思想非常简单。我们启动一个线程,使用copyarea()方法把屏幕的内容往下复制一个像素的距离。然后绘画第一个空白的直线,随机的在直线上绘画点儿,这样看起来就像星空一样了。逻辑代码如下:
    // the game loop.

    public void run()
    {
        int w = getwidth();
        int h = getheight() - 1;
        while (thread == thread.currentthread())
        {
            // increment or decrement the scrolling interval
            // based on key presses
            int state = getkeystates();

            if ((state & down_pressed) != 0)
            {
                sleeptime += sleep_increment;
                if (sleeptime > sleep_max)
                    sleeptime = sleep_max;
            } else if ((state & up_pressed) != 0)
            {
                sleeptime -= sleep_increment;
                if (sleeptime < 0)
                    sleeptime = 0;
            }

            // repaint the screen by first scrolling the
            // existing starfield down one and painting in
            // new stars...

            graphics.copyarea(0, 0, w, h, 0, 1, graphics.top | graphics.left);
            graphics.setcolor(0, 0, 0);
            graphics.drawline(0, 0, w, 0);
            graphics.setcolor(255, 255, 255);
            for (int i = 0; i < w; ++i)
            {
                int test = math.abs(random.nextint()) % 100;
                if (test < 5)
                {
                    graphics.drawline(i, 0, i, 0);
                }
            }
            flushgraphics();

            // now wait...

            try
            {
                thread.currentthread().sleep(sleeptime);
            } catch (interruptedexception e)
            {
            }
        }
    }
使用gamecanvas制作星空效果

 

 

 

 

 

 

 

 


下面给出源代码
/*
 * license
 *
 * copyright 1994-2004 sun microsystems, inc. all rights reserved.
 * 
 */

import javax.microedition.lcdui.*;
import javax.microedition.lcdui.game.*;
import javax.microedition.midlet.*;

public class gamecanvastest extends midlet implements commandlistener
{

    private display display;

    public static final command exitcommand = new command("exit", command.exit,
            1);

    public gamecanvastest()
    {
    }

    public void commandaction(command c, displayable d)
    {
        if (c == exitcommand)
        {
            exitmidlet();
        }
    }

    protected void destroyapp(boolean unconditional)
            throws midletstatechangeexception
    {
        exitmidlet();
    }

    public void exitmidlet()
    {
        notifydestroyed();
    }

    public display getdisplay()
    {
        return display;
    }

    protected void initmidlet()
    {
        gamecanvas c = new starfield();
        c.addcommand(exitcommand);
        c.setcommandlistener(this);

        getdisplay().setcurrent(c);
    }

    protected void pauseapp()
    {
    }

    protected void startapp() throws midletstatechangeexception
    {
        if (display == null)
        {
            display = display.getdisplay(this);
            initmidlet();
        }
    }
}
/*
 * license
 *
 * copyright 1994-2004 sun microsystems, inc. all rights reserved.
 */

import java.util.random;
import javax.microedition.lcdui.*;
import javax.microedition.lcdui.game.gamecanvas;

// a simple example of a game canvas that displays
// a scrolling star field. use the up and down keys
// to speed up or slow down the rate of scrolling.

public class starfield extends gamecanvas implements runnable
{

    private static final int sleep_increment = 10;

    private static final int sleep_initial = 150;

    private static final int sleep_max = 300;

    private graphics graphics;

    private random random;

    private int sleeptime = sleep_initial;

    private volatile thread thread;

    public starfield()
    {
        super(true);

        graphics = getgraphics();
        graphics.setcolor(0, 0, 0);
        graphics.fillrect(0, 0, getwidth(), getheight());
    }

 

    // the game loop.

    public void run()
    {
        int w = getwidth();
        int h = getheight() - 1;
        while (thread == thread.currentthread())
        {
            // increment or decrement the scrolling interval
            // based on key presses
            int state = getkeystates();

            if ((state & down_pressed) != 0)
            {
                sleeptime += sleep_increment;
                if (sleeptime > sleep_max)
                    sleeptime = sleep_max;
            } else if ((state & up_pressed) != 0)
            {
                sleeptime -= sleep_increment;
                if (sleeptime < 0)
                    sleeptime = 0;
            }

            // repaint the screen by first scrolling the
            // existing starfield down one and painting in
            // new stars...

            graphics.copyarea(0, 0, w, h, 0, 1, graphics.top | graphics.left);
            graphics.setcolor(0, 0, 0);
            graphics.drawline(0, 0, w, 0);
            graphics.setcolor(255, 255, 255);
            for (int i = 0; i < w; ++i)
            {
                int test = math.abs(random.nextint()) % 100;
                if (test < 5)
                {
                    graphics.drawline(i, 0, i, 0);
                }
            }
            flushgraphics();

            // now wait...

            try
            {
                thread.sleep(sleeptime);
            } catch (interruptedexception e)
            {
            }
        }
    }

    // when the canvas is shown, start a thread to
    // run the game loop.

    protected void shownotify()
    {
        random = new random();
        thread = new thread(this);
        thread.start();
    }
    // when the game canvas is hidden, stop the thread.

    protected void hidenotify()
    {
        thread = null;
    }
}

扫描关注微信公众号