使用GameCanvas制作星空效果

本文介绍如何使用MIDP2.0中的GameCanvas实现一个简单的滚动星空效果。通过调整上下按键可以改变星空滚动的速度。
http://www.3geye.net/bbs/thread-164-1-1.html

MIDP2.0中提供了游戏开发专用的API,比如GameCanvas等类。他们位于javax.microedition.lcdui.game包内。本文介绍GameCanvas的基本使用方法并实现一种滚动星空的效果。您可以参考Game Canvas Basic获得更详细的信息。

    GameCanvas是Canvas的子类,因此他同样继承了Canvas类的一些特性,比如showNotify()方法会在Canvas被显示在屏幕 的时候调用,而hideNotify()会在Canvas离开屏幕的时候被调用。我们可以把他们当作{8}来使用,用于初始化和销毁资源。比如
    // When the canvas is shown, start a thread to
    // run the game loop.

    protected void showNotify()
    {
        random = new Random();
        thread = new Thread(this);
        thread.start();
    }
    // When the game canvas is hidden, stop the thread.

    protected void hideNotify()
    {
        thread = null;
    }

在游戏开发中最重要的就是接受用户触发的事件然后重新绘制屏幕,通常我们使用getKeyStates()方法判断哪个键被按下了,然后绘制屏幕, 调用flushGraphics()。在GameCanvas中,系统事实上已经为我们实现了双缓冲技术,因此每次我们绘制的时候就是在off- screen上绘制的。结束后通过flushGraphics把它复制到屏幕上去。下面是典型的接受事件、处理逻辑、绘制屏幕的代码。
 // Get the Graphics object for the off-screen buffer
Graphics g = getGraphics();

while (true) {
      // Check user input and update positions if necessary
      int keyState = getKeyStates();
      if ((keyState & LEFT_PRESSED) != 0) {
          sprite.move(-1, 0);
      }
      else if ((keyState & RIGHT_PRESSED) != 0) {
          sprite.move(1, 0);
      }

// Clear the background to white
g.setColor(0xFFFFFF);
g.fillRect(0,0,getWidth(), getHeight());

      // Draw the Sprite
      sprite.paint(g);

      // Flush the off-screen buffer
      flushGraphics();
}

    下面开始实现我们滚动星空的效果,其实设计的思想非常简单。我们启动一个线程,使用copyArea()方法把屏幕的内容往下复制一个像素的距离。然后绘画第一个空白的直线,随机的在直线上绘画点儿,这样看起来就像星空一样了。逻辑代码如下:
    // The game loop.

    public void run()
    {
        int w = getWidth();
        int h = getHeight() - 1;
        while (thread == Thread.currentThread())
        {
            // Increment or decrement the scrolling interval
            // based on key presses
            int state = getKeyStates();

            if ((state & DOWN_PRESSED) != 0)
            {
                sleepTime += SLEEP_INCREMENT;
                if (sleepTime > SLEEP_MAX)
                    sleepTime = SLEEP_MAX;
            } else if ((state & UP_PRESSED) != 0)
            {
                sleepTime -= SLEEP_INCREMENT;
                if (sleepTime < 0)
                    sleepTime = 0;
            }

            // Repaint the screen by first scrolling the
            // existing starfield down one and painting in
            // new stars...

            graphics.copyArea(0, 0, w, h, 0, 1, Graphics.TOP | Graphics.LEFT);
            graphics.setColor(0, 0, 0);
            graphics.drawLine(0, 0, w, 0);
            graphics.setColor(255, 255, 255);
            for (int i = 0; i < w; ++i)
            {
                int test = Math.abs(random.nextInt()) % 100;
                if (test < 5)
                {
                    graphics.drawLine(i, 0, i, 0);
                }
            }
            flushGraphics();

            // Now wait...

            try
            {
                Thread.currentThread().sleep(sleepTime);
            } catch (InterruptedException e)
            {
            }
        }
    }

下面给出源代码
/*
 * License
 *
 * Copyright 1994-2004 Sun Microsystems, Inc. All Rights Reserved.
 *
 */

import javax.microedition.lcdui.*;
import javax.microedition.lcdui.game.*;
import javax.microedition.midlet.*;

public class GameCanvasTest extends MIDlet implements CommandListener
{

    private Display display;

    public static final Command exitCommand = new Command("Exit", Command.EXIT,
            1);

    public GameCanvasTest()
    {
    }

    public void commandAction(Command c, Displayable d)
    {
        if (c == exitCommand)
        {
            exitMIDlet();
        }
    }

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

    public void exitMIDlet()
    {
        notifyDestroyed();
    }

    public Display getDisplay()
    {
        return display;
    }

    protected void initMIDlet()
    {
        GameCanvas c = new StarField();
        c.addCommand(exitCommand);
        c.setCommandListener(this);

        getDisplay().setCurrent(c);
    }

    protected void pauseApp()
    {
    }

    protected void startApp() throws MIDletStateChangeException
    {
        if (display == null)
        {
            display = Display.getDisplay(this);
            initMIDlet();
        }
    }
}
/*
 * License
 *
 * Copyright 1994-2004 Sun Microsystems, Inc. All Rights Reserved.
 */

