IT/Oracle Database

Beginning Android 4 Games Development 정리

하품하는천둥 2020. 10. 9. 12:04

 

 

채우기 콘텐츠 - 주의

 

소스 코드

beginning-android-games-2nd-edition (2).vol1.egg

beginning-android-games-2nd-edition (2).vol2.egg

 

 

기본 구조

 

Screen이 Game을 연관

AndroidGame이 Screen을 연관

 

AndroidGame 생성 이후 Screen이 생성

 

 

Listing 3–1. The Input Interface and the KeyEvent and TouchEvent Classes

 

package com.badlogic.androidgames.framework;

 

import java.util.List;

 

public interface Input {

 

public static class KeyEvent {

 

public static final int KEY_DOWN = 0;
public static final int KEY_UP = 1;
public int type;
public int keyCode;
public char keyChar;

 

}

 

public static class TouchEvent {

 

public static final int TOUCH_DOWN = 0;
public static final int TOUCH_UP = 1;
public static final int TOUCH_DRAGGED = 2;
public int type;
public int x, y;
public int pointer;

 

}

 

public boolean isKeyPressed(int keyCode);
public boolean isTouchDown(int pointer);
public int getTouchX(int pointer);
public int getTouchY(int pointer);
public float getAccelX();
public float getAccelY()

public float getAccelZ();
public List<KeyEvent> getKeyEvents();
public List<TouchEvent> getTouchEvents();

 

}

 

Listing 3–3. The Audio Interface

 

package com.badlogic.androidgames.framework;

 

public interface Audio {

 

public Music newMusic(String filename);
public Sound newSound(String filename);

 

}

 

Listing 3–4. The Music Interface

 

package com.badlogic.androidgames.framework;

 

public interface Music {

 

public void play();
public void stop();
public void pause();
public void setLooping(boolean looping);
public void setVolume(float volume);
public boolean isPlaying();
public boolean isStopped();
public boolean isLooping();
public void dispose();

 

}

 

Listing 3–5. The Sound Interface

 

package com.badlogic.androidgames.framework;

 

public interface Sound {
    public void play(float volume);
    ,,,
    public void dispose();

 

}

 

Listing 3–6. The Graphics Interface

 

package com.badlogic.androidgames.framework;

 

public interface Graphics {

 

public static enum PixmapFormat {
ARGB8888, ARGB4444, RGB565
}

 

public Pixmap newPixmap(String fileName, PixmapFormat format);
public void clear(int color);
public void drawPixel(int x, int y, int color);
public void drawLine(int x, int y, int x2, int y2, int color);
public void drawRect(int x, int y, int width, int height, int color);
public void drawPixmap(Pixmap pixmap, int x, int y, int srcX, int srcY,
    int srcWidth, int srcHeight);
public void drawPixmap(Pixmap pixmap, int x, int y);
public int getWidth();
public int getHeight();

 

}

 

Listing 3–7. The Pixmap Interface

 

package com.badlogic.androidgames.framework;

 

import com.badlogic.androidgames.framework.Graphics.PixmapFormat;

 

public interface Pixmap {

 

public int getWidth();
public int getHeight();
public PixmapFormat getFormat();
public void dispose();

 

}

 

Listing 3–6. The Graphics Interface

package com.badlogic.androidgames.framework;

 

public interface Graphics {

 

public static enum PixmapFormat {
    ARGB8888, ARGB4444, RGB565
}

 

public Pixmap newPixmap(String fileName, PixmapFormat format);
public void clear(int color);
public void drawPixel(int x, int y, int color);
public void drawLine(int x, int y, int x2, int y2, int color);
public void drawRect(int x, int y, int width, int height, int color);
public void drawPixmap(Pixmap pixmap, int x, int y, int srcX, int srcY,
    int srcWidth, int srcHeight);
public void drawPixmap(Pixmap pixmap, int x, int y);
public int getWidth();
public int getHeight();

 

}

 

 

Listing 3–7. The Pixmap Interface

 

package com.badlogic.androidgames.framework;

 

import com.badlogic.androidgames.framework.Graphics.PixmapFormat;

 

public interface Pixmap {

 

public int getWidth();

public int getHeight();
public PixmapFormat getFormat();
public void dispose();

 

}

 

 

 

The Game Framework

pseudocode

createWindowAndUIComponent();

 

Input input = new Input();
Graphics graphics = new Graphics();
Audio audio = new Audio();
Screen currentScreen = new MainMenu();

 

Float lastFrameTime = currentTime();

 

while( !userQuit() ) {

 

float deltaTime = currentTime() – lastFrameTime;
lastFrameTime = currentTime();
currentScreen.updateState(input, deltaTime);
currentScreen.present(graphics, audio, deltaTime);

 

}

 

cleanupResources();

 

Listing 3–8. The Game Interface

package com.badlogic.androidgames.framework;

 

public interface Game {

 

public Input getInput();
public FileIO getFileIO();
public Graphics getGraphics();
public Audio getAudio();
public void setScreen(Screen screen);

public Screen getCurrentScreen();
public Screen getStartScreen();

 

}

 

