当前位置:首页 > 代码 > 正文

android小游戏代码(手机小游戏代码)

admin 发布:2022-12-20 00:19 124


本篇文章给大家谈谈android小游戏代码,以及手机小游戏代码对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。

本文目录一览:

Android小游戏 之《数字华容道》

[toc]

最近看《最强大脑》,看到其中的“数字华容道”这个小游戏挺有意思,于是萌生了自己写一个的想法,正好结合之前的文章 《Android开发艺术探索》第4章 View的工作原理 ,顺便复习一下。

GitHub链接:

说做就做。

经过一夜的粗制滥造,初版已经完成,现在复盘一下详细过程。

在4x4的方格棋盘中,摆放了1 15一共十五个棋子。玩家需要在最短时间内,移动棋子将1 15按顺序排列好。

本文app结构很简单,分为三个界面:目录,游戏,高分榜。分别对应的是MenuAcitivity、GameActivity、HighScoreActivity。其中MenuActivity为主界面。

新建棋盘类 BoardView ,继承自ViewGroup。在xml文件中直接加入BoardView即可。

新建棋子类 CubeView ,继承自TextView。

棋子只包含一个数字,所以简单的继承自TextView即可。由于我们还需要比对棋子是否在正确的位置,所以我们还需要给每个棋子加上数字和位置属性。

这里,我们定义了一个类Position,用于描述棋子在棋盘中的位置。

我们参考Android系统屏幕坐标系,以棋盘左上角为零点,每向右一格横坐标加一,每向下一格纵坐标加一。如图:

接下来,我们开始定义棋盘View:BoardView,这也是这个游戏的重头戏。

首先,考虑需要添加哪些属性。由于时间关系,我这里只加入了棋盘尺寸。

在style.xml文件中加入:

其中sizeH为棋盘列数,sizeV为棋盘行数。(默认4x4大小,以下文中均以4x4为例)

分别对应BoardView的 mSizeX 和 mSizeY 属性。

首先我们新建一个 cube_view.xml ,作为单颗棋子的布局。在BoardView的构造方法中,我们使用LayoutInflater将总共15颗棋子加载出来,并指定它们的位置,逐一保存在mChildren数组中。

最后,我们记录了没有棋子的空格所在位置 mBlankPos 。这个位置很关键,因为我们之后的的操作中都是围绕这个空格来的。

measure和layout的过程很简单,这里由于是自己使用,假定宽高都是定值。因为之前所有的CubeView都没有定义宽高,默认是0,所以在onMeasure中,我们使用BoardView的宽除以列数,高除以行数,得到每颗棋子的宽高并给其赋值。这样处理虽然很粗放,但是只是试玩的话并没有什么影响。

我是按照从左往右、从上往下的方式依次排列棋子,并且没有考虑棋子的margin属性,所以onLayout很简单:

至此,棋子在棋盘中就已经排列好了。

一开始的时候,我考虑的是,生成1~15的不重复随机数,然后依次给CubeView赋值即可。即:

虽然看起来是能行得通的,但是在实际的游戏过程中,遇到了非常严重的问题,那就是会出现无解的死局,也就是说无论如何都不可能解出来的棋局。经过网上搜索之后证实了这个bug的存在,而且市面上流传的该类app很多都是有这个bug的!所以这个办法就被废弃掉了,得想一个新的方法。

由于必须是按照顺序放置然后打乱的棋局才能保证有解,不能随机乱放置,所以我就模拟手动打乱,写了一个新的棋局生成器:

原理很简单,因为空格的位置是唯一的,那么我们把空格的上下左右四个棋子随机找出一个,与空格互换位置,也就模拟了一次手动点击。当点击的次数足够多时(这里循环了10000次),就可以看做是已经打乱的棋盘了。

最后把生成好的棋盘,保存在一个二维数组中即可。

(因为有个10000次的循环,我担心时间过长,于是将其放在线程中执行,但是后来我觉得自己多此一举了。)

