Basically I have been making a simple game in which I now want to create collision detection between the Player and the Enemy. I have made both a class of the player and the enemy and then also a separate GameView class. My issue is that there is simply no collision happening and I just don't understand why, I have changed the code various times but I still can't seem to crack it. I will leave my code below and if anyone sees where I have gone wrong it would be great help. Thank you.
GameView Class:
public class GameView extends SurfaceView implements Runnable {
Canvas canvas;
SurfaceHolder surfaceHolder;
Thread thread = null;
volatile boolean playing;
Paint paint;
Context context;
Player player;
int screenX, screenY, numberOfEnemies = 4, distanceBetweenEnemies;
int enemyX [] = new int[numberOfEnemies];
int enemyY [] = new int[numberOfEnemies];
private boolean paused = true;
Enemy enemy;
Enemy [] enemies;
Random random;
Rect [] enemyRectangle;
public GameView (Context context, int x, int y) {
super(context);
this.context = context;
surfaceHolder = getHolder();
paint = new Paint();
thread = new Thread();
screenX = x;
screenY = y;
player = new Player (context, screenX, screenY);
enemies = new Enemy[numberOfEnemies];
enemyRectangle = new Rect[numberOfEnemies];
enemy = new Enemy (context, screenX);
distanceBetweenEnemies = screenX * 3 / 4;
for (int i = 0; i < numberOfEnemies; i ++) {
enemies[i] = new Enemy(context, screenX);
enemyX[i] = screenX / 2 - enemy.getEnemyBitmap().getWidth() / 2 + i * distanceBetweenEnemies;
random = new Random();
enemyY[i] = random.nextInt(screenY - enemy.getEnemyBitmap().getHeight() / 2);
}
}
#Override
public void run() {
while (playing) {
draw();
if(!paused){
update();
}
}
}
private void draw () {
if (surfaceHolder.getSurface().isValid()) {
canvas = surfaceHolder.lockCanvas();
canvas.drawColor(Color.argb(255, 26, 128, 182));
canvas.drawBitmap(player.getPlayerBitmap(), player.getX(), player.getY(), null);
for (int i = 0; i < numberOfEnemies; i ++) {
canvas.drawBitmap(enemies[i].getEnemyBitmap(), enemyX[i], enemyY[i], null);
enemyRectangle [i] = new Rect(enemyX[i], enemyY[i], enemy.getEnemyBitmap().getWidth(),
enemy.getEnemyBitmap().getHeight());
enemyX[i] += enemy.getEnemySpeed();
}
update ();
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
private void update () {
player.updatePlayerPosition();
player.noLeaveScreen();
for (int i = 0; i < numberOfEnemies; i ++) {
if (enemyX[i] < 0 - enemy.getEnemyBitmap().getWidth()) {
enemyY[i] = random.nextInt(screenY);
enemyRectangle [i] = new Rect(enemyX[i], enemyY[i], enemy.getEnemyBitmap().getWidth(),
enemy.getEnemyBitmap().getHeight());
enemyX[i] += numberOfEnemies * distanceBetweenEnemies;
} else {
enemyX[i] += enemy.getEnemySpeed();
}
if (Rect.intersects(player.getPlayerRectangle(), enemyRectangle[i])) {
Log.e("COLLISION:", "Detected");
enemyX[i] = - 200;
}
}
}
public void pause () {
playing = false;
try {
thread.join();
} catch (InterruptedException e) {
Log.e("Error:", "joining thread");
}
}
public void resume () {
playing = true;
thread = new Thread(this);
thread.start();
}
#Override
public boolean onTouchEvent (MotionEvent event) {
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
player.playerJump();
break;
}
return true;
}
}
Player Class:
public class Player {
Bitmap playerBitmap;
Rect playerRectangle;
int x, y, playerJumpSpeed, gravity, screenY;
boolean playerIsMoving;
public Player (Context context, int screenX, int screenY) {
this.screenY = screenY;
gravity = 2;
playerBitmap = BitmapFactory.decodeResource(context.getResources(), R.mipmap.ic_launcher);
x = screenX/2 - playerBitmap.getWidth()/2;
y = screenY/2 - playerBitmap.getHeight()/2;
playerRectangle = new Rect(x, y, playerBitmap.getWidth(), playerBitmap.getHeight());
playerJumpSpeed = - 1000;
playerIsMoving = true;
}
public void updatePlayerPosition () {
while (playerIsMoving) {
y += gravity;
break;
}
}
public void playerJump () {
while (playerIsMoving) {
y += playerJumpSpeed;
break;
}
}
public void noLeaveScreen () {
if (y < 0) {
playerJumpSpeed = 0;
} else {
playerJumpSpeed = - 40;
}
if (getY() > (screenY - playerBitmap.getHeight())) {
gravity = 0;
} else {
gravity = 2;
}
}
public int getX () {
return x;
}
public int getY () {
return y;
}
public Bitmap getPlayerBitmap () {
return playerBitmap;
}
public Rect getPlayerRectangle () {
return playerRectangle;
}
}
Enemy Class:
public class Enemy {
Bitmap enemyBitmap;
int enemySpeed, screenX;
boolean isEnemyMoving;
Random random;
public Enemy (Context context, int screenX) {
this.screenX = screenX;
enemyBitmap = BitmapFactory.decodeResource(context.getResources(), R.mipmap.ic_launcher);
random = new Random();
isEnemyMoving = true;
enemySpeed = - 3;
}
public int getEnemySpeed () {
return enemySpeed;
}
public Bitmap getEnemyBitmap () {
return enemyBitmap;
}
}
There are the classes, any help appreciated!
Related
My app has 2 activities a main menu and a game play activity. you click play to start the game play and when you die you can click back to go to the main menu. For some reason when i click play for the third time (meaning ive died and went back to the main menu twice) the game crashes with this error.
FATAL EXCEPTION: main
Process: com.example.jordanschanzenbach.myapplication, PID: 1875
java.lang.OutOfMemoryError: Failed to allocate a 360012 byte allocation with 79976 free bytes and 78KB until OOM
at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:700)
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:535)
at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:558)
at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:588)
at com.example.jordanschanzenbach.myapplication.Obstacle.<init>(Obstacle.java:44)
at com.example.jordanschanzenbach.myapplication.ObstacleManager.populateObstacles(ObstacleManager.java:57)
at com.example.jordanschanzenbach.myapplication.ObstacleManager.<init>(ObstacleManager.java:38)
at com.example.jordanschanzenbach.myapplication.GamePlayScene.<init>(GamePlayScene.java:41)
at com.example.jordanschanzenbach.myapplication.GamePanel.<init>(GamePanel.java:29)
at com.example.jordanschanzenbach.myapplication.MainActivity.onCreate(MainActivity.java:27)
that's not the entire error message but i think i gave you what you needed. Now i tried to make an animation for the obstacles to be spikes instead of just black rectangles but for some reason the spikes will not display and i think it might correspond with the error i receive. But i don't understand why the spikes wont display as i used the same code for the animation for my player.
here is the code for my obstacle
public class Obstacle implements GameObject
{
private Rect rectangle;
private Rect rectangle2;
private int color;
private Animation falling;
private Animation fallingStill;
private Animation fallingAgain;
private AnimationManagerObstacle animationManagerObstacle;
public Rect getRectangle()
{
return rectangle;
}
public void IncrementY(float y )
{
rectangle.top += y;
rectangle.bottom += y;
rectangle2.top += y;
rectangle2.bottom += y;
}
public Obstacle(int rectHeight, int color, int startX, int startY, int playerGap)
{
this.color = color;
BitmapFactory bitfac = new BitmapFactory();
Bitmap fallings = bitfac.decodeResource(GlobalVariables.CURRENT_CONTEXT.getResources(), R.drawable.spikesupsidedown);
Bitmap fallingStills = bitfac.decodeResource(GlobalVariables.CURRENT_CONTEXT.getResources(), R.drawable.spikesupsidedown);
Bitmap fallingAgains = bitfac.decodeResource(GlobalVariables.CURRENT_CONTEXT.getResources(), R.drawable.spikesupsidedown);
falling = new Animation(new Bitmap[]{fallings}, 2);
fallingStill = new Animation(new Bitmap[]{fallings, fallingStills}, 0.5f);
fallingAgain = new Animation(new Bitmap[]{fallings, fallingAgains}, 0.5f);
animationManagerObstacle = new AnimationManagerObstacle(new Animation[]{falling, fallingStill, fallingAgain});
rectangle = new Rect(0, startY, startX, startY + rectHeight);
rectangle2 = new Rect(startX + playerGap, startY, GlobalVariables.SCREEN_WIDTH, startY + rectHeight);
}
public boolean playerCollide(RectPlayer player)
{
return Rect.intersects(rectangle, player.getRectangle()) || Rect.intersects(rectangle2, player.getRectangle());
}
#Override
public void draw(Canvas canvas)
{
Paint paint = new Paint();
paint.setColor(color);
animationManagerObstacle.draw(canvas, rectangle);
canvas.drawRect(rectangle, paint);
canvas.drawRect(rectangle2, paint);
}
#Override
public void update()
{
animationManagerObstacle.update();
}
public void update(Point point)
{
float oldTop = rectangle.top;
rectangle.set(point.x - rectangle.width() / 2,
point.y - rectangle.height() / 2,
point.x + rectangle.width() / 2,
point.y + rectangle.height() / 2);
int state = 0;
if (rectangle.left - oldTop > 1)
{
state = 1;
}
else if (rectangle.left - oldTop < 2)
{
state = 2;
}
animationManagerObstacle.playAnim(state);
animationManagerObstacle.update();
}
}
this is the line that the error message points to
Bitmap fallings = bitfac.decodeResource(GlobalVariables.CURRENT_CONTEXT.getResources(), R.drawable.spikesupsidedown);
here is my obstacle manager where i add and display the obstacles
public class ObstacleManager
{
private ArrayList<Obstacle> obstacles;
private int playerGap;
private int obstacleGap;
private int obstacleHeight;
private int color;
private long startTime;
private long initTime;
private int score = 0;
public ObstacleManager(int playerGap, int obstacleGap, int obstacleHeight, int color)
{
this.playerGap = playerGap;
this.obstacleGap = obstacleGap;
this.obstacleHeight = obstacleHeight;
this.color = color;
startTime = initTime = System.currentTimeMillis();
obstacles = new ArrayList<>();
populateObstacles();
}
public boolean playerCollide(RectPlayer player)
{
for(Obstacle ob : obstacles)
{
if(ob.playerCollide(player))
return true;
}
return false;
}
private void populateObstacles()
{
int currY = -5 * GlobalVariables.SCREEN_HEIGHT / 4;
while(currY < 0)
{
int xStart = (int)(Math.random()*(GlobalVariables.SCREEN_WIDTH - playerGap));
obstacles.add(new Obstacle(obstacleHeight, color, xStart, currY, playerGap));
currY += obstacleHeight + obstacleGap;
}
}
public void update()
{
if (GlobalVariables.GAMEOVER)
{
for (int i = 0; i < 3; i++)
{
obstacles.remove(obstacles.size() - 2);
}
}
int elapsedTime = (int)(System.currentTimeMillis() - startTime);
startTime = System.currentTimeMillis();
float speed = (float)(Math.sqrt((1 + startTime - initTime) / 1750.0)) * GlobalVariables.SCREEN_HEIGHT /17500.0f;
for(Obstacle ob : obstacles)
{
ob.IncrementY(speed * elapsedTime);
}
if(obstacles.get(obstacles.size() - 1).getRectangle().top >= GlobalVariables.SCREEN_HEIGHT * 3/4)
{
int xStart = (int)(Math.random()*(GlobalVariables.SCREEN_WIDTH - playerGap));
obstacles.add(0, new Obstacle(obstacleHeight, color, xStart,
obstacles.get(0).getRectangle().top - obstacleHeight - obstacleGap, playerGap));
obstacles.remove(obstacles.size() - 1);
score++;
if (score > GlobalVariables.HIGHSCORE)
GlobalVariables.HIGHSCORE = score;
}
}
public void draw(Canvas canvas)
{
for(Obstacle ob : obstacles)
ob.draw(canvas);
Paint paint = new Paint();
paint.setTextSize(100);
paint.setColor(Color.RED);
canvas.drawText("" + score, 50, 50 + paint.descent() - paint.ascent(), paint);
canvas.drawText("HighScore: " + GlobalVariables.HIGHSCORE, GlobalVariables.SCREEN_WIDTH / 2 + 50, 50 + paint.descent() - paint.ascent(), paint);
}
}
here is my animation manager
public class AnimationManager
{
private Animation[] animations;
private int animationsIndex = 0;
public AnimationManager(Animation[] animations)
{
this.animations = animations;
}
public void playAnim(int index)
{
for (int i = 0; i < animations.length; i++)
{
if (i == index)
{
if (!animations[index].isPlaying())
{
animations[i].play();
}
}
else
{
animations[i].stop();
}
}
animationsIndex = index;
}
public void draw(Canvas canvas, Rect rect)
{
if (animations[animationsIndex].isPlaying())
{
animations[animationsIndex].draw(canvas, rect);
}
}
public void update()
{
if (animations[animationsIndex].isPlaying())
{
animations[animationsIndex].update();
}
}
}
and finally my animation class
public class Animation
{
private Bitmap[] frames;
private int frameIndex;
private boolean isPlaying = false;
public boolean isPlaying()
{
return isPlaying;
}
public void play()
{
isPlaying = true;
frameIndex = 0;
lastFrame = System.currentTimeMillis();
}
public void stop()
{
isPlaying = false;
}
private float frameTime;
private long lastFrame;
public Animation(Bitmap[] frames, float animTime)
{
this.frames = frames;
frameIndex = 0;
frameTime = animTime / frames.length;
lastFrame = System.currentTimeMillis();
}
public void draw(Canvas canvas, Rect destination)
{
if (!isPlaying)
return;
scaleRect(destination);
canvas.drawBitmap(frames[frameIndex], null, destination, new Paint());
}
private void scaleRect(Rect rect)
{
float whRatio = (float)(frames[frameIndex].getWidth() / frames[frameIndex].getHeight());
if (rect.width() > rect.height())
{
rect.left = rect.right - (int)(rect.height() * whRatio);
}
else
{
rect.top = rect.bottom - (int)(rect.width() * (1 / whRatio));
}
}
public void update()
{
if (!isPlaying)
return;
if (System.currentTimeMillis() - lastFrame > frameTime * 1000)
{
frameIndex++;
if (frameIndex >= frames.length)
frameIndex = 0;
lastFrame = System.currentTimeMillis();
}
}
}
i dont think you necessarily needed all that but just in case :). thanks for any comments to improve or help.
OutOfMemoryError basically means that you tried to use more memory than you can. In this specific example you (bitmap) tried to allocate 360KB though you could only allocate 78KB more. You might have a memory leak somewhere or your bitmap might be too big. I think your Bitmaps might be leaking memory. I'm not an Android expert though.
I'd recommend you to create a method in Obstacle like recycle or something along this way. Then every time you remove Obstacle from obstacles in ObstacleManager call that method. In that method you should aim to recycle all no longer used bitmaps. I'd do it by calling either Animation#recycle on every of your animations or calling AnimationManagerObstacle#recycle. (Animation#recycle would be meant to call recycle on every one of your frames.)
Okay, so I need to start another activity on collision detection, I am a beginner trying to make this simple game and I just cannot figure this out ... It is marked by //This is the place I am trying to start another activity, where I want to start it, the current code gives me error
GameView.java file where I need to start the activity
package fi.itsn.jetfighter;
import android.content.Context;
import android.content.Intent;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import java.util.ArrayList;
import static android.support.v4.app.ActivityCompat.startActivity;
/**
* Created by h on 21.9.2016.
*/
public class GameView extends SurfaceView implements Runnable {
volatile boolean playing;
private Thread gameThread = null;
private Player player;
private Paint paint;
private Canvas canvas;
private SurfaceHolder surfaceHolder;
private Enemy[] enemies;
private Broccoli[] broccolis;
private int enemyCount = 3;
private int broccoliCount = 1;
private ArrayList<Star> stars = new
ArrayList<Star>();
//defining a boom object to display blast
private Boom boom;
public GameView(Context context, int screenX, int screenY) {
super(context);
player = new Player(context, screenX, screenY);
surfaceHolder = getHolder();
paint = new Paint();
int starNums = 100;
for (int i = 0; i < starNums; i++) {
Star s = new Star(screenX, screenY);
stars.add(s);
}
enemies = new Enemy[enemyCount];
for (int i = 0; i < enemyCount; i++) {
enemies[i] = new Enemy(context, screenX, screenY);
}
//initializing boom object
boom = new Boom(context);
broccolis = new Broccoli[broccoliCount];
for (int i = 0; i < broccoliCount; i++) {
broccolis[i] = new Broccoli(context, screenX, screenY);
}
}
#Override
public void run() {
while (playing) {
update();
draw();
control();
}
}
private void update() {
player.update();
//setting boom outside the screen
boom.setX(-250);
boom.setY(-250);
for (Star s : stars) {
s.update(player.getSpeed());
}
for (int i = 0; i < enemyCount; i++) {
enemies[i].update(player.getSpeed());
//if collision occurrs with player
if (Rect.intersects(player.getDetectCollision(), enemies[i].getDetectCollision())) {
//displaying boom at that location
boom.setX(enemies[i].getX());
boom.setY(enemies[i].getY());
enemies[i].setX(-200);
}
}
for (int i = 0; i < broccoliCount; i++) {
broccolis[i].update(player.getSpeed());
if (Rect.intersects(player.getDetectCollision(), broccolis[i].getDetectCollision())) {
startActivity(new Intent(this, end.class));
//This is the place I am trying to start another activity
}
}
}
private void draw() {
if (surfaceHolder.getSurface().isValid()) {
canvas = surfaceHolder.lockCanvas();
canvas.drawColor(Color.BLUE);
paint.setColor(Color.WHITE);
for (Star s : stars) {
paint.setStrokeWidth(s.getStarWidth());
canvas.drawPoint(s.getX(), s.getY(), paint);
}
canvas.drawBitmap(
player.getBitmap(),
player.getX(),
player.getY(),
paint);
for (int i = 0; i < enemyCount; i++) {
canvas.drawBitmap(
enemies[i].getBitmap(),
enemies[i].getX(),
enemies[i].getY(),
paint
);
}
for (int i = 0; i < broccoliCount; i++) {
canvas.drawBitmap(
broccolis[i].getBitmap(),
broccolis[i].getX(),
broccolis[i].getY(),
paint
);
}
//drawing boom image
canvas.drawBitmap(
boom.getBitmap(),
boom.getX(),
boom.getY(),
paint
);
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
private void control() {
try {
gameThread.sleep(17);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void pause() {
playing = false;
try {
gameThread.join();
} catch (InterruptedException e) {
}
}
public void resume() {
playing = true;
gameThread = new Thread(this);
gameThread.start();
}
#Override
public boolean onTouchEvent(MotionEvent motionEvent) {
switch (motionEvent.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_UP:
player.stopBoosting();
break;
case MotionEvent.ACTION_DOWN:
player.setBoosting();
break;
}
return true;
}
}
And here is the Broccoli.java file
package fi.itsn.jetfighter;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Rect;
import java.util.Random;
/**
* Created by h on 22.9.2016.
*/
public class Broccoli {
//bitmap for the enemy
//we have already pasted the bitmap in the drawable folder
private Bitmap bitmap;
private int x;
private int y;
private int speed = 1;
private int maxX;
private int minX;
private int maxY;
private int minY;
//creating a rect object
private Rect detectCollision;
public Broccoli(Context context, int screenX, int screenY) {
bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.broccoli);
maxX = screenX;
maxY = screenY;
minX = 0;
minY = 0;
Random generator = new Random();
speed = generator.nextInt(6) + 10;
x = screenX;
y = generator.nextInt(maxY) - bitmap.getHeight();
//initializing rect object
detectCollision = new Rect(x, y, bitmap.getWidth(), bitmap.getHeight());
}
public void update(int playerSpeed) {
x -= playerSpeed;
x -= speed;
if (x < minX - bitmap.getWidth()) {
Random generator = new Random();
speed = generator.nextInt(10) + 10;
x = maxX;
y = generator.nextInt(maxY) - bitmap.getHeight();
}
//Adding the top, left, bottom and right to the rect object
detectCollision.left = x;
detectCollision.top = y;
detectCollision.right = x + bitmap.getWidth();
detectCollision.bottom = y + bitmap.getHeight();
}
//adding a setter to x coordinate so that we can change it after collision
public void setX(int x){
this.x = x;
}
//one more getter for getting the rect object
public Rect getDetectCollision() {
return detectCollision;
}
//getters
public Bitmap getBitmap() {
return bitmap;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public int getSpeed() {
return speed;
}
}
Try with
startActivity(new Intent(getContext(), end.class));
You need to pass context not this. Here you are extending a class with SurfaceView not Activity so this won't give you context like it gives in Activity
OR
Because you are passing context in constructor so you can also do it like
public GameView(Context context, int screenX, int screenY) {{
super(context);
this.mContext = context;
}
and pass this mContext in Intent
startActivity(new Intent(mContext, end.class));
I'm trying to add multiple sprites to android game using an Array but at the minute only one will display and when I click it rather than it changing to the new sprite animation it freezes on the screen here is the code within my GameView.java and Sprite.java.
GameView.java:
/**
* This class takes care of surface for drawing and touches
*
*/
public class GameView extends SurfaceView implements SurfaceHolder.Callback {
/* Member (state) fields */
private GameLoopThread gameLoopThread;
private Paint paint; // Reference a paint object
/** The drawable to use as the background of the animation canvas */
private Bitmap mBackgroundImage;
private Sprite sprite;
private ArrayList<Sprite> spritesArrayList;
int SpriteAmount = 3;
private int hitCount;
private boolean GameOver = false;
/* For the countdown timer */
private long startTime; // Timer to count down from
private final long interval = 1 * 1000; // 1 sec interval
private CountDownTimer countDownTimer; // Reference to class
private boolean timerRunning = false;
private String displayTime; // To display time on the screen
public GameView(Context context) {
super(context);
spritesArrayList = new ArrayList<Sprite>();
// Focus must be on GameView so that events can be handled.
this.setFocusable(true);
// For intercepting events on the surface.
this.getHolder().addCallback(this);
mBackgroundImage = BitmapFactory.decodeResource(this.getResources(),
R.drawable.dbz);
}
/* Called immediately after the surface created */
public void surfaceCreated(SurfaceHolder holder) {
mBackgroundImage = Bitmap.createScaledBitmap(mBackgroundImage,
getWidth(), getHeight(), true);
// We can now safely setup the game start the game loop.
ResetGame();// Set up a new game up - could be called by a 'play again
// option'
gameLoopThread = new GameLoopThread(this.getHolder(), this);
gameLoopThread.running = true;
gameLoopThread.start();
}
// Sprite List
// To initialise/reset game
private void ResetGame() {
//sprite = new Sprite(this);
for (int P = 0; P < SpriteAmount; P++) {
spritesArrayList.add(sprite = new Sprite(this));
}
hitCount = 0;
GameOver = false;
/* Set paint details */
paint = new Paint();
paint.setColor(Color.WHITE);
paint.setTextSize(20);
// Set timer
startTime = 10;// Start at 10s to count down
// Create new object - convert startTime to milliseconds
countDownTimer = new MyCountDownTimer(startTime * 1000, interval);
countDownTimer.start();// Start it running
timerRunning = true;
}
// This class updates and manages the assets prior to drawing - called from
// the Thread
public void update() {
for (int P = 0; P < SpriteAmount; P++) {
GameOver = false;
spritesArrayList.get(P).update();
}
}
/**
* To draw the game to the screen This is called from Thread, so
* synchronisation can be done
*/
public void doDraw(Canvas canvas) {
canvas.drawBitmap(mBackgroundImage, 0, 0, null);
if (GameOver == false) {
sprite.draw(canvas);
} else if (GameOver == true) {
}
// Draw all the objects on the canvas
canvas.drawText("Hits Obtained =" + hitCount, 5, 25, paint);
canvas.drawText("Time Remaining =" + displayTime, 5, 40, paint);
if (GameOver == true) {
canvas.drawText("Return To Main Menu using return button", 5, 60,
paint);
}
}
// To be used if we need to find where screen was touched
public boolean onTouchEvent(MotionEvent event) {
for (int P = 0; P < SpriteAmount; P++) {
if (spritesArrayList.get(P).wasItTouched(event.getX(), event.getY())) {
/* For now, just renew the Sprite */
spritesArrayList.add(sprite = new Sprite(this));
hitCount++;
}
}
return true;
}
public void surfaceDestroyed(SurfaceHolder holder) {
gameLoopThread.running = false;
// Shut down the game loop thread cleanly.
boolean retry = true;
while (retry) {
try {
gameLoopThread.join();
retry = false;
} catch (InterruptedException e) {
}
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
/* Countdown Timer - private class */
private class MyCountDownTimer extends CountDownTimer {
public MyCountDownTimer(long startTime, long interval) {
super(startTime, interval);
}
public void onFinish() {
displayTime = "Times Over!";
timerRunning = false;
countDownTimer.cancel();
GameOver = true;
}
public void onTick(long millisUntilFinished) {
displayTime = " " + millisUntilFinished / 1000;
}
}// End of MyCountDownTimer
public int getHitCount() {
// TODO Auto-generated method stub
return hitCount;
}
}
Sprite.java:
public class Sprite {
// Needed for new random coordinates.
private Random random = new Random();
// x,y position of sprite - initial position (0,50)
int x = random.nextInt(500);
int X = random.nextInt(500);
int y = random.nextInt(1000);
int Y = random.nextInt(1000);
private int xSpeed = 10;// Horizontal increment of position (speed)
// apply at later date random.nextInt(10)
private int ySpeed = 10;// Vertical increment of position (speed)
// apply at later date random.nextInt(10)
private GameView gameView;
private Bitmap spritebmp;
// Width and Height of the Sprite image
private int bmp_width;
private int bmp_height;
private Integer[] imgid = { R.drawable.kidbuu, R.drawable.guko,
R.drawable.guko_ssj1
};
// Calculation for reverse direction
// x = x - (x - x)
// y = y - (y - y)
public Sprite(GameView gameView) {
this.gameView = gameView;
spritebmp = BitmapFactory.decodeResource(gameView.getResources(),
R.drawable.guko);
this.bmp_width = spritebmp.getWidth();
this.bmp_height = spritebmp.getHeight();
}
// update the position of the sprite
public void update() {
x = x + xSpeed;
y = y + ySpeed;
wrapAround(); // Adjust motion of sprite.
}
public void ReverseRandom() {
X = (x - (x - x));
Y = (y - (y - y));
}
public void draw(Canvas canvas) {
// Draw sprite image
// y = random.nextInt(500);
// x = random.nextInt(500);
canvas.drawBitmap(spritebmp, x, y, null);
}
public int calcX(int value) {
return random.nextInt(value);
}
public int calcY(int value) {
return random.nextInt(value);
}
public void wrapAround() {
ReverseRandom();
// Code to wrap around
if (x < 0)
x = X; // increment x whilst not off screen
if (x >= gameView.getWidth() - spritebmp.getWidth() - xSpeed) { // if
// gone
// of
// the
// right
// sides
// of
// screen
xSpeed = -5;
}
if (x + xSpeed <= 0) {
xSpeed = 5;
}
x = x + xSpeed;
if (y < 0)
y = Y;// increment y whilst not off screen
if (y >= gameView.getHeight() - spritebmp.getWidth() - ySpeed) {// if
// gone
// of
// the
// bottom
// of
// screen
ySpeed = -5;
}
if (y + ySpeed <= 0) {
ySpeed = 5;
}
y = y + ySpeed;
}
/* Checks if the Sprite was touched. */
public boolean wasItTouched(float ex, float ey) {
boolean touched = false;
if ((x <= ex) && (ex < x + bmp_width) && (y <= ey)
&& (ey < y + bmp_height)) {
touched = true;
}
return touched;
}// End of wasItTouched
public void change(Integer[] P) {
imgid = P;
spritebmp = BitmapFactory.decodeResource(gameView.getResources(),
R.drawable.guko_ssj1);
}
}
I have a game that displays circles randomly on the screen. The circles can be green or red at random. If you touch a red circle something happens; if you touch a green circle something happens; but what if you wanted to check if the green circle was displayed and a user did not click it? Here is my code:
public class DrawingView extends View{
public DrawingView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
RectF rectf = new RectF(0, 0, 200, 0);
private static final int w = 100;
public static int lastColor = Color.BLACK;
private final Random random = new Random();
private final Paint paint = new Paint();
private final int radius = 230;
private final Handler handler = new Handler();
public static int redColor = Color.RED;
public static int greenColor = Color.GREEN;
int randomWidth = 0;
int randomHeight = 0;
public static int addPoints = 0;
public static int savedScore;
public static List<String> a = new ArrayList<String>();
public static String[] savedScores = new String[a.size()];
Paint red;
public static int howManyPoints;
public static int highestScore = 0;
boolean isTouched;
Thread newThread = new Thread();
private final Runnable updateCircle = new Runnable() {
#Override
public void run() {
lastColor = random.nextInt(2) == 1 ? redColor : greenColor;
paint.setColor(lastColor);
if(lastColor == greenColor){
isTouched = false;
}
if(addPoints < 10){
handler.postDelayed(this, 850);
}
if(addPoints > 9 && addPoints < 30){
handler.postDelayed(this,700);
}
if(addPoints > 29){
handler.postDelayed(this, 600);
}
if(addPoints > 50){
handler.postDelayed(this, 450);
}
if(addPoints > 100){
handler.postDelayed(this, 400);
}
postInvalidate();
}
};
public void what(){
try {
newThread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(isTouched == false){
howManyPoints = addPoints;
handler.removeCallbacks(updateCircle);
lastColor = redColor;
addPoints = 0;
Intent i = new Intent(this.getContext(), YouFailed.class);
this.getContext().startActivity(i);
}
}
#Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
handler.post(updateCircle);
}
#Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
handler.removeCallbacks(updateCircle);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// your other stuff here
Paint back = new Paint();
back.setColor(Color.BLACK);
Rect background = new Rect();
background.set(0, 0, canvas.getWidth(),canvas.getHeight() );
canvas.drawRect(background, back);
Paint newPaint = new Paint();
newPaint.setColor(Color.BLUE);
newPaint.setTextSize(60);
canvas.drawText("Beta v2", 10, 60, newPaint);
if(random == null){
randomWidth =(int) (random.nextInt(Math.abs(getWidth()-radius/2)) + radius/2f);
randomHeight = (random.nextInt((int)Math.abs((getHeight()-radius/2 + radius/2f))));
}else {
randomWidth =(int) (random.nextInt(Math.abs(getWidth()-radius/2)) + radius/2f);
randomHeight = (random.nextInt((int)Math.abs((getHeight()-radius/2 + radius/2f))));
}
canvas.drawCircle(randomWidth, randomHeight, radius, paint);
what();
red = new Paint();
red.setColor(Color.BLUE);
red.setTextSize(150);
canvas.drawText("" + addPoints, 500, 1350, red);
}
#SuppressWarnings("deprecation")
#Override
public boolean onTouchEvent(MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN){
int x = (int) event.getX();
int y = (int) event.getY();
if(isInsideCircle(x, y) == true){
//Do your things here
if(lastColor == redColor){
//saveScore();
howManyPoints = addPoints;
if(howManyPoints > highestScore){
highestScore = howManyPoints;
}
handler.removeCallbacks(updateCircle);
lastColor = redColor;
addPoints = 0;
Intent i = new Intent(this.getContext(), YouFailed.class);
this.getContext().startActivity(i);
}
if(lastColor == greenColor){
addPoints++;
isTouched = true;
}
}else {
}
}
return false;
}
public void saveScore() {
a.add("" + addPoints);
//if(Integer.parseInt(savedScores[1]) < addPoints){
//savedScores[2] = savedScores[1];
//int x = Integer.parseInt(savedScores[1]);
//x = addPoints;
//}
}
public boolean isInsideCircle(int x, int y){
if ((((x - randomWidth)*(x - randomWidth)) + ((y - randomHeight)*(y - randomHeight))) < ((radius)*(radius))){
return true;
}
return false;
}
}
Just add a boolean hasBeenClicked that is false and becomes true when the user touches it
I am making a Android app. The objective is to make circles that when touched something happens. Here is the onTouch method
public boolean onTouch(View v, MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
if(isInsideCircle(x, y) == true){
//Do your things here
if(redColor == lastColor){
Intent i = new Intent(v.getContext(), YouFailed.class);
v.getContext().startActivity(i);
} else {
addPoints++;
}
}else {
}
return true;
}
This part of the code is the thing that is not functioning properly here is the entire class below.
public class DrawingView extends View{
public DrawingView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
RectF rectf = new RectF(0, 0, 200, 0);
private static final int w = 100;
public static int lastColor = Color.BLACK;
private final Random random = new Random();
private final Paint paint = new Paint();
private final int radius = 230;
private final Handler handler = new Handler();
public static int redColor = Color.RED;
public static int greenColor = Color.GREEN;
int randomWidth = 0;
int randomHeight = 0;
public static int addPoints = 0;
private final Runnable updateCircle = new Runnable() {
#Override
public void run() {
lastColor = random.nextInt(2) == 1 ? redColor : greenColor;
paint.setColor(lastColor);
invalidate();
handler.postDelayed(this, 1000);
}
};
#Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
handler.post(updateCircle);
}
#Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
handler.removeCallbacks(updateCircle);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// your other stuff here
if(random == null){
randomWidth =(int) (random.nextInt(Math.abs(getWidth()-radius/2)) + radius/2f);
randomHeight = (random.nextInt((int)Math.abs((getHeight()-radius/2 + radius/2f))));
}else {
randomWidth =(int) (random.nextInt(Math.abs(getWidth()-radius/2)) + radius/2f);
randomHeight = (random.nextInt((int)Math.abs((getHeight()-radius/2 + radius/2f))));
}
canvas.drawCircle(randomWidth, randomHeight + radius/2f, radius, paint);
paint.setColor(Color.BLACK);
paint.setTextSize(150);
canvas.drawText("Score: " + addPoints, 120, 300, paint);
}
public boolean onTouch(View v, MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
if(isInsideCircle(x, y) == true){
//Do your things here
if(redColor == lastColor){
Intent i = new Intent(v.getContext(), YouFailed.class);
v.getContext().startActivity(i);
} else {
addPoints++;
}
}else {
}
return true;
}
public boolean isInsideCircle(int x, int y){
if ((((x - randomWidth)*(x - randomWidth)) + ((y - randomHeight)*(y - randomHeight))) < ((radius)*(radius)))
return true;
return false;
}
}