3. Рекомендації щодо використання застосування
3.1. Технічна характеристика
Пристрій :планшет, смартфон.
Операційна система: Android.
Мова програмування :Java
Середовище розробки : Eclipse IDE.
Графічна платформа :самописний на основі стандартних класів ADK.
Формат файлів , що виконуються : *.apk .
Фізична структура застосування :
Рис. 6 Фізична структура додатку
Опис вмісту
Табл. 2 Опис вмісту фізичної структури додатку
Файл |
Вміст |
SnakeGame.xml |
Виконавчий файл, що вміщує у собі код застосування. Ім’я цього файлу таке саме, як назва застосування мінус.app розширення. |
AndroidManifest.xml |
Головний файл проекту, який містить у собі усі глобальні налаштування проекту. |
src |
Папка з вихідним кодом проекту. У ній містяться усі задіяні класи у проекті. |
resources |
Папка призначена для зберігання ресурсів проекту. Може містити у собі різні каталоги в залежності від використовуваного типу ресурсу. |
images |
Каталог спеціально призначений для зберігання графічних зображень використаних у проекті. Може містити у собі підкаталоги в залежності від типу екрана пристрою, на якому запускаеться додаток. |
layout |
Папка призначена для зберігання файлів компоновки екрану. При запуску додатку, головна Activity перевіряє дану папку на предмет необхідного файлу компоновки. |
3.2. Рекомендації користувачеві
Для того , щоб запустит гру «Snake» необхідно натиснути на відповідну іконку гри (див. Рис. 7).
Рис. 7 Запуск гри
Першим,
що побачить користувач , після того ,як
запустить гру,це буде картинка
«Меню гри». На
ньому зображено кнопка:
«Start
Game».
Рис. 8 Меню гри
При натисканні кнопки «Start Game» починаеться гра, користувач управляє змійкою за допомогою акселерометра.
Рис. 9 Вікно гри
і
4. Текстзастосування
SnakeGame.java
package simpleSnake;
import java.util.ArrayList;
public class SnakeGame {
public class pos {
int x;
int y;
pos(int x, int y) {
this.x = x;
this.y = y;
}
}
public static final int DIR_NORTH = 1;
public static final int DIR_EAST = 2;
public static final int DIR_SOUTH = 3;
public static final int DIR_WEST = 4;
public static int mFieldX = 18;
public static int mFieldY = 30;
public int mScore=0;
private int mField[][] = new int[mFieldX][mFieldY];
private ArrayList<pos> mSnake = new ArrayList<pos>();
int mDirection = SnakeGame.DIR_EAST;
int isGrowing = 0;
SnakeGame() {
for (int i = 0; i < mFieldX; i++)
for (int j = 0; j < mFieldY; j++) {
mField[i][j] = 0;
}
mSnake.add(new pos(2, 2));
mField[2][2] = -1;
mSnake.add(new pos(2, 3));
mField[2][3] = -1;
mSnake.add(new pos(2, 4));
mField[2][4] = -1;
addFruite();
addBarrier(3,27);
addBarrier(3,26);
addBarrier(4,27);
addBarrier(4,26);
addBarrier(15,22);
addBarrier(14,21);
addBarrier(15,21);
addBarrier(14,22);
addBarrier(15,8);
addBarrier(14,9);
addBarrier(14,8);
addBarrier(15,9);
addBarrier(3,8);
addBarrier(4,9);
addBarrier(3,9);
addBarrier(4,8);
}
private void addBarrier(int x,int y)
{
mField[x][y] = 1;
}
private void addFruite() {
boolean par = false;
while (!par) {
int x = (int) (Math.random() * mFieldX);
int y = (int) (Math.random() * mFieldY);
if (mField[x][y] == 0) {
mField[x][y] = 2;
par = true;
}
}
}
public boolean nextMove() {
switch (this.mDirection) {
case DIR_NORTH: {
int nextX = mSnake.get(mSnake.size() - 1).x;
int nextY = mSnake.get(mSnake.size() - 1).y - 1;
if ((nextY >= 0) && mField[nextX][nextY] == 0) {
if (isGrowing > 0) {
isGrowing--;
} else {
mField[mSnake.get(0).x][mSnake.get(0).y] = 0;
mSnake.remove(0);
}
mSnake.add(new pos(nextX, nextY));
mField[nextX][nextY] = -1;
return true;
} else if ((nextY >= 0) && mField[nextX][nextY] == 1) {
return false;
} else if ((nextY >= 0) && mField[nextX][nextY] > 1) {
isGrowing = isGrowing + 2;
mScore=mScore+10;
mField[nextX][nextY] = 0;
mSnake.add(new pos(nextX, nextY));
mField[nextX][nextY] = -1;
addFruite();
return true;
} else {
return false;
}
}
case DIR_EAST: {
int nextX = mSnake.get(mSnake.size() - 1).x + 1;
int nextY = mSnake.get(mSnake.size() - 1).y;
if ((nextX < mFieldX) && mField[nextX][nextY] == 0) {
if (isGrowing > 0) {
isGrowing--;
} else {
mField[mSnake.get(0).x][mSnake.get(0).y] = 0;
mSnake.remove(0);
}
mSnake.add(new pos(nextX, nextY));
mField[nextX][nextY] = -1;
return true;
} else if ((nextX < mFieldX) && mField[nextX][nextY] == 1) {
return false;
} else if ((nextX < mFieldX) && mField[nextX][nextY] > 1) {
isGrowing = isGrowing + 2;
mScore=mScore+10;
mField[nextX][nextY] = 0;
mSnake.add(new pos(nextX, nextY));
mField[nextX][nextY] = -1;
addFruite();
return true;
} else {
return false;
}
}
case DIR_SOUTH: {
int nextX = mSnake.get(mSnake.size() - 1).x;
int nextY = mSnake.get(mSnake.size() - 1).y + 1;
if ((nextX < mFieldX) && mField[nextX][nextY] == 0) {
if (isGrowing > 0) {
isGrowing--;
} else {
mField[mSnake.get(0).x][mSnake.get(0).y] = 0;
mSnake.remove(0);
}
mSnake.add(new pos(nextX, nextY));
mField[nextX][nextY] = -1;
return true;
} else if ((nextX < mFieldX) && mField[nextX][nextY] == 1) {
return false;
} else if ((nextX < mFieldX) && mField[nextX][nextY] > 1) {
isGrowing = isGrowing + 2;
mScore=mScore+10;
mField[nextX][nextY] = 0;
mSnake.add(new pos(nextX, nextY));
mField[nextX][nextY] = -1;
addFruite();
return true;
} else {
return false;
}
}
case DIR_WEST: {
int nextX = mSnake.get(mSnake.size() - 1).x - 1;
int nextY = mSnake.get(mSnake.size() - 1).y;
if ((nextX >= 0) && mField[nextX][nextY] == 0) {
if (isGrowing > 0) {
isGrowing--;
} else {
mField[mSnake.get(0).x][mSnake.get(0).y] = 0;
mSnake.remove(0);
}
mSnake.add(new pos(nextX, nextY));
mField[nextX][nextY] = -1;
return true;
} else if ((nextX >= 0) && mField[nextX][nextY] == 1) {
return false;
} else if ((nextX >= 0) && mField[nextX][nextY] > 1) {
isGrowing = isGrowing + 2;
mScore=mScore+10;
mField[nextX][nextY] = 0;
mSnake.add(new pos(nextX, nextY));
mField[nextX][nextY] = -1;
addFruite();
return true;
} else {
return false;
}
}
}
return false;
}
public int getDirection() {
return mDirection;
}
public void clearScore(){
this.mScore=0;
}
public void setDirection(int direction) {
this.mDirection = direction;
}
public int[][] getmField() {
return mField;
}
public int getSnakeLength() {
return mSnake.size();
}
public ArrayList<pos> getmSnake() {
return mSnake;
}
}
GameSurface.java
package simpleSnake;
import pac.simpleSnake.R;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.SurfaceView;
public class GameSurface extends SurfaceView {
SnakeGame mField;
Bitmap mHead, mTill, mBody, mBg, mFruite,barrier;
String someText = "123";
float x, y;
public void setXY(float x, float y) {
this.x = x;
this.y = y;
}
public GameSurface(Context context) {
super(context);
mField = new SnakeGame();
mHead = BitmapFactory.decodeResource(context.getResources(),
R.drawable.head);
mTill = BitmapFactory.decodeResource(context.getResources(),
R.drawable.till);
mBody = BitmapFactory.decodeResource(context.getResources(),
R.drawable.body);
mBg = BitmapFactory.decodeResource(context.getResources(),
R.drawable.bg);
mFruite = BitmapFactory.decodeResource(context.getResources(),
R.drawable.fruite);
barrier=BitmapFactory.decodeResource(context.getResources(),
R.drawable.barrier);
}
public void setSomeText(String someText) {
this.someText = someText;
}
void drawSnake(Canvas c) {
int width = c.getWidth();
int height = c.getHeight();
int mx = width / SnakeGame.mFieldX;
int my = height / SnakeGame.mFieldY;
Bitmap head = Bitmap.createScaledBitmap(mHead, mx, my, true);
Bitmap body = Bitmap.createScaledBitmap(mBody, mx, my, true);
Bitmap till = Bitmap.createScaledBitmap(mTill, mx, my, true);
Bitmap bg = Bitmap.createScaledBitmap(mBg, mx, my, true);
Bitmap fruite = Bitmap.createScaledBitmap(mFruite, mx, my, true);
Bitmap barrier = Bitmap.createScaledBitmap(this.barrier, mx, my, true);
Paint paint = new Paint();
paint.setColor(Color.CYAN);
c.drawCircle(width / 2, height / 2, width / 4, paint);
paint.setColor(Color.BLUE);
c.drawCircle(width / 2 - x * 5, height / 2 + y * 5, width / 10, paint);
paint.setColor(Color.BLACK);
paint.setAlpha(128);
for (int i = 0; i < SnakeGame.mFieldX; i++) {
for (int j = 0; j < SnakeGame.mFieldY; j++) {
c.drawBitmap(bg, mx * i, my * j, paint);
if (mField.getmField()[i][j] > 1) {
c.drawBitmap(fruite, mx * i, my * j, paint);
}
}
}
for (int i = 0; i < SnakeGame.mFieldX; i++) {
for (int j = 0; j < SnakeGame.mFieldY; j++) {
if(mField.getmField()[i][j] == 1) {
c.drawBitmap(barrier, mx * i, my * j, paint);
c.drawBitmap(barrier, mx * i, my * j, paint);
c.drawBitmap(barrier, mx * i, my * j, paint);
}
}
}
paint.setAlpha(0);
for (int i = 0; i < mField.getSnakeLength(); i++) {
c.drawBitmap(body, mField.getmSnake().get(i).x * mx, mField
.getmSnake().get(i).y * my, new Paint());
if (i == 0) {
c.drawBitmap(till, mField.getmSnake().get(i).x * mx, mField
.getmSnake().get(i).y * my, new Paint());
}
if (i == mField.getSnakeLength() - 1) {
c.drawBitmap(head, mField.getmSnake().get(i).x * mx, mField
.getmSnake().get(i).y * my, new Paint());
}
}
paint.setColor(Color.WHITE);
paint.setAlpha(255);
paint.setTextSize(15);
c.drawText(someText, 50, 50, paint);
}
}
SimpleSnakeActivity.java
package simpleSnake;
import pac.simpleSnake.R;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class SimpleSnakeActivity extends Activity implements OnClickListener {
Button butt;
TextView tv;
public static int GAME_MODE=0;
public static int GAME_SCORE=0;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public void onStart(){
super.onStart();
if (GAME_MODE==0){
setContentView(R.layout.main);
butt = (Button) this.findViewById(R.id.button1);
butt.setOnClickListener(this);
}
else
{
setContentView(R.layout.lose);
butt = (Button) this.findViewById(R.id.button2);
tv = (TextView) this.findViewById(R.id.textView2);
tv.setText("Your score: "+GAME_SCORE);
butt.setOnClickListener(this);
}
}
public void onClick(View v) {
Intent i = new Intent(this, simpleSnake.GameActivity.class);
GAME_MODE=0;
GAME_SCORE=0;
this.startActivity(i);
}
}
GameActivity.java
package simpleSnake;
import java.util.List;
import java.util.Timer;
import android.app.Activity;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.view.WindowManager;
public class GameActivity extends Activity implements SensorEventListener {
GameSurface surf;
Timer t;
int width, height;
SensorManager mSensorManager;
Sensor mAccelerometerSensor;
float SSX = 0, SSY = 0;
float SX = 0, SY = 0;
boolean firstTime;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
surf = new GameSurface(this);
this.setContentView(surf);
t = new Timer();
height = this.getWindowManager().getDefaultDisplay().getHeight();
width = this.getWindowManager().getDefaultDisplay().getWidth();
mSensorManager = (SensorManager) getSystemService(Activity.SENSOR_SERVICE);
List<Sensor> sensors = mSensorManager.getSensorList(Sensor.TYPE_ALL);
if (sensors.size() > 0) {
for (Sensor sensor : sensors) {
if (sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
if (mAccelerometerSensor == null)
mAccelerometerSensor = sensor;
}
}
}
}
@Override
public void onStart() {
super.onStart();
t.scheduleAtFixedRate(new GraphUpdater(surf), 0, 100);
t.scheduleAtFixedRate(new StepUpdater(this), 0, 500);
mSensorManager.registerListener(this, mAccelerometerSensor,
SensorManager.SENSOR_DELAY_GAME);
this.firstTime = true;
getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
@Override
public void onStop() {
super.onStop();
t.cancel();
t.purge();
mSensorManager.unregisterListener(this);
}
// @Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// Do nothing!
}
private int getDirection(float x, float y) {
if (Math.abs(x) > Math.abs(y)) {
if (x > 0) {
return SnakeGame.DIR_WEST;
} else {
return SnakeGame.DIR_EAST;
}
} else {
if (y > 0) {
return SnakeGame.DIR_SOUTH;
} else {
return SnakeGame.DIR_NORTH;
}
}
}
// @Override
public void onSensorChanged(SensorEvent event) {
surf.setSomeText("Your score is: "+SimpleSnakeActivity.GAME_SCORE);
SX = event.values[0];
SY = event.values[1];
if (!this.firstTime) {
float dirX = SX - SSX;
float dirY = SY - SSY;
surf.mField.setDirection(this.getDirection(dirX, dirY));
surf.setXY(dirX, dirY);
} else {
this.firstTime = false;
SSX = SX;
SSY = SY;
}
}
public void Step() {
if (!surf.mField.nextMove()) {
SimpleSnakeActivity.GAME_MODE=1;
this.finish();
}
else{
SimpleSnakeActivity.GAME_SCORE=this.surf.mField.mScore;
}
}
}
GraphUpdater.java
package simpleSnake;
import java.util.TimerTask;
import android.graphics.Canvas;
import android.graphics.Color;
public class GraphUpdater extends TimerTask {
GameSurface surf;
GraphUpdater(GameSurface surf){
this.surf = surf;
}
@Override
public void run() {
Canvas c = surf.getHolder().lockCanvas();
if (c!=null){
c.drawColor(Color.BLACK);
surf.drawSnake(c);
surf.getHolder().unlockCanvasAndPost(c);
}
}
}
StepUpdater.java
package simpleSnake;
import java.util.TimerTask;
public class StepUpdater extends TimerTask {
GameActivity act;
StepUpdater(GameActivity s){
this.act = s;
}
@Override
public void run() {
act.Step();
}
}