然后,在BoardView中定义一个setData方法,来把生成好的棋局装进来:

这样,就完成了棋局的生成。

游戏过程基本是极简的。

在初始化方法中(2.1),我们给每个棋子都定义了点击事件,模拟真实场景。具体来讲,就是当我们点击一个棋子的时候:如果棋子在空格周围,则将棋子移动到空格处;反之,则不进行任何操作。(如果设置滑动同理)

这样我们的Position类就派上用场了。

在2.1的 init() 方法中,我们有这么一句:

即是,当我们点击了其中一个棋子时,会触发 moveChildToBlank(view) 方法。这个方法的目的正是上面所说。

在移动棋子之后,我们需要检查一下是否是正确排列的顺序,如果是的话,那么表明游戏完成。

首先创建HighScore类,包含姓名,用时,步数,时间。

高分榜使用SharedPreferences+Gson,将一个ListHighScore转换为json形式保存在本地。

最佳成绩的记录是在GameActivity中完成的。流程如下:

总的来说,逻辑简单清晰。

自己开发的自然是需要作弊功能了!暂且不表。

由于只用了一个晚上完成,所以还很粗糙,很多功能不够完善,而且也没做适配和测试,难免会有bug存在。主要是把思路记录下来,方便以后自己和他人做个参考。

数字华容道GitHub地址:

基于android系统的手机游戏的开发

如果你有兴趣为Android平台开发游戏,有很多你需要了解的东西。如果你有过游戏开发经验,那么转移到移动平台上来将不是特别困难。你主要只需学习其架构以及API就行了。如果你是一名游戏开发新手,我总结了一张列表,上面有你必需知道的东西,供你起步用。这些知识适用于很多类型的游戏,包括动作类、策略类、模拟类和益智类。 Android是一个基于Java的环境。这对初学者来说是个好消息,因为相对于C++,Java被广泛认为是一门更容易上手的语言,它是移动开发的规范。Google也做了一件出色的工作,它将API文档化并提供示例代码供使用。其中有个叫做API Demos的示例几乎展示了所有API的功能。如果你熟悉Java并且用过Eclipse,要让你的第一个应用跑起来那是相当简单。如果你以前从没写过代码,在你前进路上还要学习很多,但别气馁。

获取SDK

新手上路的第一步便是获取Android SDK(软件开发工具包)。SDK里有一个核心类库,一个模拟器,一些工具和示例代码。我强烈建议使用Eclipse和Android Eclipse插件。如果你玩Android的话,Eclipse IDE对Java开发者来说很好用。如果这是你第一次开发Java项目,你可能会需要下载全套JDK,它里面包括签名和部署你的应用程序的一些工具。

学习应用程序架构

别急着一头扎进开发的海洋里,理解Android应用程序架构是很重要的。如果你不学一下,你设计出来的游戏在线下将很难调试。你将需要理解Applications、Activities、Intents以及它们怎样相互联系。Google提供了很多有用的架构信息。真正重要的是要理解为什么你的游戏需要多于一个的Activity,以及什么才是设计一个有良好用户体验的游戏。要理解这些,首先要了解什么是Activity生命周期。

学习Activity生命周期

Activity生命周期由Android操作系统来管理。你的activity创建、恢复、暂停、销毁都受操作系统的支配。正确处理这些事件是很重要的,这样应用程序才能表现良好,做用户认为正确的事。在你设计你的游戏之前了解所有这些是如何工作的是件好事,因为以后你可以为自己节省调试时间和昂贵的重新设计时间。对大多数应用来说,默认的设置将工作正常,但对于游戏,你可能需要考虑将SingleInstance标志打开。当设置为默认时,Android在它认为合适时会创建activity的新实例。对于游戏来说,你可能只需要一个游戏activity的实例。这对于你要怎样管理事务的状态有些影响,但对于我来说,这解决了一些资源管理的问题,应予以考虑。

