java swing 横版卷轴界面

使用java swing来模拟游戏中横版卷轴界面的效果

------------------------------------------------------------------
GameRibbonPanel类
------------------------------------------------------------------
package com.qsuron;

import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JFrame;

public class GameRibbonPanel extends JFrame implements Runnable, KeyListener{

    private static final long serialVersionUID = 2655407680852591409L;
    public static final int WIDTH = 300;
    public static final int HEIGHT = 240;

    private Container contentPanel;
    public Image offScreenImage = null;                    //缓冲图像
    public Ribbon ribbon = null;

    //界面初始化
    private void jframeInit(){
        this.setTitle("Swing 游戏学习2 - 卷轴");
        this.setSize(WIDTH+200,HEIGHT+200);
        this.setLocation(400,200);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        contentPanel = this.getContentPane();
        contentPanel.setLayout(null);
        this.setVisible(true);
        this.addKeyListener(this);

        BufferedImage bim = new BufferedImage(1110,240,BufferedImage.TYPE_INT_ARGB);
        try {
            bim = ImageIO.read(getClass().getResource("MyPhoto.jpg"));
        } catch (IOException e) {e.printStackTrace();}
        ribbon = new Ribbon(1,bim);

        Thread gameThread = new Thread(this);
        gameThread.start();
    }

    public static void main(String[] args){
        GameRibbonPanel grp = new GameRibbonPanel();
        grp.jframeInit();
    }

    @Override
    public void run() {
        while(true){
            ribbon.update();
            ribbon.drawRibbon(this.getGraphics());
            try {
                Thread.sleep(5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void update(Graphics g) {
        if(offScreenImage==null){
            offScreenImage = this.createImage(WIDTH,HEIGHT);
        }
        Graphics goff = offScreenImage.getGraphics();
        paint(goff);
        g.drawImage(offScreenImage,0,0,null);
    }

    @Override
    public void keyTyped(KeyEvent e) {

    }

    @Override
    public void keyPressed(KeyEvent e) {
        if(e.getKeyCode()==KeyEvent.VK_RIGHT){
            ribbon.setCanMoveLeft(true);
        }else if(e.getKeyCode()==KeyEvent.VK_LEFT){
            ribbon.setCanMoveRight(true);
        }else if(e.getKeyCode()==KeyEvent.VK_UP){
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {
        ribbon.setCanMoveLeft(false);
        ribbon.setCanMoveRight(false);
    }

}

------------------------------------------------------------------
Ribbon类
------------------------------------------------------------------
package com.qsuron;

import java.awt.Graphics;
import java.awt.image.BufferedImage;

public class Ribbon {
    public BufferedImage bim;
    private int xImHead;        //图像X指针
    private int pWidth;            //窗口宽度
    private int pHeight;        //窗口高度
    private int width = 1110;    //图像宽度
    private int moveSize;
    private boolean canMoveLeft;
    private boolean canMoveRight;

    public Ribbon(int moveSize,BufferedImage bim){
        this.bim = bim;
        xImHead = 0;
        pWidth = GameRibbonPanel.WIDTH;
        pHeight = GameRibbonPanel.HEIGHT;
        this.moveSize = moveSize;
        canMoveRight = false;
        canMoveLeft = false;
    }

    public void drawRibbon(Graphics g){
        if(xImHead == 0){
            drawRibbon(g,bim,0,pWidth,0,pWidth);
        }else if(xImHead > 0 && xImHead < pWidth){
            drawRibbon(g, bim, 0, xImHead, pWidth - xImHead, width);
            drawRibbon(g, bim, xImHead, pWidth, 0, pWidth - xImHead);
        }else if(xImHead >= pWidth){
            drawRibbon(g, bim, 0, pWidth, width - xImHead, width - xImHead + pWidth);
        }else if(xImHead < pWidth - width){
            drawRibbon(g, bim, 0, width + xImHead, - xImHead, pWidth);
            drawRibbon(g, bim, width + xImHead, pWidth, 0, pWidth - width - xImHead);
        }else if(xImHead < 0 && xImHead >= pWidth - width){
            drawRibbon(g, bim, 0, pWidth, -xImHead, pWidth - xImHead);
        }
    }

    public void drawRibbon(Graphics g,BufferedImage bim,int dx1,int dx2,int sx1,int sx2){
        g.drawImage(bim, dx1+100, 0 + 100, dx2+100, pHeight + 100, sx1, 0, sx2, pHeight, null);
    }

    public void update(){
        if(canMoveLeft){
            xImHead = (xImHead - moveSize) % width;
        }else if(canMoveRight){
            xImHead = (xImHead + moveSize) % width;
        }
    }

    public void setCanMoveLeft(boolean canMoveLeft) {
        this.canMoveLeft = canMoveLeft;
    }

    public void setCanMoveRight(boolean canMoveRight) {
        this.canMoveRight = canMoveRight;
    }
}