j2me学习六_翻译教程-牧羊犬游戏2

四.搭建游戏环境

1.新建Field类

2.引入类

// unnamed package

import javax.microedition.lcdui.*;

import javax.microedition.lcdui.game.*;

3.继承TiledField类

TieldField对象是一个能由多个小图片组成的网格,这个类允许使用小的图像来绘制大的场景

class Field

extends TiledLayer

{

//为游戏创建背景

private static final int WIDTH_IN_TILES = 12;

private static final int HEIGHT_IN_TILES = 12;

private static final int TILE_WIDTH = 16;

private static final int TILE_HEIGHT = 16;

private static int[][] cellTiles =

{{-3, -2, -3, -1, -2, -1, -3, -1, -2, -3, -1, -2},

{-2, 3, 4, 3, 1, 2, 3, 2, 1, 5, 2, -3},

{-1, 2, 1, 2, 3, 4, 5, 3, 2, 4, 3, -1},

{-2, 1, 4, 9, 9, 9, 9, 4, 5, 2, 1, -2},

{-3, 3, 5, 9, 10, 10, 10, 2, 1, 3, 5, -1},

{-2, 2, 3, 9, 10, 10, 10, 5, 4, 2, 1, -3},

{-1, 4, 2, 9, 9, 9, 9, 3, 1, 3, 2, -2},

{-3, 2, 5, 1, 3, 1, 4, 2, 5, 4, 3, -3},

{-2, 1, 4, 2, 5, 2, 3, 4, 2, 1, 2, -1},

{-1, 5, 1, 4, 3, 4, 1, 2, 3, 4, 1, -2},

{-3, 2, 4, 5, 2, 3, 2, 4, 1, 2, 3, -3},

{-2, -3, -2, -1, -2, -1, -3, -2, -1, -3, -1, -2}};

private static int FOLD_TILE = 10;

private static int FENCE_TILE = 9;

private static int[][] waterFrames = {{6, 7, 8}, {7, 8, 6}, {8, 6, 7}};

private int tickCount = 0;

5.创建生成背景的方法

用到了createAnimatedTilesetCell方法,前者用于创建动态单元,后者用于填充背景

Field()

{

super(WIDTH_IN_TILES,

HEIGHT_IN_TILES,

SheepdogMIDlet.createImage("/field.png"),

TILE_WIDTH,

TILE_HEIGHT);

createAnimatedTile(waterFrames[0][0]); // tile -1

createAnimatedTile(waterFrames[1][0]); // tile -2

createAnimatedTile(waterFrames[2][0]); // tile -3

for (int row = 0; row < HEIGHT_IN_TILES; ++row)

{

for (int column = 0; column < WIDTH_IN_TILES; ++column)

{

setCell(column, row, cellTiles[row][column]);

}

}

}

5.创建方法,设置牧羊犬的初始地点和设置记录速度

int getSheepdogStartX()

{

return getWidth() - 50;

}

int getSheepdogStartY()

{

return getHeight() - 50;

}

void tick()

{

int tickState = (tickCount++ >> 3); // slow down x8

int tile = tickState % 3;

setAnimatedTile(-1 - tile, waterFrames[tile][(tickState % 9) / 3]);

}

6.检测到不能达到的区域的通道

// return true if any part of the rectangle overlaps a water tile

// or the fence

boolean containsImpassableArea(int x, int y, int width, int height)

{

int rowMin = y / TILE_HEIGHT;

int rowMax = (y + height - 1) / TILE_HEIGHT;

int columnMin = x / TILE_WIDTH;

int columnMax = (x + width - 1) / TILE_WIDTH;

for (int row = rowMin; row <= rowMax; ++row)

{

for (int column = columnMin; column <= columnMax; ++column)

{

int cell = getCell(column, row);

if ((cell < 0) || (cell == FENCE_TILE))

{

return true;

}

}

}

return false;

}

7.检测绵羊是否进入特定区域

boolean inFold(Sprite s)

{

// we can assume that the sprite's reference pixel is unchanged

int rowMin = s.getY() / TILE_HEIGHT;

int rowMax = (s.getY() + s.getHeight() - 1) / TILE_HEIGHT;

int columnMin = s.getX() / TILE_WIDTH;

int columnMax = (s.getX() + s.getWidth() - 1) / TILE_WIDTH;

for (int row = rowMin; row <= rowMax; ++row)

{

for (int column = columnMin; column <= columnMax; ++column)

{

if (getCell(column, row) != FOLD_TILE)

{

return false;

}

}

}

return true;

}

}

五.创建游戏角色

Sheepdog class

