Menu w grze Cz.3

Każda gra powinna mieć menu początkowe oraz powinna posiadać ustawienia, które mogą modyfikować naszą grę. Taką opcją może być np. ustawianie muzyki w grze, albo jej wyciszenie. W tej części zmodyfikował cały projekt tak, aby było dostępne menu główne oraz można było wyłączać muzykę za pomocą przycisku menu. Program wygląda tak:

Teraz za ekran początkowy odpowiedzialna jest klasa MainActivity. i grafika activity_main.xml, dlatego wyrzuciłem wszystkie niepotrzebne rzeczy z tej klasy i zostawiłem tylko 3 przyciski odpowiedzialne za rozpoczęcie gry, informację i wyjście z gry.

plik MainActivity.java:

package pl.nstrefa.avrkwiat.gra1;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;

public class MainActivity extends Activity  implements OnClickListener{

 @Override
 public void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 
 //ustawienie full screna i brak tytułu gry
 requestWindowFeature(Window.FEATURE_NO_TITLE);
 getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); 
 
 
 //wyświetlenie templatki activity_main.xml
 setContentView(R.layout.activity_main);
 
 // Konfigurujemy obiekty nasłuchujące kliknięć dla wszystkich przycisków
 View przyciskNowa = findViewById(R.id.przycisk_nowaGra);
 przyciskNowa.setOnClickListener(this);
 View przyciskInformacje = findViewById(R.id.przycisk_informacje);
 przyciskInformacje.setOnClickListener(this);
 View przyciskWyjscie = findViewById(R.id.przycisk_wyjscie);
 przyciskWyjscie.setOnClickListener(this);
 
 }
 public void onClick(View v) {
 switch (v.getId()) {

 case R.id.przycisk_informacje:
 Intent i = new Intent(this, Informacje.class);
 startActivity(i);
 break;
 
 case R.id.przycisk_nowaGra:
 otworzNowaGra();
 break;
 
 case R.id.przycisk_wyjscie:
 finish();
 break;
 }
 }
 private void otworzNowaGra() {
 Intent i = new Intent(this, GameView.class);
 startActivity(i);
 //setContentView(mGameView);
 }
 @Override
 public boolean onCreateOptionsMenu(Menu menu) {
 // Inflate the menu; this adds items to the action bar if it is present.
 getMenuInflater().inflate(R.menu.main, menu);
 return true;
 }
 
 @Override
 public boolean onOptionsItemSelected(MenuItem element) {
 switch (element.getItemId()) {
 case R.id.action_settings:
 startActivity(new Intent(this, MenuPrzycisk.class));
 
 return true;
 // Wstawiamy tutaj pozostałe elementy (jeśli jakieś będą) ...
 }
 return false;
 }
}

Gdy naciśniemy przycisk Start odpali nam się aktywność GameView. Jak można zauważyć poniżej, w tym artykule klasa GameView zostałą całkowicie zmieniona, teraz dziedziczy po activity. W tej klasie jest podklasa GameViewSurf, która jest odpowiedzialna za wyświetlanie grafiki. W klasie GameView dodałem implementacje akcelerometru oraz przycisk menu.

plik GameView.java wygląda tak:

package pl.nstrefa.avrkwiat.gra1;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
//import android.hardware.SensorManager;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.SoundPool;
import android.os.Bundle;
//import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
//import java.lang.*;
import android.view.Window;

public class GameView extends Activity implements SensorEventListener{
 GameView.GameViewSurf mGameView;
 private int x=0;        
 private int y=0;    
 private SensorManager menedzer;
 private Sensor czujnik;
 private boolean muzykaTak=true;
 private static MediaPlayer mp=null;
 private SoundPool soundPool;
 
 public void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 requestWindowFeature(Window.FEATURE_NO_TITLE);
 
 mGameView = new GameView.GameViewSurf(this);
 mGameView.daneZczujnikaX(x);
 mGameView.daneZczujnikaY(y);
 
 //deklaracje itp
 setRequestedOrientation (ActivityInfo.SCREEN_ORIENTATION_NOSENSOR); 
 menedzer = (SensorManager) getSystemService(SENSOR_SERVICE);
 czujnik = menedzer.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
 menedzer.registerListener(this, czujnik,SensorManager.SENSOR_DELAY_UI);
 
 setContentView(mGameView);
 
 
 }
public class GameViewSurf extends SurfaceView implements SurfaceHolder.Callback{

 private SpriteObject sprite;
 private SpriteTlo spriteTlo;
 private GameLogic mGameLogic=null; 
 private Bitmap[] bitmapTab=new Bitmap[5];
 
 private int ID_bzyk;
 
 
 private SurfaceHolder holder;
 Activity main=null;

 public GameViewSurf(Context context) { 
 super(context);
 holder = getHolder();
 holder.addCallback(this); 
 
 
 sprite = new SpriteObject(BitmapFactory.decodeResource(getResources(), R.drawable.star), 50, 50);
 
 bitmapTab[0]=BitmapFactory.decodeResource(getResources(), R.drawable.fl);
 bitmapTab[1]=BitmapFactory.decodeResource(getResources(), R.drawable.fl);
 bitmapTab[2]=BitmapFactory.decodeResource(getResources(), R.drawable.fp);
 bitmapTab[3]=BitmapFactory.decodeResource(getResources(), R.drawable.fg);
 bitmapTab[4]=BitmapFactory.decodeResource(getResources(), R.drawable.fd);
 spriteTlo = new SpriteTlo(bitmapTab);
 
 soundPool = new SoundPool(0, AudioManager.STREAM_MUSIC, 0);
 
 
 ID_bzyk = soundPool.load(context, R.raw.bzyk, 1);
 
 setFocusable(true);
 }

