📜 ⬆️ ⬇️

Porting games from the real world to Android

It all started as if in a real detective story: the New Year holidays, December 31, the parental home for many kilometers from Moscow, and the worst thing is the complete absence of the Internet and 2x2 channel. The brain can work in two modes - either consume the content, or create it. It so happened that my brain started working in the second mode at that moment. By coincidence, I came across a long-forgotten puzzle game "Pythagoras":



And I decided to "digitize" it.
')


Pythagoras puzzle consists of 7 geometric figures, which must be folded in such a way as to obtain the shape indicated in the task. When solving a task, you must use all 7 puzzle figures.

Choosing a platform.

Well, in the appendage of everything, I have long wanted to write something under the "mobile phone".

Since Eclipse was on the laptop with the necessary Pribluda for Android, and there were several books about him, downloaded "in reserve", the choice was predetermined.

So, it is decided: we will write the Pythagoras toy for Android. I also note that I am not a programmer, in my understanding of the word.

Implementation of the idea

I will not describe how to install and configure Eclipse and how to create a project, because about this, and so much has been written, finally go to the essence of the story.

Create a project named Pifagor.
After creation we will have a file with the name Pifagor.java and the contents:

package Pifagor.android.game; import android.app.Activity; import android.os.Bundle; public class Pifagor extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); pifagorView = (PifagorView) findViewById(R.id.game); } } 