主循环

根据你写的游戏的类型,你可能需要也可能不需要一个主循环。如果你的游戏不依赖于时间或者它仅仅对用户所做的加以回应,并且不做任何视觉上的改变,永远等待着用户的输入,那么你就不需要主循环。如果你写的是动作类游戏或者带有动画、定时器或任何自动操作的游戏,你应该认真考虑下使用主循环。

游戏的主循环以一个特定的顺序通常尽可能多的在每秒钟内“滴答”提醒子系统运行。你的主循环需要在它自己的线程里运行,原因是Android有一个主用户界面线程,如果你不运行自己的线程,用户界面线程将会被你的游戏所阻塞,这会导致Android操作系统无法正常的更新任务。执行的顺序通常如下:状态,输入,人工智能,物理,动画,声音,录像。

更新状态意思是管理状态转换,例如游戏的结束、人物的选择或下一个级别。很多时候你需要在某个状态上等上几秒钟,而状态管理应该处理这种延迟,并且在时间过了之后设置成下一个状态。

输入是指用户按下的任何键、对于滚动条的移动或者用户的触摸。在处理物理之前处理这些是很重要的,因为很多时候输入会影响到物理层,因而首先处理输入将会使游戏的反应更加良好。在Android里,输入事件从主用户界面线程而来,因此你必须写代码将输入放入缓冲区,这样你的主循环可以在需要的时刻就从缓冲区里取到它。这并非难事。首先为下一个用户输入定义一个域,然后将onKeyPressed或onTouchEvent函数设为接到一个用户动作就放到那个域里,有这两步就够了。如果对于给定游戏的状态,这是一个合法的输入操作,那么所有输入需要在那一刻做的更新操作都已经定下来了,剩下来就让物理去关心怎样响应输入吧。

人工智能所做的类似于用户在决定下一个要“按”哪个按钮。学习怎样写人工智能程序超出了这篇文章的范围,但大体的意思是人工智能会按照用户的意图来按按钮。这些也有待物理去处理和响应吧。

物理可能是也可能不是真正的物理。对于动作类游戏来说,关键点是要考虑到上一次更新的时间、正在更新的当前时间、用户输入以及人工智能,并且决定它们朝着什么方向发展和是否会发生冲突。对于一个你可视化地抓取一些部件并滑动它们的游戏来说,物理就是这个游戏中滑动部件或者使之放入合适的位置的部分。对于一个小游戏来说,物理即使这个游戏中决定答案是错还是对的部分。你可能将其命名为其他东西,但每个游戏都有一个作为游戏引擎的红肉部分(译者注:可能是主体部分的意思),在这篇文章里,我把这部分称为物理。

动画并非像在游戏里放入会动的gif图片那样简单。你需要使得游戏能在恰当的时间画出每一帧。这并没有听起来那么困难。保留一些像isDancing、danceFrame和lastDanceFrameTime那样的状态域,那样动画更新便能决定是否可以切换到下一帧去了。动画更新真正做的事就那么多。真正来显示动画的变化是由录像更新来处理的。

声音更新要处理触发声音、停止声音、音量变化以及音调变化。正常情况下当写游戏的时候,声音更新会产生一些传往声音缓冲区的字节流,但是Android能够管理自己的声音,因而你的选择将是使用SoundPool或者MediaPlayer。它们都需要小心处理以免出错,但你要知道,因为一些底层实现细节,小型、低比特率的声音文件将带来最佳的性能和稳定性。

录像更新要考虑游戏的状态、角色的位置、分数、状态等等,并将一切画到屏幕上。如果使用主循环,你可能需要使用SurfaceView,并做一个“推”绘制。对于其他视图,视图本身能够调用绘制操作,主循环不必处理。SurfaceView每秒产生的帧数最多,最适合于一些有动画或屏幕上有运动部件的游戏。录像更新所要做的工作是获取游戏的状态,并及时地为这个状态绘制图像。其他的自动化操作最好由不同的更新任务来处理。