创建sheepdog的sprite,注意它没有面向右边的帧,当要让它面向右边的时候,使用图像的变换方法TRANS_MIRROR.

1. 创建Sheepdog类

2. 引入类

import javax.microedition.lcdui.*;
import javax.microedition.lcdui.game.*;

3. 继承Sprite

class Sheepdog
 extends Sprite
{

4. 创建参数

static final int WIDTH = 15;

static final int HEIGHT = 15;

static final int VIBRATION_MILLIS = 200;

private final SheepdogCanvas canvas;

private boolean barking = false;

private int[][][] animations = {{{0}, // stand up

{1, 2, 3, 4}}, // run up

{{5}, // stand left

{6, 7, 8, 9}}, // run left

{{10}, // stand down

{11, 12, 13, 14}}}; // run down

private int animationTick = 0;

private static final int STAND = 0;

private static final int RUN = 1;

private int currentDirection = SheepdogCanvas.LEFT;

5. 在SheepdogCanvas中初始化Sheepdog对象并且载入dog的图像,defineCollisionRectangle用于设定用于检测碰撞的边界,defineReferencePixel用于设定Sprite的像素引用。

 Sheepdog(SheepdogCanvas canvas)
 {
 super(SheepdogMIDlet.createImage("/dog.png"), WIDTH, HEIGHT);
 defineCollisionRectangle(2, 2, WIDTH-4, WIDTH-4);
 defineReferencePixel(WIDTH/2, HEIGHT/2);
 
this.canvas = canvas;
 }

6. 创建Sheepdog的动作,移动,犬吠

void tick(int direction, boolean bark)

{

animationTick++;

Field field = canvas.getField();

boolean moving = false;;

switch (direction)

{

case SheepdogCanvas.UP:

currentDirection = direction;

if ((getY() > 0) &&

!field.containsImpassableArea(getX(),

getY() - 1,

getWidth(),

1) &&

moveSuccessfully(0, -1))

{

moving = true;

}

else

{

canvas.vibrate(VIBRATION_MILLIS);

}

break;

case SheepdogCanvas.LEFT:

currentDirection = direction;

if ((getX() > 0) &&

!field.containsImpassableArea(getX() - 1,

getY(),

1,

getHeight()) &&

moveSuccessfully(-1, 0))

{

moving = true;

}

else

{

canvas.vibrate(VIBRATION_MILLIS);

}

break;

case SheepdogCanvas.DOWN:

currentDirection = direction;

if ((getY() + getHeight() < field.getWidth()) &&

!field.containsImpassableArea(getX(),

getY() + getHeight(),

getWidth(),

1) &&

moveSuccessfully(0, 1))

{

moving = true;

}

else

{

canvas.vibrate(VIBRATION_MILLIS);

}

break;

case SheepdogCanvas.RIGHT:

currentDirection = direction;

if ((getX() + getWidth() < field.getWidth()) &&

!field.containsImpassableArea(getX() + getWidth(),

getY(),

1,

getHeight()) &&

moveSuccessfully(1, 0))

{

moving = true;

}

else

{

canvas.vibrate(VIBRATION_MILLIS);

}

break;

default: // must be NONE

break;

}

if (moving)

{

advanceRunningAnimation();

}

else

{

setStandingAnimation();

}

// implement a toggle, so bark only happens once per click

// (will therefore not register very rapid multiple-clicks)

if (bark)

{

if (!barking)

{

SoundEffects.getInstance().startDogSound();

barking = true;

canvas.handleDogBark();

}

}

else

{

barking = false;

}

}

7. 创建用于检测Sheepdog的胜利,用到了move方法

private boolean moveSuccessfully(int dx, int dy)
 {
 move(dx, dy);
 if (canvas.overlapsSheep(this))
 {
 move(-dx, -dy);
 return false;
 }
 else
 {
 return true;
 }
 }

8. 创建Sheepdog的动作,用到了setTransform和setFrame方法,前者用于图像的变换,后者用于设定图像序列的帧

private void advanceRunningAnimation()

{

int[] sequence;

if (currentDirection == SheepdogCanvas.RIGHT)

{

sequence = animations[SheepdogCanvas.LEFT][RUN];

setTransform(TRANS_MIRROR);

}

else

{

sequence = animations[currentDirection][RUN];

setTransform(TRANS_NONE);

}

setFrame(sequence[(animationTick >> 1) % sequence.length]);

}

private void setStandingAnimation()

{

if (currentDirection == SheepdogCanvas.RIGHT)

{

setFrame(animations[SheepdogCanvas.LEFT][STAND][0]);

setTransform(TRANS_MIRROR);

}

else

{

setFrame(animations[currentDirection][STAND][0]);

setTransform(TRANS_NONE);

}

}

}

