Beruflich Dokumente
Kultur Dokumente
1
LEFT/RIGHT command when moving in gone. The same button is named as Restart
RIGHT/LEFT directions. when a game is over and is used to restart the
game. Another button placed at the top right
2. Proximity sensor corner of the screen is used to pause or resume
Proximity sensor can detect the presence of an the game. It is visible only when the game is
object near it. A simple proximity sensor gives started or restarted. Whenever the game is
the reading “NEAR” of “FAR”. We implement paused, the button’s text field is changed to
this functionality to alternatively resume and vice versa.
PAUSE/RESUME the game. So just a hand
wave over the phone would pause the game and
another wave would resume the game.
2
class extends a public android class, Surface interface to the actual surface upon which our
view and implements two android public graphics will be drawn. It holds all of the draw
interface SurfaceHolder.Callback and calls. Canvas defines what to draw on the
SensorEventListener. Surface View provides a surface. On the other hand, Paint defines the
dedicated drawing surface embedded inside a features that the drawing will have. Features
view hierarchy. The purpose of this class is to may include shape, color etc. Using Canvas,
provide a surface in which a secondary thread actually all of the drawings are performed upon
can render into the screen. an underlying Bitmap, which is placed into the
particular positions within the window. In this
5. Drawing mechanism app we have three drawable objects- snake
For the graphical design of our game we used body, game boundary and food that the snake
some android class such as Canvas and Paint tries to catch in order to increase. We used a
which made it easy for us. Canvas works as an tile block image as the bitmap for our game
interface to the actual surface upon which our drawings. The same tile image is used to draw
graphics will be drawn. It holds all of the draw all of the three drawable objects of the game.
calls. Canvas defines what to draw on the Canvas provides a method named drawBitmap
surface. On the other hand, Paint defines the that facilitates the drawing of the tiles into
features that the drawing will have. Features specified position on the screen. Android
may include shape, color etc. Using Canvas, defines this method as public void drawBitmap
actually all of the drawings are performed upon (Bitmap bitmap, float left, float top, Paint
an underlying Bitmap, which is placed into the paint).
particular positions within the window. In this
app we have three drawable objects- snake
body, game boundary and food that the snake
tries to catch in order to increase. We used a
tile block image as the bitmap for our game
drawings. The same tile image is used to draw
all of the three drawable objects of the game.
Canvas provides a method named draw Bitmap
that facilitates the drawing of the tiles into
specified position on the screen. Android
defines this method as public void drawBitmap
(Bitmap bitmap, float left, float top, Paint
paint). Parameters bitmap takes the bitmap to
be drawn which is the tiles image in our app.
Parameters left and top specifies the origin of
the drawable tiles as its top left corner. Three
individual paint objects were declared for the
three drawable elements. These objects are
painted with different colors to distinguish from
each other. Among the three drawable
elements, only the game boundary is static and
the other two- snake body and foods are
changed dynamically with the game flow. To
draw these elements, we stored all the
coordinates of the individual drawables into
separate arrays. These arrays serially keep the x
coordinates and y coordinates of the top left
corner of all of the tiles used for drawing.
5. Drawing mechanism:
For the graphical design of our game we used Figure 2: App layout at different phase of the
some android class such as Canvas and Paint game. (a) App launched (b) game paused (c)
which made it easy for us. Canvas works as an game resumed (d) game over
3
Parameters bitmap takes the bitmap to be drawn changes in accelerometer readings are filtered
which is the tiles image in our app. Parameters out. To be compatible with a natural snake
left and top specifies the origin of the drawable movement in the game, a 1800 movement is not
tiles as its top left corner. Three individual paint allowed. So we ignore a UP or DOWN
objects were declared for the three drawable command when the snake is moving in either
elements. These objects are painted with DOWN or UP direction and LEFT or RIGHT
different colors to distinguish from each other. command when moving in RIGHT or LEFT
Among the three drawable elements, only the directions correspondingly.
game boundary is static and the other two-
snake body and foods are changed dynamically
with the game flow. To draw these elements,
we stored all the coordinates of the individual
drawables into separate arrays. These arrays
serially keep the x coordinates and y
coordinates of the top left corner of all of the
tiles used for drawing.
B. Reading and converting accelerometer data
4
dir = 0; //right
}
}
else if(event.values[0]-XX>THRES_ACCL){
if(dir!=0) {
dir = 2; //left
}
}
else if(YY-event.values[1]>THRES_ACCL){
if(dir!=3){
dir = 1; //top
}
}
else if(event.values[1]-YY>THRES_ACCL){
if(dir!=1){
dir = 3; //bottom
}
}
XX = event.values[0];
YY = event.values[1];
ZZ = event.values[2]; Figure 4: Location of proximity sensor on a
} smartphone
5
the MotionEvent class to detect sliding which detects different condition of the game
movements on the left, right, top or bottom and take necessary decisions accordingly.
directions. When a user touches the screen,
onTouchEvent() method is called and the 1. Check Collision
corresponding touch action can be read from At every instant of timing schedule game
the MotionEvent class. For our application, we engine checks if there is any collision happened
ignored all other types of touch events. between snake body and any other drawable
So we collect the directional readings and as components including snake body. If collision
usual ignore the 1800 movement. The code with game boundary is detected, snake body
segment for the this part is something like this: comes out of the other end of the boundary. If
snake collides with itself i.e any part of its body
/* inside onTouchEvent method*/ then game with will be over and final score will
if (event.getAction() == be shown. If snake collides with the food its
MotionEvent.ACTION_DOWN) { length increases and scores increase.
initX = event.getX();
initY = event.getY(); 2. Timer scheduling
The game speed is defined by a timer that may
}
be updated on certain occasions. If snake passes
double totY = Math.abs(Math.abs(finalY) -
a level its timer is scheduled with a new value
Math.abs(initY));
which is proportional to that level. If game is
double totX = Math.abs(Math.abs(finalX) -
paused the timer is cancelled and it is
Math.abs(initX));
rescheduled when the game is resumed.
if (event.getAction() ==
MotionEvent.ACTION_MOVE) { 3. Snake Move
finalX = event.getX();
finalY = event.getY(); When there is no collision, pause or user input
totY = Math.abs(Math.abs(finalY) - found, the snake should moves ahead in its
Math.abs(initY)); previous direction. If snake is moving
totX = Math.abs(Math.abs(finalX) - horizontally and user selects up or down
Math.abs(initX)); direction snake will sanitized to the new
direction. In the same way when snake moves
float threshold = 20; //chosen based on vertically and user selects left or right direction
testing snake will head to the new direction. But user
if (totY > threshold || totX > threshold) { cannot redirect the snake just to the opposite
if (totX > totY) { direction such as left to right or vice versa and
if (finalX > initX) { up to down or vice versa.
engine.setDirection(1); 4. Random Food generation
} else if (finalX < initX) {
engine.setDirection(3); Every time snake eats a food, a new food is
} generated at a random location within snake
} else if (totY > totX) { boundary. Few bugs are possible if we do not
if (finalY > initY) { set some bound to this randomness. For proper
engine.setDirection(0); operation we have to make sure certain things.
} else if (finalY < initY) { Firstly, food should be within the game
engine.setDirection(2); boundary. Then, food should not be at the same
} place with the game boundary or snake body.
} We used some bounded random number
} generation technique to ensure these criteria for
} food generation.
6
F. Additional Improvement be different to generate different tones. Last
argument (500) is the duration of the tone
1. Adaptable Screen Size playback.*/
toneG.startTone(ToneGenerator.TONE_CDM
If we had developed our application on iOS, A_EMERGENCY_RINGBACK, 500);
we’d not need to worry about the screen size
much because there is only a limited number of
variations. But since there is a huge amount of The duration of the sound is very short for
variations among devices that run on android, snake movement and somewhat long when the
we needed to think of adaptable game boundary game is over.
that is configured programmatically based on
the screen size and resolution of the android G. Remote control using bluetooth
device. DisplayMetrics class provides the
screen-size of an android device. Our final and somewhat ambitious target was to
control and play the snake game from another
DisplayMetrics displayMetrics = new android device. For that purpose, we used
DisplayMetrics(); bluetooth communication. The interface or
activity for Bluetooth connection in our
displayMetrics = application looks like this:
context.getResources().getDisplayMetrics();
2. Sound generation
7
Intent enableBtIntent = new alist.add(tooth.getName()+"\n"+tooth.get
Intent(BluetoothAdapter.ACTION_REQUES Address());
T_ENABLE); }
startActivityForResult(enableBtIntent, }
1); //any integer greater than 0
} Step 3: Setup communication channel between
Intent getVisible = new the paired devices:
Intent(BluetoothAdapter.ACTION_REQUES The device with the controller app acts as a
T_DISCOVERABLE); server and the the device with the game acts as
getVisible.putExtra(BluetoothAdapter.EXTRA a client. A socket connection is established
_DISCOVERABLE_DURATION, 300); //for between these two devices using
300 seconds BluetoothSocket class library. BluetoothDevice
startActivityForResult(getVisible, 0); class represents the device connected.
public AcceptThread() {
BluetoothServerSocket tmp = null;
if(mBluetoothAdapter.startDiscovery()){ try {
pairedDeviceList = // MY_UUID is the app's UUID string, also
mBluetoothAdapter.getBondedDevices(); used by the client code
alist = new ArrayList(); tmp =
for(BluetoothDevice mBluetoothAdapter.listenUsingRfcommWith
tooth:pairedDeviceList){ ServiceRecord(NAME, MY_UUID);
8
} catch (IOException e) { } The value received on the main game
mmServerSocket = tmp; application is used for controlling the game.
} Since bluetooth is a very buggy and unstable
public void socketConnect() throws connection, we faced a lot of trouble in this part.
IOException { Therefore, we couldn’t exactly finish this part.
BluetoothSocket socket = null; Hopefully, using wifi or NFC connection would
// Keep listening until exception occurs or a solve this problem.
socket is returned
while (true) {
try {
socket = mmServerSocket.accept(); GAMEPLAY AND CONTROL
} catch (IOException e) { To play the game, a user has to move his
break; smartphone in any of the four directions or he
} or she can touch the screen and slide fingers
// If a connection was accepted along any direction. The snake will follow that
if (socket != null) { path. To pause or resume the game, he can just
break; wave his hand over the proximity sensor
} generally located at the top of an android phone
try { and the game will pause/resume. If the snake
mmServerSocket.close(); stumbles upon itself, the game is over. So the
} catch (IOException e) {} goal to keep the snake as long as possible and
} eat as much food as possible. The snake’s
length increases as it eats the food. The score is
Step 4: Sending data over bluetooth: updated and displayed live on the top of the
Whenever a valid control like a valid snake screen. Touching a boundary doesn’t kill it,
movement or pause or resume command is rather it pops out from the opposite direction of
obtained, the sendData() function is called from the screen. After some time, snake’s speed is
inside the onSensorChanged() method. also increased to make it more challenging,
Receiving data is an event triggered by the although there is an upper limit to keep it.
availability of some data over the socket.
ByteArrayOutputStream class is used for To play the game remotely from another
sending and receiving data using a buffer. android device, the player first need to setup the
bluetooth connection with the gaming device.
public void sendData(BluetoothSocket socket, We provide interface for this part too.
int data) throws IOException{
ByteArrayOutputStream output = new
ByteArrayOutputStream(4); CHALLENGES AND DISCUSSIONS
output.write(data); The main obstacle for our project was that we
OutputStream outputStream = didn’t have any previous experience on android
socket.getOutputStream(); or any type of app development. Limited
outputStream.write(output.toByteArray()); experience of object-oriented programming and
} XML also made us slow. So we had to start
from the very basic of android coding and had
public int receiveData(BluetoothSocket to work our way through our project. Because
socket) throws IOException{ the android IDE takes a lot of space and
byte[] buffer = new byte[4]; processor power, we couldn’t run it on our
ByteArrayInputStream input = new laptops (two of us even don’t have a laptop) and
ByteArrayInputStream(buffer); had to work on the school’s computer. This and
InputStream inputStream = being a group of all graduate students with
socket.getInputStream(); limited time made our progress slower than
inputStream.read(buffer); expected. However, still we managed to
return input.read(); complete our goals and now have a good
} platform for further improvement. We learned
a lot from this project and are very confident in
9
app and game development on android
platform.
FUTURE WORK
Since our project was to develop a game, there
may be a tons of different improvements
possible. We tried to incorporate many
additional features in our game like game
sound, variable screen size, buttons, multiple
color of snake’s body, multiple levels and
displaying live scores etc. Even though we can
add many things. One very important work is to
make the touch and orientation very smooth for
user’s ease. Much more testing and user
reviews are needed for this. We can also work
on the graphics and make it more like modern
games and more user-friendly. We can analyze
our coding more carefully for possible power
optimization, processing speedup and lower
memory footprint.
10