我不知道我做错了什么,但我的应用程序中出现了“IndexOutOfBoundException”。这是我的代码和logcat:
//代码
public class GameView extends View {
private Context myContext;
private int scaledCardW;
private int scaledCardH;
private int screenH, screenW;
private List<Card> deck = new ArrayList<Card>();
private List<Card> myHand = new ArrayList<Card>();
private List<Card> oppHand = new ArrayList<Card>();
private List<Card> discardPile = new ArrayList<Card>();
private float scale;
private Paint blackPaint;
private int oppScore;
private int myScore;
private boolean myTurn;
private int movingCardIdx = -1;
private int movingX;
private int movingY;
private int validRank = 8;
private int validSuit = 0;
private Bitmap cardBack;
private Bitmap nextCardButton;
private ComputerPlayer computerPlayer = new ComputerPlayer();
private int scoreThisHand = 0;
public GameView(Context context) {
super(context);
// TODO Auto-generated constructor stub
myContext = context;
scale = myContext.getResources().getDisplayMetrics().density;
blackPaint = new Paint();
blackPaint.setAntiAlias(true);
blackPaint.setColor(Color.BLACK);
blackPaint.setStyle(Paint.Style.STROKE);
blackPaint.setTextAlign(Paint.Align.LEFT);
blackPaint.setTextSize(scale * 15);
//myTurn = new Random().nextBoolean();
//myTurn = true;
}
@Override
public void onSizeChanged(int w, int h, int oldw, int oldh)
{
super.onSizeChanged(w, h, oldw, oldh);
screenH = h;
screenW = w;
initCards();
dealCards();
Bitmap tempBitmap = BitmapFactory.decodeResource(myContext.getResources(),R.drawable.card_back);
nextCardButton = BitmapFactory.decodeResource(myContext.getResources(), R.drawable.arrow_next);
scaledCardW = screenW/8;
scaledCardH = (int) (scaledCardW*1.28);
cardBack = Bitmap.createScaledBitmap(tempBitmap, scaledCardW,scaledCardH,false);
validRank = discardPile.get(0).getRank();
validSuit = discardPile.get(0).getSuit();
myTurn = new Random().nextBoolean();
if(!myTurn)
{
makeComputerPlay();
}
}
private void initCards()
{
for(int x = 0; x < 4; x++)
{
for(int y = 102; y < 115; y++)
{
int tempId = y + (x * 100);
Card tempCard = new Card(tempId);
int resourceId = getResources().getIdentifier("card"+ tempId, "drawable",myContext.getPackageName());
Bitmap tempBitmap = BitmapFactory.decodeResource(myContext.getResources(),resourceId);
scaledCardW = screenW/8;
scaledCardH = (int) (scaledCardW*1.28);
Bitmap scaledBitmap = Bitmap.createScaledBitmap(tempBitmap,scaledCardW, scaledCardH, false);
tempCard.setBmp(scaledBitmap);
deck.add(tempCard);
}
}
}
private void drawCard(List<Card> handToDraw)
{
handToDraw.add(0,deck.get(0));
deck.remove(0);
if(deck.isEmpty())
{
for(int x = discardPile.size() -1; x > 0; x --)
{
deck.add(discardPile.get(0));
discardPile.remove(0);
Collections.shuffle(deck, new Random());
}
}
}
private void dealCards()
{
Collections.shuffle(deck, new Random());
for(int y = 0; y < 7; y++)
{
drawCard(myHand);
//drawCard(oppHand);
}
}
@Override
protected void onDraw(Canvas canvas) {
//canvas.drawBitmap(deck.get(9).getBmp(), 80, 50,null);
canvas.drawText("Computer Score: " + oppScore, 10, blackPaint.getTextSize() + 10, blackPaint);
canvas.drawText("My Score: " + myScore, 10, (int)(screenH * 0.9) - blackPaint.getTextSize() - 10, blackPaint);
for (int i = 0; i < oppHand.size(); i++)
{
canvas.drawBitmap(cardBack, i*(scale*5), blackPaint.getTextSize()+(50*scale), null);
}
canvas.drawBitmap(cardBack, (screenW/2)-cardBack.getWidth()-10, (screenH/2)-(cardBack.getHeight()/2), null);
if (!discardPile.isEmpty())
{
canvas.drawBitmap(discardPile.get(0).getBmp(),(screenW/2)+10,(screenH/2)-(cardBack.getHeight()/2), null);
}
for (int i = 0; i < myHand.size(); i++) {
if (i == movingCardIdx)
{
canvas.drawBitmap(myHand.get(i).getBmp(),
movingX,
movingY,
null);
}
else
{
canvas.drawBitmap
(myHand.get(i).getBmp(),
i*(scaledCardW+5),
screenH-blackPaint.
getTextSize()-
(50*scale), null);
}
}
if (myHand.size() > 7)
{
canvas.drawBitmap(nextCardButton,
screenW-nextCardButton.getWidth()-(30*scale),screenH-nextCardButton.getHeight()-scaledCardH-(90*scale),null);
}
for (int i = 0; i < myHand.size(); i++)
{
if (i == movingCardIdx)
{
canvas.drawBitmap(myHand.get(i).getBmp(),movingX, movingY, null);
}
else
{
if(i < 7)
{
canvas.drawBitmap(myHand.get(i).getBmp(),i*(scaledCardW+5),screenH-blackPaint.getTextSize()-(50*scale),null);
}
}
}
invalidate();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int eventaction = event.getAction();
int X = (int)event.getX();
int Y = (int)event.getY();
switch (eventaction ) {
case MotionEvent.ACTION_DOWN:
if(myTurn)
{
for (int i = 0; i < 7; i++)
{
if (X > i*(scaledCardW+5) && X < i*(scaledCardW+5) + scaledCardW && Y > screenH-blackPaint.getTextSize()- (50*scale))
{
movingCardIdx = i;
movingX = X-(int)(30*scale);
movingY = Y-(int)(70*scale);
}
}
}
break;
case MotionEvent.ACTION_MOVE:
movingX = X-(int)(30*scale);
movingY = Y-(int)(70*scale);
break;
case MotionEvent.ACTION_UP:
if (movingCardIdx > -1 && X > (screenW/2)-(100*scale) && X < (screenW/2)+(100*scale) && Y > (screenH/2)-(100*scale) && Y < (screenH/2)+(100*scale) &&
(myHand.get(movingCardIdx).getRank() == 8 || myHand.get(movingCardIdx).getRank() ==
validRank || myHand.get(movingCardIdx).getSuit() == validSuit))
{
validRank = myHand.get(movingCardIdx).getRank();
validSuit = myHand.get(movingCardIdx).getSuit();
discardPile.add(0, myHand.get(movingCardIdx));
myHand.remove(movingCardIdx);
if(myHand.isEmpty())
{
endHand();
}
else
{
if(validRank == 8)
{
showChooseSuitDialog();
}
else
{
myTurn = false;
makeComputerPlay();
}
}
}
movingCardIdx = -1;
if (movingCardIdx == -1 && myTurn && X > (screenW/2)-(100*scale) && X < (screenW/2)+(100*scale) &&
Y > (screenH/2)-(100*scale) && Y < (screenH/2)+(100*scale))
{
if (checkForValidDraw())
{
drawCard(myHand);
}
else
{
Toast.makeText(myContext, "You have a valid play.", Toast.LENGTH_SHORT).show();
}
}
if (myHand.size() > 7 && X > screenW-nextCardButton.getWidth()-(30*scale) && Y > screenH-nextCardButton.getHeight()-scaledCardH- (90*scale) &&
Y < screenH-nextCardButton.getHeight()-scaledCardH - (60*scale))
{
Collections.rotate(myHand, 1);
}
break;
}
invalidate();
return true;
}
private void showChooseSuitDialog()
{
final Dialog chooseSuitDialog = new Dialog(myContext);
chooseSuitDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
chooseSuitDialog.setContentView(R.layout.choose_suit_dialog);
final Spinner suitSpinner = (Spinner)chooseSuitDialog.findViewById(R.id.suitSpinner);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(myContext, R.array.suits,android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
suitSpinner.setAdapter(adapter);
Button okButton = (Button) chooseSuitDialog.findViewById(R.id.okButton);
okButton.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View view)
{
validSuit = (suitSpinner.
getSelectedItemPosition()+1)*100;
String suitText = "";
if (validSuit == 100) {
suitText = "Diamonds";
} else if (validSuit == 200) {
suitText = "Clubs";
} else if (validSuit == 300) {
suitText = "Hearts";
} else if (validSuit == 400) {
suitText = "Spades";
}
chooseSuitDialog.dismiss();
Toast.makeText(myContext,"You chose " + suitText,Toast.LENGTH_SHORT).show();
myTurn = false;
makeComputerPlay();
}
});
chooseSuitDialog.show();
}
private boolean checkForValidDraw()
{
boolean canDraw = true;
for (int i = 0; i < myHand.size(); i++)
{
int tempId = myHand.get(i).getId();
int tempRank = myHand.get(i).getRank();
int tempSuit = myHand.get(i).getSuit();
if (validSuit == tempSuit || validRank == tempRank || tempId == 108 || tempId == 208 ||tempId == 308 || tempId == 408)
{
canDraw = false;
}
}
return canDraw;
}
private void makeComputerPlay()
{
int tempPlay = 0;
while (tempPlay == 0)
{
tempPlay = computerPlayer.makePlay(oppHand,validSuit, validRank);
if (tempPlay == 0)
{
drawCard(oppHand);
}
}
if (tempPlay == 108 || tempPlay == 208 || tempPlay == 308 || tempPlay == 408)
{
validRank = 8;
validSuit = computerPlayer.chooseSuit(oppHand);
String suitText = "";
if (validSuit == 100)
{
suitText = "Diamonds";
}
else if (validSuit == 200)
{
suitText = "Clubs";
}
else if (validSuit == 300)
{
suitText = "Hearts";
}
else if (validSuit == 400)
{
suitText = " Spades";
}
Toast.makeText(myContext, "Computer chose " + suitText, Toast.LENGTH_SHORT).show();
}
else
{
validSuit = Math.round((tempPlay/100) * 100);
validRank = tempPlay - validSuit;
}
for (int i = 0; i < oppHand.size(); i++)
{
Card tempCard = oppHand.get(i);
if (tempPlay == tempCard.getId())
{
discardPile.add(0, oppHand.get(i));
oppHand.remove(i);
}
}
if(oppHand.isEmpty())
{
endHand();
}
myTurn = true;
}
private void updateScores()
{
for (int i = 0; i < myHand.size(); i++)
{
oppScore += myHand.get(i).getScoreValue();
scoreThisHand += myHand.get(i).getScoreValue();
}
for (int i = 0; i < oppHand.size(); i++)
{
myScore += oppHand.get(i).getScoreValue();
scoreThisHand += oppHand.get(i).getScoreValue();
}
}
private void endHand()
{
final Dialog endHandDialog = new Dialog(myContext);
endHandDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
endHandDialog.setContentView(R.layout.end_hand_dialog);
updateScores();
TextView endHandText = (TextView)endHandDialog.findViewById(R.id.endHandText);
if (myHand.isEmpty())
{
if(myScore >= 300)
{
endHandText.setText("You reached " + myScore + " points. You won! Would you like to play again?");
}
else
{
endHandText.setText("You went out and got " + scoreThisHand + " points!");
}
}
else if (oppHand.isEmpty())
{
if (oppScore >= 300)
{
endHandText.setText("The computer reached " + oppScore + " points. Sorry, you lost. Would you like to play again?");
}
else
{
endHandText.setText("The computer went out and got " + scoreThisHand + " points.");
}
}
Button nextHandButton = (Button)endHandDialog.findViewById(R.id.nextHandButton);
if (oppScore >= 300 || myScore >= 300)
{
nextHandButton.setText("New Game");
}
nextHandButton.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View view)
{
if (oppScore >= 300 || myScore >= 300)
{
myScore = 0;
oppScore = 0;
}
initNewHand();
endHandDialog.dismiss();
}
});
endHandDialog.show();
}
private void initNewHand() {
// TODO Auto-generated method stub
scoreThisHand = 0;
if (myHand.isEmpty())
{
myTurn = true;
}
else if (oppHand.isEmpty())
{
myTurn = false;
}
deck.addAll(discardPile);
deck.addAll(myHand);
deck.addAll(oppHand);
discardPile.clear();
myHand.clear();
oppHand.clear();
dealCards();
drawCard(discardPile);
validSuit = discardPile.get(0).getSuit();
validRank = discardPile.get(0).getRank();
if (!myTurn)
{
makeComputerPlay();
}
}
}
//这是我的LogCat
error opening trace file: No such file or directory (2)
GC_FOR_ALLOC freed 34K, 7% free 2395K/2572K, paused 88ms, total 91ms
Grow heap (frag case) to 3.210MB for 770432-byte allocation
GC_FOR_ALLOC freed <1K, 6% free 3147K/3328K, paused 100ms, total 100ms
GC_CONCURRENT freed <1K, 6% free 3265K/3448K, paused 23ms+25ms, total 186ms
Emulator without GPU emulation detected.
GC_CONCURRENT freed 245K, 11% free 3524K/3920K, paused 75ms+53ms, total 455ms
WAIT_FOR_CONCURRENT_GC blocked 194ms
GC_CONCURRENT freed 315K, 12% free 3673K/4160K, paused 14ms+29ms, total 370ms
WAIT_FOR_CONCURRENT_GC blocked 212ms
GC_CONCURRENT freed 287K, 11% free 3853K/4320K, paused 78ms+64ms, total 441ms
WAIT_FOR_CONCURRENT_GC blocked 182ms
GC_CONCURRENT freed 352K, 12% free 3961K/4500K, paused 9ms+28ms, total 363ms
WAIT_FOR_CONCURRENT_GC blocked 243ms
GC_CONCURRENT freed 314K, 11% free 4105K/4600K, paused 98ms+61ms, total 434ms
WAIT_FOR_CONCURRENT_GC blocked 234ms
GC_CONCURRENT freed 352K, 12% free 4268K/4820K, paused 9ms+80ms, total 530ms
WAIT_FOR_CONCURRENT_GC blocked 215ms
GC_FOR_ALLOC freed 193K, 12% free 4244K/4820K, paused 68ms, total 70ms
Grow heap (frag case) to 4.583MB for 316480-byte allocation
GC_FOR_ALLOC freed <1K, 12% free 4553K/5132K, paused 147ms, total 147ms
Shutting down VM
threadid=1: thread exiting with uncaught exception (group=0x40a71930)
FATAL EXCEPTION: main
java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0
at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:251)
at java.util.ArrayList.get(ArrayList.java:304)
at com.example.crazyeights.GameView.onSizeChanged(GameView.java:94)
at android.view.View.setFrame(View.java:14094)
at android.view.View.layout(View.java:14006)
at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
at android.view.View.layout(View.java:14008)
at android.view.ViewGroup.layout(ViewGroup.java:4373)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1663)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1521)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1434)
at android.view.View.layout(View.java:14008)
at android.view.ViewGroup.layout(ViewGroup.java:4373)
at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
at android.view.View.layout(View.java:14008)
at android.view.ViewGroup.layout(ViewGroup.java:4373)
at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:1892)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1711)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:989)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4351)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749)
at android.view.Choreographer.doCallbacks(Choreographer.java:562)
at android.view.Choreographer.doFrame(Choreographer.java:532)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735)
at android.os.Handler.handleCallback(Handler.java:725)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5041)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
at dalvik.system.NativeStart.main(Native Method)
Sending signal. PID: 929 SIG: 9
GC_FOR_ALLOC freed 38K, 8% free 2395K/2576K, paused 326ms, total 332ms
Grow heap (frag case) to 3.210MB for 770432-byte allocation
GC_FOR_ALLOC freed <1K, 6% free 3147K/3332K, paused 79ms, total 79ms
GC_CONCURRENT freed <1K, 6% free 3273K/3452K, paused 31ms+29ms, total 163ms
Emulator without GPU emulation detected.
答案 0 :(得分:2)
在onSizeChanged()
中,您使用discardPile
访问get(0)
的第一个元素,但discardPile
为空。