代码看起来是什么样的?这儿有个例子。

1: public void run() {

2: while (isRunning) {

3: while (isPaused isRunning) {

4: sleep(100);

5: }

6: update();

7: }

8: }

9:

10: private void update() {

11: updateState();

12: updateInput();

13: updateAI();

14: updatePhysics();

15: updateAnimations();

16: updateSound();

17: updateVideo();

18: }

3D还是2D?

在开始写游戏之前,你要决定是做3D的还是2D的。2D游戏有一个低得多的学习曲线,一般更容易获得良好的性能。3D游戏需要更深入的数学技能,并且如果你不在意的话会有性能问题产生。如果你打算画比方框和圆圈更复杂的图形,还需要会使用3D Studio和Maya那样的建模工具。Android支持OpenGL用来3D编程,并且在OpenGL方面有很多很好的教程可供学习。

建立简单、高质量的方法

上手时,要确保你整个游戏不要就用一个庞大而冗长的方法。如果你遵循我上面描述的主循环模式,这将相当简单。每个你写的方法应当完成一个非常特定的任务,并且它就应该无差错地那样做。举例来说,如果你需要洗一副纸牌,你应该写一个“shuffleCards”的方法,并且该方法就应该只做这一件事。

这是一个适用于任何软件开发的编码实践,但对于游戏开发来说这尤为重要。在一个有状态的、实时的系统里,调试将变得非常困难。使你的方法尽量的小,一般的经验法则是每个方法有且仅有一个目的(译者注:完成且仅完成一个功能)。如果你要为一个场景用编程方式画一个背景,你可能需要一个叫做“drawBackground”的方法。诸如此类的任务能够很快完成,因而你可以按照搭积木的方法来开发你的游戏,而你能够继续添加你要的功能,并且不会使得这一切难以理解。

最重要的是效率!

性能是任何游戏的主要问题。我们的目标是使得游戏的反应越快越好,看起来越流畅越好。某些方法如Canvas.drawLine比较慢。并且要将屏幕大小的位图画到主画布上,每一帧都是代价昂贵的。如何权衡对于达到最佳性能很有必要。确保管理好你的资源,使用技巧来以最少量的CPU资源完成你的任务。如果性能不好的话,即使是最好的游戏玩起来也没劲。人们一般对于游戏卡或者响应慢几乎难以容忍。

提示和技巧

看一下SDK中的示例LunarLander。它使用SurfaceView,这对于一个每秒需要处理最多帧的游戏来说是合适的。如果你要做3D,示例中有GLView可以处理3D显示的很多初始化工作。对LightRacer来说,我不得不优化把所有东西都画出来这种方法,否则帧率将会大大地降低。我只在视图初始化的时候把背景画进一个位图里一次。路径放在它们自己的位图里,随着车手的前进而更新。这两个位图在每一帧里都被画进主画布中去,车手画在顶端,到最后会有一个爆炸。这种技术使得游戏运行在一个可以玩的程度。

如果适用的话,使得你的位图的大小精确等于你打算画到屏幕上的大小,这也是个好的实践。这么做了以后就需要缩放,可以节省CPU资源。

在游戏中始终一致的位图配置(如RGBA8888)。这将会通过减少不同格式之间转换的时间来节省图形库的CPU时间。

如果你决定开发3D游戏但没有3D方面的知识,你需要挑选一两本3D游戏编程方面的书并学习线性代数。你最少要理解点积、叉积、向量、单元向量、法线、矩阵和变换。这方面我遇到的最好的书是叫《3D游戏编程和计算机图形学数学》。

声音文件要小而且低比特率。需要加载的越少,加载速度越快,游戏所需内存越少。

声音使用OGG文件,图片使用PNG文件。