import java.util.Random;
import javax.microedition.lcdui.*;
import javax.microedition.lcdui.game.GameCanvas;

// A simple example of a game canvas that displays
// a scrolling star field. Use the UP and DOWN keys
// to speed up or slow down the rate of scrolling.

public class StarField extends GameCanvas implements Runnable
{

    private static final int SLEEP_INCREMENT = 10;

    private static final int SLEEP_INITIAL = 150;

    private static final int SLEEP_MAX = 300;

    private Graphics graphics;

    private Random random;

    private int sleepTime = SLEEP_INITIAL;

    private volatile Thread thread;

    public StarField()
    {
        super(true);

        graphics = getGraphics();
        graphics.setColor(0, 0, 0);
        graphics.fillRect(0, 0, getWidth(), getHeight());
    }

    // The game loop.

    public void run()
    {
        int w = getWidth();
        int h = getHeight() - 1;
        while (thread == Thread.currentThread())
        {
            // Increment or decrement the scrolling interval
            // based on key presses
            int state = getKeyStates();

            if ((state & DOWN_PRESSED) != 0)
            {
                sleepTime += SLEEP_INCREMENT;
                if (sleepTime > SLEEP_MAX)
                    sleepTime = SLEEP_MAX;
            } else if ((state & UP_PRESSED) != 0)
            {
                sleepTime -= SLEEP_INCREMENT;
                if (sleepTime < 0)
                    sleepTime = 0;
            }

            // Repaint the screen by first scrolling the
            // existing starfield down one and painting in
            // new stars...

            graphics.copyArea(0, 0, w, h, 0, 1, Graphics.TOP | Graphics.LEFT);
            graphics.setColor(0, 0, 0);
            graphics.drawLine(0, 0, w, 0);
            graphics.setColor(255, 255, 255);
            for (int i = 0; i < w; ++i)
            {
                int test = Math.abs(random.nextInt()) % 100;
                if (test < 5)
                {
                    graphics.drawLine(i, 0, i, 0);
                }
            }
            flushGraphics();

            // Now wait...

            try
            {
                Thread.sleep(sleepTime);
            } catch (InterruptedException e)
            {
            }
        }
    }

    // When the canvas is shown, start a thread to
    // run the game loop.

    protected void showNotify()
    {
        random = new Random();
        thread = new Thread(this);
        thread.start();
    }
    // When the game canvas is hidden, stop the thread.

    protected void hideNotify()
    {
        thread = null;
    }
}

制作一个简单的HTML5小游戏通常涉及HTML、CSS和JavaScript的结合使用。以下是一个基本的步骤指南,帮助你创建一个简单的互动游戏。 ### 游戏概念设计 首先,你需要确定游戏的规则和玩法。例如,你可以创建一个点击气球的游戏,玩家点击屏幕上不断移动的气球来得分。这种类型的游戏适合初学者,因为它涵盖了基本的用户交互和动画。 ### 创建HTML结构 在HTML文件中定义游戏的基本结构。例如: ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>点击气球游戏</title> <style> #gameCanvas { border: 1px solid black; background-color: #f0f0f0; } </style> </head> <body> <canvas id="gameCanvas" width="600" height="400"></canvas> <script src="game.js"></script> </body> </html> ``` ### 使用JavaScript实现游戏逻辑 接下来,在`game.js`文件中编写JavaScript代码来实现游戏逻辑。这包括绘制气球、处理点击事件以及更新分数。 ```javascript const canvas = document.getElementById('gameCanvas'); const ctx = canvas.getContext('2d'); let score = 0; let balloons = []; function createBalloon() { let x = Math.random() * (canvas.width - 50); let y = Math.random() * (canvas.height - 50); balloons.push({x: x, y: y, radius: 25}); } function drawBalloons() { ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.font = "20px Arial"; ctx.fillText("Score: " + score, 10, 30); balloons.forEach((balloon, index) => { ctx.beginPath(); ctx.arc(balloon.x, balloon.y, balloon.radius, 0, Math.PI*2); ctx.fillStyle = "#FF6347"; ctx.fill(); ctx.stroke(); }); } function updateGame() { drawBalloons(); requestAnimationFrame(updateGame); } canvas.addEventListener('click', function(event) { const rect = canvas.getBoundingClientRect(); const mouseX = event.clientX - rect.left; const mouseY = event.clientY - rect.top; balloons.forEach((balloon, index) => { let dx = mouseX - balloon.x; let dy = mouseY - balloon.y; let distance = Math.sqrt(dx*dx + dy*dy); if (distance < balloon.radius) { balloons.splice(index, 1); score += 10; } }); }); setInterval(createBalloon, 1000); // 每秒生成一个新的气球 updateGame(); // 开始游戏循环 ``` ### 测试与调试 确保在不同的设备和浏览器上测试游戏,以验证其兼容性和响应性。调试任何出现的问题,如气球不出现或点击事件不触发等。 ### 扩展功能 一旦基础游戏运行良好,你可以考虑增加更多功能,比如: - 不同颜色或大小的气球 - 游戏结束条件(例如,气球累积到一定数量) - 音效和背景音乐 - 分数排行榜 通过以上步骤,你可以创建一个简单的HTML5小游戏[^1]。这个基础可以作为进一步探索游戏开发的起点。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值