您的位置:首页 > 移动开发 > Android开发

零打碎敲学Android(二)—做个拼图游戏吧

2009-10-18 14:54 225 查看
Android千好万好,唯独模拟器不是太好,在不更换旧有硬件的前提下,使用Android模拟器通常会遭遇效率问题,况且在logcat下面调试,也始终不如开发桌面游戏时那么直观。有没有什么办法,能够解决这一问题呢?



其实很容易做到。



Android首先是一个精简的Linux平台,其次才是一个手机系统,Java在PC上可以做到的事情,Android不但可以做到,而且能以近乎一致的手段做到。事实上,如果有人故意通过封装抹杀Android与PC上Java应用差异性的话,任何Java游戏,都可以在很少更改代码(或者完全不更改代码)的情况下移植到Android之上。



比如,笔者下面提供的这个拼图游戏示例,就可以在几乎不改变程序结构(部分相关类需要替换,不过可以利用正则自动完成)的前提下,运行在Android上。



PC版源码(框架为LGame-Simple-0.2.0):



package org.loon.game.simple.test;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import org.loon.framework.game.simple.GameScene;
import org.loon.framework.game.simple.core.Deploy;
import org.loon.framework.game.simple.core.Screen;
import org.loon.framework.game.simple.utils.GraphicsUtils;
/**
 * 
 * Copyright 2008 
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0  *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 *
 * @project loonframework
 * @author chenpeng  
 * @email:ceponline@yahoo.com.cn 
 * @version 0.1
 */
public class ScreenTest1 extends Screen {
	private Image imageBack, tmp_imageBack, imageForward;
	private Graphics tmp_graphics;
	private int blocks[];
	private boolean isEvent;
	private int count, rs, cs, row, col, width, height;
	public ScreenTest1(String file1, String file2, int row, int col) {
		this.col = col;
		this.row = row;
		this.imageBack = GraphicsUtils.loadImage(file1);
		this.width = imageBack.getWidth(null);
		this.height = imageBack.getHeight(null);
		this.rs = width / row;
		this.cs = height / col;
		this.tmp_imageBack = GraphicsUtils
				.createImage(width, height + cs, true);
		this.tmp_graphics = tmp_imageBack.getGraphics();
		this.count = col * row;
		this.blocks = new int[count];
		this.imageForward = GraphicsUtils.loadImage(file2);
		for (int i = 0; i < count; i++) {
			blocks[i] = i;
		}
		rndBlocks();
	}
	/**
	 * 复制拼图中图片块
	 * 
	 * @param x1
	 * @param y1
	 * @param x2
	 * @param y2
	 */
	private void copy(int x1, int y1, int x2, int y2) {
		tmp_graphics.copyArea(x1 * rs, y1 * cs, rs, cs, (x2 - x1) * rs,
				(y2 - y1) * cs);
	}
	/**
	 * 随机生成拼图内容
	 * 
	 */
	private void rndBlocks() {
		tmp_graphics.drawImage(imageBack, 0, 0, null);
		for (int i = 0; i < (count * row); i++) {
			int x1 = (int) ((double) row * Math.random());
			int y1 = (int) ((double) col * Math.random());
			int x2 = (int) ((double) row * Math.random());
			int y2 = (int) ((double) col * Math.random());
			copy(x1, y1, 0, col);
			copy(x2, y2, x1, y1);
			copy(0, col, x2, y2);
			int j1 = blocks[y1 * row + x1];
			blocks[y1 * row + x1] = blocks[y2 * row + x2];
			blocks[y2 * row + x2] = j1;
		}
	}
	/**
	 * 点击鼠标
	 */
	public void leftClick(MouseEvent e) {
		if (isEvent) {
			return;
		}
		int x = e.getX() / rs;
		int y = e.getY() / cs;
		copy(0, 0, 0, col);
		copy(x, y, 0, 0);
		copy(0, col, x, y);
		int no = blocks[0];
		blocks[0] = blocks[y * row + x];
		blocks[y * row + x] = no;
		int index;
		for (index = 0; index < count; index++) {
			if (blocks[index] != index) {
				break;
			}
		}
		if (index == count) {
			isEvent = true;
		}
		return;
	}
	public void draw(Graphics2D g) {
		if (!isEvent) {
			g.drawImage(tmp_imageBack, 0, 0, null);
			for (int i = 0; i < row; i++) {
				for (int j = 0; j < col; j++)
					g.drawRect(i * rs, j * cs, rs, cs);
			}
		}
		if (isEvent && imageForward != null) {
			g.drawImage(imageBack, 0, 0, null);
			g.drawImage(imageForward, 0, 0, null);
			tmp_graphics.dispose();
		}
	}
	public boolean isEvent() {
		return isEvent;
	}
	public void setEvent(boolean isEvent) {
		this.isEvent = isEvent;
	}
	public void middleClick(MouseEvent e) {
	}
	public void onKey(KeyEvent e) {
	}
	public void onKeyUp(KeyEvent e) {
	}
	public void rightClick(MouseEvent e) {
	}
	public static void main(String[] args) {
		GameScene frame = new GameScene("拼图", 320, 480);
		Deploy deploy = frame.getDeploy();
		deploy.setScreen(new ScreenTest1("images/backimage1.jpg",
				"images/over.png", 4, 4));
		deploy.setShowFPS(true);
		deploy.setLogo(false);
		deploy.setFPS(100);
		deploy.mainLoop();
		frame.showFrame();
	}
}












Android版源码(框架为LAGame-Simple-prototype):



示例源码下载地址:http://code.google.com/p/loon-simple/downloads/list



