Package com.agifans.picedit.view

Source Code of com.agifans.picedit.view.EgoTestHandler

package com.agifans.picedit.view;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.awt.image.ColorModel;
import java.awt.image.MemoryImageSource;
import java.util.Timer;
import java.util.TimerTask;

import com.agifans.picedit.picture.EditStatus;
import com.agifans.picedit.picture.Picture;
import com.agifans.picedit.types.PictureType;
import com.agifans.picedit.utils.EgaPalette;

/**
* Handles the Ego Test mode when it is activated.
*
* @author Lance Ewing
*/
public class EgoTestHandler {

    // The possible directions that Ego can be moving in.
    enum Direction {
        NONE, NORTH, NORTH_EAST, EAST, SOUTH_EAST, SOUTH, SOUTH_WEST, WEST, NORTH_WEST
    };
   
    /**
     * The X position of Ego.
     */
    protected int x;
   
    /**
     * The Y position of Ego.
     */
    protected int y;
   
    /**
     * The View that contains the data for Ego.
     */
    protected View egoView;
   
    /**
     * The current loop that is being animated for Ego.
     */
    protected int currentLoop;
   
    /**
     * The current cell that is being displayed for Ego.
     */
    protected int currentCell;
   
    /**
     * The Direction that Ego is moving.
     */
    protected Direction direction = Direction.NONE;
   
    /**
     * The Picture that this EgoTestHandler is testing.
     */
    private Picture picture;
   
    /**
     * Holds the current edit status of the picture.
     */
    private EditStatus editStatus;
   
    /**
     * Constructor for EgoTestHandler.
     *
     * @param editStatus Holds the current edit status of the picture.
     * @param picture The Picture being tested, i.e. that Ego will be drawn on.
     */
    public EgoTestHandler(final EditStatus editStatus, Picture picture) {
        this.picture = picture;
        this.editStatus = editStatus;
       
        // Load the VIEW resource for Ego.
        try {
            this.egoView = new View(ClassLoader.getSystemResourceAsStream("com/agifans/picedit/view/view.001"));
        } catch (Exception e) {
            //Should never happen since we know that this VIEW is present in the JAR.
        }
       
        this.x = 80 - (this.getCurrentCellWidth() / 2);
        this.y = 150 - this.getCurrentCellHeight();
       
        // Timer that makes Ego walk when Ego Test mode is activated.
        Timer timer = new Timer();
        TimerTask walkingTask = new TimerTask() {
            public void run() {
                if (editStatus.isEgoTestEnabled()) {
                    cycleAndMoveEgo();
                }
            }
        };
        timer.scheduleAtFixedRate(walkingTask, 100, 100);
    }
   
    /**
     * Gets the current cell in Image form, adjusted according to the priority
     * screen rules for the Ego's current position.
     *
     * @return The created Image to be displayed on the picture.
     */
    public Image getCurrentCellImage() {
        Cell cell = this.egoView.getLoop(currentLoop).getCell(currentCell);
        int[] rgbPixelData = cell.getRGBPixelData().clone();
        int transparentColour = cell.getTransparentColour();
        int priorityBand = getPriorityBand();
        int priorityBandColour = EgaPalette.colours[priorityBand];
        int width = cell.getWidth();
        int height = cell.getHeight();
       
        int egoDataOffset = 0;
        for (int egoY=0; egoY < height; egoY++) {
            for (int egoX=0; egoX < width; egoX++) {
                if (rgbPixelData[egoDataOffset] == transparentColour) {
                    rgbPixelData[egoDataOffset] = EgaPalette.transparent;
                } else {
                    int pictureX = this.x + egoX;
                    int pictureY = this.y + egoY;
                    int picPriority = 0;
                   
                    // Determine priority at this pixel location.
                    for (int pictureOffset = (pictureY * 160) + pictureX; pictureOffset < 26880; pictureOffset = pictureOffset + 160) {
                        picPriority = EgaPalette.reverseColours.get(picture.getPriorityScreen()[pictureOffset]);
                        if (picPriority >= 3) {
                            break;
                        }
                    }
                   
                    // Convert transparent priority value back to red. Also handles KQ1 fix (i.e. 3 value)
                    if ((picPriority == 3) || (picPriority == 16)) {
                        picPriority = 4;
                    }
                   
                    // If the picture priority is greater than ego priority then
                    // make the pixel transparent. This will make Ego appear to go
                    // behind that part of the screen.
                    if (picPriority > priorityBand) {
                        rgbPixelData[egoDataOffset] = EgaPalette.transparent;
                    } else {
                        // Render Ego in its priority band if priority screen is showing.
                        if (this.editStatus.isPriorityShowing()) {
                            rgbPixelData[egoDataOffset] = priorityBandColour;
                        }
                    }
                }
                egoDataOffset++;
            }
        }
       
        return Toolkit.getDefaultToolkit().createImage(new MemoryImageSource(width, height, ColorModel.getRGBdefault(), rgbPixelData, 0, width));
    }
   