Listing 3–9. The Screen Class

 

package com.badlogic.androidgames.framework;

 

public abstract class Screen {

 

protected final Game game;

 

public Screen(Game game) {
    this.game = game;
}

 

public abstract void update(float deltaTime);
public abstract void present(float deltaTime);
public abstract void pause();
public abstract void resume();
public abstract void dispose();

 

}

 

 

A Simple Example

public class MySuperAwesomeStartScreen extends Screen {

 

Pixmap awesomePic;
int x;

 

public MySuperAwesomeStartScreen(Game game) {
    super(game);
    awesomePic = game.getGraphics().newPixmap("data/pic.png",
    PixmapFormat.RGB565);
}

 

@Override
public void update(float deltaTime) {
    x += 1;
    if (x > 100)
    x = 0;
}

 

@Override
public void present(float deltaTime) {
    game.getGraphics().clear(0);
    game.getGraphics().drawPixmap(awesomePic, x, 0, 0, 0,
        awesomePic.getWidth(), awesomePic.getHeight());
}

 

@Override
public void pause() {
    // nothing to do here
}

 

@Override
public void resume() {
    // nothing to do here
}

 

@Override
public void dispose() {
    awesomePic.dispose();
}

 

}


 

 

Frame Rate–Independent Movement

Instead of moving our Pixmap (or Mario) by a fixed amount each frame, we specify the movement speed in
units per second.

Say we want our Pixmap to advance 50 pixels per second.

 

@Override
public void update(float deltaTime) {
x += 50 * deltaTime;
if(x > 100)
x = 0;
}

 

 


Chapter 4
Android for Game Developers

Here’s the final AndroidManifest.xml content

 

<?xml version="1.0" encoding="utf-8"?>

package="com.badlogic.awesomegame"
android:versionCode="1"
android:versionName="1.0"
android:installLocation="preferExternal">
<application android:icon="@drawable/icon"
android:label="Awesomnium"
android:debuggable="true">
<activity android:name=".GameActivity"
android:label="Awesomnium"
android:screenOrientation="landscape"
android:configChanges="keyboard|keyboardHidden|orientation">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-sdk android:minSdkVersion="3" android:targetSdkVersion="9"/>
</manifest>

 

 

Listing 4–1.AndroidBasicsStarter.java, Our Main Activity Responsible for Listing and Starting All Our Tests

 

package com.badlogic.androidgames;

 

import android.app.ListActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;

import android.widget.ArrayAdapter;
import android.widget.ListView;

 

public class AndroidBasicsStarter extends ListActivity {

 

String tests[] = { "LifeCycleTest", "SingleTouchTest", "MultiTouchTest",
    "KeyTest", "AccelerometerTest", "AssetsTest",
    "ExternalStorageTest", "SoundPoolTest", "MediaPlayerTest",
    "FullScreenTest", "RenderViewTest", "ShapeTest", "BitmapTest",
    "FontTest", "SurfaceViewTest" };

 

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setListAdapter(new ArrayAdapter<String>(this,
        android.R.layout.simple_list_item_1, tests));
}

 

@Override
protected void onListItemClick(ListView list, View view, int position,
        long id) {

 

    super.onListItemClick(list, view, position, id);
    String testName = tests[position];

 

    try {
        Class clazz = Class.forName("com.badlogic.androidgames." + testName);
        Intent intent = new Intent(this, clazz);
        startActivity(intent);
    } catch (ClassNotFoundException e) {
        e.printStackTrace();

    }

 

}

 

}

 

 

 

Processing Key Events

Listing 4–5.KeyTest.Java; Testing the Key Event API

 

package com.badlogic.androidgames;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnKeyListener;
import android.widget.TextView;

 

public class KeyTest extends Activity implements OnKeyListener {

 

StringBuilder builder = new StringBuilder();
TextView textView;

 

public void onCreate(Bundle savedInstanceState) {

 

super.onCreate(savedInstanceState);
textView = new TextView(this);
textView.setText("Press keys (if you have some)!");
textView.setOnKeyListener(this);
textView.setFocusableInTouchMode(true);
textView.requestFocus();
setContentView(textView);

 

}

 

@Override
public boolean onKey(View view, int keyCode, KeyEvent event) {
    builder.setLength(0);
    switch (event.getAction()) {
        case KeyEvent.ACTION_DOWN:
        builder.append("down, ");
        break;
        case KeyEvent.ACTION_UP:
        builder.append("up, ");
        break;

   }

 

builder.append(event.getKeyCode());
builder.append(", ");
builder.append((char) event.getUnicodeChar());
String text = builder.toString();
Log.d("KeyTest", text);
textView.setText(text);

 

if (event.getKeyCode() == KeyEvent.KEYCODE_BACK)
    return false;
else
    return true;
}

 

}

 

 

 

Chapter 7
An Android Game Development Framework

 

Listing 5–1. AndroidFileIO.java; Implementing the FileIO Interface

 

