j2me学习七_翻译教程-牧羊犬游戏3

 

八.音效实现

SoundEffects class

利用MIDP2.0 的mediaAPI创建犬吠,绵羊叫,还有游戏结束音

1创建SoundEffects类

2.引入类

import javax.microedition.media.*;

import java.io.*;

3.创建参数

class SoundEffects
{
    private static SoundEffects instance;
    private Player sheepSoundPlayer;
    private Player dogSoundPlayer;

4.初始化

  private SoundEffects()
    {
        sheepSoundPlayer = createPlayer("/sheep.wav", "audio/x-wav");
        dogSoundPlayer = createPlayer("/dog.wav", "audio/x-wav");
    }
 
    static SoundEffects getInstance()
    {
        if (instance == null)
        {
            instance = new SoundEffects();
        }
        return instance;
}
5.创建声音播放方法
  void startSheepSound()
    {
        startPlayer(sheepSoundPlayer);
    }
    
    void startDogSound()
    {
        startPlayer(dogSoundPlayer);
    }
 
    void startGameOverSound()
    {
        startPlayer(createPlayer("/gameover.mid", "audio/midi"));
    }
    
    void startHighScoreSound()
    {
        startPlayer(createPlayer("/highscore.mid", "audio/midi"));
    }
 
6.创建音效控制方法
private void startPlayer(Player p)
    {
        if (p != null)
        {
            try
            {
                p.stop();
                p.setMediaTime(0L);
                p.start();
            }
            catch (MediaException me)
            {
                // ignore
            }
        }
}
7.创建createPlayer方法
private Player createPlayer(String filename, String format)
    {
        Player p = null;
        try
        {
            InputStream is = getClass().getResourceAsStream(filename);
            p = Manager.createPlayer(is, format);
            p.prefetch();
        }
        catch (IOException ioe)
        {
            // ignore
        }
        catch (MediaException me)
        {
            // ignore
        }
        return p;
    }
}
 

九.实现游戏功能

SheepdogCanvas class

1.     创建类

2.  引入类

import java.util.Random;
import java.util.Vector;
import javax.microedition.lcdui.*;
import javax.microedition.lcdui.game.*;
import javax.microedition.media.*;
import java.io.*;

3.  SheepdogCanvas类继承GameCanvas类和Runable接口,GameCanvas是Canvas的一个子类,它提供了一些方便的游戏接口,还有一些特殊的游戏特性,例如帧缓冲,按键侦听。

class SheepdogCanvas
    extends GameCanvas
   implements Runnable

