I have a dice game and I am trying to change the image of the Die that is selected after the dice are rolled to a "Dead Die" image. I have tried everything I can think of and I always end up finding the Value "0" in the Index or something else but never the correct Die.
When the dice is selected it sets it's value to a Negative Number. Example I select 6 it changes the value to -6 and changes the die to the -6 die image
How can I get it to display AND KEEP the "DEAD" image I want.
Here is the area where it gets the Images
//Get the Dice Images
public Integer getImage(int index) {
if (diceValues[index] == 0) {
return letterImages.get(index);
} else {
return diceImages.get((diceValues[index]));
}
}
I have tried changing
return letterImages.get(index);
to every possible combination of everything and when I do get it to change the image it always ends up at "0" or the the current number of dice selected or the some other number that I'm just not sure how it came up with.
Here is the entire DieManager class
package com.mygames.dice;
import java.util.HashMap;
import android.util.Log;
public class DieManager {
// Will return the Indexes of the dice when this is used
public static final int INDEX_FLAG = 1;
// Will return the values of the dice when this is used
public static final int VALUE_FLAG = 2;
// Will return the absolute values of the dice when this is used
public static final int ABS_VALUE_FLAG = 3;
// The array that holds the dice
private int[] diceValues = { 0, 0, 0, 0, 0, 0 };
private HashMap<Integer, Integer> diceImages = new HashMap<Integer, Integer>();
private HashMap<Integer, Integer> deadImages = new HashMap<Integer, Integer>();
private HashMap<Integer, Integer> letterImages = new HashMap<Integer, Integer>();
// Sets #newValue to dieValues[#index]
public void setValue(int index, int newValue) {
Log.w(getClass().getName(), "Index = " + index + " Value = " + newValue);
diceValues[index] = newValue;
}
public DieManager() {
super();
initializeMaps();
}
private void initializeMaps() {
diceImages.put(-6, R.drawable.die6_select);
diceImages.put(-5, R.drawable.die5_select);
diceImages.put(-4, R.drawable.die4_select);
diceImages.put(-3, R.drawable.die3_select);
diceImages.put(-2, R.drawable.die2_select);
diceImages.put(-1, R.drawable.die1_select);
diceImages.put(1, R.drawable.die1_roll);
diceImages.put(2, R.drawable.die2_roll);
diceImages.put(3, R.drawable.die3_roll);
diceImages.put(4, R.drawable.die4_roll);
diceImages.put(5, R.drawable.die5_roll);
diceImages.put(6, R.drawable.die6_roll);
deadImages.put(-1, R.drawable.die1_dead);
deadImages.put(-2, R.drawable.die2_dead);
deadImages.put(-3, R.drawable.die3_dead);
deadImages.put(-4, R.drawable.die4_dead);
deadImages.put(-5, R.drawable.die5_dead);
deadImages.put(-6, R.drawable.die6_dead);
letterImages.put(0, R.drawable.die_no);
letterImages.put(1, R.drawable.die_no);
letterImages.put(2, R.drawable.die_no);
letterImages.put(3, R.drawable.die_no);
letterImages.put(4, R.drawable.die_no);
letterImages.put(5, R.drawable.die_no);
}
public void rollDice() {
boolean isNewRound = (numOnTable() == 0);
for (int j = 0; j < 6; j++) {
// If its a new round then the dice value can be changed from 0.
// Else it can't
if (isNewRound || diceValues[j] != 0)
diceValues[j] = (int) ((Math.random() * 6) + 1);
}
}
// Returns the value or absolute value
public int getValue(int index, int flag) {
if (flag == ABS_VALUE_FLAG)
return Math.abs(diceValues[index]);
return diceValues[index];
}
// If a dice value is 0 then its a letter
public int numOnTable() {
int count = 6;
for (int i : diceValues) {
if (i == 0)
count--;
}
return count;
}
// Picking up makes the dice value 0
public void pickUp(int[] highlighted) {
for (int i = 0; i < highlighted.length; i++)
diceValues[highlighted[i]] = 0;
}
// A negative value means a die is highlighted
public void toggleHighlight(int index) {
diceValues[index] *= -1;
}
public void clearTable() {
diceValues[0] = 0;
diceValues[1] = 0;
diceValues[2] = 0;
diceValues[3] = 0;
diceValues[4] = 0;
diceValues[5] = 0;
}
// Return the dice that aren't 0
public int[] diceOnTable(int flag) {
if (flag == ABS_VALUE_FLAG) {
int[] array = new int[diceValues.length];
for (int i = 0; i < diceValues.length; i++)
array[i] = Math.abs(diceValues[i]);
return array;
}
return diceValues;
}
//Returns dice that are negative
public int[] getHighlighted(int flag) {
int[] dirtyArray = { 0, 0, 0, 0, 0, 0 };
int count = 0;
for (int j = 0; j < 6; j++) {
if (diceValues[j] < 0) {
if (flag == INDEX_FLAG)
dirtyArray[count++] = j;
if (flag == VALUE_FLAG)
dirtyArray[count++] = diceValues[j];
if (flag == ABS_VALUE_FLAG)
dirtyArray[count++] = Math.abs(diceValues[j]);
}
}
int[] cleanArray = new int[count];
//Returns an array of length 0
if (count == 0)
return cleanArray;
System.arraycopy(dirtyArray, 0, cleanArray, 0, count);
return cleanArray;
}
// Finds in dieValues same #value and excludes #index
public int[] findPairs(int index, int flag) {
int[] dirtyArray = { 0, 0, 0, 0, 0, 0 };
int count = 0;
for (int j = 0; j < 6; j++) {
if (j != index
&& Math.abs(diceValues[j]) == Math.abs(diceValues[index])) {
if (flag == INDEX_FLAG)
dirtyArray[count++] = j;
if (flag == VALUE_FLAG)
dirtyArray[count++] = diceValues[j];
if (flag == ABS_VALUE_FLAG)
dirtyArray[count++] = Math.abs(diceValues[j]);
}
}
int[] cleanArray = new int[count];
if (count == 0)
return cleanArray;
System.arraycopy(dirtyArray, 0, cleanArray, 0, count);
return cleanArray;
}
//Get the Dice Images
public Integer getImage(int index) {
if (diceValues[index] == 0) {
return letterImages.get(index);
} else {
return diceImages.get((diceValues[index]));
}
}
//Get the Number of dice remaining that are not 0
public int numDiceRemain() {
int counter = 0;
for (int j = 0; j < diceValues.length; j++) {
if (diceValues[j] > 0)
counter++;
}
return counter;
}
}
The dice value can never be zero on a roll because of the following line in your rollDice() method:
diceValues[j] = (int) ((Math.random() * 6) + 1);
And this seems logical to me. Why would the value on a die ever be zero?
Related
I am following Maze game tutorial from youtube Android Programming - Maze Game Pt4
The tutor's code in the video generates random mazes. I have followed the code to the 'T' throughout but my emulator only gives the following output -
My emulator's output
Here is my code. Can anyone tell me what i missed from the tutorial I was following or if the tutorial itself has some coding errors? -
public class MazaGame extends View {
private Cell[][] cells;
private static final int COLS = 7, ROWS = 10;
private static final float WALL_THICKNESS = 4;
private float cellSize,hMargin,vMargin;
private Paint wallPaint;
private Random random;
public MazaGame(Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
wallPaint = new Paint();
wallPaint.setColor(Color.BLACK);
wallPaint.setStrokeWidth(WALL_THICKNESS);
random = new Random();
createMaze();
}
private Cell getNeighbor(Cell cell){
ArrayList<Cell> neighbors = new ArrayList<>();
//left neighbor
if(cell.col >0)
if(!cells[cell.col-1][cell.row].visited)
neighbors.add(cells[cell.col-1][cell.row]);
//right neighbor
if(cell.col < COLS-1)
if(!cells[cell.col+1][cell.row].visited)
neighbors.add(cells[cell.col+1][cell.row]);
//top neighbor
if(cell.row >0)
if(!cells[cell.col][cell.row-1].visited)
neighbors.add(cells[cell.col][cell.row-1]);
//bottom neighbor
if(cell.row < ROWS-1)
if(!cells[cell.col][cell.row+1].visited)
neighbors.add(cells[cell.col][cell.row+1]);
if(neighbors.size()>0) {
int index = random.nextInt(neighbors.size());
return neighbors.get(index);
}
return null;
}
private void removeWall(Cell current, Cell next){
if(current.col == next.col && current.row == next.row+1){
current.topWall = false;
next.bottomWall = false;
}
if(current.col == next.col && current.row == next.row-1){
current.bottomWall = false;
next.topWall = false;
}
if(current.col == next.col+1 && current.row == next.row){
current.leftWall = false;
next.rightWall = false;
}
if(current.col == next.col-1 && current.row == next.row){
current.rightWall = false;
next.leftWall = false;
}
}
private void createMaze() {
Stack<Cell> stack = new Stack<>();
Cell current, next;
cells = new Cell[COLS][ROWS];
for (int x = 0; x < COLS; x++) {
for (int y = 0; y < ROWS; y++) {
cells[x][y] = new Cell(x, y);
}
}
do {
current = cells[0][0];
current.visited = true;
next = getNeighbor(current);
if (next != null) {
removeWall(current, next);
stack.push(current);
current = next;
current.visited = true;
} else
current = stack.pop();
}while (!stack.empty());
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.RED);
int width = getWidth();
int height = getHeight();
if(width/height < COLS/ROWS)
cellSize = width/(COLS+1);
else
cellSize = height/(ROWS+1);
hMargin = (width-COLS*cellSize)/2;
vMargin = (height-ROWS*cellSize)/2;
canvas.translate(hMargin,vMargin);
for(int x=0;x<COLS;x++){
for(int y=0;y<ROWS;y++){
if(cells[x][y].topWall)
canvas.drawLine(
x*cellSize,
y*cellSize,
(x+1)*cellSize,
y*cellSize,
wallPaint);
if(cells[x][y].leftWall)
canvas.drawLine(
x*cellSize,
y*cellSize,
x*cellSize,
(y+1)*cellSize,
wallPaint);
if(cells[x][y].bottomWall)
canvas.drawLine(
x*cellSize,
(y+1)*cellSize,
(x+1)*cellSize,
(y+1)*cellSize,
wallPaint);
if(cells[x][y].rightWall)
canvas.drawLine(
(x+1)*cellSize,
y*cellSize,
(x+1)*cellSize,
(y+1)*cellSize,
wallPaint);
}
}
}
private class Cell{
boolean
topWall = true,
rightWall = true,
bottomWall = true,
leftWall = true,
visited = false;
int col,row;
public Cell(int col, int row) {
this.col = col;
this.row = row;
}
}
}
I'm not going to take the time to fully internalize 100% of the code you posted, but this section looks suspicious:
do {
current = cells[0][0];
current.visited = true;
next = getNeighbor(current);
if (next != null) {
removeWall(current, next);
stack.push(current);
current = next;
current.visited = true;
} else
current = stack.pop();
}while (!stack.empty());
I suspect you want this to look like this instead:
current = cells[0][0];
current.visited = true;
do {
next = getNeighbor(current);
if (next != null) {
removeWall(current, next);
stack.push(current);
current = next;
current.visited = true;
} else
current = stack.pop();
}while (!stack.empty());
What you have right now will continuously reset current to be the cell at (0,0), because every time through the loop, you're executing
current = cells[0][0];
current.visited = true;
I suspect that this is just supposed to be the initial setup for the first cell, and you don't want this happening every time through the loop.
I want to generate n no of random no whose sum should be m and these no should always be between x and y.
For eg :- If i say I need 20 no, between 3 and 9 inclusive, whose sum should be 100.
I want to specify the sum and required amount of no as well as the limit between which random no should be generated and it should give me the random no of specified amount. Below is my code which do generates no which are greater than 2 but i am not able to put the max limit. Also, the sum which comes out and the sum of no. which it generates is not equal to specified sum. I am totally confused Please help me out.
TextView textView,randomTotaltxt;
int count0 = 0;
int count1 = 0;
int targetSum = 100;
int numberofDraws = 20;
textView = (TextView) findViewById(R.id.textview);
randomTotaltxt = (TextView) findViewById(R.id.randomTptalText);
Random r = new Random();
ArrayList<Integer> load = new ArrayList<>();
//random no
int sum = 0;
for (int i=0; i<numberofDraws;i++){
int next = r.nextInt(targetSum)+1;
Log.d("No",""+next);
load.add(next);
sum += next;
}
//scale it
double scale = 1d*targetSum/sum;
sum=0;
for (int i=0; i<numberofDraws;i++){
load.set(i, (int)(load.get(i)*scale));
sum += load.get(i);
}
while (load.contains(0)|| load.contains(1)){
for (int i=0; i<load.size();i++) {
if (load.get(i).equals(0)) {
load.set(i, load.get(i) + 2);
count0++;
sum = sum+1;
}
if (load.get(i).equals(1)) {
load.set(i, load.get(i) + 2);
sum += load.get(i);
count1++;
sum = sum+1;
}
}
}
// take rounding
while (sum++ <targetSum){
int i = r.nextInt(numberofDraws);
load.set(i, load.get(i) + 1);
}
textView.setText(""+load);
randomTotaltxt.setText(""+(sum-1));
This might not be the optimal solution but this will do your work as required.
int targetSum = 100;
int numberOfDraws = 20;
int uppr=0;
int countt =0;
ArrayList<Integer> load = new ArrayList<>();
Random random;
TextView textView1,randomTotaltxt1;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
textView1 = (TextView) findViewById(R.id.textview1);
randomTotaltxt1 = (TextView) findViewById(R.id.randomTptalText1);
random = new Random();
//random no
int sum = 0;
for (int i=0; i<numberOfDraws;i++){
int next = random.nextInt(targetSum)+1;
load.add(next);
sum += next;
}
//scale it
double scale = 1d*targetSum/sum;
sum=0;
for (int i=0; i<numberOfDraws;i++){
load.set(i, (int)(load.get(i)*scale));
sum += load.get(i);
}
// take rounding
while (sum++ <targetSum){
int i = random.nextInt(numberOfDraws);
load.set(i, load.get(i) + 1);
Log.d("TAG",""+load);
}
checkForUpperRange();
}
public void checkForUpperRange(){
for (int i=0; i<numberOfDraws;i++){
int n = load.get(i);
if (n > 9){
load.set(i, 9);
uppr = n - 9; // getting the required no.
adjustUpper();
break;
}
checkForLowerRange();
}
}
private void adjustUpper() {
for (int j=0; j<numberOfDraws;j++){
if (load.get(j) > 2){
load.set(j, load.get(j)+uppr); // uppr is added
checkForUpperRange();
break;
}
}
}
public void checkForLowerRange(){
for (int i=0; i<numberOfDraws;i++){
int n = load.get(i);
if (n == 0){
load.set(i, load.get(i)+3); // 3 is added in sum
adjust0();
break;
}
if (n == 1){
load.set(i, load.get(i)+2); // 2 is added in sum
adjust1();
break;
}
if (n == 2){
load.set(i, load.get(i)+1); // 1 is added in sum
adjust2();
break;
}
getCount();
}
}
public void getCount(){
countt = 0;
for (int k=0; k<numberOfDraws;k++){
countt = countt+ load.get(k);
showResult();
}
}
public void showResult(){
textView1.setText(""+load);
randomTotaltxt1.setText(""+countt);
}
public void adjust0(){
for (int j=0; j<numberOfDraws;j++){
if (load.get(j) > 3){
load.set(j, load.get(j)-3); // 3 is subtracted
checkForLowerRange();
break;
}
}
}
public void adjust1(){
for (int j=0; j<numberOfDraws;j++){
if (load.get(j) > 3){
load.set(j, load.get(j)-2); // 2 is subtracted
checkForLowerRange();
break;
}
}
}
public void adjust2(){
for (int j=0; j<numberOfDraws;j++){
if (load.get(j) > 3){
load.set(j, load.get(j)-1); // 1 is subtracted
checkForLowerRange();
break;
}
}
}
I want to play gif file in android on imageview. I used this link http://droid-blog.net/2011/10/14/tutorial-how-to-use-animated-gifs-in-android-part-1/ . This works fine but when I am using two buttons and I am swaping the gif images continuously app crashed after sometime..
This is my code
public class GifDecoder {
public static final int STATUS_OK = 0;
public static final int STATUS_FORMAT_ERROR = 1;
/**
* File read status: Unable to open source.
*/
public static final int STATUS_OPEN_ERROR = 2;
/** max decoder pixel stack size */
protected static final int MAX_STACK_SIZE = 4096;
protected InputStream in;
protected int status;
protected int width; // full image width
protected int height; // full image height
protected boolean gctFlag; // global color table used
protected int gctSize; // size of global color table
protected int loopCount = 1; // iterations; 0 = repeat forever
protected int[] gct; // global color table
protected int[] lct; // local color table
protected int[] act; // active color table
protected int bgIndex; // background color index
protected int bgColor; // background color
protected int lastBgColor; // previous bg color
protected int pixelAspect; // pixel aspect ratio
protected boolean lctFlag; // local color table flag
protected boolean interlace; // interlace flag
protected int lctSize; // local color table size
protected int ix, iy, iw, ih; // current image rectangle
protected int lrx, lry, lrw, lrh;
protected Bitmap image; // current frame
protected Bitmap lastBitmap; // previous frame
protected byte[] block = new byte[256]; // current data block
protected int blockSize = 0; // block size last graphic control extension info
protected int dispose = 0; // 0=no action; 1=leave in place; 2=restore to bg; 3=restore to prev
protected int lastDispose = 0;
protected boolean transparency = false; // use transparent color
protected int delay = 0; // delay in milliseconds
protected int transIndex; // transparent color index
// LZW decoder working arrays
protected short[] prefix;
protected byte[] suffix;
protected byte[] pixelStack;
protected byte[] pixels;
protected Vector<GifFrame> frames; // frames read from current file
protected int frameCount;
private static class GifFrame {
public GifFrame(Bitmap im, int del) {
image = im;
delay = del;
}
public Bitmap image;
public int delay;
}
/**
* Gets display duration for specified frame.
*
* #param n
* int index of frame
* #return delay in milliseconds
*/
public int getDelay(int n) {
delay = -1;
if ((n >= 0) && (n < frameCount)) {
delay = frames.elementAt(n).delay;
}
return delay;
}
/**
* Gets the number of frames read from file.
*
* #return frame count
*/
public int getFrameCount() {
return frameCount;
}
public Bitmap getBitmap() {
return getFrame(0);
}
public int getLoopCount() {
return loopCount;
}
protected void setPixels() {
// expose destination image's pixels as int array
int[] dest = new int[width * height];
// fill in starting image contents based on last image's dispose code
if (lastDispose > 0) {
if (lastDispose == 3) {
// use image before last
int n = frameCount - 2;
if (n > 0) {
lastBitmap = getFrame(n - 1);
} else {
lastBitmap = null;
}
}
if (lastBitmap != null) {
lastBitmap.getPixels(dest, 0, width, 0, 0, width, height);
// copy pixels
if (lastDispose == 2) {
// fill last image rect area with background color
int c = 0;
if (!transparency) {
c = lastBgColor;
}
for (int i = 0; i < lrh; i++) {
int n1 = (lry + i) * width + lrx;
int n2 = n1 + lrw;
for (int k = n1; k < n2; k++) {
dest[k] = c;
}
}
}
}
}
// copy each source line to the appropriate place in the destination
int pass = 1;
int inc = 8;
int iline = 0;
for (int i = 0; i < ih; i++) {
int line = i;
if (interlace) {
if (iline >= ih) {
pass++;
switch (pass) {
case 2:
iline = 4;
break;
case 3:
iline = 2;
inc = 4;
break;
case 4:
iline = 1;
inc = 2;
break;
default:
break;
}
}
line = iline;
iline += inc;
}
line += iy;
if (line < height) {
int k = line * width;
int dx = k + ix; // start of line in dest
int dlim = dx + iw; // end of dest line
if ((k + width) < dlim) {
dlim = k + width; // past dest edge
}
int sx = i * iw; // start of line in source
while (dx < dlim) {
// map color and insert in destination
int index = ((int) pixels[sx++]) & 0xff;
int c = act[index];
if (c != 0) {
dest[dx] = c;
}
dx++;
}
}
}
image = Bitmap.createBitmap(dest, width, height, Config.ARGB_4444);
}
public Bitmap getFrame(int n) {
if (frameCount <= 0)
return null;
n = n % frameCount;
return ((GifFrame) frames.elementAt(n)).image;
}
public int read(InputStream is) {
init();
if (is != null) {
in = is;
readHeader();
if (!err()) {
readContents();
if (frameCount < 0) {
status = STATUS_FORMAT_ERROR;
}
}
} else {
status = STATUS_OPEN_ERROR;
}
try {
is.close();
} catch (Exception e) {
}
return status;
}
protected void decodeBitmapData() {
int nullCode = -1;
int npix = iw * ih;
int available, clear, code_mask, code_size, end_of_information, in_code, old_code, bits, code, count, i, datum, data_size, first, top, bi, pi;
if ((pixels == null) || (pixels.length < npix)) {
pixels = new byte[npix]; // allocate new pixel array
}
if (prefix == null) {
prefix = new short[MAX_STACK_SIZE];
}
if (suffix == null) {
suffix = new byte[MAX_STACK_SIZE];
}
if (pixelStack == null) {
pixelStack = new byte[MAX_STACK_SIZE + 1];
}
// Initialize GIF data stream decoder.
data_size = read();
clear = 1 << data_size;
end_of_information = clear + 1;
available = clear + 2;
old_code = nullCode;
code_size = data_size + 1;
code_mask = (1 << code_size) - 1;
for (code = 0; code < clear; code++) {
prefix[code] = 0; // XXX ArrayIndexOutOfBoundsException
suffix[code] = (byte) code;
}
// Decode GIF pixel stream.
datum = bits = count = first = top = pi = bi = 0;
for (i = 0; i < npix;) {
if (top == 0) {
if (bits < code_size) {
// Load bytes until there are enough bits for a code.
if (count == 0) {
// Read a new data block.
count = readBlock();
if (count <= 0) {
break;
}
bi = 0;
}
datum += (((int) block[bi]) & 0xff) << bits;
bits += 8;
bi++;
count--;
continue;
}
// Get the next code.
code = datum & code_mask;
datum >>= code_size;
bits -= code_size;
// Interpret the code
if ((code > available) || (code == end_of_information)) {
break;
}
if (code == clear) {
// Reset decoder.
code_size = data_size + 1;
code_mask = (1 << code_size) - 1;
available = clear + 2;
old_code = nullCode;
continue;
}
if (old_code == nullCode) {
pixelStack[top++] = suffix[code];
old_code = code;
first = code;
continue;
}
in_code = code;
if (code == available) {
pixelStack[top++] = (byte) first;
code = old_code;
}
while (code > clear) {
pixelStack[top++] = suffix[code];
code = prefix[code];
}
first = ((int) suffix[code]) & 0xff;
// Add a new string to the string table,
if (available >= MAX_STACK_SIZE) {
break;
}
pixelStack[top++] = (byte) first;
prefix[available] = (short) old_code;
suffix[available] = (byte) first;
available++;
if (((available & code_mask) == 0) && (available < MAX_STACK_SIZE)) {
code_size++;
code_mask += available;
}
old_code = in_code;
}
// Pop a pixel off the pixel stack.
top--;
pixels[pi++] = pixelStack[top];
i++;
}
for (i = pi; i < npix; i++) {
pixels[i] = 0; // clear missing pixels
}
}
protected boolean err() {
return status != STATUS_OK;
}
protected void init() {
status = STATUS_OK;
frameCount = 0;
frames = new Vector<GifFrame>();
gct = null;
lct = null;
}
protected int read() {
int curByte = 0;
try {
curByte = in.read();
} catch (Exception e) {
status = STATUS_FORMAT_ERROR;
}
return curByte;
}
protected int readBlock() {
blockSize = read();
int n = 0;
if (blockSize > 0) {
try {
int count = 0;
while (n < blockSize) {
count = in.read(block, n, blockSize - n);
if (count == -1) {
break;
}
n += count;
}
} catch (Exception e) {
e.printStackTrace();
}
if (n < blockSize) {
status = STATUS_FORMAT_ERROR;
}
}
return n;
}
protected int[] readColorTable(int ncolors) {
int nbytes = 3 * ncolors;
int[] tab = null;
byte[] c = new byte[nbytes];
int n = 0;
try {
n = in.read(c);
} catch (Exception e) {
e.printStackTrace();
}
if (n < nbytes) {
status = STATUS_FORMAT_ERROR;
} else {
tab = new int[256]; // max size to avoid bounds checks
int i = 0;
int j = 0;
while (i < ncolors) {
int r = ((int) c[j++]) & 0xff;
int g = ((int) c[j++]) & 0xff;
int b = ((int) c[j++]) & 0xff;
tab[i++] = 0xff000000 | (r << 16) | (g << 8) | b;
}
}
return tab;
}
/**
* Main file parser. Reads GIF content blocks.
*/
protected void readContents() {
// read GIF file content blocks
boolean done = false;
while (!(done || err())) {
int code = read();
switch (code) {
case 0x2C: // image separator
readBitmap();
break;
case 0x21: // extension
code = read();
switch (code) {
case 0xf9: // graphics control extension
readGraphicControlExt();
break;
case 0xff: // application extension
readBlock();
String app = "";
for (int i = 0; i < 11; i++) {
app += (char) block[i];
}
if (app.equals("NETSCAPE2.0")) {
readNetscapeExt();
} else {
skip(); // don't care
}
break;
case 0xfe:// comment extension
skip();
break;
case 0x01:// plain text extension
skip();
break;
default: // uninteresting extension
skip();
}
break;
case 0x3b: // terminator
done = true;
break;
case 0x00: // bad byte, but keep going and see what happens break;
default:
status = STATUS_FORMAT_ERROR;
}
}
}
protected void readGraphicControlExt() {
read(); // block size
int packed = read(); // packed fields
dispose = (packed & 0x1c) >> 2; // disposal method
if (dispose == 0) {
dispose = 1; // elect to keep old image if discretionary
}
transparency = (packed & 1) != 0;
delay = readShort() * 10; // delay in milliseconds
transIndex = read(); // transparent color index
read(); // block terminator
}
protected void readHeader() {
String id = "";
for (int i = 0; i < 6; i++) {
id += (char) read();
}
if (!id.startsWith("GIF")) {
status = STATUS_FORMAT_ERROR;
return;
}
readLSD();
if (gctFlag && !err()) {
gct = readColorTable(gctSize);
bgColor = gct[bgIndex];
}
}
protected void readBitmap() {
ix = readShort(); // (sub)image position & size
iy = readShort();
iw = readShort();
ih = readShort();
int packed = read();
lctFlag = (packed & 0x80) != 0; // 1 - local color table flag interlace
lctSize = (int) Math.pow(2, (packed & 0x07) + 1);
interlace = (packed & 0x40) != 0;
if (lctFlag) {
lct = readColorTable(lctSize); // read table
act = lct; // make local table active
} else {
act = gct; // make global table active
if (bgIndex == transIndex) {
bgColor = 0;
}
}
int save = 0;
if (transparency) {
save = act[transIndex];
act[transIndex] = 0; // set transparent color if specified
}
if (act == null) {
status = STATUS_FORMAT_ERROR; // no color table defined
}
if (err()) {
return;
}
decodeBitmapData(); // decode pixel data
skip();
if (err()) {
return;
}
frameCount++;
image = Bitmap.createBitmap(width, height, Config.ARGB_4444);
setPixels(); // transfer pixel data to image
frames.addElement(new GifFrame(image, delay)); // add image to frame
if (transparency) {
act[transIndex] = save;
}
resetFrame();
}
protected void readLSD() {
// logical screen size
width = readShort();
height = readShort();
// packed fields
int packed = read();
gctFlag = (packed & 0x80) != 0; // 1 : global color table flag
// 2-4 : color resolution
// 5 : gct sort flag
gctSize = 2 << (packed & 7); // 6-8 : gct size
bgIndex = read(); // background color index
pixelAspect = read(); // pixel aspect ratio
}
protected void readNetscapeExt() {
do {
readBlock();
if (block[0] == 1) {
int b1 = ((int) block[1]) & 0xff;
int b2 = ((int) block[2]) & 0xff;
loopCount = (b2 << 8) | b1;
}
} while ((blockSize > 0) && !err());
}
protected int readShort() {
// read 16-bit value, LSB first
return read() | (read() << 8);
}
protected void resetFrame() {
lastDispose = dispose;
lrx = ix;
lry = iy;
lrw = iw;
lrh = ih;
lastBitmap = image;
lastBgColor = bgColor;
dispose = 0;
transparency = false;
delay = 0;
lct = null;
}
protected void skip() {
do {
readBlock();
} while ((blockSize > 0) && !err());
}
}
public class GifDecoderView extends ImageView {
private boolean mIsPlayingGif = false;
private GifDecoder mGifDecoder;
private Bitmap mTmpBitmap;
final Handler mHandler = new Handler();
final Runnable mUpdateResults = new Runnable() {
public void run() {
if (mTmpBitmap != null && !mTmpBitmap.isRecycled()) {
GifDecoderView.this.setImageBitmap(mTmpBitmap);
}
}
};
public GifDecoderView(Context context, InputStream stream) {
super(context);
playGif(stream);
}
public void playGif(InputStream stream) {
mGifDecoder = new GifDecoder();
mGifDecoder.read(stream);
mIsPlayingGif = true;
new Thread(new Runnable() {
public void run() {
final int n = mGifDecoder.getFrameCount();
final int ntimes = mGifDecoder.getLoopCount();
int repetitionCounter = 0;
do {
for (int i = 0; i < n; i++) {
mTmpBitmap = mGifDecoder.getFrame(i);
int t = mGifDecoder.getDelay(i);
mHandler.post(mUpdateResults);
try {
Thread.sleep(t);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if(ntimes != 0) {
repetitionCounter ++;
}
} while (mIsPlayingGif && (repetitionCounter <= ntimes));
}
}).start();
}
public void stopRendering() {
mIsPlayingGif = true;
}
}
This is my activity
public class MainActivity extends FragmentActivity implements OnClickListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_gif_main);
playGif("animation2.gif");
findViewById(R.id.btn1).setOnClickListener(MainActivity.this);
findViewById(R.id.btn2).setOnClickListener(MainActivity.this);
}
public void playGif(String name)
{
try
{
InputStream is = getApplicationContext().getAssets().open(name);
GifDecoderView gif= new GifDecoderView(getApplicationContext(), is);
LinearLayout ll=(LinearLayout)findViewById(R.id.ll);
ll.removeAllViews();
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(100,100);
ll.addView(gif, is), params);
}
catch(Exception e)
{
e.printStackTrace();
}
}
#Override
public void onClick(View v) {
switch(v.getId())
{
case R.id.btn1:
playGif("animation2.gif");
break;
case R.id.btn2:
playGif("animation1.gif");
break;
}
}
}
Please check this code. Thanks in advance. App getting crashed when I continuously swaping the image.
The problem is caused by the GarbageCollector not having released the old GIF Instances as you recreate them all the time, over and over again!
Try caching both GifDecoderView instances, i.e. create them once and keep them during runtime, instead of recreating them, i.e. in your oncreate do this:
InputStream is = getApplicationContext().getAssets().open(gif0Name);
this.mGif0 = new GifDecoderView(getApplicationContext(), is);
is = getApplicationContext().getAssets().open(gif1Name);
this.mGif1 = new GifDecoderView(getApplicationContext(), is);
Add the two field s in the class accordingly and remember to destroy them once your activity will be destroyed.
Also: Consider not to recreate the entire views but to stop playback of the gif to be hidden and hide the enclosing view! WIll make your code much smaller and you don't have to recreate stuff all the time!
EDIT: By the way, what does your DecoderView do, if you add this GIFMovieView?
I Am developing android abacus application, in that i need to develope the user interface like the following and i am using the following logic. It compiles and executes without exceptions but the view is not visible.
So, please guide me how develope this.
**MainActivity**
public class Hello extends Activity implements SensorListener
{
private MyView myView;
private SensorManager sensorManager;
public void onAccuracyChanged(int paramInt1, int paramInt2)
{
}
public void onCreate(Bundle paramBundle)
{
super.onCreate(paramBundle);
Log.e("hello", "hello");
this.myView = new MyView(this);
setContentView(this.myView);
Log.e("hello", "hello after constructor");
this.sensorManager = ((SensorManager)getSystemService("sensor"));
this.myView.setTheme(2);
}
protected void onResume()
{
super.onResume();
this.sensorManager.registerListener(this, 3, 0);
}
public void onSensorChanged(int paramInt, float[] paramArrayOfFloat)
{
switch (paramInt)
{
default:
case 1:
case 2:
}
this.myView.resetTama();
do
{
do
return;
while (Math.abs(paramArrayOfFloat[2]) <= 50.0F);
}
while (Math.abs(paramArrayOfFloat[0]) <= 15.0F);
}
public void onWindowFocusChanged(boolean paramBoolean)
{
super.onWindowFocusChanged(paramBoolean);
if (paramBoolean)
this.myView.init();
}
}
**MyView class**
public class MyView extends RelativeLayout
{
private final int FP = -1;
private final int WC = -2;
public boolean disableApplication = false;
private int imgType = 1;
public boolean isBlack = false;
boolean isInitialized;
private Bitmap myBitmap;
private Paint myPaint = new Paint();
private int[] numbers;
private Tama[] oyatamaArray;
private Tama[][] tamaArray;
public MyView(Context paramContext)
{
super(paramContext);
Log.e("MyView", "MyView");
setFocusable(true);
setBackgroundResource(R.drawable.haikei);
this.myBitmap = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.tama);
this.numbers = new int[6];
//for displaying numbers
for (int i = 0; i<numbers.length; i++)
{
if (i >= this.numbers.length)
{
loadChangeThemeButton(paramContext);
new TextView(paramContext).setBackgroundResource(R.drawable.bar);
return;
}
this.numbers[i] = 0;
}
}
private void changeBackgroundImage()
{
int i = 1 + this.imgType;
this.imgType = i;
if (i > 3)
this.imgType = 1;
setTheme(this.imgType);
}
private void loadChangeThemeButton(Context paramContext)
{
ImageButton localImageButton = new ImageButton(paramContext);
localImageButton.setBackgroundResource(R.drawable.themebutton);
RelativeLayout.LayoutParams localLayoutParams = new RelativeLayout.LayoutParams(-2, -2);
localLayoutParams.addRule(9);
localLayoutParams.addRule(12);
localLayoutParams.setMargins(0, 0, 30, 30);
addView(localImageButton, localLayoutParams);
localImageButton.setOnClickListener(new View.OnClickListener()
{
public void onClick(View paramView)
{
MyView.this.changeBackgroundImage();
}
});
}
private Bitmap returnNumberImg(Resources paramResources, int paramInt)
{
switch (paramInt)
{
default:
return BitmapFactory.decodeResource(paramResources, R.drawable.n0);
case 1:
return BitmapFactory.decodeResource(paramResources, R.drawable.n1);
case 2:
return BitmapFactory.decodeResource(paramResources, R.drawable.n2);
case 3:
return BitmapFactory.decodeResource(paramResources, R.drawable.n3);
case 4:
return BitmapFactory.decodeResource(paramResources, R.drawable.n4);
case 5:
return BitmapFactory.decodeResource(paramResources, R.drawable.n5);
case 6:
return BitmapFactory.decodeResource(paramResources, R.drawable.n6);
case 7:
return BitmapFactory.decodeResource(paramResources, R.drawable.n7);
case 8:
return BitmapFactory.decodeResource(paramResources, R.drawable.n8);
case 9:
}
return BitmapFactory.decodeResource(paramResources, R.drawable.n9);
}
private void settingTamasTouchX(int paramInt1, int paramInt2)
{
int i = 0;
if (i >= this.oyatamaArray.length);
int k;
for (int j = 0; ; j++)
{
if (j >= this.tamaArray.length)
{
return;
}
k = 0;
if (k < this.tamaArray[j].length)
{
if (this.tamaArray[j][k].checkArea(paramInt1, paramInt2));
for (this.tamaArray[j][k].touchX = paramInt1; ; this.tamaArray[j][k].touchX = 0)
{
k++;
break;
}
// break label90;
}
}
}
public void init()
{
int i = getHeight() / 7;
int[] arrayOfInt = new int[6];
int j = 5;
//if (j < 0){
this.oyatamaArray = new Tama[6];
//}
int m;
int i1 = 0;
for (int k = 0; ; k++)
{
if (k >= this.oyatamaArray.length)
{
this.tamaArray = ((Tama[][])Array.newInstance(Tama.class, new int[] { 6, 4 }));
m = 0;
if (m < this.tamaArray.length)
{
for (int n = 0; ; n++)
{
if (n >= this.tamaArray[m].length)
{
m++;
break;
}
this.tamaArray[m][n] = new Tama(40 + n * 37, arrayOfInt[m] - 32, n + m * 10);
}
// break label154;
}
i1 = 0;
if (i1 < this.tamaArray.length)
{
for (int i2 = 0; ; i2++)
{
if (i2 >= this.tamaArray[i1].length)
{
i1++;
break;
}
if (i2 != this.tamaArray[i1].length - 1)
this.tamaArray[i1][i2].ueTama = this.tamaArray[i1][(i2 + 1)];
if (i2 == 0)
continue;
this.tamaArray[i1][i2].shitaTama = this.tamaArray[i1][(i2 - 1)];
}
// break label222;
}
this.isInitialized = true;
return;
}
this.oyatamaArray[k] = new Tama(279, arrayOfInt[k] - 32, k);
this.oyatamaArray[k].isOya = true;
}
}
#Override
protected void onDraw(Canvas paramCanvas)
{
Log.e("this is",".........onDraw");
if (!this.isInitialized)
init();
int i = 0;
Resources localResources;
int m;
while (true)
{
int j;
if (i >= this.oyatamaArray.length)
{
j = 0;
if (j >= this.tamaArray.length)
{
localResources = getContext().getResources();
m = 0;
if (m < 7)
break;
return;
}
}
else
{
paramCanvas.drawBitmap(this.myBitmap, this.oyatamaArray[i].getX(), this.oyatamaArray[i].getY(), this.myPaint);
i++;
continue;
}
for (int k = 0; ; k++)
{
if (k >= this.tamaArray[j].length)
{
j++;
break;
}
paramCanvas.drawBitmap(this.myBitmap, this.tamaArray[j][k].getX(), this.tamaArray[j][k].getY(), this.myPaint);
}
}
if (this.numbers.length <= m)
{
for (Bitmap localBitmap = BitmapFactory.decodeResource(localResources, R.drawable.space); ; localBitmap = returnNumberImg(localResources, this.numbers[m]))
{
paramCanvas.drawBitmap(localBitmap, 8.0F, getHeight() / 2 + m * 18, this.myPaint);
m++;
break;
}
}
}
public boolean onTouchEvent(MotionEvent paramMotionEvent)
{
int i = (int)paramMotionEvent.getX();
int j = (int)paramMotionEvent.getY();
if ((paramMotionEvent.getAction() == 0) && (i >= 0) && (i <= 40) && (410 <= j) && (j <= 430))
changeBackgroundImage();
if (paramMotionEvent.getAction() == 0)
settingTamasTouchX(i, j);
if (1 == paramMotionEvent.getAction())
settingTamasTouchX(0, 0);
int k;
int m = 0;
if (2 == paramMotionEvent.getAction())
{
k = 0;
if (k >= this.oyatamaArray.length)
{
m = 0;
if (m < this.tamaArray.length)
{
for (int n = 0; ; n++)
{
if (n >= this.tamaArray[m].length)
{
m++;
break;
}
this.tamaArray[m][n].checkAndSetArea(i, j);
if (!this.tamaArray[m][n].isUp)
continue;
int[] arrayOfInt = this.numbers;
arrayOfInt[m] = (1 + arrayOfInt[m]);
}
// break label164;
}
invalidate();
}
}
else
{
return true;
}
this.oyatamaArray[k].checkAndSetArea(i, j);
if (this.oyatamaArray[k].isUp)
this.numbers[k] = 5;
while (true)
{
k++;
break;
}
// label164:
return disableApplication;
}
public void resetTama()
{
int j;
for (int i = 0; ; i++)
{
if (i >= this.oyatamaArray.length)
{
j = 0;
if (j < this.tamaArray.length)
break;
invalidate();
return;
}
this.oyatamaArray[i].moveX(this.oyatamaArray[i].startX);
this.oyatamaArray[i].isUp = false;
this.numbers[i] = 0;
}
for (int k = 0; ; k++)
{
if (k >= this.tamaArray[j].length)
{
j++;
break;
}
this.tamaArray[j][k].moveX(this.tamaArray[j][k].startX);
this.tamaArray[j][k].isUp = false;
}
}
public void sensorChange(float[] paramArrayOfFloat)
{
int i = 0;
if (paramArrayOfFloat[2] < -50.0F)
i = 0 - 3;
int k;
while (true)
{
int j = 0;
if (j >= this.oyatamaArray.length)
{
k = 0;
if (k < this.tamaArray.length)
break;
if (i != 0)
invalidate();
return;
}
else
{
this.oyatamaArray[j].moveX(i + this.oyatamaArray[j].getX());
if (this.oyatamaArray[j].isUp)
this.numbers[j] = 5;
while (true)
{
j++;
break;
}
}
}
for (int m = 0; ; m++)
{
if (m >= this.tamaArray[k].length)
{
k++;
break;
}
this.tamaArray[k][m].moveX(i + this.tamaArray[k][m].getX());
if (!this.tamaArray[k][m].isUp)
continue;
int[] arrayOfInt = this.numbers;
arrayOfInt[k] = (1 + arrayOfInt[k]);
}
}
public void setTheme(int paramInt)
{
Resources localResources = getContext().getResources();
if (paramInt == 1)
{
this.myBitmap = BitmapFactory.decodeResource(localResources, R.drawable.tama);
setBackgroundResource(R.drawable.haikei);
}
while (true)
{
invalidate();
// return;
if (paramInt == 2)
{
this.myBitmap = BitmapFactory.decodeResource(localResources, R.drawable.tama2);
setBackgroundResource(R.drawable.haikei1);
continue;
}
this.myBitmap = BitmapFactory.decodeResource(localResources, R.drawable.tama3);
setBackgroundResource(R.drawable.haikei1);
}
}
}
Try this (instead of the setContentView )
this.myView = new MyView(this);
this.myView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT));
this.addContentView(myView, new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT));
I have been killing myself trying to develop an algorithm to determine the positions of the cells in a grid by which row or column they are in.
For example, I have an 8x8 grid and I need to determine all of the positions of the cells in row 3.
The issue that I have is that, without alot of loops, I need to figure out a way to map the position clicked to the row and column that contain that cell.
Here is what I did to create an ArrayList of the cells:
public class GameBoard {
public ArrayList<Row> rows = new ArrayList<Row>();
public ArrayList<Column> columns = new ArrayList<Column>();
private int maxPositions;
public GameBoard(int rowCount, int colCount) {
this.maxPositions = (rowCount * colCount) - 1;
for(int x = 0;x < rowCount;x++){
Row row = new Row(x);
row.cells.addAll(this.getRowCells(x, colCount));
rows.add(row);
}
for(int x = 0;x < colCount;x++){
Column column = new Column(x);
column.cells.addAll(getColumnCells(x, colCount));
columns.add(column);
}
}
private ArrayList<Cell> getRowCells(int rowId, int colCount) {
ArrayList<Cell> row_cells = new ArrayList<Cell>();
int first_position = ((rowId * colCount) -1);
Cell cell = new Cell();
cell.id = first_position;
row_cells.add(cell);
int x = 1;
while(x < colCount) {
cell = new Cell();
cell.id = first_position + x;
row_cells.add(cell);
x++;
}
return row_cells;
}
private ArrayList<Cell> getColumnCells(int columnId, int rowCount) {
ArrayList<Cell> col_cells = new ArrayList<Cell>();
int first_position = columnId;
Cell cell = new Cell();
cell.id = first_position;
col_cells.add(cell);
int x = 1;
while(x < rowCount) {
cell = new Cell();
cell.id = rows.get(x).cells.get(columnId).id;
col_cells.add(cell);
x++;
}
return col_cells;
}
public Cell getColumnNextCell(int position, int columnId) {
Cell cell = null;
if ((position > -1) && (position <= maxPositions)) {
cell = columns.get(columnId).cells.get(position + 1);
}
return cell;
}
public Cell getColumnPreviousCell(int position, int columnId) {
Cell cell = null;
if ((position > 0) && (position <= maxPositions)) {
cell = columns.get(columnId).cells.get(position - 1);
}
return cell;
}
public Cell getRowNextCell(int position, int rowId) {
Cell cell = null;
if ((position > -1) && (position <= maxPositions)) {
cell = rows.get(rowId).cells.get(position + 1);
}
return cell;
}
public Cell getRowPreviousCell(int position, int rowId) {
Cell cell = null;
if ((position > 0) && (position <= maxPositions)) {
cell = rows.get(rowId).cells.get(position - 1);
}
return cell;
}
}
As you can see with the methods like getColumnNextCell() through getRowPreviousCell() the logic is a mess and I am stuck on how to determine the column and row of the clicked cell (as I explained). Any help would be greatly appreciated.
For clarification the Row and Column objects are identical. They look like this.
public class Column {
public int id;
public ArrayList<Cell> cells = new ArrayList<Cell>();
public Column(int idx) {
this.id = idx;
}
}
Can't you just use an array for the cells
int rows, cols;
Cell[][] cells;
public GameBoard(int rowCount, int colCount) {
this.maxPositions = (rowCount * colCount) - 1;
this.rows = rowCount;
this.cols = colCount;
this.cells = new Cell[rows];
for(int i=0; i < rows; i++) {
cells[i] = new Cell[cols];
for(int j = 0; j < cols; j++) {
cells[i][j] = new Cell();
// whatever else you need to do...
}
}
}
This way it would be easy to get the cell you want
Cell getCell(int position) {
return cells[position/rows][position%cols];
}
Why don't you use simple two dimensional array? If your grid is not resized after creation, there is no advantage of using ArrayList objects. So what about having your base class something like this:
public class GameBoard {
private Cell[][] cells;
private int maxPositions;
private int rows;
private int cols;
public GameBoard(int rowCount, int colCount) {
this.rows = rowCount;
this.cols = colCount;
cells = new Cell[rowCount][colCount];
for (int i = 0; i < rowCount; i++) {
for (int j = 0; j < colCount; j++) {
cells[i][j] = new Cell();
}
}
this.maxPositions = (rowCount * colCount) - 1;
}
...
}
Now you don't have row and column objects, just array of cells. Isn't those cells actually what you need or do those row and column arrays have another purpose? So I think you are trying to do simple thing with too difficult way.