package com.badlogic.androidgames.framework.impl;

 

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.AssetManager;
import android.os.Environment;
import android.preference.PreferenceManager;
import com.badlogic.androidgames.framework.FileIO;

 

public class AndroidFileIO implements FileIO {

 

Context context;
AssetManager assets;
String externalStoragePath;
public AndroidFileIO(Context context) {
this.context = context;
this.assets = context.getAssets();
this.externalStoragePath = Environment.getExternalStorageDirectory()
.getAbsolutePath() + File.separator;
}
@Override
public InputStream readAsset(String fileName) throws IOException {
return assets.open(fileName);
}
@Override
public InputStream readFile(String fileName) throws IOException {
return new FileInputStream(externalStoragePath + fileName);
}

@Override
public OutputStream writeFile(String fileName) throws IOException {
return new FileOutputStream(externalStoragePath + fileName);
}
public SharedPreferences getPreferences() {
return PreferenceManager.getDefaultSharedPreferences(context);
}

 

}

 

 

Listing 5–2. AndroidAudio.java; Implementing the Audio Interface

 

package com.badlogic.androidgames.framework.impl;

 

import java.io.IOException;
import android.app.Activity;
import android.content.res.AssetFileDescriptor;
import android.content.res.AssetManager;
import android.media.AudioManager;
import android.media.SoundPool;
import com.badlogic.androidgames.framework.Audio;
import com.badlogic.androidgames.framework.Music;
import com.badlogic.androidgames.framework.Sound;

 

public class AndroidAudio implements Audio {

 

AssetManager assets;
SoundPool soundPool;

 

public AndroidAudio(Activity activity) {
    activity.setVolumeControlStream(AudioManager.STREAM_MUSIC);
    this.assets = activity.getAssets();
    this.soundPool = new SoundPool(20, AudioManager.STREAM_MUSIC, 0);
}

 

@Override
public Music newMusic(String filename) {
    try {
        AssetFileDescriptor assetDescriptor = assets.openFd(filename);
        return new AndroidMusic(assetDescriptor);
    } catch (IOException e) {
       throw new RuntimeException("Couldn't load music '" + filename + "'");
    }
}

 

@Override
public Sound newSound(String filename) {
    try {
        AssetFileDescriptor assetDescriptor = assets.openFd(filename);
        int soundId = soundPool.load(assetDescriptor, 0);
        return new AndroidSound(soundPool, soundId);
    } catch (IOException e) {
        throw new RuntimeException("Couldn't load sound '" + filename + "'");
}    

 

}

 

 

Listing 5–3. Implementing the Sound Interface using AndroidSound.java.

 

package com.badlogic.androidgames.framework.impl;
import android.media.SoundPool;
import com.badlogic.androidgames.framework.Sound;
public class AndroidSound implements Sound {
int soundId;
SoundPool soundPool;
public AndroidSound(SoundPool soundPool, int soundId) {
this.soundId = soundId;
this.soundPool = soundPool;
}
@Override
public void play(float volume) {
soundPool.play(soundId, volume, volume, 0, 0, 1);
}
@Override
public void dispose() {
soundPool.unload(soundId);
}
}

 

 

Listing 5–4. AndroidMusic.java; Implementing the Music Interface

 

package com.badlogic.androidgames.framework.impl;
import android.content.res.AssetFileDescriptor;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import com.badlogic.androidgames.framework.Music;
public class AndroidMusic implements Music, OnCompletionListener {
MediaPlayer mediaPlayer;
boolean isPrepared = false;

public AndroidMusic(AssetFileDescriptor assetDescriptor) {
mediaPlayer = new MediaPlayer();
try {
mediaPlayer.setDataSource(assetDescriptor.getFileDescriptor(),
assetDescriptor.getStartOffset(),
assetDescriptor.getLength());
mediaPlayer.prepare();
isPrepared = true;
mediaPlayer.setOnCompletionListener(this);
} catch (Exception e) {
throw new RuntimeException("Couldn't load music");
}
}

@Override
public void dispose() {
if (mediaPlayer.isPlaying())
mediaPlayer.stop();
mediaPlayer.release();
}

@Override

public boolean isLooping() {
return mediaPlayer.isLooping();
}
@Override
public boolean isPlaying() {
return mediaPlayer.isPlaying();
}
@Override
public boolean isStopped() {
return !isPrepared;
}

@Override
public void pause() {
if (mediaPlayer.isPlaying())
mediaPlayer.pause();
}

@Override
public void play() {
if (mediaPlayer.isPlaying())
return;
try {
synchronized (this) {
if (!isPrepared)
mediaPlayer.prepare();
mediaPlayer.start();
}
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}

@Override
public void setLooping(boolean isLooping) {

mediaPlayer.setLooping(isLooping);
}
@Override
public void setVolume(float volume) {
mediaPlayer.setVolume(volume, volume);
}

@Override
public void stop() {
mediaPlayer.stop();
synchronized (this) {
isPrepared = false;
}
}

@Override
public void onCompletion(MediaPlayer player) {
synchronized (this) {
isPrepared = false;
}
}
}