package org.loon.framework.android.game;
import android.view.KeyEvent;
import android.view.MotionEvent;
/**
 * 
 * Copyright 2008 - 2009
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0  * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 * 
 * @project loonframework
 * @author chenpeng
 * @email <a title="" href="http://hi.baidu.com/ceponline" mce_href="http://hi.baidu.com/ceponline" target="_blank">ceponline</a>@yahoo.com.cn
 * @version 0.1.0
 */
public class ScreenTest1 extends LAScreen {
	private LAImage imageBack, tmp_imageBack, imageForward;
	private LAGraphics tmp_graphics;
	private int blocks[];
	private boolean isEvent;
	private int count, rs, cs, row, col, width, height;
	public ScreenTest1(String file1, String file2, int row, int col) {
		this.col = col;
		this.row = row;
		this.imageBack = getLAImage(file1);
		this.width = imageBack.getWidth();
		this.height = imageBack.getHeight();
		this.rs = width / row;
		this.cs = height / col;
		this.tmp_imageBack = new LAImage(width, height + cs);
		this.tmp_graphics = tmp_imageBack.getLAGraphics();
		this.count = col * row;
		this.blocks = new int[count];
		this.imageForward = getLAImage(file2);
		for (int i = 0; i < count; i++) {
			blocks[i] = i;
		}
		rndBlocks();
	}
	/**
	 * 复制拼图中图片块
	 * 
	 * @param x1
	 * @param y1
	 * @param x2
	 * @param y2
	 */
	private void copy(int x1, int y1, int x2, int y2) {
		tmp_graphics.copyArea(x1 * rs, y1 * cs, rs, cs, (x2 - x1) * rs,
				(y2 - y1) * cs);
	}
	/**
	 * 随机生成拼图内容
	 * 
	 */
	private void rndBlocks() {
		tmp_graphics.drawImage(imageBack, 0, 0);
		for (int i = 0; i < (count * row); i++) {
			int x1 = (int) ((double) row * Math.random());
			int y1 = (int) ((double) col * Math.random());
			int x2 = (int) ((double) row * Math.random());
			int y2 = (int) ((double) col * Math.random());
			copy(x1, y1, 0, col);
			copy(x2, y2, x1, y1);
			copy(0, col, x2, y2);
			int j1 = blocks[y1 * row + x1];
			blocks[y1 * row + x1] = blocks[y2 * row + x2];
			blocks[y2 * row + x2] = j1;
		}
	}
	/**
	 * 点击触摸屏
	 */
	public boolean onTouchDown(MotionEvent e) {
		if (isEvent) {
			return isEvent;
		}
		int x = (int) (e.getX() / rs);
		int y = (int) (e.getY() / cs);
		copy(0, 0, 0, col);
		copy(x, y, 0, 0);
		copy(0, col, x, y);
		int no = blocks[0];
		blocks[0] = blocks[y * row + x];
		blocks[y * row + x] = no;
		int index;
		for (index = 0; index < count; index++) {
			if (blocks[index] != index) {
				break;
			}
		}
		if (index == count) {
			isEvent = true;
		}
		return isEvent;
	}
	/**
	 * 绘制拼图
	 */
	public void draw(LAGraphics g) {
		if (!isEvent) {
			g.drawImage(tmp_imageBack, 0, 0);
			for (int i = 0; i < row; i++) {
				for (int j = 0; j < col; j++)
					g.drawRect(i * rs, j * cs, rs, cs);
			}
		}
		if (isEvent && imageForward != null) {
			g.drawImage(imageBack, 0, 0);
			g.drawImage(imageForward, 0, 0);
			tmp_graphics.dispose();
		}
	}
	public boolean isEvent() {
		return isEvent;
	}
	public void setEvent(boolean isEvent) {
		this.isEvent = isEvent;
	}
	public boolean onKeyDown(int keyCode, KeyEvent e) {
		return false;
	}
	public boolean onKeyUp(int keyCode, KeyEvent e) {
		return false;
	}
	public boolean onTouchMove(MotionEvent e) {
		return false;
	}
	public boolean onTouchUp(MotionEvent e) {
		return false;
	}
}




package org.loon.framework.android.game;
import android.app.Activity;
import android.os.Bundle;
/**
 * 
 * Copyright 2008 - 2009
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0  * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 * 
 * @project loonframework
 * @author chenpeng
 * @email <a title="" href="http://hi.baidu.com/ceponline" mce_href="http://hi.baidu.com/ceponline" target="_blank">ceponline</a>@yahoo.com.cn
 * @version 0.1.0
 */
public class Main extends Activity {
	private LAGameView view;
	public void onCreate(Bundle icicle) {
		super.onCreate(icicle);
		view = new LAGameView(this);
		view.setScreen(new ScreenTest1("backimage1.jpg",
				"over.png", 4, 4));
		view.setShowFPS(true);
		view.mainLoop();
	}
	protected void onPause() {
		if (view != null) {
			view.setRunning(false);
		}
		super.onPause();
	}
	protected void onStop() {
		if (view != null) {
			view.setRunning(false);
		}
		super.onStop();
	}
}












示例源码下载地址:http://code.google.com/p/loon-simple/downloads/list



Android游戏与Java桌面游戏在本质上不存在任何区别,逻辑实现更可以完全一致。通过示例我们看到,把一个以LGame-Simple框架开发的Java桌面游戏移植到Android上居然是如此简单。



事实上,未来的Android版LGame-Simple,函数实现将与PC版保持一致,对于差异性代码,笔者也将提供相互转换的辅助工具。



如果您正在以LGame-Simple开发Java游戏,那么恭喜您,至多到今年12月底,它也将可以同时运行在Android上了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: