So I just started learn how to create an app with android-studio and I'm trying to make a simple animation. For exemple I thought of a bouncing ball, but for the moment I can't make my ball move. I don't understand perfectly how everything works but I managed to draw a ball in the screen, now I want my ball to move but the problem is that I can't manage to update my screen (which is drawn by the onDraw function) while it is opened, the phone just show the final screen when all the movement is finished. I heard that I had to use invalidate function but I don't know how to use it and I tried to make a move function to use it. I would like to know what would be the simplest change I have to do on my code to see the ball moving on the screen.
package com.example.myfirstapp;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.os.Bundle;
import android.os.SystemClock;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import java.util.Random;
public class AnimationActivity extends AppCompatActivity {
public int posX= 300;
public int posY= 300;
public int radius= 50;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
RenderView renderView = new RenderView(this);
setContentView(renderView);
while(posX<2000) {
renderView.move();
setContentView(renderView);
}
}
class RenderView extends View {
public RenderView(Context context){
super(context);
}
public void move(){
posX=posX+1;
//SystemClock.sleep(2);
invalidate();
}
protected void onDraw(Canvas canvas) {
int width = getWidth();
int height = getHeight();
canvas.drawRGB(255, 255, 255);
Paint ball = new Paint();
ball.setAntiAlias(true);
ball.setARGB(255,255,0,0);
ball.setStyle(Paint.Style.FILL_AND_STROKE);
canvas.drawCircle(posX,posY,radius,ball);
}
}
}
Try this code
public class MainActivity extends AppCompatActivity {
public int posX = 300;
public int posY = 300;
public int radius = 50;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
RenderView renderView = new RenderView(this);
setContentView(renderView);
/* while (posX < 2000) {
renderView.move();
renderView.invalidate();
}*/
}
class RenderView extends View {
public RenderView(Context context) {
super(context);
}
public void move() {
posX++;
//SystemClock.sleep(2);
}
protected void onDraw(Canvas canvas) {
int width = getWidth();
int height = getHeight();
canvas.drawRGB(255, 255, 255);
Paint ball = new Paint();
ball.setAntiAlias(true);
ball.setColor(getResources().getColor(R.color.colorAccent));
ball.setStyle(Paint.Style.FILL_AND_STROKE);
canvas.drawCircle(posX, posY, radius, ball);
if (posX > 350) {
posX = 300;
posY+=10;
}
posX++;
invalidate();
}
}
}
Related
I am making a game which requires the sprites to move towards the bottom of the screen. You can imagine it a bit like a rhythm game(guitar hero). However, I am having problems as the sprites are not moving at all even if the loop seems to work fine.
The GamePanel-
package com.jollygent.tapthepointer;
import java.util.ArrayList;
import java.util.Random;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class GamePanel extends SurfaceView{
SurfaceHolder holder;
GameLoopThread loop;
GamePanel game = this;
Random rand;
int y;
//ArrayList<Pointers> pointers = new ArrayList<Pointers>();
Pointers pointers;
public GamePanel(Context context) {
super(context);
holder = getHolder();
loop = new GameLoopThread(this);
rand = new Random();
pointers = new Pointers(rand.nextInt(4)+1,getWidth()/2,0,this);
//placeholder
this.setBackgroundColor(Color.WHITE);
holder.addCallback(new SurfaceHolder.Callback() {
#Override
public void surfaceDestroyed(SurfaceHolder arg0) {
// TODO Auto-generated method stub
loop.setRunning(false);
}
#Override
public void surfaceCreated(SurfaceHolder arg0) {
loop = new GameLoopThread(game);
if(!loop.isRunning()){
loop.setRunning(true);
loop.start();
}
else{
loop.setPause(false);
}
}
#Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stubn
}
});
}
public GameLoopThread getLoop(){
return loop;
}
public void update(){
}
public void draw(Canvas canvas){
pointers.draw(canvas);
Paint paint = new Paint();
paint.setColor(Color.BLACK);
paint.setStrokeWidth(20);
paint.setStyle(Paint.Style.STROKE);
canvas.drawLine(0,getHeight()/2 + 50,getWidth(),getHeight()/2 + 50, paint);
}
}
The Pointer class
package com.jollygent.tapthepointer;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
public class Pointers {
GamePanel game;
private int x,y;
Bitmap pointer;
Bitmap rotated_pointer;
Matrix matrix;
public Pointers(int type,int x,int y,GamePanel game){
this.game = game;
this.x = x;
this.y = y;
pointer = BitmapFactory.decodeResource(game.getResources(),R.drawable.pointer_xx);
matrix = new Matrix();
switch(type){
//points right
case 1:
matrix.postRotate(90);
break;
//points left
case 2:
matrix.postRotate(-90);
break;
//points up
case 3:
rotated_pointer = pointer;
break;
//points down
case 4:
matrix.postRotate(180);
break;
}
rotated_pointer = Bitmap.createBitmap(pointer,0,0,pointer.getHeight(),pointer.getWidth(), matrix,true);
}
public void update(){
/*if(y < game.getHeight()){
y += pointer.getHeight();
}*/
}
public int getHeight(){
return pointer.getHeight();
}
public void draw(Canvas canvas){
y++;//placeholder movement to see if the sprite actually moves. It doesn't.
canvas.drawBitmap(rotated_pointer,x,y,null);
}
}
Finally, I think it's necessary to post the GameLoopThread-
package com.jollygent.tapthepointer;
import android.graphics.Canvas;
public class GameLoopThread extends Thread{
GamePanel game;
boolean running = false;
boolean paused = false;
Canvas canvas;
static final int FPS = 10;
public GameLoopThread(GamePanel game){
this.game = game;
}
public boolean isRunning(){
return running;
}
public void setRunning(boolean b){
this.running = b;
}
public void setPause(boolean b){
this.paused = b;
}
#Override
public void run() {
// TODO Auto-generated method stub
long beginTime;
long ticks = 1000/FPS;
long sleepTime;
while(running){
if(!paused){
beginTime = System.currentTimeMillis();
canvas = null;
try{
canvas = game.holder.lockCanvas();
synchronized(game.getHolder()){
game.draw(canvas);
}
}finally{
if(canvas != null){
game.getHolder().unlockCanvasAndPost(canvas);
}
}
sleepTime = (System.currentTimeMillis() - beginTime)/ticks;
try{
if(sleepTime > 0)
Thread.sleep(sleepTime);
else
Thread.sleep(10);
}catch(Exception e){
e.printStackTrace();
}
}
}
}
}
I'm probably making a very stupid mistake, but no matter how much I scan into the code and change around few bits I can't seem to figure out how exactly to move the sprite. Also, how can I make it so the sprite is centered exactly in any device?
Thank you.
EDIT:
package com.jollygent.tapthepointer;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.Window;
public class GameActivity extends Activity {
GamePanel game;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
game = new GamePanel(this);
setContentView(game);
}
#Override
public void onPause(){
super.onPause();
game.getLoop().setPaused(true);
}
#Override
public void onResume(){
super.onResume();
game.getLoop().setPaused(false);
}
}
The problem is that the loop only runs once and once only. Perhaps the GameActivity is the problem?
why does this not work? it prints the locations as the should but it does not move the image on the screen? i am using an emulator.
i think the image should be moving around but it stays in the same place even though the x and y values are changing. i think the problem may be the canvas i am using when i call onDraw(canvas). what can i do to this canvas to make it work (if the canvas is the problem)?
if this is not enough detail please tell me. code below;
GameView.java
package com.example.game;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.view.View;
public class GameView extends View implements Runnable{
Thread gameLoop = new Thread(this);
boolean running = false;
int x = 10;
int y = 10;
Canvas canvas = new Canvas();
private Bitmap bmp;
public GameView(Context context) {
super(context);
bmp = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
}
#Override
public void onDraw(Canvas canvas) {
canvas.drawColor(Color.BLACK);
canvas.drawBitmap(bmp, x, y, null);
System.out.println(x);
if(x < 100) {
x+=10;
}
if(x >= 99 && y < 400) {
y+=10;
}
if(y > 350 && x >= 99) {
x = 10;
y = 10;
}
}
public void start() {
if(!running) {
running = true;
gameLoop.start();
}
}
public void stop() {
if(running) {
running = false;
}
}
#Override
public void run() {
while(running) {
try{
onDraw(canvas);
Thread.sleep(1000);
}catch(Exception exc) {System.err.println("error sleep interup");}
}
}
}
Main.java
package com.example.game;
import android.app.Activity;
import android.os.Bundle;
public class Main extends Activity {
GameView gv;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
gv = new GameView(this);
setContentView(gv);
gv.start();
}
}
You should put the object back on the canvas after you calculated the x and y coordinates.
public void onDraw(Canvas canvas) {
canvas.drawColor(Color.BLACK);
System.out.println(x);
if(x < 100) {
x+=10;
}
if(x >= 99 && y < 400) {
y+=10;
}
if(y > 350 && x >= 99) {
x = 10;
y = 10;
}
canvas.drawBitmap(bmp, x, y, null);
}
Iam doing my first game for android.
I want to do a very simple thing which is to have a background and a ball that will "spawn" in it.
So I have made my GameView:
package com.example.newarkanoid;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.MotionEvent;
import android.view.View;
public class Tela extends View {
Paint paint;
int x,y;
int lastx,lasty;
Bola bola;
public Tela(Context context, Bola BOLA) {
super(context);
paint = new Paint();
x=0;lastx=0;
y=0;lasty=0;
bola = BOLA;
bola.paint.setColor(Color.BLACK);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
paint.setColor(Color.WHITE);
canvas.drawPaint(paint);
bola.invalidate();
}
public boolean onTouchEvent(MotionEvent event) {
x = (int)event.getX();
y = (int)event.getY();
if(lastx !=x || lasty !=y){
lastx=x;
lasty=y;
bola.x = x;
bola.y = y;
bola.invalidate();
}
return false;
}
}
Well, above is my MainDisplay, now i need a ball:
package com.example.newarkanoid;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.View;
public class Bola extends View {
Paint paint;
float x,y,raio;
public Bola(Context context, float x, float y, float raio) {
super(context);
this.x = x;
this.y = y;
this.raio = raio;
paint = new Paint();
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
paint.setStyle(Paint.Style.FILL);
canvas.drawCircle(x, y, raio, paint);
}
}
So, I did like that cause my teacher told me, you dont have to call invalidate for the intire main display, you can call invalidate just for your ball, so i made my ball drawing code, also its properties.
So as you can see in the code, when i click somewhere in the touchscreen my ball x and y will change to the click position, and then call invalidate.
The thing is, the ball does not even appear when i create my mainDisplay, so I was wondering, is there something like a context problem? why my ball isnt drawn?
Also, here is my MainActivity:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bola bola = new Bola(this,20,20,5);
Tela t = new Tela(this,bola);
setContentView(t);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
paint.setColor(Color.WHITE);
canvas.drawPaint(paint);
bola.invalidate();
}
when bola invalidate, bola will draw with its canvas, different the Tela's canvas. You can create a class, not extends view, with draw method
public void draw(Canvas canvas) {
paint.setStyle(Paint.Style.FILL);
canvas.drawCircle(x, y, raio, paint);
}
and call in tela:
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
paint.setColor(Color.WHITE);
canvas.drawPaint(paint);
bola.draw(canvas);
}
use bola.draw(canvas); in your onDraw()
I have been researching and struggling with my code to get a textview to update the score when a "ghost" is touched.
This is my first Android application and so far as i can tell(i added Log.w() to the ontouch but a log is never posted as well as the score not being incremented or even appearing) the onTouch(View v, MotionEvent event) is never called. Below is my code.
package com.cs461.Ian;
//TODO:Add accelerometer support
//TODO:Add Clickable ghosts
//TODO:Add camera background
/*Completed:(As of 2:30am 4/16)
* Activity launches
* Ghost appears on screen
* Ghost will randomly move around the screen
*/
import java.util.Random;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.View;
import android.widget.TextView;
public class CameraActivity extends Activity{
Bitmap g;
Ghost a;
Ghost still;
SurfaceHolder mSurfaceHolder;
boolean firsttime=true;
int draw_x,draw_y,xSpeed,ySpeed,score=0;
TextView t;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.game);
a = new Ghost(getApplicationContext());
still = new Ghost(getApplicationContext());
//requestWindowFeature(Window.FEATURE_NO_TITLE);
a.Initalize(BitmapFactory.decodeResource(getResources(), R.drawable.ghost), 20, 20);
still.Initalize(BitmapFactory.decodeResource(getResources(), R.drawable.ghost), 120, 120);
t = (TextView) findViewById(R.id.t);
t.setText("TEST SCORE TO SEE IF TEXTVIEW SHOWS UP");
a.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN){
score++;
t.setText("Score: "+score);
}
return true;
}
});
still.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN){
score++;
t.setText("Score: "+score);
Log.w("CLICKED","Clicked on ghost "+score+" times");
}
return true;
}
});
setContentView(new Panel(this));
}
class Panel extends View {
public Panel(Context context) {
super(context);
}
#Override
public void onDraw(Canvas canvas) {
//g.Initalise(BitmapFactory.decodeFile("/res/drawable-hdpi/ghost.png"), 200, 150, 5, 5);;
update(canvas);
invalidate();
}
/*Places ghost on screen and bounces it around in the screen. My phone is apparently only API level 4(the most up to date is 15) so i didn't code it
*for the accelerometer yet.
*/
public void update(Canvas canvas) {
Random rand = new Random();
if(firsttime){
draw_x = Math.round(System.currentTimeMillis() % (this.getWidth()*2)) ;
draw_y = Math.round(System.currentTimeMillis() % (this.getHeight()*2)) ;
xSpeed = rand.nextInt(10);
ySpeed = rand.nextInt(10);
firsttime=false;
}
draw_x+=xSpeed;
draw_y+=ySpeed;
draw_x = Math.round(System.currentTimeMillis() % (this.getWidth()*2)) ;
draw_y = Math.round(System.currentTimeMillis() % (this.getHeight()*2)) ;
if (draw_x>this.getWidth()){
draw_x = (this.getWidth()*2)-draw_x;
xSpeed = rand.nextInt(10);
if(xSpeed >=5)
xSpeed=-xSpeed;
}
if (draw_y>this.getHeight()){
draw_y = (this.getHeight()*2)-draw_y;
ySpeed = rand.nextInt(10);
if(ySpeed >=5)
ySpeed=-ySpeed;
}
g = BitmapFactory.decodeResource(getResources(), R.drawable.ghost);
canvas.drawBitmap(g, draw_x, draw_y, null);
still.draw(canvas);
a.update(canvas);
}
}
}
Forgot to add class Ghost:
package com.cs461.Ian;
import java.util.Random;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
public class Ghost extends View implements View.OnTouchListener{
public Ghost(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
private Bitmap mAnimation;
private int mXPos;
private int mYPos;
private Rect mSRectangle;
private int mSpriteHeight;
private int mSpriteWidth;
View v;
Rect dest;
int score = 0;
/*public Ghost() {
mSRectangle = new Rect(0,0,0,0);
mXPos = 80;
mYPos = 200;
}*/
public void Initalize(Bitmap theBitmap, int Height, int Width) {
mSRectangle = new Rect(0,0,0,0);
mXPos = 80;
mYPos = 200;
mAnimation = theBitmap;
mSpriteHeight = Height;
mSpriteWidth = Width;
mSRectangle.top = 0;
mSRectangle.bottom = mSpriteHeight;
mSRectangle.left = 0;
mSRectangle.right = mSpriteWidth;
dest = new Rect(mXPos, mYPos, mXPos + mSpriteWidth,
mYPos + mSpriteHeight);
}
public void draw(Canvas canvas) {
canvas.drawBitmap(mAnimation, mXPos, mYPos, null);
}
public void update(Canvas canvas) {
new Random();
mXPos = Math.round(System.currentTimeMillis() % (canvas.getWidth()*2)) ;
mYPos = Math.round(System.currentTimeMillis() % (canvas.getHeight()*2)) ;
if (mXPos>canvas.getWidth())
mXPos = (canvas.getWidth()*2)-mXPos;
if (mYPos>canvas.getHeight())
mYPos = (canvas.getHeight()*2)-mYPos;
draw(canvas);
}
public Rect getRect() {
return mSRectangle;
}
#Override
public boolean onTouch(View v, MotionEvent event) {
score++;
//CameraActivity.t.setText("Score: "+CameraActivity.score);
Log.w("CLICKED","Clicked on ghost "+score+" times");
return true; //doesn't work if returns false either
}
}
Override dispatchTouchEvent(MotionEvent event) in your Activity to handle all the touch events that may occur. Return false to pass down the MotionEvent to the next view\layout in the hierachy if they they handle events.
I have an array of objects that need to be drawn to a canvas; each object is represented as:
scatterPlot.java
package scatter.plot;
import java.util.ArrayList;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.view.View;
public class scatterPoint extends View {
private final Point coordinates;
private final int itemShape;
private Paint itemColour = new Paint(Paint.ANTI_ALIAS_FLAG);
private scatterPoint[] mShapes;
public scatterPoint(Context context, Point p, int shape, Paint colour) { // Constructor
super(context);
coordinates = p;
itemShape = shape;
itemColour = colour;
}
//get set points
public void setPoints(scatterPoint[] p){
mShapes = p;
}
public scatterPoint[] getScatterPoints(){
return mShapes;
}
#Override
protected void onDraw(Canvas canvas) {
//super.onDraw(canvas);
int radius = 10;
for (scatterPoint i : mShapes) {
switch(itemShape){
case 0:
canvas.drawRect(i.coordinates.x - radius, i.coordinates.y - radius, i.coordinates.x + radius, i.coordinates.y + radius, i.itemColour);
break;
case 1:
Path path = new Path();
path.moveTo(i.coordinates.x - radius, i.coordinates.y - radius);
path.lineTo(i.coordinates.x, i.coordinates.y + radius);
path.lineTo(i.coordinates.x + radius, i.coordinates.y - radius);
path.lineTo(i.coordinates.x - radius, i.coordinates.y - radius);
path.close();
canvas.drawPath(path, i.itemColour);
break;
case 2:
canvas.drawCircle(i.coordinates.x, i.coordinates.y, radius, i.itemColour);
break;
}
}
}
public Point getCoordinates(){
return coordinates;
}
public int getShape(){
return itemShape;
}
public Paint getColour(){
return itemColour;
}
}
Relevant methods from main (ScatterPlotActivity.java):
package scatter.plot;
import java.util.Random;
import android.app.Activity;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.os.Bundle;
import android.view.Display;
import android.view.WindowManager;
import android.widget.FrameLayout;
public class ScatterPlotActivity extends Activity {
FrameLayout main;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
main = (FrameLayout) findViewById(R.id.main_view);
scatterPoint[] points = generatePoints();
//
//add scatterPoint to main
//
}
public scatterPoint[] generatePoints(){
//
return points;
}
}
Any ideas on what is wrong with how I'm trying to draw these objects?
I think the problem comes from the fact that you're creating each time a new FrameLayout. Declare your FrameLayout in your main and then call your method drawPoints like this:
drawPoint(points[i], main);
and your method will look like this :
public void drawPoint(scatterPoint point, FrameLayout main) {
main.addView(point);
}
This way they will always be added to the same Layout.
The problem is:
public void drawPoint(scatterPoint point) {
FrameLayout main = (FrameLayout) findViewById(R.id.main_view);
main.addView(point);
}
Make your FrameLayout main; a global variable. Then, right after you call setContentView(R.layout.x); in onActivityCreated(), call main = (FrameLayout) findViewById(R.id.main_view);
You only want to make this call once. Every time the current implementation calls public void drawPoint(scatterPoint point);, the FrameLayout is being reinitialized and clearing all the old drawings.
By the looks of things, you are actually drawing all of your scatter point views. However, due to how you are adding them to the FrameLayout, they are stacking on top of each other. Look in your drawPoint() method. You add the point to FrameLayout, which was designed to only handle one view (for more on this statement refer to FrameLayout), and the FrameLayout just draws the new view right over the last view drawn.
class ScatterShape {
public float mX = 0, mY = 0;
public int mShape = 0;
public Paint mColor = new Paint();
public ScatterShape(float x, float y, int shape, int color) {
mX = x;
mY = y;
mShape = shape;
mColor.setColor(color);
}
}
public class ScatterShaperDrawer extends View {
private List<ScatterShape> mShapes = new ArrayList<ScatterShapes>();
private float mmRadius = 5;
// Make getter and setter
#Override public void onDraw(Canvas canvas) {
for (ScatterShape i : mShapes) {
switch(i.mShape){
case 0:
canvas.drawRect(i.mX - mRadius, i.mY - mRadius, i.mX + mRadius, i.mY + mRadius, itemColor);
break;
case 1:
Path path = new Path();
path.moveTo(i.mX - mRadius, i.mY - mRadius);
path.lineTo(i.mX, i.mY + mRadius);
path.lineTo(i.mX + mRadius, i.mY - mRadius);
path.lineTo(i.mX - mRadius, i.mY - mRadius);
path.close();
canvas.drawPath(path, i.mColor);
break;
case 2:
canvas.drawCircle(i.mX, i.mY, mRadius, i.mColor);
break;
}
}
}
}