{

4.  定义和初始化参数

static final int NONE = -1;

    static final int UP = 0;

    static final int LEFT = 1;

    static final int DOWN = 2;

    static final int RIGHT = 3;

 

    private static final int MILLIS_PER_TICK = 50;

    private static final int NUM_SHEEP = 5;

   

    private final SheepdogMIDlet midlet;

    private final Field field;

    private final Sheepdog sheepdog;

    private final Vector sheep = new Vector();

    private final LayerManager layerManager;

 

    private final Graphics graphics;

    private long gameDuration;

    private long startTime;

private volatile Thread animationThread = null;

5.创建SheepdogCanvas对象,getGraphic方法用于获得Graphics对象来渲染GameCanvas,LayerManager类用于管理一系列的图层

   SheepdogCanvas(SheepdogMIDlet midlet)

    {

        super(true);   // suppress key events for game keys

        this.midlet = midlet;

        setFullScreenMode(true);

        graphics = getGraphics();

 

        layerManager = new LayerManager();

        field = new Field();

        sheepdog = new Sheepdog(this);

        layerManager.append(sheepdog);

        for (int i = 0; i < NUM_SHEEP; ++i)

        {

            Sheep newSheep = new Sheep(this);

            layerManager.append(newSheep);

            sheep.addElement(newSheep);

        }

        layerManager.append(field);   // last layer, behind sprites

 

        init();

}

6.创建用于按键侦听的方法,如果按了一个负数按键码的按键了,则跳出菜单

public void keyPressed(int keyCode)

    {

        // The constructor suppresses key events for game keys, so we'll

        // only get key events for non-game keys. The number keys, * & #

        // have positive keyCodes, so negative keyCodes mean non-game

        // special keys like soft-keys. We'll use key-presses on special

        // keys to take us to the menu.

        if (keyCode < 0)

        {

            stop();

            midlet.sheepdogCanvasMenu();

        }

    }

7.初见初始化函数,getWidth和getHeight方法用于获得当前画布的宽和高,setPosition方法用于设定层得位置(左上角为基准点)

void init()

    {

        sheepdog.setPosition(field.getSheepdogStartX(),

                             field.getSheepdogStartY());

        for (int i = 0; i < sheep.size(); ++i)

        {

            Sheep sh = (Sheep)(sheep.elementAt(i));

            // find a valid position for the sheep

            do

            {

                int x = midlet.random(field.getWidth() - Sheep.WIDTH);

                int y = midlet.random(field.getHeight() - Sheep.HEIGHT);

                sh.setPosition(x, y);

            } while (field.containsImpassableArea(sh.getX(),

                                                  sh.getY(),

                                                  sh.getWidth(),

                                                  sh.getHeight()) ||

                     overlapsSheepdog(sh) ||

                     overlapsSheep(sh, i) ||

                     field.inFold(sh));

        }

}

8.创建用于开始和终止游戏的方法

public synchronized void start()

    {

        animationThread = new Thread(this);

        animationThread.start();

        startTime = System.currentTimeMillis() - gameDuration;

    }

 

    public synchronized void stop()

    {

        gameDuration = System.currentTimeMillis() - startTime;

        animationThread = null;

}

9.创建run方法,FlushGraphics方法用于将缓冲区的图像在屏幕上显示

    public void run()

    {

        Thread currentThread = Thread.currentThread();

        try

        {

            // This ends when animationThread is set to null, or when

            // it is subsequently set to a new thread; either way, the

            // current thread should terminate

            while (currentThread == animationThread)

            {

                long startTime = System.currentTimeMillis();

                // Don't advance game or draw if canvas is covered by

                // a system screen.

                if (isShown())

                {

                    tick();

                    draw();

                    flushGraphics();

                }

                long timeTaken = System.currentTimeMillis() - startTime;

                if (timeTaken < MILLIS_PER_TICK)

                {

                    synchronized (this)

                    {

                        wait(MILLIS_PER_TICK - timeTaken);

                    }

                }

                else

                {

                    currentThread.yield();

                }

            }

        }

        catch (InterruptedException e)

        {

            // won't be thrown

        }

}

10.创建用于监视多按键同时按下的情况,用到了getKeyStates方法来获得当前按键情况

private void tick()

    {

        // If player presses two or more direction buttons, we ignore them

        // all. But pressing fire is independent. The code below also ignores

        // direction buttons if GAME_A..GAME_D are pressed.

        int keyStates = getKeyStates();

        boolean bark = (keyStates & FIRE_PRESSED) != 0;

        keyStates &= ~FIRE_PRESSED;

        int direction = (keyStates == UP_PRESSED) ? UP :

                        (keyStates == LEFT_PRESSED) ? LEFT:

                        (keyStates == DOWN_PRESSED) ? DOWN :

                        (keyStates == RIGHT_PRESSED) ? RIGHT : NONE;

        sheepdog.tick(direction, bark);

        for (int i = 0; i < sheep.size(); ++i)

        {

            Sheep sh = (Sheep)(sheep.elementAt(i));

            sh.tick();

        }

        field.tick();

    }

11.创建多个方法用于提取对象和控制犬吠

Field getField()

    {

        return field;

    }

    Sheepdog getSheepdog()

    {

        return sheepdog;

    }

 

    Vector getSheep()

    {

        return sheep;

    }

 

    void handleDogBark()

    {

        for (int i = 0; i < sheep.size(); ++i)

        {

            Sheep sh = (Sheep)(sheep.elementAt(i));

            sh.handleDogBark();

        }

}

12.创建精灵的碰撞控制方法,一个精灵是一个基本的视觉对象,它储存在一个图像中,并能变化;不同的帧能够显示精灵的运动,一些变换,如旋转,缩放也能应用到精灵上,用于进一步改变他们的显示。collidesWith方法用于检测精灵碰撞。

boolean overlapsSheepdog(Sprite sprite)

    {

        return sprite.collidesWith(sheepdog, false); // false -> not pixelLevel

    }

 

    boolean overlapsSheep(Sprite sprite)

    {

        return overlapsSheep(sprite, sheep.size());

    }

 

    // whether the sprite overlaps the first  'count' sheep

    boolean overlapsSheep(Sprite sprite, int count)

    {

        for (int i = 0; i < count; ++i)

        {

            Sheep sh = (Sheep)(sheep.elementAt(i));

            if (sprite.collidesWith(sh, false))  // false -> not pixelLevel

            {

                return true;

            }

        }

        return false;

    }

 

   

    boolean overlapsOtherSheep(Sprite sprite)

    {

        for (int i = 0; i < sheep.size(); ++i)

        {

            Object obj = sheep.elementAt(i);

            if (obj != sprite)

            {

                Sheep sh = (Sheep)obj;

                if (sprite.collidesWith(sh, false))  // false -> not pixelLevel

                {

                    return true;

                }

            }

        }

        return false;

    }

 

    void vibrate(int millis)

    {

        midlet.vibrate(millis);

}

13.创建方法用于画出游戏中可视的对象。getX方法获取x值,getY获取y之。

// draw game

    private void draw()

    {

        int width = getWidth();

        int height = getHeight();

 

        // clear screen to grey

        graphics.setColor(0x00888888);

        graphics.fillRect(0, 0, width, height);

 

        // clip and translate to centre

        int dx = origin(sheepdog.getX() + sheepdog.getWidth() / 2,

                        field.getWidth(),

                        width);

        int dy = origin(sheepdog.getY() + sheepdog.getHeight() / 2,

                        field.getHeight(),

                        height);

        graphics.setClip(dx, dy, field.getWidth(), field.getHeight());

        graphics.translate(dx, dy);

 

        The paint method paints this Layer if it is visible.

 

For more information, see paint in the MIDP 2.0 API specification.

 

        // draw background and sprites

        layerManager.paint(g, 0, 0);

 

        // undo clip & translate

        graphics.translate(-dx, -dy);

        graphics.setClip(0, 0, width, height);

 

        // display time & score

        long time = (System.currentTimeMillis() - startTime) / 1000;

        int score = numSheepInFold();

        graphics.setColor(0x00FFFFFF); // white

        graphics.drawString(Integer.toString(score),

                            1,

                            1,

                            Graphics.TOP | Graphics.LEFT);

        graphics.drawString(Long.toString(time),

                            width - 2,

                            1,

                            Graphics.TOP | Graphics.RIGHT);

 

        if (score == sheep.size())

        {

            midlet.sheepdogCanvasGameOver(time);

        }

    }

14.创建用于计算场景大小的方法

 

    // If the screen is bigger than the field, we center the field

    // in the screen. Otherwise we center the screen on the focus, except

    // that we don't scroll beyond the edges of the field.

    private int origin(int focus, int fieldLength, int screenLength)

    {

        int origin;

        if (screenLength >= fieldLength)

        {

            origin = (screenLength - fieldLength) / 2;

        }

        else if (focus <= screenLength / 2)

        {

            origin = 0;

        }

        else if (focus >= (fieldLength - screenLength / 2))

        {

            origin = screenLength - fieldLength;

        }

        else

        {

            origin = screenLength / 2 - focus;

        }

        return origin;

    }

15.创建用于计算羊的数目的方法

int numSheepInFold()

    {

        int count = 0;

        for (int i = 0; i < sheep.size(); ++i)

        {

            Sheep sh = (Sheep)(sheep.elementAt(i));

            if (field.inFold(sh))

            {

                count++;

            }

        }

        return count;

    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值