确保释放所有媒体播放器,当Activity销毁时空出所有的资源。这能保证垃圾收集器清除了所有东西,也能保证在两次游戏开始之间没有内存泄露。

加入Android谷歌小组,寻求社区支持。这里有人可以在开发过程中给你帮助。

最重要的是,花时间测试再测试,确保每一小部分都如你所愿地工作。改善游戏是整个开发中最耗时最困难的部分。如果你匆匆将其推向市场,你很可能会使用户们失望,你会感到你的努力都白费了。你不可能使所有人都喜欢你写的东西,但你至少要尽量发布你最高质量的作品。

Google在这里有帮助你上手的绝佳的文档。

电驴上也有很多不错的书籍和视频教程~希望对你有帮助

怎么用编程开发个游戏?

第一就是游戏逻辑,也就是与平台无关的游戏逻辑的开发。

第二部分是游戏引擎,大部分会用到一些引擎的工作流、一些各种系统封装好的高层的API。

第三部分是weapp,小游戏的框架是参考了webview的框架,但其实它的底层不是webview,而是webview精简优化过的平台,小游戏有的只是与核心相关的一些渲染的API。

这里的weapp-adaper是把小游戏的能力适配到与webview更接近的环境,让更上层的游戏或引擎本身能够更快速地集入到平台中。

总的来说小游戏的入口为game.js,游戏可以利用底层的一些能力将游戏的整个界面绘制出来。配置文件为game.json主要用来配置小游戏是横屏还是竖屏,小游戏的全局对象game Gobal类似于webview中的window对象,同时支持javascript语言。

但是小游戏有一个重要的一个限制是禁止动态执行代码,开发者必须先提交审核,在审核通过后才可以上架给普通用户。另外,小游戏包括引擎的代码量比较大,所以限制大小比小程序要大,首包限制大小为4M。

求一个安卓开发小游戏源代码,临时交作业用

package com.fiveChess;

import android.app.Activity;

import android.os.Bundle;

import android.view.Display;

import android.view.Menu;

import android.view.MenuItem;

import android.view.Window;

import android.view.WindowManager;

public class MainActivity extends Activity {

GameView gameView = null;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

this.getWindow().requestFeature(Window.FEATURE_NO_TITLE);

this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);

Display display = this.getWindowManager().getDefaultDisplay();

gameView = new GameView(this,display.getWidth(),display.getHeight());

setContentView(gameView);

}

@Override

public boolean onCreateOptionsMenu(Menu menu) {

menu.add("重新开始").setIcon(android.R.drawable.ic_menu_myplaces);

menu.add("退出");

return super.onCreateOptionsMenu(menu);

}

@Override

public boolean onOptionsItemSelected(MenuItem item) {

if(item.getTitle().equals("重新开始")){

gameView.canPlay = true;

gameView.chess = new int[gameView.row][gameView.col];

gameView.invalidate();

}else if(item.getTitle().equals("退出")){

finish();

}

return super.onOptionsItemSelected(item);

}

}

package com.fiveChess;

import android.app.AlertDialog;

import android.content.Context;

import android.content.DialogInterface;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Paint;

import android.graphics.Paint.Style;

import android.view.MotionEvent;

import android.view.View;

