论坛首页 移动开发技术论坛

J2ME实现水波倒影效果(CLDC1.1及CLDC1.0)

浏览 9012 次
精华帖 (0) :: 良好帖 (1) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2008-10-07   最后修改:2010-01-02
水波渲染
package org.gameeden.micro.effect;

import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;

/**
 * 水波渲染。
 * @author Sol
 * @since CLDC 1.1
 */
public final class WaveRenderer
{
    private long time;
    
    /**
     * 绘制波动的图像。
     * @param g 指定的Graphics上下文
     * @param img 图像源
     * @param inverted 是否颠倒图像
     * @param power 波能(0.0-1.0)
     * @param x_src 图像拷贝起始象素X坐标
     * @param y_src 图像拷贝起始象素Y坐标
     * @param width 图像拷贝宽
     * @param height 图像拷贝高
     * @param x_dest 锚点的象素X坐标
     * @param y_dest 锚点的象素Y坐标
     * @param anchor 图像锚点
     * @throws IllegalArgumentException 如果参数错误则抛出此异常
     */
    public void drawImage(Graphics g,Image img,boolean inverted,double power,int x_src,int y_src,int width,int height,int x_dest,int y_dest,int anchor) throws IllegalArgumentException
    {
        switch(anchor)
        {
            case Graphics.TOP|Graphics.LEFT:
            case Graphics.TOP|Graphics.RIGHT:
            case Graphics.TOP|Graphics.HCENTER:
            case Graphics.BOTTOM|Graphics.LEFT:
            case Graphics.BOTTOM|Graphics.RIGHT:
            case Graphics.BOTTOM|Graphics.HCENTER:
            case Graphics.VCENTER|Graphics.LEFT:
            case Graphics.VCENTER|Graphics.RIGHT:
            case Graphics.VCENTER|Graphics.HCENTER:
                break;
            default:
                throw new IllegalArgumentException();
        }
        
        if(power<0||power>1)
        {
            throw new IllegalArgumentException();
        }

        if(x_src<0||y_src<0||width<0||height<0||x_src+width>img.getWidth()||y_src+height>img.getHeight())
        {
            throw new IllegalArgumentException();
        }

        int swing=height>>3;
        int offsetX=-((anchor&Graphics.RIGHT)!=0?width:(anchor&Graphics.HCENTER)!=0?width>>1:0);
        int offsetY=-((anchor&Graphics.BOTTOM)!=0?height:(anchor&Graphics.VCENTER)!=0?height>>1:0);

        time++;

        for(int n=0,offset;n<height;n++)
        {
            offset=(int)((swing*(n+20)*Math.sin((double)swing*(height-n)/(n+1)+time)/height)*power);
            
            if(n+offset<0)
            {
                offset=-n;
            }
            else if(n+offset>=height)
            {
                offset=height-n-1;
            }

            g.setClip(x_dest+offsetX,y_dest+offsetY+n,width,1);
            
            if(inverted)
            {
                g.drawImage(img,x_dest+offsetX-x_src,y_dest+offsetY-y_src-height+1+(n<<1)+offset,Graphics.LEFT|Graphics.TOP);
            }
            else
            {
                g.drawImage(img,x_dest+offsetX-x_src,y_dest+offsetY-y_src-offset,Graphics.LEFT|Graphics.TOP);
            }
        }
    }
}




测试
import java.io.IOException;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.game.GameCanvas;
import javax.microedition.lcdui.game.Sprite;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;

import org.gameeden.micro.effect.WaveRenderer;

public final class TestMidlet extends MIDlet
{
    public TestMidlet()
    {
        try
        {
            TestCanvas testCanvas=new TestCanvas();
            Display.getDisplay(this).setCurrent(testCanvas);
            new Thread(testCanvas).start();
        }
        catch(IOException e)
        {
            e.printStackTrace();
        }
    }
    
    protected void startApp() throws MIDletStateChangeException
    {
    }
    
    protected void pauseApp()
    {
    }

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

final class TestCanvas extends GameCanvas implements Runnable
{
    private WaveRenderer waveRenderer;
    
    private int screenWidth;
    private int screenHeight;
    private int screenHalfWidth;
    private int screenHalfHeight;
    
    private Graphics g;
    private Image img;
    
    private int imgWidth;
    private int imgHeight;
    private int height;

    public TestCanvas() throws IOException
    {
        super(false);
        setFullScreenMode(true);
        
        waveRenderer=new WaveRenderer();
        
        screenWidth=getWidth();
        screenHeight=getHeight();
        screenHalfWidth=screenWidth>>1;
        screenHalfHeight=screenHeight>>1;

        g=getGraphics();
        img=Image.createImage("/logo.png");
        
        imgWidth=img.getWidth();
        imgHeight=img.getHeight();
    }
    
    public void run()
    {
        while(true)
        {
            render();
            flushGraphics();
            
            try
            {
                Thread.sleep(50);
            }
            catch(InterruptedException e)
            {
                e.printStackTrace();
            }
        }
    }
    
    public void render()
    {
        if(height+1<imgHeight)
        {
            height++;
        }

        g.setClip(0,0,screenWidth,screenHeight);
        g.drawRegion(img,0,0,imgWidth,height,Sprite.TRANS_NONE,screenHalfWidth,screenHalfHeight,Graphics.HCENTER|Graphics.BOTTOM);
        
        waveRenderer.drawImage(g,img,true,0.5,0,0,imgWidth,height,screenHalfWidth,screenHalfHeight,Graphics.HCENTER|Graphics.TOP);
    }
}




CLDC1.1效果图(模拟器录制)
  • src.rar (7.2 KB)
  • 描述: CLDC1.1 源码(高精度模拟)
  • 下载次数: 368
  • src.rar (7.3 KB)
  • 描述: CLDC1.0 源码(低精度模拟)
  • 下载次数: 240
论坛首页 移动开发技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics