8 way movement in MIDP 2.0

Started by
15 comments, last by spillz 18 years, 4 months ago
dude, help me help you by only posting the relevant code (most importantly delete out all the commented stuff)

as far as i can see you have implemented keyPressed, which you use to set your gameAction and keyCode variables to the code of the last key pressed (i think you should get rid of gameAction and just test keyCode against KEY_NUM2,4,6,8 for the horizontal/vertical movements in your main loop as the gameAction codes for up, left, right and down aren't 2,4,6,8 keys on all phones). the biggest problem with the code is your sprite will keep moving until another key is pressed unless you override keyReleased and inside that set the gameAction to zero OR set your gameAction to zero after each move (if you do it the 2nd way the user will need a key press for each move).

is this going to be a shooting game? will you have a fire key? if so, you are going to need to keep track of more than one key at a time. that is a user may want to move and fire at the same time. i'm not sure how well the keyPressed/keyReleased methods actually handle multiple keys being pressed at the same time... (some people just have automatic fire in their games because of this)

Advertisement
Quote:Original post by spillz
dude, help me help you by only posting the relevant code (most importantly delete out all the commented stuff)

as far as i can see you have implemented keyPressed, which you use to set your gameAction and keyCode variables to the code of the last key pressed (i think you should get rid of gameAction and just test keyCode against KEY_NUM2,4,6,8 for the horizontal/vertical movements in your main loop as the gameAction codes for up, left, right and down aren't 2,4,6,8 keys on all phones). the biggest problem with the code is your sprite will keep moving until another key is pressed unless you override keyReleased and inside that set the gameAction to zero OR set your gameAction to zero after each move (if you do it the 2nd way the user will need a key press for each move).

is this going to be a shooting game? will you have a fire key? if so, you are going to need to keep track of more than one key at a time. that is a user may want to move and fire at the same time. i'm not sure how well the keyPressed/keyReleased methods actually handle multiple keys being pressed at the same time... (some people just have automatic fire in their games because of this)


Sorry about that, it's all cleaned up now. Anyways, yes it will be a shooter game, and I will most likely lean towards autofire. As I probably said before, the Siemens M55/56 has a way of automapping d-pad game actions to 2, 4, 6, 8, and I'm not too worried about this not being on all phones since the game will only be built for my phone. I will try to map to the number keys only.

EDIT: Every time I use the get getKeyCode method and test it against 2, 4, 6, 8, I get an IllegalArgumentException. In other words, since the number keys already have key codes, how do I invoke them? Also, after setting gameAction to zero in both keyPressed and keyReleased methods, I was able to move the sprite according to how long I held a key. Anyways, here's what I had in mind:

private int keyUpLeft=49;
private int keyUpRight=51;
private int keyDownLeft=55;
private int keyDownRight=57;

public void run(){
switch(keyUpLeft){
case KEY_NUM1:
playerSprite.moveUpLeft();
break;
}
switch(keyUpRight){
case KEY_NUM3:
playerSprite.moveUpRight();
break;
}
switch(keyDownLeft){
case KEY_NUM7:
playerSprite.moveDownLeft();
break;
}
switch(keyDownRight){
case KEY_NUM9:
playerSprite.moveDownRight();
break;
}
}

[Edited by - thelegendofzaku on December 1, 2005 11:25:06 PM]
Quote:Original post by thelegendofzaku
EDIT: Every time I use the get getKeyCode method and test it against 2, 4, 6, 8, I get an IllegalArgumentException. In other words, since the number keys already have key codes, how do I invoke them? Also, after setting gameAction to zero in both keyPressed and keyReleased methods, I was able to move the sprite according to how long I held a key. Anyways, here's what I had in mind:
}


show me the relevant code for your overrides of keyPressed and keyReleased. i saw before you were using keyCodes and also saw that you posted on the j2me forum. as that poster said you don't need to use the getKeyCode method since the keyCode passed in keypressed and keyreleased is already a code in the correct format. i also think your switch statements in your main loop don't make sense.

anyway, this is what i suggest:

class YourGameCanvas extends GameCanvas implements Runnable{

int keyPress;

protected void keyPressed(int keyCode){
keyPress=keyCode;
}

protected void keyRepeated(int keyCode){
keyPress=keyCode;
}

protected void keyReleased(int keyCode){
keyPress=0;
}

public void run(){
while(/*game running condition satisfied*/)
{
switch(keyPress){
case KEY_NUM1: playerSprite.moveDownLeft(); break;
case KEY_NUM2: playerSprite.moveDown(); break;
case KEY_NUM3: playerSprite.moveDownRight(); break;
case KEY_NUM4: playerSprite.moveLeft(); break;
case KEY_NUM6: playerSprite.moveRight(); break;
case KEY_NUM7: playerSprite.moveUpLeft(); break;
case KEY_NUM8: playerSprite.moveUp(); break;
case KEY_NUM9: playerSprite.moveUpRight(); break;
}
}
//drawing+flushgraphics + sleep etc...
}
}

if you insist on processing the left/right/up/down keys as game actions then delete the lines for KEY_NUM2,4,6,8 and add an additional switch statement straight after the one above:

switch(getGameAction(keyPress)){
case DOWN: playerSprite.moveDown(); break;
case LEFT: playerSprite.moveLeft(); break;
case RIGHT: playerSprite.moveRight(); break;
case UP: playerSprite.moveUp(); break;
}
I just finished trying that method, but it made it worst since that is preventing the screen from being drawn. Here's some recent code:

public class ExampleGameCanvas extends GameCanvas implements Runnable {
int keyPress;

//more declared variables

protected void keyPressed(int keyCode){
//super.keyPressed(keyCode);
keyPress=keyCode;
}
protected void keyRepeated(int keyCode){
//super.keyRepeated(keyCode);
keyPress=keyCode;
}
protected void keyReleased(int keyCode){
//super.keyReleased(keyCode);
keyPress=0;
}
// Constructor and initialization
public ExampleGameCanvas() throws Exception {
super(false);
//usual constructor code goes here

}
.
.
.
.

// Main Game Loop
public void run() {
Graphics g = getGraphics();
while (isPlay == true) {
switch(keyPress){
case KEY_NUM1: playerSprite.moveUpLeft(); break;
case KEY_NUM2: playerSprite.moveUp(); break;
case KEY_NUM3: playerSprite.moveUpRight(); break;
case KEY_NUM4: playerSprite.moveLeft(); break;
case KEY_NUM6: playerSprite.moveRight(); break;
case KEY_NUM7: playerSprite.moveDownLeft(); break;
case KEY_NUM8: playerSprite.moveDown(); break;
case KEY_NUM9: playerSprite.moveDownRight(); break;
}
switch(getGameAction(keyPress)){
case UP: playerSprite.moveUp(); break;
case DOWN: playerSprite.moveDown(); break;
case LEFT: playerSprite.moveLeft(); break;
case RIGHT: playerSprite.moveRight(); break;
}
drawScreen(g);
try { Thread.sleep(delay); }
catch (InterruptedException ie) {}
}
}
// Method to Display Graphics
private void drawScreen(Graphics g) {
//usual drawing of the graphics
}

}
first you may as well call the super versions of keyPressed/keyRepeated/keyReleased in case there is something there that affects screen painting (i really doubt it)...

i don't know why anything there would stop the screen from drawing. paste in your draw code. are you sure you haven't misplaced a brace somewhere? try commenting out the switches statments/method overrides and see if your drawing comes back. then add back incrementally till you find the problem. if you are using netbeans, use the debugger to step through your code in the emulator.
OK, I figured out the problem. It seems that the Up, Down, Left, and Right cases in the threaded loop did not like the key code variable. So what I did was seperate them into two different int variables: one invoking the getGameAction method for the D-Pad and 2, 4, 6, 8 while keeping keyPresses equaling to the keyCode variable in the keyPressed method. Then I just created seperate threaded loops for them: one for the game actions and another for the diagonals and it worked. Here's the almost final code since I wanna ask you something. I commented out the keyRepeated method, do I really need it for my code or can it be expended since I accomplished my main goal, which was move a sprite according to how long I held down a key and to move diagonally? Anyways, here it is:

import com.siemens.mp.color_game.*;
import javax.microedition.lcdui.*;

public class ExampleGameCanvas extends GameCanvas implements Runnable {
private boolean isPlay; // Game Loop runs when isPlay is true
private long delay; // To give thread consistency
private int currentX, currentY; // To hold current position of the 'X'
private int width; // To hold screen width
private int height; // To hold screen height
private int keyPress;
private int regGameCodes;

// Sprites to be used
private GreenThing playerSprite;
private Sprite backgroundSprite;

// Layer Manager
private LayerManager layerManager;

// Constructor and initialization
public ExampleGameCanvas() throws Exception {
super(true);
width = getWidth();
height = getHeight();

currentX = width / 2;
currentY = height / 2;
delay = 20;

// Load Images to Sprites
Image playerImage = Image.createImage("/transparent.PNG");
playerSprite = new GreenThing (playerImage,32,32,width,height);
playerSprite.startPosition();

Image backgroundImage = Image.createImage("/background2.PNG");
backgroundSprite = new Sprite(backgroundImage);

layerManager = new LayerManager();
layerManager.append(playerSprite);
layerManager.append(backgroundSprite);

}
// Automatically start thread for game loop
public void start() {
isPlay = true;
Thread t = new Thread(this);
t.start();
}
public void stop() { isPlay = false; }

// Main Game Loop
public void run() {
Graphics g = getGraphics();
while (isPlay == true) {
switch(regGameCodes){
case UP: playerSprite.moveUp(); break;
case DOWN: playerSprite.moveDown(); break;
case LEFT: playerSprite.moveLeft(); break;
case RIGHT: playerSprite.moveRight(); break;
}
switch(keyPress){
case KEY_NUM1: playerSprite.moveUpLeft(); break;
case KEY_NUM3: playerSprite.moveUpRight(); break;
case KEY_NUM7: playerSprite.moveDownLeft(); break;
case KEY_NUM9: playerSprite.moveDownRight(); break;
}
drawScreen(g);
try { Thread.sleep(delay); }
catch (InterruptedException ie) {}
}
}
protected void keyPressed(int keyCode){
super.keyPressed(keyCode);
regGameCodes=getGameAction(keyCode);
keyPress=keyCode;
}
/*protected void keyRepeated(int keyCode){
super.keyRepeated(keyCode);
keyPress=keyCode;
}*/
protected void keyReleased(int keyCode){
super.keyReleased(keyCode);
regGameCodes=0;
keyPress=0;
}
// Method to Display Graphics
private void drawScreen(Graphics g) {
//g.setColor(0x00C000);
g.setColor(0xffffff);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(0x0000ff);

// updating player sprite position
//playerSprite.setPosition(currentX,currentY);

// display all layers
//layerManager.paint(g,0,0);
layerManager.setViewWindow(0,0,101,80);
layerManager.paint(g,0,0);
flushGraphics();
}
}

Thank you very much in advance if the code is good to go.
that looks like it should work fine. you probably don't need keyRepeated for your purposes.

the UP, DOWN, LEFT, RIGHT members of GameCanvas aren't standard keyCodes: that's why you need to call getGameAction(keyPress). i don't know why there would be a difference between calling getGameAction in the keyPressed method (in this version) or in the switch statement (as in the previous version of your code).

good luck with your game

This topic is closed to new replies.

Advertisement