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));
Related
I wanted to create a game in which one could move a ball in a labyrinth using accelerometer sensor. In one of the classes extending from View I have the labyrinth, the ball, the goal and a method which draws them, a method which controls the movement of the ball.
package pl.wsiz.greatlabyrinth;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import androidx.annotation.Nullable;
import java.util.ArrayList;
import java.util.Random;
import java.util.Stack;
public class GameView extends View {
private enum Direction{
up, down, left, right
}
private Cell[][] cells;
private Cell player, exit;
private static final int columns = 11, rows = 20;
private static final float wallThickness = 5;
private float cellSize, hMargin, vMargin;
private Paint wallPaint, playerPaint, exitPaint;
private Random random;
public GameView(Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
wallPaint = new Paint();
wallPaint.setColor(Color.BLACK);
wallPaint.setStrokeWidth(wallThickness);
playerPaint = new Paint();
playerPaint.setColor(Color.RED);
exitPaint = new Paint();
exitPaint.setColor(Color.BLUE);
random = new Random();
createLabyrinth();
}
private Cell getNeighbour(Cell cell){
ArrayList<Cell> neighbours = new ArrayList<>();
//left neighbour
if(cell.column > 0) {
if (!cells[cell.column - 1][cell.row].visited) {
neighbours.add(cells[cell.column - 1][cell.row]);
}
}
//right neighbour
if(cell.column < columns-1) {
if (!cells[cell.column + 1][cell.row].visited) {
neighbours.add(cells[cell.column + 1][cell.row]);
}
}
//top neighbour
if(cell.row > 0) {
if (!cells[cell.column][cell.row - 1].visited) {
neighbours.add(cells[cell.column][cell.row - 1]);
}
}
//bottom neighbour
if(cell.row < rows-1) {
if (!cells[cell.column][cell.row + 1].visited) {
neighbours.add(cells[cell.column][cell.row + 1]);
}
}
if(neighbours.size() > 0) {
int index = random.nextInt(neighbours.size());
return neighbours.get(index);
}
return null;
}
private void removeWall(Cell current, Cell next){
if(current.column == next.column && current.row == next.row+1) {
current.topWall = false;
next.bottomWall = false;
}
if(current.column == next.column && current.row == next.row-1) {
current.bottomWall = false;
next.topWall = false;
}
if(current.column == next.column+1 && current.row == next.row) {
current.leftWall = false;
next.rightWall = false;
}
if(current.column == next.column-1 && current.row == next.row) {
current.rightWall = false;
next.leftWall = false;
}
}
private void createLabyrinth(){
Stack<Cell> stack = new Stack<>();
Cell current, next;
cells = new Cell[columns][rows];
for(int i=0; i<columns; i++){
for(int j=0; j<rows;j++){
cells[i][j] = new Cell(i, j);
}
}
player = cells[0][0];
exit = cells[columns-1][rows-1];
current = cells[0][0];
current.visited = true;
do {
next = getNeighbour(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.WHITE);
int width = getWidth();
int height = getHeight();
if(width/height < columns/rows) {
cellSize = width/(columns+3);
}
else {
cellSize = height/(rows+3);
}
hMargin = (width-columns*cellSize)/2;
vMargin = (height-rows*cellSize)/2;
canvas.translate(hMargin, vMargin);
for(int i=0; i<columns; i++){
for(int j=0; j<rows;j++){
if(cells[i][j].topWall)
canvas.drawLine(i*cellSize, j*cellSize, (i+1)*cellSize,j*cellSize, wallPaint);
if(cells[i][j].leftWall)
canvas.drawLine(i*cellSize, j*cellSize, i*cellSize,(j+1)*cellSize, wallPaint);
if(cells[i][j].bottomWall)
canvas.drawLine(i*cellSize, (j+1)*cellSize, (i+1)*cellSize,(j+1)*cellSize, wallPaint);
if(cells[i][j].rightWall)
canvas.drawLine((i+1)*cellSize, j*cellSize, (i+1)*cellSize,(j+1)*cellSize, wallPaint);
}
}
float margin = cellSize/2;
canvas.drawCircle(player.column*cellSize+margin, player.row*cellSize+margin,(cellSize/2)-5, playerPaint);
canvas.drawCircle(exit.column*cellSize+margin, exit.row*cellSize+margin,(cellSize/2)-5, exitPaint);
}
private void movePlayer(Direction direction){
switch (direction){
case up:
if(!player.topWall)
player = cells[player.column][player.row-1];
break;
case down:
if(!player.bottomWall)
player = cells[player.column][player.row+1];
break;
case left:
if(!player.leftWall)
player = cells[player.column-1][player.row];
break;
case right:
if(!player.rightWall)
player = cells[player.column+1][player.row];
break;
}
checkExit();
invalidate();
}
private void checkExit(){
if(player == exit)
createLabyrinth();
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN)
return true;
if(event.getAction() == MotionEvent.ACTION_MOVE){
float x = event.getX();
float y = event.getY();
float playerCenterX = hMargin + (player.column+0.5f)*cellSize;
float playerCenterY = vMargin + (player.row+0.5f)*cellSize;
float xDirection = x - playerCenterX;
float yDirection = y - playerCenterY;
float absXD = Math.abs(xDirection);
float absYD = Math.abs(yDirection);
if(absXD > cellSize || absYD > cellSize){
if(absXD>absYD){
//move in x-direction
if(xDirection>0){
movePlayer(Direction.right);
}
else{
movePlayer(Direction.left);
}
}
else {
//move in y-direction
if (yDirection > 0) {
movePlayer(Direction.down);
} else {
movePlayer(Direction.up);
}
}
}
return true;
}
return super.onTouchEvent(event);
}
private class Cell {
boolean leftWall = true;
boolean rightWall = true;
boolean topWall = true;
boolean bottomWall = true;
boolean visited = false;
int column, row;
public Cell(int column, int row) {
this.column = column;
this.row = row;
}
}
}
In the second class extending AppCompatActivity I have the code of accelerometer to be used in moving the ball.
package pl.wsiz.greatlabyrinth;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
public class GameActivity extends AppCompatActivity implements SensorEventListener {
private SensorManager sensorManager;
private Sensor accelerometr;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game);
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
accelerometr = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
}
#Override
public void onSensorChanged(SensorEvent event) {
float x = event.values[0];
float y = event.values[1];
float z = event.values[2];
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
#Override
protected void onResume() {
super.onResume();
sensorManager.registerListener(this, accelerometr, SensorManager.SENSOR_DELAY_GAME);
}
#Override
protected void onPause() {
super.onPause();
sensorManager.unregisterListener(this);
}
}
I do not know how to join accelerometer with the first quoted code so that the ball moves using sensor and not onTouchEvent method. I would be grateful for some code with a little explanation.
I am trying to edit this game code and call a second activity in //Show Result in order to go to another screen when the game is over.
There's an error "cannot resolve contructor".
enter image description here
I think the problem is with the intent but I am not really sure about where I can put it.
Can you help me?
Thank you
This is the GameView code
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.content.Intent;
public class GameView extends View {
// Canvas
private int canvasWidth;
private int canvasHeight;
// J
//private Bitmap j;
private Bitmap j[] = new Bitmap[2];
private int jX = 10;
private int jY;
private int jSpeed;
// Blue Ball
private int blueX;
private int blueY;
private int blueSpeed = 15;
private Paint bluePaint = new Paint();
// Black Ball
private int blackX;
private int blackY;
private int blackSpeed = 20;
private Paint blackPaint = new Paint();
// Background
private Bitmap bgImage;
// Score
private Paint scorePaint = new Paint();
private int score;
// Level
private Paint levelPaint = new Paint();
// Life
private Bitmap life[] = new Bitmap[2];
private int life_count;
// Status Check
private boolean touch_flg = false;
public GameView(Context context) {
super(context);
j[0] = BitmapFactory.decodeResource(getResources(), R.drawable.jun1);
j[1] = BitmapFactory.decodeResource(getResources(), R.drawable.jun2);
bgImage = BitmapFactory.decodeResource(getResources(), R.drawable.bg);
bluePaint.setColor(Color.BLUE);
bluePaint.setAntiAlias(false);
blackPaint.setColor(Color.BLACK);
blackPaint.setAntiAlias(false);
scorePaint.setColor(Color.BLACK);
scorePaint.setTextSize(32);
scorePaint.setTypeface(Typeface.DEFAULT_BOLD);
scorePaint.setAntiAlias(true);
levelPaint.setColor(Color.DKGRAY);
levelPaint.setTextSize(32);
levelPaint.setTypeface(Typeface.DEFAULT_BOLD);
levelPaint.setTextAlign(Paint.Align.CENTER);
levelPaint.setAntiAlias(true);
life[0] = BitmapFactory.decodeResource(getResources(), R.drawable.heart);
life[1] = BitmapFactory.decodeResource(getResources(), R.drawable.heart_g);
// First position.
jY = 500;
score = 0;
life_count = 3;
}
#Override
protected void onDraw(Canvas canvas) {
canvasWidth = canvas.getWidth();
canvasHeight = canvas.getHeight();
canvas.drawBitmap(bgImage, 0, 0, null);
// Bird
int minBirdY = j[0].getHeight();
int maxBirdY = canvasHeight - j[0].getHeight() * 3;
jY += jSpeed;
if (jY < minBirdY) jY = minBirdY;
if (jY > maxBirdY) jY = maxBirdY;
jSpeed += 2;
if (touch_flg) {
// Flap wings.
canvas.drawBitmap(j[1], jX, jY, null);
touch_flg = false;
} else {
canvas.drawBitmap(j[0], jX, jY, null);
}
// Blue
blueX -= blueSpeed;
if (hitCheck(blueX, blueY)) {
score += 10;
blueX = -100;
}
if (blueX < 0) {
blueX = canvasWidth + 20;
blueY = (int) Math.floor(Math.random() * (maxBirdY - minBirdY)) + minBirdY;
}
canvas.drawCircle(blueX, blueY, 10, bluePaint);
// Black
blackX -= blackSpeed;
if (hitCheck(blackX, blackY)) {
blackX = -100;
life_count--;
if (life_count == 0) {
// Show Result
Intent i = new Intent(this, result.class);
i.putExtra("SCORE", score);
}
}
if (blackX < 0) {
blackX = canvasWidth + 200;
blackY = (int) Math.floor(Math.random() * (maxBirdY - minBirdY)) + minBirdY;
}
canvas.drawCircle(blackX, blackY, 20, blackPaint);
// Score
canvas.drawText("Score : " + score, 20, 60, scorePaint);
// Level
canvas.drawText("Lv.1", canvasWidth / 2, 60, levelPaint);
// Life
for (int i = 0; i < 3; i++) {
int x = (int) (560 + life[0].getWidth() * 1.5 * i);
int y = 30;
if (i < life_count) {
canvas.drawBitmap(life[0], x, y, null);
} else {
canvas.drawBitmap(life[1], x, y, null);
}
}
}
public boolean hitCheck(int x, int y) {
if (jX < x && x < (jX + j[0].getWidth()) &&
jY < y && y < (jY + j[0].getHeight())) {
return true;
}
return false;
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
touch_flg = true;
jSpeed = -20;
}
return true;
}
}
View doesn't extend the Context class, which Intent's constructor needs for what you're doing.
Use
Intent i = new Intent(getContext(), result.class);
in your View class.
I have a sprite sheet of 612x864 dimension with 5 rows and 5 columns .My problem is how can I load it and animate it? I want to move the cat sprite in y-axis only .I've already try but my code is not working properly. Here is my code.
In GameView.java
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class GameView extends SurfaceView {
private Bitmap bmp;
private SurfaceHolder holder;
private GameLoopThread gameLoopThread;
private Sprite sprite;
public GameView(Context context) {
super(context);
gameLoopThread = new GameLoopThread(this);
holder = getHolder();
holder.addCallback(new SurfaceHolder.Callback() {
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
gameLoopThread.setRunning(false);
while (retry) {
try {
gameLoopThread.join();
retry = false;
} catch (InterruptedException e) {
}
}
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
gameLoopThread.setRunning(true);
gameLoopThread.start();
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
}
});
bmp = BitmapFactory.decodeResource(getResources(), R.drawable.catsprite);
sprite = new Sprite(this,bmp);
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.BLACK);
sprite.onDraw(canvas);
}
}
GameLoopThread.java
import android.graphics.Canvas;
public class GameLoopThread extends Thread {
static final long FPS = 10;
private GameView view;
private boolean running = false;
public GameLoopThread(GameView view) {
this.view = view;
}
public void setRunning(boolean run) {
running = run;
}
#Override
public void run() {
long ticksPS = 1000 / FPS;
long startTime;
long sleepTime;
while (running) {
Canvas c = null;
startTime = System.currentTimeMillis();
try {
c = view.getHolder().lockCanvas();
synchronized (view.getHolder()) {
view.onDraw(c);
}
} finally {
if (c != null) {
view.getHolder().unlockCanvasAndPost(c);
}
}
sleepTime = ticksPS-(System.currentTimeMillis() - startTime);
try {
if (sleepTime > 0)
sleep(sleepTime);
else
sleep(10);
} catch (Exception e) {}
}
}
}
Sprite.java
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Rect;
public class Sprite {
private static final int BMP_ROWS = 5;
private static final int BMP_COLUMNS = 5;
private int x = 0;
private int y = 0;
private int ySpeed = 3;
private GameView gameView;
private Bitmap bmp;
private int currentFrame = 1;
private int width;
private int height;
public Sprite(GameView gameView, Bitmap bmp) {
this.gameView = gameView;
this.bmp = bmp;
this.width = bmp.getWidth() / BMP_COLUMNS;
this.height = bmp.getHeight() / BMP_ROWS;
}
private void update() {
if (y > gameView.getWidth() - width - y) {
ySpeed = -5;
}
if (y + y < 0) {
ySpeed = 5;
}
y = y + ySpeed;
currentFrame = ++currentFrame % BMP_COLUMNS;
}
public void onDraw(Canvas canvas) {
update();
int srcX = currentFrame * width;
int srcY = 1 * height;
Rect src = new Rect(srcX, srcY, srcX + width, srcY + height);
Rect dst = new Rect(x, y, x + width, y + height);
canvas.drawBitmap(bmp, src, dst, null);
}
}
I'll recommend you to use this library. It's great for Sprite Animation. It has some limitations though, but it works fine.
Here is the code how I done it.
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.runningcat);
int width = bitmap.getWidth();
int height = bitmap.getHeight();
int frameWidth = width / 5; //you have 5 columns
int frameHeight = height / 5; //and 5 rows
int frameNum = 25; //there would be 25 images
SpriteSheetDrawer spriteSheetDrawer = new SpriteSheetDrawer(
bitmap,
frameWidth,
frameHeight,
frameNum)
.spriteLoop(true)
.frequency(2); //change it as per your need
DisplayObject displayObject = new DisplayObject();
displayObject
.with(spriteSheetDrawer)
.tween()
.tweenLoop(true)
.transform(0, 0) //I have changed it according to my need, you can also do this by changing these values
.toX(4000, 0) //this one too.
.end();
//In actual example, it's set as animation starts from one end of the screen and goes till the other one.
FPSTextureView textureView = (FPSTextureView) findViewById(R.id.fpsAnimation);
textureView.addChild(displayObject).tickStart();
Problem is in src value that you're using in method. canvas.drawBitmap(bmp, src, dst, null); srcY should be zero. I've tested here.
private Bitmap character;
private counter,charFrame;
private RectF annonymousRectF;
private Rect annonymousRect;
public Sprite() {
character=BitmapFactory.decodeResource(context.getResources(), R.drawable.flipchar2);
annonymousRect=new Rect();
annonymousRectF=new RectF();
}
public void update() {
counter++;
if(counter%5==0)
if(charFrame<NO_CHAR_FRAME-1)
charFrame++;
else
charFrame=0;
}
public void draw(){
annonymousRect.set(charFrame*character.getWidth()/NO_CHAR_FRAME,0,(charFrame+1)*character.getWidth()/NO_CHAR_FRAME,character.getHeight());
annonymousRectF.set(-width*.015f,height*.35f,width*.5f,height*.58f); //set value according to where you want to draw
canvas.drawBitmap(character, annonymousRect,annonymousRectF, null);
}
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!
I have a rectangle I want to move up the screen at a constant rate and am confused as to why my code isn't working. Below is the code:
package com.ashmore.MyGame;
import java.util.ArrayList;
import java.util.List;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.Log;
import com.ashmore.framework.Game;
import com.ashmore.framework.Graphics;
import com.ashmore.framework.Image;
import com.ashmore.framework.Screen;
import com.ashmore.framework.Input.TouchEvent;
public class GameScreen extends Screen {
enum GameState {
Ready, Running, Paused
}
GameState state = GameState.Ready;
boolean BarisMoving = false;
private ArrayList<Rect> rectangles = new ArrayList<Rect>();
int bar_x = 32;
int bar_y = 653;
int bar_width = 183;
int bar_height = 648;
Rect bar;
Paint paint;
public GameScreen(Game game) {
super(game);
// Initialize game objects here
bar = new Rect();
bar.set(bar_x, bar_y, bar_width, bar_height);
// Defining a paint object
paint = new Paint();
paint.setTextSize(30);
paint.setTextAlign(Paint.Align.CENTER);
paint.setAntiAlias(true);
paint.setColor(Color.WHITE);
}
private void updateRunning(List<TouchEvent> touchEvents, float deltaTime) {
// 1. All touch input is handled here:
int len = touchEvents.size();
for (int i = 0; i < len; i++) {
TouchEvent event = touchEvents.get(i);
BarisMoving = true;
if (event.type == TouchEvent.TOUCH_UP) {
if (ScalesScreen.scaleType.equals("C")) {
rectangles.add(new Rect(56, 400, 80, 435));
//rectangles.get(0);
break;
}
if (BarisMoving) {
bar_y = bar_y -= 10;
}
for (Rect rect : rectangles) {
if(bar.intersect(rect)) {
checkButtons();
}
}
}
}
private void checkButtons() {
Log.d("GameScreen","Note and Bar Intersected");
}
#Override
public void paint(float deltaTime) {
Graphics g = game.getGraphics();
Paint paint = new Paint();
Paint paint2 = new Paint();
paint.setColor(Color.RED);
paint2.setColor(Color.RED);
for (Rect rect : rectangles) {
g.drawRect(rect, paint);
}
g.drawRect(bar, paint2);
}
private boolean inBounds(TouchEvent event, int x, int y, int width,
int height) {
if (event.x > x && event.x < x + width - 1 && event.y > y
&& event.y < y + height - 1)
return true;
else
return false;
}
}
I am probably missing something really basic. However, I can't seem to find the issue. Any help is appreciated!
I have figured out my problem. The problem was where my code was placed in the updateRunning() method. In my question, the setting of the boolean BarisMoving was set equal to "true" when there was a touch event:
int len = touchEvents.size();
for (int i = 0; i < len; i++) {
TouchEvent event = touchEvents.get(i);
BarisMoving = true;
The boolean had to be moved outside of this (above int len = touchEvents.size();) and outside of the whole touch event area to work the way I wanted (outside of the for () { and the ending bracket }).