 @Override
 public void surfaceChanged(SurfaceHolder holder, int format, int width,    int height) {
 }

 @Override
 public void surfaceCreated(SurfaceHolder holder) {
 if (mGameLogic == null){
 mGameLogic = new GameLogic(holder, this);
 mGameLogic.setGameState(true); 
 mGameLogic.start();        
 
 }
 
 }
 
 @Override
 public void surfaceDestroyed(SurfaceHolder holder) {
 boolean retry = true;
 
 if (mGameLogic != null){
 mGameLogic.setGameState(false); 
 while (retry) { 
 try {
 mGameLogic.join();
 retry = false; //Loop until game thread is done, making sure the thread is taken care of.
 } catch (InterruptedException e) {
 
 }
 }
 mGameLogic=null;
 }
 }
 
 
 public void onDraw(Canvas canvas) {
 
 canvas.drawColor(Color.BLACK);
 spriteTlo.draw(canvas);
 sprite.draw(canvas);
 }

 public void update() {
 if (sprite.getX() >= getWidth()){ 

 sprite.setX(getWidth());
 }
 if (sprite.getX() <= 0){

 sprite.setX(0);
 }
 if (sprite.getY() >= getHeight()){ 
 
 sprite.setY(getHeight());
 }
 if (sprite.getY() <= 0){
 
 sprite.setY(0);
 }
 spriteTlo.update(sprite.getX(), sprite.getY());
 sprite.update();

 }
 public void playsound(int sound_id){ 
 soundPool.play(sound_id, 1.0f, 1.0f, 10, 0, 1.0f);
 }
 public void daneZczujnikaX(int x){
 
 if (x!=0) {
 this.playsound(ID_bzyk);
 
 }
 sprite.setMoveX(-x);
 }
 
 public void daneZczujnikaY(int y){
 if (y!=0) {
 this.playsound(ID_bzyk);
 
 }
 sprite.setMoveY(y);
 }
}
public void onAccuracyChanged(Sensor czujnik, int dokladnosc) {
 // Do zrobienia: automatycznie wygenerowany zalążek metody
 }
public void onSensorChanged(SensorEvent zdarzenie) {

 
 for (int i = 0; i < zdarzenie.values.length; i++) {             

 
 if(i==0){

 x = (int)zdarzenie.values[i];
 mGameView.daneZczujnikaX(x);
 
 }
 if(i==1){

 y = (int)zdarzenie.values[i];
 mGameView.daneZczujnikaY(y);
 }
 if(i==2){}//os z
 
 }
 
 }
@Override
public boolean onCreateOptionsMenu(Menu menu) {
 // Inflate the menu; this adds items to the action bar if it is present.
 getMenuInflater().inflate(R.menu.main, menu);
 return true;
}

 @Override
 public boolean onOptionsItemSelected(MenuItem element) {
 switch (element.getItemId()) {
 case R.id.action_settings:
 startActivity(new Intent(this, MenuPrzycisk.class));
 
 return true;
 // Wstawiamy tutaj pozostałe elementy (jeśli jakieś będą) ...
 }
 return false;
 }
@Override
protected void onResume() {
 super.onResume();
 Muzyka.play(this, R.raw.background_music);
 menedzer.registerListener(this, czujnik, SensorManager.SENSOR_DELAY_GAME);
 
}
@Override
protected void onPause() {
 super.onPause();
 Muzyka.stop(this);
 
 menedzer.unregisterListener(this);
}
}

Gdy naciśniemy przycisk menu, to zostaje wywołana klasa MenuPrzycisk

MenuPrzycisk.java wygląda tak:

package pl.nstrefa.avrkwiat.gra1;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.preference.PreferenceManager;

public class MenuPrzycisk extends PreferenceActivity {
 private static final String OPCJA_TEKST = "key_muzyka" ;
 private static boolean OPCJA_TEKST_STRING = true;
 

 /** Called when the activity is first created. */
 @Override
 public void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 addPreferencesFromResource(R.xml.ustawienia);
 // TODO Auto-generated method stub
 }
 public static boolean wezEditTekst(Context kontekst) {
 
 return PreferenceManager.getDefaultSharedPreferences(kontekst).getBoolean(OPCJA_TEKST, OPCJA_TEKST_STRING);
 }
}

Ta klasa ma za zadanie wyświetlić menu i za pomocą metody wezEditText() odebrać wartości boolean z checkBoxa. Ta wartość odpowiedzialna jest za załączanie muzyki. Można to zobaczyć w klasie Muzyka.

Muzyka.java wygląda tak:

package pl.nstrefa.avrkwiat.gra1;

import android.content.Context;
import android.media.MediaPlayer;

public class Muzyka {
 private static MediaPlayer mp = null;


 public static void play(Context kontekst, int zasob) {
 stop(kontekst);

 
 if (MenuPrzycisk.wezEditTekst(kontekst)) {
 mp = MediaPlayer.create(kontekst, zasob);
 mp.setLooping(true);
 mp.start();
 }
 }

 public static void stop(Context kontekst) {
 if (mp != null) {
 mp.stop();
 mp.release();
 mp = null;
 }
 }
}

Cały projekt można pobrać klikając tu