近来学习android,看到一款flash游戏,挺不错,游戏比较简单.想山寨一下.呵呵.
链接是: http://f.game.china.com/html/2010-07-13/146128.htm
一个空中射击类游戏.
游戏介绍:
游戏需要你控制UFO飞碟粘住小行星“子弹”,然后把他们发射出去,撞击其他的行星就可以了。大行星被撞击以后会分裂成小行星。你的小行星子弹也会越来越多。所以抓紧粘抓紧射击。注意!后面的关卡里会有其他敌对飞碟,也一样要干掉。
游戏玩法:
方向键上下左右移动,中间键弹出子弹.
游戏框架设计:
主角,敌对星球,子弹,脚本继承同一个父类,提供和实现一些共有信息.
有个圆的工具类,用来记录圆的坐标和半径,可以检测两个圆是否碰撞(这是这个游戏的碰撞检测).
工程结构如下:
基类的代码为:
package com.st;
import android.graphics.Bitmap;
import android.graphics.Canvas;
public abstract class SObject {
protected int speedX;
protected int speedY;
protected Bitmap img;
protected Round round;
protected int curState;
public SObject(int x, int y,int speedX,int speedY,Bitmap img) {
super();
this.speedX = speedX;
this.speedY = speedY;
this.img = img;
round = new Round(x,y,img.getHeight()/2);
}
/*
* 检测两个对象是否相碰撞
*/
protected boolean collide(SObject obj){
return this.round.collide(obj.round);
}
protected abstract void paint(Canvas myCanvas);
protected abstract void update();
}
Hero主角类代码:
package com.st;
import java.util.ArrayList;
import java.util.List;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
public class Hero extends SObject {
public static final int NORMAL = 0;//一般状态
public static final int HURT = 1;//受伤状态
public static final int SHOOT = 2;//射击状态
List<Bullet> bullets;//主角的子弹列表
public Hero(int x, int y, Bitmap img) {
super(x, y, 0, 0,img);
bullets = new ArrayList<Bullet>();
}
@Override
public void update() {
checkCollide();
checkKey();
switch(curState){
case NORMAL:
break;
case HURT:
break;
case SHOOT:
break;
}
}
private void checkKey() {
for(int i=0;i<STView.keyContral.length;i++){
if(STView.keyContral[i]){
switch(i){
case 0:
round.x -= 5;
break;
case 1:
round.x += 5;
break;
case 2:
round.y -= 5;
break;
case 3:
round.y += 5;
break;
case 4:
curState = SHOOT;
shoot();
break;
}
}
}
}
private void shoot() {
for(int i=0;i<bullets.size();i++){
Bullet bullet = bullets.get(i);
double dis = Math.sqrt(bullet.offsetX*bullet.offsetX+bullet.offsetY*bullet.offsetY);
double v = 20;
double vx = bullet.offsetX*v/dis;
double vy = bullet.offsetY*v/dis;
bullet.speedX = (int)vx;
bullet.speedY = (int)vy;
bullet.curState = Bullet.NORMAL;
bullet.bulletType = Bullet.HEROBULLET;
bullets.remove(i);
}
}
private void checkCollide() {
for(int i=0;i<STView.objs.size();i++){
SObject obj = STView.objs.get(i);
//
if(obj instanceof Enemy ){
if(this.collide(obj)){
curState = HURT;
}
}
//
if(obj instanceof Bullet ){
if(((Bullet) obj).bulletType != Bullet.ENEMYBULLET && obj.curState == Bullet.NORMAL && this.collide(obj)){
bullets.add((Bullet)obj);
obj.curState = Bullet.STICK;
((Bullet)obj).offsetHero(obj.round.x - this.round.x,obj.round.y - this.round.y);
}
}
}
}
private int curFrame;
@Override
protected void paint(Canvas myCanvas) {
curFrame++;
if(curFrame > 500){
curFrame = 0;
}
if(curState == HURT){
if(curFrame % 2 == 0){
return;
}
if(curFrame > 10){
curState = NORMAL;
}
}
Paint paint = new Paint();
myCanvas.drawBitmap(img, round.x-img.getWidth()/2, round.y-img.getHeight()/2, paint);
}
}
主角需要检测跟敌机的碰撞检测,当碰撞了,主角就会变成受伤状态;当主角与子弹碰撞了,子弹就会变成粘附状态.主角也可以射击,这是粘附在主角上的子弹将会按照与主角的角度进行移动.
敌对星球代码实现:
package com.st;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
public class Enemy extends SObject {
public Enemy(int x, int y,int speedX,int speedY, Bitmap img) {
super(x, y, speedX, speedY,img);
}
@Override
public void update() {
round.x+=speedX;
round.y+=speedY;
//top
if(round.y < 0 && Math.abs(round.y) > round.r){
round.y = STView.height + round.r;
}
//bottom
if(Math.abs(round.y) > STView.height+round.r){
round.y = -round.r;
}
//left
if(round.x < 0 && Math.abs(round.x) > round.r){
round.x = STView.width + round.r;
}
//right
if(Math.abs(round.x) > STView.width+round.r){
round.x = -round.r;
}
checkCollide();
}
private void checkCollide() {
for(int i=0;i<STView.objs.size();i++){
SObject obj = STView.objs.get(i);
//子弹
if(obj instanceof Bullet ){
if(((Bullet) obj).bulletType == Bullet.HEROBULLET && obj.curState == Bullet.NORMAL && this.collide(obj)){
STView.objs.remove(obj);
STView.objs.remove(this);
}
}
}
}
@Override
protected void paint(Canvas myCanvas) {
Paint paint = new Paint();
myCanvas.drawBitmap(img, round.x-img.getWidth()/2, round.y-img.getHeight()/2, paint);
}
}
敌机需要检测是否与主角发射的子弹相撞,如果相撞就销毁.这里我处理为敌机销毁,那个子弹也销毁.
子弹的代码实现:
package com.st;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
public class Bullet extends SObject {
public static final int NORMAL = 0;//普通
public static final int STICK = 1;//粘附主角
public static final int FREEBULLET = 0;//游离的子弹
public static final int HEROBULLET = 1;//主角的子弹
public static final int ENEMYBULLET = 2;//敌机的子弹
public int bulletType;//子弹的类型
public int offsetX;//跟主角粘附时的X偏移
public int offsetY;//跟主角粘附时的Y偏移
public Bullet(int x, int y,int speedX,int speedY,Bitmap img) {
super(x, y, speedX, speedY,img);
}
public void offsetHero(int offsetX,int offsetY){
this.offsetX = offsetX;
this.offsetY = offsetY;
}
@Override
public void update() {
switch(curState){
case NORMAL:
updateNormal();
break;
case STICK:
updateStick();
break;
}
}
private void updateNormal() {
round.x+=speedX;
round.y+=speedY;
//top
if(round.y < 0 && Math.abs(round.y) > round.r){
round.y = STView.height + round.r;
}
//bottom
if(Math.abs(round.y) > STView.height+round.r){
round.y = -round.r;
}
//left
if(round.x < 0 && Math.abs(round.x) > round.r){
round.x = STView.width + round.r;
}
//right
if(Math.abs(round.x) > STView.width+round.r){
round.x = -round.r;
}
}
private void updateStick() {
round.x = STView.hero.round.x + offsetX;
round.y = STView.hero.round.y + offsetY;
}
@Override
protected void paint(Canvas myCanvas) {
Paint paint = new Paint();
myCanvas.drawBitmap(img, round.x-img.getWidth()/2, round.y-img.getHeight()/2, paint);
}
}
它主要是状态之间的切换,还有子弹的类型,是属于谁的.还是游离的.
脚本的实现代码:
package com.st;
import java.io.DataInputStream;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
public class Script extends SObject implements IScript{
private int timer;
private int allTimer;
private boolean isCheck;
public Script(int x, int y,Bitmap img,int allTimer) {
super(x, y, 0, 0,img);
this.allTimer = allTimer;
isCheck = true;
}
@Override
public void update() {
timer++;
if(isCheck){
checkScript();
}
}
@Override
public void checkScript() {
if(timer > allTimer){
runScript();
isCheck = false;
}
}
@Override
public void loadScript(DataInputStream is) {
// TODO Auto-generated method stub
}
@Override
public void runScript() {
//假设已经在如果脚本文件
//下面为执行脚本文件
//生成两个敌人
Bitmap enemy1Img = STView.getImageFromAssetFile("enemy1.png");
SObject enemy1 = new Enemy(50,50,10,10,enemy1Img);
Bitmap enemy2Img = STView.getImageFromAssetFile("enemy2.png");
SObject enemy2 = new Enemy(200,200,-10,10,enemy2Img);
//一个子弹
Bitmap bullut1Img = STView.getImageFromAssetFile("bullet.png");
SObject bullut1 = new Bullet(100,100,10,-10,bullut1Img);//top
SObject bullut2 = new Bullet(100,100,-3,-3,bullut1Img);//top
SObject bullut3 = new Bullet(100,100,-3,3,bullut1Img);//left
SObject bullut4 = new Bullet(100,100,3,-3,bullut1Img);//left
STView.objs.add(enemy1);
STView.objs.add(enemy2);
STView.objs.add(bullut1);
STView.objs.add(bullut2);
STView.objs.add(bullut3);
STView.objs.add(bullut4);
}
@Override
protected void paint(Canvas myCanvas) {
// Paint paint = new Paint();
// myCanvas.drawBitmap(img, x-img.getWidth()/2, y-img.getHeight()/2, paint);
}
}
我模拟了一个脚本的实现,包括脚本的检测,脚本的执行.
好了,基本上就是这样.代码我一会上传下.后续的游戏要素没有加上,因为还有其他更重要的是要做,这个就这样了。虽然程序小,但也学到了不少东西,算是一个j2me到android的移植版本了。算是一个菜鸟的学习过程,呵呵。
一直在看himi的android游戏开发博客教程,感觉不错,谢谢分享。呵呵。