I have this class which extends SurfaceView. The code that I have so far makes the player follow my finger, but it also allows the player to "teleport" to wherever the finger goes and I do not want that.
#Override
public boolean onTouchEvent(MotionEvent event) {
pointerX = (int)event.getX();
pointerY = (int)event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (!player.getPlaying()) {
player.setPlaying(true);
}
if (!player.playerAlive) {
if ((pointerX >= rescaleX(600) && pointerX <= rescaleX(842)) && (pointerY >= rescaleY(900) && pointerY <= rescaleY(1142))) {
//newGame();
player.setX(600);
player.setY(900);
}
}
if (player.playerAlive) {
// player.move(true);
}
break;
case MotionEvent.ACTION_MOVE:
if (!player.getPlaying()){
player.setPlaying(true);
player.move(true);
} else {
player.move(true);
}
break;
case MotionEvent.ACTION_UP:
//player.move(true);
if (!player.playerAlive) {
if ((pointerX >= rescaleX(600) && pointerX <= rescaleX(842)) && (pointerY >= rescaleY(900) && pointerY <= rescaleY(1142))) {
newGame();
player.setX(600);
player.setY(900);
}
}
break;
}
return true;
//return super.onTouchEvent(event);
}
Here is the move() method in the player class:
public void move(boolean b) {
if(b){
if((GamePanel.pointerX * GamePanel.WIDTH / MainActivity.dispX) - 141 >= 1380 - getWidth()){setX(1380-getWidth());}
if((GamePanel.pointerY * GamePanel.HEIGHT / MainActivity.dispY) - 141 >= 1880 - getHeight()){setY(1880 - getHeight());}
setX((int) ((GamePanel.pointerX * GamePanel.WIDTH / MainActivity.dispX) - 141));
setY((int) ((GamePanel.pointerY * GamePanel.HEIGHT / MainActivity.dispY) - 141));
}
Don't "directly" translate finger inputs into 'logic' for moving things.
You should have your onTouchEvent method reads the X and Y values of where a finger press is, and then passes that to some logic. That logic should then decide if that info should be passed to a new method moveCharacterTo(x,y)
the 'logic' I mention above could be several things, You could use the strategy pattern to decide what 'strategy/policy(algorithm)' should be used to process the screen. Or you could just have a single class with a method to compare touch events and see if they are 'close' to the character or not, and then react accordingly.
Related
In the below code every time keycode 144 is pressed , i want to perform some function when the time difference between keypress down and up is greater than 1000 millisecond. But i have notice that when keydown exceed around 100 millisecond, it keep on repeatedly calling keydown, instead of waiting for keyup listener and finally calculating difference which is false as it caculate difference from the last keydown time. how to program in such a way that listener should call only once key down until kep up event is trigger
#Override
public boolean dispatchKeyEvent(KeyEvent event) {
long diff=0;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
down = System.currentTimeMillis();
Log.e("current_down",String.valueOf((down)));
break;
case MotionEvent.ACTION_UP:
Log.e("current_down2",String.valueOf((down)));
//this is the time in milliseconds
diff = (System.currentTimeMillis()- down);
break;
}
int keyCode = event.getKeyCode();
Log.e("javan",String.valueOf((keyCode)));
if (event.getAction() == KeyEvent.ACTION_UP && keyCode == 144) {
if(diff >1000){
//do something
}
}
long diff = 0; // these two values should be declared at the start of the
long down = 0; // method
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if(down == 0) {
down = System.currentTimeMillis(); // save current time if nothing is saved
Log.e("current_down",String.valueOf((down)));
}
break;
case MotionEvent.ACTION_UP:
Log.e("current_down2",String.valueOf((down)));
//this is the time in milliseconds
diff = (System.currentTimeMillis()- down);
down = 0; // if you need the value of down afterwards,
// you can create another variable and save it there,
// this should be reset to 0 after action up for your case
}
Now, there are most certainly other ways, but this one was off the top of my head.
I am reading "Learning Java by Building Android Games" and in a Retro Squash Game example I don't know how to implement collision detection for the racket. The movement of the racket uses onTouchEvent. I have tried to implement an if statement but it deosn't get checked until the next touch event- so it doesn't work properly. Please help.
//Event that handles in which direction is the racket moving according to where is the user touching the screen
#Override
public boolean onTouchEvent(MotionEvent motionEvent) {
//gets the movement action without the pointers(ACTION_MASK) ??? -U: handles multitouch
switch (motionEvent.getAction() & MotionEvent.ACTION_MASK) {
//what happens if user touches the screen and holds
case MotionEvent.ACTION_DOWN:
//if the screen was touched on the right side of the display than move the racket right
if (motionEvent.getX() >= (screenWidth / 2) && racketPosition.x <= screenWidth) {
racketIsMovingLeft = false;
racketIsMovingRight = true;
} else if (motionEvent.getX() < (screenWidth / 2) && racketPosition.x >= 0) {
racketIsMovingLeft = true;
racketIsMovingRight = false;
} else {
racketIsMovingLeft = false;
racketIsMovingRight = false;
}
break;
//when the user lets go of the screen the racket immediately stops moving
case MotionEvent.ACTION_UP:
racketIsMovingLeft = false;
racketIsMovingRight = false;
break;
}
return true;
}
Ok. I have found the solution. I wasn't looking at the right piece of code - sorry. I have edited the piece which is responsible for changing the racketPoint.x of the racket. Here it is:
public void updateCount() {
//change the racket position according to the movement
if (racketIsMovingRight && (racketPosition.x+racketWidth/2)<=screenWidth) {
racketPosition.x += racketSpeed;
}
if (racketIsMovingLeft && (racketPosition.x-racketWidth/2)>=0) {
racketPosition.x -= racketSpeed;
}
//rest of the code
I'm making a snake game and I've encountered an error.
I have tried two different loops: thread.sleep and Timer.schedule.
I have gotten the same problem.
It will be working fine, but at random intervals, it will start to skip every other frame for 6-10 frames.
In case I wasn't clear, 1 frame is
#Override public void paintComponent(Graphics G){...}
being called. (I have also tried paint)
This has occurred in some other games I've created, but not all. What can I do to fix it?
Here's a full copy of the code:
https://github.com/jnmcd/Snake/blob/master/Code.java
EDIT: I've done some debugging. It appears that the it's not a problem with the paint. The JPanel doesn't always update. What can I do to fix it?
I found what I needed to do. I had to add a revaidate() after the repaint().
Also In the checkKillCollisions you have to break the loop right after you found the losing condition.
Also if the game ends it keeps on showing the error message[Dialog] for which there i no end.So I have created a flag gameOver to check is game is over or not in Snake Class
static Boolean gameOver = false;//Defined in Snake Class
public void checkKillCollisions() {
boolean lose = false;
for (int i = 1; i < Snake.segments.size(); i++) {
if (Snake.segments.get(i).x == x && Snake.segments.get(i).y == y) {
lose = true;
break;//Have to do this
}
}
if (x >= 60 || x < 0 || y >= 60 || y < 0) {
lose = true;
}
if (lose) {
Snake.window.popUp("You Lose");
}
Snake.gameOver = lose;//Will set the gameOVer flag in Snake class
}
And I've modified the Loop class to stop running right after the gameOver flag is set to true
class Loop extends TimerTask {
#Override
public void run() {
if (!Snake.gameOver) {
Snake.updates();
Snake.window.render();
} else {
System.out.println("Game Over");
cancel();
Snake.window.dispose();
}
}
}
I wonder how to remove the conditional statements and replace it with method. for code without listener, I can do it. but this one has the listener event (arg0), which makes me confused. fyi, this code is in the Main Class, and I want to get rid these code out of the main class.
thanks for your help!!
#Override
public void onMotionSensingEvent( MotionSensingEvent arg0) {
double gradient = 1.38;
double speed;
float testpitch = 0;
testpitch = arg0.getOrientation().getPitch();
float testroll = 0;
testroll = arg0.getOrientation().getRoll();
if (testroll > 16 && flyingControl)
{
speed = gradient*testroll-22.1;
System.out.println("kanan = " + speed);
ardrone.goRight(speed);
}
else if (testroll < (-24) && flyingControl)
{
speed = gradient*testroll*-1 - 22.1;
System.out.println("kiri = " + speed);
ardrone.goLeft(speed);
}
else if (testpitch < (-20) && flyingControl)
{
System.out.println("go up");
ardrone.up();
}
else if (testpitch > 20 && flyingControl)
{
System.out.println("go down");
ardrone.down();
}
else
{
ardrone.stop();
}
}
Alright, so i cant figure out how to make this rpg game im working for android have collision.
I draw the map on the screen in a drawable portion that the character is located in. I move the character by a 64 amount across the screen and when it hits the bounds of the screen it will then move the map and look like the character is moving across the map. It stop when the map hits the end it doesnt move the screen any more. What im trying to do is figure out a away to check if my character is in a certain bitmap and not let it pass through. Here is the code for my player moving, and the map itself. The character and the tiles are bitmaps.
Anything else needed to allow you to help me better comment and i will post more and how it works.
Edit:
sp.yp and sp.xp is the position of the character on screen.
This Draw the map to the screen:
public void draw(Canvas canvas){
//How many tiles are on the screen length times width
for(int x = 0; x <= 31;x++){
for(int y = 0; y <= 17;y++){
switch(Map[Mapx + x][Mapy + y]){
case 0:
canvas.drawBitmap(BLOCK_ROCK, x*32,y*32,null);
break;
case 1:
canvas.drawBitmap(BLOCK_OCEAN, x*32,y*32,null);
break;
case 2:
canvas.drawBitmap(BLOCK_GRASS, x*32,y*32,null);
break;
case 3:
canvas.drawBitmap(BLOCK_ROCK, x*32,y*32,null);
break;
case 4:
canvas.drawBitmap(BLOCK_FLOWER, x*32,y*32,null);
break;
}
}
}
}
This is the movment of the player, these methods are called when person hits the keypad i have drawn to the screen:
public void Down(){
if(sp.yp == 512){
if(w.Mapy == w.mapheight - 17 - 1){
}else{
w.Mapy +=1;
}
}else{
sp.setYd(64);
sp.update();
sp.setYd(0);
}
}
public void Left(){
if(sp.xp == box.xMin + 32){
sp.isRight = false;
if(w.Mapx == 0){
}else{
w.Mapx -=1;
}
}else{
sp.isRight = false;
sp.setXd(-64);
sp.update();
sp.xd = 0;
}
}
public void Jump(){
if(sp.yp == 64){
if(w.Mapy == 0){
}else{
w.Mapy -=1;
}
}else{
sp.setYd(-64);
sp.update();
sp.setYd(0);
}
}
public void Right(){
if(sp.xp == 992){
sp.isRight = true;
if(w.Mapx == w.mapwidth - 31 - 1){
}else{
w.Mapx +=1;
}
}else{
sp.isRight = true;
sp.setXd(64);
sp.update();
sp.xd = 0;
}
}
You should look into a game engine to handle this type of thing. There are several that are easy to import into your project and provide a great deal of functionality so you can work on designing the game and media resources more. Trust me, you probably don't want to code the whole engine.
Check
AndEngine - http://www.andengine.org/
Libgdx - http://code.google.com/p/libgdx/
I suggest AndEngine because there is a great app of simple examples you can use to experiment with. You can find it on:
code.google.com/p/ andengineexamples/
(no space in the address... sorry couldn't post more than two links)