• collided(): Kiểm tra va chạm giữa các thực thể.
Tiếp theo, mở rộng lớp Entity cho mỗi phần tử game và cài đặt phương thức update() và paint(). Đối với Ball:
publicclass Ball extendsEntity {
publicint radium = 2;
public Ball(int radium){
this.radium = radium;
width = radium * 2;
height = radium * 2;
// red color
this.color = 0×00FF0000;
}
/**
* Paints the ball using a circle
*/
publicvoidpaint(Graphics g) {
g.setColor(color);
g.fillArc0;
}
/***
* Updates the ball position.
*/
publicvoidupdate() {
// update position
oldX=x;
oldY=y;
x += speedX;
y += speedY;
}
}
Đối với Pad:
publicclass Pad extendsEntity{
int minLimit = 0;
int maxLimit = 1;
public Pad(int width, int height) {
this.width = width;
this.height = height;
}
publicvoid paint(Graphics g) {
g.setColor(0,0,255);
g.fillRect(x, y, width, height);
}
publicvoid update() {
// change x position according the speed
x += speedX;
// check if world bounds are reached
if (x < minLimit) {
x = minLimit;
}
if 0{
x = maxLimit – width;
}
}
}
Đối với Brick:
publicclass Brick extendsEntity {
boolean active = true;
public Brick(int color){
this.color = color;
}
publicvoid paint(Graphics g) {
// only paints if still active
if (active){
g.setColor(color);
g.fillRect(x, y, width, height);
}
}
publicvoid update() {
// the bricks don’t move
}
}
Bây giờ, tạo và cấu hình các lớp này trên lớp Canvas. Tạo phương thức init() trên lớp Canvas:
publicvoid init(){
// resets lifes
lifes = 3;
// resets score
score = 0;
// resets time
time = 0;
// bricks hit
bricksHit = 0;
// create a pad
pad = new Pad(getWidth()/10,getWidth0;
pad.x = (this.getWidth()-pad.width) / 2;
pad.y = this.getHeight0;
pad.maxLimit = getWidth();
pad.minLimit = 0;
// create ball
ball = new Ball(4);
ball.x = getWidth() / 2;
ball.y = getHeight() / 2;
ball.speedX = 1;
ball.speedY = 1;
// set collision limits
wallMinX = 0;
wallMaxX = getWidth();
wallMinY = 0;
// to allow to get out of screen
wallMaxY = getHeight() + 4 * ball.radium;
// create bricks
Brick brick;
bricks = newVector();
for 2)
brick.width = BRICK_WIDTH;
brick.height = BRICK_HEIGHT;
brick.x = 2);
brick.y = 20;
bricks.addElement(brick);
}
}
Sau khi tất cả các đối tượng được tạo ra, cập nhật lại trạng thái và vẽ lại, được mô tả trong 2 phương thức updateGameState() và updateGameScreen():
// draws elements to the screen
protectedvoid updateGameScreen(Graphics g) {
// stores width and height
width = getWidth();
height = getHeight();
// set background color
g.setColor(0,0,0);
// clear screen
g.fillRect(0, 0, width, height);
// draw score
g.setColor(255,255,255);
g.drawString0;
// draw game elements
pad.paint(g);
ball.paint(g);
// draw bricks stored in the Vector bricks
for (int i=0; i < bricks.size0{
Brick brick = (Brick)(bricks.elementAt(i));
brick.paint(g);
}
}
// updates state of all elements in the game
publicvoid updateGameState(){
pad.update();
ball.update();
checkBallCollisionWithWalls();
checkBallCollisionWihPad();
checkBallCollisionWithBricks();
checkBallOutOfReach();
// check if bricks ended
if (bricksHit == bricks.size()){
run = false;
}
}
Game cần tương tác trở lại với các sự kiện keypad để di chuyển pad của người chơi.
// update game entities according to use presses on keypad
publicvoid checkUserInput() {
int state = getKeyStates();
if ( (state & GameCanvas.LEFT_PRESSED) > 0) {
// move left
pad.speedX=-1;
} elseif( (state & GameCanvas.RIGHT_PRESSED) > 0) {
// move right
pad.speedX=1;
} else {
// don't move
pad.speedX=0;
}
}
Bây giờ nếu bạn chạy trò chơi trên mô phỏng, các bạn sẽ có một màn hình trò chơi thực sự, nơi bạn có thể chơi trò chơi riêng của bạn: Di chuyển pad, trúng ball và xóa tất cả các brick.
Trong phần tiếp theo giải thích cách sử dụng hình ảnh để có được một trò chơi tìm kiếm tốt hơn.
Phát triển game đơn giãn trên Mobile(P4)
Trong bài trước, lớp GameCanvas được xây dựng với tất cả các tương tác giữa các element chính. Bây giờ, tất cả các element gameplay được xây dựng, đây là lúc cải thiện giao diện trực quan của trò chơi bằng cách sử dụng các tập tin hình ảnh thay vì sử dụng phương thức draw/fill trên đối tượng graphics để biểu diễn các thực thể trò chơi. Tôi đã tạo ra một số hình ảnh dựa trên các tài nguyên SpriteLib sẽ được sử dụng trong trò chơi.
Image
Để truy cập và hiển thị các hình ảnh trong MIDlet, ta phải sử dụng một phần tử hay lớp Image trong giao diện người dùng cấp thấp. Lớp này lưu trữ dữ liệu hình ảnh đồ họa độc lập với thiết bị hiển thị trong một bộ nhớ đệm off-screen. Các hình ảnh hoặc ở dạng Mutable hay Immutable phụ thuộc vào cách mà chúng được tạo ra. Thông thường, các hình ảnh dạng Immutable được ta ra thông qua việc load hình ảnh từ tài nguyên như file Jar hay mạng. Các hình ảnh dạng Immutable được tạo ra thông qua việc sử dụng phương thức tĩnh createImage() của lớp Image. Tuy nhiên, một khi ảnh Immutable đã được tạo ra thì nó không thể được sửa đổi. Các hình ảnh dạng Mutable được tạo ra thông qua phương thức khởi dựng(Constructor) của lớp Image và lúc đó nó chỉ chứa các pixel trắng. Ứng dụng có thể biểu diễn image Mutable bằng cách gọi phương thức getGraphics() trên Image để có được đối tượng Graphics cho mục đích này.
Trong game này, các hình ảnh Immutable đại diện cho các thực thể game. Bây giờ, ta hãy thay đổi lớp Pad và tạo ra đối tượng Image trong constructor của nó.
Image image;
public Pad() {
try {
image = Image.createImage“;
width = image.getWidth();
height = image.getHeight();
} catch (IOException e) {
e.printStackTrace();
}
}
Sau đó, cài đặt lại phương thức paint() của lớp Pad để vẽ hình ảnh:
publicvoid paint(Graphics g) {
g.drawImage(image, x,y, Graphics.TOP | Graphics.LEFT);
}
Lưu ý: khi tạo hình ảnh, bạn nên sử dụng ảnh với định dạng PNG, bởi đây là định dạng thông dụng của các loại thiết bị. Những thiết bị đời mới có thể hỗ trợ nhiều định dạng khác như: JPEG, BMP…, tuy nhiên để an toàn bạn nên tạo ra file ảnh dạng PNG.
Tiếp theo, ta sửa đổi lớp Ball như sau:
Image image;
public Ball() {
try {
image = Image.createImage“;
width = image.getWidth();
height = image.getHeight();
} catch (IOException e) {
e.printStackTrace();
}
}
publicvoid paint(Graphics g) {
g.drawImage(image, x,y, Graphics.TOP | Graphics.LEFT);
}
Bây giờ, nếu bạn chạy ứng dụng, bạn sẽ cố một Ball đẹp, tuy nhiên trong game sử dụng nhiều Brick với màu sắc khác nhau, và mỗi Brick được cắt từ một Image chính. Bạn có thể làm điều này thông qua sử dụng phương thức setClip() trong lớp Graphics, tuy nhiên từ MIDP 2.0 trở đi, nó còn một hỗ trợ một lớp Sprite để ta làm điều này.
Sprite
Một Sprite là một thuật ngữ chung trong game. Nó tham chiếu đến một phần tử trực quan được tạo ra bởi các Image, thường chuyển động và di chuyển xung quanh các phần tử khác một cách độc lập trong game.Lớp Sprite trong MIDP 2.0 đại diện cho khái niệm này.Nó cho phép tạo ra các Sprite dựa trên các hình ảnh với nhiều frame.Nó có thể thay đổi frame, điều khiển chuyển động và kiểm tra va chạm với các phần tử khác.
Tất cả các khả năng này được sử dụng trong các thực thể của game, và ta hãy xem cách xây dựng Brick:
publicstaticint BRICK_FRAMES = 20;
Image image = null;
Sprite sprite = null;
public Brick(){
// load image
image = Image.createImage“;
// create the sprite with 20 frames, one for each brick
sprite = new Sprite(image,image.getWidth()/BRICK_FRAMES, image.getHeight());
width = sprite.getWidth();
height = sprite.getHeight();
}
Mã này tạo ra một Sprite với 20 khung hình(frame), một cho mỗi Brick có sẵn trên hình ảnh. Trước khi vẽ Brick bạn cần thay đổi frame sẽ được sử dụng....
