Wireless Tools Kit + J2ME 返朴归真(二)自己做游戏音乐!

今天折腾了一下把音乐的元素加到那个UFO游戏里面去了,目前来说这也算是个完整的游戏了。

它具备开始画面和开场音乐,有生命次数的游戏过程和背景音乐,有记分机制,有结束画面和结束音乐,最后还有一个MIDlet图标。

先把代码贴出来:

// UFOCanvas.java

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

public class UFOCanvas extends GameCanvas implements Runnable {
  private Display  display;
  private boolean  sleeping, restart;
  private long     frameDelay;
  private Random   rand;
  private Sprite   ufoSprite;
  private Sprite   gameoverImg, coverImg;
  private int      ufoXSpeed, ufoYSpeed;
  private int      ox = 0, oy = 0;
  private int      gx = -getWidth(), gy = -getHeight();
  private int      cx, cy, sx, sy;
  private int      score;
  private int      ufoLife = 3;
  private Sprite[] roidSprite = new Sprite[3];
  private Sprite[] ufolifeSprite = new Sprite[3];
  private Player   startmusic;
  private Player   gameovermusic;
  private Player   backmusic;

  public UFOCanvas(Display d) {
    super(true);
    display = d;
    frameDelay = 33;
  }
 
  public void start() {
    display.setCurrent(this);
    rand = new Random();
    ufoXSpeed = ufoYSpeed = 0;
    restart = true;
    score = 0;
    try {

      //初始化UFO、游戏结束画面、封面画面、玩法介绍画面、关于我们画面的精灵和位置
      ufoSprite = new Sprite(Image.createImage("/Saucer.png"));
      ufoSprite.setPosition((getWidth() - ufoSprite.getWidth()) / 2,
        (getHeight() - ufoSprite.getHeight()) / 2);
      gameoverImg = new Sprite(Image.createImage("/gameover.png"));
      gameoverImg.setPosition(-getWidth(),-getHeight());
      coverImg = new Sprite(Image.createImage("/cover.png"));
      coverImg.setPosition(0,0);

      //初始化小行星精灵和位置和动画侦范围
      Image img = Image.createImage("/Roid.png");
      roidSprite[0] = new Sprite(img, 42, 35);
      roidSprite[1] = new Sprite(img, 42, 35);
      roidSprite[2] = new Sprite(img, 42, 35);
     
      //初始化UFO生命图示精灵和位置
      Image img2 = Image.createImage("/UFO.png");
      ufolifeSprite[0] = new Sprite(img2,12,12);
      ufolifeSprite[0].setPosition(2,270);
      ufolifeSprite[1] = new Sprite(img2,12,12);
      ufolifeSprite[1].setPosition(14,270);
      ufolifeSprite[2] = new Sprite(img2,12,12);
      ufolifeSprite[2].setPosition(26,270);

      //初始化开始、结束和背景音乐对象
      InputStream is = getClass().getResourceAsStream("startmusic.mid");
      startmusic = Manager.createPlayer(is, "audio/midi");
      startmusic.prefetch();
      is = getClass().getResourceAsStream("gameovermusic.mid");
      gameovermusic = Manager.createPlayer(is, "audio/midi");
      gameovermusic.prefetch();
      is = getClass().getResourceAsStream("backmusic.mid");
      backmusic = Manager.createPlayer(is, "audio/midi");
      backmusic.prefetch();

      //当start方法被调用时就播放开始音乐
      startmusic.start();

    }catch (IOException e) {}
     catch (MediaException me) {}

    //开始线程
    sleeping = false;
    Thread t = new Thread(this);
    t.start();
  }
 
  public void stop() {
    sx = getWidth() /2;
    sy = getHeight() /2;
    sleeping = true;
    startmusic.close();
    backmusic.close();
    //gameovermusic.close();
  }

  public void run() {
    Graphics g = getGraphics();
   
    //游戏主循环
    while (!sleeping) {     
      update();
      draw(g);
      try {
        Thread.sleep(frameDelay);
      }catch (InterruptedException ie) {}
    } //while
  } //run
 