public class GameView extends View {

Context context = null;

int screenWidth,screenHeight;

String message = "";//提示轮到哪个玩家

int row,col; //划线的行数和列数

int stepLength = 30;//棋盘每格间距

int[][] chess = null;//0代表没有棋子,1代表是黑棋,2代表白旗

boolean isBlack = true;

boolean canPlay = true;

public GameView(Context context,int screenWidth,int screenHeight) {

super(context);

this.context = context;

this.screenWidth = screenWidth;

this.screenHeight = screenHeight;

this.message = "黑棋先行";

row = (screenHeight-50)/stepLength+1;

col = (screenWidth-10)/stepLength+1;

chess = new int[row][col];

}

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

Paint paint = new Paint();

paint.setColor(Color.WHITE);

canvas.drawRect(0, 0, screenWidth, screenHeight, paint);//画背景

paint.setColor(Color.BLUE);

paint.setTextSize(25);

canvas.drawText(message, (screenWidth-100)/2, 30, paint);//画最顶层的字

paint.setColor(Color.BLACK);

//画棋盘

for(int i=0;irow;i++){

canvas.drawLine(10, 50+i*stepLength, 10+(col-1)*stepLength, 50+i*stepLength, paint);

}

for(int i=0;icol;i++){

canvas.drawLine(10+i*stepLength,50,10+i*stepLength,50+(row-1)*stepLength, paint);

}

for(int r=0;rrow;r++){

for(int c=0;ccol;c++){

if(chess[r][c] == 1){

paint.setColor(Color.BLACK);

paint.setStyle(Style.FILL);

canvas.drawCircle(10+c*stepLength, 50+r*stepLength, 10, paint);

}else if(chess[r][c] == 2){

//画白棋

paint.setColor(Color.WHITE);

paint.setStyle(Style.FILL);

canvas.drawCircle(10+c*stepLength, 50+r*stepLength, 10, paint);

paint.setColor(Color.BLACK);

paint.setStyle(Style.STROKE);

canvas.drawCircle(10+c*stepLength, 50+r*stepLength, 10, paint);

}

}

}

}

@Override

public boolean onTouchEvent(MotionEvent event) {

if(!canPlay){return false;}

float x = event.getX();

float y = event.getY();

int r = Math.round((y-50)/stepLength);

int c = Math.round((x-10)/stepLength);

if(r0 || rrow-1 || c0 || ccol-1){return false;}

if(chess[r][c]!=0){return false;}//若有棋子则不再画棋子了

if(isBlack){

chess[r][c] = 1;

isBlack = false;

message = "轮到白棋";

}else{

chess[r][c] = 2;

isBlack = true;

message = "轮到黑棋";

}

invalidate();

if(judge(r, c,0,1)) return false;

if(judge(r, c,1,0)) return false ;

if(judge(r, c,1,1)) return false;

if(judge(r, c,1,-1)) return false;

return super.onTouchEvent(event);

}

private boolean judge(int r, int c,int x,int y) {//r,c表示行和列,x表示在y方向上的偏移,y表示在x方向上的偏移

int count = 1;

int a = r;

int b = c;

while(r=0 rrow c=0 ccol r+x=0 r+xrow c+y=0 c+ycol chess[r][c] == chess[r+x][c+y]){

count++;

if(y0){

c++;

}else if(y0){

c--;

}

if(x0){

r++;

}else if(x0){

r--;

}

}

while(a=0 arow b=0 bcol a-x=0 a-xrow b-y=0 b-ycol chess[a][b] == chess[a-x][b-y]){

count++;

if(y0){

b--;

}else if(y0){

b++;

}

if(x0){

a--;

}else if(x0){

a++;

}

}

if(count=5){

String str = "";

if(isBlack){

str = "白棋胜利";

}else{

str = "黑棋胜利";

}

new AlertDialog.Builder(context).setTitle("游戏结束").setMessage(str).setPositiveButton("重新开始", new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialog, int which) {

chess = new int[row][col];

invalidate();

}

}).setNegativeButton("观看棋局", new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialog, int which) {

canPlay = false;

}

}).show();

return true;

}

return false;

}

}

PS:五子棋,无需图片,直接在程序里画出来的。注意我发的是两个文件,一个activity,一个类文件,别把它当成一个文件了

关于android小游戏代码和手机小游戏代码的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。

版权说明:如非注明,本站文章均为 AH站长 原创,转载请注明出处和附带本文链接;

本文地址:http://ahzz.com.cn/post/31889.html


取消回复欢迎 发表评论:

分享到

温馨提示

下载成功了么?或者链接失效了?

联系我们反馈

立即下载