    /**
     * Gets the priority band associated with where Ego currently is.
     *
     * @return The priority band associated with where Ego currently is.
     */
    public int getPriorityBand() {
        int priorityBand = 0;
       
        // Priority is calculated based on where the bottom of the cell is.
        int egoBottom = this.y + this.getCurrentCellHeight();
       
        if (editStatus.getPictureType().equals(PictureType.SCI0)) {
            // For SCI0, the top 42 lines are for priority 0. The other 14 bands
            // get an even share of the 148 remaining lines (which, btw, doesn't
            // divide evenly, so the bands are not even as then are in AGI).
            priorityBand = ((int) ((egoBottom - 42) / ((190 - 42) / 14))) + 1;
        } else if (editStatus.getPictureType().equals(PictureType.AGI)) {
            // For AGI it is evenly split, 168 lines split 14 ways.
            priorityBand = (egoBottom / 12) + 1;

            // Make sure priority band is 4 or above for AGI since the bottom
            // four priority colours are reserved as control lines.
            if (priorityBand < 4) {
                priorityBand = 4;
            }
        }
       
        return priorityBand;
    }
   
    /**
     * Gets the width of Ego's current cell.
     *
     * @return The width of Ego's current cell.
     */
    public int getCurrentCellWidth() {
        return this.egoView.getLoop(currentLoop).getCell(currentCell).getWidth();
    }
   
    /**
     * Gets the height of Ego's current cell.
     *
     * @return The height of Ego's current cell.
     */
    public int getCurrentCellHeight() {
        return this.egoView.getLoop(currentLoop).getCell(currentCell).getHeight();
    }
   
    /**
     * Draws Ego on to the given Graphics2D. The zoom factor determines where
     * exactly Ego gets drawn on the screen and how much to stretch it.
     *
     * @param graphics The graphics to draw the Ego cell image on to.
     * @param zoomFactor The current zoom factor.
     */
    public void drawEgo(Graphics graphics, int zoomFactor) {
        Image egoImage = this.getCurrentCellImage();
        graphics.drawImage(egoImage, x * 2 * zoomFactor, y * zoomFactor, getCurrentCellWidth() * 2 * zoomFactor, getCurrentCellHeight() * zoomFactor, null);
    }
   
    /**
     * Cycles Ego to the next Cell and moves in the current direction.
     */
    public void cycleAndMoveEgo() {
        if (direction != Direction.NONE) {
            Loop loop = this.egoView.getLoop(currentLoop);
           
            int newX = x;
            int newY = y;
           
            // Move in the appropriate direction.
            switch (direction) {
                case NORTH:
                    newY = newY - 1;
                    if (newY < 0) {
                        newY = 167 - this.getCurrentCellHeight();
                    }
                    break;
           
                case SOUTH:
                    newY = newY + 1;
                    if (newY > (167 - this.getCurrentCellHeight())) {
                        newY = 0;
                    }
                    break;
           
                case EAST:
                    newX = newX + 1;
                    if (newX > (159 - this.getCurrentCellWidth())) {
                        newX = 0;
                    }
                    break;
           
                case WEST:
                    newX = newX - 1;
                    if (newX < 0) {
                        newX = 159 - this.getCurrentCellWidth();
                    }
                    break;
            }
           
            // Check to see if Ego is allowed to move to the new position (i.e. no obstacle line)
            int startOffset = ((newY + this.getCurrentCellHeight()) * 160) + newX;
            int endOffset = startOffset + this.getCurrentCellWidth();
            for (int pictureOffset=startOffset; pictureOffset < endOffset; pictureOffset++) {
                // If this point has a black unconditional obstacle pixel then exit without applying movement.
                if (EgaPalette.reverseColours.get(picture.getPriorityScreen()[pictureOffset]) == 0) {
                    return;
                }
            }

            // It is okay to move to the new position, so apply the motion.
            this.x = newX;
            this.y = newY;
           
            // Cycle to the next cell in this loop.
            this.currentCell++;
            if (this.currentCell >= loop.getNumberOfCells()) {
                this.currentCell = 0;
            }
        }
    }
   
    /**
     * Handles given KeyEvent if applicable.
     *
     * @param keyEvent The KeyEvent to handle (if applicable).
     */
    public void handleKeyEvent(KeyEvent keyEvent) {
        int key = keyEvent.getKeyCode();
       
        switch (key) {
            case KeyEvent.VK_UP:
                if (this.direction == Direction.NORTH) {
                    this.direction = Direction.NONE;
                } else {
                    this.direction = Direction.NORTH;
                    this.currentLoop = 3;
                    this.currentCell = 0;
                }
                break;
               
            case KeyEvent.VK_DOWN:
                if (this.direction == Direction.SOUTH) {
                    this.direction = Direction.NONE;
                } else {
                    this.direction = Direction.SOUTH;
                    this.currentLoop = 2;
                    this.currentCell = 0;
                }
                break;
               
            case KeyEvent.VK_LEFT:
                if (this.direction == Direction.WEST) {
                    this.direction = Direction.NONE;
                } else {
                    this.direction = Direction.WEST;
                    this.currentLoop = 1;
                    this.currentCell = 0;
                }
                break;
               
            case KeyEvent.VK_RIGHT:
                if (this.direction == Direction.EAST) {
                    this.direction = Direction.NONE;
                } else {
                    this.direction = Direction.EAST;
                    this.currentLoop = 0;
                    this.currentCell = 0;
                }
                break;
        }
    }
}
TOP

Related Classes of com.agifans.picedit.view.EgoTestHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.