  private void update() {

    //用restart来判断是否显示主画面还是进入游戏
    if(restart) {
      int keyState = getKeyStates();
      if((keyState & FIRE_PRESSED)!= 0) {

        //如果START被按下则停止开始音乐并播放背景音乐
        try {
          backmusic.setLoopCount(-1);
          backmusic.setMediaTime(0);
          startmusic.stop();
          backmusic.start();
        } catch (MediaException me) {}

        coverImg.setPosition(-getWidth(),-getHeight());
        restart = false;
        score = 0;
      }
      else coverImg.setPosition(0,0);
      return;
    }

    //通过按上下左右键来改变精灵速度
    int keyState = getKeyStates();
    if ((keyState & LEFT_PRESSED) != 0)
      ufoXSpeed--;
    else if ((keyState & RIGHT_PRESSED) != 0)
      ufoXSpeed++;
    if ((keyState & UP_PRESSED) != 0)
      ufoYSpeed--;
    else if ((keyState & DOWN_PRESSED) != 0)
      ufoYSpeed++;
   
    //UFO速度在8和-8之间随机取得
    ufoXSpeed = Math.min(Math.max(ufoXSpeed, -8), 8);
    ufoYSpeed = Math.min(Math.max(ufoYSpeed, -8), 8);

    ufoSprite.move(ufoXSpeed, ufoYSpeed);
    checkBounds(ufoSprite);

    for (int i = 0; i < 3; i++) {
      roidSprite[i].move(i + 1, 1 - i);//使三个小行星向不同的方向运动
      checkBounds(roidSprite[i]);//折屏算法

      //第二个小行星精灵roidSprite[1]是反向侦动画,否则是正向侦动画
      if (i == 1) roidSprite[i].prevFrame();
        else      roidSprite[i].nextFrame();

      // 检测碰撞
      if (ufoSprite.collidesWith(roidSprite[i], true)) {
       
        // 播放警告声音
        AlertType.ERROR.playSound(display);

        // 碰撞之后重置UFO精灵和移动速度;
        ufoSprite.setPosition((getWidth() - ufoSprite.getWidth()) / 2,
          (getHeight() - ufoSprite.getHeight()) / 2);
        ufoXSpeed = ufoYSpeed = 0;
       
        //重置小行星位置
        for (int j = 0; j < 3; j++)
          roidSprite[j].setPosition(0, 0);

        //检测UFO生命减少是否到可以停止游戏
        if ( ufoLife > 0 ) {
          ufoLife--;
          ufolifeSprite[ufoLife].setPosition(-12,-12);
        }
         else {
          gameoverImg.setPosition(0,0);
          for (int j = 0; j < 3; j++)
            roidSprite[j].setPosition(-43, -35);  //将小行星置于屏幕外

          //播放游戏结束声音
          try {
            gameovermusic.start();
          } catch(MediaException me){}

          stop();
         } //else

        // 此时不用更新小行星精灵
        break;
      }

      //检测得分
      for(int l = 0; l < 3; l++) {
        if (Math.abs(ufoSprite.getX() - roidSprite[l].getX()) < 22 &&
            Math.abs(ufoSprite.getY() - roidSprite[l].getY()) < 22) {
          AlertType.WARNING.playSound(display);
          gx = getWidth()/2;
          gy = getHeight()/2;
          score += 5;
        }
      }
    }
  }
 
  private void draw(Graphics g) {
    g.setColor(0x000000);   
    g.fillRect(0, 0, getWidth(), getHeight());
    g.setColor(255, 255, 255); // white
    g.drawString("You 've touched :"+score,sx, sy, Graphics.TOP | Graphics.LEFT);
    g.drawString("Good!", gx, gy, Graphics.TOP | Graphics.HCENTER);
    ufoSprite.paint(g);
    gameoverImg.paint(g);   

    for (int i = 0; i < 3; i++)
      roidSprite[i].paint(g);
    for (int k = 0; k < 3; k++)
      ufolifeSprite[k].paint(g);

    coverImg.paint(g);
    flushGraphics();
  }

  //折屏算法
  private void checkBounds(Sprite sprite) {
    if (sprite.getX() < -sprite.getWidth())
      sprite.setPosition(getWidth(), sprite.getY());
    else if (sprite.getX() > getWidth())
      sprite.setPosition(-sprite.getWidth(), sprite.getY());
    if (sprite.getY() < -sprite.getHeight())
      sprite.setPosition(sprite.getX(), getHeight());
    else if (sprite.getY() > getHeight())
      sprite.setPosition(sprite.getX(), -sprite.getHeight());
  }
}

================================================

UFOMIDlet.java文件和之前贴的没有区别,就不贴了。

目前游戏还有一个BUG,就是当UFO精灵和小行星精灵产生“绝妙”的时候会停在绝对距离小于22的那个位置重复运行。这个事情就属于代码活性不强,严格点儿说代码几乎可以说是错的。——虽然由于FrameDelay=33可以投机的避免碰撞之前的瞬间先处理得分机制,不过有时这种碰撞的滞后感还是非常令人恼火的!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值