A start.
Now we will create the file PifagorDraw.java in which our game will be implemented. We define the class PifagorDraw which is a child of the class Thread. For our class, we define the methods for handling events on the screen, reset the game to the initial state, and override the run method:

 package Pifagor.android.game; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Paint.Style; import android.view.MotionEvent; import android.view.SurfaceHolder; public class PifagorDraw extends Thread { private SurfaceHolder appScreen; private boolean appRunning; //    private boolean appPaused; //    private Paint appPaint; // private Bitmap clearScreen; //     private PifagorPuzzle Puzzles[]; //   private int activePuzzle; //    private long thisTime; //        private long downTime; //        private PifagorTask Tasks[]; //   private PifagorTask ResetPiktogram; //     private int activeTask; //    private int maxTasks; //    private boolean prevButton, nextButton, resetButton; //    //   //   private int PuzzleTemplate1[][][] = {......}; //   private int PuzzleTemplate2[][][] = {......}; //   private int PuzzleTemplate3[][][] = {......}; //   private int PuzzleTemplate4[][][] = {......}; //   private int PuzzleTemplate5[][][] = {......}; //   "" private int Pikto1[][] = {......}; //   private int Task1[][] = {......}; private int Task2[][] = {......}; private int Task3[][] = {......}; private int Task4[][] = {......}; //  public PifagorDraw(SurfaceHolder surfaceHolder, Context context) { //     appScreen = surfaceHolder; appRunning = false; appPaused = false; activePuzzle = 0; thisTime = 0; downTime = 0; prevButton = false; nextButton = false; resetButton = false; //   appPaint = new Paint(); appPaint.setColor(Color.BLUE); appPaint.setStrokeWidth(2); appPaint.setStyle(Style.STROKE); //      clearScreen = Bitmap.createBitmap(screenWidth, screenHeight, Bitmap.Config.RGB_565); //      Puzzles = new PifagorPuzzle[7]; Puzzles[0] = new PifagorPuzzle(......); Puzzles[1] = new PifagorPuzzle(......); Puzzles[2] = new PifagorPuzzle(......); Puzzles[3] = new PifagorPuzzle(......); Puzzles[4] = new PifagorPuzzle(......); Puzzles[5] = new PifagorPuzzle(......); Puzzles[6] = new PifagorPuzzle(......); PuzzlesReset(); //      maxTasks = 4; activeTask = 0; Tasks = new PifagorTask[maxTasks]; Tasks[0] = new PifagorTask(......); Tasks[1] = new PifagorTask(......); Tasks[2] = new PifagorTask(......); Tasks[3] = new PifagorTask(......); //    ResetPiktogram = new PifagorTask(......); } //     public void setRunning(boolean status) { appRunning = status; } //     public boolean Touch(MotionEvent event) { int mouseX = (int)event.getX(); int mouseY = (int)event.getY(); switch(event.getAction()) { case MotionEvent.ACTION_MOVE: //   ...... break; case MotionEvent.ACTION_DOWN: //   ...... break; case MotionEvent.ACTION_UP: //   ...... break; } return true; //  true,       } //        public void PuzzlesReset() { ...... } @Override public void run() { while(appRunning) { if (!appPaused) { Canvas canvas = null; try { canvas = appScreen.lockCanvas(); synchronized(appScreen) { //         // : //   canvas.drawBitmap(clearScreen, 0, 0, null); //    for(int i=0;i<7;i++) { Puzzles[i].Update(); Puzzles[i].Draw(canvas); } ...... sleep(20); } } catch (Exception e) { } finally { if (canvas != null) { appScreen.unlockCanvasAndPost(canvas); } } } } } } 


I read about various ways of working with graphics on Android, but more or less figured out with one, and I will use it.

Now create a file in the project with the name PifagorView.java. In this file, we declare the PifagorView class, which is a child of the SurfaceView class, and add the inheritance of the SurfaceHolder.Callback interface - this class will be the link.
In the created class, we need to override the three methods inherited from SurfaceView to respond to changes in the View state, as well as one method to handle screen events (click, drag, drop):

 package Pifagor.android.game; import android.content.Context; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.SurfaceHolder; import android.view.SurfaceView; public class PifagorView extends SurfaceView implements SurfaceHolder.Callback { private SurfaceHolder appScreen; private PifagorDraw appThread; public boolean surfaceCreated; //  public PifagorView(Context context, AttributeSet attrs) { super(context, attrs); surfaceCreated = false; appScreen = getHolder(); appScreen.addCallback(this); appThread = new PifagorDraw(appScreen, context); setFocusable(true); } @Override public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) { // TODO Auto-generated method stub } @Override public void surfaceCreated(SurfaceHolder holder) { appThread = new PifagorDraw(holder, getContext(), screenWidth, screenHeight); appThread.setRunning(true); appThread.start(); } @Override public void surfaceDestroyed(SurfaceHolder arg0) { boolean retry = true; appThread.setRunning(false); while(retry) { try { appThread.join(); retry = false; } catch (InterruptedException e){ } } } @Override public boolean onTouchEvent(MotionEvent event) { return appThread.Touch(event); //           PifagorDraw,        } } 


Now we need to tweak the main.xml file - we have created our View object and now we need to place it on the screen:

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <Pifagor.android.game.PifagorView android:id="@+id/game" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </LinearLayout> 


Also in the project there are two more classes PifagorPuzzle, which describes the geometric figures of the puzzle, and the class PifagorTask, which describes the tasks. We will not consider them.

The application, in principle, can already be launched, but when the application is minimized and resumed, it will fall with a critical error.
To fix this, do the following:

First, in the PifagorView class, we will create the CreateThread and TerminateThread methods (which is clear from the name for what they will be used for), and slightly change the overridden SurfaceCreated and SurfaceDestoryed methods:
 public class PifagorView extends SurfaceView implements SurfaceHolder.Callback { private SurfaceHolder appScreen; private PifagorDraw appThread; public boolean surfaceCreated; private int screenWidth; private int screenHeight; //  public PifagorView(Context context, AttributeSet attrs) { super(context, attrs); surfaceCreated = false; appScreen = getHolder(); appScreen.addCallback(this); appThread = new PifagorDraw(appScreen, context, screenWidth, screenHeight); setFocusable(true); } //   public void terminateThread() { boolean retry = true; appThread.setRunning(false); while(retry) { try { appThread.join(); retry = false; } catch (InterruptedException e){ } } } //   public void createThread(SurfaceHolder holder) { appThread = new PifagorDraw(holder, getContext()); appThread.setRunning(true); appThread.start(); } @Override public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) { // TODO Auto-generated method stub } @Override public void surfaceCreated(SurfaceHolder holder) { if (surfaceCreated == false) { createThread(holder); surfaceCreated = true; } } @Override public void surfaceDestroyed(SurfaceHolder arg0) { terminateThread(); } @Override public boolean onTouchEvent(MotionEvent event) { return appThread.Touch(event); } } 


Second, in the Pifagor class, override the onPause and onResume methods:
 public class Pifagor extends Activity { /** Called when the activity is first created. */ private PifagorView pifagorView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); pifagorView = (PifagorView) findViewById(R.id.game); } @Override public void onPause() { super.onPause(); pifagorView.terminateThread(); } @Override public void onResume() { super.onResume(); if (pifagorView.surfaceCreated == true) { pifagorView.createThread(pifagorView.getHolder()); } } } 


Thus, when the application is minimized, the game process described in the PifagorDraw class will be destroyed, and when returned to the application, it will be launched again.

I did not give full source codes, if anyone is interested, write in a personal, I will send.

Well, we start and see what happens:

I did not find a designer for a toy. If someone is willing to participate - write in a personal.

What's next?
The game is written, you need to do something further. Or clean up the archive, where it will disappear or try to put in the Android Maket. The second is much more interesting, so we register on the market.android.com/publish, register Google Checkout (it's better to register via IE, I had problems with other browsers), pay $ 25 and as usual at the very last moment we try to understand where we are again , that is, we are looking for information - how to promote applications in the Android Market. We read the article and then draw up the following plan:

Source: https://habr.com/ru/post/114059/


All Articles