Sheep class

原理和Sheepdog class 差不多,直接上代码

// unnamed package

import javax.microedition.lcdui.*;

import javax.microedition.lcdui.game.*;

import java.util.*;

Set Sheep to extend Sprite.

class Sheep

extends Sprite

{

//创建参数

static final int WIDTH = 15;

static final int HEIGHT = 15;

private final SheepdogCanvas canvas;

private int[][][] animations = {{{0}, // stand up

{1, 2, 3, 4}}, // run up

{{5}, // stand left

{6, 7, 8, 9}}, // run left

{{10}, // stand down

{11, 12, 13, 14}}}; // run down

private int animationTick;

private static int numSheep = 0;

private static final int STAND = 0;

private static final int RUN = 1;

private int currentDirection = SheepdogCanvas.DOWN;

private final int flockFactor;

private final int minDogFactor;

private final int maxDogFactor;

private int dogFactor;

//初始化sheep对象

Sheep(SheepdogCanvas canvas)

{

super(SheepdogMIDlet.createImage("/sheep.png"), WIDTH, HEIGHT);

defineCollisionRectangle(2, 2, WIDTH-4, WIDTH-4);

defineReferencePixel(WIDTH/2, HEIGHT/2);

this.canvas = canvas;

animationTick = numSheep++;

flockFactor = 100 + SheepdogMIDlet.random(100);

minDogFactor = SheepdogMIDlet.random(20);

maxDogFactor = minDogFactor + 10;

dogFactor = minDogFactor;

}

.

void tick()

{

// sheep are 4x as slow as dogs

if ((animationTick++ % 4) != 0)

{

return;

}

//创建羊的人工智能

// adjust dog factor

adjustDogFactor();

// ARTIFICIAL INTELLIGENCE SECTION

// - wants to move away from dog, if dog is close

// - wants to move closer to flock (average position of other

// sheep) if they are close

// - if preferred direction is diagonal and major direction is

// blocked, take minor direction

// - each sheep varies in how much it's scared of the dog, and

// how much it wants to flock

// We do this by calculating a weighted direction vector

// First calculate dog effect

Sheepdog sheepdog = canvas.getSheepdog();

int dx = getX() - sheepdog.getX();

int dy = getY() - sheepdog.getY();

int sumsq = dx * dx + dy * dy;

Field field = canvas.getField();

int dogEffectX =

dogFactor * dx * field.getWidth() * field.getWidth() / sumsq;

int dogEffectY =

dogFactor * dy * field.getHeight() * field.getHeight() / sumsq;

// Next calculate flock effect

int flockDx = 0;

int flockDy = 0;

Vector sheep = canvas.getSheep();

for (int i = 0; i < sheep.size(); ++i)

{

Sheep sh = (Sheep)(sheep.elementAt(i));

if (sh != this)

{

flockDx += getX() - sh.getX();

flockDy += getY() - sh.getY();

}

}

int flockEffectX = (flockDx * flockFactor) / (sheep.size() - 1);

int flockEffectY = (flockDy * flockFactor) / (sheep.size() - 1);

// Now calculate total effect

int totalEffectX = dogEffectX - flockEffectX;

int totalEffectY = dogEffectY - flockEffectY;

// Determine preferred directions

int firstDirection;

int secondDirection;

int thirdDirection;

if (Math.abs(totalEffectY) > Math.abs(totalEffectX))

{

// Prefer to move vertically

if (totalEffectY > 0)

{

firstDirection = SheepdogCanvas.DOWN;

}

else

{

firstDirection = SheepdogCanvas.UP;

}

if (totalEffectX > 0)

{

secondDirection = SheepdogCanvas.RIGHT;

thirdDirection = SheepdogCanvas.NONE;

}

else if (totalEffectX < 0)

{

secondDirection = SheepdogCanvas.LEFT;

thirdDirection = SheepdogCanvas.NONE;

}

else // totalEffectX == 0

{

if (SheepdogMIDlet.random(2) == 0)

{

secondDirection = SheepdogCanvas.LEFT;

thirdDirection = SheepdogCanvas.RIGHT;

}

else

{

secondDirection = SheepdogCanvas.RIGHT;

thirdDirection = SheepdogCanvas.LEFT;

}

}

}

else

{

// Prefer to move horizontally

if (totalEffectX > 0)

{

firstDirection = SheepdogCanvas.RIGHT;

}

else

{

firstDirection = SheepdogCanvas.LEFT;

}

if (totalEffectY > 0)

{

secondDirection = SheepdogCanvas.DOWN;

thirdDirection = SheepdogCanvas.NONE;

}

else if (totalEffectY < 0)

{

secondDirection = SheepdogCanvas.UP;

thirdDirection = SheepdogCanvas.NONE;

}

else // totalEffectY == 0

{

if (SheepdogMIDlet.random(2) == 0)

{

secondDirection = SheepdogCanvas.UP;

thirdDirection = SheepdogCanvas.DOWN;

}

else

{

secondDirection = SheepdogCanvas.DOWN;

thirdDirection = SheepdogCanvas.UP;

}

}

}

// if we can move in the preferred directions, do so, else

// stand facing the dog

if (tryMove(firstDirection) ||

tryMove(secondDirection) ||

((thirdDirection != SheepdogCanvas.NONE) &&

tryMove(thirdDirection)))

{

advanceRunningAnimation();

}

else

{

if (Math.abs(dx) > Math.abs(dy))

{

if (dx > 0)

{

currentDirection = SheepdogCanvas.LEFT;

}

else

{

currentDirection = SheepdogCanvas.RIGHT;

}

}

else

{

if (dy > 0)

{

currentDirection = SheepdogCanvas.UP;

}

else

{

currentDirection = SheepdogCanvas.DOWN;

}

}

setStandingAnimation();

}

// Will baa occasionally if dog is close. Dog distance ranges from

// about 11 minimum to double width of field

int dogDistance = Math.abs(dx) + Math.abs(dy);

if (SheepdogMIDlet.random(dogDistance - 10) == 0)

{

SoundEffects.getInstance().startSheepSound();

}

}

private void adjustDogFactor()

{

dogFactor += SheepdogMIDlet.random(4) - 2; // -2..1

if (dogFactor < minDogFactor)

{

dogFactor = minDogFactor;

}

else if (dogFactor > maxDogFactor)

{

dogFactor = maxDogFactor;

}

}

//创建检测羊的行动路线

private boolean tryMove(int direction)

{

Field field = canvas.getField();

boolean blocked = true;

int dx = 0;

int dy = 0;

switch (direction)

{

case SheepdogCanvas.UP:

if ((getY() > 0) &&

!field.containsImpassableArea(getX(),

getY() - 1,

getWidth(),

1))

{

blocked = false;

dy = -1;

}

break;

case SheepdogCanvas.LEFT:

if ((getX() > 0) &&

!field.containsImpassableArea(getX() - 1,

getY(),

1,

getHeight()))

{

blocked = false;

dx = -1;

}

break;

case SheepdogCanvas.DOWN:

if ((getY() + getHeight() - 1 < field.getWidth()) &&

!field.containsImpassableArea(getX(),

getY() + getHeight(),

getWidth(),

1))

{

blocked = false;

dy = 1;

}

break;

case SheepdogCanvas.RIGHT:

if ((getX() + getWidth() - 1 < field.getWidth()) &&

!field.containsImpassableArea(getX() + getWidth(),

getY(),

1,

getHeight()))

{

blocked = false;

dx = 1;

}

break;

default:

// can't happen

break;

}

boolean success = false;

if (!blocked)

{

boolean wasInFold = field.inFold(this);

move(dx, dy);

if (canvas.overlapsOtherSheep(this) ||

canvas.overlapsSheepdog(this) ||

(wasInFold && !field.inFold(this)))

{

move(-dx, -dy);

}

else

{

currentDirection = direction;

success = true;

}

}

return success;

}

//创建羊的两个动作形态

private void advanceRunningAnimation()

{

int[] sequence;

if (currentDirection == SheepdogCanvas.RIGHT)

{

sequence = animations[SheepdogCanvas.LEFT][RUN];

setTransform(TRANS_MIRROR);

}

else

{

sequence = animations[currentDirection][RUN];

setTransform(TRANS_NONE);

}

setFrame(sequence[(animationTick >> 2) % sequence.length]);

}

private void setStandingAnimation()

{

if (currentDirection == SheepdogCanvas.RIGHT)

{

setFrame(animations[SheepdogCanvas.LEFT][STAND][0]);

setTransform(TRANS_MIRROR);

}

else

{

setFrame(animations[currentDirection][STAND][0]);

setTransform(TRANS_NONE);

}

}

//创建当有犬吠时羊的反应

void handleDogBark()

{

// sheep should get nervous

dogFactor += 5;

if (dogFactor > maxDogFactor)

{

dogFactor = maxDogFactor;

}

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值