[UPDATE] i changed the order a bit so i call the super.act(delta) at the end of the method and it seems to help a bit! But not that sure about it yet.
I got a square system for my map. So its an 2D array and i i make one move the figure does move from one square to the next. While that it's not possible to "stop" the figure between 2 squares. When my characters made one move i check if the Touchpad is touched and if yes i start the next move. While that it seems to lag sometimes and i dont know why!? I really hope you may find the "lag". Here is how i calculate the next move inside the act()of my Actor Character:
#Override
public void act(float delta) {
super.act(delta); // so the actions work
if (moveDone) {
if (screen.gameHud.pad.isTouched()) {
// check in which direction is the touchcontroller
if (screen.gameHud.pad.getKnobPercentX() < 0
&& Math.abs(screen.gameHud.pad.getKnobPercentY()) < Math
.abs(screen.gameHud.pad.getKnobPercentX())) {
// checkt if the |x|>|y|
if (checkNextMove(Status.LEFT)) {
this.status = Status.LEFT;
move(Status.LEFT);
this.screen.map.mapArray[(int) (this.mapPos.x)][(int) this.mapPos.y] = Config.EMPTYPOSITION;
this.screen.map.mapArray[(int) (this.mapPos.x - 1)][(int) this.mapPos.y] = Config.CHARSTATE;
this.mapPos.x--;
moveDone = false;
}
} else if //.... rest is the same just with other directions
else{ //if touchpad isnt touched!
setIdle();
}
updateSprite(delta); //just change the textureRegion if its time for that
} //methode end
Okay so you need some more informations i am sure. Checkmoves like this:
case LEFT:
if (this.mapPos.x - 1 >= 0)
if (this.screen.map.mapArray[(int) (this.mapPos.x - 1)][(int) this.mapPos.y] == Config.EMPTYPOSITION)
return true;
break; //same for all other just direction changin
And the last you need to know is the move(_) i guess. It does add an moveTo Action to my figures.
public void move(Status direction) {
switch (direction) {
case LEFT:
this.addAction(Actions.sequence(
Actions.moveTo((getX() - Config.BLOCK_SIZE), getY(), speed),
moveDoneAction));
break;
moveDoneAction is a simple RunnableAction that set the boolean moveDone to true if its done moving.
i really hope you can help. If you need some more informations please let me know as comment!
There are better tools than StackOverflow for optimizing Android code. Use a profiler and see what is actually happening. Specifically, the traceview profiler: how to use traceview in eclipse for android development? (If you're not using Eclipse, you can use traceview directly via the ADT.)
Related
So for a school project, I have to create a game with a program called 'Processing'.
I am creating a main menu with the switch statement. For that I want to use the buttons 'Start', 'Help', and 'exit'.i would like to use those buttons to change the variables of the switch statement. Therefore I'm using "mousePressed". The problem is that which button I'm pressing, is giving me the same result as the 'exit' button. Could somebody give me tips on how I can structure my menu better or even make my button work? I am using a library on Processing called 'ControlP5' to make my buttons.
here is my code so far:
int mode; // 1: intro screen, 2: game , 3: game over
final int INTRO = 1;
final int PLAY = 2;
final int GAMEOVER = 3;
//==============================================================
void setup(){
size(1920,1080);
mode = 1;
}
//========================================================
void draw(){
if(mode == 1){
introScreen();
}
else if (mode == 2){
gameItself();
}
else if (mode == 3){
gameOver();
}
else println("mode error");{
}
}
void introScreen(){
mode = 1;
static int Page = 0;
import controlP5.*;
ControlP5 cp5;
cp5= new ControlP5(this);
switch(Page){
case 0: // main menu
cp5.addButton("Start").setValue(0).setPosition(1420,250).setSize(400,100);
cp5.addButton("Exit").setValue(0).setPosition(1420,650).setSize(400,100);
cp5.addButton("Help").setValue(0).setPosition(1420,450).setSize(400,100);
break;
case 1: //help menu
cp5.addButton("Back").setValue(0).setPosition(1420,450).setSize(400,100);
break;
}
public void Start(){
if(mousePressed){
mode = 2; // switching to the game itself
}
println("Start");
}
public void Exit(){
if(mousePressed){
exit(); }
println("Exit");
}
public void Help(){
Page = 1;
println("Help");
}
public void Back(){
if(mousePressed){
Page = 0;
}
println("Back");
}
void gameItself(){
// game and stuff
}
void gameOver(){
//gameover
}
Take a look at how the mousePressed event works. You may use this information useful.
To achieve your goal as to change the Page variable by clicking buttons, there are multiple options. First, I'll go with the easier one, the one which doesn't need an import but just check for coordinates. Then I'll do the same thing, but with controlP5.
1. Just checking where the clicks lands
I'll go with the most basic one: detecting the "click" and checking if it's coordinates are inside a button.
First, we'll add the mouseClicked() method. This method is called every time a mouse button is pressed.
// I'm typing this out of IDE si there may be some quirks to fix in the code
void mouseClicked() {
switch(Page) {
case 0:
if (mouseX > 1420 && mouseX < 1420+400 && mouseY > 250 && mouseY < 250+100) {
// You're in the main menu and Start was clicked
}
if (mouseX > 1420 && mouseX < 1420+400 && mouseY > 650 && mouseY < 650+100) {
// You're in the main menu and Exit was clicked
}
if (mouseX > 1420 && mouseX < 1420+400 && mouseY > 450 && mouseY < 450+100) {
// You're in the main menu and Help was clicked
}
// You should use 'else if' instead of 3 different if, but I coded it like that so it would be easier to see the small differences between the coordinates
case 1:
if (mouseX > 1420 && mouseX < 1420+400 && mouseY > 450 && mouseY < 450+100) {
// You're un the help menu and Back was clicked
}
}
}
As you can see, I just used the coordinates and size of your buttons to check if the click was located inside one. That's kind of ninja-ing my way out of this issue. I don't know how far into programming you are, or else I would recommand to build a class to handle user inputs, but this way is easy to manage for small exercises like homework.
2. Designing controlP5 buttons
I'm not a ControlP5 expert, so we'll keep close to the basics.
I'll be blunt, the code you provided is ripe with problems, and it's not so many lines, so instead of pointing where it goes wrong I'll give you some skeleton code which will work and on which you can build some understanding. I'll give you the tools and then you can make your project work.
When you design your buttons, if you design them all in the same object, they'll share some properties. For an example, all your buttons will be visible or invisible at the same time. You don't need to redraw them all the time, because they already handle this, so you need to manage them with another method.
You should design your buttons as global objects (as you did), and add them to the ControlP5 object which makes the most sense. You can have one button per object if you want, or many if they are linked together, for an example all the "menu" buttons which appears at the same time could be owned by the same object. Design your buttons in the setup() method if you design them only one time for the whole program. Of course, if this was more than an homework, you may want to avoid the buttons being globals, but it'll be much easier to keep them in memory for a short project.
The "name" of the button is also the name of the method that it'll try to call if you click on it. Two buttons cannot share the same "name". Buttons can have a set value which will be sent to the method that they call.
You don't need to use Processing's mouse events for the buttons to work. They are self-contained: they have their own events, like being clicked on or detecting when the mouse is over them. Here's the documentation for the full list of the methods included in the ControlP5 buttons.
You don't need to manage the buttons in the draw() loop. They manage themselves.
Here's some skeleton code to demonstrate what I just said. You can copy and paste it in a new Processing project and run it to see what's going on.
ControlP5 cp5;
ControlP5 flipVisibilityButton;
int Page = 0;
void setup() {
size(1920, 800);
textAlign(CENTER, CENTER);
textSize(60);
fill(255);
cp5 = new ControlP5(this); // this is ONE object, which will own buttons.
cp5.addButton("MenuButton0") // this is the name of the button, but also the name of the method it will call
.setValue(0) // this value will be sent to the method it calls
.setPosition(1420, 250)
.setSize(400, 100);
cp5.addButton("MenuButton1")
.setValue(1)
.setPosition(1420, 450)
.setSize(400, 100);
cp5.addButton("MenuButton2")
.setValue(2)
.setPosition(1420, 650)
.setSize(400, 100);
flipVisibilityButton = new ControlP5(this); // this is a different object which own it's own controls (a button in this case)
flipVisibilityButton.addButton("flipVisibility")
.setValue(2)
.setPosition(200, height/2)
.setSize(200, 100);
}
void draw() {
// No button management to see here
background(0);
// showing which button has been pressed while also keeping watch to see if the mouse is over one of the cp5 buttons
text(Page + "\n" + cp5.isMouseOver(), width/2, height/2);
}
void MenuButton0(int value) {
ChangePage(value);
}
void MenuButton1(int value) {
ChangePage(value);
}
void MenuButton2(int value) {
ChangePage(value);
}
void ChangePage(int value) {
Page = value;
}
void flipVisibility(int value) {
// When the buttons are invisible, they are also unclickable
cp5.setVisible(!cp5.isVisible());
}
You should be able to expand on this example to do your project, but if you have difficulties don't hesitate to comment here and ask further questions. Have fun!
I am making a chess game and so far everything is good and I am writing the rules of each piece now. The problem is that a for loop is acting oddly. Its for the bishop so x is going down and y is going up. At this point it acts oddly whenever I try to add the point to a possible move
for (int i = 0; i < 8; i++) {
Point newLoc = new Point(x-i, y+i);
if(team.equals("white")) {
if(containsPiece(newLoc)) {
if(ChessBoard.black.containsKey(newLoc)) {
possibilities.put(newLoc, rating);
break;
}
else {
break;
}
} else
possibilities.put(newLoc, rating);
}
containsPiece() is working just fine and possibilities is the HashMap I am storing the possible moves in.
The way I see it it should be working perfect because if the tile at newLoc is white it shouldn't add it to the possible moves and stop getting any moves after it in that direction. Does anyone see why it seems to abandon all the previous possible moves added to possibilities
i should start in 1, not 0, since when i==0, newLoc is the position of the bishop ((x-0,y+0)), so you break from the loop, since the bishop is a white tile.
I am making a game using android eclipse(java) where enemies fall from the top of the screen to the bottom. I have succeeded in making them fall (a little too fast but good enough for now) but I have not been able to make them respond correctly to tapping. At first, all enemies were defeated wherever the touch occurred but now there is no response at all. My question is how do i correctly read the player input. Thanks to anyone who reads this. This is my first post so I apologize if the question was posed incorrectly.
public boolean onTouchEvent(MotionEvent e) {
switch (e.getAction() & MotionEvent.ACTION_MASK) {
// Player has touched the screen
case MotionEvent.ACTION_DOWN:
paused = false;
// Has the player tapped an alien
for (int i = 0; i < enemyNumb; i++) {
if (aliens[i].getVisibility() & aliens[i].getX() == e.getX() & aliens[i].getY() == e.getY()) { // Enemy defeated code goes here
Okay, I got it to work by using a box to detect a click within. This is what i used before but the aliens were put into the same box so they all disappeared and it made me believe that it was wrong. Thank you cricket_007 for the suggestion.
if ( aliens[i].getRect().contains(e.getX(), e.getY()))
I'm working on a breakout game for an assignment and for part 2 of it I need to include code that stops the bat from being moved out of the boundaries. I'm pretty sure that I need to use an if statements but I don't know what exactly I should put inside the brackets for else (something that will enable the bat to move). I
This is the code in particular I'm talking about.
if (dist < 0)
{
}
else
{} // move
if ((dist + 150)> 600)
{
}
else
{} // move
(Part 2 is in the ModelBreakout class).
There are lots of classes and just so many different parts of the code that are to do with the movement of the bat and I don't know what to use for this part, I would appreciate a hint of what I need to do!
Edit: I removed all of the classes because people were complaining. If you would like to view the classes go to this page and scroll down to the title Mini project: The BreakOut game.
Thanks for any help. I'm not looking for anyone to do my work for me, I would just like some guidance, I've worked out that I need to do an if statement, I'm just not sure of what I need to put inside it.
TL;DR.
I recently created a similar game. Here's how I implemented it.
Racket Class
protected static final float MIN_X = 10;
protected static final float MAX_X = 590;
public void moveLeft()
{
if (x > MIN_X)
{
x -= 5;
}
}
public void moveRight()
{
if (x < MAX_X)
{
x += 5;
}
}
Player extends Racket
public void process(int key)
{
if (key == KeyEvent.VK_KP_LEFT || key == KeyEvent.VK_LEFT)
{
moveLeft();
}
else if (key == KeyEvent.VK_KP_RIGHT || key == KeyEvent.VK_RIGHT)
{
moveRight();
}
}
Edit: This is not the complete classes. It's just some items lifted from them. There's a key listener added to the game which passes the key to Player.process().
Edit 2: Updated my code. Your width is set to 600 so the boundaries can be 10 and 590. This should work for you
Looking at the classes there are built in methods for each object on the screen, so you could do something like this:
If( Bat.GetX() < 0 ) {
Bat.moveX( *INSERT THE X HERE* )
}
And you also could do a the same thing for the max width. Also if you do a simple fix like this make sure to change the refresh rate of the screen, otherwise you will see the bat Jumping to the new position.
I try to improve the movement of my figures but i dont find the real reason why they stutter a bit. I am moving them with an SequenceAction containing an MoveToAction and an RunnableAction that does reset the moveDone flag so there can be started a new move.
The game itself is gridbased so if a move is done the squence starts a move to the next grid depending on the direction. So here is how it looks like:
note that this is inside of the Act of the figure
....//some more here
if (checkNextMove(Status.LEFT)) //check if the position is valid
{
status = Status.LEFT; //change enum status
move(Status.LEFT); // calls the move
screen.map.mapArray[(int) mapPos.x][(int) mapPos.y] = Config.EMPTYPOSITION;
screen.map.mapArray[(int) (mapPos.x - 1)][(int) mapPos.y] = Config.CHARSTATE;
mapPos.x--;
moveDone = false;
}
//... same for the up down right and so on.
//at the end of this checking the updating of the actor:
// methode from the absctract to change sprites
updateSprite(delta);
super.act(delta); // so the actions work
//end of act
And here is the move Method that does add the Actions
protected void move(Status direction)
{
// delete all old actions if there are some left.
clearActions();
moveAction.setDuration(speed);
//restart all actions to they can used again
sequence.restart();
switch (direction)
{
case LEFT:
moveAction.setPosition(getX() - Config.TILE_SIZE, getY());
addAction(sequence);
break;
case RIGHT:
moveAction.setPosition(getX() + Config.TILE_SIZE, getY());
addAction(sequence);
break;
case UP:
moveAction.setPosition(getX(), getY() + Config.TILE_SIZE);
addAction(sequence);
break;
case DOWN:
moveAction.setPosition(getX(), getY() - Config.TILE_SIZE);
addAction(sequence);
break;
default:
break;
}
}
The figures dont really move smothy.
Anyone does see a misstake or isnt it possible to let them move smothy like this?
It always stutter a bit if a new move is started. So i think this might not work good. Is there a differnt approach to move them exactly from one Grid to an nother? (Tried it myself with movementspeed * delta time but this does not work exactly and i struggeled around and used the Actionmodel)
it seems to make troubles with the one Frame where it does not move for example.
Here is an mp4 Video of the stuttering:
stuttering.mp4
just to mention, the camera movement is just fine. it's smothy but the figure stutters as you can see i hope
If you use your moveAction each move, you should call moveAction.restart() to reset the counter inside it:
// delete all old actions if there are some left.
clearActions();
sequence.reset(); // clear sequence
// add movementspeed. Note it can change!
moveAction.restart();
moveAction.setDuration(speed);
UPDATE:
Now issue occurs, because you call restart of SequenceAction after clearActions(). If your clearActions() removes all actions from SequenceAction then restart will be called for empty SequenceAction. So, do this instead:
//restart all actions to they can used again
sequence.restart();
// delete all old actions if there are some left.
clearActions();
moveAction.setDuration(speed);
Okay so i solved it myself. It has nothing todo with changing sequences around. It has something todo with the updatefrequency of the act() of the figures. The MoveToAction interpolates between the 2 points given by time. So if the last update, updates the MoveToAction by "to much time" it would need to go over the 100% of the action. So it would move to far but the action does not do this it set the final position and thats what it should do. Thats why it does not look fluent.
So how to solve this issue?
By decreasing the updatetime the "to far movement" decreases too because the steplength is getting smaller. So i need to increase the updatespeed above the 60fps. Luckily i got an thread for my updating of the figures and positions and so on. GameLogicThread. This ran on 60fps too. So i solved the stuttering by increasing it's frequence. up to around 210fps at the moment so the "overstep" is minimal. You can't even notice it.
To Show how my thread works:
public class GameLogicThread extends Thread
{
private GameScreen m_screen;
private boolean m_runing;
private long m_timeBegin;
private long m_timeDiff;
private long m_sleepTime;
private final static float FRAMERATE = 210f;
public GameLogicThread(GameScreen screen)
{
m_screen = screen;
setName("GameLogic");
}
#Override
public void run()
{
m_runing = true;
Logger.log("Started");
while (m_runing)
{
m_timeBegin = TimeUtils.millis();
// hanlde events
m_screen.m_main.handler.processEvents();
synchronized (m_screen.figureStage)
{
// now figures
if (m_screen.m_status == GameStatus.GAME)
{
m_screen.character.myAct(1f / GameLogicThread.FRAMERATE);// and here it is ;)
m_screen.figureStage.act(1f / GameLogicThread.FRAMERATE);
}
}
m_timeDiff = TimeUtils.millis() - m_timeBegin;
m_sleepTime = (long) (1f / GameLogicThread.FRAMERATE * 1000f - m_timeDiff);
if (m_sleepTime > 0)
{
try
{
Thread.sleep(m_sleepTime);
}
catch (InterruptedException e)
{
Logger.error("Couldn't sleep " + e.getStackTrace());
}
}
else
{
Logger.error("we are to slow! " + m_sleepTime);
}
}
}
public void stopThread()
{
m_runing = false;
boolean retry = true;
while (retry)
{
try
{
this.join();
retry = false;
}
catch (Exception e)
{
Logger.error(e.getMessage());
}
}
}
}